From 87750d633cfb070c86ab6ee9dec790e823146689 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 13 May 2014 14:40:00 +0400 Subject: [PATCH] JavaDescriptorResolver supports resolving classes by PSI elements, not by FqNames --- .../resolve/java/JavaDescriptorResolver.java | 6 ++++ .../lazy/LazyJavaPackageFragmentProvider.kt | 36 +++++++++++++------ .../LazyJavaPackageFragmentScope.kt | 8 +++-- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 9d44efda178..891909f1acc 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -23,6 +23,7 @@ import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor; import org.jetbrains.jet.lang.descriptors.PackageFragmentProvider; import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaPackageFragmentProvider; +import org.jetbrains.jet.lang.resolve.java.structure.JavaClass; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolver; @@ -55,6 +56,11 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes return lazyJavaPackageFragmentProvider.getClass(qualifiedName); } + @Nullable + public ClassDescriptor resolveClass(@NotNull JavaClass javaClass) { + return lazyJavaPackageFragmentProvider.getClass(javaClass); + } + @Nullable public PackageFragmentDescriptor getPackageFragment(@NotNull FqName fqName) { return lazyJavaPackageFragmentProvider.getPackageFragment(fqName); diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/LazyJavaPackageFragmentProvider.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/LazyJavaPackageFragmentProvider.kt index 7989dce0d7f..12e47514418 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/LazyJavaPackageFragmentProvider.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/LazyJavaPackageFragmentProvider.kt @@ -27,7 +27,9 @@ import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils import org.jetbrains.jet.lang.resolve.java.resolver.JavaPackageFragmentProvider import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaPackageFragment import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass -import org.jetbrains.jet.lang.resolve.scopes.JetScope +import org.jetbrains.jet.storage.MemoizedFunctionToNotNull +import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaClassDescriptor +import org.jetbrains.kotlin.util.sure public class LazyJavaPackageFragmentProvider( outerContext: GlobalJavaResolverContext, @@ -67,6 +69,22 @@ public class LazyJavaPackageFragmentProvider( } } + private val topLevelClasses = c.storageManager.createMemoizedFunctionWithNullableValues @lambda { + (jClass: JavaClass): LazyJavaClassDescriptor? -> + val fqName = jClass.getFqName() + if (fqName == null) return@lambda null + + val packageFragment = getPackageFragment(fqName.parent()) + if (packageFragment == null) return@lambda null + + LazyJavaClassDescriptor( + c.withTypes(TypeParameterResolver.EMPTY), + packageFragment, + fqName, + jClass + ) + } + override fun getPackageFragment(fqName: FqName) = _packageFragments(fqName) override fun getPackageFragments(fqName: FqName) = getPackageFragment(fqName)?.let {listOf(it)}.orEmpty() @@ -76,6 +94,7 @@ public class LazyJavaPackageFragmentProvider( override fun getClassNamesInPackage(packageName: FqName) = getPackageFragment(packageName)?.getMemberScope()?.getAllClassNames().orEmpty() fun getClass(fqName: FqName): ClassDescriptor? = c.javaClassResolver.resolveClassByFqName(fqName) + fun getClass(javaClass: JavaClass): ClassDescriptor? = c.javaClassResolver.resolveClass(javaClass) internal val resolveKotlinBinaryClass = c.storageManager.createMemoizedFunctionWithNullableValues { (kotlinClass: KotlinJvmBinaryClass) -> c.deserializedDescriptorResolver.resolveClass(kotlinClass) @@ -94,18 +113,13 @@ public class LazyJavaPackageFragmentProvider( return c.javaResolverCache.getClassResolvedFromSource(fqName) } } - val resolvedClassifier = getContainingScope(javaClass)?.getClassifier(javaClass.getName()) - return resolvedClassifier as? ClassDescriptor ?: c.javaResolverCache.getClass(javaClass) - } - - private fun getContainingScope(javaClass: JavaClass): JetScope? { val outerClass = javaClass.getOuterClass() - if (outerClass != null) { - return resolveClass(outerClass)?.getUnsubstitutedInnerClassesScope() - } - else { - return getPackageFragment(javaClass.getFqName()!!.parent())?.getMemberScope() + if (outerClass == null) { + return topLevelClasses(javaClass) } + val outerClassScope = resolveClass(outerClass)?.getUnsubstitutedInnerClassesScope() + val nestedClass = outerClassScope?.getClassifier(javaClass.getName()) as? ClassDescriptor + return nestedClass ?: c.javaResolverCache.getClass(javaClass) } override fun resolveClassByFqName(fqName: FqName): ClassDescriptor? { diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragmentScope.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragmentScope.kt index f3c6a45690c..f772b939566 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragmentScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragmentScope.kt @@ -54,8 +54,12 @@ public abstract class LazyJavaPackageFragmentScope( val cached = c.javaResolverCache.getClass(jClass) if (cached != null) cached - else - LazyJavaClassDescriptor(c.withTypes(TypeParameterResolver.EMPTY), packageFragment, fqName, jClass) + else { + val classDescriptor = c.javaClassResolver.resolveClass(jClass) + assert(classDescriptor == null || classDescriptor.getContainingDeclaration() == packageFragment, + "Wrong package fragment for $classDescriptor, expected $packageFragment") + classDescriptor + } } }