Always create descriptors for class object psi element in lazy resolve
KT-4397 Exception: @NotNull method org/jetbrains/jet/lang/resolve/lazy/ResolveSession.getClassDescriptor must not return null #KT-4397 Fixed
This commit is contained in:
@@ -214,7 +214,8 @@ public class ResolveSession implements KotlinCodeAnalyzer {
|
|||||||
return (ClassDescriptor) declaration;
|
return (ClassDescriptor) declaration;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*package*/ LazyClassDescriptor getClassObjectDescriptor(JetClassObject classObject) {
|
@NotNull
|
||||||
|
/*package*/ LazyClassDescriptor getClassObjectDescriptor(@NotNull JetClassObject classObject) {
|
||||||
JetClass aClass = PsiTreeUtil.getParentOfType(classObject, JetClass.class);
|
JetClass aClass = PsiTreeUtil.getParentOfType(classObject, JetClass.class);
|
||||||
|
|
||||||
final LazyClassDescriptor parentClassDescriptor;
|
final LazyClassDescriptor parentClassDescriptor;
|
||||||
@@ -237,16 +238,18 @@ public class ResolveSession implements KotlinCodeAnalyzer {
|
|||||||
// It's possible that there are several class objects and another class object is taking part in lazy resolve. We still want to
|
// 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.
|
// build descriptors for such class objects.
|
||||||
final JetClassLikeInfo classObjectInfo = parentClassDescriptor.getClassObjectInfo(classObject);
|
final JetClassLikeInfo classObjectInfo = parentClassDescriptor.getClassObjectInfo(classObject);
|
||||||
if (classObjectInfo != null) {
|
assert classObjectInfo != null :
|
||||||
final Name name = SpecialNames.getClassObjectName(parentClassDescriptor.getName());
|
String.format("Failed to find class object info for existent class object declaration: %s",
|
||||||
return storageManager.compute(new Function0<LazyClassDescriptor>() {
|
JetPsiUtil.getElementTextWithContext(classObject));
|
||||||
@Override
|
|
||||||
public LazyClassDescriptor invoke() {
|
final Name name = SpecialNames.getClassObjectName(parentClassDescriptor.getName());
|
||||||
// Create under lock to avoid premature access to published 'this'
|
return storageManager.compute(new Function0<LazyClassDescriptor>() {
|
||||||
return new LazyClassDescriptor(ResolveSession.this, parentClassDescriptor, name, classObjectInfo);
|
@Override
|
||||||
}
|
public LazyClassDescriptor invoke() {
|
||||||
});
|
// Create under lock to avoid premature access to published 'this'
|
||||||
}
|
return new LazyClassDescriptor(ResolveSession.this, parentClassDescriptor, name, classObjectInfo);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return (LazyClassDescriptor) declaration;
|
return (LazyClassDescriptor) declaration;
|
||||||
|
|||||||
+1
-3
@@ -258,9 +258,6 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc
|
|||||||
@Nullable
|
@Nullable
|
||||||
public JetClassLikeInfo getClassObjectInfo(JetClassObject classObject) {
|
public JetClassLikeInfo getClassObjectInfo(JetClassObject classObject) {
|
||||||
if (classObject != null) {
|
if (classObject != null) {
|
||||||
if (!DescriptorUtils.inStaticContext(this)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
JetObjectDeclaration objectDeclaration = classObject.getObjectDeclaration();
|
JetObjectDeclaration objectDeclaration = classObject.getObjectDeclaration();
|
||||||
if (objectDeclaration != null) {
|
if (objectDeclaration != null) {
|
||||||
return JetClassInfoUtil.createClassLikeInfo(objectDeclaration);
|
return JetClassInfoUtil.createClassLikeInfo(objectDeclaration);
|
||||||
@@ -269,6 +266,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc
|
|||||||
else if (getKind() == ClassKind.OBJECT || getKind() == ClassKind.ENUM_ENTRY || getKind() == ClassKind.ENUM_CLASS) {
|
else if (getKind() == ClassKind.OBJECT || getKind() == ClassKind.ENUM_ENTRY || getKind() == ClassKind.ENUM_CLASS) {
|
||||||
return new SyntheticClassObjectInfo(originalClassInfo, this);
|
return new SyntheticClassObjectInfo(originalClassInfo, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class A {
|
||||||
|
class B {
|
||||||
|
class object {
|
||||||
|
val TEST = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
internal final class A {
|
||||||
|
/*primary*/ public constructor A()
|
||||||
|
|
||||||
|
internal final class B {
|
||||||
|
/*primary*/ public constructor B()
|
||||||
|
|
||||||
|
internal class object <class-object-for-B> {
|
||||||
|
/*primary*/ private constructor <class-object-for-B>()
|
||||||
|
internal final val TEST: jet.Int
|
||||||
|
internal final fun <get-TEST>(): jet.Int
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1577,6 +1577,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
|
|||||||
doTestCompiledKotlin("compiler/testData/loadJava/compiledKotlin/annotations/classes/ClassObject.kt");
|
doTestCompiledKotlin("compiler/testData/loadJava/compiledKotlin/annotations/classes/ClassObject.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ClassObjectInStaticNestedClass.kt")
|
||||||
|
public void testClassObjectInStaticNestedClass() throws Exception {
|
||||||
|
doTestCompiledKotlin("compiler/testData/loadJava/compiledKotlin/annotations/classes/ClassObjectInStaticNestedClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("Deprecated.kt")
|
@TestMetadata("Deprecated.kt")
|
||||||
public void testDeprecated() throws Exception {
|
public void testDeprecated() throws Exception {
|
||||||
doTestCompiledKotlin("compiler/testData/loadJava/compiledKotlin/annotations/classes/Deprecated.kt");
|
doTestCompiledKotlin("compiler/testData/loadJava/compiledKotlin/annotations/classes/Deprecated.kt");
|
||||||
|
|||||||
+5
@@ -105,6 +105,11 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
|
|||||||
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/ClassObject.kt");
|
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/ClassObject.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ClassObjectInStaticNestedClass.kt")
|
||||||
|
public void testClassObjectInStaticNestedClass() throws Exception {
|
||||||
|
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/ClassObjectInStaticNestedClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("Deprecated.kt")
|
@TestMetadata("Deprecated.kt")
|
||||||
public void testDeprecated() throws Exception {
|
public void testDeprecated() throws Exception {
|
||||||
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/Deprecated.kt");
|
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/Deprecated.kt");
|
||||||
|
|||||||
@@ -310,22 +310,6 @@ public class DescriptorUtils {
|
|||||||
return superClassDescriptor.equals(KotlinBuiltIns.getInstance().getAny());
|
return superClassDescriptor.equals(KotlinBuiltIns.getInstance().getAny());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean inStaticContext(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
|
||||||
if (containingDeclaration instanceof PackageFragmentDescriptor) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (containingDeclaration instanceof ClassDescriptor) {
|
|
||||||
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
|
|
||||||
|
|
||||||
if (classDescriptor.getKind().isSingleton()) {
|
|
||||||
return inStaticContext(classDescriptor.getContainingDeclaration());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isEnumClassObject(@NotNull DeclarationDescriptor descriptor) {
|
public static boolean isEnumClassObject(@NotNull DeclarationDescriptor descriptor) {
|
||||||
if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() == ClassKind.CLASS_OBJECT) {
|
if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() == ClassKind.CLASS_OBJECT) {
|
||||||
DeclarationDescriptor containing = descriptor.getContainingDeclaration();
|
DeclarationDescriptor containing = descriptor.getContainingDeclaration();
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
trait <lineMarker></lineMarker>TestTrait {
|
||||||
|
fun <lineMarker></lineMarker>test()
|
||||||
|
}
|
||||||
|
|
||||||
|
class A {
|
||||||
|
class B {
|
||||||
|
class object : TestTrait { // TODO: No line marker
|
||||||
|
override fun <lineMarker descr="<b>internal</b> <b>open</b> <b>fun</b> test(): jet.Unit <i>defined in</i> A.B.<class-object-for-B><br/>implements<br/><b>internal</b> <b>abstract</b> <b>fun</b> test(): jet.Unit <i>defined in</i> TestTrait"></lineMarker>test() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -61,6 +61,10 @@ public class OverrideImplementLineMarkerTest extends JetLightCodeInsightFixtureT
|
|||||||
doTest();
|
doTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testClassObjectInStaticNestedClass() throws Exception {
|
||||||
|
doTest();
|
||||||
|
}
|
||||||
|
|
||||||
public void testFakeOverrideProperty() throws Exception {
|
public void testFakeOverrideProperty() throws Exception {
|
||||||
doTest();
|
doTest();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user