@Nullable @Override public RefEntity getReference(final String type, final String fqName) { for (RefManagerExtension extension : myExtensions.values()) { final RefEntity refEntity = extension.getReference(type, fqName); if (refEntity != null) return refEntity; } if (SmartRefElementPointer.FILE.equals(type)) { return RefFileImpl.fileFromExternalName(this, fqName); } if (SmartRefElementPointer.MODULE.equals(type)) { return RefModuleImpl.moduleFromName(this, fqName); } if (SmartRefElementPointer.PROJECT.equals(type)) { return getRefProject(); } if (SmartRefElementPointer.DIR.equals(type)) { String url = VfsUtilCore.pathToUrl(PathMacroManager.getInstance(getProject()).expandPath(fqName)); VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(url); if (vFile != null) { final PsiDirectory dir = PsiManager.getInstance(getProject()).findDirectory(vFile); return getReference(dir); } } return null; }
private boolean belongsToScope(final PsiElement psiElement, final boolean ignoreScope) { if (psiElement == null || !psiElement.isValid()) return false; if (psiElement instanceof PsiCompiledElement) return false; final PsiFile containingFile = ApplicationManager.getApplication() .runReadAction( new Computable<PsiFile>() { @Override public PsiFile compute() { return psiElement.getContainingFile(); } }); if (containingFile == null) { return false; } for (RefManagerExtension extension : myExtensions.values()) { if (!extension.belongsToScope(psiElement)) return false; } final Boolean inProject = ApplicationManager.getApplication() .runReadAction( new Computable<Boolean>() { @Override public Boolean compute() { return psiElement.getManager().isInProject(psiElement); } }); return inProject.booleanValue() && (ignoreScope || getScope() == null || getScope().contains(psiElement)); }
@NotNull @Override public RefEntity getRefinedElement(@NotNull RefEntity ref) { for (RefManagerExtension extension : myExtensions.values()) { ref = extension.getRefinedElement(ref); } return ref; }
@Override public void visitElement(PsiElement element) { final RefManagerExtension extension = getExtension(element.getLanguage()); if (extension != null) { extension.visitElement(element); } for (PsiElement aChildren : element.getChildren()) { aChildren.accept(this); } }
@Override public Element export( @NotNull RefEntity refEntity, @NotNull final Element element, final int actualLine) { refEntity = getRefinedElement(refEntity); Element problem = new Element("problem"); if (refEntity instanceof RefElement) { final RefElement refElement = (RefElement) refEntity; final SmartPsiElementPointer pointer = refElement.getPointer(); PsiFile psiFile = pointer.getContainingFile(); if (psiFile == null) return null; Element fileElement = new Element("file"); Element lineElement = new Element("line"); final VirtualFile virtualFile = psiFile.getVirtualFile(); LOG.assertTrue(virtualFile != null); fileElement.addContent(virtualFile.getUrl()); if (actualLine == -1) { final Document document = PsiDocumentManager.getInstance(pointer.getProject()).getDocument(psiFile); LOG.assertTrue(document != null); final Segment range = pointer.getRange(); lineElement.addContent( String.valueOf( range != null ? document.getLineNumber(range.getStartOffset()) + 1 : -1)); } else { lineElement.addContent(String.valueOf(actualLine)); } problem.addContent(fileElement); problem.addContent(lineElement); appendModule(problem, refElement.getModule()); } else if (refEntity instanceof RefModule) { final RefModule refModule = (RefModule) refEntity; final VirtualFile moduleFile = refModule.getModule().getModuleFile(); final Element fileElement = new Element("file"); fileElement.addContent(moduleFile != null ? moduleFile.getUrl() : refEntity.getName()); problem.addContent(fileElement); appendModule(problem, refModule); } for (RefManagerExtension extension : myExtensions.values()) { extension.export(refEntity, problem); } new SmartRefElementPointerImpl(refEntity, true).writeExternal(problem); element.addContent(problem); return problem; }
@Override public void iterate(@NotNull RefVisitor visitor) { for (RefElement refElement : getSortedElements()) { refElement.accept(visitor); } if (myModules != null) { for (RefModule refModule : myModules.values()) { refModule.accept(visitor); } } for (RefManagerExtension extension : myExtensions.values()) { extension.iterate(visitor); } }
public void cleanup() { myScope = null; myRefProject = null; synchronized (myRefTable) { myRefTable.clear(); mySortedRefs = null; } myModules.clear(); myContext = null; myGraphAnnotators.clear(); for (RefManagerExtension extension : myExtensions.values()) { extension.cleanup(); } }
@Nullable public RefElement getReference(final PsiElement elem, final boolean ignoreScope) { if (ApplicationManager.getApplication() .runReadAction( new Computable<Boolean>() { @Override public Boolean compute() { return elem == null || !elem.isValid() || elem instanceof LightElement || !(elem instanceof PsiDirectory) && !belongsToScope(elem, ignoreScope); } })) { return null; } return getFromRefTableOrCache( elem, () -> ApplicationManager.getApplication() .runReadAction( new Computable<RefElementImpl>() { @Override @Nullable public RefElementImpl compute() { final RefManagerExtension extension = getExtension(elem.getLanguage()); if (extension != null) { final RefElement refElement = extension.createRefElement(elem); if (refElement != null) return (RefElementImpl) refElement; } if (elem instanceof PsiFile) { return new RefFileImpl((PsiFile) elem, RefManagerImpl.this); } if (elem instanceof PsiDirectory) { return new RefDirectoryImpl((PsiDirectory) elem, RefManagerImpl.this); } return null; } }), element -> { element.initialize(); for (RefManagerExtension each : myExtensions.values()) { each.onEntityInitialized(element, elem); } fireNodeInitialized(element); }); }
@Override @Nullable public String getGroupName(final RefElement entity) { for (RefManagerExtension extension : myExtensions.values()) { final String groupName = extension.getGroupName(entity); if (groupName != null) return groupName; } final LinkedList<String> containingDirs = new LinkedList<>(); RefEntity parent = entity.getOwner(); while (parent != null && !(parent instanceof RefDirectory)) { parent = parent.getOwner(); } while (parent instanceof RefDirectory) { containingDirs.addFirst(parent.getName()); parent = parent.getOwner(); } return containingDirs.isEmpty() ? null : StringUtil.join(containingDirs, File.separator); }
@Override @Nullable public String getType(final RefEntity ref) { for (RefManagerExtension extension : myExtensions.values()) { final String type = extension.getType(ref); if (type != null) return type; } if (ref instanceof RefFile) { return SmartRefElementPointer.FILE; } if (ref instanceof RefModule) { return SmartRefElementPointer.MODULE; } if (ref instanceof RefProject) { return SmartRefElementPointer.PROJECT; } if (ref instanceof RefDirectory) { return SmartRefElementPointer.DIR; } return null; }
public RefManagerImpl( @NotNull Project project, @Nullable AnalysisScope scope, @NotNull GlobalInspectionContext context) { myProject = project; myScope = scope; myContext = context; myPsiManager = PsiManager.getInstance(project); myRefProject = new RefProjectImpl(this); for (InspectionExtensionsFactory factory : Extensions.getExtensions(InspectionExtensionsFactory.EP_NAME)) { final RefManagerExtension extension = factory.createRefManagerExtension(this); if (extension != null) { myExtensions.put(extension.getID(), extension); myLanguageExtensions.put(extension.getLanguage(), extension); } } if (scope != null) { for (Module module : ModuleManager.getInstance(getProject()).getModules()) { getRefModule(module); } } }
void removeReference(@NotNull RefElement refElem) { final PsiElement element = refElem.getElement(); final RefManagerExtension extension = element != null ? getExtension(element.getLanguage()) : null; if (extension != null) { extension.removeReference(refElem); } synchronized (myRefTable) { mySortedRefs = null; if (element != null && myRefTable.remove(createAnchor(element)) != null) return; // PsiElement may have been invalidated and new one returned by getElement() is different so // we need to do this stuff. for (Map.Entry<PsiAnchor, RefElement> entry : myRefTable.entrySet()) { RefElement value = entry.getValue(); PsiAnchor anchor = entry.getKey(); if (value == refElem) { myRefTable.remove(anchor); break; } } } }