@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; }
public static int getCumulativeVersion() { int version = VERSION; for (final FileType fileType : FileTypeRegistry.getInstance().getRegisteredFileTypes()) { 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) { version += ((IStubFileElementType)type).getStubVersion(); } } } BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType); if (builder != null) { version += builder.getStubVersion(); } } return version; }
@Override @Nullable public SmartPointerElementInfo createElementInfo(@NotNull PsiElement element, @NotNull PsiFile containingFile) { if (element instanceof StubBasedPsiElement && containingFile instanceof PsiFileWithStubSupport) { PsiFileWithStubSupport stubFile = (PsiFileWithStubSupport)containingFile; StubTree stubTree = stubFile.getStubTree(); if (stubTree != null) { // use stubs when tree is not loaded StubBasedPsiElement stubPsi = (StubBasedPsiElement)element; int stubId = PsiAnchor.calcStubIndex(stubPsi); IStubElementType myStubElementType = stubPsi.getElementType(); IElementType contentElementType = ((PsiFileImpl)containingFile).getContentElementType(); if (stubId != -1 && contentElementType instanceof IStubFileElementType) { // TemplateDataElementType is not IStubFileElementType return new AnchorElementInfo(element, stubFile, stubId, myStubElementType); } } } PsiElement anchor = getAnchor(element); if (anchor != null) { return new AnchorElementInfo(anchor, containingFile); } return null; }
public static boolean canHaveStub(@NotNull VirtualFile file) { final FileType fileType = file.getFileType(); 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; } if (IndexingStamp.isFileIndexedStateCurrent(file, INDEX_ID)) { return true; } } } final BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType); return builder != null && builder.acceptsFile(file); }
public void doTest() throws Exception { final List<String> data = TestUtils.readInput(getTestDataPath() + "/" + getTestName(true) + ".test"); String fileText = data.get(0); PsiFile psiFile = TestUtils.createPseudoPhysicalGroovyFile(getProject(), fileText); ASTNode node = psiFile.getNode(); Assert.assertNotNull(node); IElementType type = node.getElementType(); Assert.assertTrue(type instanceof IStubFileElementType); IStubFileElementType stubFileType = (IStubFileElementType) type; StubBuilder builder = stubFileType.getBuilder(); StubElement element = builder.buildStubTree(psiFile); StringBuffer buffer = new StringBuffer(); getStubsTreeImpl(element, buffer, ""); String stubTree = buffer.toString().trim(); assertEquals(data.get(1), stubTree); }
@Nullable public static StubIndexReference createStubReference(@NotNull PsiElement element, @NotNull PsiFile containingFile) { if (element instanceof StubBasedPsiElement && element.isPhysical() && (element instanceof PsiCompiledElement || ((PsiFileImpl)containingFile).getContentElementType() instanceof IStubFileElementType)) { final StubBasedPsiElement elt = (StubBasedPsiElement)element; final IStubElementType elementType = elt.getElementType(); if (elt.getStub() != null || elementType.shouldCreateStub(element.getNode())) { int index = calcStubIndex((StubBasedPsiElement)element); if (index != -1) { return new StubIndexReference(containingFile, index, containingFile.getLanguage(), elementType); } } } return null; }
public static boolean canHaveStub(@NotNull VirtualFile file) { final FileType fileType = file.getFileType(); 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; } final ID indexId = IndexInfrastructure.getStubId(INDEX_ID, file.getFileType()); if (IndexingStamp.isFileIndexed(file, indexId, IndexInfrastructure.getIndexCreationStamp(indexId))) { return true; } } } final BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType); return builder != null && builder.acceptsFile(file); }
private static Map<FileType, Integer> computeVersionMap() { Map<FileType, Integer> map = new HashMap<FileType, Integer>(); for (final FileType fileType : FileTypeManager.getInstance().getRegisteredFileTypes()) { 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) { map.put(fileType, ((IStubFileElementType)type).getStubVersion()); } } } final BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType); if (builder != null) { map.put(fileType, builder.getStubVersion()); } } return map; }
@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; }
public static boolean canHaveStub(@Nonnull VirtualFile file) { final FileType fileType = file.getFileType(); 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; }
/** Order is deterministic. First element matches {@link FileViewProvider#getStubBindingRoot()} */ @NotNull public static List<Pair<IStubFileElementType, PsiFile>> getStubbedRoots(@NotNull FileViewProvider viewProvider) { final List<Trinity<Language, IStubFileElementType, PsiFile>> roots = new SmartList<Trinity<Language, IStubFileElementType, PsiFile>>(); 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, new Comparator<Trinity<Language, IStubFileElementType, PsiFile>>() { @Override public int compare(Trinity<Language, IStubFileElementType, PsiFile> o1, Trinity<Language, IStubFileElementType, PsiFile> 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, new Function<Trinity<Language, IStubFileElementType, PsiFile>, Pair<IStubFileElementType, PsiFile>>() { @Override public Pair<IStubFileElementType, PsiFile> fun(Trinity<Language, IStubFileElementType, PsiFile> trinity) { return Pair.create(trinity.second, trinity.third); } }); }
@Override public StubElement buildStubTree(@NotNull PsiFile file) { LighterAST tree = FORCED_AST.get(); if (tree == null) { FileType fileType = file.getFileType(); if (!(fileType instanceof LanguageFileType)) { LOG.error("File is not of LanguageFileType: " + fileType + ", " + file); return null; } Language language = ((LanguageFileType)fileType).getLanguage(); final IFileElementType contentType = LanguageParserDefinitions.INSTANCE.forLanguage(language).getFileNodeType(); if (!(contentType instanceof IStubFileElementType)) { LOG.error("File is not of IStubFileElementType: " + contentType + ", " + file); return null; } final FileASTNode node = file.getNode(); if (contentType instanceof ILightStubFileElementType) { tree = node.getLighterAST(); } else { tree = new TreeBackedLighterAST(node); } } else { FORCED_AST.set(null); } if (tree == null) return null; final StubElement rootStub = createStubForFile(file, tree); buildStubTree(tree, tree.getRoot(), rootStub); return rootStub; }
private static boolean canHaveStub(PsiFile file) { if (!(file instanceof PsiFileImpl)) return false; VirtualFile vFile = file.getVirtualFile(); IElementType elementType = ((PsiFileImpl)file).getContentElementType(); return elementType instanceof IStubFileElementType && vFile != null && ((IStubFileElementType)elementType).shouldBuildStubFor(vFile); }
@Override @Nullable public StubTree getStubTree() { ApplicationManager.getApplication().assertReadAccessAllowed(); if (Boolean.TRUE.equals(getUserData(BUILDING_STUB))) return null; final StubTree derefd = derefStub(); if (derefd != null) return derefd; if (getTreeElement() != null) return null; if (!(getContentElementType() instanceof IStubFileElementType)) return null; final VirtualFile vFile = getVirtualFile(); if (!(vFile instanceof VirtualFileWithId)) return null; final PsiFile stubBindingRoot = getViewProvider().getStubBindingRoot(); if (stubBindingRoot != this) { LOG.error("Attempted to create stubs for non-root file: " + this + ", stub binding root: " + stubBindingRoot); return null; } ObjectStubTree tree = StubTreeLoader.getInstance().readOrBuild(getProject(), vFile, this); if (!(tree instanceof StubTree)) return null; StubTree stubHolder = (StubTree)tree; synchronized (PsiLock.LOCK) { if (getTreeElement() != null) return null; final StubTree derefdOnLock = derefStub(); if (derefdOnLock != null) return derefdOnLock; //noinspection unchecked ((StubBase)stubHolder.getRoot()).setPsi(this); myStub = new SoftReference<StubTree>(stubHolder); return stubHolder; } }
public StubTree calcStubTree() { FileElement fileElement = calcTreeElement(); synchronized (myStubFromTreeLock) { StubTree tree = fileElement.getUserData(STUB_TREE_IN_PARSED_TREE); if (tree == null) { ApplicationManager.getApplication().assertReadAccessAllowed(); IElementType contentElementType = getContentElementType(); if (!(contentElementType instanceof IStubFileElementType)) { VirtualFile vFile = getVirtualFile(); throw new AssertionError("ContentElementType: " + contentElementType + "; file: " + this + "\n\t" + "Boolean.TRUE.equals(getUserData(BUILDING_STUB)) = " + Boolean.TRUE.equals(getUserData(BUILDING_STUB)) + "\n\t" + "getTreeElement() = " + getTreeElement() + "\n\t" + "vFile instanceof VirtualFileWithId = " + (vFile instanceof VirtualFileWithId) + "\n\t" + "StubUpdatingIndex.canHaveStub(vFile) = " + StubTreeLoader.getInstance().canHaveStub(vFile)); } StubElement currentStubTree = ((IStubFileElementType)contentElementType).getBuilder().buildStubTree(this); tree = new StubTree((PsiFileStub)currentStubTree); tree.setDebugInfo("created in calcStubTree"); try { TreeUtil.bindStubsToTree(this, tree); } catch (TreeUtil.StubBindingException e) { rebuildStub(); throw new RuntimeException("Stub and PSI element type mismatch in " + getName(), e); } fileElement.putUserData(STUB_TREE_IN_PARSED_TREE, tree); } return tree; } }
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, ", ") + "]"; }
/** 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<Trinity<Language, IStubFileElementType, PsiFile>>(); 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, new Comparator<Trinity<Language, IStubFileElementType, PsiFile>>() { @Override public int compare(Trinity<Language, IStubFileElementType, PsiFile> o1, Trinity<Language, IStubFileElementType, PsiFile> 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, new Function<Trinity<Language, IStubFileElementType, PsiFile>, Pair<IStubFileElementType, PsiFile>>() { @Override public Pair<IStubFileElementType, PsiFile> fun(Trinity<Language, IStubFileElementType, PsiFile> trinity) { return Pair.create(trinity.second, trinity.third); } }); }
private static boolean canHaveStub(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) { return ((IStubFileElementType)owner).getStubVersion(); } else { return ((BinaryFileStubBuilder)owner).getStubVersion(); } }
@Override public IStubFileElementType getType() { return RmlFileStubElementType.INSTANCE; }
@Override public IStubFileElementType<FileStub> getFileNodeType() { return FileStub.TYPE; }
@Override public IStubFileElementType getType() { return TYPE; }
public IStubFileElementType getType() { return LuaParserDefinition.LUA_FILE; }
@Override public IStubFileElementType getType() { return JavaStubElementTypes.JAVA_FILE; }
@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(); FileContentImpl fileContent = (FileContentImpl)inputData; PsiFile psi = fileContent.getPsiFileForPsiDependentIndex(); 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.getLighterASTForPsiDependentIndex()); } data = stubBuilder.buildStubTree(psi); final List<Pair<IStubFileElementType, PsiFile>> stubbedRoots = getStubbedRoots(viewProvider); final List<PsiFileStub> stubs = new ArrayList<PsiFileStub>(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); } } final PsiFileStub[] stubsArray = stubs.toArray(new PsiFileStub[stubs.size()]); for (PsiFileStub stub : stubsArray) { if (stub instanceof PsiFileStubImpl) { ((PsiFileStubImpl)stub).setStubRoots(stubsArray); } } } } finally { psi.putUserData(IndexingDataKeys.FILE_TEXT_CONTENT_KEY, null); psi.getManager().finishBatchFilesProcessingMode(); } } inputData.putUserData(stubElementKey, data); return data; } }
@Override public IStubFileElementType getType() { return (IStubFileElementType) LanguageParserDefinitions.INSTANCE.forLanguage(PythonLanguage.getInstance()).getFileNodeType(); }
@Override public IStubFileElementType getType() { return GroovyParserDefinition.GROOVY_FILE; }
@Override public IStubFileElementType getType() { return (IStubFileElementType) SchemaStubElementTypes.SCHEMA_FILE; }
@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 == null && !fileType.isBinary()) { final LanguageFileType languageFileType = (LanguageFileType)fileType; Language l = languageFileType.getLanguage(); final IFileElementType type = LanguageParserDefinitions.INSTANCE.forLanguage(l).getFileNodeType(); PsiFile psi = inputData.getPsiFile(); psi = psi.getViewProvider().getStubBindingRoot(); CharSequence contentAsText = inputData.getContentAsText(); psi.putUserData(IndexingDataKeys.FILE_TEXT_CONTENT_KEY, contentAsText); try { if (type instanceof IStubFileElementType) { data = ((IStubFileElementType)type).getBuilder().buildStubTree(psi); } else if (languageFileType instanceof SubstitutedFileType) { SubstitutedFileType substituted = (SubstitutedFileType) languageFileType; LanguageFileType original = (LanguageFileType)substituted.getOriginalFileType(); final IFileElementType originalType = LanguageParserDefinitions.INSTANCE.forLanguage(original.getLanguage()).getFileNodeType(); if (originalType instanceof IStubFileElementType) { data = ((IStubFileElementType)originalType).getBuilder().buildStubTree(psi); } } } finally { psi.putUserData(IndexingDataKeys.FILE_TEXT_CONTENT_KEY, null); } } inputData.putUserData(stubElementKey, data); return data; } }
public IStubFileElementType getType() { return GroovyParserDefinition.GROOVY_FILE; }