use of org.jetbrains.jps.incremental.BinaryContent in project intellij-community by JetBrains.
the class CompilerManagerImpl method compileJavaCode.
@Override
public Collection<ClassObject> compileJavaCode(List<String> options, Collection<File> platformCp, Collection<File> classpath, Collection<File> modulePath, Collection<File> sourcePath, Collection<File> files, File outputDir) throws IOException, CompilationException {
final Pair<Sdk, JavaSdkVersion> runtime = BuildManager.getJavacRuntimeSdk(myProject);
final Sdk sdk = runtime.getFirst();
final SdkTypeId type = sdk.getSdkType();
String javaHome = null;
if (type instanceof JavaSdkType) {
javaHome = sdk.getHomePath();
if (!isJdkOrJre(javaHome)) {
// this can be a java-dependent SDK, implementing JavaSdkType
// hack, because there is no direct way to obtain the java sdk, this sdk depends on
final String binPath = ((JavaSdkType) type).getBinPath(sdk);
javaHome = binPath != null ? new File(binPath).getParent() : null;
if (!isJdkOrJre(javaHome)) {
javaHome = null;
}
}
}
if (javaHome == null) {
throw new IOException("Was not able to determine JDK for project " + myProject.getName());
}
final OutputCollector outputCollector = new OutputCollector();
DiagnosticCollector diagnostic = new DiagnosticCollector();
final Set<File> sourceRoots = new THashSet<>(FileUtil.FILE_HASHING_STRATEGY);
if (!sourcePath.isEmpty()) {
for (File file : sourcePath) {
sourceRoots.add(file);
}
} else {
for (File file : files) {
final File parentFile = file.getParentFile();
if (parentFile != null) {
sourceRoots.add(parentFile);
}
}
}
final Map<File, Set<File>> outs = Collections.singletonMap(outputDir, sourceRoots);
final ExternalJavacManager javacManager = getJavacManager();
boolean compiledOk = javacManager != null && javacManager.forkJavac(javaHome, -1, Collections.emptyList(), options, platformCp, classpath, modulePath, sourcePath, files, outs, diagnostic, outputCollector, new JavacCompilerTool(), CanceledStatus.NULL);
if (!compiledOk) {
final List<CompilationException.Message> messages = new SmartList<>();
for (Diagnostic<? extends JavaFileObject> d : diagnostic.getDiagnostics()) {
final JavaFileObject source = d.getSource();
final URI uri = source != null ? source.toUri() : null;
messages.add(new CompilationException.Message(kindToCategory(d.getKind()), d.getMessage(Locale.US), uri != null ? uri.toURL().toString() : null, (int) d.getLineNumber(), (int) d.getColumnNumber()));
}
throw new CompilationException("Compilation failed", messages);
}
final List<ClassObject> result = new ArrayList<>();
for (OutputFileObject fileObject : outputCollector.getCompiledClasses()) {
final BinaryContent content = fileObject.getContent();
result.add(new CompiledClass(fileObject.getName(), fileObject.getClassName(), content != null ? content.toByteArray() : null));
}
return result;
}
use of org.jetbrains.jps.incremental.BinaryContent in project intellij-community by JetBrains.
the class ExternalJavacMessageHandler method handleMessage.
public boolean handleMessage(MessageLite message) {
try {
final JavacRemoteProto.Message msg = (JavacRemoteProto.Message) message;
final JavacRemoteProto.Message.Type messageType = msg.getMessageType();
if (messageType == JavacRemoteProto.Message.Type.RESPONSE) {
final JavacRemoteProto.Message.Response response = msg.getResponse();
final JavacRemoteProto.Message.Response.Type responseType = response.getResponseType();
if (responseType == JavacRemoteProto.Message.Response.Type.BUILD_MESSAGE) {
final JavacRemoteProto.Message.Response.CompileMessage compileMessage = response.getCompileMessage();
final JavacRemoteProto.Message.Response.CompileMessage.Kind messageKind = compileMessage.getKind();
if (messageKind == JavacRemoteProto.Message.Response.CompileMessage.Kind.STD_OUT) {
if (compileMessage.hasText()) {
myDiagnosticSink.outputLineAvailable(compileMessage.getText());
}
} else {
final String sourceUri = compileMessage.hasSourceUri() ? compileMessage.getSourceUri() : null;
final JavaFileObject srcFileObject = sourceUri != null ? new DummyJavaFileObject(URI.create(sourceUri)) : null;
myDiagnosticSink.report(new DummyDiagnostic(convertKind(messageKind), srcFileObject, compileMessage));
}
return false;
}
if (responseType == JavacRemoteProto.Message.Response.Type.OUTPUT_OBJECT) {
final JavacRemoteProto.Message.Response.OutputObject outputObject = response.getOutputObject();
final JavacRemoteProto.Message.Response.OutputObject.Kind kind = outputObject.getKind();
final String outputRoot = outputObject.hasOutputRoot() ? outputObject.getOutputRoot() : null;
final File outputRootFile = outputRoot != null ? new File(outputRoot) : null;
final BinaryContent fileObjectContent;
final ByteString content = outputObject.hasContent() ? outputObject.getContent() : null;
if (content != null) {
final byte[] bytes = content.toByteArray();
fileObjectContent = new BinaryContent(bytes, 0, bytes.length);
} else {
fileObjectContent = null;
}
final String sourceUri = outputObject.hasSourceUri() ? outputObject.getSourceUri() : null;
final URI srcUri = sourceUri != null ? URI.create(sourceUri) : null;
final OutputFileObject fileObject = new OutputFileObject(null, outputRootFile, outputObject.hasRelativePath() ? outputObject.getRelativePath() : null, new File(outputObject.getFilePath()), convertKind(kind), outputObject.hasClassName() ? outputObject.getClassName() : null, srcUri, myEncodingName, fileObjectContent);
myOutputSink.save(fileObject);
return false;
}
if (responseType == JavacRemoteProto.Message.Response.Type.SRC_FILE_LOADED) {
final JavacRemoteProto.Message.Response.OutputObject outputObject = response.getOutputObject();
final File file = new File(outputObject.getFilePath());
myDiagnosticSink.javaFileLoaded(file);
return false;
}
if (responseType == JavacRemoteProto.Message.Response.Type.CLASS_DATA) {
final JavacRemoteProto.Message.Response.ClassData data = response.getClassData();
final String className = data.getClassName();
final Collection<String> imports = data.getImportStatementList();
final Collection<String> staticImports = data.getStaticImportList();
myDiagnosticSink.registerImports(className, imports, staticImports);
return false;
}
if (responseType == JavacRemoteProto.Message.Response.Type.CUSTOM_OUTPUT_OBJECT) {
final JavacRemoteProto.Message.Response.OutputObject outputObject = response.getOutputObject();
final String pluginId = outputObject.getFilePath();
final String name = outputObject.getClassName();
final byte[] content = outputObject.hasContent() ? outputObject.getContent().toByteArray() : new byte[0];
myDiagnosticSink.customOutputData(pluginId, name, content);
return false;
}
if (responseType == JavacRemoteProto.Message.Response.Type.BUILD_COMPLETED) {
if (response.hasCompletionStatus()) {
myTerminatedSuccessfully = response.getCompletionStatus();
}
return true;
}
throw new Exception("Unsupported response type: " + responseType.name());
}
if (messageType == JavacRemoteProto.Message.Type.FAILURE) {
final JavacRemoteProto.Message.Failure failure = msg.getFailure();
final StringBuilder buf = new StringBuilder();
if (failure.hasDescription()) {
buf.append(failure.getDescription());
}
if (failure.hasStacktrace()) {
if (buf.length() > 0) {
buf.append("\n");
}
buf.append(failure.getStacktrace());
}
myDiagnosticSink.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, buf.toString()));
return true;
}
throw new Exception("Unsupported message type: " + messageType.name());
} catch (Throwable e) {
myDiagnosticSink.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, e.getMessage()));
return true;
}
}
use of org.jetbrains.jps.incremental.BinaryContent in project intellij-community by JetBrains.
the class OutputFileObject method getCharContent.
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
final BinaryContent content = myContent;
final String encoding = myEncodingName;
if (content != null) {
return encoding == null ? new String(content.getBuffer(), content.getOffset(), content.getLength()) : new String(content.getBuffer(), content.getOffset(), content.getLength(), encoding);
}
return FileUtilRt.loadFile(myFile, encoding, false);
}
use of org.jetbrains.jps.incremental.BinaryContent in project intellij-community by JetBrains.
the class PatternValidatorBuilder method instrument.
@Nullable
@Override
protected BinaryContent instrument(CompileContext context, CompiledClass compiled, ClassReader reader, ClassWriter writer, InstrumentationClassFinder finder) {
final JpsIntelliLangConfiguration config = JpsIntelliLangExtensionService.getInstance().getConfiguration(context.getProjectDescriptor().getModel().getGlobal());
final PatternInstrumenter instrumenter = new PatternInstrumenter(config.getPatternAnnotationClass(), writer, config.getInstrumentationType(), finder);
try {
reader.accept(instrumenter, 0);
if (instrumenter.instrumented()) {
return new BinaryContent(writer.toByteArray());
}
} catch (InstrumentationException e) {
context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.ERROR, e.getMessage()));
}
return null;
}
use of org.jetbrains.jps.incremental.BinaryContent 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);
}
}
}
Aggregations