JS: several bugfixes in incremental compilation
1. Fix exported packages sometimes being mixed up 2. Fix metadata losing package fragments sometimes 3. Don't serialize empty packages to .meta.js 4. Preserve order of package fragments in .meta.js 5. In IC tests, compare textual representation of metadata rather than binary representation
This commit is contained in:
+7
-7
@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.DataOutputStream
|
||||
import java.util.*
|
||||
import java.util.zip.GZIPInputStream
|
||||
import java.util.zip.GZIPOutputStream
|
||||
|
||||
@@ -109,7 +108,7 @@ object KotlinJavascriptSerializationUtil {
|
||||
|
||||
for (fqName in getPackagesFqNames(module)) {
|
||||
val fragment = serializePackageFragment(bindingContext, module, fqName)
|
||||
if (fragment.hasPackage() || fragment.class_Count > 0) {
|
||||
if (!fragment.isEmpty()) {
|
||||
builder.addPackageFragment(fragment)
|
||||
}
|
||||
}
|
||||
@@ -212,13 +211,11 @@ object KotlinJavascriptSerializationUtil {
|
||||
module: ModuleDescriptor,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
): Map<String, ByteArray> {
|
||||
val contentMap = hashMapOf<String, ByteArray>()
|
||||
val contentMap = mutableMapOf<String, ByteArray>()
|
||||
|
||||
for (fqName in getPackagesFqNames(module)) {
|
||||
val part = serializePackageFragment(bindingContext, module, fqName)
|
||||
if (part.class_Count == 0 && part.`package`.let { packageProto ->
|
||||
packageProto.functionCount == 0 && packageProto.propertyCount == 0 && packageProto.typeAliasCount == 0
|
||||
}) continue
|
||||
if (part.isEmpty()) continue
|
||||
|
||||
val stream = ByteArrayOutputStream()
|
||||
with(DataOutputStream(stream)) {
|
||||
@@ -236,6 +233,9 @@ object KotlinJavascriptSerializationUtil {
|
||||
return contentMap
|
||||
}
|
||||
|
||||
private fun ProtoBuf.PackageFragment.isEmpty(): Boolean =
|
||||
class_Count == 0 && `package`.let { it.functionCount == 0 && it.propertyCount == 0 && it.typeAliasCount == 0 }
|
||||
|
||||
fun serializeHeader(packageFqName: FqName?, languageVersionSettings: LanguageVersionSettings): JsProtoBuf.Header {
|
||||
val header = JsProtoBuf.Header.newBuilder()
|
||||
|
||||
@@ -253,7 +253,7 @@ object KotlinJavascriptSerializationUtil {
|
||||
}
|
||||
|
||||
private fun getPackagesFqNames(module: ModuleDescriptor): Set<FqName> {
|
||||
return HashSet<FqName>().apply {
|
||||
return mutableSetOf<FqName>().apply {
|
||||
getSubPackagesFqNames(module.getPackage(FqName.ROOT), this)
|
||||
add(FqName.ROOT)
|
||||
}
|
||||
|
||||
+19
-6
@@ -17,13 +17,12 @@
|
||||
package org.jetbrains.kotlin.serialization.js
|
||||
|
||||
import org.jetbrains.kotlin.contracts.ContractDeserializerImpl
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.NotFoundClasses
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProviderImpl
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentDeclarationFilter
|
||||
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.parentOrNull
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.*
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
@@ -36,12 +35,26 @@ fun createKotlinJavascriptPackageFragmentProvider(
|
||||
configuration: DeserializationConfiguration,
|
||||
lookupTracker: LookupTracker
|
||||
): PackageFragmentProvider {
|
||||
val packageFragments = packageFragmentProtos.mapNotNull { proto ->
|
||||
val packageFragments: MutableList<PackageFragmentDescriptor> = packageFragmentProtos.mapNotNullTo(mutableListOf()) { proto ->
|
||||
proto.fqName?.let { fqName ->
|
||||
KotlinJavascriptPackageFragment(fqName, storageManager, module, proto, header, configuration)
|
||||
}
|
||||
}
|
||||
|
||||
// Generate empty PackageFragmentDescriptor instances for packages that aren't mentioned in compilation units directly.
|
||||
// For example, if there's `package foo.bar` directive, we'll get only PackageFragmentDescriptor for `foo.bar`, but
|
||||
// none for `foo`. Various descriptor/scope code relies on presence of such package fragments, and currently we
|
||||
// don't know if it's possible to fix this.
|
||||
// TODO: think about fixing issues in descriptors/scopes
|
||||
val packageFqNames = packageFragmentProtos.mapNotNullTo(mutableSetOf()) { it.fqName }
|
||||
for (packageFqName in packageFqNames.mapNotNull { it.parentOrNull() }) {
|
||||
var ancestorFqName = packageFqName
|
||||
while (!ancestorFqName.isRoot && packageFqNames.add(ancestorFqName)) {
|
||||
packageFragments += EmptyPackageFragmentDescriptor(module, ancestorFqName)
|
||||
ancestorFqName = ancestorFqName.parent()
|
||||
}
|
||||
}
|
||||
|
||||
val provider = PackageFragmentProviderImpl(packageFragments)
|
||||
|
||||
val notFoundClasses = NotFoundClasses(storageManager, module)
|
||||
@@ -63,7 +76,7 @@ fun createKotlinJavascriptPackageFragmentProvider(
|
||||
platformDependentDeclarationFilter = PlatformDependentDeclarationFilter.NoPlatformDependent
|
||||
)
|
||||
|
||||
for (packageFragment in packageFragments) {
|
||||
for (packageFragment in packageFragments.filterIsInstance<KotlinJavascriptPackageFragment>()) {
|
||||
packageFragment.components = components
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user