use of org.jetbrains.jps.incremental.messages.ProgressMessage in project intellij-community by JetBrains.
the class FormsInstrumenter method instrumentForms.
private Map<File, Collection<File>> instrumentForms(CompileContext context, ModuleChunk chunk, final Map<File, String> chunkSourcePath, final InstrumentationClassFinder finder, Collection<File> forms, OutputConsumer outConsumer) throws ProjectBuildException {
final Map<File, Collection<File>> instrumented = new THashMap<>(FileUtil.FILE_HASHING_STRATEGY);
final Map<String, File> class2form = new HashMap<>();
final MyNestedFormLoader nestedFormsLoader = new MyNestedFormLoader(chunkSourcePath, ProjectPaths.getOutputPathsWithDependents(chunk), finder);
for (File formFile : forms) {
final LwRootContainer rootContainer;
try {
rootContainer = Utils.getRootContainer(formFile.toURI().toURL(), new CompiledClassPropertiesProvider(finder.getLoader()));
} catch (AlienFormFileException e) {
// ignore non-IDEA forms
continue;
} catch (UnexpectedFormElementException e) {
context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.ERROR, e.getMessage(), formFile.getPath()));
LOG.info(e);
continue;
} catch (UIDesignerException e) {
context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.ERROR, e.getMessage(), formFile.getPath()));
LOG.info(e);
continue;
} catch (Exception e) {
throw new ProjectBuildException("Cannot process form file " + formFile.getAbsolutePath(), e);
}
final String classToBind = rootContainer.getClassToBind();
if (classToBind == null) {
continue;
}
final CompiledClass compiled = findClassFile(outConsumer, classToBind);
if (compiled == null) {
context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.WARNING, "Class to bind does not exist: " + classToBind, formFile.getAbsolutePath()));
continue;
}
final File alreadyProcessedForm = class2form.get(classToBind);
if (alreadyProcessedForm != null) {
context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.WARNING, formFile.getAbsolutePath() + ": The form is bound to the class " + classToBind + ".\nAnother form " + alreadyProcessedForm.getAbsolutePath() + " is also bound to this class", formFile.getAbsolutePath()));
continue;
}
class2form.put(classToBind, formFile);
for (File file : compiled.getSourceFiles()) {
addBinding(file, formFile, instrumented);
}
try {
context.processMessage(new ProgressMessage("Instrumenting forms... [" + chunk.getPresentableShortName() + "]"));
final BinaryContent originalContent = compiled.getContent();
final ClassReader classReader = new FailSafeClassReader(originalContent.getBuffer(), originalContent.getOffset(), originalContent.getLength());
final int version = ClassProcessingBuilder.getClassFileVersion(classReader);
final InstrumenterClassWriter classWriter = new InstrumenterClassWriter(classReader, ClassProcessingBuilder.getAsmClassWriterFlags(version), finder);
final AsmCodeGenerator codeGenerator = new AsmCodeGenerator(rootContainer, finder, nestedFormsLoader, false, classWriter);
final byte[] patchedBytes = codeGenerator.patchClass(classReader);
if (patchedBytes != null) {
compiled.setContent(new BinaryContent(patchedBytes));
}
final FormErrorInfo[] warnings = codeGenerator.getWarnings();
for (final FormErrorInfo warning : warnings) {
context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.WARNING, warning.getErrorMessage(), formFile.getAbsolutePath()));
}
final FormErrorInfo[] errors = codeGenerator.getErrors();
if (errors.length > 0) {
StringBuilder message = new StringBuilder();
for (final FormErrorInfo error : errors) {
if (message.length() > 0) {
message.append("\n");
}
message.append(formFile.getAbsolutePath()).append(": ").append(error.getErrorMessage());
}
context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.ERROR, message.toString()));
}
} catch (Exception e) {
context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.ERROR, "Forms instrumentation failed" + e.getMessage(), formFile.getAbsolutePath()));
}
}
return instrumented;
}
use of org.jetbrains.jps.incremental.messages.ProgressMessage 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.messages.ProgressMessage in project intellij-community by JetBrains.
the class JavaBuilderUtil method updateMappings.
/**
* @param filesToCompile files compiled in this round
* @param markDirtyRound compilation round at which dirty files should be visible to builders
* @return true if additional compilation pass is required, false otherwise
* @throws Exception
*/
private static boolean updateMappings(CompileContext context, final Mappings delta, DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder, ModuleChunk chunk, Collection<File> filesToCompile, Collection<File> successfullyCompiled, final CompilationRound markDirtyRound, @Nullable FileFilter skipMarkingDirtyFilter) throws IOException {
try {
boolean performIntegrate = true;
boolean additionalPassRequired = false;
final Set<String> removedPaths = getRemovedPaths(chunk, dirtyFilesHolder);
final Mappings globalMappings = context.getProjectDescriptor().dataManager.getMappings();
final boolean errorsDetected = Utils.errorsDetected(context);
if (!isForcedRecompilationAllJavaModules(context)) {
if (context.shouldDifferentiate(chunk)) {
context.processMessage(new ProgressMessage("Checking dependencies... [" + chunk.getPresentableShortName() + "]"));
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);
// accumulate all successfully compiled in this round
allCompiledFiles.addAll(successfullyCompiled);
// unmark as affected all successfully compiled
allAffectedFiles.removeAll(successfullyCompiled);
final Set<File> affectedBeforeDif = new THashSet<>(FileUtil.FILE_HASHING_STRATEGY);
affectedBeforeDif.addAll(allAffectedFiles);
final Set<File> compiledWithErrors = getFilesContainer(context, COMPILED_WITH_ERRORS_KEY);
COMPILED_WITH_ERRORS_KEY.set(context, null);
final ModulesBasedFileFilter moduleBasedFilter = new ModulesBasedFileFilter(context, chunk);
final boolean incremental = globalMappings.differentiateOnIncrementalMake(delta, removedPaths, filesToCompile, compiledWithErrors, allCompiledFiles, allAffectedFiles, moduleBasedFilter, CONSTANT_SEARCH_SERVICE.get(context));
if (LOG.isDebugEnabled()) {
LOG.debug("Differentiate Results:");
LOG.debug(" Compiled Files:");
for (final File c : allCompiledFiles) {
LOG.debug(" " + c.getAbsolutePath());
}
LOG.debug(" Affected Files:");
for (final File c : allAffectedFiles) {
LOG.debug(" " + c.getAbsolutePath());
}
LOG.debug("End Of Differentiate Results.");
}
if (incremental) {
final Set<File> newlyAffectedFiles = new HashSet<>(allAffectedFiles);
newlyAffectedFiles.removeAll(affectedBeforeDif);
final String infoMessage = "Dependency analysis found " + newlyAffectedFiles.size() + " affected files";
LOG.info(infoMessage);
context.processMessage(new ProgressMessage(infoMessage));
removeFilesAcceptedByFilter(newlyAffectedFiles, skipMarkingDirtyFilter);
if (!newlyAffectedFiles.isEmpty()) {
if (LOG.isDebugEnabled()) {
for (File file : newlyAffectedFiles) {
LOG.debug("affected file: " + file.getPath());
}
final List<Pair<File, JpsModule>> wrongFiles = checkAffectedFilesInCorrectModules(context, newlyAffectedFiles, moduleBasedFilter);
if (!wrongFiles.isEmpty()) {
LOG.debug("Wrong affected files for module chunk " + chunk.getName() + ": ");
for (Pair<File, JpsModule> pair : wrongFiles) {
final String name = pair.second != null ? pair.second.getName() : "null";
LOG.debug("\t[" + name + "] " + pair.first.getPath());
}
}
}
for (File file : newlyAffectedFiles) {
FSOperations.markDirtyIfNotDeleted(context, markDirtyRound, file);
}
additionalPassRequired = isCompileJavaIncrementally(context) && chunkContainsAffectedFiles(context, chunk, newlyAffectedFiles);
}
} else {
// non-incremental mode
final String messageText = "Marking " + chunk.getPresentableShortName() + " and direct dependants for recompilation";
LOG.info("Non-incremental mode: " + messageText);
context.processMessage(new ProgressMessage(messageText));
final boolean alreadyMarkedDirty = FSOperations.isMarkedDirty(context, chunk);
additionalPassRequired = isCompileJavaIncrementally(context) && !alreadyMarkedDirty;
if (alreadyMarkedDirty) {
// need this to make sure changes data stored in Delta is complete
globalMappings.differentiateOnNonIncrementalMake(delta, removedPaths, filesToCompile);
} else {
performIntegrate = false;
}
FileFilter toBeMarkedFilter = skipMarkingDirtyFilter == null ? null : new NegationFileFilter(skipMarkingDirtyFilter);
FSOperations.markDirtyRecursively(context, markDirtyRound, chunk, toBeMarkedFilter);
}
} else {
if (!errorsDetected) {
// makes sense only if we are going to integrate changes
globalMappings.differentiateOnNonIncrementalMake(delta, removedPaths, filesToCompile);
}
}
} else {
if (!errorsDetected) {
// makes sense only if we are going to integrate changes
globalMappings.differentiateOnRebuild(delta);
}
}
if (errorsDetected) {
// will be compiled during the first phase of the next make
return false;
}
if (performIntegrate) {
context.processMessage(new ProgressMessage("Updating dependency information... [" + chunk.getPresentableShortName() + "]"));
globalMappings.integrate(delta);
}
return additionalPassRequired;
} catch (BuildDataCorruptedException e) {
throw e.getCause();
} finally {
// clean progress messages
context.processMessage(new ProgressMessage(""));
}
}
use of org.jetbrains.jps.incremental.messages.ProgressMessage in project intellij-plugins by JetBrains.
the class FlexBuilder method setProgressMessage.
private static void setProgressMessage(final CompileContext context, final JpsFlexBuildConfiguration bc) {
String postfix = bc.isTempBCForCompilation() ? " - " + FlexCommonUtils.getBCSpecifier(bc) : "";
if (!bc.getName().equals(bc.getModule().getName()))
postfix += " (module " + bc.getModule().getName() + ")";
context.processMessage(new ProgressMessage(FlexCommonBundle.message("compiling", bc.getName() + postfix)));
}
use of org.jetbrains.jps.incremental.messages.ProgressMessage in project android by JetBrains.
the class AndroidSourceGeneratingBuilder method runAidlCompiler.
private static boolean runAidlCompiler(@NotNull final CompileContext context, @NotNull Map<File, ModuleBuildTarget> files, @NotNull Map<JpsModule, MyModuleData> moduleDataMap) {
if (files.size() > 0) {
context.processMessage(new ProgressMessage(AndroidJpsBundle.message("android.jps.progress.aidl")));
}
boolean success = true;
for (Map.Entry<File, ModuleBuildTarget> entry : files.entrySet()) {
final File file = entry.getKey();
final ModuleBuildTarget buildTarget = entry.getValue();
final String filePath = file.getPath();
final MyModuleData moduleData = moduleDataMap.get(buildTarget.getModule());
if (!LOG.assertTrue(moduleData != null)) {
context.processMessage(new CompilerMessage(ANDROID_IDL_COMPILER, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.internal.error")));
success = false;
continue;
}
final File generatedSourcesDir = AndroidJpsUtil.getGeneratedSourcesStorage(buildTarget.getModule(), context.getProjectDescriptor().dataManager);
final File aidlOutputDirectory = new File(generatedSourcesDir, AndroidJpsUtil.AIDL_GENERATED_SOURCE_ROOT_NAME);
if (!aidlOutputDirectory.exists() && !aidlOutputDirectory.mkdirs()) {
context.processMessage(new CompilerMessage(ANDROID_IDL_COMPILER, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.cannot.create.directory", aidlOutputDirectory.getPath())));
success = false;
continue;
}
final IAndroidTarget target = moduleData.getPlatform().getTarget();
try {
final File[] sourceRoots = AndroidJpsUtil.getSourceRootsForModuleAndDependencies(buildTarget.getModule());
final String[] sourceRootPaths = AndroidJpsUtil.toPaths(sourceRoots);
final String packageName = computePackageForFile(context, file);
if (packageName == null) {
context.processMessage(new CompilerMessage(ANDROID_IDL_COMPILER, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.errors.cannot.compute.package", filePath)));
success = false;
continue;
}
final File outputFile = new File(aidlOutputDirectory, packageName.replace('.', File.separatorChar) + File.separator + FileUtil.getNameWithoutExtension(file) + ".java");
final String outputFilePath = outputFile.getPath();
final Map<AndroidCompilerMessageKind, List<String>> messages = AndroidIdl.execute(target, filePath, outputFilePath, sourceRootPaths);
addMessages(context, messages, filePath, ANDROID_IDL_COMPILER);
if (messages.get(AndroidCompilerMessageKind.ERROR).size() > 0) {
success = false;
} else if (outputFile.exists()) {
final SourceToOutputMapping sourceToOutputMap = context.getProjectDescriptor().dataManager.getSourceToOutputMap(buildTarget);
sourceToOutputMap.setOutput(filePath, outputFilePath);
FSOperations.markDirty(context, CompilationRound.CURRENT, outputFile);
}
} catch (final IOException e) {
AndroidJpsUtil.reportExceptionError(context, filePath, e, ANDROID_IDL_COMPILER);
success = false;
}
}
return success;
}
Aggregations