From a691b91a32706c64ac05fc09bf706f40b476f79d Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 23 Jan 2012 15:47:05 +0100 Subject: [PATCH] javac server impl --- .../compiler/CompileServerManager.java | 3 +- .../proto/javac_remote_proto.proto | 4 +- .../CanceledStatus.java} | 4 +- .../jps/incremental/CompileContext.java | 10 +- .../jps/incremental/IncProjectBuilder.java | 6 +- .../jps/incremental/java/JavaBuilder.java | 2 +- .../jps/javac/EmbeddedJavacProxy.java | 10 +- .../jps/javac/ExternalProcessJavacProxy.java | 10 +- .../jetbrains/jps/javac/JavacFileManager.java | 2 + .../org/jetbrains/jps/javac/JavacMain.java | 8 +- .../jetbrains/jps/javac/JavacProtoUtil.java | 131 ++++++++++++++++++ .../jetbrains/jps/javac/JavacRemoteProto.java | 89 ++++++++---- .../org/jetbrains/jps/javac/JavacServer.java | 98 ++++++++++++- .../jps/javac/JavacServerClient.java | 10 +- .../jps/server/ServerMessageHandler.java | 2 +- .../org/jetbrains/jps/server/ServerState.java | 7 +- 16 files changed, 341 insertions(+), 55 deletions(-) rename jps/jps-builders/src/org/jetbrains/jps/{server/BuildCanceledStatus.java => api/CanceledStatus.java} (53%) create mode 100644 jps/jps-builders/src/org/jetbrains/jps/javac/JavacProtoUtil.java diff --git a/java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java b/java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java index fe60dddad08c..c4234a7cca1c 100644 --- a/java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java @@ -411,7 +411,8 @@ public class CompileServerManager implements ApplicationComponent{ // debugging cmdLine.addParameter("-XX:+HeapDumpOnOutOfMemoryError"); - cmdLine.addParameter("-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5008"); + //cmdLine.addParameter("-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5008"); + if (Registry.is("compiler.server.use.memory.temp.cache")) { cmdLine.addParameter("-D"+Server.USE_MEMORY_TEMP_CACHE_OPTION + "=true"); } diff --git a/jps/jps-builders/proto/javac_remote_proto.proto b/jps/jps-builders/proto/javac_remote_proto.proto index db9133118092..ea213a3d8d90 100644 --- a/jps/jps-builders/proto/javac_remote_proto.proto +++ b/jps/jps-builders/proto/javac_remote_proto.proto @@ -55,6 +55,7 @@ message Message { ERROR = 1; WARNING = 2; INFO = 3; + STD_OUT = 4; } required Kind kind = 1; optional string text = 2; @@ -79,13 +80,14 @@ message Message { optional string output_root = 3; optional string relative_path = 4; optional string class_name = 5; - optional string source_uri = 6; + optional string source_path = 6; optional bytes content = 7; } required Type response_type = 1; optional CompileMessage compile_message = 2; optional OutputObject output_object = 3; + optional bool completion_status = 4; } required UUID session_id = 1; diff --git a/jps/jps-builders/src/org/jetbrains/jps/server/BuildCanceledStatus.java b/jps/jps-builders/src/org/jetbrains/jps/api/CanceledStatus.java similarity index 53% rename from jps/jps-builders/src/org/jetbrains/jps/server/BuildCanceledStatus.java rename to jps/jps-builders/src/org/jetbrains/jps/api/CanceledStatus.java index 2517dd6f7a26..d97759a183e1 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/server/BuildCanceledStatus.java +++ b/jps/jps-builders/src/org/jetbrains/jps/api/CanceledStatus.java @@ -1,9 +1,9 @@ -package org.jetbrains.jps.server; +package org.jetbrains.jps.api; /** * @author Eugene Zhuravlev * Date: 1/13/12 */ -public interface BuildCanceledStatus { +public interface CanceledStatus { boolean isCanceled(); } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java index 47190aa05fe8..23200ff2ffb2 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java @@ -6,13 +6,13 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.ether.dependencyView.Mappings; import org.jetbrains.jps.*; +import org.jetbrains.jps.api.CanceledStatus; import org.jetbrains.jps.incremental.messages.BuildMessage; import org.jetbrains.jps.incremental.messages.ProgressMessage; import org.jetbrains.jps.incremental.messages.UptoDateFilesSavedEvent; import org.jetbrains.jps.incremental.storage.BuildDataManager; import org.jetbrains.jps.incremental.storage.SourceToOutputMapping; import org.jetbrains.jps.incremental.storage.TimestampStorage; -import org.jetbrains.jps.server.BuildCanceledStatus; import java.io.File; import java.util.*; @@ -39,7 +39,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler private volatile boolean myErrorsFound = false; private final long myCompilationStartStamp; private final TimestampStorage myTsStorage; - private final BuildCanceledStatus myCancelStatus; + private final CanceledStatus myCancelStatus; private float myDone = -1.0f; public CompileContext(CompileScope scope, @@ -47,7 +47,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler boolean isProjectRebuild, ProjectChunks productionChunks, ProjectChunks testChunks, - FSState fsState, final BuildDataManager dataManager, TimestampStorage tsStorage, MessageHandler delegateMessageHandler, final ModuleRootsIndex rootsIndex, BuildCanceledStatus cancelStatus) throws ProjectBuildException { + FSState fsState, final BuildDataManager dataManager, TimestampStorage tsStorage, MessageHandler delegateMessageHandler, final ModuleRootsIndex rootsIndex, CanceledStatus cancelStatus) throws ProjectBuildException { myTsStorage = tsStorage; myCancelStatus = cancelStatus; myCompilationStartStamp = System.currentTimeMillis(); @@ -146,6 +146,10 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler return myCompilingTests; } + public CanceledStatus getCancelStatus() { + return myCancelStatus; + } + void setCompilingTests(boolean compilingTests) { myCompilingTests = compilingTests; } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java index a1140d4bf783..8e3b8479238b 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java @@ -3,6 +3,7 @@ package org.jetbrains.jps.incremental; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.io.PersistentEnumerator; import org.jetbrains.jps.*; +import org.jetbrains.jps.api.CanceledStatus; import org.jetbrains.jps.incremental.messages.BuildMessage; import org.jetbrains.jps.incremental.messages.CompilerMessage; import org.jetbrains.jps.incremental.messages.ProgressMessage; @@ -10,7 +11,6 @@ import org.jetbrains.jps.incremental.storage.BuildDataManager; import org.jetbrains.jps.incremental.storage.SourceToFormMapping; import org.jetbrains.jps.incremental.storage.SourceToOutputMapping; import org.jetbrains.jps.incremental.storage.TimestampStorage; -import org.jetbrains.jps.server.BuildCanceledStatus; import org.jetbrains.jps.server.ProjectDescriptor; import java.io.File; @@ -28,7 +28,7 @@ public class IncProjectBuilder { private final ProjectDescriptor myProjectDescriptor; private final BuilderRegistry myBuilderRegistry; - private final BuildCanceledStatus myCancelStatus; + private final CanceledStatus myCancelStatus; private ProjectChunks myProductionChunks; private ProjectChunks myTestChunks; private final List myMessageHandlers = new ArrayList(); @@ -44,7 +44,7 @@ public class IncProjectBuilder { private final float myTotalModulesWork; private final int myTotalBuilderCount; - public IncProjectBuilder(ProjectDescriptor pd, BuilderRegistry builderRegistry, BuildCanceledStatus cs) { + public IncProjectBuilder(ProjectDescriptor pd, BuilderRegistry builderRegistry, CanceledStatus cs) { myProjectDescriptor = pd; myBuilderRegistry = builderRegistry; myCancelStatus = cs; diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java index d1e5e8ebae13..574e4119959f 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java @@ -300,7 +300,7 @@ public class JavaBuilder extends Builder{ } private JavacProxy createJavacProxy(CompileContext context) { - return new EmbeddedJavacProxy(); + return new EmbeddedJavacProxy(context.getCancelStatus()); } private static ClassLoader createInstrumentationClassLoader(Collection classpath, Collection platformCp, Map chunkSourcePath, OutputFilesSink outputSink) diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/EmbeddedJavacProxy.java b/jps/jps-builders/src/org/jetbrains/jps/javac/EmbeddedJavacProxy.java index 04479475558d..5bfedba45c06 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/EmbeddedJavacProxy.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/EmbeddedJavacProxy.java @@ -1,5 +1,7 @@ package org.jetbrains.jps.javac; +import org.jetbrains.jps.api.CanceledStatus; + import java.io.File; import java.util.Collection; import java.util.List; @@ -12,7 +14,13 @@ import java.util.Set; */ public class EmbeddedJavacProxy extends JavacProxy{ + private final CanceledStatus myCanceledStatus; + + public EmbeddedJavacProxy(CanceledStatus canceledStatus) { + myCanceledStatus = canceledStatus; + } + public boolean compile(List options, Collection files, Collection classpath, Collection platformCp, Collection sourcePath, Map> outs, DiagnosticOutputConsumer diagnosticSink, OutputFileConsumer outputSink) { - return JavacMain.compile(options, files, classpath, platformCp, sourcePath, outs, diagnosticSink, outputSink); + return JavacMain.compile(options, files, classpath, platformCp, sourcePath, outs, diagnosticSink, outputSink, myCanceledStatus); } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/ExternalProcessJavacProxy.java b/jps/jps-builders/src/org/jetbrains/jps/javac/ExternalProcessJavacProxy.java index 90d28084b93b..057c86ea9fd1 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/ExternalProcessJavacProxy.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/ExternalProcessJavacProxy.java @@ -1,5 +1,7 @@ package org.jetbrains.jps.javac; +import org.jetbrains.jps.api.CanceledStatus; + import java.io.File; import java.util.Collection; import java.util.List; @@ -12,11 +14,17 @@ import java.util.Set; */ public class ExternalProcessJavacProxy extends JavacProxy{ + private final CanceledStatus myCanceledStatus; + + public ExternalProcessJavacProxy(CanceledStatus canceledStatus) { + myCanceledStatus = canceledStatus; + } + public boolean connect() { return false; // todo } public boolean compile(List options, Collection files, Collection classpath, Collection platformCp, Collection sourcePath, Map> outs, DiagnosticOutputConsumer diagnosticSink, OutputFileConsumer outputSink) { - return JavacMain.compile(options, files, classpath, platformCp, sourcePath, outs, diagnosticSink, outputSink); + return false; // todo } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacFileManager.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacFileManager.java index 66b38d6e2f61..9bc9c4239cc1 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacFileManager.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacFileManager.java @@ -23,6 +23,8 @@ class JavacFileManager extends ForwardingJavaFileManager> myOutputsMap = Collections.emptyMap(); interface Context { + boolean isCanceled(); + StandardJavaFileManager getStandardFileManager(); void consumeOutputFile(@NotNull OutputFileObject obj); diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java index 532f2c247834..626a0d5a33a0 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java @@ -2,6 +2,8 @@ package org.jetbrains.jps.javac; import com.intellij.openapi.util.SystemInfo; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.api.CanceledStatus; import org.jetbrains.jps.server.ClasspathBootstrap; import javax.tools.*; @@ -24,7 +26,7 @@ public class JavacMain { Collection sourcePath, Map> outputDirToRoots, final DiagnosticOutputConsumer outConsumer, - final OutputFileConsumer outputSink) { + final OutputFileConsumer outputSink, @Nullable CanceledStatus canceledStatus) { final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); for (File outputDir : outputDirToRoots.keySet()) { @@ -117,6 +119,10 @@ public class JavacMain { } } + public boolean isCanceled() { + return false; // todo + } + public StandardJavaFileManager getStandardFileManager() { return myStdManager; } diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacProtoUtil.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacProtoUtil.java new file mode 100644 index 000000000000..3e2c403fca0c --- /dev/null +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacProtoUtil.java @@ -0,0 +1,131 @@ +package org.jetbrains.jps.javac; + +import com.google.protobuf.ByteString; +import com.intellij.openapi.util.io.FileUtil; + +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; +import java.io.File; +import java.util.UUID; + +/** + * @author Eugene Zhuravlev + * Date: 1/23/12 + */ +public class JavacProtoUtil { + + public static JavacRemoteProto.Message.Response createOutputObjectResponse(OutputFileObject fileObject) { + final JavacRemoteProto.Message.Response.OutputObject.Builder msgBuilder = JavacRemoteProto.Message.Response.OutputObject.newBuilder(); + + msgBuilder.setKind(convertKind(fileObject.getKind())); + msgBuilder.setFilePath(FileUtil.toSystemIndependentName(fileObject.getFile().getPath())); + final OutputFileObject.Content content = fileObject.getContent(); + if (content != null) { + msgBuilder.setContent(ByteString.copyFrom(content.getBuffer(), content.getOffset(), content.getLength())); + } + final String className = fileObject.getClassName(); + if (className != null) { + msgBuilder.setClassName(className); + } + final File outputRoot = fileObject.getOutputRoot(); + if (outputRoot != null) { + msgBuilder.setOutputRoot(FileUtil.toSystemIndependentName(outputRoot.getPath())); + } + final String relativePath = fileObject.getRelativePath(); + if (relativePath != null) { + msgBuilder.setRelativePath(relativePath); + } + final File sourceFile = fileObject.getSourceFile(); + if (sourceFile != null) { + msgBuilder.setSourcePath(FileUtil.toSystemIndependentName(sourceFile.getPath())); + } + + final JavacRemoteProto.Message.Response.Builder builder = JavacRemoteProto.Message.Response.newBuilder(); + builder.setResponseType(JavacRemoteProto.Message.Response.Type.OUTPUT_OBJECT).setOutputObject(msgBuilder.build()); + + return builder.build(); + } + + public static JavacRemoteProto.Message.Response createStdOutputResponse(String text) { + final JavacRemoteProto.Message.Response.CompileMessage.Builder msgBuilder = JavacRemoteProto.Message.Response.CompileMessage.newBuilder(); + msgBuilder.setKind(JavacRemoteProto.Message.Response.CompileMessage.Kind.STD_OUT); + msgBuilder.setText(text); + final JavacRemoteProto.Message.Response.Builder builder = JavacRemoteProto.Message.Response.newBuilder(); + builder.setResponseType(JavacRemoteProto.Message.Response.Type.BUILD_MESSAGE).setCompileMessage(msgBuilder.build()); + + return builder.build(); + } + + public static JavacRemoteProto.Message.Response createBuildMessageResponse(Diagnostic.Kind kind, String text, final String srcPath, final long line, final long column, final long beginOffset, final long endOffset) { + final JavacRemoteProto.Message.Response.CompileMessage.Builder msgBuilder = JavacRemoteProto.Message.Response.CompileMessage.newBuilder(); + msgBuilder.setKind(convertKind(kind)); + msgBuilder.setText(text); + msgBuilder.setSourceFilePath(srcPath); + msgBuilder.setLine(line); + msgBuilder.setColumn(column); + msgBuilder.setProblemBeginOffset(beginOffset); + msgBuilder.setProblemEndOffset(endOffset); + + final JavacRemoteProto.Message.Response.Builder builder = JavacRemoteProto.Message.Response.newBuilder(); + builder.setResponseType(JavacRemoteProto.Message.Response.Type.BUILD_MESSAGE).setCompileMessage(msgBuilder.build()); + + return builder.build(); + } + + public static JavacRemoteProto.Message.Response createBuildCompletedResponse(boolean code) { + final JavacRemoteProto.Message.Response.Builder builder = JavacRemoteProto.Message.Response.newBuilder(); + builder.setResponseType(JavacRemoteProto.Message.Response.Type.BUILD_COMPLETED).setCompletionStatus(code); + return builder.build(); + } + + public static JavacRemoteProto.Message.Failure createFailure(String description) { + final JavacRemoteProto.Message.Failure.Builder builder = JavacRemoteProto.Message.Failure.newBuilder(); + builder.setDescription(description); + return builder.build(); + } + + public static JavacRemoteProto.Message toMessage(UUID requestId, JavacRemoteProto.Message.Request request) { + return JavacRemoteProto.Message.newBuilder().setMessageType(JavacRemoteProto.Message.Type.REQUEST).setSessionId(toProtoUUID(requestId)).setRequest(request).build(); + } + + public static JavacRemoteProto.Message toMessage(UUID requestId, JavacRemoteProto.Message.Response response) { + return JavacRemoteProto.Message.newBuilder().setMessageType(JavacRemoteProto.Message.Type.RESPONSE).setSessionId(toProtoUUID(requestId)).setResponse(response).build(); + } + + public static JavacRemoteProto.Message toMessage(UUID requestId, JavacRemoteProto.Message.Failure failure) { + return JavacRemoteProto.Message.newBuilder().setMessageType(JavacRemoteProto.Message.Type.FAILURE).setSessionId(toProtoUUID(requestId)).setFailure(failure).build(); + } + + public static JavacRemoteProto.Message.UUID toProtoUUID(UUID requestId) { + return JavacRemoteProto.Message.UUID.newBuilder().setMostSigBits(requestId.getMostSignificantBits()).setLeastSigBits(requestId.getLeastSignificantBits()).build(); + } + public static UUID fromProtoUUID(JavacRemoteProto.Message.UUID requestId) { + return new UUID(requestId.getMostSigBits(), requestId.getLeastSigBits()); + } + + private static JavacRemoteProto.Message.Response.OutputObject.Kind convertKind(JavaFileObject.Kind kind) { + switch (kind) { + case CLASS: + return JavacRemoteProto.Message.Response.OutputObject.Kind.CLASS; + case SOURCE: + return JavacRemoteProto.Message.Response.OutputObject.Kind.SOURCE; + case HTML: + return JavacRemoteProto.Message.Response.OutputObject.Kind.HTML; + default: + return JavacRemoteProto.Message.Response.OutputObject.Kind.OTHER; + } + } + private static JavacRemoteProto.Message.Response.CompileMessage.Kind convertKind(Diagnostic.Kind kind) { + switch (kind) { + case ERROR: + return JavacRemoteProto.Message.Response.CompileMessage.Kind.ERROR; + case MANDATORY_WARNING: + case WARNING: + case NOTE: + return JavacRemoteProto.Message.Response.CompileMessage.Kind.WARNING; + default: + return JavacRemoteProto.Message.Response.CompileMessage.Kind.INFO; + } + } + +} diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacRemoteProto.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacRemoteProto.java index 24e9e4f8e672..88f8bfa724a5 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacRemoteProto.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacRemoteProto.java @@ -1890,6 +1890,7 @@ public final class JavacRemoteProto { ERROR(0, 1), WARNING(1, 2), INFO(2, 3), + STD_OUT(3, 4), ; @@ -1900,6 +1901,7 @@ public final class JavacRemoteProto { case 1: return ERROR; case 2: return WARNING; case 3: return INFO; + case 4: return STD_OUT; default: return null; } } @@ -2544,12 +2546,12 @@ public final class JavacRemoteProto { public boolean hasClassName() { return hasClassName; } public java.lang.String getClassName() { return className_; } - // optional string source_uri = 6; - public static final int SOURCE_URI_FIELD_NUMBER = 6; - private boolean hasSourceUri; - private java.lang.String sourceUri_ = ""; - public boolean hasSourceUri() { return hasSourceUri; } - public java.lang.String getSourceUri() { return sourceUri_; } + // optional string source_path = 6; + public static final int SOURCE_PATH_FIELD_NUMBER = 6; + private boolean hasSourcePath; + private java.lang.String sourcePath_ = ""; + public boolean hasSourcePath() { return hasSourcePath; } + public java.lang.String getSourcePath() { return sourcePath_; } // optional bytes content = 7; public static final int CONTENT_FIELD_NUMBER = 7; @@ -2585,8 +2587,8 @@ public final class JavacRemoteProto { if (hasClassName()) { output.writeString(5, getClassName()); } - if (hasSourceUri()) { - output.writeString(6, getSourceUri()); + if (hasSourcePath()) { + output.writeString(6, getSourcePath()); } if (hasContent()) { output.writeBytes(7, getContent()); @@ -2619,9 +2621,9 @@ public final class JavacRemoteProto { size += com.google.protobuf.CodedOutputStream .computeStringSize(5, getClassName()); } - if (hasSourceUri()) { + if (hasSourcePath()) { size += com.google.protobuf.CodedOutputStream - .computeStringSize(6, getSourceUri()); + .computeStringSize(6, getSourcePath()); } if (hasContent()) { size += com.google.protobuf.CodedOutputStream @@ -2786,8 +2788,8 @@ public final class JavacRemoteProto { if (other.hasClassName()) { setClassName(other.getClassName()); } - if (other.hasSourceUri()) { - setSourceUri(other.getSourceUri()); + if (other.hasSourcePath()) { + setSourcePath(other.getSourcePath()); } if (other.hasContent()) { setContent(other.getContent()); @@ -2835,7 +2837,7 @@ public final class JavacRemoteProto { break; } case 50: { - setSourceUri(input.readString()); + setSourcePath(input.readString()); break; } case 58: { @@ -2952,24 +2954,24 @@ public final class JavacRemoteProto { return this; } - // optional string source_uri = 6; - public boolean hasSourceUri() { - return result.hasSourceUri(); + // optional string source_path = 6; + public boolean hasSourcePath() { + return result.hasSourcePath(); } - public java.lang.String getSourceUri() { - return result.getSourceUri(); + public java.lang.String getSourcePath() { + return result.getSourcePath(); } - public Builder setSourceUri(java.lang.String value) { + public Builder setSourcePath(java.lang.String value) { if (value == null) { throw new NullPointerException(); } - result.hasSourceUri = true; - result.sourceUri_ = value; + result.hasSourcePath = true; + result.sourcePath_ = value; return this; } - public Builder clearSourceUri() { - result.hasSourceUri = false; - result.sourceUri_ = getDefaultInstance().getSourceUri(); + public Builder clearSourcePath() { + result.hasSourcePath = false; + result.sourcePath_ = getDefaultInstance().getSourcePath(); return this; } @@ -3027,6 +3029,13 @@ public final class JavacRemoteProto { public boolean hasOutputObject() { return hasOutputObject; } public org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.OutputObject getOutputObject() { return outputObject_; } + // optional bool completion_status = 4; + public static final int COMPLETION_STATUS_FIELD_NUMBER = 4; + private boolean hasCompletionStatus; + private boolean completionStatus_ = false; + public boolean hasCompletionStatus() { return hasCompletionStatus; } + public boolean getCompletionStatus() { return completionStatus_; } + private void initFields() { responseType_ = org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.Type.BUILD_MESSAGE; compileMessage_ = org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.CompileMessage.getDefaultInstance(); @@ -3055,6 +3064,9 @@ public final class JavacRemoteProto { if (hasOutputObject()) { output.writeMessage(3, getOutputObject()); } + if (hasCompletionStatus()) { + output.writeBool(4, getCompletionStatus()); + } } private int memoizedSerializedSize = -1; @@ -3075,6 +3087,10 @@ public final class JavacRemoteProto { size += com.google.protobuf.CodedOutputStream .computeMessageSize(3, getOutputObject()); } + if (hasCompletionStatus()) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(4, getCompletionStatus()); + } memoizedSerializedSize = size; return size; } @@ -3228,6 +3244,9 @@ public final class JavacRemoteProto { if (other.hasOutputObject()) { mergeOutputObject(other.getOutputObject()); } + if (other.hasCompletionStatus()) { + setCompletionStatus(other.getCompletionStatus()); + } return this; } @@ -3272,6 +3291,10 @@ public final class JavacRemoteProto { setOutputObject(subBuilder.buildPartial()); break; } + case 32: { + setCompletionStatus(input.readBool()); + break; + } } } } @@ -3372,6 +3395,24 @@ public final class JavacRemoteProto { return this; } + // optional bool completion_status = 4; + public boolean hasCompletionStatus() { + return result.hasCompletionStatus(); + } + public boolean getCompletionStatus() { + return result.getCompletionStatus(); + } + public Builder setCompletionStatus(boolean value) { + result.hasCompletionStatus = true; + result.completionStatus_ = value; + return this; + } + public Builder clearCompletionStatus() { + result.hasCompletionStatus = false; + result.completionStatus_ = false; + return this; + } + // @@protoc_insertion_point(builder_scope:org.jetbrains.javac.Message.Response) } diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java index 42bea77a9e56..c7fbd6a58b48 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java @@ -10,8 +10,13 @@ import org.jboss.netty.handler.codec.protobuf.ProtobufDecoder; import org.jboss.netty.handler.codec.protobuf.ProtobufEncoder; import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder; import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender; +import org.jetbrains.annotations.NotNull; +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; +import java.io.File; import java.net.InetSocketAddress; +import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -97,10 +102,99 @@ public class JavacServer { } } + + public static JavacRemoteProto.Message compile(final ChannelHandlerContext ctx, final UUID sessionId, List options, Collection files, Collection classpath, Collection platformCp, Collection sourcePath, Map> outs) { + final DiagnosticOutputConsumer diagnostic = new DiagnosticOutputConsumer() { + public void outputLineAvailable(String line) { + Channels.write(ctx.getChannel(), JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createStdOutputResponse(line))); + } + + public void report(Diagnostic diagnostic) { + final Diagnostic.Kind kind = diagnostic.getKind(); + final JavaFileObject source = diagnostic.getSource(); + final String srcPath = source != null? source.toUri().getPath() : null; + final JavacRemoteProto.Message.Response response = JavacProtoUtil.createBuildMessageResponse( + kind, diagnostic.getMessage(Locale.US), srcPath, diagnostic.getLineNumber(), diagnostic.getColumnNumber(), diagnostic.getStartPosition(), diagnostic.getEndPosition() + ); + Channels.write(ctx.getChannel(), JavacProtoUtil.toMessage(sessionId, response)); + } + }; + + final OutputFileConsumer outputSink = new OutputFileConsumer() { + public void save(@NotNull OutputFileObject fileObject) { + Channels.write(ctx.getChannel(), JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createOutputObjectResponse(fileObject))); + } + }; + + final boolean rc = JavacMain.compile(options, files, classpath, platformCp, sourcePath, outs, diagnostic, outputSink, null/*todo*/); + + return JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createBuildCompletedResponse(rc)); + } + + + public static void cancelBuild() { + // todo + } + + private static List toFiles(List paths) { + final List files = new ArrayList(paths.size()); + for (String path : paths) { + files.add(new File(path)); + } + return files; + } + private static class CompilationRequestsHandler extends SimpleChannelHandler { public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { - // todo + final JavacRemoteProto.Message msg = (JavacRemoteProto.Message)e.getMessage(); + final UUID sessionId = JavacProtoUtil.fromProtoUUID(msg.getSessionId()); + final JavacRemoteProto.Message.Type messageType = msg.getMessageType(); + + JavacRemoteProto.Message reply = null; + + try { + if (messageType == JavacRemoteProto.Message.Type.REQUEST) { + final JavacRemoteProto.Message.Request request = msg.getRequest(); + final JavacRemoteProto.Message.Request.Type requestType = request.getRequestType(); + if (requestType == JavacRemoteProto.Message.Request.Type.COMPILE) { + final List options = request.getOptionList(); + final List files = toFiles(request.getFileList()); + final List cp = toFiles(request.getClasspathList()); + final List platformCp = toFiles(request.getPlatformClasspathList()); + final List srcPath = toFiles(request.getSourcepathList()); + + final Map> outs = new HashMap>(); + for (JavacRemoteProto.Message.Request.OutputGroup outputGroup : request.getOutputList()) { + final Set srcRoots = new HashSet(); + for (String root : outputGroup.getSourceRootsList()) { + srcRoots.add(new File(root)); + } + outs.put(new File(outputGroup.getOutputRoot()), srcRoots); + } + + reply = compile(ctx, sessionId, options, files, cp, platformCp, srcPath, outs); + } + else if (requestType == JavacRemoteProto.Message.Request.Type.CANCEL){ + cancelBuild(); + } + else if (requestType == JavacRemoteProto.Message.Request.Type.SHUTDOWN){ + cancelBuild(); + System.exit(0); + } + else { + reply = JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createFailure("Unsupported request type: " + requestType.name())); + } + } + else { + reply = JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createFailure("Unsupported message: " + messageType.name())); + } + } + finally { + if (reply != null) { + Channels.write(ctx.getChannel(), reply); + } + } } public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { @@ -114,4 +208,4 @@ public class JavacServer { super.channelOpen(ctx, e); } } -} +} \ No newline at end of file diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerClient.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerClient.java index bfd8f705f778..048482b3793f 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerClient.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerClient.java @@ -50,16 +50,8 @@ public class JavacServerClient extends SimpleProtobufClient modules, Collection paths, final BuildParameters params, final MessageHandler msgHandler, BuildCanceledStatus cs) throws Throwable{ + public void startBuild(String projectPath, Set modules, Collection paths, final BuildParameters params, final MessageHandler msgHandler, CanceledStatus cs) throws Throwable{ final String projectName = getProjectName(projectPath); BuildType buildType = params.buildType;