Don't cache nulls for invalid names in Java resolve
This commit is contained in:
+14
-26
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassDescriptor
|
||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -47,17 +46,6 @@ public class LazyJavaPackageFragmentProvider(
|
||||
else null
|
||||
}
|
||||
|
||||
private val topLevelClasses = c.storageManager.createMemoizedFunctionWithNullableValues lambda@ {
|
||||
jClass: JavaClass ->
|
||||
val fqName = jClass.getFqName()
|
||||
if (fqName == null) return@lambda null
|
||||
|
||||
val packageFragment = getPackageFragment(fqName.parent())
|
||||
if (packageFragment == null) return@lambda null
|
||||
|
||||
LazyJavaClassDescriptor(c, packageFragment, fqName, jClass)
|
||||
}
|
||||
|
||||
private fun getPackageFragment(fqName: FqName) = packageFragments(fqName)
|
||||
|
||||
override fun getPackageFragments(fqName: FqName) = emptyOrSingletonList(getPackageFragment(fqName))
|
||||
@@ -69,22 +57,22 @@ public class LazyJavaPackageFragmentProvider(
|
||||
|
||||
private inner class FragmentClassResolver : LazyJavaClassResolver {
|
||||
override fun resolveClass(javaClass: JavaClass): ClassDescriptor? {
|
||||
val fqName = javaClass.getFqName()
|
||||
if (fqName != null) {
|
||||
if (javaClass.getOriginKind() == JavaClass.OriginKind.KOTLIN_LIGHT_CLASS) {
|
||||
return c.javaResolverCache.getClassResolvedFromSource(fqName)
|
||||
}
|
||||
val fqName = javaClass.fqName
|
||||
if (fqName != null && javaClass.originKind == JavaClass.OriginKind.KOTLIN_LIGHT_CLASS) {
|
||||
return c.javaResolverCache.getClassResolvedFromSource(fqName)
|
||||
}
|
||||
val outerClass = javaClass.getOuterClass()
|
||||
if (outerClass == null) {
|
||||
val kotlinResult = c.resolveKotlinBinaryClass(c.kotlinClassFinder.findKotlinClass(javaClass))
|
||||
return when (kotlinResult) {
|
||||
is KotlinClassLookupResult.Found -> kotlinResult.descriptor
|
||||
else -> topLevelClasses(javaClass)
|
||||
}
|
||||
|
||||
javaClass.outerClass?.let { outerClass ->
|
||||
val outerClassScope = resolveClass(outerClass)?.unsubstitutedInnerClassesScope
|
||||
return outerClassScope?.getClassifier(javaClass.name) as? ClassDescriptor
|
||||
}
|
||||
val outerClassScope = resolveClass(outerClass)?.getUnsubstitutedInnerClassesScope()
|
||||
return outerClassScope?.getClassifier(javaClass.getName()) as? ClassDescriptor
|
||||
|
||||
val kotlinResult = c.resolveKotlinBinaryClass(c.kotlinClassFinder.findKotlinClass(javaClass))
|
||||
if (kotlinResult is KotlinClassLookupResult.Found) return kotlinResult.descriptor
|
||||
|
||||
if (fqName == null) return null
|
||||
|
||||
return getPackageFragment(fqName.parent())?.resolveTopLevelClass(javaClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.load.java.lazy.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
|
||||
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaPackage
|
||||
|
||||
class LazyJavaPackageFragment(
|
||||
@@ -26,6 +27,13 @@ class LazyJavaPackageFragment(
|
||||
) : PackageFragmentDescriptorImpl(c.module, jPackage.getFqName()) {
|
||||
private val scope by lazy { LazyPackageFragmentScopeForJavaPackage(c, jPackage, this) }
|
||||
|
||||
private val topLevelClasses = c.storageManager.createMemoizedFunctionWithNullableValues {
|
||||
javaClass: JavaClass ->
|
||||
LazyJavaClassDescriptor(c, this, javaClass.fqName!!, javaClass)
|
||||
}
|
||||
|
||||
internal fun resolveTopLevelClass(javaClass: JavaClass) = topLevelClasses(javaClass)
|
||||
|
||||
override fun getMemberScope() = scope
|
||||
|
||||
override fun toString() = "lazy java package fragment: $fqName"
|
||||
|
||||
+12
-14
@@ -57,29 +57,27 @@ public class LazyPackageFragmentScopeForJavaPackage(
|
||||
|
||||
private val packageFragment: LazyJavaPackageFragment get() = getContainingDeclaration() as LazyJavaPackageFragment
|
||||
|
||||
private val classes = c.storageManager.createMemoizedFunctionWithNullableValues<Name, ClassDescriptor> { name -> findClass(name) }
|
||||
|
||||
private fun findClass(name: Name): ClassDescriptor? {
|
||||
if (!SpecialNames.isSafeIdentifier(name)) return null
|
||||
|
||||
private val classes = c.storageManager.createMemoizedFunctionWithNullableValues<Name, ClassDescriptor> { name ->
|
||||
val classId = ClassId(packageFragment.fqName, name)
|
||||
|
||||
val kotlinResult = c.resolveKotlinBinaryClass(c.kotlinClassFinder.findKotlinClass(classId))
|
||||
return when (kotlinResult) {
|
||||
when (kotlinResult) {
|
||||
is KotlinClassLookupResult.Found -> kotlinResult.descriptor
|
||||
is KotlinClassLookupResult.SyntheticClass -> null
|
||||
is KotlinClassLookupResult.NotFound -> {
|
||||
val javaClass = c.finder.findClass(classId) ?: return null
|
||||
val classDescriptor = c.javaClassResolver.resolveClass(javaClass)
|
||||
assert(classDescriptor == null || classDescriptor.containingDeclaration == packageFragment) {
|
||||
"Wrong package fragment for $classDescriptor, expected $packageFragment"
|
||||
c.finder.findClass(classId)?.let { javaClass ->
|
||||
c.javaClassResolver.resolveClass(javaClass).apply {
|
||||
assert(this == null || this.containingDeclaration == packageFragment) {
|
||||
"Wrong package fragment for $this, expected $packageFragment"
|
||||
}
|
||||
}
|
||||
}
|
||||
return classDescriptor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getClassifier(name: Name, location: UsageLocation): ClassifierDescriptor? = classes(name)
|
||||
override fun getClassifier(name: Name, location: UsageLocation): ClassifierDescriptor? =
|
||||
if (SpecialNames.isSafeIdentifier(name)) classes(name) else null
|
||||
|
||||
override fun getProperties(name: Name, location: UsageLocation) = deserializedPackageScope().getProperties(name, location)
|
||||
override fun getFunctions(name: Name, location: UsageLocation) = deserializedPackageScope().getFunctions(name, location) + super.getFunctions(name, location)
|
||||
@@ -100,8 +98,8 @@ public class LazyPackageFragmentScopeForJavaPackage(
|
||||
if (!kindFilter.acceptsKinds(DescriptorKindFilter.NON_SINGLETON_CLASSIFIERS_MASK)) return listOf()
|
||||
|
||||
return jPackage.getClasses(nameFilter).asSequence()
|
||||
.filter { c -> c.getOriginKind() != JavaClass.OriginKind.KOTLIN_LIGHT_CLASS }
|
||||
.map { c -> c.getName() }.toList()
|
||||
.filter { c -> c.originKind != JavaClass.OriginKind.KOTLIN_LIGHT_CLASS }
|
||||
.map { c -> c.name }.toList()
|
||||
}
|
||||
|
||||
override fun getFunctionNames(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<Name> {
|
||||
|
||||
Reference in New Issue
Block a user