Search in sources :

Example 6 with CompilerMessage

use of org.jetbrains.jps.incremental.messages.CompilerMessage in project intellij-community by JetBrains.

the class JavaBuilder method compileJava.

private boolean compileJava(CompileContext context, ModuleChunk chunk, Collection<File> files, Collection<File> originalClassPath, Collection<File> originalPlatformCp, Collection<File> sourcePath, DiagnosticOutputConsumer diagnosticSink, OutputFileConsumer outputSink, JavaCompilingTool compilingTool) throws Exception {
    final TasksCounter counter = new TasksCounter();
    COUNTER_KEY.set(context, counter);
    final JpsJavaExtensionService javaExt = JpsJavaExtensionService.getInstance();
    final JpsJavaCompilerConfiguration compilerConfig = javaExt.getCompilerConfiguration(context.getProjectDescriptor().getProject());
    assert compilerConfig != null;
    final Set<JpsModule> modules = chunk.getModules();
    ProcessorConfigProfile profile = null;
    if (modules.size() == 1) {
        profile = compilerConfig.getAnnotationProcessingProfile(modules.iterator().next());
    } else {
        String message = validateCycle(chunk, javaExt, compilerConfig, modules);
        if (message != null) {
            diagnosticSink.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, message));
            return true;
        }
    }
    final Map<File, Set<File>> outs = buildOutputDirectoriesMap(context, chunk);
    try {
        final int targetLanguageLevel = JpsJavaSdkType.parseVersion(getLanguageLevel(chunk.getModules().iterator().next()));
        final boolean shouldForkJavac = shouldForkCompilerProcess(context, chunk, targetLanguageLevel);
        final boolean hasModules = targetLanguageLevel >= 9 && getJavaModuleIndex(context).hasJavaModules(modules);
        // when forking external javac, compilers from SDK 1.6 and higher are supported
        Pair<String, Integer> forkSdk = null;
        if (shouldForkJavac) {
            forkSdk = getForkedJavacSdk(chunk, targetLanguageLevel);
            if (forkSdk == null) {
                String text = "Cannot start javac process for " + chunk.getName() + ": unknown JDK home path.\nPlease check project configuration.";
                diagnosticSink.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, text));
                return true;
            }
        }
        final int compilerSdkVersion = forkSdk == null ? getCompilerSdkVersion(context) : forkSdk.getSecond();
        final List<String> options = getCompilationOptions(compilerSdkVersion, context, chunk, profile, compilingTool);
        if (LOG.isDebugEnabled()) {
            LOG.debug("Compiling chunk [" + chunk.getName() + "] with options: \"" + StringUtil.join(options, " ") + "\"");
        }
        Collection<File> platformCp = calcEffectivePlatformCp(originalPlatformCp, options, compilingTool);
        if (platformCp == null) {
            String text = "Compact compilation profile was requested, but target platform for module \"" + chunk.getName() + "\"" + " differs from javac's platform (" + System.getProperty("java.version") + ")\n" + "Compilation profiles are not supported for such configuration";
            context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, text));
            return true;
        }
        Collection<File> classPath = originalClassPath;
        Collection<File> modulePath = Collections.emptyList();
        if (hasModules) {
            // in Java 9, named modules are not allowed to read classes from the classpath
            // moreover, the compiler requires all transitive dependencies to be on the module path
            modulePath = ProjectPaths.getCompilationModulePath(chunk, false);
            classPath = Collections.emptyList();
        }
        if (!platformCp.isEmpty()) {
            final int chunkSdkVersion;
            if (hasModules) {
                modulePath = newArrayList(concat(platformCp, modulePath));
                platformCp = Collections.emptyList();
            } else if ((chunkSdkVersion = getChunkSdkVersion(chunk)) >= 9) {
                // if chunk's SDK is 9 or higher, there is no way to specify full platform classpath
                // because platform classes are stored in jimage binary files with unknown format.
                // Because of this we are clearing platform classpath so that javac will resolve against its own boot classpath
                // and prepending additional jars from the JDK configuration to compilation classpath
                classPath = newArrayList(concat(platformCp, classPath));
                platformCp = Collections.emptyList();
            } else if (shouldUseReleaseOption(context, compilerSdkVersion, chunkSdkVersion, targetLanguageLevel)) {
                final Collection<File> joined = new ArrayList<>(classPath.size() + 1);
                for (File file : platformCp) {
                    // include only additional jars from sdk distribution, e.g. tools.jar
                    if (!FileUtil.toSystemIndependentName(file.getAbsolutePath()).contains("/jre/")) {
                        joined.add(file);
                    }
                }
                joined.addAll(classPath);
                classPath = joined;
                platformCp = Collections.emptyList();
            }
        }
        final ClassProcessingConsumer classesConsumer = new ClassProcessingConsumer(context, outputSink);
        final boolean rc;
        if (!shouldForkJavac) {
            updateCompilerUsageStatistics(context, compilingTool.getDescription(), chunk);
            rc = JavacMain.compile(options, files, classPath, platformCp, modulePath, sourcePath, outs, diagnosticSink, classesConsumer, context.getCancelStatus(), compilingTool);
        } else {
            updateCompilerUsageStatistics(context, "javac " + forkSdk.getSecond(), chunk);
            final List<String> vmOptions = getCompilationVMOptions(context, compilingTool);
            final ExternalJavacManager server = ensureJavacServerStarted(context);
            rc = server.forkJavac(forkSdk.getFirst(), getExternalJavacHeapSize(context), vmOptions, options, platformCp, classPath, modulePath, sourcePath, files, outs, diagnosticSink, classesConsumer, compilingTool, context.getCancelStatus());
        }
        return rc;
    } finally {
        counter.await();
    }
}
Also used : THashSet(gnu.trove.THashSet) CompilerMessage(org.jetbrains.jps.incremental.messages.CompilerMessage) ContainerUtil.newArrayList(com.intellij.util.containers.ContainerUtil.newArrayList) JpsModule(org.jetbrains.jps.model.module.JpsModule) JpsJavaExtensionService(org.jetbrains.jps.model.java.JpsJavaExtensionService)

