下面列出了怎么用com.intellij.psi.tree.IStubFileElementType的API类实例代码及写法,或者点击链接到github查看源代码。
public static String getFileViewProviderMismatchDiagnostics(@Nonnull FileViewProvider provider) {
Function<PsiFile, String> fileClassName = file -> file.getClass().getSimpleName();
Function<Pair<IStubFileElementType, PsiFile>, String> stubRootToString = pair -> "(" + pair.first.toString() + ", " + pair.first.getLanguage() + " -> " + fileClassName.fun(pair.second) + ")";
List<Pair<IStubFileElementType, PsiFile>> roots = StubTreeBuilder.getStubbedRoots(provider);
return "path = " +
provider.getVirtualFile().getPath() +
", stubBindingRoot = " +
fileClassName.fun(provider.getStubBindingRoot()) +
", languages = [" +
StringUtil.join(provider.getLanguages(), Language::getID, ", ") +
"], fileTypes = [" +
StringUtil.join(provider.getAllFiles(), file -> file.getFileType().getName(), ", ") +
"], files = [" +
StringUtil.join(provider.getAllFiles(), fileClassName, ", ") +
"], roots = [" +
StringUtil.join(roots, stubRootToString, ", ") +
"]";
}
@Override
public boolean canHaveStub(VirtualFile file) {
final FileType fileType = file.getFileType();
if (fileType instanceof LanguageFileType) {
Language l = ((LanguageFileType)fileType).getLanguage();
ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(l);
if (parserDefinition == null) return false;
final IFileElementType elementType = parserDefinition.getFileNodeType();
return elementType instanceof IStubFileElementType && ((IStubFileElementType)elementType).shouldBuildStubFor(file);
}
else if (fileType.isBinary()) {
final BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType);
return builder != null && builder.acceptsFile(file);
}
return false;
}
/**
* Order is deterministic. First element matches {@link FileViewProvider#getStubBindingRoot()}
*/
@Nonnull
public static List<Pair<IStubFileElementType, PsiFile>> getStubbedRoots(@Nonnull FileViewProvider viewProvider) {
final List<Trinity<Language, IStubFileElementType, PsiFile>> roots = new SmartList<>();
final PsiFile stubBindingRoot = viewProvider.getStubBindingRoot();
for (Language language : viewProvider.getLanguages()) {
final PsiFile file = viewProvider.getPsi(language);
if (file instanceof PsiFileImpl) {
final IElementType type = ((PsiFileImpl)file).getElementTypeForStubBuilder();
if (type != null) {
roots.add(Trinity.create(language, (IStubFileElementType)type, file));
}
}
}
ContainerUtil.sort(roots, (o1, o2) -> {
if (o1.third == stubBindingRoot) return o2.third == stubBindingRoot ? 0 : -1;
else if (o2.third == stubBindingRoot) return 1;
else return StringUtil.compare(o1.first.getID(), o2.first.getID(), false);
});
return ContainerUtil.map(roots, trinity -> Pair.create(trinity.second, trinity.third));
}
@Nullable
private static SmartPointerElementInfo createAnchorInfo(@Nonnull PsiElement element, @Nonnull PsiFile containingFile) {
if (element instanceof StubBasedPsiElement && containingFile instanceof PsiFileImpl) {
IStubFileElementType stubType = ((PsiFileImpl)containingFile).getElementTypeForStubBuilder();
if (stubType != null && stubType.shouldBuildStubFor(containingFile.getViewProvider().getVirtualFile())) {
StubBasedPsiElement stubPsi = (StubBasedPsiElement)element;
int stubId = PsiAnchor.calcStubIndex(stubPsi);
if (stubId != -1) {
return new AnchorElementInfo(element, (PsiFileImpl)containingFile, stubId, stubPsi.getElementType());
}
}
}
Pair<Identikit.ByAnchor, PsiElement> pair = Identikit.withAnchor(element, LanguageUtil.getRootLanguage(containingFile));
if (pair != null) {
return new AnchorElementInfo(pair.second, containingFile, pair.first);
}
return null;
}
@Nonnull
public final AstSpine getStubbedSpine() {
AstSpine result = myStubbedSpine;
if (result == null) {
PsiFileImpl file = (PsiFileImpl)getPsi();
IStubFileElementType type = file.getElementTypeForStubBuilder();
if (type == null) return AstSpine.EMPTY_SPINE;
result = RecursionManager.doPreventingRecursion(file, false, () -> new AstSpine(calcStubbedDescendants(type.getBuilder())));
if (result == null) {
throw new StackOverflowPreventedException("Endless recursion prevented");
}
myStubbedSpine = result;
}
return result;
}
public static boolean canHaveStub(@Nonnull ProjectLocator projectLocator, @Nullable Project project, @Nonnull VirtualFile file) {
FileType fileType = SubstitutedFileType.substituteFileType(file, file.getFileType(), project == null ? projectLocator.guessProjectForFile(file) : project);
if (fileType instanceof LanguageFileType) {
final Language l = ((LanguageFileType)fileType).getLanguage();
final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(l);
if (parserDefinition == null) {
return false;
}
final IFileElementType elementType = parserDefinition.getFileNodeType();
if (elementType instanceof IStubFileElementType) {
if (((IStubFileElementType)elementType).shouldBuildStubFor(file)) {
return true;
}
FileBasedIndex fileBasedIndex = FileBasedIndex.getInstance();
if (file instanceof NewVirtualFile &&
fileBasedIndex instanceof FileBasedIndexImpl &&
((FileBasedIndexImpl)fileBasedIndex).getIndex(INDEX_ID).isIndexedStateForFile(((NewVirtualFile)file).getId(), file)) {
return true;
}
}
}
final BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType);
return builder != null && builder.acceptsFile(file);
}
private static Object getVersionOwner(FileType fileType) {
Object owner = null;
if (fileType instanceof LanguageFileType) {
Language l = ((LanguageFileType)fileType).getLanguage();
ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(l);
if (parserDefinition != null) {
final IFileElementType type = parserDefinition.getFileNodeType();
if (type instanceof IStubFileElementType) {
owner = type;
}
}
}
BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType);
if (builder != null) {
owner = builder;
}
return owner;
}
public static void checkStubTextConsistency(@Nonnull PsiFile file) throws StubTextInconsistencyException {
PsiUtilCore.ensureValid(file);
FileViewProvider viewProvider = file.getViewProvider();
if (viewProvider instanceof FreeThreadedFileViewProvider || viewProvider.getVirtualFile() instanceof LightVirtualFile) return;
PsiFile bindingRoot = viewProvider.getStubBindingRoot();
if (!(bindingRoot instanceof PsiFileImpl)) return;
IStubFileElementType fileElementType = ((PsiFileImpl)bindingRoot).getElementTypeForStubBuilder();
if (fileElementType == null || !fileElementType.shouldBuildStubFor(viewProvider.getVirtualFile())) return;
List<PsiFileStub> fromText = restoreStubsFromText(viewProvider);
List<PsiFileStub> fromPsi = ContainerUtil.map(StubTreeBuilder.getStubbedRoots(viewProvider), p -> ((PsiFileImpl)p.getSecond()).calcStubTree().getRoot());
if (fromPsi.size() != fromText.size()) {
throw new StubTextInconsistencyException(
"Inconsistent stub roots: " + "PSI says it's " + ContainerUtil.map(fromPsi, s -> s.getType()) + " but re-parsing the text gives " + ContainerUtil.map(fromText, s -> s.getType()), file,
fromText, fromPsi);
}
for (int i = 0; i < fromPsi.size(); i++) {
PsiFileStub psiStub = fromPsi.get(i);
if (!DebugUtil.stubTreeToString(psiStub).equals(DebugUtil.stubTreeToString(fromText.get(i)))) {
throw new StubTextInconsistencyException("Stub is inconsistent with text in " + file.getLanguage(), file, fromText, fromPsi);
}
}
}
private static boolean canHaveStub(@Nonnull PsiFile file) {
if (!(file instanceof PsiFileImpl)) return false;
VirtualFile vFile = file.getVirtualFile();
IStubFileElementType elementType = ((PsiFileImpl)file).getElementTypeForStubBuilder();
return elementType != null && vFile != null && elementType.shouldBuildStubFor(vFile);
}
private static String info(Object owner) {
if (owner instanceof IStubFileElementType) {
return "stub:" + owner.getClass().getName();
}
else {
return "binary stub builder:" + owner.getClass().getName();
}
}
private static int version(Object owner) {
if (owner instanceof IStubFileElementType) {
IStubFileElementType elementType = (IStubFileElementType)owner;
if (elementType.getLanguage() instanceof TemplateLanguage && elementType.getStubVersion() < IStubFileElementType.getTemplateStubVersion()) {
LOG.error(elementType.getLanguage() + " stub version should call super.getStubVersion()");
}
return elementType.getStubVersion();
}
else {
return ((BinaryFileStubBuilder)owner).getStubVersion();
}
}
@NotNull
@Override
public IStubFileElementType<NASMFileStub> getType() {
return NASMFileElementType.INSTANCE;
}
@NotNull
@Override
public IStubFileElementType getType() {
return OclFileStubElementType.INSTANCE;
}
@NotNull
@Override
public IStubFileElementType getType() {
return RmlFileStubElementType.INSTANCE;
}
@Override
public IStubFileElementType<FileStub> getFileNodeType() {
return FileStub.TYPE;
}
@Override
public IStubFileElementType getType() {
return TYPE;
}
@Override
public IStubFileElementType<FileStub> getFileNodeType() {
return FileStub.TYPE;
}
@Override
public IStubFileElementType getType() {
return TYPE;
}
@Override
public IStubFileElementType getType() {
return BashElementTypes.FILE;
}
@Override
public IStubFileElementType getType()
{
return CSharpStubElements.FILE;
}
@Nonnull
@Override
public IStubFileElementType getType() {
return TYPE;
}
@Nullable
public static Stub buildStubTree(final FileContent inputData) {
Stub data = inputData.getUserData(stubElementKey);
if (data != null) return data;
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (inputData) {
data = inputData.getUserData(stubElementKey);
if (data != null) return data;
final FileType fileType = inputData.getFileType();
final BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType);
if (builder != null) {
data = builder.buildStubTree(inputData);
if (data instanceof PsiFileStubImpl && !((PsiFileStubImpl)data).rootsAreSet()) {
((PsiFileStubImpl)data).setStubRoots(new PsiFileStub[]{(PsiFileStubImpl)data});
}
}
else {
CharSequence contentAsText = inputData.getContentAsText();
PsiDependentFileContent fileContent = (PsiDependentFileContent)inputData;
PsiFile psi = fileContent.getPsiFile();
final FileViewProvider viewProvider = psi.getViewProvider();
psi = viewProvider.getStubBindingRoot();
psi.putUserData(IndexingDataKeys.FILE_TEXT_CONTENT_KEY, contentAsText);
// if we load AST, it should be easily gc-able. See PsiFileImpl.createTreeElementPointer()
psi.getManager().startBatchFilesProcessingMode();
try {
IStubFileElementType stubFileElementType = ((PsiFileImpl)psi).getElementTypeForStubBuilder();
if (stubFileElementType != null) {
final StubBuilder stubBuilder = stubFileElementType.getBuilder();
if (stubBuilder instanceof LightStubBuilder) {
LightStubBuilder.FORCED_AST.set(fileContent.getLighterAST());
}
data = stubBuilder.buildStubTree(psi);
final List<Pair<IStubFileElementType, PsiFile>> stubbedRoots = getStubbedRoots(viewProvider);
final List<PsiFileStub> stubs = new ArrayList<>(stubbedRoots.size());
stubs.add((PsiFileStub)data);
for (Pair<IStubFileElementType, PsiFile> stubbedRoot : stubbedRoots) {
final PsiFile secondaryPsi = stubbedRoot.second;
if (psi == secondaryPsi) continue;
final StubBuilder stubbedRootBuilder = stubbedRoot.first.getBuilder();
if (stubbedRootBuilder instanceof LightStubBuilder) {
LightStubBuilder.FORCED_AST.set(new TreeBackedLighterAST(secondaryPsi.getNode()));
}
final StubElement element = stubbedRootBuilder.buildStubTree(secondaryPsi);
if (element instanceof PsiFileStub) {
stubs.add((PsiFileStub)element);
}
ensureNormalizedOrder(element);
}
final PsiFileStub[] stubsArray = stubs.toArray(PsiFileStub.EMPTY_ARRAY);
for (PsiFileStub stub : stubsArray) {
if (stub instanceof PsiFileStubImpl) {
((PsiFileStubImpl)stub).setStubRoots(stubsArray);
}
}
}
}
finally {
psi.putUserData(IndexingDataKeys.FILE_TEXT_CONTENT_KEY, null);
psi.getManager().finishBatchFilesProcessingMode();
}
}
ensureNormalizedOrder(data);
inputData.putUserData(stubElementKey, data);
return data;
}
}