From b0b173eb5a174ed59cd508156cf335a7cb4acc82 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 24 Jul 2013 20:11:12 +0400 Subject: [PATCH] Resolve descriptors in error class objects --- .../jet/lang/resolve/lazy/ResolveSession.java | 35 ++++++++++++++++--- .../lazy/descriptors/LazyClassDescriptor.java | 2 +- .../resolve/references/InObjectClassObject.kt | 11 ++++++ .../resolve/references/InSecondClassObject.kt | 15 ++++++++ .../ReferenceResolveTestGenerated.java | 10 ++++++ 5 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 idea/testData/resolve/references/InObjectClassObject.kt create mode 100644 idea/testData/resolve/references/InSecondClassObject.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java index ef36abacb26..f5d3c49a941 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java @@ -31,6 +31,8 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.BindingTraceContext; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo; import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactory; import org.jetbrains.jet.lang.resolve.lazy.declarations.PackageMemberDeclarationProvider; import org.jetbrains.jet.lang.resolve.lazy.descriptors.LazyClassDescriptor; @@ -189,10 +191,35 @@ public class ResolveSession implements KotlinCodeAnalyzer { } /*package*/ LazyClassDescriptor getClassObjectDescriptor(JetClassObject classObject) { - LazyClassDescriptor classDescriptor = (LazyClassDescriptor) getClassDescriptor(PsiTreeUtil.getParentOfType(classObject, JetClass.class)); - LazyClassDescriptor classObjectDescriptor = (LazyClassDescriptor) classDescriptor.getClassObjectDescriptor(); - assert classObjectDescriptor != null : "Class object is declared, but is null for " + classDescriptor; - return classObjectDescriptor; + JetClass aClass = PsiTreeUtil.getParentOfType(classObject, JetClass.class); + + LazyClassDescriptor parentClassDescriptor; + + if (aClass != null) { + parentClassDescriptor = (LazyClassDescriptor) getClassDescriptor(aClass); + } + else { + // Class object in object is an error but we want to find descriptors even for this case + JetObjectDeclaration objectDeclaration = PsiTreeUtil.getParentOfType(classObject, JetObjectDeclaration.class); + assert objectDeclaration != null : String.format("Class object %s can be in class or object in file %s", classObject, classObject.getContainingFile().getText()); + parentClassDescriptor = (LazyClassDescriptor) getClassDescriptor(objectDeclaration); + } + + // Activate resolution and writing to trace + parentClassDescriptor.getClassObjectDescriptor(); + DeclarationDescriptor declaration = getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, classObject.getObjectDeclaration()); + + if (declaration == null) { + // It's possible that there are several class objects and another class object is taking part in lazy resolve. We still want to + // build descriptors for such class objects. + JetClassLikeInfo classObjectInfo = parentClassDescriptor.getClassObjectInfo(classObject); + if (classObjectInfo != null) { + Name name = DescriptorUtils.getClassObjectName(parentClassDescriptor.getName().asString()); + return new LazyClassDescriptor(this, parentClassDescriptor, name, classObjectInfo); + } + } + + return (LazyClassDescriptor) declaration; } @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java index 708005af8ef..ae0f98c2c17 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java @@ -292,7 +292,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc } @Nullable - private JetClassLikeInfo getClassObjectInfo(JetClassObject classObject) { + public JetClassLikeInfo getClassObjectInfo(JetClassObject classObject) { if (classObject != null) { if (!DescriptorUtils.inStaticContext(this)) { return null; diff --git a/idea/testData/resolve/references/InObjectClassObject.kt b/idea/testData/resolve/references/InObjectClassObject.kt new file mode 100644 index 00000000000..549ed1ad603 --- /dev/null +++ b/idea/testData/resolve/references/InObjectClassObject.kt @@ -0,0 +1,11 @@ +package test + +class A + +object b { + class object { + val x = A() + } +} + +// REF: (test).A \ No newline at end of file diff --git a/idea/testData/resolve/references/InSecondClassObject.kt b/idea/testData/resolve/references/InSecondClassObject.kt new file mode 100644 index 00000000000..c1dafa4cbc7 --- /dev/null +++ b/idea/testData/resolve/references/InSecondClassObject.kt @@ -0,0 +1,15 @@ +package test + +class A + +class Many { + class object { + val x = A() + } + + class object { + val y = A() + } +} + +// REF: (test).A \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/resolve/ReferenceResolveTestGenerated.java b/idea/tests/org/jetbrains/jet/resolve/ReferenceResolveTestGenerated.java index 90f91cdafa0..05a810537ee 100644 --- a/idea/tests/org/jetbrains/jet/resolve/ReferenceResolveTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/resolve/ReferenceResolveTestGenerated.java @@ -86,6 +86,16 @@ public class ReferenceResolveTestGenerated extends AbstractResolveBaseTest { doTest("idea/testData/resolve/references/InFunctionParameterType.kt"); } + @TestMetadata("InObjectClassObject.kt") + public void testInObjectClassObject() throws Exception { + doTest("idea/testData/resolve/references/InObjectClassObject.kt"); + } + + @TestMetadata("InSecondClassObject.kt") + public void testInSecondClassObject() throws Exception { + doTest("idea/testData/resolve/references/InSecondClassObject.kt"); + } + @TestMetadata("PackageReference.kt") public void testPackageReference() throws Exception { doTest("idea/testData/resolve/references/PackageReference.kt");