Resolve descriptors in error class objects
This commit is contained in:
@@ -31,6 +31,8 @@ import org.jetbrains.jet.lang.psi.*;
|
|||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
|
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.DeclarationProviderFactory;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.declarations.PackageMemberDeclarationProvider;
|
import org.jetbrains.jet.lang.resolve.lazy.declarations.PackageMemberDeclarationProvider;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.descriptors.LazyClassDescriptor;
|
import org.jetbrains.jet.lang.resolve.lazy.descriptors.LazyClassDescriptor;
|
||||||
@@ -189,10 +191,35 @@ public class ResolveSession implements KotlinCodeAnalyzer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*package*/ LazyClassDescriptor getClassObjectDescriptor(JetClassObject classObject) {
|
/*package*/ LazyClassDescriptor getClassObjectDescriptor(JetClassObject classObject) {
|
||||||
LazyClassDescriptor classDescriptor = (LazyClassDescriptor) getClassDescriptor(PsiTreeUtil.getParentOfType(classObject, JetClass.class));
|
JetClass aClass = PsiTreeUtil.getParentOfType(classObject, JetClass.class);
|
||||||
LazyClassDescriptor classObjectDescriptor = (LazyClassDescriptor) classDescriptor.getClassObjectDescriptor();
|
|
||||||
assert classObjectDescriptor != null : "Class object is declared, but is null for " + classDescriptor;
|
LazyClassDescriptor parentClassDescriptor;
|
||||||
return classObjectDescriptor;
|
|
||||||
|
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
|
@Override
|
||||||
|
|||||||
+1
-1
@@ -292,7 +292,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private JetClassLikeInfo getClassObjectInfo(JetClassObject classObject) {
|
public JetClassLikeInfo getClassObjectInfo(JetClassObject classObject) {
|
||||||
if (classObject != null) {
|
if (classObject != null) {
|
||||||
if (!DescriptorUtils.inStaticContext(this)) {
|
if (!DescriptorUtils.inStaticContext(this)) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class A
|
||||||
|
|
||||||
|
object b {
|
||||||
|
class object {
|
||||||
|
val x = <caret>A()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// REF: (test).A
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class A
|
||||||
|
|
||||||
|
class Many {
|
||||||
|
class object {
|
||||||
|
val x = A()
|
||||||
|
}
|
||||||
|
|
||||||
|
class object {
|
||||||
|
val y = <caret>A()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// REF: (test).A
|
||||||
@@ -86,6 +86,16 @@ public class ReferenceResolveTestGenerated extends AbstractResolveBaseTest {
|
|||||||
doTest("idea/testData/resolve/references/InFunctionParameterType.kt");
|
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")
|
@TestMetadata("PackageReference.kt")
|
||||||
public void testPackageReference() throws Exception {
|
public void testPackageReference() throws Exception {
|
||||||
doTest("idea/testData/resolve/references/PackageReference.kt");
|
doTest("idea/testData/resolve/references/PackageReference.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user