From 46a3a59b81843ba1ffed37b141ec84b2c389dedb Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Mon, 31 Jul 2017 22:51:11 +0300 Subject: [PATCH] Fix missing lookups from deserialized JS descriptors --- .../js/KotlinJavascriptSerializerTest.kt | 3 ++- .../DeserializedPackageMemberScope.kt | 11 ++++++++++- .../kotlin/caches/resolve/JsAnalyzerFacade.kt | 4 +++- .../js/analyze/TopDownAnalyzerFacadeForJS.kt | 12 ++++++++++-- .../jetbrains/kotlin/js/config/JsConfig.java | 8 ++++++-- .../js/KotlinJavascriptSerializationUtil.kt | 19 +++++++++++++------ ...kotlinJavascriptPackageFragmentProvider.kt | 5 +++-- 7 files changed, 47 insertions(+), 15 deletions(-) diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerTest.kt b/compiler/tests/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerTest.kt index 9f6568e515b..e7330ba6eaa 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerTest.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.addKotlinSourceRoots import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl +import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.js.config.JsConfig @@ -90,7 +91,7 @@ class KotlinJavascriptSerializerTest : TestCaseWithTmpdir() { assert(metadata.size == 1) val provider = KotlinJavascriptSerializationUtil.readModule( - metadata.single().body, LockBasedStorageManager(), module, DeserializationConfiguration.Default + metadata.single().body, LockBasedStorageManager(), module, DeserializationConfiguration.Default, LookupTracker.DO_NOTHING ).data.sure { "No package fragment provider was created" } module.initialize(provider) diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedPackageMemberScope.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedPackageMemberScope.kt index 9202813536b..bc9b7bef674 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedPackageMemberScope.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedPackageMemberScope.kt @@ -16,9 +16,12 @@ package org.jetbrains.kotlin.serialization.deserialization.descriptors +import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor +import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation +import org.jetbrains.kotlin.incremental.record import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter @@ -28,7 +31,7 @@ import org.jetbrains.kotlin.serialization.deserialization.NameResolver import org.jetbrains.kotlin.serialization.deserialization.TypeTable open class DeserializedPackageMemberScope( - packageDescriptor: PackageFragmentDescriptor, + private val packageDescriptor: PackageFragmentDescriptor, proto: ProtoBuf.Package, nameResolver: NameResolver, containerSource: DeserializedContainerSource?, @@ -50,6 +53,12 @@ open class DeserializedPackageMemberScope( override fun createClassId(name: Name) = ClassId(packageFqName, name) + + override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? { + c.components.lookupTracker.record(location, packageDescriptor, name) + return super.getContributedClassifier(name, location) + } + override fun getNonDeclaredFunctionNames(): Set = emptySet() override fun getNonDeclaredVariableNames(): Set = emptySet() diff --git a/idea/ide-common/src/org/jetbrains/kotlin/caches/resolve/JsAnalyzerFacade.kt b/idea/ide-common/src/org/jetbrains/kotlin/caches/resolve/JsAnalyzerFacade.kt index 76ec714bb2e..b3c8ab5b18a 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/caches/resolve/JsAnalyzerFacade.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/caches/resolve/JsAnalyzerFacade.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.descriptors.PackagePartProvider import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.frontend.di.createContainerForLazyResolve +import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.js.resolve.JsPlatform import org.jetbrains.kotlin.resolve.BindingTraceContext import org.jetbrains.kotlin.resolve.TargetEnvironment @@ -76,7 +77,8 @@ object JsAnalyzerFacade : AnalyzerFacade() { .filter { it.version.isCompatible() } .mapNotNull { KotlinJavascriptSerializationUtil.readModule( - it.body, moduleContext.storageManager, moduleDescriptor, container.get() + it.body, moduleContext.storageManager, moduleDescriptor, container.get(), + LookupTracker.DO_NOTHING ).data } diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt index fc375e0487e..cb7ae3275d5 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt @@ -42,12 +42,18 @@ object TopDownAnalyzerFacadeForJS { val context = ContextForNewModule( ProjectContext(config.project), Name.special("<${config.moduleId}>"), JsPlatform.builtIns, null ) + + // a hack to avoid adding lookups for builtins + val lookupTracker = config.configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER) + config.configuration.put(CommonConfigurationKeys.LOOKUP_TRACKER, LookupTracker.DO_NOTHING) context.module.setDependencies( listOf(context.module) + config.moduleDescriptors.map { it.data } + listOf(JsPlatform.builtIns.builtInsModule), config.friendModuleDescriptors.map { it.data }.toSet() ) + lookupTracker?.let { config.configuration.put(CommonConfigurationKeys.LOOKUP_TRACKER, it) } + val trace = BindingTraceContext() trace.record(MODULE_KIND, context.module, config.moduleKind) return analyzeFilesWithGivenTrace(files, trace, context, config) @@ -60,18 +66,20 @@ object TopDownAnalyzerFacadeForJS { moduleContext: ModuleContext, config: JsConfig ): JsAnalysisResult { + val lookupTracker = config.configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER) ?: LookupTracker.DO_NOTHING val packageFragment = config.configuration[JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER]?.let { val metadata = PackagesWithHeaderMetadata(it.headerMetadata, it.packagePartsMetadata) KotlinJavascriptSerializationUtil.readDescriptors(metadata, moduleContext.storageManager, moduleContext.module, - DeserializationConfiguration.Default) + DeserializationConfiguration.Default, + lookupTracker) } val analyzerForJs = createTopDownAnalyzerForJs( moduleContext, trace, FileBasedDeclarationProviderFactory(moduleContext.storageManager, files), config.configuration.languageVersionSettings, - config.configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER) ?: LookupTracker.DO_NOTHING, + lookupTracker, packageFragment ) analyzerForJs.analyzeDeclarations(TopDownAnalysisMode.TopLevelDeclarations, files) diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/config/JsConfig.java b/js/js.frontend/src/org/jetbrains/kotlin/js/config/JsConfig.java index 558a524712e..fed0a6f36b5 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/config/JsConfig.java +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/config/JsConfig.java @@ -31,6 +31,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.config.*; import org.jetbrains.kotlin.descriptors.PackageFragmentProvider; import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl; +import org.jetbrains.kotlin.incremental.components.LookupTracker; import org.jetbrains.kotlin.js.resolve.JsPlatform; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration; @@ -236,7 +237,8 @@ public class JsConfig { JsModuleDescriptor rawDescriptor = KotlinJavascriptSerializationUtil.readModuleFromProto( cached, storageManager, moduleDescriptor, - new CompilerDeserializationConfiguration(languageVersionSettings) + new CompilerDeserializationConfiguration(languageVersionSettings), + LookupTracker.DO_NOTHING.INSTANCE ); PackageFragmentProvider provider = rawDescriptor.getData(); @@ -318,9 +320,11 @@ public class JsConfig { Name.special("<" + m.getModuleName() + ">"), storageManager, JsPlatform.INSTANCE.getBuiltIns() ); + LookupTracker lookupTracker = configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER, LookupTracker.DO_NOTHING.INSTANCE); JsModuleDescriptor rawDescriptor = KotlinJavascriptSerializationUtil.readModule( m.getBody(), storageManager, moduleDescriptor, - new CompilerDeserializationConfiguration(languageVersionSettings) + new CompilerDeserializationConfiguration(languageVersionSettings), + lookupTracker ); PackageFragmentProvider provider = rawDescriptor.getData(); diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt index ec5bed545fd..25874d3f6a6 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.serialization.js import org.jetbrains.kotlin.config.KotlinCompilerVersion import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.protobuf.CodedInputStream import org.jetbrains.kotlin.resolve.BindingContext @@ -43,9 +44,13 @@ object KotlinJavascriptSerializationUtil { @JvmStatic fun readModule( - metadata: ByteArray, storageManager: StorageManager, module: ModuleDescriptor, configuration: DeserializationConfiguration + metadata: ByteArray, + storageManager: StorageManager, + module: ModuleDescriptor, + configuration: DeserializationConfiguration, + lookupTracker: LookupTracker ): JsModuleDescriptor = - readModuleFromProto(readModuleAsProto(metadata, module.name.asString()), storageManager, module, configuration) + readModuleFromProto(readModuleAsProto(metadata, module.name.asString()), storageManager, module, configuration, lookupTracker) @JvmStatic fun readModuleAsProto(metadata: ByteArray, name: String): JsModuleDescriptor = @@ -55,11 +60,12 @@ object KotlinJavascriptSerializationUtil { fun readModuleFromProto( jsModule: JsModuleDescriptor, storageManager: StorageManager, module: ModuleDescriptor, - configuration: DeserializationConfiguration + configuration: DeserializationConfiguration, + lookupTracker: LookupTracker ): JsModuleDescriptor { val (header, packageFragmentProtos) = jsModule.data return jsModule.copy(createKotlinJavascriptPackageFragmentProvider( - storageManager, module, header, packageFragmentProtos, configuration + storageManager, module, header, packageFragmentProtos, configuration, lookupTracker )) } @@ -67,13 +73,14 @@ object KotlinJavascriptSerializationUtil { metadata: PackagesWithHeaderMetadata, storageManager: StorageManager, module: ModuleDescriptor, - configuration: DeserializationConfiguration + configuration: DeserializationConfiguration, + lookupTracker: LookupTracker ): PackageFragmentProvider { val scopeProto = metadata.packages.map { ProtoBuf.PackageFragment.parseFrom(it, JsSerializerProtocol.extensionRegistry) } val headerProto = JsProtoBuf.Header.parseFrom(CodedInputStream.newInstance(metadata.header), JsSerializerProtocol.extensionRegistry) - return createKotlinJavascriptPackageFragmentProvider(storageManager, module, headerProto, scopeProto, configuration) + return createKotlinJavascriptPackageFragmentProvider(storageManager, module, headerProto, scopeProto, configuration, lookupTracker) } fun serializeMetadata( diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt index d183ec34667..b950344cb27 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt @@ -31,7 +31,8 @@ fun createKotlinJavascriptPackageFragmentProvider( module: ModuleDescriptor, header: JsProtoBuf.Header, packageFragmentProtos: List, - configuration: DeserializationConfiguration + configuration: DeserializationConfiguration, + lookupTracker: LookupTracker ): PackageFragmentProvider { val packageFragments = packageFragmentProtos.mapNotNull { proto -> proto.fqName?.let { fqName -> @@ -52,7 +53,7 @@ fun createKotlinJavascriptPackageFragmentProvider( provider, LocalClassifierTypeSettings.Default, ErrorReporter.DO_NOTHING, - LookupTracker.DO_NOTHING, + lookupTracker, DynamicTypeDeserializer, emptyList(), notFoundClasses