diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java index 178d67823d1..b8ace4a6b45 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java @@ -45,7 +45,6 @@ import org.jetbrains.kotlin.load.java.SpecialBuiltinMembers; import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor; import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment; -import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageScope; import org.jetbrains.kotlin.load.java.typeEnhancement.TypeEnhancementKt; import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass; import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryPackageSourceElement; @@ -71,8 +70,6 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature; -import org.jetbrains.kotlin.resolve.scopes.AbstractScopeAdapter; -import org.jetbrains.kotlin.resolve.scopes.MemberScope; import org.jetbrains.kotlin.serialization.deserialization.DeserializedType; import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor; import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor; @@ -291,12 +288,10 @@ public class KotlinTypeMapper { String facadeSimpleName; - MemberScope scope = packageFragmentDescriptor.getMemberScope(); - if (scope instanceof AbstractScopeAdapter) { - scope = ((AbstractScopeAdapter) scope).getActualScope(); - } - if (scope instanceof LazyJavaPackageScope) { - facadeSimpleName = ((LazyJavaPackageScope) scope).getFacadeSimpleNameForPartSimpleName(implClassName.asString()); + if (packageFragmentDescriptor instanceof LazyJavaPackageFragment) { + facadeSimpleName = ((LazyJavaPackageFragment) packageFragmentDescriptor).getFacadeSimpleNameForPartSimpleName( + implClassName.asString() + ); } else if (packageFragmentDescriptor instanceof IncrementalPackageFragmentProvider.IncrementalPackageFragment) { assert incrementalCache != null @@ -314,8 +309,8 @@ public class KotlinTypeMapper { } } else { - throw new AssertionError("Unexpected package member scope for " + descriptor + ": " + - scope + " :" + scope.getClass().getSimpleName()); + throw new AssertionError("Unexpected package fragment for " + descriptor + ": " + + packageFragmentDescriptor + " (" + packageFragmentDescriptor.getClass().getSimpleName() + ")"); } return ContainingClassesInfo.forPackageMemberOrNull(packageFragmentDescriptor.getFqName(), facadeSimpleName, implSimpleName); } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/LazyJavaPackageFragmentProvider.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/LazyJavaPackageFragmentProvider.kt index 92c06d883c3..dbbf9368067 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/LazyJavaPackageFragmentProvider.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/LazyJavaPackageFragmentProvider.kt @@ -52,7 +52,7 @@ class LazyJavaPackageFragmentProvider( override fun getPackageFragments(fqName: FqName) = emptyOrSingletonList(getPackageFragment(fqName)) override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean) = - getPackageFragment(fqName)?.getMemberScope()?.getSubPackages().orEmpty() + getPackageFragment(fqName)?.javaScope?.getSubPackages().orEmpty() fun getClass(javaClass: JavaClass): ClassDescriptor? = c.javaClassResolver.resolveClass(javaClass) @@ -70,10 +70,7 @@ class LazyJavaPackageFragmentProvider( if (fqName == null) return null - val packageFragment = getPackageFragment(fqName.parent()) ?: return null - return packageFragment - .getMemberScope() - .findClassifierByJavaClass(javaClass, NoLookupLocation.FROM_JAVA_LOADER) + return getPackageFragment(fqName.parent())?.javaScope?.findClassifierByJavaClass(javaClass, NoLookupLocation.FROM_JAVA_LOADER) } } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageFragment.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageFragment.kt index 51abc9a0671..0fef0d26aed 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageFragment.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageFragment.kt @@ -21,30 +21,59 @@ import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext import org.jetbrains.kotlin.load.java.structure.JavaPackage import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryPackageSourceElement +import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.scopes.ChainedMemberScope +import org.jetbrains.kotlin.resolve.scopes.LazyScopeAdapter import org.jetbrains.kotlin.storage.getValue class LazyJavaPackageFragment( private val c: LazyJavaResolverContext, private val jPackage: JavaPackage ) : PackageFragmentDescriptorImpl(c.module, jPackage.fqName) { - private val scope by c.storageManager.createLazyValue { + internal val binaryClasses by c.storageManager.createLazyValue { + c.components.packageMapper.findPackageParts(fqName.asString()).mapNotNull { partName -> + val classId = ClassId(fqName, Name.identifier(partName)) + c.components.kotlinClassFinder.findKotlinClass(classId)?.let { partName to it } + }.toMap() + } + + internal val javaScope by c.storageManager.createLazyValue { LazyJavaPackageScope(c, jPackage, this) } - internal val kotlinBinaryClasses by c.storageManager.createLazyValue { - c.components.packageMapper.findPackageParts(fqName.asString()).mapNotNull { - val classId = ClassId(fqName, Name.identifier(it)) - c.components.kotlinClassFinder.findKotlinClass(classId) - } + private val scope by c.storageManager.createLazyValue { + ChainedMemberScope.create("Java + Deserialized Kotlin scope", listOf(javaScope) + LazyScopeAdapter(c.storageManager.createLazyValue { + ChainedMemberScope.create("Deserialized Kotlin scope", binaryClasses.values.mapNotNull { partClass -> + c.components.deserializedDescriptorResolver.createKotlinPackagePartScope(this, partClass) + }) + })) } + private val partToFacade by c.storageManager.createLazyValue { + val result = hashMapOf() + kotlinClasses@for ((partName, kotlinClass) in binaryClasses) { + val header = kotlinClass.classHeader + when (header.kind) { + KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> { + val facadeName = header.multifileClassName ?: continue@kotlinClasses + result[partName] = facadeName.substringAfterLast('/') + } + KotlinClassHeader.Kind.FILE_FACADE -> { + result[partName] = partName + } + else -> {} + } + } + result + } + + fun getFacadeSimpleNameForPartSimpleName(partName: String): String? = partToFacade[partName] + override fun getMemberScope() = scope - override fun toString() = "lazy java package fragment: $fqName" + override fun toString() = "Lazy Java package fragment: $fqName" - override fun getSource(): SourceElement { - return KotlinJvmBinaryPackageSourceElement(jPackage, kotlinBinaryClasses) - } + override fun getSource(): SourceElement = KotlinJvmBinaryPackageSourceElement(this) } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageScope.kt index 44f41d965bc..04101801a9c 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageScope.kt @@ -33,7 +33,6 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.storage.NullableLazyValue -import org.jetbrains.kotlin.storage.getValue class LazyJavaPackageScope( c: LazyJavaResolverContext, @@ -47,33 +46,6 @@ class LazyJavaPackageScope( c.components.finder.knownClassNamesInPackage(ownerDescriptor.fqName) } - private val partToFacade = c.storageManager.createLazyValue { - val result = hashMapOf() - kotlinClasses@for (kotlinClass in ownerDescriptor.kotlinBinaryClasses) { - val header = kotlinClass.classHeader - when (header.kind) { - KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> { - val partName = kotlinClass.classId.shortClassName.asString() - val facadeName = header.multifileClassName ?: continue@kotlinClasses - result[partName] = facadeName.substringAfterLast('/') - } - KotlinClassHeader.Kind.FILE_FACADE -> { - val fileFacadeName = kotlinClass.classId.shortClassName.asString() - result[fileFacadeName] = fileFacadeName - } - else -> {} - } - } - result - } - - fun getFacadeSimpleNameForPartSimpleName(partName: String): String? = - partToFacade()[partName] - - private val deserializedPackageScope by c.storageManager.createLazyValue { - c.components.deserializedDescriptorResolver.createKotlinPackageScope(ownerDescriptor, ownerDescriptor.kotlinBinaryClasses) - } - private val classes = c.storageManager.createMemoizedFunctionWithNullableValues { request -> val classId = ClassId(ownerDescriptor.fqName, request.name) @@ -148,23 +120,7 @@ class LazyJavaPackageScope( fun findClassifierByJavaClass(javaClass: JavaClass, location: LookupLocation) = findClassifier(javaClass.name, javaClass, location) - override fun getContributedVariables(name: Name, location: LookupLocation): Collection { - // We should track lookups here because this scope can be used for kotlin packages too (if it doesn't contain toplevel properties nor functions). - recordLookup(name, location) - return deserializedPackageScope.getContributedVariables(name, NoLookupLocation.FOR_ALREADY_TRACKED) - } - - override fun getContributedFunctions(name: Name, location: LookupLocation): List { - // We should track lookups here because this scope can be used for kotlin packages too (if it doesn't contain toplevel properties nor functions). - recordLookup(name, location) - return deserializedPackageScope.getContributedFunctions(name, NoLookupLocation.FOR_ALREADY_TRACKED) + super.getContributedFunctions(name, NoLookupLocation.FOR_ALREADY_TRACKED) - } - - override fun addExtraDescriptors(result: MutableSet, - kindFilter: DescriptorKindFilter, - nameFilter: (Name) -> Boolean) { - result.addAll(deserializedPackageScope.getContributedDescriptors(kindFilter, nameFilter)) - } + override fun getContributedVariables(name: Name, location: LookupLocation): Collection = emptyList() override fun computeMemberIndex(): MemberIndex = object : MemberIndex by EMPTY_MEMBER_INDEX { // For SAM-constructors diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt index 8946e244ee0..4a8388f616b 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt @@ -331,17 +331,9 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS } } - addExtraDescriptors(result, kindFilter, nameFilter) - return result.toReadOnlyList() } - protected open fun addExtraDescriptors(result: MutableSet, - kindFilter: DescriptorKindFilter, - nameFilter: (Name) -> Boolean) { - // Do nothing - } - protected abstract fun getClassNames(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection override fun toString() = "Lazy scope for ${ownerDescriptor}" diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/DeserializedDescriptorResolver.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/DeserializedDescriptorResolver.kt index aaab6f67988..d9888ea85c5 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/DeserializedDescriptorResolver.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/DeserializedDescriptorResolver.kt @@ -20,7 +20,6 @@ import com.google.protobuf.InvalidProtocolBufferException import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader -import org.jetbrains.kotlin.resolve.scopes.ChainedMemberScope import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.serialization.ClassDataWithSource import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents @@ -52,7 +51,7 @@ class DeserializedDescriptorResolver(private val errorReporter: ErrorReporter) { ) } - private fun createKotlinPackagePartScope(descriptor: PackageFragmentDescriptor, kotlinClass: KotlinJvmBinaryClass): MemberScope? { + fun createKotlinPackagePartScope(descriptor: PackageFragmentDescriptor, kotlinClass: KotlinJvmBinaryClass): MemberScope? { val data = readData(kotlinClass, KOTLIN_FILE_FACADE_OR_MULTIFILE_CLASS_PART) ?: return null val strings = kotlinClass.classHeader.strings.sure { "String table not found in $kotlinClass" } val (nameResolver, packageProto) = parseProto(kotlinClass) { @@ -65,19 +64,6 @@ class DeserializedDescriptorResolver(private val errorReporter: ErrorReporter) { } } - fun createKotlinPackageScope( - descriptor: PackageFragmentDescriptor, - packageParts: List - ): MemberScope { - val scopes = packageParts.mapNotNull { callable -> - createKotlinPackagePartScope(descriptor, callable) - } - if (scopes.isEmpty()) { - return MemberScope.Empty - } - return ChainedMemberScope("Member scope for union of package parts data", scopes) - } - internal fun readData(kotlinClass: KotlinJvmBinaryClass, expectedKinds: Set): Array? { val header = kotlinClass.classHeader if (!header.metadataVersion.isCompatible()) { diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/KotlinJvmBinaryPackageSourceElement.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/KotlinJvmBinaryPackageSourceElement.kt index 77e428de5bb..3fc9f502b7e 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/KotlinJvmBinaryPackageSourceElement.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/KotlinJvmBinaryPackageSourceElement.kt @@ -19,30 +19,22 @@ package org.jetbrains.kotlin.load.kotlin import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.descriptors.SourceFile import org.jetbrains.kotlin.load.java.descriptors.getImplClassNameForDeserialized -import org.jetbrains.kotlin.load.java.structure.JavaPackage +import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor class KotlinJvmBinaryPackageSourceElement( - private val jPackage: JavaPackage, - kotlinBinaryClasses: List + private val packageFragment: LazyJavaPackageFragment ) : SourceElement { - private val implClassNameToBinaryClass = run { - val result = hashMapOf() - for (kotlinBinaryClass in kotlinBinaryClasses) { - result[kotlinBinaryClass.classId.shortClassName.asString()] = kotlinBinaryClass - } - result - } + override fun toString() = "$packageFragment: ${packageFragment.binaryClasses.keys}" - override fun toString(): String = "Binary package ${jPackage.fqName}: ${implClassNameToBinaryClass.keys}" override fun getContainingFile(): SourceFile = SourceFile.NO_SOURCE_FILE fun getRepresentativeBinaryClass(): KotlinJvmBinaryClass { - return implClassNameToBinaryClass.values.first() + return packageFragment.binaryClasses.values.first() } fun getContainingBinaryClass(descriptor: DeserializedCallableMemberDescriptor): KotlinJvmBinaryClass? { val name = descriptor.getImplClassNameForDeserialized() ?: return null - return implClassNameToBinaryClass[name.asString()] + return packageFragment.binaryClasses[name.asString()] } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ChainedMemberScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ChainedMemberScope.kt index 47642a9bc44..7e6f21dcedd 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ChainedMemberScope.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ChainedMemberScope.kt @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.resolve.scopes import org.jetbrains.kotlin.descriptors.ClassifierDescriptor -import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.incremental.components.LookupLocation @@ -55,4 +54,14 @@ class ChainedMemberScope( p.popIndent() p.println("}") } + + companion object { + fun create(debugName: String, scopes: List): MemberScope { + return when (scopes.size) { + 0 -> MemberScope.Empty + 1 -> scopes.single() + else -> ChainedMemberScope(debugName, scopes) + } + } + } }