public static void clearCaches( @NotNull PsiFile injected, @NotNull DocumentWindowImpl documentWindow) { VirtualFileWindowImpl virtualFile = (VirtualFileWindowImpl) injected.getVirtualFile(); PsiManagerEx psiManagerEx = (PsiManagerEx) injected.getManager(); if (psiManagerEx.getProject().isDisposed()) return; psiManagerEx.getFileManager().setViewProvider(virtualFile, null); PsiElement context = InjectedLanguageManager.getInstance(injected.getProject()).getInjectionHost(injected); PsiFile hostFile; if (context != null) { hostFile = context.getContainingFile(); } else { VirtualFile delegate = virtualFile.getDelegate(); hostFile = delegate.isValid() ? psiManagerEx.findFile(delegate) : null; } if (hostFile != null) { // modification of cachedInjectedDocuments must be under PsiLock synchronized (PsiLock.LOCK) { List<DocumentWindow> cachedInjectedDocuments = getCachedInjectedDocuments(hostFile); for (int i = cachedInjectedDocuments.size() - 1; i >= 0; i--) { DocumentWindow cachedInjectedDocument = cachedInjectedDocuments.get(i); if (cachedInjectedDocument == documentWindow) { cachedInjectedDocuments.remove(i); } } } } }
public JavaFileManagerImpl(Project project) { myManager = PsiManagerEx.getInstanceEx(project); myPackageIndex = PackageIndex.getInstance(myManager.getProject()); project .getMessageBus() .connect() .subscribe( ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() { @Override public void rootsChanged(final ModuleRootEvent event) { myNontrivialPackagePrefixes = null; } }); }
private boolean hasAcceptablePackage(@NotNull VirtualFile vFile) { if (vFile.getFileType() == JavaClassFileType.INSTANCE) { // See IDEADEV-5626 final VirtualFile root = ProjectRootManager.getInstance(myManager.getProject()) .getFileIndex() .getClassRootForFile(vFile); VirtualFile parent = vFile.getParent(); final PsiNameHelper nameHelper = PsiNameHelper.getInstance(myManager.getProject()); while (parent != null && !Comparing.equal(parent, root)) { if (!nameHelper.isIdentifier(parent.getName())) return false; parent = parent.getParent(); } } return true; }
@NotNull private Getter<FileElement> createTreeElementPointer(@NotNull FileElement treeElement) { if (isKeepTreeElementByHardReference()) { return treeElement; } return myManager.isBatchFilesProcessingMode() ? new PatchedWeakReference<FileElement>(treeElement) : new SoftReference<FileElement>(treeElement); }
protected boolean isPsiUpToDate(@NotNull VirtualFile vFile) { final FileViewProvider provider = myManager.findViewProvider(vFile); Language language = getLanguage(); if (provider == null || provider.getPsi(language) == this) { // provider == null in tests return true; } Language baseLanguage = provider.getBaseLanguage(); return baseLanguage != language && provider.getPsi(baseLanguage) == this; }
@Override public boolean isValid() { FileViewProvider provider = getViewProvider(); final VirtualFile vFile = provider.getVirtualFile(); if (!vFile.isValid()) return false; if (!provider.isEventSystemEnabled()) return true; // "dummy" file if (myManager.getProject().isDisposed()) return false; return isPsiUpToDate(vFile); }
public IpnbPyFragment( Project project, CharSequence text, boolean isPhysical, IpnbCodeSourcePanel codeSourcePanel) { super( PsiManagerEx.getInstanceEx(project) .getFileManager() .createFileViewProvider( new LightVirtualFile("code.py", IpnbPyLanguageDialect.getInstance(), text), isPhysical)); myPhysical = isPhysical; myCodeSourcePanel = codeSourcePanel; myFilePanel = codeSourcePanel.getIpnbCodePanel().getFileEditor().getIpnbFilePanel(); ((SingleRootFileViewProvider) getViewProvider()).forceCachedPsi(this); }
@NotNull private FileElement loadTreeElement() { ApplicationManager.getApplication().assertReadAccessAllowed(); final FileViewProvider viewProvider = getViewProvider(); if (viewProvider.isPhysical() && myManager.isAssertOnFileLoading(viewProvider.getVirtualFile())) { LOG.error( "Access to tree elements not allowed in tests. path='" + viewProvider.getVirtualFile().getPresentableUrl() + "'"); } Document cachedDocument = FileDocumentManager.getInstance().getCachedDocument(getViewProvider().getVirtualFile()); FileElement treeElement = createFileElement(viewProvider.getContents()); treeElement.setPsi(this); List<Pair<StubBasedPsiElementBase, CompositeElement>> bindings = calcStubAstBindings(treeElement, cachedDocument); synchronized (PsiLock.LOCK) { FileElement existing = derefTreeElement(); if (existing != null) { return existing; } switchFromStubToAst(bindings); myStub = null; myTreeElementPointer = createTreeElementPointer(treeElement); if (LOG.isDebugEnabled() && viewProvider.isPhysical()) { LOG.debug("Loaded text for file " + viewProvider.getVirtualFile().getPresentableUrl()); } return treeElement; } }
@NotNull @Override public Collection<String> getNonTrivialPackagePrefixes() { Set<String> names = myNontrivialPackagePrefixes; if (names == null) { names = new HashSet<>(); final ProjectRootManager rootManager = ProjectRootManager.getInstance(myManager.getProject()); final List<VirtualFile> sourceRoots = rootManager.getModuleSourceRoots(JavaModuleSourceRootTypes.SOURCES); final ProjectFileIndex fileIndex = rootManager.getFileIndex(); for (final VirtualFile sourceRoot : sourceRoots) { if (sourceRoot.isDirectory()) { final String packageName = fileIndex.getPackageNameByDirectory(sourceRoot); if (packageName != null && !packageName.isEmpty()) { names.add(packageName); } } } myNontrivialPackagePrefixes = names; } return names; }
@NotNull private List<Pair<PsiClass, VirtualFile>> doFindClasses( @NotNull String qName, @NotNull final GlobalSearchScope scope) { final Collection<PsiClass> classes = JavaFullClassNameIndex.getInstance().get(qName.hashCode(), myManager.getProject(), scope); if (classes.isEmpty()) return Collections.emptyList(); List<Pair<PsiClass, VirtualFile>> result = new ArrayList<>(classes.size()); for (PsiClass aClass : classes) { final String qualifiedName = aClass.getQualifiedName(); if (qualifiedName == null || !qualifiedName.equals(qName)) continue; PsiFile file = aClass.getContainingFile(); if (file == null) { throw new AssertionError("No file for class: " + aClass + " of " + aClass.getClass()); } final boolean valid = file.isValid(); VirtualFile vFile = file.getVirtualFile(); if (!valid) { LOG.error( "Invalid file " + file + "; virtualFile:" + vFile + (vFile != null && !vFile.isValid() ? " (invalid)" : "") + "; id=" + (vFile == null ? 0 : ((VirtualFileWithId) vFile).getId()), new PsiInvalidElementAccessException(aClass)); continue; } if (!hasAcceptablePackage(vFile)) continue; result.add(Pair.create(aClass, vFile)); } return result; }
public void forceCachedPsi(final PsiFile psiFile) { myPsiFile.set(psiFile); ((PsiManagerEx) myManager).getFileManager().setViewProvider(getVirtualFile(), this); }