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 000000000000..08aec68183ac Binary files /dev/null and b/java/java-tests/testData/psi/cls/mirror/pkg/DefaultPackage.class differ diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/LocalClass$1MyRunnable.class b/java/java-tests/testData/psi/cls/mirror/pkg/LocalClass$1MyRunnable.class new file mode 100644 index 000000000000..ae380d41c837 Binary files /dev/null and b/java/java-tests/testData/psi/cls/mirror/pkg/LocalClass$1MyRunnable.class differ diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/LocalClass.class b/java/java-tests/testData/psi/cls/mirror/pkg/LocalClass.class new file mode 100644 index 000000000000..b654b6fbeba2 Binary files /dev/null and b/java/java-tests/testData/psi/cls/mirror/pkg/LocalClass.class differ 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 000000000000..3e131308b818 Binary files /dev/null and b/java/java-tests/testData/psi/cls/mirror/pkg/Middle$Buck$Inner$Buck.class differ diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/Middle$Buck.class b/java/java-tests/testData/psi/cls/mirror/pkg/Middle$Buck.class new file mode 100644 index 000000000000..d470c41c4dab Binary files /dev/null and b/java/java-tests/testData/psi/cls/mirror/pkg/Middle$Buck.class differ diff --git a/java/java-tests/testData/psi/cls/mirror/src/pkg/DefaultPackage.java b/java/java-tests/testData/psi/cls/mirror/src/pkg/DefaultPackage.java new file mode 100644 index 000000000000..afc7849374c1 --- /dev/null +++ b/java/java-tests/testData/psi/cls/mirror/src/pkg/DefaultPackage.java @@ -0,0 +1,2 @@ +public class DefaultPackage { +} diff --git a/java/java-tests/testData/psi/cls/mirror/src/pkg/LocalClass.java b/java/java-tests/testData/psi/cls/mirror/src/pkg/LocalClass.java new file mode 100644 index 000000000000..fa8e230ff60a --- /dev/null +++ b/java/java-tests/testData/psi/cls/mirror/src/pkg/LocalClass.java @@ -0,0 +1,13 @@ +package pkg; + +public class LocalClass { + public Runnable runnable() { + class MyRunnable implements Runnable { + public void run() { + System.out.println(this); + } + } + + return new MyRunnable(); + } +} diff --git a/java/java-tests/testData/psi/cls/mirror/src/pkg/Middle$Buck.java b/java/java-tests/testData/psi/cls/mirror/src/pkg/Middle$Buck.java new file mode 100644 index 000000000000..d9c6bb88ab9b --- /dev/null +++ b/java/java-tests/testData/psi/cls/mirror/src/pkg/Middle$Buck.java @@ -0,0 +1,6 @@ +package pkg; + +public class Middle$Buck { + private static class Inner$Buck { + } +} diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java index b9a4a189a6b0..234c624dcaba 100644 --- a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java @@ -44,6 +44,9 @@ public class ClsMirrorBuildingTest extends LightIdeaTestCase { public void testClassRefs() { doTest(); } public void testEA46236() { doTest("ValuedEnum"); } public void testKotlinFunList() { doTest(); } + public void testMiddle$Buck() { doTest(); } + public void testDefaultPackage() { doTest(); } + public void testLocalClass() { doTest(); } private void doTest() { doTest(getTestName(false));