Example 7 with CompilerMessage

use of org.jetbrains.jps.incremental.messages.CompilerMessage in project intellij-community by JetBrains.

the class JavaBuilder method addCompilationOptions.

public static void addCompilationOptions(int compilerSdkVersion, List<String> options, CompileContext context, ModuleChunk chunk, @Nullable ProcessorConfigProfile profile) {
    if (!isEncodingSet(options)) {
        final CompilerEncodingConfiguration config = context.getProjectDescriptor().getEncodingConfiguration();
        final String encoding = config.getPreferredModuleChunkEncoding(chunk);
        if (config.getAllModuleChunkEncodings(chunk).size() > 1) {
            final StringBuilder msgBuilder = new StringBuilder();
            msgBuilder.append("Multiple encodings set for module chunk ").append(chunk.getName());
            if (encoding != null) {
                msgBuilder.append("\n\"").append(encoding).append("\" will be used by compiler");
            }
            context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.INFO, msgBuilder.toString()));
        }
        if (!StringUtil.isEmpty(encoding)) {
            options.add("-encoding");
            options.add(encoding);
        }
    }
    addCrossCompilationOptions(compilerSdkVersion, options, context, chunk);
    if (addAnnotationProcessingOptions(options, profile)) {
        final File srcOutput = ProjectPaths.getAnnotationProcessorGeneratedSourcesOutputDir(chunk.getModules().iterator().next(), chunk.containsTests(), profile);
        if (srcOutput != null) {
            srcOutput.mkdirs();
            options.add("-s");
            options.add(srcOutput.getPath());
        }
    }
}
Also used : CompilerMessage(org.jetbrains.jps.incremental.messages.CompilerMessage)

Example 8 with CompilerMessage

use of org.jetbrains.jps.incremental.messages.CompilerMessage in project intellij-community by JetBrains.

the class JavaBuilder method buildFinished.

