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