mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-113062 (using file naming convention to tell top-level classes from inner)
Allows to correctly identify and parse classes with "$" abuse.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ public class DefaultClsStubBuilderFactory extends ClsStubBuilderFactory {
|
||||
try {
|
||||
final ClassReader reader = new ClassReader(bytes);
|
||||
final StubBuildingVisitor<VirtualFile> classVisitor =
|
||||
new StubBuildingVisitor<VirtualFile>(vFile, VirtualFileInnerClassStrategy.INSTANCE, file, 0, null);
|
||||
new StubBuildingVisitor<VirtualFile>(vFile, VirtualFileInnerClassStrategy.INSTANCE, file, 0, vFile.getNameWithoutExtension());
|
||||
try {
|
||||
reader.accept(classVisitor, ClassReader.SKIP_FRAMES);
|
||||
}
|
||||
|
||||
@@ -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<T> 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<T> extends ClassVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
if (!getClassName(outerName).equals(myResult.getQualifiedName())) return;
|
||||
|
||||
final T innerSource = myInnersStrategy.findInnerClass(innerName, mySource);
|
||||
if (innerSource == null) return;
|
||||
|
||||
|
||||
@@ -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 */ }
|
||||
}
|
||||
@@ -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 */ }
|
||||
}
|
||||
@@ -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 */ }
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
public class DefaultPackage {
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package pkg;
|
||||
|
||||
public class Middle$Buck {
|
||||
private static class Inner$Buck {
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user