Builder API for creation DirtyFilesHolder objects

GitOrigin-RevId: 7391b32458737bd61214670001539c4ec04618b8
This commit is contained in:
Eugene Zhuravlev
2020-01-16 12:36:12 +00:00
committed by intellij-monorepo-bot
parent 8a4282313f
commit 61713a7ca7
6 changed files with 100 additions and 15 deletions
@@ -1,6 +1,9 @@
Cleaning output files:
out/production/Simple/xxx/MyForm.class
End of files
Compiling files:
src/xxx/MyForm.java
End of files
Compiling forms:
src/xxx/MyForm.form
End of files
End of files
@@ -42,9 +42,9 @@ import java.util.List;
* @author nik
*/
public abstract class BuildTarget<R extends BuildRootDescriptor> {
private final BuildTargetType<?> myTargetType;
private final BuildTargetType<? extends BuildTarget<R>> myTargetType;
protected BuildTarget(BuildTargetType<?> targetType) {
protected BuildTarget(BuildTargetType<? extends BuildTarget<R>> targetType) {
myTargetType = targetType;
}
@@ -54,7 +54,7 @@ public abstract class BuildTarget<R extends BuildRootDescriptor> {
*/
public abstract String getId();
public final BuildTargetType<?> getTargetType() {
public final BuildTargetType<? extends BuildTarget<R>> getTargetType() {
return myTargetType;
}
@@ -27,7 +27,7 @@ import org.jetbrains.jps.model.module.JpsModule;
public abstract class ModuleBasedTarget<R extends BuildRootDescriptor> extends BuildTarget<R> {
protected final JpsModule myModule;
public ModuleBasedTarget(ModuleBasedBuildTargetType<?> targetType, @NotNull JpsModule module) {
public ModuleBasedTarget(ModuleBasedBuildTargetType<? extends ModuleBasedTarget<R>> targetType, @NotNull JpsModule module) {
super(targetType);
myModule = module;
}
@@ -23,10 +23,7 @@ import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.builders.BuildRootDescriptor;
import org.jetbrains.jps.builders.BuildRootIndex;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.FileProcessor;
import org.jetbrains.jps.builders.*;
import org.jetbrains.jps.builders.impl.BuildTargetChunk;
import org.jetbrains.jps.builders.java.JavaBuilderUtil;
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor;
@@ -42,9 +39,7 @@ import java.io.FileFilter;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Set;
import java.util.*;
/**
* @author Eugene Zhuravlev
@@ -98,6 +93,88 @@ public class FSOperations {
}
}
public interface DirtyFilesHolderBuilder<R extends BuildRootDescriptor, T extends BuildTarget<R>> {
/**
* Marks specified files dirty if the file is not deleted
* If the file was marked dirty as a result of this operation or had been already marked dirty,
* the file is stored internally in the builder
*/
DirtyFilesHolderBuilder<R, T> markDirtyFile(T target, File file) throws IOException;
/**
* @return an object accumulating information about files marked with this builder
* Use returned object for further processing of marked files. For example, the object can be passed to
* {@link BuildOperations#cleanOutputsCorrespondingToChangedFiles(CompileContext, DirtyFilesHolder)}
* to clean outputs corresponding marked sources
*/
DirtyFilesHolder<R, T> create();
}
/**
* @param context
* @param round desired compilation round at which these dirty marks should be visible
* @return a builder object that marks dirty files and collects data about files marked
*/
public static <R extends BuildRootDescriptor, T extends BuildTarget<R>> DirtyFilesHolderBuilder<R, T> createDirtyFilesHolderBuilder(CompileContext context, final CompilationRound round) {
return new DirtyFilesHolderBuilder<R, T>() {
private final Map<T, Map<R, Set<File>>> dirtyFiles = new HashMap<>();
@Override
public DirtyFilesHolderBuilder<R, T> markDirtyFile(T target, File file) throws IOException {
final ProjectDescriptor pd = context.getProjectDescriptor();
final R rd = pd.getBuildRootIndex().findParentDescriptor(file, Collections.singleton(target.getTargetType()), context);
if (rd != null) {
if (pd.fsState.markDirtyIfNotDeleted(context, round, file, rd, pd.getProjectStamps().getStampStorage()) || pd.fsState.isMarkedForRecompilation(context, round, rd, file)) {
Map<R, Set<File>> targetFiles = dirtyFiles.get(target);
if (targetFiles == null) {
targetFiles = new HashMap<>();
dirtyFiles.put(target, targetFiles);
}
Set<File> rootFiles = targetFiles.get(rd);
if (rootFiles == null) {
rootFiles = new THashSet<>(FileUtil.FILE_HASHING_STRATEGY);
targetFiles.put(rd, rootFiles);
}
rootFiles.add(file);
}
}
return this;
}
@Override
public DirtyFilesHolder<R, T> create() {
return new DirtyFilesHolder<R, T>() {
@Override
public void processDirtyFiles(@NotNull FileProcessor<R, T> processor) throws IOException {
for (Map.Entry<T, Map<R, Set<File>>> entry : dirtyFiles.entrySet()) {
final T target = entry.getKey();
for (Map.Entry<R, Set<File>> targetEntry: entry.getValue().entrySet()) {
final R rd = targetEntry.getKey();
for (File file : targetEntry.getValue()) {
processor.apply(target, file, rd);
}
}
}
}
@Override
public boolean hasDirtyFiles() {
return !dirtyFiles.isEmpty();
}
@Override
public boolean hasRemovedFiles() {
return false;
}
@Override
public @NotNull Collection<String> getRemovedFiles(@NotNull T target) {
return Collections.emptyList();
}
};
}
};
}
public static void markDeleted(CompileContext context, File file) throws IOException {
final JavaSourceRootDescriptor rd = context.getProjectDescriptor().getBuildRootIndex().findJavaRootDescriptor(context, file);
if (rd != null) {
@@ -25,7 +25,7 @@ import org.jetbrains.jps.model.artifact.JpsArtifact;
public abstract class ArtifactBasedBuildTarget extends BuildTarget<ArtifactRootDescriptor> {
private final JpsArtifact myArtifact;
protected ArtifactBasedBuildTarget(BuildTargetType<?> targetType, @NotNull JpsArtifact artifact) {
protected ArtifactBasedBuildTarget(BuildTargetType<? extends BuildTarget<ArtifactRootDescriptor>> targetType, @NotNull JpsArtifact artifact) {
super(targetType);
myArtifact = artifact;
}
@@ -118,6 +118,8 @@ public class FormsBindingManager extends FormsBuilder {
final JpsJavaCompilerConfiguration configuration = JpsJavaExtensionService.getInstance().getCompilerConfiguration(project);
final JpsCompilerExcludes excludes = configuration.getCompilerExcludes();
final FSOperations.DirtyFilesHolderBuilder<JavaSourceRootDescriptor, ModuleBuildTarget> holderBuilder = FSOperations.createDirtyFilesHolderBuilder(context, CompilationRound.CURRENT);
// force compilation of bound source file if the form is dirty
for (final Map.Entry<File, ModuleBuildTarget> entry : formsToCompile.entrySet()) {
final File form = entry.getKey();
@@ -126,7 +128,7 @@ public class FormsBindingManager extends FormsBuilder {
for (File boundSource : sources) {
if (!excludes.isExcluded(boundSource)) {
addBinding(boundSource, form, srcToForms);
FSOperations.markDirty(context, CompilationRound.CURRENT, boundSource);
holderBuilder.markDirtyFile(target, boundSource);
context.getScope().markIndirectlyAffected(target, boundSource);
filesToCompile.put(boundSource, target);
exitCode = ExitCode.OK;
@@ -145,7 +147,8 @@ public class FormsBindingManager extends FormsBuilder {
final File formFile = new File(formPath);
if (!excludes.isExcluded(formFile) && formFile.exists()) {
addBinding(srcFile, formFile, srcToForms);
FSOperations.markDirty(context, CompilationRound.CURRENT, formFile);
holderBuilder.markDirtyFile(target, formFile);
context.getScope().markIndirectlyAffected(target, formFile);
formsToCompile.put(formFile, target);
exitCode = ExitCode.OK;
@@ -153,6 +156,8 @@ public class FormsBindingManager extends FormsBuilder {
}
}
}
BuildOperations.cleanOutputsCorrespondingToChangedFiles(context, holderBuilder.create());
}
FORMS_TO_COMPILE.set(context, srcToForms.isEmpty()? null : srcToForms);