From 1541fa8e3c2226b689b5a2ce548f218513cff901 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 13 Jan 2016 11:25:49 +0100 Subject: [PATCH] [java] more fool-proof inner class detection --- .../intellij/psi/ClassFileViewProvider.java | 18 ++++++------------ .../psi/cls/mirror/pkg/Groovy$Inner.class | Bin 0 -> 5318 bytes .../psi/cls/mirror/pkg/Groovy$_closure1.class | Bin 0 -> 2602 bytes .../testData/psi/cls/mirror/pkg/Groovy.class | Bin 0 -> 5138 bytes .../mirror/pkg/KindaInner$Real$Inner.class | Bin 0 -> 273 bytes .../mirror/pkg/KindaInner$RealInner$.class | Bin 0 -> 273 bytes .../psi/cls/mirror/pkg/KindaInner.class | Bin 198 -> 325 bytes .../psi/cls/mirror/src/pkg/Groovy.groovy | 6 ++++++ .../psi/cls/mirror/src/pkg/KindaInner.java | 5 ++++- .../intellij/psi/ClsMirrorBuildingTest.java | 4 ++++ 10 files changed, 20 insertions(+), 13 deletions(-) create mode 100644 java/java-tests/testData/psi/cls/mirror/pkg/Groovy$Inner.class create mode 100644 java/java-tests/testData/psi/cls/mirror/pkg/Groovy$_closure1.class create mode 100644 java/java-tests/testData/psi/cls/mirror/pkg/Groovy.class create mode 100644 java/java-tests/testData/psi/cls/mirror/pkg/KindaInner$Real$Inner.class create mode 100644 java/java-tests/testData/psi/cls/mirror/pkg/KindaInner$RealInner$.class create mode 100644 java/java-tests/testData/psi/cls/mirror/src/pkg/Groovy.groovy diff --git a/java/java-psi-impl/src/com/intellij/psi/ClassFileViewProvider.java b/java/java-psi-impl/src/com/intellij/psi/ClassFileViewProvider.java index 815f47650540..abd8fbe389d6 100644 --- a/java/java-psi-impl/src/com/intellij/psi/ClassFileViewProvider.java +++ b/java/java-psi-impl/src/com/intellij/psi/ClassFileViewProvider.java @@ -60,23 +60,18 @@ public class ClassFileViewProvider extends SingleRootFileViewProvider { public static boolean isInnerClass(@NotNull VirtualFile file) { String name = file.getNameWithoutExtension(); - int index = name.lastIndexOf('$'); - if (index > 0 && index < name.length() - 1) { - String parentName = name.substring(0, index), childName = name.substring(index + 1); - if (file.getParent().findChild(parentName + ".class") != null) { - return isInnerClass(file, parentName, childName); - } - } - return false; + return name.indexOf('$') >= 0 && detectInnerClass(file); } - private static boolean isInnerClass(VirtualFile file, final String parentName, final String childName) { + private static boolean detectInnerClass(VirtualFile file) { Boolean isInner = IS_INNER_CLASS.get(file); if (isInner != null) return isInner; final Ref ref = Ref.create(Boolean.FALSE); try { - new ClassReader(file.contentsToByteArray(false)).accept(new ClassVisitor(Opcodes.ASM5) { + ClassReader reader = new ClassReader(file.contentsToByteArray(false)); + final String className = reader.getClassName(); + reader.accept(new ClassVisitor(Opcodes.ASM5) { @Override public void visitOuterClass(String owner, String name, String desc) { ref.set(Boolean.TRUE); @@ -85,8 +80,7 @@ public class ClassFileViewProvider extends SingleRootFileViewProvider { @Override public void visitInnerClass(String name, String outer, String inner, int access) { - if ((inner == null || childName.equals(inner)) && outer != null && parentName.equals(outer.substring(outer.lastIndexOf('/') + 1)) || - inner == null && outer == null && name.substring(name.lastIndexOf('/') + 1).equals(parentName + '$' + childName)) { + if (className.equals(name)) { ref.set(Boolean.TRUE); throw new ProcessCanceledException(); } diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/Groovy$Inner.class b/java/java-tests/testData/psi/cls/mirror/pkg/Groovy$Inner.class new file mode 100644 index 0000000000000000000000000000000000000000..d0b24cbda9d0f8b4524a52ba4db1d9c938d964b0 GIT binary patch literal 5318 zcmbtY`F|AU9e&4I4tO7A{&*vh$4)Cw#g^7z!blJTi^ z0t?m2TE#>iiLz_D`CM1QESGzVgSJ4b*LH@|IeWkwHb={8tVG^vD9sdbOnIV4qK*O!G{e34!{}`C{I^Tc9@Cy3fEOG{q1>vt%B! z+%B_F$mCsXtK*pC0=Few4^($@wCLtXtaOh2W%8$e!A=8J?xCg6U9J8mP;67R%7zU(IQ z#WDMcmFN(-D{MF8I{D&IXEh)y8PM1Wtf?BW27ZUq)iY8mM6qF7t0_tpcL@-^O#-dS z1G7zrkF;N^t~bYUC$FRV5!Ov zvp8%I>@IeVI*wIz`vnHVPO2)I)^ch#X^kNp+W9JG!@U)F(u1ASlU?l5qB&y8974;w z2;KtKLyi7{fluKHxodnn#O((6#XJKqWIaXXp9Y@AGm`JCJV@@806&Z8P4e?dB$y}W<~h& z^n1ixw9mwF8j}LoSBA-~VvXV~3yZ-TI4`q$4zCz^2`6QxzB&iOp7M*5_oqy`sW$g@ zSHHLa9KUF!hreXPa&o2S$HJ}QjQYWZnoUK_>0JrQJBs30{9+ljoqnzb27Zm#V|W9< z5xB9!*l&BR+pNLu_GodS+i`4e+`ki8RpIeC`fXQn9M4%L`CSyn?|E|(q&}-$Hiu~7 z53+UM!XIZK$QU8bT7ig?KIyXuSuQ9o!Q6* zM6$JQnYs(un5~U>X0j1JCUN%^wq3-=T9Oq@dnWQqEL&T}!dHfKpc12UgbyR@Y;{ zw)z0F+Uf(0UBbVPR{Q2_@IB!umwMo@4eYH|_88lH1BAyl!aEeg@rVBphzG*PRj}QG z@$Mkl?f_!z3J{BVxiW?PydgfUA+`dDvl`+K1@SyB7QTJXsOn7K!aT^@ zT9$elH)Jm%GO<6EWiPRh;n;wa%r- literal 0 HcmV?d00001 diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/Groovy$_closure1.class b/java/java-tests/testData/psi/cls/mirror/pkg/Groovy$_closure1.class new file mode 100644 index 0000000000000000000000000000000000000000..b3299bf30e0ed67f260f73f423e0ef333bd85b19 GIT binary patch literal 2602 zcmb7GT~`}b6x}z0PBIJ-!iQFDr5Yd!v?;W;1tTHVrlN=%hsjMC8fM~TLW^Hj z-~1tcr>zT6mLE@cEq|2Db7v+Yg~7G@GBdgNoPGB>XPM)DidxmIH!MCSfid(~oYhoSH7co$yCWgUFlkzqlxCLry4t9xJS(eV*!m_e~ZY~3`7foGd$kcve@SjsT4 zPZ>_l=!R}zV;GO;Hqw2AGDCd`2V&79V8#cGH1|`AJI79R}NrtYX zfN`Us7)z!&m0`>$#>8>|Ak`NPN_Kp6gi2$mYgHb?s|@FT(|l5d63!A65qPFyS=_K0 zuE%rj!f-2la%|CgqMX6ZHi#vC7HVNvVsu8VT%09BzpEzek-E(=1LirP+5*!xpD#Bfi>(T(B+OsH6o0 zsYai6)d(R+`toyUxIz-}P3}p};2fJ4oki2JO=0f25kK2M~kzuf1Azl|JmIb&fY}Xh% zRd+mIeDUE}0uK|zGL0`yv|Ws0wEeth!P;u*M$FKA7?QIjVS}n#Hm$t6$rV(g%eaS4 zhO>u;dDAhy$;vgq4Bl-E6 zuyBK%TT!IQ&wFpK!5J$rEyX5(eCwGyG1|A`l+{c?cPjEFi@eI9Ubsw`Uxu>`~ zv5V`1AR=KgWjugEdJFI{9lXe%VqT;Ll+%TlNyJ$JI`)xub}7fy@*Y4xB|`v6$>?x& zsn9f_X7dcrIi&&yqaXZ^JB!5c?g5rpqJiWdR$M}|_($QHU-t0gPcZ*C`slffFa9Ej z#b=1_pyDEgunyfr7$XFc%P1XX?BotmTcOyu_OSh@!?crfZ_$1L SKR8bbKhj(1C4g`6E$|=5Xr_Gt literal 0 HcmV?d00001 diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/Groovy.class b/java/java-tests/testData/psi/cls/mirror/pkg/Groovy.class new file mode 100644 index 0000000000000000000000000000000000000000..12dc5f0a72c16fdbbe242f03af6d544c0b6b3d51 GIT binary patch literal 5138 zcmbVQ_kR=T9e!S0wrp`Mv6DCuqJS(L3j=nUZHZYnvPmooQE2NP^4S*1cgpExARQT< z>HKuBbfj(4Hld9J2{s`lbU~YR@3c*urhB*lKtFxnyZ59s7HP;2KHa_V_x+CNJ6}Kf z-$x$@(2oBIL<)z8lRIt88aoz-5SVjFAJdb0-5gHtIe5s(I$_ibEFN|#ymgP-->nmv z>8-SRL;}JVn4hXJ>Mxn5elTxrBKug;(VbkjE3X%e-R6)bkVskfa58HR8Y6nCm{gK% zV<=DQIm=9zX?Z?8FhCByT@-S&K;x+4=fY;b@XXwcWyS<%3=BBAQ6uf> zqXqKn5oivq3=FJUyJ5gI#teIxUMLu5`?`)bo$FV3tnFC4u2Z0XbI!~;FBPbbH}BIh z9}6M~VWAW?Y&czdKA+Ax##Y8XL*?8i9FIRoYKyl)(~M5^uf) zjvB5-OzL!`xvUfjIU~8EfR?IgNyHl@3ev+ALxz<|a2IJ_3tA;&s|4DsI$t4^ z&f2+xbNw;Lkm0d)P%k)!9Y&HNCmj&byQK;im$sxGYa&>UwHhLrAuZ_;h*wplN)(3i z5*qAV=*94spm@*7=ITDL!jO1uz{UvHgV0IFWxF(Nk(jRsLoF(ijt%CDPAq4RS%-~S zyTJOO+_Yoo%;9Pw5b%JC6Gl%}dlm3IJzm|Tg?t#-PpJytP8iz+7)?8vIPnA1`3IMj zUS1&Xil7VK0vn%CymPF;VqgyDX-_geV%g4KuIy4PVeBSOS-t4&wLIPeD}q2M8-szT zbkNX?z6es-Lk@#Rv0xkeV2YRuZ25m?D6R*(na-7nR;wCrM8Axww7^2oKlI{=HMqy@ zD%rMSI(-6zK_$H?nUZW?8C4tuGL-UF#0E_)Yw`;0lbY;jcAEOA!O)q`i+j2~%=`@Q zDGma&E3sBI92sa+YK_t-z*U`W-p4x36G206u&sh&J1m6#LG!0udHI0Ih#J6aq_Mg{ z-I$&)(b|CW%q6M(l;BXxS3!=t^FVdoZw%`GA~cEZoBWNu(;Col=G_DWnSI8j5fv z%Mw`!Q_Lr%XjWH4W| z2Fvp6@Os%D-oTEwIm=?ip0DAxvfJ0-4)Uv%fs|zqhw(-ZC~g$)8Iql^Cup&xAj>!7 zEfKs4Z{_fk=gK}WW;sXnXt)b+mwWHfFb`2F_+52?=-+t9Gix-=^_Jet%q8~yEHhI& zYhcC-5lHSY3L;qEmLW8&SYk@X+GD2Wr-X?@R!op`5AbbGOpS2LDyV!6O`+Plg+EnSD+f>WJ9~??A|7aNBxTp_!buieL{Nm~k z#TOztk8cWGSxJ*=NfySF3@jR};oH)yPvJWnzKXBO4Ex?C5O$gWK+^t@F4w&&d-dhd z*gwWk8mZw=>9DLER(UPBF6dF;m_U*6EM||XnB*>n@e8K@kY)F=;cEC5o{r#`ct+sr z3Spn+l5R7Gc335IaJy|=oMnF_u&hGkQuJAlM{zW36yyykjNkI2Mv!`qVo@KafZxf~ zc@Dq72q9l%7ok5!@GSnskgAO4v2N3p1N2{roBPU8FW)JcC0?FKQx=0~pKj;mrERZ# zP<+}d*;!*pPJU?aVOLqBh->Jp5M!#I^I(m2Z6Rq)n;4d=ht(>}|U#_njy4?!^B2cn`l*3_yOr zuf_G3jFb1{1B(4z#lDV+EO$-e!UypowLJxqp)MK literal 0 HcmV?d00001 diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/KindaInner$Real$Inner.class b/java/java-tests/testData/psi/cls/mirror/pkg/KindaInner$Real$Inner.class new file mode 100644 index 0000000000000000000000000000000000000000..0054490e431e2a92f886db0aa4f55a375666f832 GIT binary patch literal 273 zcmY+8K@Y(|5QX0qEmg|VLE_+mgI*lPMIsSGg1B$l$WlvM{4XbogCF2WiD@0M$?Ti= z&FL9$n8i(ld-YCjNBBqKs8w($a?H{R6W y%GHTb{I^0420tDLaq>Y%le;QotYlg@&@~xbT+Pp#fh;ovITRUfRt@A)K=uuSuQzi5 literal 0 HcmV?d00001 diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/KindaInner.class b/java/java-tests/testData/psi/cls/mirror/pkg/KindaInner.class index 3379de74b299445637b8cdbe9d4a00540e05b256..bcff46b721287c9951df89c22ede3e548f3ede5e 100644 GIT binary patch delta 230 zcmX@cc$CTI)W2Q(7#J8#7(}=jm>Kxl83foF1lbvc7#X;NQWJAjJoEBWix?Srz_fEt zVsUY5F*}1WR2nR*GEvl%nUjHQVxmetBZFi?cDlZIW?o7nL=xE)Y;q7)3I;} z5r~1N0cma^OBP6jL|C=9GcaxhOY;CpHn1QwP!lhZ$Hc$~6k%Wx5&|+=fS8qmgMl4L Ib1-lK02PTTo&W#< delta 102 zcmX@gbc|8-)W2Q(7#J8#7Ia(8MxUQcqY1dGP5wSPMo0P$e_T$1e5>)Mj!@? j0%Hn1QwkmLaJm>4(#1)T~c diff --git a/java/java-tests/testData/psi/cls/mirror/src/pkg/Groovy.groovy b/java/java-tests/testData/psi/cls/mirror/src/pkg/Groovy.groovy new file mode 100644 index 000000000000..0741fffd4993 --- /dev/null +++ b/java/java-tests/testData/psi/cls/mirror/src/pkg/Groovy.groovy @@ -0,0 +1,6 @@ +package pkg + +class Groovy { + static class Inner { } + Runnable r = { println("I'm runnable") } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/cls/mirror/src/pkg/KindaInner.java b/java/java-tests/testData/psi/cls/mirror/src/pkg/KindaInner.java index 7c01c26695c3..dc9a388eab52 100644 --- a/java/java-tests/testData/psi/cls/mirror/src/pkg/KindaInner.java +++ b/java/java-tests/testData/psi/cls/mirror/src/pkg/KindaInner.java @@ -1,3 +1,6 @@ package pkg; -class KindaInner { } \ No newline at end of file +class KindaInner { + static class RealInner$ { } + static class Real$Inner { } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java index 2b0fdccabfca..323f489dc5bb 100644 --- a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java @@ -166,6 +166,10 @@ public class ClsMirrorBuildingTest extends LightIdeaTestCase { assertTrue(isInner("pkg/Nested$Inner1$Inner2")); assertTrue(isInner("pkg/NormalClass$1")); assertTrue(isInner("pkg/LocalClass$1MyRunnable")); + assertTrue(isInner("pkg/KindaInner$RealInner$")); + assertTrue(isInner("pkg/KindaInner$Real$Inner")); + assertTrue(isInner("pkg/Groovy$Inner")); + assertTrue(isInner("pkg/Groovy$_closure1")); assertTrue(isInner("weird/ToStringStyle$1")); assertFalse(isInner("pkg/KindaInner$Class"));