From 3e8031acbd4ecbde9fa0f804bc724183d3740f5d Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 7 Jun 2013 17:47:40 +0400 Subject: [PATCH] Properly load objects nested into class objects from Java --- .../resolver/JavaClassObjectResolver.java | 2 +- .../resolve/java/scope/JavaBaseScope.java | 29 +++++++++++++++---- .../resolve/scopes/WritableScopeImpl.java | 19 ++++++++++-- .../diagnostics/tests/objects/Objects.kt | 4 +-- .../tests/objects/ObjectsInheritance.kt | 2 +- .../loadKotlin/class/NamedObjectInClass.kt | 8 +++++ .../loadKotlin/class/NamedObjectInClass.txt | 13 +++++++++ .../LoadCompiledKotlinTestGenerated.java | 5 ++++ ...esolveNamespaceComparingTestGenerated.java | 5 ++++ 9 files changed, 76 insertions(+), 11 deletions(-) create mode 100644 compiler/testData/loadKotlin/class/NamedObjectInClass.kt create mode 100644 compiler/testData/loadKotlin/class/NamedObjectInClass.txt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java index 8bf16a28584..5f59d056aee 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java @@ -149,7 +149,7 @@ public final class JavaClassObjectResolver { classObjectDescriptor.createTypeConstructor(); JavaClassNonStaticMembersScope classMembersScope = new JavaClassNonStaticMembersScope(classObjectDescriptor, data, semanticServices); WritableScopeImpl writableScope = - new WritableScopeImpl(classMembersScope, classObjectDescriptor, RedeclarationHandler.THROW_EXCEPTION, fqName.toString()); + new WritableScopeImpl(classMembersScope, classObjectDescriptor, RedeclarationHandler.THROW_EXCEPTION, "Member lookup scope"); writableScope.changeLockLevel(WritableScope.LockLevel.BOTH); classObjectDescriptor.setScopeForMemberLookup(writableScope); classObjectDescriptor.setScopeForConstructorResolve(classMembersScope); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaBaseScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaBaseScope.java index 74628e966a8..6f1edf2f678 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaBaseScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaBaseScope.java @@ -20,7 +20,9 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.intellij.openapi.progress.ProgressIndicatorProvider; +import com.intellij.openapi.util.Condition; import com.intellij.psi.PsiElement; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; @@ -33,10 +35,7 @@ import org.jetbrains.jet.lang.resolve.java.provider.PsiDeclarationProvider; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScopeImpl; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Set; +import java.util.*; public abstract class JavaBaseScope extends JetScopeImpl { @@ -50,6 +49,8 @@ public abstract class JavaBaseScope extends JetScopeImpl { private final Map> propertyDescriptors = Maps.newHashMap(); @Nullable private Collection allDescriptors = null; + @Nullable + private Set objectDescriptors = null; @NotNull protected final ClassOrNamespaceDescriptor descriptor; @@ -130,10 +131,19 @@ public abstract class JavaBaseScope extends JetScopeImpl { protected Collection computeAllDescriptors() { Collection result = Sets.newHashSet(); result.addAll(computeFieldAndFunctionDescriptors()); - result.addAll(getInnerClasses()); + result.addAll(filterObjects(getInnerClasses(), false)); return result; } + @NotNull + @Override + public Set getObjectDescriptors() { + if (objectDescriptors == null) { + objectDescriptors = new HashSet(filterObjects(getInnerClasses(), true)); + } + return objectDescriptors; + } + @NotNull protected abstract Collection computeInnerClasses(); @@ -174,4 +184,13 @@ public abstract class JavaBaseScope extends JetScopeImpl { } return innerClasses; } + + private static Collection filterObjects(Collection classes, final boolean objects) { + return ContainerUtil.filter(classes, new Condition() { + @Override + public boolean value(T classDescriptor) { + return classDescriptor.getKind().isObject() == objects; + } + }); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java index 7f1c06745b2..8aeb050d97a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java @@ -33,6 +33,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { private final Multimap declaredDescriptorsAccessibleBySimpleName = HashMultimap.create(); private boolean allDescriptorsDone = false; + private Set allObjectDescriptors = null; + @NotNull private final DeclarationDescriptor ownerDeclarationDescriptor; @@ -401,13 +403,26 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override public ClassDescriptor getObjectDescriptor(@NotNull Name name) { - return getObjectDescriptorsMap().get(name); + ClassDescriptor descriptor = getObjectDescriptorsMap().get(name); + if (descriptor != null) return descriptor; + + ClassDescriptor fromWorker = getWorkerScope().getObjectDescriptor(name); + if (fromWorker != null) return fromWorker; + + return super.getObjectDescriptor(name); } @NotNull @Override public Set getObjectDescriptors() { - return Sets.newHashSet(getObjectDescriptorsMap().values()); + if (allObjectDescriptors == null) { + allObjectDescriptors = Sets.newHashSet(getObjectDescriptorsMap().values()); + allObjectDescriptors.addAll(getWorkerScope().getObjectDescriptors()); + for (JetScope imported : getImports()) { + allObjectDescriptors.addAll(imported.getObjectDescriptors()); + } + } + return allObjectDescriptors; } @Override diff --git a/compiler/testData/diagnostics/tests/objects/Objects.kt b/compiler/testData/diagnostics/tests/objects/Objects.kt index 27575534eb1..f9f8fc7a515 100644 --- a/compiler/testData/diagnostics/tests/objects/Objects.kt +++ b/compiler/testData/diagnostics/tests/objects/Objects.kt @@ -14,7 +14,7 @@ package toplevelObjectDeclarations } } - object B : A {} + object B : A {} val x = A.foo() @@ -26,4 +26,4 @@ package toplevelObjectDeclarations override fun foo() : Int = 1 } - val z = y.foo() + val z = y.foo() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/objects/ObjectsInheritance.kt b/compiler/testData/diagnostics/tests/objects/ObjectsInheritance.kt index 9d7c9ee16ee..441221407cc 100644 --- a/compiler/testData/diagnostics/tests/objects/ObjectsInheritance.kt +++ b/compiler/testData/diagnostics/tests/objects/ObjectsInheritance.kt @@ -3,4 +3,4 @@ package toplevelObjectDeclarations object CObj {} -object DOjb : CObj {} +object DOjb : CObj {} \ No newline at end of file diff --git a/compiler/testData/loadKotlin/class/NamedObjectInClass.kt b/compiler/testData/loadKotlin/class/NamedObjectInClass.kt new file mode 100644 index 00000000000..367c75a314a --- /dev/null +++ b/compiler/testData/loadKotlin/class/NamedObjectInClass.kt @@ -0,0 +1,8 @@ +package test + +public class Outer { + public object Obj { + public val v: String = "val" + public fun f(): String = "fun" + } +} diff --git a/compiler/testData/loadKotlin/class/NamedObjectInClass.txt b/compiler/testData/loadKotlin/class/NamedObjectInClass.txt new file mode 100644 index 00000000000..d34694c31c3 --- /dev/null +++ b/compiler/testData/loadKotlin/class/NamedObjectInClass.txt @@ -0,0 +1,13 @@ +package test + +public final class Outer { + /*primary*/ public constructor Outer() + public final val Obj: test.Outer.Obj + + public object Obj { + /*primary*/ private constructor Obj() + public final val v: jet.String + public final fun (): jet.String + public final fun f(): jet.String + } +} diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java index 191e3bb70de..036177825ea 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java @@ -158,6 +158,11 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT doTestWithAccessors("compiler/testData/loadKotlin/class/NamedObject.kt"); } + @TestMetadata("NamedObjectInClass.kt") + public void testNamedObjectInClass() throws Exception { + doTestWithAccessors("compiler/testData/loadKotlin/class/NamedObjectInClass.kt"); + } + @TestMetadata("NamedObjectInClassObject.kt") public void testNamedObjectInClassObject() throws Exception { doTestWithAccessors("compiler/testData/loadKotlin/class/NamedObjectInClassObject.kt"); diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java index 4bf970ac668..f6e5a1cdd7f 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java @@ -160,6 +160,11 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/class/NamedObject.kt"); } + @TestMetadata("NamedObjectInClass.kt") + public void testNamedObjectInClass() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/class/NamedObjectInClass.kt"); + } + @TestMetadata("NamedObjectInClassObject.kt") public void testNamedObjectInClassObject() throws Exception { doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/class/NamedObjectInClassObject.kt");