JPS is now module-path aware (IDEA-158385)

This commit is contained in:
Eugene Zhuravlev
2016-08-10 17:35:12 +02:00
parent eb018359e6
commit d683904c6b
12 changed files with 257 additions and 22 deletions
@@ -57,7 +57,8 @@ import org.jetbrains.jps.javac.ExternalJavacManager;
import org.jetbrains.jps.javac.OutputFileConsumer;
import org.jetbrains.jps.javac.OutputFileObject;
import javax.tools.*;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Array;
@@ -339,6 +340,7 @@ public class CompilerManagerImpl extends CompilerManager {
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 {
@@ -376,7 +378,7 @@ public class CompilerManagerImpl extends CompilerManager {
final ExternalJavacManager javacManager = getJavacManager();
boolean compiledOk = javacManager != null && javacManager.forkJavac(
javaHome, -1, Collections.<String>emptyList(), options, platformCp, classpath, sourcePath, files, outs, diagnostic, outputCollector,
javaHome, -1, Collections.emptyList(), options, platformCp, classpath, modulePath, sourcePath, files, outs, diagnostic, outputCollector,
new JavacCompilerTool(), CanceledStatus.NULL
);
@@ -297,6 +297,7 @@ public abstract class CompilerManager {
public abstract 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;
@@ -103,7 +103,7 @@ public class CompilingEvaluatorImpl extends CompilingEvaluator {
final List<File> sourcePath = Collections.emptyList();
final Set<File> sources = Collections.singleton(sourceFile);
return compilerManager.compileJavaCode(options, platformClasspath, classpath, sourcePath, sources, srcDir);
return compilerManager.compileJavaCode(options, platformClasspath, classpath, Collections.emptyList(), sourcePath, sources, srcDir);
}
catch (CompilationException e) {
final StringBuilder res = new StringBuilder("Compilation failed:\n");
@@ -176,7 +176,7 @@ public class JavaScratchCompilationSupport implements ProjectComponent, CompileT
options.add("-proc:none"); // disable annotation processing
final Collection<ClassObject> result = CompilerManager.getInstance(project).compileJavaCode(
options, platformCp, cp, Collections.<File>emptyList(), files, outputDir
options, platformCp, cp, Collections.emptyList(), Collections.emptyList(), files, outputDir
);
for (ClassObject classObject : result) {
final byte[] bytes = classObject.getContent();
@@ -41,6 +41,7 @@ message Message {
repeated string classpath = 5;
repeated string sourcepath = 6;
repeated OutputGroup output = 7;
repeated string module_path = 8;
}
message Response {
@@ -25,10 +25,7 @@ import org.jetbrains.jps.model.java.*;
import org.jetbrains.jps.model.java.compiler.ProcessorConfigProfile;
import org.jetbrains.jps.model.library.JpsOrderRootType;
import org.jetbrains.jps.model.library.sdk.JpsSdk;
import org.jetbrains.jps.model.module.JpsDependencyElement;
import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.model.module.JpsModuleSourceRoot;
import org.jetbrains.jps.model.module.JpsSdkDependency;
import org.jetbrains.jps.model.module.*;
import org.jetbrains.jps.util.JpsPathUtil;
import java.io.File;
@@ -60,6 +57,12 @@ public class ProjectPaths {
return getClasspathFiles(chunk, JpsJavaClasspathKind.compile(chunk.containsTests()), excludeMainModuleOutput, ClasspathPart.AFTER_JDK, true);
}
// todo: implementation can be changed
@NotNull
public static Collection<File> getCompilationModulePath(ModuleChunk chunk) {
return getClasspathFiles(chunk, JpsJavaClasspathKind.compile(chunk.containsTests()), true, ClasspathPart.MODULE_PATH, true);
}
@NotNull
private static Collection<File> getClasspathFiles(ModuleChunk chunk,
JpsJavaClasspathKind kind,
@@ -77,6 +80,9 @@ public class ProjectPaths {
else if (classpathPart == ClasspathPart.AFTER_JDK) {
enumerator = enumerator.satisfying(new AfterJavaSdkItemFilter(module));
}
else if (classpathPart == ClasspathPart.MODULE_PATH) {
enumerator = enumerator.satisfying(new ModuleSourceElementsFilter());
}
JpsJavaDependenciesRootsEnumerator rootsEnumerator = enumerator.classes();
if (excludeMainModuleOutput) {
rootsEnumerator = rootsEnumerator.withoutSelfModuleOutput();
@@ -187,7 +193,7 @@ public class ProjectPaths {
return StringUtil.isEmpty(sourceDirName)? outputDir : new File(outputDir, sourceDirName);
}
private enum ClasspathPart {WHOLE, BEFORE_JDK, AFTER_JDK}
private enum ClasspathPart {WHOLE, BEFORE_JDK, AFTER_JDK, MODULE_PATH}
private static class BeforeJavaSdkItemFilter implements Condition<JpsDependencyElement> {
private JpsModule myModule;
@@ -227,4 +233,15 @@ public class ProjectPaths {
}
}
private static class ModuleSourceElementsFilter implements Condition<JpsDependencyElement> {
private ModuleSourceElementsFilter() {
}
@Override
public boolean value(JpsDependencyElement dependency) {
return dependency instanceof JpsModuleDependency || dependency instanceof JpsModuleSourceDependency;
}
}
}
@@ -61,7 +61,8 @@ import org.jetbrains.jps.model.serialization.PathMacroUtil;
import org.jetbrains.jps.service.JpsServiceManager;
import org.jetbrains.jps.service.SharedThreadPool;
import javax.tools.*;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import java.io.*;
import java.net.ServerSocket;
import java.util.*;
@@ -113,7 +114,10 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
ourDefaultRtJar = rtJar;
}
// todo: remove this prop. when there appears a way to undestand directly from the project model, whether we should use model_path
private static final boolean JAVA9_MODULE_PATH_ENABLED = Boolean.valueOf(System.getProperty("compiler.java9.use.module_path", "false"));
private static boolean isRtJarPath(String path) {
if (StringUtil.endsWithIgnoreCase(path, RT_JAR_PATH_SUFFIX)) {
return true;
@@ -417,11 +421,13 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
}
final Collection<File> modulePath = JAVA9_MODULE_PATH_ENABLED && targetLanguageLevel >= 9? ProjectPaths.getCompilationModulePath(chunk) : Collections.<File>emptyList();
final ClassProcessingConsumer classesConsumer = new ClassProcessingConsumer(context, outputSink);
final boolean rc;
if (!shouldForkJavac) {
rc = JavacMain.compile(
options, files, classpath, _platformCp, sourcePath, outs, diagnosticSink, classesConsumer, context.getCancelStatus(), compilingTool
options, files, classpath, _platformCp, modulePath, sourcePath, outs, diagnosticSink, classesConsumer, context.getCancelStatus(), compilingTool
);
}
else {
@@ -431,7 +437,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
rc = server.forkJavac(
forkSdk.getFirst(),
getExternalJavacHeapSize(context),
vmOptions, options, _platformCp, classpath, sourcePath,
vmOptions, options, _platformCp, classpath, modulePath, sourcePath,
files, outs, diagnosticSink, classesConsumer, compilingTool, context.getCancelStatus()
);
}
@@ -46,7 +46,7 @@ import org.jetbrains.jps.cmdline.ClasspathBootstrap;
import org.jetbrains.jps.incremental.GlobalContextKey;
import org.jetbrains.jps.service.SharedThreadPool;
import javax.tools.*;
import javax.tools.Diagnostic;
import java.io.File;
import java.net.InetAddress;
import java.net.UnknownHostException;
@@ -112,6 +112,7 @@ public class ExternalJavacManager {
public boolean forkJavac(final String javaHome, final int heapSize, List<String> vmOptions, List<String> options,
Collection<File> platformCp,
Collection<File> classpath,
Collection<File> modulePath,
Collection<File> sourcePath,
Collection<File> files,
Map<File, Set<File>> outs,
@@ -119,7 +120,7 @@ public class ExternalJavacManager {
final JavaCompilingTool compilingTool,
final CanceledStatus cancelStatus) {
final ExternalJavacMessageHandler rh = new ExternalJavacMessageHandler(diagnosticSink, outputSink, getEncodingName(options));
final JavacRemoteProto.Message.Request request = JavacProtoUtil.createCompilationRequest(options, files, classpath, platformCp, sourcePath, outs);
final JavacRemoteProto.Message.Request request = JavacProtoUtil.createCompilationRequest(options, files, classpath, platformCp, modulePath, sourcePath, outs);
final UUID uuid = UUID.randomUUID();
final JavacProcessDescriptor processDescriptor = new JavacProcessDescriptor(uuid, rh, request);
synchronized (myMessageHandlers) {
@@ -35,7 +35,8 @@ import org.jetbrains.jps.builders.java.JavaBuilderUtil;
import org.jetbrains.jps.builders.java.JavaCompilingTool;
import org.jetbrains.jps.service.SharedThreadPool;
import javax.tools.*;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import java.io.File;
import java.util.*;
import java.util.concurrent.TimeUnit;
@@ -146,6 +147,7 @@ public class ExternalJavacProcess {
Collection<File> files,
Collection<File> classpath,
Collection<File> platformCp,
Collection<File> modulePath,
Collection<File> sourcePath,
Map<File, Set<File>> outs,
final CanceledStatus canceledStatus) {
@@ -184,8 +186,9 @@ public class ExternalJavacProcess {
try {
JavaCompilingTool tool = getCompilingTool();
final boolean rc = JavacMain.compile(options, files, classpath, platformCp, sourcePath, outs, diagnostic, outputSink, canceledStatus,
tool);
final boolean rc = JavacMain.compile(
options, files, classpath, platformCp, modulePath, sourcePath, outs, diagnostic, outputSink, canceledStatus, tool
);
return JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createBuildCompletedResponse(rc));
}
catch (Throwable e) {
@@ -230,6 +233,7 @@ public class ExternalJavacProcess {
final List<File> cp = toFiles(request.getClasspathList());
final List<File> platformCp = toFiles(request.getPlatformClasspathList());
final List<File> srcPath = toFiles(request.getSourcepathList());
final List<File> modulePath = toFiles(request.getModulePathList());
final Map<File, Set<File>> outs = new HashMap<File, Set<File>>();
for (JavacRemoteProto.Message.Request.OutputGroup outputGroup : request.getOutputList()) {
@@ -247,7 +251,7 @@ public class ExternalJavacProcess {
public void run() {
try {
context.channel().writeAndFlush(
compile(context, sessionId, options, files, cp, platformCp, srcPath, outs, cancelHandler)
compile(context, sessionId, options, files, cp, platformCp, modulePath, srcPath, outs, cancelHandler)
).awaitUninterruptibly();
}
finally {
@@ -53,6 +53,7 @@ public class JavacMain {
final Collection<File> sources,
Collection<File> classpath,
Collection<File> platformClasspath,
Collection<File> modulePath,
Collection<File> sourcePath,
Map<File, Set<File>> outputDirToRoots,
final DiagnosticOutputConsumer diagnosticConsumer,
@@ -128,7 +129,20 @@ public class JavacMain {
return false;
}
}
if (!modulePath.isEmpty()) {
final JavaFileManager.Location modulePathLocation = StandardLocation.locationFor("MODULE_PATH");
if (modulePathLocation != null) { // if this option is supported
try {
fileManager.setLocation(modulePathLocation, modulePath);
}
catch (IOException e) {
fileManager.getContext().reportMessage(Diagnostic.Kind.ERROR, e.getMessage());
return false;
}
}
}
try {
// ensure the source path is set;
// otherwise, if not set, javac attempts to search both classes and sources in classpath;
@@ -20,7 +20,8 @@ import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.incremental.BinaryContent;
import javax.tools.*;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.PrintStream;
@@ -41,7 +42,7 @@ public class JavacProtoUtil {
return JavacRemoteProto.Message.Request.newBuilder().setRequestType(JavacRemoteProto.Message.Request.Type.SHUTDOWN).build();
}
public static JavacRemoteProto.Message.Request createCompilationRequest(List<String> options, Collection<File> files, Collection<File> classpath, Collection<File> platformCp, Collection<File> sourcePath, Map<File, Set<File>> outs) {
public static JavacRemoteProto.Message.Request createCompilationRequest(List<String> options, Collection<File> files, Collection<File> classpath, Collection<File> platformCp, Collection<File> modulePath, Collection<File> sourcePath, Map<File, Set<File>> outs) {
final JavacRemoteProto.Message.Request.Builder builder = JavacRemoteProto.Message.Request.newBuilder();
builder.setRequestType(JavacRemoteProto.Message.Request.Type.COMPILE);
builder.addAllOption(options);
@@ -54,6 +55,9 @@ public class JavacProtoUtil {
for (File file : platformCp) {
builder.addPlatformClasspath(FileUtil.toSystemIndependentName(file.getPath()));
}
for (File file : modulePath) {
builder.addModulePath(FileUtil.toSystemIndependentName(file.getPath()));
}
for (File file : sourcePath) {
builder.addSourcepath(FileUtil.toSystemIndependentName(file.getPath()));
}
@@ -1458,6 +1458,26 @@ public final class JavacRemoteProto {
* <code>repeated .org.jetbrains.javac.Message.Request.OutputGroup output = 7;</code>
*/
int getOutputCount();
// repeated string module_path = 8;
/**
* <code>repeated string module_path = 8;</code>
*/
java.util.List<java.lang.String>
getModulePathList();
/**
* <code>repeated string module_path = 8;</code>
*/
int getModulePathCount();
/**
* <code>repeated string module_path = 8;</code>
*/
java.lang.String getModulePath(int index);
/**
* <code>repeated string module_path = 8;</code>
*/
com.google.protobuf.ByteString
getModulePathBytes(int index);
}
/**
* Protobuf type {@code org.jetbrains.javac.Message.Request}
@@ -1559,6 +1579,14 @@ public final class JavacRemoteProto {
output_.add(input.readMessage(org.jetbrains.jps.javac.JavacRemoteProto.Message.Request.OutputGroup.PARSER, extensionRegistry));
break;
}
case 66: {
if (!((mutable_bitField0_ & 0x00000080) == 0x00000080)) {
modulePath_ = new com.google.protobuf.LazyStringArrayList();
mutable_bitField0_ |= 0x00000080;
}
modulePath_.add(input.readBytes());
break;
}
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -1585,6 +1613,9 @@ public final class JavacRemoteProto {
if (((mutable_bitField0_ & 0x00000040) == 0x00000040)) {
output_ = java.util.Collections.unmodifiableList(output_);
}
if (((mutable_bitField0_ & 0x00000080) == 0x00000080)) {
modulePath_ = new com.google.protobuf.UnmodifiableLazyStringList(modulePath_);
}
makeExtensionsImmutable();
}
}
@@ -2472,6 +2503,36 @@ public final class JavacRemoteProto {
return output_.get(index);
}
// repeated string module_path = 8;
public static final int MODULE_PATH_FIELD_NUMBER = 8;
private com.google.protobuf.LazyStringList modulePath_;
/**
* <code>repeated string module_path = 8;</code>
*/
public java.util.List<java.lang.String>
getModulePathList() {
return modulePath_;
}
/**
* <code>repeated string module_path = 8;</code>
*/
public int getModulePathCount() {
return modulePath_.size();
}
/**
* <code>repeated string module_path = 8;</code>
*/
public java.lang.String getModulePath(int index) {
return modulePath_.get(index);
}
/**
* <code>repeated string module_path = 8;</code>
*/
public com.google.protobuf.ByteString
getModulePathBytes(int index) {
return modulePath_.getByteString(index);
}
private void initFields() {
requestType_ = org.jetbrains.jps.javac.JavacRemoteProto.Message.Request.Type.COMPILE;
option_ = com.google.protobuf.LazyStringArrayList.EMPTY;
@@ -2480,6 +2541,7 @@ public final class JavacRemoteProto {
classpath_ = com.google.protobuf.LazyStringArrayList.EMPTY;
sourcepath_ = com.google.protobuf.LazyStringArrayList.EMPTY;
output_ = java.util.Collections.emptyList();
modulePath_ = com.google.protobuf.LazyStringArrayList.EMPTY;
}
private byte memoizedIsInitialized = -1;
public final boolean isInitialized() {
@@ -2524,6 +2586,9 @@ public final class JavacRemoteProto {
for (int i = 0; i < output_.size(); i++) {
output.writeMessage(7, output_.get(i));
}
for (int i = 0; i < modulePath_.size(); i++) {
output.writeBytes(8, modulePath_.getByteString(i));
}
}
private int memoizedSerializedSize = -1;
@@ -2585,6 +2650,15 @@ public final class JavacRemoteProto {
size += com.google.protobuf.CodedOutputStream
.computeMessageSize(7, output_.get(i));
}
{
int dataSize = 0;
for (int i = 0; i < modulePath_.size(); i++) {
dataSize += com.google.protobuf.CodedOutputStream
.computeBytesSizeNoTag(modulePath_.getByteString(i));
}
size += dataSize;
size += 1 * getModulePathList().size();
}
memoizedSerializedSize = size;
return size;
}
@@ -2690,6 +2764,8 @@ public final class JavacRemoteProto {
bitField0_ = (bitField0_ & ~0x00000020);
output_ = java.util.Collections.emptyList();
bitField0_ = (bitField0_ & ~0x00000040);
modulePath_ = com.google.protobuf.LazyStringArrayList.EMPTY;
bitField0_ = (bitField0_ & ~0x00000080);
return this;
}
@@ -2752,6 +2828,12 @@ public final class JavacRemoteProto {
bitField0_ = (bitField0_ & ~0x00000040);
}
result.output_ = output_;
if (((bitField0_ & 0x00000080) == 0x00000080)) {
modulePath_ = new com.google.protobuf.UnmodifiableLazyStringList(
modulePath_);
bitField0_ = (bitField0_ & ~0x00000080);
}
result.modulePath_ = modulePath_;
result.bitField0_ = to_bitField0_;
return result;
}
@@ -2820,6 +2902,16 @@ public final class JavacRemoteProto {
output_.addAll(other.output_);
}
}
if (!other.modulePath_.isEmpty()) {
if (modulePath_.isEmpty()) {
modulePath_ = other.modulePath_;
bitField0_ = (bitField0_ & ~0x00000080);
} else {
ensureModulePathIsMutable();
modulePath_.addAll(other.modulePath_);
}
}
return this;
}
@@ -3483,6 +3575,99 @@ public final class JavacRemoteProto {
return this;
}
// repeated string module_path = 8;
private com.google.protobuf.LazyStringList modulePath_ = com.google.protobuf.LazyStringArrayList.EMPTY;
private void ensureModulePathIsMutable() {
if (!((bitField0_ & 0x00000080) == 0x00000080)) {
modulePath_ = new com.google.protobuf.LazyStringArrayList(modulePath_);
bitField0_ |= 0x00000080;
}
}
/**
* <code>repeated string module_path = 8;</code>
*/
public java.util.List<java.lang.String>
getModulePathList() {
return java.util.Collections.unmodifiableList(modulePath_);
}
/**
* <code>repeated string module_path = 8;</code>
*/
public int getModulePathCount() {
return modulePath_.size();
}
/**
* <code>repeated string module_path = 8;</code>
*/
public java.lang.String getModulePath(int index) {
return modulePath_.get(index);
}
/**
* <code>repeated string module_path = 8;</code>
*/
public com.google.protobuf.ByteString
getModulePathBytes(int index) {
return modulePath_.getByteString(index);
}
/**
* <code>repeated string module_path = 8;</code>
*/
public Builder setModulePath(
int index, java.lang.String value) {
if (value == null) {
throw new NullPointerException();
}
ensureModulePathIsMutable();
modulePath_.set(index, value);
return this;
}
/**
* <code>repeated string module_path = 8;</code>
*/
public Builder addModulePath(
java.lang.String value) {
if (value == null) {
throw new NullPointerException();
}
ensureModulePathIsMutable();
modulePath_.add(value);
return this;
}
/**
* <code>repeated string module_path = 8;</code>
*/
public Builder addAllModulePath(
java.lang.Iterable<java.lang.String> values) {
ensureModulePathIsMutable();
super.addAll(values, modulePath_);
return this;
}
/**
* <code>repeated string module_path = 8;</code>
*/
public Builder clearModulePath() {
modulePath_ = com.google.protobuf.LazyStringArrayList.EMPTY;
bitField0_ = (bitField0_ & ~0x00000080);
return this;
}
/**
* <code>repeated string module_path = 8;</code>
*/
public Builder addModulePathBytes(
com.google.protobuf.ByteString value) {
if (value == null) {
throw new NullPointerException();
}
ensureModulePathIsMutable();
modulePath_.add(value);
return this;
}
// @@protoc_insertion_point(builder_scope:org.jetbrains.javac.Message.Request)
}