[java] optimizes inner class detection (IDEA-153835)
authorRoman Shevchenko <roman.shevchenko@jetbrains.com>
Tue, 5 Apr 2016 09:49:04 +0000 (11:49 +0200)
committerRoman Shevchenko <roman.shevchenko@jetbrains.com>
Tue, 5 Apr 2016 09:49:04 +0000 (11:49 +0200)
java/java-psi-impl/src/com/intellij/psi/ClassFileViewProvider.java

index 9e39182e8a533ab4a09954c25ff9bf0be7df7541..7ff44384c50d1e7dad68240e4e8b40082fd6e5c4 100644 (file)
@@ -28,6 +28,7 @@ import com.intellij.psi.impl.PsiManagerImpl;
 import com.intellij.psi.impl.compiled.ClsFileImpl;
 import com.intellij.psi.impl.file.PsiBinaryFileImpl;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.jetbrains.org.objectweb.asm.ClassReader;
 import org.jetbrains.org.objectweb.asm.ClassVisitor;
 import org.jetbrains.org.objectweb.asm.Opcodes;
@@ -59,7 +60,7 @@ public class ClassFileViewProvider extends SingleRootFileViewProvider {
 
     // skip inner, anonymous, missing and corrupted classes
     try {
-      if (!isInnerClass(file, file.contentsToByteArray(false))) {
+      if (!isInnerClass(file)) {
         return new ClsFileImpl(this);
       }
     }
@@ -70,29 +71,31 @@ public class ClassFileViewProvider extends SingleRootFileViewProvider {
     return null;
   }
 
-  /** @deprecated use {@link #isInnerClass(VirtualFile, byte[])} (to be removed in IDEA 17) */
-  @SuppressWarnings("unused")
   public static boolean isInnerClass(@NotNull VirtualFile file) {
-    try {
-      String name = file.getNameWithoutExtension();
-      int p = name.lastIndexOf('$', name.length() - 2);
-      return p > 0 && detectInnerClass(file, file.contentsToByteArray(false));
-    }
-    catch (IOException e) {
-      throw new RuntimeException(e);
-    }
+    return detectInnerClass(file, null);
   }
 
   public static boolean isInnerClass(@NotNull VirtualFile file, @NotNull byte[] content) {
+    return detectInnerClass(file, content);
+  }
+
+  private static boolean detectInnerClass(VirtualFile file, @Nullable byte[] content) {
     String name = file.getNameWithoutExtension();
     int p = name.lastIndexOf('$', name.length() - 2);
-    return p > 0 && detectInnerClass(file, content);
-  }
+    if (p <= 0) return false;
 
-  private static boolean detectInnerClass(VirtualFile file, byte[] content) {
     Boolean isInner = IS_INNER_CLASS.get(file);
     if (isInner != null) return isInner;
 
+    if (content == null) {
+      try {
+        content = file.contentsToByteArray(false);
+      }
+      catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+    }
+
     ClassReader reader = new ClassReader(content);
     final Ref<Boolean> ref = Ref.create(Boolean.FALSE);
     final String className = reader.getClassName();