diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/DefaultClsStubBuilderFactory.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/DefaultClsStubBuilderFactory.java index a0a8e956e968..dd1f0e44ef5d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/DefaultClsStubBuilderFactory.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/DefaultClsStubBuilderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,9 +40,8 @@ public class DefaultClsStubBuilderFactory extends ClsStubBuilderFactory { final PsiJavaFileStubImpl file = new PsiJavaFileStubImpl("do.not.know.yet", true); try { final ClassReader reader = new ClassReader(bytes); - final StubBuildingVisitor classVisitor = - new StubBuildingVisitor(vFile, VirtualFileInnerClassStrategy.INSTANCE, file, 0); + new StubBuildingVisitor(vFile, VirtualFileInnerClassStrategy.INSTANCE, file, 0, null); try { reader.accept(classVisitor, ClassReader.SKIP_FRAMES); } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java index 7324f7bbcb4b..d65a00d165de 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java @@ -40,6 +40,8 @@ import java.util.Collections; import java.util.List; import java.util.regex.Pattern; +import static com.intellij.psi.CommonClassNames.*; + /** * @author max */ @@ -57,19 +59,21 @@ public class StubBuildingVisitor extends ClassVisitor { @NonNls private static final String SYNTHETIC_CLASS_INIT_METHOD = ""; @NonNls private static final String SYNTHETIC_INIT_METHOD = ""; + private final T mySource; private final InnerClassSourceStrategy myInnersStrategy; private final StubElement myParent; private final int myAccess; - private final T mySource; - private PsiModifierListStub myModList; + private final String myShortName; private PsiClassStub myResult; + private PsiModifierListStub myModList; - public StubBuildingVisitor(final T classSource, InnerClassSourceStrategy innersStrategy, final StubElement parent, final int access) { + public StubBuildingVisitor(T classSource, InnerClassSourceStrategy innersStrategy, StubElement parent, int access, String shortName) { super(Opcodes.ASM4); mySource = classSource; myInnersStrategy = innersStrategy; myParent = parent; myAccess = access; + myShortName = shortName; } public PsiClassStub getResult() { @@ -77,25 +81,17 @@ public class StubBuildingVisitor extends ClassVisitor { } @Override - public void visit(final int version, - final int access, - final String name, - final String signature, - final String superName, - final String[] interfaces) { + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { String fqn = getClassName(name); + String shortName = myShortName != null ? myShortName : PsiNameHelper.getShortClassName(fqn); - final String shortName = PsiNameHelper.getShortClassName(fqn); - - final int flags = myAccess == 0 ? access : myAccess; - + int flags = myAccess == 0 ? access : myAccess; boolean isDeprecated = (flags & Opcodes.ACC_DEPRECATED) != 0; boolean isInterface = (flags & Opcodes.ACC_INTERFACE) != 0; boolean isEnum = (flags & Opcodes.ACC_ENUM) != 0; boolean isAnnotationType = (flags & Opcodes.ACC_ANNOTATION) != 0; - final byte stubFlags = PsiClassStubImpl.packFlags(isDeprecated, isInterface, isEnum, false, false, isAnnotationType, false, false); - + byte stubFlags = PsiClassStubImpl.packFlags(isDeprecated, isInterface, isEnum, false, false, isAnnotationType, false, false); myResult = new PsiClassStubImpl(JavaStubElementTypes.CLASS, myParent, fqn, shortName, null, stubFlags); LanguageLevel languageLevel = convertFromVersion(version); @@ -131,16 +127,15 @@ public class StubBuildingVisitor extends ClassVisitor { if (isInterface) { if (isAnnotationType) { - convertedInterfaces.remove(CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION); + convertedInterfaces.remove(JAVA_LANG_ANNOTATION_ANNOTATION); } newReferenceList(JavaStubElementTypes.EXTENDS_LIST, myResult, ArrayUtil.toStringArray(convertedInterfaces)); newReferenceList(JavaStubElementTypes.IMPLEMENTS_LIST, myResult); } else { if (convertedSuper == null || - CommonClassNames.JAVA_LANG_OBJECT.equals(convertedSuper) || - isEnum && (CommonClassNames.JAVA_LANG_ENUM.equals(convertedSuper) || - (CommonClassNames.JAVA_LANG_ENUM + "<" + fqn + ">").equals(convertedSuper))) { + JAVA_LANG_OBJECT.equals(convertedSuper) || + isEnum && (JAVA_LANG_ENUM.equals(convertedSuper) || (JAVA_LANG_ENUM + "<" + fqn + ">").equals(convertedSuper))) { newReferenceList(JavaStubElementTypes.EXTENDS_LIST, myResult); } else { @@ -303,12 +298,10 @@ public class StubBuildingVisitor extends ClassVisitor { @Override public void visitInnerClass(final String name, final String outerName, final String innerName, final int access) { if ((access & Opcodes.ACC_SYNTHETIC) != 0) return; - if (!isCorrectName(innerName)) return; + if (!isCorrectName(innerName) || outerName == null) return; - if (innerName == null || outerName == null) return; if ((getClassName(outerName) + "." + innerName).equals(myResult.getQualifiedName())) { - // Our result is inner class - + // our result is inner class if (myParent instanceof PsiFileStub) { throw new OutOfOrderInnerClassException(); } @@ -322,7 +315,7 @@ public class StubBuildingVisitor extends ClassVisitor { final ClassReader reader = myInnersStrategy.readerForInnerClass(innerSource); if (reader == null) return; - final StubBuildingVisitor classVisitor = new StubBuildingVisitor(innerSource, myInnersStrategy, myResult, access); + final StubBuildingVisitor classVisitor = new StubBuildingVisitor(innerSource, myInnersStrategy, myResult, access, innerName); reader.accept(classVisitor, ClassReader.SKIP_FRAMES); } diff --git a/java/java-tests/testData/psi/cls/mirror/KotlinFunList.txt b/java/java-tests/testData/psi/cls/mirror/KotlinFunList.txt new file mode 100644 index 000000000000..a08328b13468 --- /dev/null +++ b/java/java-tests/testData/psi/cls/mirror/KotlinFunList.txt @@ -0,0 +1,27 @@ + + // IntelliJ API Decompiler stub source generated from a class file + // Implementation of methods is not available + +package pkg; + +public abstract class KotlinFunList { + public static pkg.KotlinFunList.ClassObject$ $classobj; + + public KotlinFunList() { /* compiled code */ } + + public static final class ClassObject$ { + public ClassObject$() { /* compiled code */ } + + public final class Standard { + final pkg.KotlinFunList.ClassObject$ this$0; + + public Standard() { /* compiled code */ } + } + + public final class Empty { + final pkg.KotlinFunList.ClassObject$ this$0; + + public Empty() { /* compiled code */ } + } + } +} diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/KotlinFunList$ClassObject$$Empty.class b/java/java-tests/testData/psi/cls/mirror/pkg/KotlinFunList$ClassObject$$Empty.class new file mode 100644 index 000000000000..c945dc77c2e3 Binary files /dev/null and b/java/java-tests/testData/psi/cls/mirror/pkg/KotlinFunList$ClassObject$$Empty.class differ diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/KotlinFunList$ClassObject$$Standard.class b/java/java-tests/testData/psi/cls/mirror/pkg/KotlinFunList$ClassObject$$Standard.class new file mode 100644 index 000000000000..6efcde3d204c Binary files /dev/null and b/java/java-tests/testData/psi/cls/mirror/pkg/KotlinFunList$ClassObject$$Standard.class differ diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/KotlinFunList$ClassObject$.class b/java/java-tests/testData/psi/cls/mirror/pkg/KotlinFunList$ClassObject$.class new file mode 100644 index 000000000000..e009afb0d2e8 Binary files /dev/null and b/java/java-tests/testData/psi/cls/mirror/pkg/KotlinFunList$ClassObject$.class differ diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/KotlinFunList.class b/java/java-tests/testData/psi/cls/mirror/pkg/KotlinFunList.class new file mode 100644 index 000000000000..7ccb27045b01 Binary files /dev/null and b/java/java-tests/testData/psi/cls/mirror/pkg/KotlinFunList.class differ diff --git a/java/java-tests/testData/psi/cls/mirror/src/pkg/KotlinFunList.java b/java/java-tests/testData/psi/cls/mirror/src/pkg/KotlinFunList.java new file mode 100644 index 000000000000..913dcfcd2f8d --- /dev/null +++ b/java/java-tests/testData/psi/cls/mirror/src/pkg/KotlinFunList.java @@ -0,0 +1,23 @@ +package pkg; + +public abstract class KotlinFunList { + public static pkg.KotlinFunList.ClassObject$ $classobj; + + public KotlinFunList() { } + + public static final class ClassObject$ { + public ClassObject$() { } + + public final class Empty { + final ClassObject$ this$0; + + public Empty() { this$0 = null; } + } + + public final class Standard { + final ClassObject$ this$0; + + public Standard() { this$0 = null; } + } + } +} diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java index a7deee87bada..b9a4a189a6b0 100644 --- a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java @@ -43,6 +43,7 @@ public class ClsMirrorBuildingTest extends LightIdeaTestCase { public void testPrimitives() { doTest(); } public void testClassRefs() { doTest(); } public void testEA46236() { doTest("ValuedEnum"); } + public void testKotlinFunList() { doTest(); } private void doTest() { doTest(getTestName(false));