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 000000000000..d0b24cbda9d0 Binary files /dev/null and b/java/java-tests/testData/psi/cls/mirror/pkg/Groovy$Inner.class differ 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 000000000000..b3299bf30e0e Binary files /dev/null and b/java/java-tests/testData/psi/cls/mirror/pkg/Groovy$_closure1.class differ 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 000000000000..12dc5f0a72c1 Binary files /dev/null and b/java/java-tests/testData/psi/cls/mirror/pkg/Groovy.class differ 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 000000000000..0054490e431e Binary files /dev/null and b/java/java-tests/testData/psi/cls/mirror/pkg/KindaInner$Real$Inner.class differ diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/KindaInner$RealInner$.class b/java/java-tests/testData/psi/cls/mirror/pkg/KindaInner$RealInner$.class new file mode 100644 index 000000000000..208126587756 Binary files /dev/null and b/java/java-tests/testData/psi/cls/mirror/pkg/KindaInner$RealInner$.class differ 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 3379de74b299..bcff46b72128 100644 Binary files a/java/java-tests/testData/psi/cls/mirror/pkg/KindaInner.class and b/java/java-tests/testData/psi/cls/mirror/pkg/KindaInner.class differ 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"));