From 5eacd6bdee5d1b096bbd1262fcefbe82d0c7bb51 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 23 Oct 2013 13:51:32 +0400 Subject: [PATCH] Differentiate package fragments loaded from java packages and java (static) classes --- .../resolve/java/lazy/LazyJavaSubModule.kt | 20 ++++- .../descriptors/LazyJavaClassMemberScope.kt | 4 + .../lazy/descriptors/LazyJavaMemberScope.kt | 12 +-- .../descriptors/LazyJavaPackageFragment.kt | 43 +++++++--- .../LazyJavaPackageFragmentScope.kt | 80 ++++++++++++++----- 5 files changed, 119 insertions(+), 40 deletions(-) diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/LazyJavaSubModule.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/LazyJavaSubModule.kt index ab88b111e54..8c2c533ccc1 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/LazyJavaSubModule.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/LazyJavaSubModule.kt @@ -2,11 +2,12 @@ package org.jetbrains.jet.lang.resolve.java.lazy import org.jetbrains.jet.lang.descriptors.ModuleDescriptor import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor -import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaPackageFragment import org.jetbrains.jet.storage.MemoizedFunctionToNullable import org.jetbrains.jet.lang.resolve.name.FqName import org.jetbrains.jet.lang.resolve.java.structure.JavaClass import org.jetbrains.jet.lang.descriptors.ClassDescriptor +import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyPackageFragmentForJavaPackage +import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyPackageFragmentForJavaClass public open class LazyJavaSubModule( private val outerContext: GlobalJavaResolverContext, @@ -22,10 +23,23 @@ public open class LazyJavaSubModule( private val _packageFragments: MemoizedFunctionToNullable = c.storageManager.createMemoizedFunctionWithNullableValues { fqName -> - val parent = if (fqName.isRoot()) module else getPackageFragment(fqName.parent()) ?: throw IllegalStateException("Cannot resolve parent package for: $fqName") - LazyJavaPackageFragment(c, parent, fqName) + val jPackage = c.finder.findPackage(fqName) + if (jPackage != null) { + LazyPackageFragmentForJavaPackage(c, findParent(fqName), jPackage) + } + else { + val jClass = c.finder.findClass(fqName) + if (jClass != null && (jClass.getOuterClass() == null || jClass.isStatic())) { + LazyPackageFragmentForJavaClass(c, findParent(fqName), jClass) + } + else null + } } + private fun findParent(fqName: FqName) = + if (fqName.isRoot()) module else getPackageFragment(fqName.parent()) + ?: throw IllegalStateException("Cannot resolve parent package for: $fqName") + fun getPackageFragment(fqName: FqName): NamespaceDescriptor? = _packageFragments(fqName) fun getClass(fqName: FqName): ClassDescriptor? = c.javaClassResolver.resolveClassByFqName(fqName) diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt index b4885f6f72e..2652c0cc0f0 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt @@ -267,4 +267,8 @@ public class LazyJavaClassMemberScope( override fun getContainingDeclaration(): LazyJavaClassDescriptor { return super.getContainingDeclaration() as LazyJavaClassDescriptor } + + // namespaces should be resolved elsewhere + override fun getNamespace(name: Name): NamespaceDescriptor? = null + override fun getAllPackageNames(): Collection = listOf() } \ No newline at end of file diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt index 8df3518bfc1..b33deae3b5f 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt @@ -40,9 +40,6 @@ public abstract class LazyJavaMemberScope( override fun getObjectDescriptor(name: Name): ClassDescriptor? = null override fun getObjectDescriptors() = emptyList() - // namespaces should be resolved elsewhere - override fun getNamespace(name: Name): NamespaceDescriptor? = null - override fun getLocalVariable(name: Name): VariableDescriptor? = null override fun getDeclarationsByLabel(labelName: LabelName) = emptyList() @@ -52,10 +49,14 @@ public abstract class LazyJavaMemberScope( private fun computeAllDescriptors(): MutableCollection { val result = arrayListOf() + for (name in getAllPackageNames()) { + val descriptor = getNamespace(name) + result.add(descriptor ?: throw IllegalStateException("Descriptor not found for name $name in " + getContainingDeclaration())) + } + for (name in getAllClassNames()) { val descriptor = getClassifier(name) - assert(descriptor != null) {"Descriptor not found for name " + name + " in " + getContainingDeclaration()} - result.add(descriptor!!) + result.add(descriptor ?: throw IllegalStateException("Descriptor not found for name $name in " + getContainingDeclaration())) } for (name in getAllFunctionNames()) { @@ -71,6 +72,7 @@ public abstract class LazyJavaMemberScope( return result } + protected abstract fun getAllPackageNames(): Collection protected abstract fun getAllClassNames(): Collection protected abstract fun getAllPropertyNames(): Collection protected abstract fun getAllFunctionNames(): Collection diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragment.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragment.kt index 19a94d596ef..0684c554914 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragment.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragment.kt @@ -3,23 +3,46 @@ package org.jetbrains.jet.lang.resolve.java.lazy.descriptors import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor import org.jetbrains.jet.lang.descriptors.impl.AbstractNamespaceDescriptorImpl import org.jetbrains.jet.lang.descriptors.impl.NamespaceDescriptorParent -import org.jetbrains.jet.lang.resolve.name.FqName import org.jetbrains.jet.utils.emptyList import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaResolverContext +import org.jetbrains.jet.lang.resolve.name.Name +import org.jetbrains.jet.lang.resolve.scopes.JetScope +import org.jetbrains.jet.lang.resolve.java.structure.JavaPackage +import org.jetbrains.jet.lang.resolve.name.FqName import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe +import org.jetbrains.jet.lang.resolve.java.structure.JavaClass +import org.jetbrains.kotlin.util.sure -public class LazyJavaPackageFragment( +abstract class LazyJavaPackageFragment( c: LazyJavaResolverContext, containingDeclaration: NamespaceDescriptorParent, - private val _fqName: FqName -) : AbstractNamespaceDescriptorImpl( - containingDeclaration, - emptyList(), - if (_fqName.isRoot()) FqNameUnsafe.ROOT_NAME else _fqName.shortName() - ), NamespaceDescriptor, LazyJavaDescriptor { + name: Name +) : AbstractNamespaceDescriptorImpl(containingDeclaration, emptyList(), name), NamespaceDescriptor, LazyJavaDescriptor { - private val _memberScope = LazyJavaPackageFragmentScope(c, this) + protected abstract val _memberScope: JetScope override fun getMemberScope() = _memberScope - override fun getFqName() = _fqName } + +public class LazyPackageFragmentForJavaPackage( + c: LazyJavaResolverContext, + containingDeclaration: NamespaceDescriptorParent, + val jPackage: JavaPackage +) : LazyJavaPackageFragment(c, containingDeclaration, jPackage.getFqName().shortNameOrSpecial()) { + override fun getFqName(): FqName = jPackage.getFqName() + + override val _memberScope = LazyPackageFragmentScopeForJavaPackage(c, jPackage, this) +} + +public class LazyPackageFragmentForJavaClass( + c: LazyJavaResolverContext, + containingDeclaration: NamespaceDescriptorParent, + val jClass: JavaClass +) : LazyJavaPackageFragment(c, containingDeclaration, + jClass.getFqName().sure("Attempt to build a package of an anonymous/local class: $jClass") + .shortNameOrRoot() +) { + override fun getFqName(): FqName = jClass.getFqName()!! + + override val _memberScope = LazyPackageFragmentScopeForJavaClass(c, jClass, this) +} \ No newline at end of file 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 c7cf32749ca..3aaf67dfcb4 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 @@ -7,22 +7,45 @@ import java.util.Collections import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaResolverContext import org.jetbrains.jet.lang.resolve.java.lazy.withTypes import org.jetbrains.jet.lang.resolve.java.lazy.TypeParameterResolver +import org.jetbrains.jet.lang.resolve.java.structure.JavaPackage +import org.jetbrains.jet.lang.resolve.name.FqName +import org.jetbrains.jet.utils.flatten +import org.jetbrains.jet.lang.resolve.java.structure.JavaClass -public class LazyJavaPackageFragmentScope( +public abstract class LazyJavaPackageFragmentScope( c: LazyJavaResolverContext, - containingDeclaration: NamespaceDescriptor -) : LazyJavaMemberScope(c.withTypes(), containingDeclaration) { + packageFragment: LazyJavaPackageFragment +) : LazyJavaMemberScope(c.withTypes(), packageFragment) { - private val fqName = DescriptorUtils.getFQName(containingDeclaration).toSafe() + protected val fqName: FqName = DescriptorUtils.getFQName(packageFragment).toSafe() private val classes = c.storageManager.createMemoizedFunctionWithNullableValues { - name -> - val fqName = fqName.child(name) - val javaClass = c.finder.findClass(fqName) - if (javaClass == null) - null - else - LazyJavaClassDescriptor(c.withTypes(TypeParameterResolver.EMPTY), containingDeclaration, fqName, javaClass) - } + name -> + val fqName = fqName.child(name) + val javaClass = c.finder.findClass(fqName) + if (javaClass == null) + null + else + LazyJavaClassDescriptor(c.withTypes(TypeParameterResolver.EMPTY), packageFragment, fqName, javaClass) + } + + override fun addExtraDescriptors(result: MutableCollection) { + // no extra descriptors + } + + override fun getClassifier(name: Name): ClassifierDescriptor? = classes(name) + + override fun getNamespace(name: Name): NamespaceDescriptor? = c.subModule.getPackageFragment(getContainingDeclaration().getFqName().child(name)) + + override fun getImplicitReceiversHierarchy(): List = listOf() + + override fun getContainingDeclaration()= super.getContainingDeclaration() as LazyJavaPackageFragment +} + +public class LazyPackageFragmentScopeForJavaPackage( + c: LazyJavaResolverContext, + private val jPackage: JavaPackage, + packageFragment: LazyJavaPackageFragment +) : LazyJavaPackageFragmentScope(c, packageFragment) { override fun getAllClassNames(): Collection { val javaPackage = c.finder.findPackage(fqName) @@ -30,21 +53,34 @@ public class LazyJavaPackageFragmentScope( return javaPackage!!.getClasses().map { c -> c.getName() } } - override fun getAllPropertyNames() = Collections.emptyList() - override fun getAllFunctionNames() = Collections.emptyList() - - override fun addExtraDescriptors(result: MutableCollection) { - // no extra descriptors - } + override fun getAllPackageNames(): Collection = + listOf( + jPackage.getClasses().map { c -> c.getName() }, + jPackage.getSubPackages().map { sp -> sp.getFqName().shortName() } + ).flatten() - override fun getClassifier(name: Name): ClassifierDescriptor? = classes(name) + + override fun getProperties(name: Name): Collection = Collections.emptyList() + override fun getAllPropertyNames() = Collections.emptyList() + + override fun getFunctions(name: Name): Collection = Collections.emptyList() + override fun getAllFunctionNames() = Collections.emptyList() +} + +public class LazyPackageFragmentScopeForJavaClass( + c: LazyJavaResolverContext, + private val jClass: JavaClass, + packageFragment: LazyJavaPackageFragment +) : LazyJavaPackageFragmentScope(c, packageFragment) { + + override fun getAllClassNames(): Collection = jClass.getInnerClasses().map { c -> c.getName() } + override fun getAllPackageNames(): Collection = jClass.getInnerClasses().filter { c -> c.isStatic() }.map { c -> c.getName() } // TODO override fun getProperties(name: Name): Collection = Collections.emptyList() + override fun getAllPropertyNames() = Collections.emptyList() // TODO override fun getFunctions(name: Name): Collection = Collections.emptyList() - - override fun getImplicitReceiversHierarchy(): List = listOf() - + override fun getAllFunctionNames() = Collections.emptyList() }