Search in sources :

Example 1 with ProgressMessage

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;
}
Also used : ProgressMessage(org.jetbrains.jps.incremental.messages.ProgressMessage) CompilerMessage(org.jetbrains.jps.incremental.messages.CompilerMessage) THashMap(gnu.trove.THashMap) LwRootContainer(com.intellij.uiDesigner.lw.LwRootContainer) THashMap(gnu.trove.THashMap) InstrumenterClassWriter(com.intellij.compiler.instrumentation.InstrumenterClassWriter) CompiledClassPropertiesProvider(com.intellij.uiDesigner.lw.CompiledClassPropertiesProvider) FailSafeClassReader(com.intellij.compiler.instrumentation.FailSafeClassReader) ClassReader(org.jetbrains.org.objectweb.asm.ClassReader) FailSafeClassReader(com.intellij.compiler.instrumentation.FailSafeClassReader)

Example 2 with ProgressMessage

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;
}
Also used : ProgressMessage(org.jetbrains.jps.incremental.messages.ProgressMessage) OneToManyPathsMapping(org.jetbrains.jps.incremental.storage.OneToManyPathsMapping) InstrumentationClassFinder(com.intellij.compiler.instrumentation.InstrumentationClassFinder) THashSet(gnu.trove.THashSet) ProjectBuilderLogger(org.jetbrains.jps.builders.logging.ProjectBuilderLogger) JpsUiDesignerConfiguration(org.jetbrains.jps.uiDesigner.model.JpsUiDesignerConfiguration) GridConstraints(com.intellij.uiDesigner.core.GridConstraints) JpsProject(org.jetbrains.jps.model.JpsProject) JpsDummyElement(org.jetbrains.jps.model.JpsDummyElement) THashMap(gnu.trove.THashMap)

Example 3 with ProgressMessage

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(""));
    }
}
Also used : ProgressMessage(org.jetbrains.jps.incremental.messages.ProgressMessage) THashSet(gnu.trove.THashSet) JpsModule(org.jetbrains.jps.model.module.JpsModule) BuildDataCorruptedException(org.jetbrains.jps.builders.storage.BuildDataCorruptedException) Mappings(org.jetbrains.jps.builders.java.dependencyView.Mappings) FileFilter(java.io.FileFilter) File(java.io.File) THashSet(gnu.trove.THashSet) Pair(com.intellij.openapi.util.Pair)

Example 4 with 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)));
}
Also used : ProgressMessage(org.jetbrains.jps.incremental.messages.ProgressMessage)

Example 5 with ProgressMessage

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;
}
Also used : ProgressMessage(org.jetbrains.jps.incremental.messages.ProgressMessage) SourceToOutputMapping(org.jetbrains.jps.builders.storage.SourceToOutputMapping) CompilerMessage(org.jetbrains.jps.incremental.messages.CompilerMessage) IAndroidTarget(com.android.sdklib.IAndroidTarget) HashMap(com.intellij.util.containers.HashMap) TObjectLongHashMap(gnu.trove.TObjectLongHashMap)

Aggregations

ProgressMessage (org.jetbrains.jps.incremental.messages.ProgressMessage)32 File (java.io.File)20 CompilerMessage (org.jetbrains.jps.incremental.messages.CompilerMessage)17 IOException (java.io.IOException)14 JpsModule (org.jetbrains.jps.model.module.JpsModule)10 THashSet (gnu.trove.THashSet)8 JpsAndroidModuleExtension (org.jetbrains.jps.android.model.JpsAndroidModuleExtension)7 ProjectBuildException (org.jetbrains.jps.incremental.ProjectBuildException)5 IAndroidTarget (com.android.sdklib.IAndroidTarget)4 HashMap (com.intellij.util.containers.HashMap)4 TObjectLongHashMap (gnu.trove.TObjectLongHashMap)4 ArrayList (java.util.ArrayList)4 ProjectBuilderLogger (org.jetbrains.jps.builders.logging.ProjectBuilderLogger)4 Pair (com.intellij.openapi.util.Pair)3 HashSet (com.intellij.util.containers.HashSet)3 AndroidBuildTestingManager (org.jetbrains.android.util.AndroidBuildTestingManager)3 BuildRootDescriptor (org.jetbrains.jps.builders.BuildRootDescriptor)3 JavaSourceRootDescriptor (org.jetbrains.jps.builders.java.JavaSourceRootDescriptor)3 BuildDataCorruptedException (org.jetbrains.jps.builders.storage.BuildDataCorruptedException)3 JpsProject (org.jetbrains.jps.model.JpsProject)3