Fix missing lookups from deserialized JS descriptors

This commit is contained in:
Alexey Tsvetkov
2017-07-31 22:51:11 +03:00
parent 7e7fcd352c
commit 46a3a59b81
7 changed files with 47 additions and 15 deletions
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.addKotlinSourceRoots import org.jetbrains.kotlin.config.addKotlinSourceRoots
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl 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.analyze.TopDownAnalyzerFacadeForJS
import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.js.config.JsConfig import org.jetbrains.kotlin.js.config.JsConfig
@@ -90,7 +91,7 @@ class KotlinJavascriptSerializerTest : TestCaseWithTmpdir() {
assert(metadata.size == 1) assert(metadata.size == 1)
val provider = KotlinJavascriptSerializationUtil.readModule( 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" } ).data.sure { "No package fragment provider was created" }
module.initialize(provider) module.initialize(provider)
@@ -16,9 +16,12 @@
package org.jetbrains.kotlin.serialization.deserialization.descriptors package org.jetbrains.kotlin.serialization.deserialization.descriptors
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor 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.components.NoLookupLocation
import org.jetbrains.kotlin.incremental.record
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter 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 import org.jetbrains.kotlin.serialization.deserialization.TypeTable
open class DeserializedPackageMemberScope( open class DeserializedPackageMemberScope(
packageDescriptor: PackageFragmentDescriptor, private val packageDescriptor: PackageFragmentDescriptor,
proto: ProtoBuf.Package, proto: ProtoBuf.Package,
nameResolver: NameResolver, nameResolver: NameResolver,
containerSource: DeserializedContainerSource?, containerSource: DeserializedContainerSource?,
@@ -50,6 +53,12 @@ open class DeserializedPackageMemberScope(
override fun createClassId(name: Name) = ClassId(packageFqName, name) 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<Name> = emptySet() override fun getNonDeclaredFunctionNames(): Set<Name> = emptySet()
override fun getNonDeclaredVariableNames(): Set<Name> = emptySet() override fun getNonDeclaredVariableNames(): Set<Name> = emptySet()
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.descriptors.PackagePartProvider
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.frontend.di.createContainerForLazyResolve 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.js.resolve.JsPlatform
import org.jetbrains.kotlin.resolve.BindingTraceContext import org.jetbrains.kotlin.resolve.BindingTraceContext
import org.jetbrains.kotlin.resolve.TargetEnvironment import org.jetbrains.kotlin.resolve.TargetEnvironment
@@ -76,7 +77,8 @@ object JsAnalyzerFacade : AnalyzerFacade() {
.filter { it.version.isCompatible() } .filter { it.version.isCompatible() }
.mapNotNull { .mapNotNull {
KotlinJavascriptSerializationUtil.readModule( KotlinJavascriptSerializationUtil.readModule(
it.body, moduleContext.storageManager, moduleDescriptor, container.get<DeserializationConfiguration>() it.body, moduleContext.storageManager, moduleDescriptor, container.get<DeserializationConfiguration>(),
LookupTracker.DO_NOTHING
).data ).data
} }
@@ -42,12 +42,18 @@ object TopDownAnalyzerFacadeForJS {
val context = ContextForNewModule( val context = ContextForNewModule(
ProjectContext(config.project), Name.special("<${config.moduleId}>"), JsPlatform.builtIns, null 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( context.module.setDependencies(
listOf(context.module) + listOf(context.module) +
config.moduleDescriptors.map { it.data } + config.moduleDescriptors.map { it.data } +
listOf(JsPlatform.builtIns.builtInsModule), listOf(JsPlatform.builtIns.builtInsModule),
config.friendModuleDescriptors.map { it.data }.toSet() config.friendModuleDescriptors.map { it.data }.toSet()
) )
lookupTracker?.let { config.configuration.put(CommonConfigurationKeys.LOOKUP_TRACKER, it) }
val trace = BindingTraceContext() val trace = BindingTraceContext()
trace.record(MODULE_KIND, context.module, config.moduleKind) trace.record(MODULE_KIND, context.module, config.moduleKind)
return analyzeFilesWithGivenTrace(files, trace, context, config) return analyzeFilesWithGivenTrace(files, trace, context, config)
@@ -60,18 +66,20 @@ object TopDownAnalyzerFacadeForJS {
moduleContext: ModuleContext, moduleContext: ModuleContext,
config: JsConfig config: JsConfig
): JsAnalysisResult { ): JsAnalysisResult {
val lookupTracker = config.configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER) ?: LookupTracker.DO_NOTHING
val packageFragment = config.configuration[JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER]?.let { val packageFragment = config.configuration[JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER]?.let {
val metadata = PackagesWithHeaderMetadata(it.headerMetadata, it.packagePartsMetadata) val metadata = PackagesWithHeaderMetadata(it.headerMetadata, it.packagePartsMetadata)
KotlinJavascriptSerializationUtil.readDescriptors(metadata, KotlinJavascriptSerializationUtil.readDescriptors(metadata,
moduleContext.storageManager, moduleContext.storageManager,
moduleContext.module, moduleContext.module,
DeserializationConfiguration.Default) DeserializationConfiguration.Default,
lookupTracker)
} }
val analyzerForJs = createTopDownAnalyzerForJs( val analyzerForJs = createTopDownAnalyzerForJs(
moduleContext, trace, moduleContext, trace,
FileBasedDeclarationProviderFactory(moduleContext.storageManager, files), FileBasedDeclarationProviderFactory(moduleContext.storageManager, files),
config.configuration.languageVersionSettings, config.configuration.languageVersionSettings,
config.configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER) ?: LookupTracker.DO_NOTHING, lookupTracker,
packageFragment packageFragment
) )
analyzerForJs.analyzeDeclarations(TopDownAnalysisMode.TopLevelDeclarations, files) analyzerForJs.analyzeDeclarations(TopDownAnalysisMode.TopLevelDeclarations, files)
@@ -31,6 +31,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.config.*; import org.jetbrains.kotlin.config.*;
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider; import org.jetbrains.kotlin.descriptors.PackageFragmentProvider;
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl; 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.js.resolve.JsPlatform;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration; import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration;
@@ -236,7 +237,8 @@ public class JsConfig {
JsModuleDescriptor<PackageFragmentProvider> rawDescriptor = KotlinJavascriptSerializationUtil.readModuleFromProto( JsModuleDescriptor<PackageFragmentProvider> rawDescriptor = KotlinJavascriptSerializationUtil.readModuleFromProto(
cached, storageManager, moduleDescriptor, cached, storageManager, moduleDescriptor,
new CompilerDeserializationConfiguration(languageVersionSettings) new CompilerDeserializationConfiguration(languageVersionSettings),
LookupTracker.DO_NOTHING.INSTANCE
); );
PackageFragmentProvider provider = rawDescriptor.getData(); PackageFragmentProvider provider = rawDescriptor.getData();
@@ -318,9 +320,11 @@ public class JsConfig {
Name.special("<" + m.getModuleName() + ">"), storageManager, JsPlatform.INSTANCE.getBuiltIns() Name.special("<" + m.getModuleName() + ">"), storageManager, JsPlatform.INSTANCE.getBuiltIns()
); );
LookupTracker lookupTracker = configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER, LookupTracker.DO_NOTHING.INSTANCE);
JsModuleDescriptor<PackageFragmentProvider> rawDescriptor = KotlinJavascriptSerializationUtil.readModule( JsModuleDescriptor<PackageFragmentProvider> rawDescriptor = KotlinJavascriptSerializationUtil.readModule(
m.getBody(), storageManager, moduleDescriptor, m.getBody(), storageManager, moduleDescriptor,
new CompilerDeserializationConfiguration(languageVersionSettings) new CompilerDeserializationConfiguration(languageVersionSettings),
lookupTracker
); );
PackageFragmentProvider provider = rawDescriptor.getData(); PackageFragmentProvider provider = rawDescriptor.getData();
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.serialization.js
import org.jetbrains.kotlin.config.KotlinCompilerVersion import org.jetbrains.kotlin.config.KotlinCompilerVersion
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.protobuf.CodedInputStream import org.jetbrains.kotlin.protobuf.CodedInputStream
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
@@ -43,9 +44,13 @@ object KotlinJavascriptSerializationUtil {
@JvmStatic @JvmStatic
fun readModule( fun readModule(
metadata: ByteArray, storageManager: StorageManager, module: ModuleDescriptor, configuration: DeserializationConfiguration metadata: ByteArray,
storageManager: StorageManager,
module: ModuleDescriptor,
configuration: DeserializationConfiguration,
lookupTracker: LookupTracker
): JsModuleDescriptor<PackageFragmentProvider?> = ): JsModuleDescriptor<PackageFragmentProvider?> =
readModuleFromProto(readModuleAsProto(metadata, module.name.asString()), storageManager, module, configuration) readModuleFromProto(readModuleAsProto(metadata, module.name.asString()), storageManager, module, configuration, lookupTracker)
@JvmStatic @JvmStatic
fun readModuleAsProto(metadata: ByteArray, name: String): JsModuleDescriptor<KotlinJavaScriptLibraryParts> = fun readModuleAsProto(metadata: ByteArray, name: String): JsModuleDescriptor<KotlinJavaScriptLibraryParts> =
@@ -55,11 +60,12 @@ object KotlinJavascriptSerializationUtil {
fun readModuleFromProto( fun readModuleFromProto(
jsModule: JsModuleDescriptor<KotlinJavaScriptLibraryParts>, jsModule: JsModuleDescriptor<KotlinJavaScriptLibraryParts>,
storageManager: StorageManager, module: ModuleDescriptor, storageManager: StorageManager, module: ModuleDescriptor,
configuration: DeserializationConfiguration configuration: DeserializationConfiguration,
lookupTracker: LookupTracker
): JsModuleDescriptor<PackageFragmentProvider?> { ): JsModuleDescriptor<PackageFragmentProvider?> {
val (header, packageFragmentProtos) = jsModule.data val (header, packageFragmentProtos) = jsModule.data
return jsModule.copy(createKotlinJavascriptPackageFragmentProvider( return jsModule.copy(createKotlinJavascriptPackageFragmentProvider(
storageManager, module, header, packageFragmentProtos, configuration storageManager, module, header, packageFragmentProtos, configuration, lookupTracker
)) ))
} }
@@ -67,13 +73,14 @@ object KotlinJavascriptSerializationUtil {
metadata: PackagesWithHeaderMetadata, metadata: PackagesWithHeaderMetadata,
storageManager: StorageManager, storageManager: StorageManager,
module: ModuleDescriptor, module: ModuleDescriptor,
configuration: DeserializationConfiguration configuration: DeserializationConfiguration,
lookupTracker: LookupTracker
): PackageFragmentProvider { ): PackageFragmentProvider {
val scopeProto = metadata.packages.map { val scopeProto = metadata.packages.map {
ProtoBuf.PackageFragment.parseFrom(it, JsSerializerProtocol.extensionRegistry) ProtoBuf.PackageFragment.parseFrom(it, JsSerializerProtocol.extensionRegistry)
} }
val headerProto = JsProtoBuf.Header.parseFrom(CodedInputStream.newInstance(metadata.header), 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( fun serializeMetadata(
@@ -31,7 +31,8 @@ fun createKotlinJavascriptPackageFragmentProvider(
module: ModuleDescriptor, module: ModuleDescriptor,
header: JsProtoBuf.Header, header: JsProtoBuf.Header,
packageFragmentProtos: List<ProtoBuf.PackageFragment>, packageFragmentProtos: List<ProtoBuf.PackageFragment>,
configuration: DeserializationConfiguration configuration: DeserializationConfiguration,
lookupTracker: LookupTracker
): PackageFragmentProvider { ): PackageFragmentProvider {
val packageFragments = packageFragmentProtos.mapNotNull { proto -> val packageFragments = packageFragmentProtos.mapNotNull { proto ->
proto.fqName?.let { fqName -> proto.fqName?.let { fqName ->
@@ -52,7 +53,7 @@ fun createKotlinJavascriptPackageFragmentProvider(
provider, provider,
LocalClassifierTypeSettings.Default, LocalClassifierTypeSettings.Default,
ErrorReporter.DO_NOTHING, ErrorReporter.DO_NOTHING,
LookupTracker.DO_NOTHING, lookupTracker,
DynamicTypeDeserializer, DynamicTypeDeserializer,
emptyList(), emptyList(),
notFoundClasses notFoundClasses