duplicate code: reuse PsiAnchor

This commit is contained in:
Alexey Kudravtsev
2016-04-27 13:31:03 +03:00
parent b3a9c321e4
commit 56cf5f8ee8
6 changed files with 52 additions and 69 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,29 +16,32 @@
package com.intellij.psi.stubsHierarchy.impl;
import com.intellij.psi.PsiClass;
import com.intellij.psi.stubs.IStubElementType;
public abstract class ClassAnchor {
public final int myFileId;
final int myFileId;
public final static ClassAnchor[] EMPTY_ARRAY = new ClassAnchor[0];
public static final ClassAnchor[] EMPTY_ARRAY = new ClassAnchor[0];
protected ClassAnchor(int fileId) {
private ClassAnchor(int fileId) {
myFileId = fileId;
}
public static class StubClassAnchor extends ClassAnchor {
public final int myStubId;
final int myStubId;
final IStubElementType myStubElementType;
public StubClassAnchor(int fileId, int stubId) {
StubClassAnchor(int fileId, int stubId, IStubElementType stubElementType) {
super(fileId);
this.myStubId = stubId;
myStubId = stubId;
myStubElementType = stubElementType;
}
}
public static class DirectClassAnchor extends ClassAnchor {
static class DirectClassAnchor extends ClassAnchor {
public final PsiClass myPsiClass;
public DirectClassAnchor(int fileId, PsiClass psiClass) {
DirectClassAnchor(int fileId, PsiClass psiClass) {
super(fileId);
myPsiClass = psiClass;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,31 +15,27 @@
*/
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.StubBase;
import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.stubs.StubTree;
import java.util.List;
import com.intellij.psi.stubs.IStubElementType;
import org.jetbrains.annotations.NotNull;
public class ClassAnchorUtil {
public static PsiClass retrieve(Project project, SmartClassAnchor anchor) {
if (anchor instanceof SmartClassAnchor.DirectSmartClassAnchor) {
return ((SmartClassAnchor.DirectSmartClassAnchor)anchor).myPsiClass;
} else if (anchor instanceof SmartClassAnchor.StubSmartClassAnchor) {
SmartClassAnchor.StubSmartClassAnchor stubAnchor = ((SmartClassAnchor.StubSmartClassAnchor)anchor);
}
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);
return (PsiClass) restoreFromStubIndex((PsiFileWithStubSupport)psiFile, stubAnchor.myStubId, stubAnchor.myStubElementType);
}
return null;
}
@@ -53,35 +49,7 @@ public class ClassAnchorUtil {
});
}
public 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();
private static PsiElement restoreFromStubIndex(@NotNull PsiFileWithStubSupport fileImpl, int index, IStubElementType stubElementType) {
return PsiAnchor.restoreFromStubIndex(fileImpl, index, stubElementType, false);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,33 +16,37 @@
package com.intellij.psi.stubsHierarchy.impl;
import com.intellij.psi.PsiClass;
import com.intellij.psi.stubsHierarchy.impl.ClassAnchor.*;
import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.stubsHierarchy.impl.ClassAnchor.DirectClassAnchor;
import com.intellij.psi.stubsHierarchy.impl.ClassAnchor.StubClassAnchor;
public class SmartClassAnchor {
public final static SmartClassAnchor[] EMPTY_ARRAY = new SmartClassAnchor[0];
public static final SmartClassAnchor[] EMPTY_ARRAY = new SmartClassAnchor[0];
public final int myId;
public final int myFileId;
public SmartClassAnchor(int id, int fileId) {
this.myId = id;
private SmartClassAnchor(int id, int fileId) {
myId = id;
myFileId = fileId;
}
public static class StubSmartClassAnchor extends SmartClassAnchor {
public final int myStubId;
static class StubSmartClassAnchor extends SmartClassAnchor {
final int myStubId;
final IStubElementType myStubElementType;
public StubSmartClassAnchor(int id, int fileId, int stubId) {
StubSmartClassAnchor(int id, int fileId, int stubId, IStubElementType stubElementType) {
super(id, fileId);
myStubId = stubId;
myStubElementType = stubElementType;
}
}
public static class DirectSmartClassAnchor extends SmartClassAnchor {
static class DirectSmartClassAnchor extends SmartClassAnchor {
public final PsiClass myPsiClass;
public DirectSmartClassAnchor(int id, int fileId, PsiClass psiClass) {
DirectSmartClassAnchor(int id, int fileId, PsiClass psiClass) {
super(id, fileId);
myPsiClass = psiClass;
}
@@ -50,7 +54,7 @@ public class SmartClassAnchor {
static SmartClassAnchor create(int symbolId, ClassAnchor classAnchor) {
if (classAnchor instanceof StubClassAnchor) {
return new StubSmartClassAnchor(symbolId, classAnchor.myFileId, ((StubClassAnchor)classAnchor).myStubId);
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);
@@ -113,7 +113,7 @@ public class Translator {
}
}
ClassAnchor.StubClassAnchor anchor = new ClassAnchor.StubClassAnchor(fileId, def.myStubId);
ClassAnchor.StubClassAnchor anchor = new ClassAnchor.StubClassAnchor(fileId, def.myStubId, def.getStubElementType());
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);
@@ -16,6 +16,10 @@
package com.intellij.psi.impl.java.stubs.hierarchy;
import com.intellij.psi.impl.java.stubs.JavaClassElementType;
import com.intellij.psi.stubs.IStubElementType;
import com.intellij.util.BitUtil;
import java.util.Arrays;
public class IndexTree {
@@ -135,6 +139,13 @@ public class IndexTree {
this.mySupers = supers;
}
public IStubElementType getStubElementType() {
boolean isEnum = BitUtil.isSet(myMods, IndexTree.ENUM);
boolean isAnonymous = false;
return JavaClassElementType.typeForClass(isAnonymous, isEnum);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -116,7 +116,7 @@ public abstract class PsiAnchor {
}
@NotNull
public static PsiAnchor wrapperOrHardReference(@NotNull PsiElement element) {
private static PsiAnchor wrapperOrHardReference(@NotNull PsiElement element) {
for (SmartPointerAnchorProvider provider : SmartPointerAnchorProvider.EP_NAME.getExtensions()) {
PsiElement anchorElement = provider.getAnchor(element);
if (anchorElement != null && anchorElement != element) {
@@ -399,7 +399,8 @@ public abstract class PsiAnchor {
@Nullable
public static PsiElement restoreFromStubIndex(PsiFileWithStubSupport fileImpl,
int index,
@NotNull IStubElementType elementType, boolean throwIfNull) {
@NotNull IStubElementType elementType,
boolean throwIfNull) {
if (fileImpl == null) {
if (throwIfNull) throw new AssertionError("Null file");
return null;
@@ -504,11 +505,7 @@ public abstract class PsiAnchor {
}
catch (AssertionError e) {
String msg = e.getMessage();
if (file == null) {
msg += "\n no PSI file";
} else {
msg += "\n current file stamp=" + (short)file.getModificationStamp();
}
msg += file == null ? "\n no PSI file" : "\n current file stamp=" + (short)file.getModificationStamp();
final Document document = FileDocumentManager.getInstance().getCachedDocument(myVirtualFile);
if (document != null) {
msg += "\n committed=" + PsiDocumentManager.getInstance(myProject).isCommitted(document);