use of org.jetbrains.jps.incremental.storage.OneToManyPathsMapping in project intellij-community by JetBrains.
the class FormsInstrumenter method build.
@Override
public ExitCode build(CompileContext context, ModuleChunk chunk, DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder, OutputConsumer outputConsumer) throws ProjectBuildException, IOException {
final JpsProject project = context.getProjectDescriptor().getProject();
final JpsUiDesignerConfiguration config = JpsUiDesignerExtensionService.getInstance().getOrCreateUiDesignerConfiguration(project);
if (!config.isInstrumentClasses()) {
return ExitCode.NOTHING_DONE;
}
final Map<File, Collection<File>> srcToForms = FORMS_TO_COMPILE.get(context);
FORMS_TO_COMPILE.set(context, null);
if (srcToForms == null || srcToForms.isEmpty()) {
return ExitCode.NOTHING_DONE;
}
final Set<File> formsToCompile = new THashSet<>(FileUtil.FILE_HASHING_STRATEGY);
for (Collection<File> files : srcToForms.values()) {
formsToCompile.addAll(files);
}
if (JavaBuilderUtil.isCompileJavaIncrementally(context)) {
final ProjectBuilderLogger logger = context.getLoggingManager().getProjectBuilderLogger();
if (logger.isEnabled()) {
logger.logCompiledFiles(formsToCompile, getPresentableName(), "Compiling forms:");
}
}
try {
final Collection<File> platformCp = ProjectPaths.getPlatformCompilationClasspath(chunk, false);
final List<File> classpath = new ArrayList<>();
classpath.addAll(ProjectPaths.getCompilationClasspath(chunk, false));
// forms_rt.jar
classpath.add(getResourcePath(GridConstraints.class));
final Map<File, String> chunkSourcePath = ProjectPaths.getSourceRootsWithDependents(chunk);
// sourcepath for loading forms resources
classpath.addAll(chunkSourcePath.keySet());
final JpsSdk<JpsDummyElement> sdk = chunk.representativeTarget().getModule().getSdk(JpsJavaSdkType.INSTANCE);
final InstrumentationClassFinder finder = ClassProcessingBuilder.createInstrumentationClassFinder(sdk, platformCp, classpath, outputConsumer);
try {
final Map<File, Collection<File>> processed = instrumentForms(context, chunk, chunkSourcePath, finder, formsToCompile, outputConsumer);
final OneToManyPathsMapping sourceToFormMap = context.getProjectDescriptor().dataManager.getSourceToFormMap();
for (Map.Entry<File, Collection<File>> entry : processed.entrySet()) {
final File src = entry.getKey();
final Collection<File> forms = entry.getValue();
final Collection<String> formPaths = new ArrayList<>(forms.size());
for (File form : forms) {
formPaths.add(form.getPath());
}
sourceToFormMap.update(src.getPath(), formPaths);
srcToForms.remove(src);
}
// clean mapping
for (File srcFile : srcToForms.keySet()) {
sourceToFormMap.remove(srcFile.getPath());
}
} finally {
finder.releaseResources();
}
} finally {
context.processMessage(new ProgressMessage("Finished instrumenting forms [" + chunk.getPresentableShortName() + "]"));
}
return ExitCode.OK;
}
use of org.jetbrains.jps.incremental.storage.OneToManyPathsMapping in project intellij-community by JetBrains.
the class IncProjectBuilder method processDeletedPaths.
//private static void createClasspathIndex(final BuildTargetChunk chunk) {
// final Set<File> outputDirs = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
// for (BuildTarget<?> target : chunk.getTargets()) {
// if (target instanceof ModuleBuildTarget) {
// File outputDir = ((ModuleBuildTarget)target).getOutputDir();
// if (outputDir != null && outputDirs.add(outputDir)) {
// try {
// BufferedWriter writer = new BufferedWriter(new FileWriter(new File(outputDir, CLASSPATH_INDEX_FILE_NAME)));
// try {
// writeIndex(writer, outputDir, "");
// }
// finally {
// writer.close();
// }
// }
// catch (IOException e) {
// // Ignore. Failed to create optional classpath index
// }
// }
// }
// }
//}
//private static void writeIndex(final BufferedWriter writer, final File file, final String path) throws IOException {
// writer.write(path);
// writer.write('\n');
// final File[] files = file.listFiles();
// if (files != null) {
// for (File child : files) {
// final String _path = path.isEmpty() ? child.getName() : path + "/" + child.getName();
// writeIndex(writer, child, _path);
// }
// }
//}
private boolean processDeletedPaths(CompileContext context, final Set<? extends BuildTarget<?>> targets) throws ProjectBuildException {
boolean doneSomething = false;
try {
// cleanup outputs
final Map<BuildTarget<?>, Collection<String>> targetToRemovedSources = new HashMap<>();
final THashSet<File> dirsToDelete = new THashSet<>(FileUtil.FILE_HASHING_STRATEGY);
for (BuildTarget<?> target : targets) {
final Collection<String> deletedPaths = myProjectDescriptor.fsState.getAndClearDeletedPaths(target);
if (deletedPaths.isEmpty()) {
continue;
}
targetToRemovedSources.put(target, deletedPaths);
if (isTargetOutputCleared(context, target)) {
continue;
}
final int buildTargetId = context.getProjectDescriptor().getTargetsState().getBuildTargetId(target);
final boolean shouldPruneEmptyDirs = target instanceof ModuleBasedTarget;
final SourceToOutputMapping sourceToOutputStorage = context.getProjectDescriptor().dataManager.getSourceToOutputMap(target);
final ProjectBuilderLogger logger = context.getLoggingManager().getProjectBuilderLogger();
// actually delete outputs associated with removed paths
final Collection<String> pathsForIteration;
if (myIsTestMode) {
// ensure predictable order in test logs
pathsForIteration = new ArrayList<>(deletedPaths);
Collections.sort((List<String>) pathsForIteration);
} else {
pathsForIteration = deletedPaths;
}
for (String deletedSource : pathsForIteration) {
// deleting outputs corresponding to non-existing source
final Collection<String> outputs = sourceToOutputStorage.getOutputs(deletedSource);
if (outputs != null && !outputs.isEmpty()) {
List<String> deletedOutputPaths = new ArrayList<>();
final OutputToTargetRegistry outputToSourceRegistry = context.getProjectDescriptor().dataManager.getOutputToTargetRegistry();
for (String output : outputToSourceRegistry.getSafeToDeleteOutputs(outputs, buildTargetId)) {
final boolean deleted = BuildOperations.deleteRecursively(output, deletedOutputPaths, shouldPruneEmptyDirs ? dirsToDelete : null);
if (deleted) {
doneSomething = true;
}
}
for (String outputPath : outputs) {
outputToSourceRegistry.removeMapping(outputPath, buildTargetId);
}
if (!deletedOutputPaths.isEmpty()) {
if (logger.isEnabled()) {
logger.logDeletedFiles(deletedOutputPaths);
}
context.processMessage(new FileDeletedEvent(deletedOutputPaths));
}
}
if (target instanceof ModuleBuildTarget) {
// check if deleted source was associated with a form
final OneToManyPathsMapping sourceToFormMap = context.getProjectDescriptor().dataManager.getSourceToFormMap();
final Collection<String> boundForms = sourceToFormMap.getState(deletedSource);
if (boundForms != null) {
for (String formPath : boundForms) {
final File formFile = new File(formPath);
if (formFile.exists()) {
FSOperations.markDirty(context, CompilationRound.CURRENT, formFile);
}
}
sourceToFormMap.remove(deletedSource);
}
}
}
}
if (!targetToRemovedSources.isEmpty()) {
final Map<BuildTarget<?>, Collection<String>> existing = Utils.REMOVED_SOURCES_KEY.get(context);
if (existing != null) {
for (Map.Entry<BuildTarget<?>, Collection<String>> entry : existing.entrySet()) {
final Collection<String> paths = targetToRemovedSources.get(entry.getKey());
if (paths != null) {
paths.addAll(entry.getValue());
} else {
targetToRemovedSources.put(entry.getKey(), entry.getValue());
}
}
}
Utils.REMOVED_SOURCES_KEY.set(context, targetToRemovedSources);
}
FSOperations.pruneEmptyDirs(context, dirsToDelete);
} catch (IOException e) {
throw new ProjectBuildException(e);
}
return doneSomething;
}
use of org.jetbrains.jps.incremental.storage.OneToManyPathsMapping in project intellij-community by JetBrains.
the class FormsBindingManager method build.
@Override
public ExitCode build(CompileContext context, ModuleChunk chunk, DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder, OutputConsumer outputConsumer) throws ProjectBuildException, IOException {
ExitCode exitCode = ExitCode.NOTHING_DONE;
final JpsProject project = context.getProjectDescriptor().getProject();
final JpsUiDesignerConfiguration config = JpsUiDesignerExtensionService.getInstance().getOrCreateUiDesignerConfiguration(project);
if (!config.isInstrumentClasses() && !config.isCopyFormsRuntimeToOutput()) {
return exitCode;
}
final Map<File, ModuleBuildTarget> filesToCompile = new THashMap<>(FileUtil.FILE_HASHING_STRATEGY);
final Map<File, ModuleBuildTarget> formsToCompile = new THashMap<>(FileUtil.FILE_HASHING_STRATEGY);
final Map<File, Collection<File>> srcToForms = new THashMap<>(FileUtil.FILE_HASHING_STRATEGY);
if (!JavaBuilderUtil.isForcedRecompilationAllJavaModules(context) && config.isInstrumentClasses() && FORCE_FORMS_REBUILD_FLAG.get(context, Boolean.FALSE)) {
// force compilation of all forms, but only once per chunk
if (!FORMS_REBUILD_FORCED.get(context, Boolean.FALSE)) {
FORMS_REBUILD_FORCED.set(context, Boolean.TRUE);
FSOperations.markDirty(context, CompilationRound.CURRENT, chunk, FORM_SOURCES_FILTER);
}
}
dirtyFilesHolder.processDirtyFiles(new FileProcessor<JavaSourceRootDescriptor, ModuleBuildTarget>() {
public boolean apply(ModuleBuildTarget target, File file, JavaSourceRootDescriptor descriptor) throws IOException {
if (JAVA_SOURCES_FILTER.accept(file)) {
filesToCompile.put(file, target);
} else if (FORM_SOURCES_FILTER.accept(file)) {
formsToCompile.put(file, target);
}
return true;
}
});
if (config.isInstrumentClasses()) {
final JpsJavaCompilerConfiguration configuration = JpsJavaExtensionService.getInstance().getOrCreateCompilerConfiguration(project);
final JpsCompilerExcludes excludes = configuration.getCompilerExcludes();
// 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();
final ModuleBuildTarget target = entry.getValue();
final Collection<File> sources = findBoundSourceCandidates(context, target, form);
for (File boundSource : sources) {
if (!excludes.isExcluded(boundSource)) {
addBinding(boundSource, form, srcToForms);
FSOperations.markDirty(context, CompilationRound.CURRENT, boundSource);
filesToCompile.put(boundSource, target);
exitCode = ExitCode.OK;
}
}
}
// form should be considered dirty if the class it is bound to is dirty
final OneToManyPathsMapping sourceToFormMap = context.getProjectDescriptor().dataManager.getSourceToFormMap();
for (Map.Entry<File, ModuleBuildTarget> entry : filesToCompile.entrySet()) {
final File srcFile = entry.getKey();
final ModuleBuildTarget target = entry.getValue();
final Collection<String> boundForms = sourceToFormMap.getState(srcFile.getPath());
if (boundForms != null) {
for (String formPath : boundForms) {
final File formFile = new File(formPath);
if (!excludes.isExcluded(formFile) && formFile.exists()) {
addBinding(srcFile, formFile, srcToForms);
FSOperations.markDirty(context, CompilationRound.CURRENT, formFile);
formsToCompile.put(formFile, target);
exitCode = ExitCode.OK;
}
}
}
}
}
FORMS_TO_COMPILE.set(context, srcToForms.isEmpty() ? null : srcToForms);
if (config.isCopyFormsRuntimeToOutput() && containsValidForm(formsToCompile.keySet())) {
for (ModuleBuildTarget target : chunk.getTargets()) {
if (!target.isTests()) {
final File outputDir = target.getOutputDir();
if (outputDir != null) {
final String outputRoot = FileUtil.toSystemIndependentName(outputDir.getPath());
final List<File> generatedFiles = CopyResourcesUtil.copyFormsRuntime(outputRoot, false);
if (!generatedFiles.isEmpty()) {
exitCode = ExitCode.OK;
// now inform others about files just copied
for (File file : generatedFiles) {
outputConsumer.registerOutputFile(target, file, Collections.<String>emptyList());
}
}
}
}
}
}
return exitCode;
}
Aggregations