public void buildFinished(CompileContext context) {
    final ConcurrentMap<String, Collection<String>> stats = COMPILER_USAGE_STATISTICS.get(context);
    if (stats.size() == 1) {
        final Map.Entry<String, Collection<String>> entry = stats.entrySet().iterator().next();
        final String compilerName = entry.getKey();
        context.processMessage(new CompilerMessage("", BuildMessage.Kind.JPS_INFO, compilerName + " was used to compile java sources"));
        LOG.info(compilerName + " was used to compile " + entry.getValue());
    } else {
        for (Map.Entry<String, Collection<String>> entry : stats.entrySet()) {
            final String compilerName = entry.getKey();
            final Collection<String> moduleNames = entry.getValue();
            context.processMessage(new CompilerMessage("", BuildMessage.Kind.JPS_INFO, moduleNames.size() == 1 ? compilerName + " was used to compile [" + moduleNames.iterator().next() + "]" : compilerName + " was used to compile " + moduleNames.size() + " modules"));
            LOG.info(compilerName + " was used to compile " + moduleNames);
        }
    }
}
Also used : CompilerMessage(org.jetbrains.jps.incremental.messages.CompilerMessage) THashMap(gnu.trove.THashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap)

Example 9 with CompilerMessage

use of org.jetbrains.jps.incremental.messages.CompilerMessage in project intellij-community by JetBrains.

the class OutputFilesSink method save.

public void save(@NotNull final OutputFileObject fileObject) {
    final BinaryContent content = fileObject.getContent();
    final File srcFile = fileObject.getSourceFile();
    boolean isTemp = false;
    final JavaFileObject.Kind outKind = fileObject.getKind();
    if (srcFile != null && content != null) {
        final String sourcePath = FileUtil.toSystemIndependentName(srcFile.getPath());
        final JavaSourceRootDescriptor rootDescriptor = myContext.getProjectDescriptor().getBuildRootIndex().findJavaRootDescriptor(myContext, srcFile);
        try {
            if (rootDescriptor != null) {
                isTemp = rootDescriptor.isTemp;
                if (!isTemp) {
                    // first, handle [src->output] mapping and register paths for files_generated event
                    if (outKind == JavaFileObject.Kind.CLASS) {
                        // todo: avoid array copying?
                        myOutputConsumer.registerCompiledClass(rootDescriptor.target, new CompiledClass(fileObject.getFile(), srcFile, fileObject.getClassName(), content));
                    } else {
                        myOutputConsumer.registerOutputFile(rootDescriptor.target, fileObject.getFile(), Collections.<String>singleton(sourcePath));
                    }
                }
            } else {
                // was not able to determine the source root descriptor or the source root is excluded from compilation (e.g. for annotation processors)
                if (outKind == JavaFileObject.Kind.CLASS) {
                    myOutputConsumer.registerCompiledClass(null, new CompiledClass(fileObject.getFile(), srcFile, fileObject.getClassName(), content));
                }
            }
        } catch (IOException e) {
            myContext.processMessage(new CompilerMessage(JavaBuilder.BUILDER_NAME, e));
        }
        if (!isTemp && outKind == JavaFileObject.Kind.CLASS) {
            // register in mappings any non-temp class file
            try {
                final ClassReader reader = new FailSafeClassReader(content.getBuffer(), content.getOffset(), content.getLength());
                myMappingsCallback.associate(FileUtil.toSystemIndependentName(fileObject.getFile().getPath()), sourcePath, reader);
            } catch (Throwable e) {
                // need this to make sure that unexpected errors in, for example, ASM will not ruin the compilation  
                final String message = "Class dependency information may be incomplete! Error parsing generated class " + fileObject.getFile().getPath();
                LOG.info(message, e);
                myContext.processMessage(new CompilerMessage(JavaBuilder.BUILDER_NAME, BuildMessage.Kind.WARNING, message + "\n" + CompilerMessage.getTextFromThrowable(e), sourcePath));
            }
        }
    }
    if (outKind == JavaFileObject.Kind.CLASS) {
        myContext.processMessage(new ProgressMessage("Writing classes... " + myChunkName));
        if (!isTemp && srcFile != null) {
            mySuccessfullyCompiled.add(srcFile);
        }
    }
}
Also used : ProgressMessage(org.jetbrains.jps.incremental.messages.ProgressMessage) CompilerMessage(org.jetbrains.jps.incremental.messages.CompilerMessage) CompiledClass(org.jetbrains.jps.incremental.CompiledClass) IOException(java.io.IOException) BinaryContent(org.jetbrains.jps.incremental.BinaryContent) FailSafeClassReader(com.intellij.compiler.instrumentation.FailSafeClassReader) ClassReader(org.jetbrains.org.objectweb.asm.ClassReader) JavaSourceRootDescriptor(org.jetbrains.jps.builders.java.JavaSourceRootDescriptor) File(java.io.File) FailSafeClassReader(com.intellij.compiler.instrumentation.FailSafeClassReader)

