下面列出了com.intellij.psi.FileViewProvider#getStubBindingRoot ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* 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));
}
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);
}
}
}
@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;
}
}