mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
updating class dependencies in a centralized way at the end of every compilation round
This commit is contained in:
@@ -52,9 +52,60 @@ import java.util.*;
|
||||
public class JavaBuilderUtil {
|
||||
private static final Key<Set<File>> ALL_AFFECTED_FILES_KEY = Key.create("_all_affected_files_");
|
||||
private static final Key<Set<File>> ALL_COMPILED_FILES_KEY = Key.create("_all_compiled_files_");
|
||||
private static final Key<Set<File>> FILES_TO_COMPILE_KEY = Key.create("_files_to_compile_");
|
||||
private static final Key<Set<File>> SUCCESSFULLY_COMPILED_FILES_KEY = Key.create("_successfully_compiled_files_");
|
||||
private static final Key<Pair<Mappings, Callbacks.Backend>> MAPPINGS_DELTA_KEY = Key.create("_mappings_delta_");
|
||||
public static final Key<Callbacks.ConstantAffectionResolver> CONSTANT_SEARCH_SERVICE = Key.create("_constant_search_service_");
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.Builder");
|
||||
|
||||
public static void registerFileToCompile(CompileContext context, File file) {
|
||||
registerFilesToCompile(context, Collections.singleton(file));
|
||||
}
|
||||
|
||||
public static void registerFilesToCompile(CompileContext context, Collection<File> files) {
|
||||
getFilesContainer(context, FILES_TO_COMPILE_KEY).addAll(files);
|
||||
}
|
||||
|
||||
public static void registerSuccessfullyCompiled(CompileContext context, File file) {
|
||||
registerSuccessfullyCompiled(context, Collections.singleton(file));
|
||||
}
|
||||
|
||||
public static void registerSuccessfullyCompiled(CompileContext context, Collection<File> files) {
|
||||
getFilesContainer(context, SUCCESSFULLY_COMPILED_FILES_KEY).addAll(files);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Callbacks.Backend getDependenciesRegistrar(CompileContext context) {
|
||||
Pair<Mappings, Callbacks.Backend> pair = MAPPINGS_DELTA_KEY.get(context);
|
||||
if (pair == null) {
|
||||
final Mappings delta = context.getProjectDescriptor().dataManager.getMappings().createDelta();
|
||||
pair = Pair.create(delta, delta.getCallback());
|
||||
MAPPINGS_DELTA_KEY.set(context, pair);
|
||||
}
|
||||
return pair.second;
|
||||
}
|
||||
|
||||
public static boolean updateMappingsOnRoundCompletion(
|
||||
CompileContext context, DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder, ModuleChunk chunk) throws IOException {
|
||||
|
||||
Mappings delta = null;
|
||||
|
||||
final Pair<Mappings, Callbacks.Backend> pair = MAPPINGS_DELTA_KEY.get(context);
|
||||
if (pair != null) {
|
||||
MAPPINGS_DELTA_KEY.set(context, null);
|
||||
delta = pair.getFirst();
|
||||
}
|
||||
|
||||
if (delta == null) {
|
||||
return false;
|
||||
}
|
||||
final Set<File> compiledFiles = getFilesContainer(context, FILES_TO_COMPILE_KEY);
|
||||
FILES_TO_COMPILE_KEY.set(context, null);
|
||||
final Set<File> successfullyCompiled = getFilesContainer(context, SUCCESSFULLY_COMPILED_FILES_KEY);
|
||||
SUCCESSFULLY_COMPILED_FILES_KEY.set(context, null);
|
||||
return updateMappings(context, delta, dirtyFilesHolder, chunk, compiledFiles, successfullyCompiled);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param context
|
||||
@@ -83,8 +134,8 @@ public class JavaBuilderUtil {
|
||||
if (!isForcedRecompilationAllJavaModules(context)) {
|
||||
if (context.shouldDifferentiate(chunk)) {
|
||||
context.processMessage(new ProgressMessage("Checking dependencies... [" + chunk.getPresentableShortName() + "]"));
|
||||
final Set<File> allCompiledFiles = getAllCompiledFilesContainer(context);
|
||||
final Set<File> allAffectedFiles = getAllAffectedFilesContainer(context);
|
||||
final Set<File> allCompiledFiles = getFilesContainer(context, ALL_COMPILED_FILES_KEY);
|
||||
final Set<File> allAffectedFiles = getFilesContainer(context, ALL_AFFECTED_FILES_KEY);
|
||||
|
||||
// mark as affected all files that were dirty before compilation
|
||||
allAffectedFiles.addAll(filesToCompile);
|
||||
@@ -232,22 +283,14 @@ public class JavaBuilderUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Set<File> getAllAffectedFilesContainer(CompileContext context) {
|
||||
Set<File> allAffectedFiles = ALL_AFFECTED_FILES_KEY.get(context);
|
||||
if (allAffectedFiles == null) {
|
||||
allAffectedFiles = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
|
||||
ALL_AFFECTED_FILES_KEY.set(context, allAffectedFiles);
|
||||
@NotNull
|
||||
private static Set<File> getFilesContainer(CompileContext context, final Key<Set<File>> dataKey) {
|
||||
Set<File> files = dataKey.get(context);
|
||||
if (files == null) {
|
||||
files = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
|
||||
dataKey.set(context, files);
|
||||
}
|
||||
return allAffectedFiles;
|
||||
}
|
||||
|
||||
private static Set<File> getAllCompiledFilesContainer(CompileContext context) {
|
||||
Set<File> allCompiledFiles = ALL_COMPILED_FILES_KEY.get(context);
|
||||
if (allCompiledFiles == null) {
|
||||
allCompiledFiles = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
|
||||
ALL_COMPILED_FILES_KEY.set(context, allCompiledFiles);
|
||||
}
|
||||
return allCompiledFiles;
|
||||
return files;
|
||||
}
|
||||
|
||||
private static Set<String> getRemovedPaths(ModuleChunk chunk, DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder) {
|
||||
|
||||
@@ -1135,55 +1135,63 @@ public class IncProjectBuilder {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (ModuleLevelBuilder builder : builders) {
|
||||
processDeletedPaths(context, chunk.getTargets());
|
||||
long start = System.nanoTime();
|
||||
final ModuleLevelBuilder.ExitCode buildResult = builder.build(context, chunk, dirtyFilesHolder, outputConsumer);
|
||||
incBuilderElapsedTime(builder, System.nanoTime() - start);
|
||||
|
||||
doneSomething |= (buildResult != ModuleLevelBuilder.ExitCode.NOTHING_DONE);
|
||||
|
||||
if (buildResult == ModuleLevelBuilder.ExitCode.ABORT) {
|
||||
throw new StopBuildException("Builder " + builder.getPresentableName() + " requested build stop");
|
||||
}
|
||||
context.checkCanceled();
|
||||
if (buildResult == ModuleLevelBuilder.ExitCode.ADDITIONAL_PASS_REQUIRED) {
|
||||
if (!nextPassRequired) {
|
||||
// recalculate basis
|
||||
myTargetsProcessed -= (buildersPassed * modulesInChunk) / stageCount;
|
||||
stageCount += myTotalModuleLevelBuilderCount;
|
||||
myTargetsProcessed += (buildersPassed * modulesInChunk) / stageCount;
|
||||
try {
|
||||
for (ModuleLevelBuilder builder : builders) {
|
||||
processDeletedPaths(context, chunk.getTargets());
|
||||
long start = System.nanoTime();
|
||||
final ModuleLevelBuilder.ExitCode buildResult = builder.build(context, chunk, dirtyFilesHolder, outputConsumer);
|
||||
incBuilderElapsedTime(builder, System.nanoTime() - start);
|
||||
|
||||
doneSomething |= (buildResult != ModuleLevelBuilder.ExitCode.NOTHING_DONE);
|
||||
|
||||
if (buildResult == ModuleLevelBuilder.ExitCode.ABORT) {
|
||||
throw new StopBuildException("Builder " + builder.getPresentableName() + " requested build stop");
|
||||
}
|
||||
context.checkCanceled();
|
||||
if (buildResult == ModuleLevelBuilder.ExitCode.ADDITIONAL_PASS_REQUIRED) {
|
||||
nextPassRequired = true;
|
||||
}
|
||||
else if (buildResult == ModuleLevelBuilder.ExitCode.CHUNK_REBUILD_REQUIRED) {
|
||||
if (!rebuildFromScratchRequested && !JavaBuilderUtil.isForcedRecompilationAllJavaModules(context)) {
|
||||
LOG.info("Builder " + builder.getPresentableName() + " requested rebuild of module chunk " + chunk.getName());
|
||||
// allow rebuild from scratch only once per chunk
|
||||
rebuildFromScratchRequested = true;
|
||||
try {
|
||||
// forcibly mark all files in the chunk dirty
|
||||
context.getProjectDescriptor().fsState.clearContextRoundData(context);
|
||||
FSOperations.markDirty(context, CompilationRound.NEXT, chunk, null);
|
||||
// reverting to the beginning
|
||||
myTargetsProcessed -= (buildersPassed * modulesInChunk) / stageCount;
|
||||
stageCount = myTotalModuleLevelBuilderCount;
|
||||
buildersPassed = 0;
|
||||
nextPassRequired = true;
|
||||
outputConsumer.clear();
|
||||
break BUILDER_CATEGORY_LOOP;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new ProjectBuildException(e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG.debug("Builder " + builder.getPresentableName() + " requested second chunk rebuild");
|
||||
}
|
||||
}
|
||||
|
||||
buildersPassed++;
|
||||
updateDoneFraction(context, modulesInChunk / (stageCount));
|
||||
}
|
||||
}
|
||||
finally {
|
||||
final boolean moreToCompile = JavaBuilderUtil.updateMappingsOnRoundCompletion(context, dirtyFilesHolder, chunk);
|
||||
if (moreToCompile) {
|
||||
nextPassRequired = true;
|
||||
}
|
||||
else if (buildResult == ModuleLevelBuilder.ExitCode.CHUNK_REBUILD_REQUIRED) {
|
||||
if (!rebuildFromScratchRequested && !JavaBuilderUtil.isForcedRecompilationAllJavaModules(context)) {
|
||||
LOG.info("Builder " + builder.getPresentableName() + " requested rebuild of module chunk " + chunk.getName());
|
||||
// allow rebuild from scratch only once per chunk
|
||||
rebuildFromScratchRequested = true;
|
||||
try {
|
||||
// forcibly mark all files in the chunk dirty
|
||||
context.getProjectDescriptor().fsState.clearContextRoundData(context);
|
||||
FSOperations.markDirty(context, CompilationRound.NEXT, chunk, null);
|
||||
// reverting to the beginning
|
||||
myTargetsProcessed -= (buildersPassed * modulesInChunk) / stageCount;
|
||||
stageCount = myTotalModuleLevelBuilderCount;
|
||||
buildersPassed = 0;
|
||||
nextPassRequired = true;
|
||||
outputConsumer.clear();
|
||||
break BUILDER_CATEGORY_LOOP;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new ProjectBuildException(e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG.debug("Builder " + builder.getPresentableName() + " requested second chunk rebuild");
|
||||
}
|
||||
if (nextPassRequired && !rebuildFromScratchRequested) {
|
||||
// recalculate basis
|
||||
myTargetsProcessed -= (buildersPassed * modulesInChunk) / stageCount;
|
||||
stageCount += myTotalModuleLevelBuilderCount;
|
||||
myTargetsProcessed += (buildersPassed * modulesInChunk) / stageCount;
|
||||
}
|
||||
|
||||
buildersPassed++;
|
||||
updateDoneFraction(context, modulesInChunk / (stageCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,8 +39,6 @@ import org.jetbrains.jps.builders.java.JavaBuilderExtension;
|
||||
import org.jetbrains.jps.builders.java.JavaBuilderUtil;
|
||||
import org.jetbrains.jps.builders.java.JavaCompilingTool;
|
||||
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor;
|
||||
import org.jetbrains.jps.builders.java.dependencyView.Callbacks;
|
||||
import org.jetbrains.jps.builders.java.dependencyView.Mappings;
|
||||
import org.jetbrains.jps.builders.logging.ProjectBuilderLogger;
|
||||
import org.jetbrains.jps.builders.storage.BuildDataCorruptedException;
|
||||
import org.jetbrains.jps.cmdline.ProjectDescriptor;
|
||||
@@ -252,9 +250,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
final Collection<File> platformCp = ProjectPaths.getPlatformCompilationClasspath(chunk, false/*context.isProjectRebuild()*/);
|
||||
|
||||
// begin compilation round
|
||||
final Mappings delta = pd.dataManager.getMappings().createDelta();
|
||||
final Callbacks.Backend mappingsCallback = delta.getCallback();
|
||||
final OutputFilesSink outputSink = new OutputFilesSink(context, outputConsumer, mappingsCallback, chunk.getPresentableShortName());
|
||||
final OutputFilesSink outputSink = new OutputFilesSink(context, outputConsumer, JavaBuilderUtil.getDependenciesRegistrar(context), chunk.getPresentableShortName());
|
||||
try {
|
||||
if (hasSourcesToCompile) {
|
||||
final AtomicReference<String> ref = COMPILER_VERSION_INFO.get(context);
|
||||
@@ -323,9 +319,8 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (JavaBuilderUtil.updateMappings(context, delta, dirtyFilesHolder, chunk, files, outputSink.getSuccessfullyCompiled())) {
|
||||
exitCode = ExitCode.ADDITIONAL_PASS_REQUIRED;
|
||||
}
|
||||
JavaBuilderUtil.registerFilesToCompile(context, files);
|
||||
JavaBuilderUtil.registerSuccessfullyCompiled(context, outputSink.getSuccessfullyCompiled());
|
||||
}
|
||||
|
||||
return exitCode;
|
||||
|
||||
+1
-3
@@ -147,9 +147,7 @@ public class GreclipseBuilder extends ModuleLevelBuilder {
|
||||
context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.ERROR, "Compilation failed"));
|
||||
}
|
||||
|
||||
if (GroovyBuilder.updateDependencies(context, chunk, dirtyFilesHolder, toCompile, successfullyCompiled, outputConsumer, this)) {
|
||||
return ExitCode.ADDITIONAL_PASS_REQUIRED;
|
||||
}
|
||||
GroovyBuilder.updateDependencies(context, toCompile, successfullyCompiled, outputConsumer, this);
|
||||
return ExitCode.OK;
|
||||
|
||||
}
|
||||
|
||||
+9
-15
@@ -40,7 +40,6 @@ import org.jetbrains.jps.builders.FileProcessor;
|
||||
import org.jetbrains.jps.builders.java.JavaBuilderUtil;
|
||||
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor;
|
||||
import org.jetbrains.jps.builders.java.dependencyView.Callbacks;
|
||||
import org.jetbrains.jps.builders.java.dependencyView.Mappings;
|
||||
import org.jetbrains.jps.builders.storage.SourceToOutputMapping;
|
||||
import org.jetbrains.jps.cmdline.ClasspathBootstrap;
|
||||
import org.jetbrains.jps.cmdline.ProjectDescriptor;
|
||||
@@ -162,8 +161,8 @@ public class GroovyBuilder extends ModuleLevelBuilder {
|
||||
context.processMessage(message);
|
||||
}
|
||||
|
||||
if (!myForStubs && updateDependencies(context, chunk, dirtyFilesHolder, toCompile, compiled, outputConsumer, this)) {
|
||||
return ExitCode.ADDITIONAL_PASS_REQUIRED;
|
||||
if (!myForStubs) {
|
||||
updateDependencies(context, toCompile, compiled, outputConsumer, this);
|
||||
}
|
||||
return hasFilesToCompileForNextRound(context) ? ExitCode.ADDITIONAL_PASS_REQUIRED : ExitCode.OK;
|
||||
}
|
||||
@@ -443,17 +442,14 @@ public class GroovyBuilder extends ModuleLevelBuilder {
|
||||
return toCompile;
|
||||
}
|
||||
|
||||
public static boolean updateDependencies(CompileContext context,
|
||||
ModuleChunk chunk,
|
||||
DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder,
|
||||
List<File> toCompile,
|
||||
Map<ModuleBuildTarget, Collection<GroovycOSProcessHandler.OutputItem>> successfullyCompiled,
|
||||
OutputConsumer outputConsumer, Builder builder) throws IOException {
|
||||
final Mappings delta = context.getProjectDescriptor().dataManager.getMappings().createDelta();
|
||||
final List<File> successfullyCompiledFiles = new ArrayList<File>();
|
||||
public static void updateDependencies(CompileContext context,
|
||||
List<File> toCompile,
|
||||
Map<ModuleBuildTarget, Collection<GroovycOSProcessHandler.OutputItem>> successfullyCompiled,
|
||||
OutputConsumer outputConsumer, Builder builder) throws IOException {
|
||||
JavaBuilderUtil.registerFilesToCompile(context, toCompile);
|
||||
if (!successfullyCompiled.isEmpty()) {
|
||||
|
||||
final Callbacks.Backend callback = delta.getCallback();
|
||||
final Callbacks.Backend callback = JavaBuilderUtil.getDependenciesRegistrar(context);
|
||||
|
||||
for (Map.Entry<ModuleBuildTarget, Collection<GroovycOSProcessHandler.OutputItem>> entry : successfullyCompiled.entrySet()) {
|
||||
final ModuleBuildTarget target = entry.getKey();
|
||||
@@ -479,12 +475,10 @@ public class GroovyBuilder extends ModuleLevelBuilder {
|
||||
builder.getPresentableName(), BuildMessage.Kind.WARNING, message + "\n" + CompilerMessage.getTextFromThrowable(e), sourcePath)
|
||||
);
|
||||
}
|
||||
successfullyCompiledFiles.add(srcFile);
|
||||
JavaBuilderUtil.registerSuccessfullyCompiled(context, srcFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return JavaBuilderUtil.updateMappings(context, delta, dirtyFilesHolder, chunk, toCompile, successfullyCompiledFiles);
|
||||
}
|
||||
|
||||
private static String readClassName(byte[] classBytes) throws IOException{
|
||||
|
||||
Reference in New Issue
Block a user