simplify stubHierarchy anchors and remove unused ones; restore their ability to work with any JVM language element types

This commit is contained in:
peter
2016-06-08 19:25:50 +02:00
parent 6e013e9be0
commit 4c4cb2f4a2
7 changed files with 64 additions and 90 deletions
@@ -15,36 +15,15 @@
*/
package com.intellij.psi.stubsHierarchy.impl;
import com.intellij.psi.PsiClass;
import com.intellij.psi.stubs.IStubElementType;
public abstract class ClassAnchor {
public class ClassAnchor {
final int myFileId;
final int myStubId;
public static final ClassAnchor[] EMPTY_ARRAY = new ClassAnchor[0];
private ClassAnchor(int fileId) {
ClassAnchor(int fileId, int stubId) {
myFileId = fileId;
}
public static class StubClassAnchor extends ClassAnchor {
final int myStubId;
final IStubElementType myStubElementType;
StubClassAnchor(int fileId, int stubId, IStubElementType stubElementType) {
super(fileId);
myStubId = stubId;
myStubElementType = stubElementType;
}
}
static class DirectClassAnchor extends ClassAnchor {
public final PsiClass myPsiClass;
DirectClassAnchor(int fileId, PsiClass psiClass) {
super(fileId);
myPsiClass = psiClass;
}
myStubId = stubId;
}
}
@@ -15,29 +15,25 @@
*/
package com.intellij.psi.stubsHierarchy.impl;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiFileImpl;
import com.intellij.psi.impl.source.PsiFileWithStubSupport;
import com.intellij.psi.stubs.IStubElementType;
import org.jetbrains.annotations.NotNull;
import com.intellij.psi.stubs.StubBase;
import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.stubs.StubTree;
import java.util.List;
public class ClassAnchorUtil {
public static PsiClass retrieve(Project project, SmartClassAnchor anchor) {
if (anchor instanceof SmartClassAnchor.DirectSmartClassAnchor) {
return ((SmartClassAnchor.DirectSmartClassAnchor)anchor).myPsiClass;
}
if (anchor instanceof SmartClassAnchor.StubSmartClassAnchor) {
SmartClassAnchor.StubSmartClassAnchor stubAnchor = (SmartClassAnchor.StubSmartClassAnchor)anchor;
VirtualFile file = PersistentFS.getInstance().findFileById(stubAnchor.myFileId);
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
return (PsiClass) restoreFromStubIndex((PsiFileWithStubSupport)psiFile, stubAnchor.myStubId, stubAnchor.myStubElementType);
}
return null;
PsiFile psiFile = PsiManager.getInstance(project).findFile(anchor.retrieveFile());
assert psiFile != null;
return (PsiClass)restoreFromStubIndex((PsiFileWithStubSupport)psiFile, anchor.myStubId);
}
public static PsiClass retrieveInReadAction(final Project project, final SmartClassAnchor anchor) {
@@ -49,7 +45,35 @@ public class ClassAnchorUtil {
});
}
private static PsiElement restoreFromStubIndex(@NotNull PsiFileWithStubSupport fileImpl, int index, IStubElementType stubElementType) {
return PsiAnchor.restoreFromStubIndex(fileImpl, index, stubElementType, false);
private static PsiElement restoreFromStubIndex(PsiFileWithStubSupport fileImpl, int index) {
StubTree tree = fileImpl.getStubTree();
boolean foreign = tree == null;
if (foreign) {
if (fileImpl instanceof PsiFileImpl) {
tree = ((PsiFileImpl)fileImpl).calcStubTree();
}
else {
return null;
}
}
List<StubElement<?>> list = tree.getPlainList();
if (index >= list.size()) {
return null;
}
StubElement stub = list.get(index);
if (foreign) {
final PsiElement cachedPsi = ((StubBase)stub).getCachedPsi();
if (cachedPsi != null) return cachedPsi;
final ASTNode ast = fileImpl.findTreeForStub(tree, stub);
if (ast != null) {
return ast.getPsi();
}
return null;
}
return stub.getPsi();
}
}
@@ -15,51 +15,32 @@
*/
package com.intellij.psi.stubsHierarchy.impl;
import com.intellij.psi.PsiClass;
import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.stubsHierarchy.impl.ClassAnchor.DirectClassAnchor;
import com.intellij.psi.stubsHierarchy.impl.ClassAnchor.StubClassAnchor;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
import org.jetbrains.annotations.NotNull;
public class SmartClassAnchor {
public static final SmartClassAnchor[] EMPTY_ARRAY = new SmartClassAnchor[0];
public final int myId;
public final int myFileId;
final int myStubId;
private SmartClassAnchor(int id, int fileId) {
myId = id;
myFileId = fileId;
SmartClassAnchor(int symbolId, ClassAnchor classAnchor) {
myId = symbolId;
myFileId = classAnchor.myFileId;
myStubId = classAnchor.myStubId;
}
static class StubSmartClassAnchor extends SmartClassAnchor {
final int myStubId;
final IStubElementType myStubElementType;
StubSmartClassAnchor(int id, int fileId, int stubId, IStubElementType stubElementType) {
super(id, fileId);
myStubId = stubId;
myStubElementType = stubElementType;
}
@NotNull
VirtualFile retrieveFile() {
VirtualFile file = PersistentFS.getInstance().findFileById(myFileId);
assert file != null;
return file;
}
static class DirectSmartClassAnchor extends SmartClassAnchor {
public final PsiClass myPsiClass;
DirectSmartClassAnchor(int id, int fileId, PsiClass psiClass) {
super(id, fileId);
myPsiClass = psiClass;
}
@Override
public String toString() {
return myStubId + " in " + retrieveFile().getPath();
}
static SmartClassAnchor create(int symbolId, ClassAnchor classAnchor) {
if (classAnchor instanceof StubClassAnchor) {
return new StubSmartClassAnchor(symbolId, classAnchor.myFileId, ((StubClassAnchor)classAnchor).myStubId, ((StubClassAnchor)classAnchor).myStubElementType);
}
if (classAnchor instanceof DirectClassAnchor) {
return new DirectSmartClassAnchor(symbolId, classAnchor.myFileId, ((DirectClassAnchor)classAnchor).myPsiClass);
}
return null;
}
}
@@ -67,7 +67,7 @@ public class Symbols {
public ClassSymbol enterClass(ClassAnchor classAnchor, int flags, int shortName, Symbol owner, UnitInfo info, QualifiedName[] supers, HierarchyConnector connector) {
QualifiedName qualifiedName = myNameEnvironment.qualifiedName(owner, shortName);
SmartClassAnchor smartClassAnchor = SmartClassAnchor.create(id++, classAnchor);
SmartClassAnchor smartClassAnchor = new SmartClassAnchor(id++, classAnchor);
ClassSymbol c = new ClassSymbol(smartClassAnchor, flags, owner, qualifiedName, shortName, info, supers, connector);
putClass(c);
return c;
@@ -113,7 +113,7 @@ public class Translator {
}
}
ClassAnchor.StubClassAnchor anchor = new ClassAnchor.StubClassAnchor(fileId, def.myStubId, def.getStubElementType());
ClassAnchor anchor = new ClassAnchor(fileId, def.myStubId);
QualifiedName[] supers = superList.isEmpty() ? QualifiedName.EMPTY_ARRAY : superList.toArray(new QualifiedName[superList.size()]);
Declaration[] innerDefs = innerDefList.isEmpty() ? Declaration.EMPTY_ARRAY : innerDefList.toArray(new Declaration[innerDefList.size()]);
return new ClassDeclaration(anchor, def.myMods, name, supers, innerDefs);
@@ -21,10 +21,10 @@ import com.intellij.psi.stubsHierarchy.impl.QualifiedName;
public final class ClassDeclaration extends Declaration {
public final int mods;
public final int myName;
public final ClassAnchor.StubClassAnchor myClassAnchor;
public final ClassAnchor myClassAnchor;
public QualifiedName[] mySupers;
public ClassDeclaration(ClassAnchor.StubClassAnchor classAnchor,
public ClassDeclaration(ClassAnchor classAnchor,
int mods,
int name,
QualifiedName[] supers,