From 4645f02b2b9b4d8aa8742eb259b3e99a29976074 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Sat, 16 Nov 2013 19:01:13 +0100 Subject: [PATCH] IDEA-113062 (using file naming convention to tell top-level classes from inner) Allows to correctly identify and parse classes with "$" abuse. --- .../intellij/psi/ClassFileViewProvider.java | 23 +++++++++--------- .../impl/compiled/ClassFileStubBuilder.java | 3 ++- .../DefaultClsStubBuilderFactory.java | 2 +- .../impl/compiled/StubBuildingVisitor.java | 17 +++++++++---- .../psi/cls/mirror/DefaultPackage.txt | 7 ++++++ .../testData/psi/cls/mirror/LocalClass.txt | 11 +++++++++ .../testData/psi/cls/mirror/Middle$Buck.txt | 13 ++++++++++ .../psi/cls/mirror/pkg/DefaultPackage.class | Bin 0 -> 202 bytes .../mirror/pkg/LocalClass$1MyRunnable.class | Bin 0 -> 629 bytes .../psi/cls/mirror/pkg/LocalClass.class | Bin 0 -> 389 bytes .../mirror/pkg/Middle$Buck$Inner$Buck.class | Bin 0 -> 276 bytes .../psi/cls/mirror/pkg/Middle$Buck.class | Bin 0 -> 280 bytes .../cls/mirror/src/pkg/DefaultPackage.java | 2 ++ .../psi/cls/mirror/src/pkg/LocalClass.java | 13 ++++++++++ .../psi/cls/mirror/src/pkg/Middle$Buck.java | 6 +++++ .../intellij/psi/ClsMirrorBuildingTest.java | 3 +++ 16 files changed, 82 insertions(+), 18 deletions(-) create mode 100644 java/java-tests/testData/psi/cls/mirror/DefaultPackage.txt create mode 100644 java/java-tests/testData/psi/cls/mirror/LocalClass.txt create mode 100644 java/java-tests/testData/psi/cls/mirror/Middle$Buck.txt create mode 100644 java/java-tests/testData/psi/cls/mirror/pkg/DefaultPackage.class create mode 100644 java/java-tests/testData/psi/cls/mirror/pkg/LocalClass$1MyRunnable.class create mode 100644 java/java-tests/testData/psi/cls/mirror/pkg/LocalClass.class create mode 100644 java/java-tests/testData/psi/cls/mirror/pkg/Middle$Buck$Inner$Buck.class create mode 100644 java/java-tests/testData/psi/cls/mirror/pkg/Middle$Buck.class create mode 100644 java/java-tests/testData/psi/cls/mirror/src/pkg/DefaultPackage.java create mode 100644 java/java-tests/testData/psi/cls/mirror/src/pkg/LocalClass.java create mode 100644 java/java-tests/testData/psi/cls/mirror/src/pkg/Middle$Buck.java 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 43c4036ef814..27e4b34253a2 100644 --- a/java/java-psi-impl/src/com/intellij/psi/ClassFileViewProvider.java +++ b/java/java-psi-impl/src/com/intellij/psi/ClassFileViewProvider.java @@ -20,7 +20,6 @@ import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.impl.PsiManagerImpl; import com.intellij.psi.impl.compiled.ClsFileImpl; import org.jetbrains.annotations.NotNull; @@ -38,20 +37,22 @@ public class ClassFileViewProvider extends SingleRootFileViewProvider { @Override protected PsiFile createFile(@NotNull final Project project, @NotNull final VirtualFile vFile, @NotNull final FileType fileType) { - final FileIndexFacade fileIndex = ServiceManager.getService(project, FileIndexFacade.class); - if (fileIndex.isInLibraryClasses(vFile) || !fileIndex.isInSource(vFile)) { - String name = vFile.getName(); + FileIndexFacade fileIndex = ServiceManager.getService(project, FileIndexFacade.class); + if (!fileIndex.isInLibraryClasses(vFile) && fileIndex.isInSource(vFile)) { + return null; + } - // skip inners & anonymous (todo: read actual class name from file) - int dotIndex = name.lastIndexOf('.'); - if (dotIndex < 0) dotIndex = name.length(); - int index = name.lastIndexOf('$', dotIndex); - if (index <= 0 || index == dotIndex - 1) { - return new ClsFileImpl((PsiManagerImpl)PsiManager.getInstance(project), this); + // skip inners & anonymous + String name = vFile.getNameWithoutExtension(); + int index = name.lastIndexOf('$', name.length()); + if (index > 0 && index < name.length() - 1) { + String supposedParentName = name.substring(0, index) + ".class"; + if (vFile.getParent().findChild(supposedParentName) != null) { + return null; } } - return null; + return new ClsFileImpl(PsiManager.getInstance(project), this); } @NotNull diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java index 68e5b0f02ec7..27acff68612e 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java @@ -31,7 +31,8 @@ import com.intellij.util.indexing.FileContent; */ public class ClassFileStubBuilder implements BinaryFileStubBuilder { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClassFileStubBuilder"); - public static final int STUB_VERSION = JavaFileElementType.STUB_VERSION + 6; + + public static final int STUB_VERSION = JavaFileElementType.STUB_VERSION + 7; @Override public boolean acceptsFile(final VirtualFile file) { 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 dd1f0e44ef5d..c0bcba0f8502 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 @@ -41,7 +41,7 @@ public class DefaultClsStubBuilderFactory extends ClsStubBuilderFactory { try { final ClassReader reader = new ClassReader(bytes); final StubBuildingVisitor classVisitor = - new StubBuildingVisitor(vFile, VirtualFileInnerClassStrategy.INSTANCE, file, 0, null); + new StubBuildingVisitor(vFile, VirtualFileInnerClassStrategy.INSTANCE, file, 0, vFile.getNameWithoutExtension()); 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 d65a00d165de..e9ddcc149f8c 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 @@ -17,7 +17,8 @@ package com.intellij.psi.impl.compiled; import com.intellij.openapi.util.text.StringUtil; import com.intellij.pom.java.LanguageLevel; -import com.intellij.psi.*; +import com.intellij.psi.PsiNameHelper; +import com.intellij.psi.PsiReferenceList; import com.intellij.psi.impl.cache.ModifierFlags; import com.intellij.psi.impl.cache.TypeInfo; import com.intellij.psi.impl.java.stubs.*; @@ -82,8 +83,16 @@ public class StubBuildingVisitor extends ClassVisitor { @Override 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); + String fqn, shortName; + if (myShortName != null && name.endsWith(myShortName)) { + shortName = myShortName; + fqn = name.length() == shortName.length() + ? shortName : getClassName(name.substring(0, name.length() - shortName.length() - 1)) + "." + shortName; + } + else { + fqn = getClassName(name); + shortName = PsiNameHelper.getShortClassName(fqn); + } int flags = myAccess == 0 ? access : myAccess; boolean isDeprecated = (flags & Opcodes.ACC_DEPRECATED) != 0; @@ -307,8 +316,6 @@ public class StubBuildingVisitor extends ClassVisitor { } } - if (!getClassName(outerName).equals(myResult.getQualifiedName())) return; - final T innerSource = myInnersStrategy.findInnerClass(innerName, mySource); if (innerSource == null) return; diff --git a/java/java-tests/testData/psi/cls/mirror/DefaultPackage.txt b/java/java-tests/testData/psi/cls/mirror/DefaultPackage.txt new file mode 100644 index 000000000000..453e8668ee74 --- /dev/null +++ b/java/java-tests/testData/psi/cls/mirror/DefaultPackage.txt @@ -0,0 +1,7 @@ + + // IntelliJ API Decompiler stub source generated from a class file + // Implementation of methods is not available + +public class DefaultPackage { + public DefaultPackage() { /* compiled code */ } +} diff --git a/java/java-tests/testData/psi/cls/mirror/LocalClass.txt b/java/java-tests/testData/psi/cls/mirror/LocalClass.txt new file mode 100644 index 000000000000..a53c42cec1dd --- /dev/null +++ b/java/java-tests/testData/psi/cls/mirror/LocalClass.txt @@ -0,0 +1,11 @@ + + // IntelliJ API Decompiler stub source generated from a class file + // Implementation of methods is not available + +package pkg; + +public class LocalClass { + public LocalClass() { /* compiled code */ } + + public java.lang.Runnable runnable() { /* compiled code */ } +} diff --git a/java/java-tests/testData/psi/cls/mirror/Middle$Buck.txt b/java/java-tests/testData/psi/cls/mirror/Middle$Buck.txt new file mode 100644 index 000000000000..3d9b279a4ace --- /dev/null +++ b/java/java-tests/testData/psi/cls/mirror/Middle$Buck.txt @@ -0,0 +1,13 @@ + + // IntelliJ API Decompiler stub source generated from a class file + // Implementation of methods is not available + +package pkg; + +public class Middle$Buck { + public Middle$Buck() { /* compiled code */ } + + private static class Inner$Buck { + private Inner$Buck() { /* compiled code */ } + } +} diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/DefaultPackage.class b/java/java-tests/testData/psi/cls/mirror/pkg/DefaultPackage.class new file mode 100644 index 0000000000000000000000000000000000000000..08aec68183ac00f92784281d5e9bf5fbfe66ec05 GIT binary patch literal 202 zcmX^0Z`VEs1_omWUM>b^1}=66ZgvJ9Mg}&U%)HDJJ4Oa(4b3n{1{UZ1lvG9rexJ;| zRKL>Pq|~C2#H1Xc2v=}^X;E^jTPBDj?2?+6SejE3keHmEn4YSal~|U@!@$D8%E-Wn zD#gek0Fuq9#800e+Nm z3M7C&?C$KDGw1Bge*b)a0XRo7iZId&BFIFshIIuS$V%9hup?oYA>#H7r*O)Us12XG z<(k#j&8n$8PK9z8hA`YqhLrXm0KO~CTVB0b?7R{7pGgxhd!t`DdnHI`X~8Kj|4GHHHkZO&-&-b%5F9Q|hm zLqiUn1=Py{!#rlP3#c5>ja@!hh4=pnal}&KU$|o!30Az z`1g7lAf3kQaJ9!y?9GE$(2_TV4y(0lnyfB1ST#C?u7UPDj6257#Xr2mv%B0g;K62h J7&q80;2YbmO_2Zq literal 0 HcmV?d00001 diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/Middle$Buck$Inner$Buck.class b/java/java-tests/testData/psi/cls/mirror/pkg/Middle$Buck$Inner$Buck.class new file mode 100644 index 0000000000000000000000000000000000000000..3e131308b8187ec5e2aa15ddfe5854a3ccfe9036 GIT binary patch literal 276 zcmZ9GPY=OB5XIkCwXCA95{ZKY4tj7E2NH?Ip968lf=OX@S()CCozY4 z`+GBaJMYi)1z?Br8!kiha@>1A&I9;R2PfMo z&cLwW{QnHIkN@940N-c}6i|23aM5(pB8ZtWD(Q{0@Ide^Ok$a)DkYSEw9%Ilq0k>} z3B}1NQiSGQ8@0@ifl4+qh`A%yrz{E8ROirI=qQSn-T1YaSLwk;g~!f^o&Tn>Ggtjs znw`H2_A0y(Iv=Lq>pFDd@a=gJC-3B1W$Ic6O2a$oW@W)uupK;5