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();
}
}
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());
}
}
}
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);
}
}
}
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);
}
}
}
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));
}
}
Aggregations