Example 10 with CompilerMessage

use of org.jetbrains.jps.incremental.messages.CompilerMessage in project intellij-community by JetBrains.

the class ResourcesBuilder method copyResource.

private static void copyResource(CompileContext context, ResourceRootDescriptor rd, File file, BuildOutputConsumer outputConsumer) throws IOException {
    final File outputRoot = rd.getTarget().getOutputDir();
    if (outputRoot == null) {
        return;
    }
    final String sourceRootPath = FileUtil.toSystemIndependentName(rd.getRootFile().getAbsolutePath());
    final String relativePath = FileUtil.getRelativePath(sourceRootPath, FileUtil.toSystemIndependentName(file.getPath()), '/');
    final String prefix = rd.getPackagePrefix();
    final StringBuilder targetPath = new StringBuilder();
    targetPath.append(FileUtil.toSystemIndependentName(outputRoot.getPath()));
    if (prefix.length() > 0) {
        targetPath.append('/').append(prefix.replace('.', '/'));
    }
    targetPath.append('/').append(relativePath);
    context.processMessage(new ProgressMessage("Copying resources... [" + rd.getTarget().getModule().getName() + "]"));
    final String outputPath = targetPath.toString();
    final File targetFile = new File(outputPath);
    FileUtil.copyContent(file, targetFile);
    try {
        outputConsumer.registerOutputFile(targetFile, Collections.singletonList(file.getPath()));
    } catch (Exception e) {
        context.processMessage(new CompilerMessage(BUILDER_NAME, e));
    }
}
Also used : ProgressMessage(org.jetbrains.jps.incremental.messages.ProgressMessage) CompilerMessage(org.jetbrains.jps.incremental.messages.CompilerMessage) File(java.io.File) IOException(java.io.IOException) ProjectBuildException(org.jetbrains.jps.incremental.ProjectBuildException) BuildDataCorruptedException(org.jetbrains.jps.builders.storage.BuildDataCorruptedException)

Aggregations

CompilerMessage (org.jetbrains.jps.incremental.messages.CompilerMessage)75 File (java.io.File)34 IOException (java.io.IOException)22 ProgressMessage (org.jetbrains.jps.incremental.messages.ProgressMessage)18 JpsModule (org.jetbrains.jps.model.module.JpsModule)15 HashMap (com.intellij.util.containers.HashMap)11 JpsAndroidModuleExtension (org.jetbrains.jps.android.model.JpsAndroidModuleExtension)11 TObjectLongHashMap (gnu.trove.TObjectLongHashMap)9 ArrayList (java.util.ArrayList)9 THashSet (gnu.trove.THashSet)8 Nullable (org.jetbrains.annotations.Nullable)8 ProjectBuildException (org.jetbrains.jps.incremental.ProjectBuildException)8 IAndroidTarget (com.android.sdklib.IAndroidTarget)7 NotNull (org.jetbrains.annotations.NotNull)7 BuildMessage (org.jetbrains.jps.incremental.messages.BuildMessage)6 AndroidCompilerMessageKind (org.jetbrains.android.util.AndroidCompilerMessageKind)5 FailSafeClassReader (com.intellij.compiler.instrumentation.FailSafeClassReader)4 JpsDummyElement (org.jetbrains.jps.model.JpsDummyElement)4 Pair (com.intellij.openapi.util.Pair)3 THashMap (gnu.trove.THashMap)3