diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinJavaFileStubProvider.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinJavaFileStubProvider.java index 8619eab849e..e73c3eaf94d 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinJavaFileStubProvider.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinJavaFileStubProvider.java @@ -124,7 +124,12 @@ public class KotlinJavaFileStubProvider implements CachedValueProvideremptyMap()) + ); + } String jvmInternalName = CodegenBinding.getJvmInternalName(bindingContext, classDescriptor); Collection allInnerClasses = CodegenBinding.getAllInnerClasses(bindingContext, classDescriptor); diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java index 2fb8ff86550..efe0f9581f5 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java @@ -90,7 +90,8 @@ public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightC private static String getJvmInternalName(JetClassOrObject classOrObject) { if (JetPsiUtil.isLocal(classOrObject)) { - return getLightClassDataExactly(classOrObject).getJvmInternalName(); + LightClassData data = getLightClassDataExactly(classOrObject); + return data != null ? data.getJvmInternalName() : ""; } return PsiCodegenPredictor.getPredefinedJvmInternalName(classOrObject); } @@ -255,9 +256,10 @@ public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightC return getLightClassStubWithData().getJavaFileStub(); } - @NotNull + @Nullable protected final ClassDescriptor getDescriptor() { - return getLightClassDataExactly(classOrObject).getDescriptor(); + LightClassDataForKotlinClass data = getLightClassDataExactly(classOrObject); + return data != null ? data.getDescriptor() : null; } @NotNull @@ -276,16 +278,11 @@ public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightC ); } - @NotNull + @Nullable private static LightClassDataForKotlinClass getLightClassDataExactly(JetClassOrObject classOrObject) { OutermostKotlinClassLightClassData data = (OutermostKotlinClassLightClassData) getLightClassStubWithData(classOrObject).getClassData(); - - if (data.getClassOrObject().equals(classOrObject)) return data; - - LightClassDataForKotlinClass innerClassData = data.getAllInnerClasses().get(classOrObject); - assert innerClassData != null; - return innerClassData; + return data.getClassOrObject().equals(classOrObject) ? data : data.getAllInnerClasses().get(classOrObject); } @NotNull @@ -523,13 +520,17 @@ public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightC public boolean isInheritor(@NotNull PsiClass baseClass, boolean checkDeep) { String qualifiedName; if (baseClass instanceof KotlinLightClassForExplicitDeclaration) { - qualifiedName = DescriptorUtils.getFqName(((KotlinLightClassForExplicitDeclaration) baseClass).getDescriptor()).asString(); + ClassDescriptor baseDescriptor = ((KotlinLightClassForExplicitDeclaration) baseClass).getDescriptor(); + qualifiedName = baseDescriptor != null ? DescriptorUtils.getFqName(baseDescriptor).asString() : null; } else { qualifiedName = baseClass.getQualifiedName(); } - return ResolvePackage.checkSuperTypeByFQName(getDescriptor(), qualifiedName, checkDeep); + ClassDescriptor thisDescriptor = getDescriptor(); + return qualifiedName != null + && thisDescriptor != null + && ResolvePackage.checkSuperTypeByFQName(thisDescriptor, qualifiedName, checkDeep); } @Override @@ -573,7 +574,10 @@ public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightC } private String getFirstSupertypeFQName() { - Collection superTypes = getDescriptor().getTypeConstructor().getSupertypes(); + ClassDescriptor descriptor = getDescriptor(); + if (descriptor == null) return CommonClassNames.JAVA_LANG_OBJECT; + + Collection superTypes = descriptor.getTypeConstructor().getSupertypes(); if (superTypes.isEmpty()) return CommonClassNames.JAVA_LANG_OBJECT; diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassStubWithData.kt b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassStubWithData.kt index 9a4349887ee..4ac1b568673 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassStubWithData.kt +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassStubWithData.kt @@ -26,7 +26,7 @@ trait LightClassData { trait LightClassDataForKotlinClass: LightClassData { val classOrObject: JetClassOrObject - val descriptor: ClassDescriptor + val descriptor: ClassDescriptor? } object KotlinPackageLightClassData: LightClassData { @@ -36,13 +36,13 @@ object KotlinPackageLightClassData: LightClassData { data class InnerKotlinClassLightClassData( override val jvmInternalName: String, override val classOrObject: JetClassOrObject, - override val descriptor: ClassDescriptor + override val descriptor: ClassDescriptor? ): LightClassDataForKotlinClass data class OutermostKotlinClassLightClassData( override val jvmInternalName: String, override val classOrObject: JetClassOrObject, - override val descriptor: ClassDescriptor, + override val descriptor: ClassDescriptor?, val allInnerClasses: Map ): LightClassDataForKotlinClass diff --git a/idea/testData/hierarchy/class/sub/AllFromClass/AllFromClass_verification.xml b/idea/testData/hierarchy/class/sub/AllFromClass/AllFromClass_verification.xml new file mode 100644 index 00000000000..cf5f21ee9be --- /dev/null +++ b/idea/testData/hierarchy/class/sub/AllFromClass/AllFromClass_verification.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/idea/testData/hierarchy/class/sub/AllFromClass/main.kt b/idea/testData/hierarchy/class/sub/AllFromClass/main.kt new file mode 100644 index 00000000000..3be283ecfcd --- /dev/null +++ b/idea/testData/hierarchy/class/sub/AllFromClass/main.kt @@ -0,0 +1,19 @@ +open class A + +open class B: A() + +trait T: A + +open class C: B() + +trait U: T + +object O1: A() + +object O2: B() + +object O3: C() + +object O4: T + +object O5: U diff --git a/idea/testData/hierarchy/class/sub/AllFromTrait/AllFromTrait_verification.xml b/idea/testData/hierarchy/class/sub/AllFromTrait/AllFromTrait_verification.xml new file mode 100644 index 00000000000..cf5f21ee9be --- /dev/null +++ b/idea/testData/hierarchy/class/sub/AllFromTrait/AllFromTrait_verification.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/idea/testData/hierarchy/class/sub/AllFromTrait/main.kt b/idea/testData/hierarchy/class/sub/AllFromTrait/main.kt new file mode 100644 index 00000000000..372b045336b --- /dev/null +++ b/idea/testData/hierarchy/class/sub/AllFromTrait/main.kt @@ -0,0 +1,19 @@ +trait A + +open class B: A + +trait T: A + +open class C: B() + +trait U: T + +object O1: A + +object O2: B() + +object O3: C() + +object O4: T + +object O5: U diff --git a/idea/testData/hierarchy/class/sub/ClassFromClass/ClassFromClass_verification.xml b/idea/testData/hierarchy/class/sub/ClassFromClass/ClassFromClass_verification.xml index 6f4bc04a297..d64338ddc32 100644 --- a/idea/testData/hierarchy/class/sub/ClassFromClass/ClassFromClass_verification.xml +++ b/idea/testData/hierarchy/class/sub/ClassFromClass/ClassFromClass_verification.xml @@ -1,3 +1,12 @@ - - \ No newline at end of file + + + + + + + + + + + diff --git a/idea/testData/hierarchy/class/sub/ClassFromClass/main.kt b/idea/testData/hierarchy/class/sub/ClassFromClass/main.kt index cf9a72996c7..f72d6a9be7a 100644 --- a/idea/testData/hierarchy/class/sub/ClassFromClass/main.kt +++ b/idea/testData/hierarchy/class/sub/ClassFromClass/main.kt @@ -1,3 +1,26 @@ -class MyClass: A() +open class A -open class A \ No newline at end of file +class B: A() {} + +class MyClass(a: A = run { class X: A(); object: A() {} }) { + inner class G: A() {} + + { + class C: A() + } + + fun foo(a: A = run { class X: A(); object: A() {} }) { + val t = object { + inner class F: A() + } + + class D: A() + } +} + +val bar: Int + get() { + class E: A() + + return 0 + } \ No newline at end of file diff --git a/idea/testData/hierarchy/class/sub/ClassFromTrait/ClassFromTrait_verification.xml b/idea/testData/hierarchy/class/sub/ClassFromTrait/ClassFromTrait_verification.xml new file mode 100644 index 00000000000..d64338ddc32 --- /dev/null +++ b/idea/testData/hierarchy/class/sub/ClassFromTrait/ClassFromTrait_verification.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/idea/testData/hierarchy/class/sub/ClassFromTrait/main.kt b/idea/testData/hierarchy/class/sub/ClassFromTrait/main.kt new file mode 100644 index 00000000000..d6bb44e0702 --- /dev/null +++ b/idea/testData/hierarchy/class/sub/ClassFromTrait/main.kt @@ -0,0 +1,26 @@ +trait A + +class B: A + +class MyClass(a: A = run { class X: A; object: A {} }) { + inner class G: A {} + + { + class C: A + } + + fun foo(a: A = run { class X: A; object: A {} }) { + val t = object { + inner class F: A + } + + class D: A + } +} + +val bar: Int + get() { + class E: A + + return 0 + } \ No newline at end of file diff --git a/idea/testData/hierarchy/class/sub/ObjectFromClass/ObjectFromClass_verification.xml b/idea/testData/hierarchy/class/sub/ObjectFromClass/ObjectFromClass_verification.xml index 9bad1269d44..6b16012ffc7 100644 --- a/idea/testData/hierarchy/class/sub/ObjectFromClass/ObjectFromClass_verification.xml +++ b/idea/testData/hierarchy/class/sub/ObjectFromClass/ObjectFromClass_verification.xml @@ -1,3 +1,10 @@ - - \ No newline at end of file + + + + + + + + + diff --git a/idea/testData/hierarchy/class/sub/ObjectFromClass/main.kt b/idea/testData/hierarchy/class/sub/ObjectFromClass/main.kt index 3ff7a7d66ca..bc578c31956 100644 --- a/idea/testData/hierarchy/class/sub/ObjectFromClass/main.kt +++ b/idea/testData/hierarchy/class/sub/ObjectFromClass/main.kt @@ -1,3 +1,28 @@ -object O: A() +open class A -open class A \ No newline at end of file +object B: A() + +class MyClass(a: A = run { object: A() {} }) { + { + object C: A() + } + + fun foo(a: A = run { object: A() {} }) { + object D: A() + } + + val t = object { + object F: A() + } +} + +val bar: Int + get() { + object E: A() + + return 0 + } + +val x = object: A() { + +} \ No newline at end of file diff --git a/idea/testData/hierarchy/class/sub/ObjectFromTrait/ObjectFromTrait_verification.xml b/idea/testData/hierarchy/class/sub/ObjectFromTrait/ObjectFromTrait_verification.xml index 9bad1269d44..6b16012ffc7 100644 --- a/idea/testData/hierarchy/class/sub/ObjectFromTrait/ObjectFromTrait_verification.xml +++ b/idea/testData/hierarchy/class/sub/ObjectFromTrait/ObjectFromTrait_verification.xml @@ -1,3 +1,10 @@ - - \ No newline at end of file + + + + + + + + + diff --git a/idea/testData/hierarchy/class/sub/ObjectFromTrait/main.kt b/idea/testData/hierarchy/class/sub/ObjectFromTrait/main.kt index 45daa84c030..648a519f9a7 100644 --- a/idea/testData/hierarchy/class/sub/ObjectFromTrait/main.kt +++ b/idea/testData/hierarchy/class/sub/ObjectFromTrait/main.kt @@ -1,3 +1,28 @@ -object O: A +trait A -trait A \ No newline at end of file +object B: A + +class MyClass(a: A = run { object: A {} }) { + { + object C: A + } + + fun foo(a: A = run { object: A {} }) { + object D: A + } + + val t = object { + object F: A + } +} + +val bar: Int + get() { + object E: A + + return 0 + } + +val x = object: A { + +} \ No newline at end of file diff --git a/idea/testData/hierarchy/class/sub/TraitFromClass/TraitFromClass_verification.xml b/idea/testData/hierarchy/class/sub/TraitFromClass/TraitFromClass_verification.xml new file mode 100644 index 00000000000..689e0b70f8d --- /dev/null +++ b/idea/testData/hierarchy/class/sub/TraitFromClass/TraitFromClass_verification.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/idea/testData/hierarchy/class/sub/TraitFromClass/main.kt b/idea/testData/hierarchy/class/sub/TraitFromClass/main.kt new file mode 100644 index 00000000000..02e6d785b3d --- /dev/null +++ b/idea/testData/hierarchy/class/sub/TraitFromClass/main.kt @@ -0,0 +1,26 @@ +open class A + +trait B: A() + +class MyClass(a: A = run { trait X: A(); object: A() {} }) { + inner trait G: A() {} + + { + trait C: A() + } + + fun foo(a: A = run { trait X: A(); object: A() {} }) { + trait D: A() + + val t = object { + inner trait F: A() + } + } +} + +val bar: Int + get() { + trait E: A() + + return 0 + } \ No newline at end of file diff --git a/idea/testData/hierarchy/class/sub/TraitFromTrait/TraitFromTrait_verification.xml b/idea/testData/hierarchy/class/sub/TraitFromTrait/TraitFromTrait_verification.xml new file mode 100644 index 00000000000..689e0b70f8d --- /dev/null +++ b/idea/testData/hierarchy/class/sub/TraitFromTrait/TraitFromTrait_verification.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/idea/testData/hierarchy/class/sub/TraitFromTrait/main.kt b/idea/testData/hierarchy/class/sub/TraitFromTrait/main.kt new file mode 100644 index 00000000000..0d892745ad7 --- /dev/null +++ b/idea/testData/hierarchy/class/sub/TraitFromTrait/main.kt @@ -0,0 +1,26 @@ +trait A + +trait B: A + +class MyClass(a: A = run { trait X: A; object: A {} }) { + inner trait G: A {} + + { + trait C: A + } + + fun foo(a: A = run { trait X: A; object: A {} }) { + trait D: A + + val t = object { + inner trait F: A + } + } +} + +val bar: Int + get() { + trait E: A + + return 0 + } \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/hierarchy/HierarchyTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/hierarchy/HierarchyTestGenerated.java index a8e6e0d3417..013c763f96c 100644 --- a/idea/tests/org/jetbrains/jet/plugin/hierarchy/HierarchyTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/hierarchy/HierarchyTestGenerated.java @@ -184,11 +184,26 @@ public class HierarchyTestGenerated extends AbstractHierarchyTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/hierarchy/class/sub"), Pattern.compile("^([^\\.]+)$"), false); } + @TestMetadata("AllFromClass") + public void testAllFromClass() throws Exception { + doSubClassHierarchyTest("idea/testData/hierarchy/class/sub/AllFromClass"); + } + + @TestMetadata("AllFromTrait") + public void testAllFromTrait() throws Exception { + doSubClassHierarchyTest("idea/testData/hierarchy/class/sub/AllFromTrait"); + } + @TestMetadata("ClassFromClass") public void testClassFromClass() throws Exception { doSubClassHierarchyTest("idea/testData/hierarchy/class/sub/ClassFromClass"); } + @TestMetadata("ClassFromTrait") + public void testClassFromTrait() throws Exception { + doSubClassHierarchyTest("idea/testData/hierarchy/class/sub/ClassFromTrait"); + } + @TestMetadata("ObjectFromClass") public void testObjectFromClass() throws Exception { doSubClassHierarchyTest("idea/testData/hierarchy/class/sub/ObjectFromClass"); @@ -199,6 +214,16 @@ public class HierarchyTestGenerated extends AbstractHierarchyTest { doSubClassHierarchyTest("idea/testData/hierarchy/class/sub/ObjectFromTrait"); } + @TestMetadata("TraitFromClass") + public void testTraitFromClass() throws Exception { + doSubClassHierarchyTest("idea/testData/hierarchy/class/sub/TraitFromClass"); + } + + @TestMetadata("TraitFromTrait") + public void testTraitFromTrait() throws Exception { + doSubClassHierarchyTest("idea/testData/hierarchy/class/sub/TraitFromTrait"); + } + } @TestMetadata("idea/testData/hierarchy/calls/callers")