mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
javac ast indices: return vfs listener + process uncommitted changes
This commit is contained in:
+4
-2
@@ -23,6 +23,7 @@ import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.compiler.*;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -33,6 +34,7 @@ import com.intellij.openapi.util.Couple;
|
||||
import com.intellij.openapi.util.ModificationTracker;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileWithId;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
@@ -71,12 +73,12 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceService imple
|
||||
|
||||
private volatile CompilerReferenceReader myReader;
|
||||
|
||||
public CompilerReferenceServiceImpl(Project project) {
|
||||
public CompilerReferenceServiceImpl(Project project, FileDocumentManager fileDocumentManager, PsiDocumentManager psiDocumentManager) {
|
||||
super(project);
|
||||
|
||||
myProjectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();
|
||||
myFileTypes = Stream.of(LanguageLightRefAdapter.INSTANCES).flatMap(a -> a.getFileTypes().stream()).collect(Collectors.toSet());
|
||||
myDirtyModulesHolder = new DirtyModulesHolder(this);
|
||||
myDirtyModulesHolder = new DirtyModulesHolder(this, fileDocumentManager, psiDocumentManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,18 +15,23 @@
|
||||
*/
|
||||
package com.intellij.compiler.backwardRefs;
|
||||
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.SmartHashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -34,14 +39,20 @@ import static com.intellij.psi.search.GlobalSearchScope.EMPTY_SCOPE;
|
||||
|
||||
class DirtyModulesHolder extends UserDataHolderBase {
|
||||
private final CompilerReferenceServiceImpl myService;
|
||||
private final FileDocumentManager myFileDocManager;
|
||||
private final PsiDocumentManager myPsiDocManager;
|
||||
private final Set<Module> myChangedModules = ContainerUtil.newHashSet();
|
||||
private final Set<Module> myChangedModulesDuringCompilation = ContainerUtil.newHashSet();
|
||||
private final Object myLock = new Object();
|
||||
|
||||
private boolean myCompilationPhase;
|
||||
|
||||
public DirtyModulesHolder(@NotNull CompilerReferenceServiceImpl service){
|
||||
public DirtyModulesHolder(@NotNull CompilerReferenceServiceImpl service,
|
||||
FileDocumentManager fileDocumentManager,
|
||||
PsiDocumentManager psiDocumentManager){
|
||||
myService = service;
|
||||
myFileDocManager = fileDocumentManager;
|
||||
myPsiDocManager = psiDocumentManager;
|
||||
}
|
||||
|
||||
void compilerActivityStarted() {
|
||||
@@ -62,13 +73,23 @@ class DirtyModulesHolder extends UserDataHolderBase {
|
||||
}
|
||||
|
||||
GlobalSearchScope getDirtyScope() {
|
||||
return CachedValuesManager.getManager(myService.getProject()).getCachedValue(this, () -> {
|
||||
synchronized (myLock) {
|
||||
final GlobalSearchScope dirtyScope =
|
||||
myChangedModules.stream().map(Module::getModuleWithDependentsScope).reduce(EMPTY_SCOPE, (s1, s2) -> s1.union(s2));
|
||||
return CachedValueProvider.Result.create(dirtyScope, PsiModificationTracker.MODIFICATION_COUNT, myService);
|
||||
synchronized (myLock) {
|
||||
final Set<Module> unCommittedModules = new SmartHashSet<>(0);
|
||||
for (Document document : myFileDocManager.getUnsavedDocuments()) {
|
||||
final Module m = getModuleForSourceContentFile(myFileDocManager.getFile(document));
|
||||
if (m != null && !myChangedModules.contains(m)) unCommittedModules.add(m);
|
||||
}
|
||||
});
|
||||
for (Document document : ReadAction.compute(() -> myPsiDocManager.getUncommittedDocuments())) {
|
||||
final Module m = getModuleForSourceContentFile(ObjectUtils.notNull(myPsiDocManager.getPsiFile(document)).getVirtualFile());
|
||||
if (m != null && !myChangedModules.contains(m)) unCommittedModules.add(m);
|
||||
}
|
||||
GlobalSearchScope dirtyCommittedScope = CachedValuesManager.getManager(myService.getProject()).getCachedValue(this, () ->
|
||||
CachedValueProvider.Result.create(addModulesWithDependentToScope(myChangedModules, EMPTY_SCOPE), PsiModificationTracker.MODIFICATION_COUNT, myService));
|
||||
if (unCommittedModules.isEmpty()) {
|
||||
return dirtyCommittedScope;
|
||||
}
|
||||
return addModulesWithDependentToScope(unCommittedModules, dirtyCommittedScope);
|
||||
}
|
||||
}
|
||||
|
||||
boolean contains(VirtualFile file) {
|
||||
@@ -76,71 +97,71 @@ class DirtyModulesHolder extends UserDataHolderBase {
|
||||
}
|
||||
|
||||
void installVFSListener() {
|
||||
PsiManager.getInstance(myService.getProject()).addPsiTreeChangeListener(new PsiTreeChangeAdapter() {
|
||||
VirtualFileManager.getInstance().addVirtualFileListener(new VirtualFileAdapter() {
|
||||
@Override
|
||||
public void beforeChildAddition(@NotNull PsiTreeChangeEvent event) {
|
||||
psiChanged(event.getFile(), event.getParent());
|
||||
public void fileCreated(@NotNull VirtualFileEvent event) {
|
||||
processChange(event.getFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeChildRemoval(@NotNull PsiTreeChangeEvent event) {
|
||||
psiChanged(event.getFile(), event.getParent());
|
||||
public void fileCopied(@NotNull VirtualFileCopyEvent event) {
|
||||
processChange(event.getFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeChildReplacement(@NotNull PsiTreeChangeEvent event) {
|
||||
psiChanged(event.getFile(), event.getParent());
|
||||
public void fileMoved(@NotNull VirtualFileMoveEvent event) {
|
||||
processChange(event.getFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeChildMovement(@NotNull PsiTreeChangeEvent event) {
|
||||
final PsiFile file = event.getFile();
|
||||
if (file != null) {
|
||||
psiChanged(file, null);
|
||||
}
|
||||
else {
|
||||
psiChanged(null, event.getOldParent());
|
||||
psiChanged(null, event.getNewParent());
|
||||
public void beforePropertyChange(@NotNull VirtualFilePropertyEvent event) {
|
||||
if (VirtualFile.PROP_NAME.equals(event.getPropertyName()) || VirtualFile.PROP_SYMLINK_TARGET.equals(event.getPropertyName())) {
|
||||
processChange(event.getFile());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeChildrenChange(@NotNull PsiTreeChangeEvent event) {
|
||||
psiChanged(event.getFile(), event.getParent());
|
||||
public void beforeContentsChange(@NotNull VirtualFileEvent event) {
|
||||
processChange(event.getFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforePropertyChange(@NotNull PsiTreeChangeEvent event) {
|
||||
if (PsiTreeChangeEvent.PROP_UNLOADED_PSI.equals(event.getPropertyName()) ||
|
||||
PsiTreeChangeEvent.PROP_WRITABLE.equals(event.getPropertyName())) return;
|
||||
psiChanged(event.getFile(), event.getParent());
|
||||
public void beforeFileDeletion(@NotNull VirtualFileEvent event) {
|
||||
processChange(event.getFile());
|
||||
}
|
||||
|
||||
private void psiChanged(@Nullable PsiFile psiFile, @Nullable PsiElement parent) {
|
||||
final VirtualFile file;
|
||||
if (psiFile != null) {
|
||||
file = psiFile.getVirtualFile();
|
||||
}
|
||||
else if (parent instanceof PsiFileSystemItem) {
|
||||
file = ((PsiFileSystemItem)parent).getVirtualFile();
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
if (myService.getFileIndex().isInSourceContent(file) && myService.getFileTypes().contains(file.getFileType())) {
|
||||
final Module module = myService.getFileIndex().getModuleForFile(file);
|
||||
if (module != null) {
|
||||
synchronized (myLock) {
|
||||
if (myCompilationPhase) {
|
||||
myChangedModulesDuringCompilation.add(module);
|
||||
}
|
||||
else {
|
||||
myChangedModules.add(module);
|
||||
}
|
||||
@Override
|
||||
public void beforeFileMovement(@NotNull VirtualFileMoveEvent event) {
|
||||
processChange(event.getFile());
|
||||
}
|
||||
|
||||
private void processChange(VirtualFile file) {
|
||||
fileChanged(file);
|
||||
}
|
||||
|
||||
void fileChanged(VirtualFile file) {
|
||||
final Module module = getModuleForSourceContentFile(file);
|
||||
if (module != null) {
|
||||
synchronized (myLock) {
|
||||
if (myCompilationPhase) {
|
||||
myChangedModulesDuringCompilation.add(module);
|
||||
} else {
|
||||
myChangedModules.add(module);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}, myService.getProject());
|
||||
}
|
||||
|
||||
private Module getModuleForSourceContentFile(VirtualFile file) {
|
||||
if (myService.getFileIndex().isInSourceContent(file) && myService.getFileTypes().contains(file.getFileType())) {
|
||||
return myService.getFileIndex().getModuleForFile(file);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static GlobalSearchScope addModulesWithDependentToScope(Collection<Module> modules, GlobalSearchScope baseScope) {
|
||||
return modules.stream().map(Module::getModuleWithDependentsScope).reduce(baseScope, (s1, s2) -> s1.union(s2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -756,7 +756,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
|
||||
@Override
|
||||
@NotNull
|
||||
public Document[] getUncommittedDocuments() {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
ApplicationManager.getApplication().assertReadAccessAllowed();
|
||||
Document[] documents = myUncommittedDocuments.toArray(new Document[myUncommittedDocuments.size()]);
|
||||
return ArrayUtil.stripTrailingNulls(documents);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user