javac ast indices: carefully update data about compiled modules

This commit is contained in:
Dmitry Batkovich
2017-01-13 15:39:38 +03:00
parent 55ab006770
commit 599ff4ccda
3 changed files with 79 additions and 43 deletions
@@ -103,38 +103,22 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceService imple
compilerManager.addCompilationStatusListener(new CompilationStatusListener() {
@Override
public void compilationFinished(boolean aborted, int errors, int warnings, CompileContext compileContext) {
compilationFinished(errors, compileContext);
compilationFinished(compileContext);
}
@Override
public void automakeCompilationFinished(int errors, int warnings, CompileContext compileContext) {
compilationFinished(errors, compileContext);
compilationFinished(compileContext);
}
private void compilationFinished(int errors, CompileContext context) {
private void compilationFinished(CompileContext context) {
Runnable compilationFinished = () -> {
final Module[] compilationModules = ReadAction.compute(() -> {
if (myProject.isDisposed()) return null;
return context.getCompileScope().getAffectedModules();
});
if (compilationModules == null) return;
Set<Module> modulesWithErrors;
if (errors != 0) {
modulesWithErrors = Stream.of(context.getMessages(CompilerMessageCategory.ERROR))
.map(CompilerMessage::getVirtualFile)
.distinct()
.map(f -> f == null ? null : myProjectFileIndex.getModuleForFile(f))
.collect(Collectors.toSet());
}
else {
modulesWithErrors = Collections.emptySet();
}
if (modulesWithErrors.contains(null) /*unknown error location*/) {
myDirtyScopeHolder.compilerActivityFinished(Module.EMPTY_ARRAY, compilationModules);
} else {
myDirtyScopeHolder.compilerActivityFinished(compilationModules, modulesWithErrors.toArray(Module.EMPTY_ARRAY));
}
myDirtyScopeHolder.compilerActivityFinished(compilationModules);
myCompilationCount.increment();
openReaderIfNeed();
};
@@ -149,19 +133,11 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceService imple
CompileScope projectCompileScope = compilerManager.createProjectCompileScope(myProject);
boolean isUpToDate = compilerManager.isUpToDate(projectCompileScope);
executeOnBuildThread(() -> {
Module[] modules = ReadAction.compute(() -> {
if (myProject.isDisposed()) return null;
return projectCompileScope.getAffectedModules();
});
if (modules == null) return;
myDirtyScopeHolder.upToDateChecked(isUpToDate);
if (isUpToDate) {
myDirtyScopeHolder.compilerActivityFinished(modules, Module.EMPTY_ARRAY);
myCompilationCount.increment();
openReaderIfNeed();
}
else {
myDirtyScopeHolder.compilerActivityFinished(Module.EMPTY_ARRAY, modules);
}
});
});
}
@@ -16,13 +16,16 @@
package com.intellij.compiler.backwardRefs;
import com.intellij.compiler.CompilerConfiguration;
import com.intellij.compiler.CompilerReferenceService;
import com.intellij.compiler.backwardRefs.view.DirtyScopeTestInfo;
import com.intellij.compiler.server.CustomBuilderMessageHandler;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.compiler.options.ExcludeEntryDescription;
import com.intellij.openapi.compiler.options.ExcludedEntriesListener;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.UserDataHolderBase;
@@ -35,14 +38,17 @@ import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.util.ObjectUtils;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBusConnection;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jps.backwardRefs.BackwardReferenceIndexBuilder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class DirtyScopeHolder extends UserDataHolderBase {
private final CompilerReferenceServiceImpl myService;
@@ -55,6 +61,8 @@ public class DirtyScopeHolder extends UserDataHolderBase {
private final List<ExcludeEntryDescription> myExcludedDescriptions = new SmartList<>(); // guarded by myLock
private boolean myCompilationPhase; // guarded by myLock
private volatile GlobalSearchScope myExcludedFilesScope; // calculated outside myLock
private final Set<String> myCompilationAffectedModules = ContainerUtil.newConcurrentSet(); // used outside myLock
public DirtyScopeHolder(@NotNull CompilerReferenceServiceImpl service,
FileDocumentManager fileDocumentManager,
@@ -63,16 +71,25 @@ public class DirtyScopeHolder extends UserDataHolderBase {
myFileDocManager = fileDocumentManager;
myPsiDocManager = psiDocumentManager;
service.getProject().getMessageBus().connect().subscribe(ExcludedEntriesListener.TOPIC, new ExcludedEntriesListener() {
@Override
public void onEntryAdded(@NotNull ExcludeEntryDescription description) {
synchronized (myLock) {
if (myCompilationPhase) {
myExcludedDescriptions.add(description);
if (CompilerReferenceService.isEnabled()) {
final MessageBusConnection connect = service.getProject().getMessageBus().connect();
connect.subscribe(ExcludedEntriesListener.TOPIC, new ExcludedEntriesListener() {
@Override
public void onEntryAdded(@NotNull ExcludeEntryDescription description) {
synchronized (myLock) {
if (myCompilationPhase) {
myExcludedDescriptions.add(description);
}
}
}
}
});
});
connect.subscribe(CustomBuilderMessageHandler.TOPIC, (builderId, messageType, messageText) -> {
if (BackwardReferenceIndexBuilder.BUILDER_ID.equals(builderId)) {
myCompilationAffectedModules.add(messageText);
}
});
}
}
void compilerActivityStarted() {
@@ -80,22 +97,52 @@ public class DirtyScopeHolder extends UserDataHolderBase {
myCompilationPhase = true;
Collections.addAll(myExcludedDescriptions, CompilerConfiguration.getInstance(myService.getProject()).getExcludedEntriesConfiguration().getExcludeEntryDescriptions());
myExcludedFilesScope = null;
myCompilationAffectedModules.clear();
}
}
void compilerActivityFinished(Module[] affectedModules, Module[] markAsDirty) {
void upToDateChecked(boolean isUpToDate) {
compilationFinished(() -> {
if (!isUpToDate) {
final Module[] modules = ReadAction.compute(() -> {
final Project project = myService.getProject();
if (project.isDisposed()) {
return null;
}
return ModuleManager.getInstance(project).getModules();
});
if (modules == null) return;
ContainerUtil.addAll(myVFSChangedModules, modules);
}
});
}
void compilerActivityFinished(Module[] affectedModules) {
compilationFinished(() -> {
final ModuleManager moduleManager = ModuleManager.getInstance(myService.getProject());
final List<Module> compiledModules = myCompilationAffectedModules.stream().map(moduleManager::findModuleByName).collect(Collectors.toList());
myVFSChangedModules.removeAll(compiledModules);
final Set<Module> unCompiledModules = ContainerUtil.newHashSet(affectedModules);
unCompiledModules.removeAll(compiledModules);
myVFSChangedModules.removeAll(unCompiledModules);
});
}
private void compilationFinished(Runnable action) {
ExcludeEntryDescription[] descriptions;
synchronized (myLock) {
myCompilationPhase = false;
ContainerUtil.removeAll(myVFSChangedModules, affectedModules);
Collections.addAll(myVFSChangedModules, markAsDirty);
action.run();
myCompilationAffectedModules.clear();
myVFSChangedModules.addAll(myChangedModulesDuringCompilation);
myChangedModulesDuringCompilation.clear();
descriptions = myExcludedDescriptions.toArray(new ExcludeEntryDescription[myExcludedDescriptions.size()]);
myExcludedDescriptions.clear();
}
myExcludedFilesScope = ExcludedFromCompileFilesUtil.getExcludedFilesScope(descriptions, myService.getFileTypes(), myService.getProject(), myService.getFileIndex());
}
GlobalSearchScope getDirtyScope() {
@@ -122,7 +169,7 @@ public class DirtyScopeHolder extends UserDataHolderBase {
}
@NotNull
private Set<Module> getAllDirtyModules() {
Set<Module> getAllDirtyModules() {
final Set<Module> dirtyModules = new THashSet<>(myVFSChangedModules);
for (Document document : myFileDocManager.getUnsavedDocuments()) {
final VirtualFile file = myFileDocManager.getFile(document);
@@ -20,6 +20,8 @@ import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.builders.DirtyFilesHolder;
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor;
import org.jetbrains.jps.incremental.*;
import org.jetbrains.jps.incremental.messages.CustomBuilderMessage;
import org.jetbrains.jps.model.module.JpsModule;
import java.io.IOException;
import java.util.Collection;
@@ -27,8 +29,10 @@ import java.util.Collections;
import java.util.List;
public class BackwardReferenceIndexBuilder extends ModuleLevelBuilder {
public static final String BUILDER_ID = "compiler.ref.index";
public BackwardReferenceIndexBuilder() {
super(BuilderCategory.INITIAL);
super(BuilderCategory.CLASS_POST_PROCESSOR);
}
@NotNull
@@ -66,6 +70,15 @@ public class BackwardReferenceIndexBuilder extends ModuleLevelBuilder {
}
}
}
for (ModuleBuildTarget target : chunk.getTargets()) {
if (target instanceof JVMModuleBuildTarget) {
final JpsModule module = target.getModule();
final String moduleName = module.getName();
context.processMessage(new CustomBuilderMessage(BUILDER_ID, "processed module", moduleName));
}
}
return null;
}
}