From 894d3b07d9aa7192c16d5e401648b0f8a2d4f4b4 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 22 Oct 2013 11:27:25 +0200 Subject: [PATCH] Properly calculate short name for inner class with dollars https://github.com/JetBrains/intellij-community/pull/108 --- .../DefaultClsStubBuilderFactory.java | 5 +-- .../impl/compiled/StubBuildingVisitor.java | 41 ++++++++---------- .../testData/psi/cls/mirror/KotlinFunList.txt | 27 ++++++++++++ .../KotlinFunList$ClassObject$$Empty.class | Bin 0 -> 545 bytes .../KotlinFunList$ClassObject$$Standard.class | Bin 0 -> 551 bytes .../pkg/KotlinFunList$ClassObject$.class | Bin 0 -> 408 bytes .../psi/cls/mirror/pkg/KotlinFunList.class | Bin 0 -> 404 bytes .../psi/cls/mirror/src/pkg/KotlinFunList.java | 23 ++++++++++ .../intellij/psi/ClsMirrorBuildingTest.java | 1 + 9 files changed, 70 insertions(+), 27 deletions(-) create mode 100644 java/java-tests/testData/psi/cls/mirror/KotlinFunList.txt create mode 100644 java/java-tests/testData/psi/cls/mirror/pkg/KotlinFunList$ClassObject$$Empty.class create mode 100644 java/java-tests/testData/psi/cls/mirror/pkg/KotlinFunList$ClassObject$$Standard.class create mode 100644 java/java-tests/testData/psi/cls/mirror/pkg/KotlinFunList$ClassObject$.class create mode 100644 java/java-tests/testData/psi/cls/mirror/pkg/KotlinFunList.class create mode 100644 java/java-tests/testData/psi/cls/mirror/src/pkg/KotlinFunList.java 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 0000000000000000000000000000000000000000..c945dc77c2e328427bdae60ed5639bf4caa8ed94 GIT binary patch literal 545 zcmah`+e!ja6kXfPoSdc{?P?bh8psT?dQ9;}5~86Vl-@@h?AUmexdeSy4-)jy2lP?V z9_^tLj05|!SbLqd*&m;8?*PtG%piqz9cgUD)uzCfK!Koz4>GV$1$GHW({qC0wmWcp zp~dZ$Qm#M6+<;KB$B+H$^(geDYDLPHL1_IPs1d|WjAymFR5EN34$A+H9o-R9&C$I} z$l6l5H_@=``W>h1F_LM^zH-9I=ek_)T-XEW$*Fpd>Q`qzYmIq`ptnbn-*a0s*2w?z zd=e`dScY!Ez@7mOI>B1Jn{_!HhtGuccQ*gp5ZEUa7mE;*<#^fL91UlDk~H5b0W+Y>=>*Ppn9 z(B}49Dc7H4Za_G4o*qW^n`!7t)rpiNgV6pt&>-jwF`m_$QpvDIIIjLTc5+WhwWmXu zkaMJRZ==V)>-R+8V3J{ci?Ce}G_a93eQf^)8RIs?^Sk*LuO$(K1X$5CS=- N_K-n|Kh&{{{1;eOf!+WB literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..e009afb0d2e83cb443d445b6b887b10e8673bd99 GIT binary patch literal 408 zcmah_O-sW-6r7hf-8M$s)GrkD6!7C<(6e|c7Q~{5iuX;kl&$HeBpbn>D^Y${3Z`nkob~2<@?z zCXsm}ut{()=L`EpXq{`L?FFH6cyv!_4zffMx+87WO*xNMekbFU6>prC`9uwMMf%s7 zO|==8W~2*yGLw(ehldq`EyDidVHzzN!sTea${(fDOrx*3goD3l!k_4b@E_;*vw~kX zoWkM%suuC)v|N2=do>5#;}_6#-CpI|Vj1Z0&>EwIE?mZ4zQRF(CU)52K=8TE*g^0K Dbhclj literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..7ccb27045b018d9632eb3ac03f4df3530fcb252e GIT binary patch literal 404 zcmZWlyH3ME5S&dM8yiC&KtTZl$wi=uB}x*di4+N8L6M05Y);l0b4GsfUsOmGd;lMX zSRV}`&F$>W&F2$fas$j5d-?+6g{fc!c3rPQu{-2Eysq zwT { + 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));