Move package part-related code from LazyJavaPackageScope to LazyJavaPackageFragment

This commit is contained in:
Alexander Udalov
2015-12-22 02:47:26 +03:00
parent e516b695ae
commit a34aaa5955
8 changed files with 64 additions and 108 deletions
@@ -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.JavaCallableMemberDescriptor;
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor; 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.LazyJavaPackageFragment;
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageScope;
import org.jetbrains.kotlin.load.java.typeEnhancement.TypeEnhancementKt; import org.jetbrains.kotlin.load.java.typeEnhancement.TypeEnhancementKt;
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass; import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass;
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryPackageSourceElement; 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.JvmMethodParameterKind;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature; 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.DeserializedType;
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor; import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor; import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor;
@@ -291,12 +288,10 @@ public class KotlinTypeMapper {
String facadeSimpleName; String facadeSimpleName;
MemberScope scope = packageFragmentDescriptor.getMemberScope(); if (packageFragmentDescriptor instanceof LazyJavaPackageFragment) {
if (scope instanceof AbstractScopeAdapter) { facadeSimpleName = ((LazyJavaPackageFragment) packageFragmentDescriptor).getFacadeSimpleNameForPartSimpleName(
scope = ((AbstractScopeAdapter) scope).getActualScope(); implClassName.asString()
} );
if (scope instanceof LazyJavaPackageScope) {
facadeSimpleName = ((LazyJavaPackageScope) scope).getFacadeSimpleNameForPartSimpleName(implClassName.asString());
} }
else if (packageFragmentDescriptor instanceof IncrementalPackageFragmentProvider.IncrementalPackageFragment) { else if (packageFragmentDescriptor instanceof IncrementalPackageFragmentProvider.IncrementalPackageFragment) {
assert incrementalCache != null assert incrementalCache != null
@@ -314,8 +309,8 @@ public class KotlinTypeMapper {
} }
} }
else { else {
throw new AssertionError("Unexpected package member scope for " + descriptor + ": " + throw new AssertionError("Unexpected package fragment for " + descriptor + ": " +
scope + " :" + scope.getClass().getSimpleName()); packageFragmentDescriptor + " (" + packageFragmentDescriptor.getClass().getSimpleName() + ")");
} }
return ContainingClassesInfo.forPackageMemberOrNull(packageFragmentDescriptor.getFqName(), facadeSimpleName, implSimpleName); return ContainingClassesInfo.forPackageMemberOrNull(packageFragmentDescriptor.getFqName(), facadeSimpleName, implSimpleName);
} }
@@ -52,7 +52,7 @@ class LazyJavaPackageFragmentProvider(
override fun getPackageFragments(fqName: FqName) = emptyOrSingletonList(getPackageFragment(fqName)) override fun getPackageFragments(fqName: FqName) = emptyOrSingletonList(getPackageFragment(fqName))
override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean) = 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) fun getClass(javaClass: JavaClass): ClassDescriptor? = c.javaClassResolver.resolveClass(javaClass)
@@ -70,10 +70,7 @@ class LazyJavaPackageFragmentProvider(
if (fqName == null) return null if (fqName == null) return null
val packageFragment = getPackageFragment(fqName.parent()) ?: return null return getPackageFragment(fqName.parent())?.javaScope?.findClassifierByJavaClass(javaClass, NoLookupLocation.FROM_JAVA_LOADER)
return packageFragment
.getMemberScope()
.findClassifierByJavaClass(javaClass, NoLookupLocation.FROM_JAVA_LOADER)
} }
} }
} }
@@ -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.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.structure.JavaPackage import org.jetbrains.kotlin.load.java.structure.JavaPackage
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryPackageSourceElement 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.ClassId
import org.jetbrains.kotlin.name.Name 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 import org.jetbrains.kotlin.storage.getValue
class LazyJavaPackageFragment( class LazyJavaPackageFragment(
private val c: LazyJavaResolverContext, private val c: LazyJavaResolverContext,
private val jPackage: JavaPackage private val jPackage: JavaPackage
) : PackageFragmentDescriptorImpl(c.module, jPackage.fqName) { ) : 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) LazyJavaPackageScope(c, jPackage, this)
} }
internal val kotlinBinaryClasses by c.storageManager.createLazyValue { private val scope by c.storageManager.createLazyValue {
c.components.packageMapper.findPackageParts(fqName.asString()).mapNotNull { ChainedMemberScope.create("Java + Deserialized Kotlin scope", listOf(javaScope) + LazyScopeAdapter(c.storageManager.createLazyValue {
val classId = ClassId(fqName, Name.identifier(it)) ChainedMemberScope.create("Deserialized Kotlin scope", binaryClasses.values.mapNotNull { partClass ->
c.components.kotlinClassFinder.findKotlinClass(classId) c.components.deserializedDescriptorResolver.createKotlinPackagePartScope(this, partClass)
} })
}))
} }
private val partToFacade by c.storageManager.createLazyValue {
val result = hashMapOf<String, String>()
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 getMemberScope() = scope
override fun toString() = "lazy java package fragment: $fqName" override fun toString() = "Lazy Java package fragment: $fqName"
override fun getSource(): SourceElement { override fun getSource(): SourceElement = KotlinJvmBinaryPackageSourceElement(this)
return KotlinJvmBinaryPackageSourceElement(jPackage, kotlinBinaryClasses)
}
} }
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.storage.NullableLazyValue import org.jetbrains.kotlin.storage.NullableLazyValue
import org.jetbrains.kotlin.storage.getValue
class LazyJavaPackageScope( class LazyJavaPackageScope(
c: LazyJavaResolverContext, c: LazyJavaResolverContext,
@@ -47,33 +46,6 @@ class LazyJavaPackageScope(
c.components.finder.knownClassNamesInPackage(ownerDescriptor.fqName) c.components.finder.knownClassNamesInPackage(ownerDescriptor.fqName)
} }
private val partToFacade = c.storageManager.createLazyValue {
val result = hashMapOf<String, String>()
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<FindClassRequest, ClassDescriptor> { request -> private val classes = c.storageManager.createMemoizedFunctionWithNullableValues<FindClassRequest, ClassDescriptor> { request ->
val classId = ClassId(ownerDescriptor.fqName, request.name) val classId = ClassId(ownerDescriptor.fqName, request.name)
@@ -148,23 +120,7 @@ class LazyJavaPackageScope(
fun findClassifierByJavaClass(javaClass: JavaClass, location: LookupLocation) = findClassifier(javaClass.name, javaClass, location) fun findClassifierByJavaClass(javaClass: JavaClass, location: LookupLocation) = findClassifier(javaClass.name, javaClass, location)
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> { override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> = emptyList()
// 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<SimpleFunctionDescriptor> {
// 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<DeclarationDescriptor>,
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean) {
result.addAll(deserializedPackageScope.getContributedDescriptors(kindFilter, nameFilter))
}
override fun computeMemberIndex(): MemberIndex = object : MemberIndex by EMPTY_MEMBER_INDEX { override fun computeMemberIndex(): MemberIndex = object : MemberIndex by EMPTY_MEMBER_INDEX {
// For SAM-constructors // For SAM-constructors
@@ -331,17 +331,9 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
} }
} }
addExtraDescriptors(result, kindFilter, nameFilter)
return result.toReadOnlyList() return result.toReadOnlyList()
} }
protected open fun addExtraDescriptors(result: MutableSet<DeclarationDescriptor>,
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean) {
// Do nothing
}
protected abstract fun getClassNames(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<Name> protected abstract fun getClassNames(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<Name>
override fun toString() = "Lazy scope for ${ownerDescriptor}" override fun toString() = "Lazy scope for ${ownerDescriptor}"
@@ -20,7 +20,6 @@ import com.google.protobuf.InvalidProtocolBufferException
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader 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.resolve.scopes.MemberScope
import org.jetbrains.kotlin.serialization.ClassDataWithSource import org.jetbrains.kotlin.serialization.ClassDataWithSource
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents 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 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 strings = kotlinClass.classHeader.strings.sure { "String table not found in $kotlinClass" }
val (nameResolver, packageProto) = parseProto(kotlinClass) { val (nameResolver, packageProto) = parseProto(kotlinClass) {
@@ -65,19 +64,6 @@ class DeserializedDescriptorResolver(private val errorReporter: ErrorReporter) {
} }
} }
fun createKotlinPackageScope(
descriptor: PackageFragmentDescriptor,
packageParts: List<KotlinJvmBinaryClass>
): 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<KotlinClassHeader.Kind>): Array<String>? { internal fun readData(kotlinClass: KotlinJvmBinaryClass, expectedKinds: Set<KotlinClassHeader.Kind>): Array<String>? {
val header = kotlinClass.classHeader val header = kotlinClass.classHeader
if (!header.metadataVersion.isCompatible()) { if (!header.metadataVersion.isCompatible()) {
@@ -19,30 +19,22 @@ package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.SourceFile import org.jetbrains.kotlin.descriptors.SourceFile
import org.jetbrains.kotlin.load.java.descriptors.getImplClassNameForDeserialized 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 import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
class KotlinJvmBinaryPackageSourceElement( class KotlinJvmBinaryPackageSourceElement(
private val jPackage: JavaPackage, private val packageFragment: LazyJavaPackageFragment
kotlinBinaryClasses: List<KotlinJvmBinaryClass>
) : SourceElement { ) : SourceElement {
private val implClassNameToBinaryClass = run { override fun toString() = "$packageFragment: ${packageFragment.binaryClasses.keys}"
val result = hashMapOf<String, KotlinJvmBinaryClass>()
for (kotlinBinaryClass in kotlinBinaryClasses) {
result[kotlinBinaryClass.classId.shortClassName.asString()] = kotlinBinaryClass
}
result
}
override fun toString(): String = "Binary package ${jPackage.fqName}: ${implClassNameToBinaryClass.keys}"
override fun getContainingFile(): SourceFile = SourceFile.NO_SOURCE_FILE override fun getContainingFile(): SourceFile = SourceFile.NO_SOURCE_FILE
fun getRepresentativeBinaryClass(): KotlinJvmBinaryClass { fun getRepresentativeBinaryClass(): KotlinJvmBinaryClass {
return implClassNameToBinaryClass.values.first() return packageFragment.binaryClasses.values.first()
} }
fun getContainingBinaryClass(descriptor: DeserializedCallableMemberDescriptor): KotlinJvmBinaryClass? { fun getContainingBinaryClass(descriptor: DeserializedCallableMemberDescriptor): KotlinJvmBinaryClass? {
val name = descriptor.getImplClassNameForDeserialized() ?: return null val name = descriptor.getImplClassNameForDeserialized() ?: return null
return implClassNameToBinaryClass[name.asString()] return packageFragment.binaryClasses[name.asString()]
} }
} }
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.resolve.scopes package org.jetbrains.kotlin.resolve.scopes
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.LookupLocation
@@ -55,4 +54,14 @@ class ChainedMemberScope(
p.popIndent() p.popIndent()
p.println("}") p.println("}")
} }
companion object {
fun create(debugName: String, scopes: List<MemberScope>): MemberScope {
return when (scopes.size) {
0 -> MemberScope.Empty
1 -> scopes.single()
else -> ChainedMemberScope(debugName, scopes)
}
}
}
} }