diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant index cba7816b15ef..1d802d4255f5 100644 --- a/build/scripts/layouts.gant +++ b/build/scripts/layouts.gant @@ -157,7 +157,10 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir module("jps-model") } - fileset(dir: "$home/jps/lib", includes: "optimizedFileManager.jar") + fileset(dir: "$home/jps/lib") { + include(name: "optimizedFileManager.jar") + include(name: "ecj-*.jar") + } fileset(dir: "$home/lib", includesfile: "${home}/lib/required_for_dist.txt") diff --git a/build/scripts/libLicenses.gant b/build/scripts/libLicenses.gant index 499532977c06..753c6ad8b8ff 100644 --- a/build/scripts/libLicenses.gant +++ b/build/scripts/libLicenses.gant @@ -239,6 +239,7 @@ libraryLicense(name: "protobuf", version: "2.3.0", license: "New BSD", url: "htt libraryLicense(name: "Netty", libraryName: "Netty", version: "3.3.1", license: "Apache 2.0", url: "http://netty.io", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0") libraryLicense(name: "Kryo", libraryName: "Kryo", version: "1.04", license: "New BSD License", url: "http://code.google.com/p/kryo/", licenseUrl: "http://www.opensource.org/licenses/bsd-license.php") libraryLicense(name: "Snappy-Java", libraryName: "Snappy-Java", version: "1.0.4.1", license: "Apache 2.0", url: "http://code.google.com/p/snappy-java/", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0") +libraryLicense(name: "ecj-4.2.jar", libraryName: "ecj-4.2.jar", version: "4.2", license: "CPL 1.0", url: "http://www.eclipse.org/jdt/core/index.php") jetbrainsLibrary("JPS") jetbrainsLibrary("Maven Embedder") jetbrainsLibrary("tcServiceMessages") diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompiler.java index e043fbe9423c..b17c463f2813 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompiler.java @@ -50,9 +50,20 @@ public class EclipseCompiler extends ExternalCompiler { private final Project myProject; private final List myTempFiles = new ArrayList(); + private static final String COMPILER_CLASS_NAME = "org.eclipse.jdt.core.compiler.batch.BatchCompiler"; @NonNls private static final String PATH_TO_COMPILER_JAR = findJarPah(); private static String findJarPah() { + try { + final Class aClass = Class.forName(COMPILER_CLASS_NAME); + final String path = PathManager.getResourceRoot(aClass, "/" + aClass.getName().replace('.', '/') + ".class"); + if (path != null) { + return path; + } + } + catch (ClassNotFoundException ignored) { + } + File dir = new File(PathManager.getLibPath()); File[] jars = dir.listFiles(new FilenameFilter() { public boolean accept(File dir, String name) { diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index b6e26e706010..8ba5b70a2d71 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -696,6 +696,7 @@ public class BuildManager implements ApplicationComponent{ if (ApplicationManager.getApplication().isUnitTestMode()) { cmdLine.addParameter("-Dtest.mode=true"); } + cmdLine.addParameter("-Djdt.compiler.useSingleThread=true"); final String shouldGenerateIndex = System.getProperty(GlobalOptions.GENERATE_CLASSPATH_INDEX_OPTION); if (shouldGenerateIndex != null) { diff --git a/jps/jps-builders/jps-builders.iml b/jps/jps-builders/jps-builders.iml index 31cc304514d6..7b79e8572ff5 100644 --- a/jps/jps-builders/jps-builders.iml +++ b/jps/jps-builders/jps-builders.iml @@ -41,6 +41,15 @@ + + + + + + + + + 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 49a7dce25c80..807a16612f15 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 @@ -419,8 +419,9 @@ public class JavaBuilder extends ModuleLevelBuilder { try { final boolean rc; if (USE_EMBEDDED_JAVAC) { + final boolean useEclipse = useEclipseCompiler(context); rc = JavacMain.compile( - options, files, classpath, platformCp, sourcePath, outs, diagnosticSink, classesConsumer, context.getCancelStatus() + options, files, classpath, platformCp, sourcePath, outs, diagnosticSink, classesConsumer, context.getCancelStatus(), useEclipse ); } else { @@ -442,6 +443,10 @@ public class JavaBuilder extends ModuleLevelBuilder { } } + private static boolean useEclipseCompiler(CompileContext context) { + return USE_EMBEDDED_JAVAC && "Eclipse".equalsIgnoreCase(context.getProject().getCompilerConfiguration().getOptions().get("DEFAULT_COMPILER")); + } + private void ensurePendingTasksCompleted() { synchronized (myCounterLock) { while (myTasksInProgress > 0) { @@ -563,8 +568,9 @@ public class JavaBuilder extends ModuleLevelBuilder { private static int getJavacServerHeapSize(CompileContext context) { int heapSize = 512; final Project project = context.getProject(); - final Map javacOpts = project.getCompilerConfiguration().getJavacOptions(); - final String hSize = javacOpts.get("MAXIMUM_HEAP_SIZE"); + final CompilerConfiguration config = project.getCompilerConfiguration(); + final Map opts = useEclipseCompiler(context)? config.getEclipseOptions() : config.getJavacOptions(); + final String hSize = opts.get("MAXIMUM_HEAP_SIZE"); if (hSize != null) { try { heapSize = Integer.parseInt(hSize); @@ -765,10 +771,10 @@ public class JavaBuilder extends ModuleLevelBuilder { //options.add("-verbose"); final Project project = context.getProject(); final CompilerConfiguration compilerConfig = project.getCompilerConfiguration(); - final Map javacOpts = compilerConfig.getJavacOptions(); - final boolean debugInfo = !"false".equals(javacOpts.get("DEBUGGING_INFO")); - final boolean nowarn = "true".equals(javacOpts.get("GENERATE_NO_WARNINGS")); - final boolean deprecation = !"false".equals(javacOpts.get("DEPRECATION")); + final Map opts = useEclipseCompiler(context)? compilerConfig.getEclipseOptions() : compilerConfig.getJavacOptions(); + final boolean debugInfo = !"false".equals(opts.get("DEBUGGING_INFO")); + final boolean nowarn = "true".equals(opts.get("GENERATE_NO_WARNINGS")); + final boolean deprecation = !"false".equals(opts.get("DEPRECATION")); if (debugInfo) { options.add("-g"); } @@ -779,7 +785,7 @@ public class JavaBuilder extends ModuleLevelBuilder { options.add("-nowarn"); } - final String customArgs = javacOpts.get("ADDITIONAL_OPTIONS_STRING"); + final String customArgs = opts.get("ADDITIONAL_OPTIONS_STRING"); if (customArgs != null) { final StringTokenizer customOptsTokenizer = new StringTokenizer(customArgs, " \t\r\n"); boolean skip = false; 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 5d412459459e..3a57440d2f49 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java @@ -22,6 +22,7 @@ public class JavacMain { private static final Set FILTERED_SINGLE_OPTIONS = new HashSet(Arrays.asList( "-verbose", "-proc:only", "-implicit:class", "-implicit:none" )); + private static final JavaCompiler SYSTEM_JAVA_COMPILER = ToolProvider.getSystemJavaCompiler(); public static boolean compile(Collection options, final Collection sources, @@ -31,14 +32,34 @@ public class JavacMain { Map> outputDirToRoots, final DiagnosticOutputConsumer outConsumer, final OutputFileConsumer outputSink, - CanceledStatus canceledStatus) { - final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + CanceledStatus canceledStatus, boolean useEclipseCompiler) { + JavaCompiler compiler = null; + if (useEclipseCompiler) { + for (JavaCompiler javaCompiler : ServiceLoader.load(JavaCompiler.class)) { + compiler = javaCompiler; + break; + } + if (compiler == null) { + compiler = SYSTEM_JAVA_COMPILER; + } + } + else { + compiler = SYSTEM_JAVA_COMPILER; + } + + final boolean nowUsingJavac = compiler == SYSTEM_JAVA_COMPILER; for (File outputDir : outputDirToRoots.keySet()) { outputDir.mkdirs(); } final JavacFileManager fileManager = new JavacFileManager(new ContextImpl(compiler, outConsumer, outputSink, canceledStatus)); + if (nowUsingJavac && useEclipseCompiler) { + final String message = "Eclipse Batch Compiler was not found in classpath, using Javac instead"; + fileManager.getContext().reportMessage(Diagnostic.Kind.WARNING, message); + System.err.println(message); + } + fileManager.handleOption("-bootclasspath", Collections.singleton("").iterator()); // this will clear cached stuff fileManager.handleOption("-extdirs", Collections.singleton("").iterator()); // this will clear cached stuff @@ -81,12 +102,17 @@ public class JavacMain { //noinspection IOResourceOpenedButNotSafelyClosed final LineOutputWriter out = new LineOutputWriter() { protected void lineAvailable(String line) { - outConsumer.outputLineAvailable(line); + if (nowUsingJavac) { + outConsumer.outputLineAvailable(line); + } + else { + // todo: filter too verbose eclipse output? + } } }; try { - final Collection _options = prepareOptions(options); + final Collection _options = prepareOptions(options, compiler); final JavaCompiler.CompilationTask task = compiler.getTask( out, fileManager, outConsumer, _options, null, fileManager.toJavaFileObjects(sources) ); @@ -117,9 +143,11 @@ public class JavacMain { return true; } - private static Collection prepareOptions(final Collection options) { + private static Collection prepareOptions(final Collection options, JavaCompiler compiler) { final List result = new ArrayList(); - result.add("-implicit:class"); + if (compiler == SYSTEM_JAVA_COMPILER) { + result.add("-implicit:class"); // the option supported by javac only + } boolean skip = false; for (String option : options) { if (FILTERED_OPTIONS.contains(option)) { 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 4cb83029243b..42ccd4c525e9 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java @@ -14,7 +14,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.api.CanceledStatus; import org.jetbrains.jps.api.SharedThreadPool; -import javax.tools.*; +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; import java.io.File; import java.net.InetSocketAddress; import java.util.*; @@ -134,7 +135,7 @@ public class JavacServer { }; try { - final boolean rc = JavacMain.compile(options, files, classpath, platformCp, sourcePath, outs, diagnostic, outputSink, canceledStatus); + final boolean rc = JavacMain.compile(options, files, classpath, platformCp, sourcePath, outs, diagnostic, outputSink, canceledStatus, false); return JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createBuildCompletedResponse(rc)); } catch (CompilationCanceledException e) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java b/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java index 59627572644e..53a4ec614716 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java +++ b/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java @@ -33,12 +33,11 @@ import org.jetbrains.asm4.ClassWriter; import org.jetbrains.jps.MacroExpander; import org.jetbrains.jps.javac.JavacServer; -import javax.tools.*; +import javax.tools.JavaCompiler; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; import java.io.File; -import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; +import java.util.*; /** * @author Eugene Zhuravlev @@ -114,6 +113,14 @@ public class ClasspathBootstrap { catch (Throwable ignored) { } + for (JavaCompiler javaCompiler : ServiceLoader.load(JavaCompiler.class)) { // Eclipse compiler + final File compilerResource = getResourcePath(javaCompiler.getClass()); + final String name = compilerResource.getName(); + if (name.startsWith("ecj-") && name.endsWith(".jar")) { + cp.add(compilerResource); + } + } + return new ArrayList(cp); } diff --git a/jps/lib/ecj-4.2.jar b/jps/lib/ecj-4.2.jar new file mode 100644 index 000000000000..f4f7dd736f9d Binary files /dev/null and b/jps/lib/ecj-4.2.jar differ diff --git a/jps/model/src/org/jetbrains/jps/CompilerConfiguration.groovy b/jps/model/src/org/jetbrains/jps/CompilerConfiguration.groovy index 1dc8b34ebd41..142e7b2ca136 100644 --- a/jps/model/src/org/jetbrains/jps/CompilerConfiguration.groovy +++ b/jps/model/src/org/jetbrains/jps/CompilerConfiguration.groovy @@ -7,7 +7,9 @@ class CompilerConfiguration { List resourcePatterns = [] List resourceIncludePatterns = "properties,xml,gif,png,jpeg,jpg,jtml,dtd,tld,ftl".split(",").collect {"**/?*.$it"} List resourceExcludePatterns = [] + Map options = [:] Map javacOptions = [:] + Map eclipseOptions = [:] boolean clearOutputDirectoryOnRebuild = true boolean addNotNullAssertions = true AnnotationProcessingProfile defaultAnnotationProcessingProfile = new AnnotationProcessingProfile() diff --git a/jps/model/src/org/jetbrains/jps/idea/IdeaProjectLoader.groovy b/jps/model/src/org/jetbrains/jps/idea/IdeaProjectLoader.groovy index 694979c49f06..f674116b05f2 100644 --- a/jps/model/src/org/jetbrains/jps/idea/IdeaProjectLoader.groovy +++ b/jps/model/src/org/jetbrains/jps/idea/IdeaProjectLoader.groovy @@ -246,8 +246,9 @@ public class IdeaProjectLoader { configuration.excludes.addExcludedDirectory(getFileByUrl(it."@url"), Boolean.parseBoolean(it."@includeSubdirectories")) } } - + configuration.options.putAll(loadOptions(componentTag)); configuration.javacOptions.putAll(loadOptions(getComponent(root, "JavacSettings"))) + configuration.eclipseOptions.putAll(loadOptions(getComponent(root, "EclipseCompilerSettings"))) def annotationProcessingTag = componentTag?.annotationProcessing if (annotationProcessingTag != null) {