direct inheritor search with javac indices: do not forget of classes declared in...
authorDmitry Batkovich <dmitry.batkovich@jetbrains.com>
Wed, 12 Oct 2016 16:19:42 +0000 (19:19 +0300)
committerDmitry Batkovich <dmitry.batkovich@jetbrains.com>
Wed, 12 Oct 2016 16:19:42 +0000 (19:19 +0300)
java/java-indexing-impl/src/com/intellij/compiler/JavaBaseCompilerSearchAdapter.java
java/java-tests/testData/compiler/bytecodeReferences/testHierarchy/Test.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/compiler/CompilerReferencesTest.java

index 1067021c5673ff97f8f97dd04f500fd26097ed1d..3a91451a8354de7dd15b644a4649c8a6832d22b3 100644 (file)
@@ -159,17 +159,26 @@ public class JavaBaseCompilerSearchAdapter implements ClassResolvingCompilerSear
       while (true) {
         int lastIndex = internalName.lastIndexOf('$', curLast);
         if (lastIndex > -1 && lastIndex < internalName.length() - 1) {
-          final boolean anonymousSign = Character.isDigit(internalName.charAt(lastIndex + 1));
-          if (anonymousSign) {
+          final int followingIndex = lastIndex + 1;
+          final boolean digit = Character.isDigit(internalName.charAt(followingIndex));
+          if (digit) {
             if (curLast == internalName.length() - 1) {
-              if (matcherBySuperNameAdded) {
+              final int nextNonDigit = getNextNonDigitIndex(internalName, followingIndex);
+              if (nextNonDigit == -1) {
+                if (matcherBySuperNameAdded) {
+                  break;
+                }
+                matcherBySuperNameAdded = true;
+                //anonymous
+                matchers.add(new InternalClassMatcher.BySuperName(baseClass.getName()));
                 break;
+              } else {
+                //declared inside method
+                matchers.add(new InternalClassMatcher.ByName(internalName.substring(nextNonDigit)));
               }
-              matcherBySuperNameAdded = true;
-              matchers.add(new InternalClassMatcher.BySuperName(baseClass.getName()));
-              break;
             }
             else {
+              //declared in anonymous
               matchers.add(new InternalClassMatcher.ByName(StringUtil.getShortName(internalName, '$')));
               break;
             }
@@ -185,6 +194,15 @@ public class JavaBaseCompilerSearchAdapter implements ClassResolvingCompilerSear
     return matchers;
   }
 
+  private static int getNextNonDigitIndex(String name, int digitIndex) {
+    for (int i = digitIndex + 1; i < name.length(); i++) {
+      if (!Character.isDigit(name.charAt(i))) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
   private interface InternalClassMatcher {
     boolean matches(PsiClassStub stub);
 
diff --git a/java/java-tests/testData/compiler/bytecodeReferences/testHierarchy/Test.java b/java/java-tests/testData/compiler/bytecodeReferences/testHierarchy/Test.java
new file mode 100644 (file)
index 0000000..d973b27
--- /dev/null
@@ -0,0 +1,9 @@
+class Test {
+
+  void m() {
+
+    class FooInsideMethodImpl extends Foo {}
+
+  }
+
+}
\ No newline at end of file
index 58386645f0d500eee40a600b4607eec87ef3e84d..7cfe4c2bb4509ab3080f7a5edea430eab3a1e80f 100644 (file)
@@ -80,17 +80,17 @@ public class CompilerReferencesTest extends AbstractCompilerAwareTest {
   }
 
   public void testHierarchy() {
-    myFixture.configureByFiles(getName() + "/Foo.java", getName() + "/FooImpl.java", getName() + "/Bar.java", getName() + "/Baz.java");
+    myFixture.configureByFiles(getName() + "/Foo.java", getName() + "/FooImpl.java", getName() + "/Bar.java", getName() + "/Baz.java", getName() + "/Test.java");
     rebuildProject();
     CompilerReferenceService.CompilerDirectInheritorInfo<PsiClass> directInheritorInfo = getHierarchyUnderForElementCaret();
 
     Collection<PsiClass> inheritors = directInheritorInfo.getDirectInheritors().collect(Collectors.toList());
-    assertSize(4, inheritors);
+    assertSize(6, inheritors);
     for (PsiClass inheritor : inheritors) {
       if (inheritor instanceof PsiAnonymousClass) {
         assertOneOf(inheritor.getTextOffset(), 58, 42, 94);
       } else {
-        assertOneOf(inheritor.getQualifiedName(), "FooImpl", "FooImpl2");
+        assertOneOf(inheritor.getName(), "FooImpl", "FooImpl2", "FooInsideMethodImpl");
       }
     }