From 5e0ef68d6445fee8c258f2bfead1062c5b176c18 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Fri, 11 Oct 2013 15:48:36 +0400 Subject: [PATCH] JPS: switch to using *CompilerArgument classes(from IDEA Project Settings) in build. --- .../compiler/runner/CompilerRunnerUtil.java | 44 +++++++-- .../compiler/runner/KotlinCompilerRunner.java | 95 ++++++++++++------- .../jet/plugin/compiler/JetCompiler.java | 12 ++- .../KotlinCompilerConfigurableTab.java | 2 +- .../JetCompilerMessagingTest.java | 2 +- .../jet/jps/JpsKotlinCompilerSettings.java | 39 ++------ .../jet/jps/build/KotlinBuilder.java | 30 +++--- 7 files changed, 137 insertions(+), 87 deletions(-) diff --git a/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/CompilerRunnerUtil.java b/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/CompilerRunnerUtil.java index 6e0cbdc1291..02fc3ae786d 100644 --- a/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/CompilerRunnerUtil.java +++ b/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/CompilerRunnerUtil.java @@ -17,8 +17,10 @@ package org.jetbrains.jet.compiler.runner; import com.intellij.util.Function; +import com.intellij.util.xmlb.XmlSerializer; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.cli.common.messages.*; +import org.jetbrains.jet.cli.common.arguments.CompilerArguments; +import org.jetbrains.jet.cli.common.messages.MessageCollector; import org.jetbrains.jet.preloading.ClassPreloadingUtils; import org.jetbrains.jet.utils.KotlinPaths; @@ -29,13 +31,17 @@ import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import static org.jetbrains.jet.cli.common.messages.CompilerMessageLocation.NO_LOCATION; -import static org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity.*; +import static org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity.ERROR; public class CompilerRunnerUtil { + private static final String STRING_ARRAY_CLASS_NAME = String[].class.getName(); + private static final String COMPILER_ARGUMENTS_CLASS_NAME = CompilerArguments.class.getName(); private static SoftReference ourClassLoaderRef = new SoftReference(null); public static List kompilerClasspath(KotlinPaths paths, MessageCollector messageCollector) { @@ -106,15 +112,34 @@ public class CompilerRunnerUtil { } public static Object invokeExecMethod( - String className, String[] arguments, CompilerEnvironment environment, + String compilerClassName, CompilerArguments arguments, CompilerEnvironment environment, + MessageCollector messageCollector, PrintStream out, boolean usePreloader + ) throws Exception { + return invokeExecMethod(compilerClassName, COMPILER_ARGUMENTS_CLASS_NAME, arguments, environment, messageCollector, out, usePreloader); + } + + public static Object invokeExecMethod( + String compilerClassName, String[] arguments, CompilerEnvironment environment, + MessageCollector messageCollector, PrintStream out, boolean usePreloader + ) throws Exception { + return invokeExecMethod(compilerClassName, STRING_ARRAY_CLASS_NAME, arguments, environment, messageCollector, out, usePreloader); + } + + public static Object invokeExecMethod( + String compilerClassName, String argumentsClassName, T arguments, CompilerEnvironment environment, MessageCollector messageCollector, PrintStream out, boolean usePreloader ) throws Exception { ClassLoader loader = usePreloader ? getOrCreatePreloader(environment.getKotlinPaths(), messageCollector) : getOrCreateClassLoader(environment.getKotlinPaths(), messageCollector); - Class kompiler = Class.forName(className, true, loader); - Method exec = kompiler.getMethod("exec", PrintStream.class, String[].class); - return exec.invoke(kompiler.newInstance(), out, arguments); + + Class argumentsClass = Class.forName(argumentsClassName, true, loader); + Object argumentsInLoader = copyObject(arguments, loader); + + Class kompiler = Class.forName(compilerClassName, true, loader); + Method exec = kompiler.getMethod("exec", PrintStream.class, argumentsClass); + + return exec.invoke(kompiler.newInstance(), out, argumentsInLoader); } public static void outputCompilerMessagesAndHandleExitCode(@NotNull MessageCollector messageCollector, @@ -129,4 +154,9 @@ public class CompilerRunnerUtil { CompilerOutputParser.parseCompilerMessagesFromReader(messageCollector, reader, outputItemsCollector); handleProcessTermination(exitCode, messageCollector); } + + private static Object copyObject(Object object, ClassLoader loader) throws ClassNotFoundException { + Class objectClassInLoader = Class.forName(object.getClass().getName(), true, loader); + return XmlSerializer.deserialize(XmlSerializer.serialize(object), objectClassInLoader); + } } diff --git a/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/KotlinCompilerRunner.java b/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/KotlinCompilerRunner.java index 15978eccec1..2dad7bee88d 100644 --- a/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/KotlinCompilerRunner.java +++ b/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/KotlinCompilerRunner.java @@ -16,9 +16,14 @@ package org.jetbrains.jet.compiler.runner; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.xmlb.Accessor; +import com.intellij.util.xmlb.XmlSerializerUtil; +import org.jetbrains.jet.cli.common.arguments.CommonCompilerArguments; +import org.jetbrains.jet.cli.common.arguments.K2JSCompilerArguments; +import org.jetbrains.jet.cli.common.arguments.K2JVMCompilerArguments; import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation; import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity; import org.jetbrains.jet.cli.common.messages.MessageCollector; @@ -26,23 +31,30 @@ import org.jetbrains.jet.cli.common.messages.MessageCollectorUtil; import java.io.File; import java.io.PrintStream; -import java.util.*; +import java.util.List; +import java.util.Set; public class KotlinCompilerRunner { private static final String K2JVM_COMPILER = "org.jetbrains.jet.cli.jvm.K2JVMCompiler"; private static final String K2JS_COMPILER = "org.jetbrains.jet.cli.js.K2JSCompiler"; public static void runK2JvmCompiler( + CommonCompilerArguments commonArguments, + K2JVMCompilerArguments k2jvmArguments, MessageCollector messageCollector, CompilerEnvironment environment, File moduleFile, OutputItemsCollector collector ) { - String[] arguments = createArgumentsForJvmCompiler(moduleFile); + K2JVMCompilerArguments arguments = mergeBeans(commonArguments, k2jvmArguments); + setupK2JvmSettings(moduleFile, arguments); + runCompiler(K2JVM_COMPILER, arguments, messageCollector, collector, environment); } public static void runK2JsCompiler( + CommonCompilerArguments commonArguments, + K2JSCompilerArguments k2jsArguments, MessageCollector messageCollector, CompilerEnvironment environment, OutputItemsCollector collector, @@ -50,13 +62,15 @@ public class KotlinCompilerRunner { Set libraryFiles, File outputFile ) { - String[] arguments = createArgumentsForJsCompiler(outputFile, sourceFiles, libraryFiles); + K2JSCompilerArguments arguments = mergeBeans(commonArguments, k2jsArguments); + setupK2JsSettings(outputFile, sourceFiles, libraryFiles, arguments); + runCompiler(K2JS_COMPILER, arguments, messageCollector, collector, environment); } private static void runCompiler( final String compilerClassName, - final String[] arguments, + final CommonCompilerArguments arguments, final MessageCollector messageCollector, OutputItemsCollector collector, final CompilerEnvironment environment @@ -71,7 +85,7 @@ public class KotlinCompilerRunner { private static int execCompiler( String compilerClassName, - String[] arguments, + CommonCompilerArguments arguments, CompilerEnvironment environment, PrintStream out, MessageCollector messageCollector @@ -80,9 +94,7 @@ public class KotlinCompilerRunner { messageCollector.report(CompilerMessageSeverity.INFO, "Using kotlinHome=" + environment.getKotlinPaths().getHomePath(), CompilerMessageLocation.NO_LOCATION); - messageCollector.report(CompilerMessageSeverity.INFO, - "Invoking in-process compiler " + compilerClassName + " with arguments " + Arrays.asList(arguments), - CompilerMessageLocation.NO_LOCATION); + Object rc = CompilerRunnerUtil.invokeExecMethod(compilerClassName, arguments, environment, messageCollector, out, /*usePreloader=*/true); // exec() returns a K2JVMCompiler.ExitCode object, that class is not accessible here, @@ -95,40 +107,55 @@ public class KotlinCompilerRunner { } } - private static String[] createArgumentsForJvmCompiler(File moduleFile) { - return new String[]{ - "-module", moduleFile.getAbsolutePath(), - "-tags", "-verbose", "-version", - "-notNullAssertions", "-notNullParamAssertions", - "-noStdlib", "-noJdkAnnotations", "-noJdk"}; + private static T mergeBeans(F from, T to) { + T copy = XmlSerializerUtil.createCopy(to); + + for (Accessor accessor : XmlSerializerUtil.getAccessors(from.getClass())) { + accessor.write(copy, accessor.read(from)); + } + + return copy; } - private static String[] createArgumentsForJsCompiler( + private static void setupCommonSettings(CommonCompilerArguments settings) { + settings.tags = true; + settings.verbose = true; + settings.version = true; + settings.printArgs = true; + } + + private static void setupK2JvmSettings( + File moduleFile, + K2JVMCompilerArguments settings + ) { + setupCommonSettings(settings); + + settings.module = moduleFile.getAbsolutePath(); + settings.notNullAssertions = true; + settings.notNullParamAssertions = true; + settings.noStdlib = true; + settings.noJdkAnnotations = true; + settings.noJdk = true; + } + + private static void setupK2JsSettings( File outputFile, List sourceFiles, - Set libraryFiles + Set libraryFiles, + K2JSCompilerArguments settings ) { - List args = new ArrayList(); + setupCommonSettings(settings); - Collections.addAll(args, "-tags", "-verbose", "-version", "-sourcemap"); - - String separator = ","; - String sourceFilesAsString = StringUtil.join(sourceFiles, new Function() { + List sourceFilePaths = ContainerUtil.map(sourceFiles, new Function() { @Override public String fun(File file) { return file.getPath(); } - }, separator); - - args.add("-sourceFiles"); - args.add(sourceFilesAsString); - - args.add("-output"); - args.add(outputFile.getPath()); - - args.add("-libraryFiles"); - args.add(StringUtil.join(libraryFiles, separator)); - - return ArrayUtil.toStringArray(args); + }); + settings.sourceFiles = ArrayUtil.toStringArray(sourceFilePaths); + settings.outputFile = outputFile.getPath(); + settings.libraryFiles = ArrayUtil.toStringArray(libraryFiles); + //TODO drop later + settings.sourcemap = true; } } diff --git a/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java b/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java index 8b6393b61d9..77bff7330cd 100644 --- a/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java +++ b/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java @@ -31,6 +31,7 @@ import com.intellij.util.Chunk; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.cli.common.arguments.K2JVMCompilerArguments; import org.jetbrains.jet.cli.common.messages.MessageCollector; import org.jetbrains.jet.compiler.runner.*; import org.jetbrains.jet.plugin.JetFileType; @@ -133,7 +134,16 @@ public class JetCompiler implements TranslatingCompiler { File scriptFile, OutputItemsCollector outputItemsCollector ) { - KotlinCompilerRunner.runK2JvmCompiler(messageCollector, environment, scriptFile, outputItemsCollector); + K2JVMCompilerArguments commonArguments = new K2JVMCompilerArguments(); + commonArguments.verbose = true; + commonArguments.tags = true; + commonArguments.printArgs = true; + commonArguments.version = true; + + K2JVMCompilerArguments jvmArguments = new K2JVMCompilerArguments(); + jvmArguments.module = scriptFile.getAbsolutePath(); + + KotlinCompilerRunner.runK2JvmCompiler(commonArguments, jvmArguments, messageCollector, environment, scriptFile, outputItemsCollector); } public static File tryToWriteScriptFile( diff --git a/idea/src/org/jetbrains/jet/plugin/compiler/configuration/KotlinCompilerConfigurableTab.java b/idea/src/org/jetbrains/jet/plugin/compiler/configuration/KotlinCompilerConfigurableTab.java index 51b340e7ce2..7a4edc4f11b 100644 --- a/idea/src/org/jetbrains/jet/plugin/compiler/configuration/KotlinCompilerConfigurableTab.java +++ b/idea/src/org/jetbrains/jet/plugin/compiler/configuration/KotlinCompilerConfigurableTab.java @@ -91,7 +91,7 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co } private boolean isGenerateNoWarnings() { - return SUPPRESS_WARNINGS.equals(commonCompilerSettings.suppress); + return commonCompilerSettings.suppressAllWarnings(); } private void setGenerateNoWarnings(boolean selected) { diff --git a/idea/tests/org/jetbrains/jet/plugin/compilerMessages/JetCompilerMessagingTest.java b/idea/tests/org/jetbrains/jet/plugin/compilerMessages/JetCompilerMessagingTest.java index 32d998f29fd..b315fb6893d 100644 --- a/idea/tests/org/jetbrains/jet/plugin/compilerMessages/JetCompilerMessagingTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/compilerMessages/JetCompilerMessagingTest.java @@ -81,7 +81,7 @@ public final class JetCompilerMessagingTest extends IDECompilerMessagingTest { @Override protected void checkHeader(@NotNull MessageChecker checker) { checker.expect(Message.info().textStartsWith("Using kotlinHome=")); - checker.expect(Message.info().textStartsWith("Invoking in-process compiler")); + checker.expect(Message.info().textStartsWith("Invoking compiler")); checker.expect(Message.info().textStartsWith("Kotlin Compiler version")); checker.expect(Message.stats().textStartsWith("Using Kotlin home directory")); checker.expect(Message.stats().text("Configuring the compilation environment")); diff --git a/jps-plugin/src/org/jetbrains/jet/jps/JpsKotlinCompilerSettings.java b/jps-plugin/src/org/jetbrains/jet/jps/JpsKotlinCompilerSettings.java index b46de016e22..2ca6b28331f 100644 --- a/jps-plugin/src/org/jetbrains/jet/jps/JpsKotlinCompilerSettings.java +++ b/jps-plugin/src/org/jetbrains/jet/jps/JpsKotlinCompilerSettings.java @@ -16,8 +16,6 @@ package org.jetbrains.jet.jps; -import com.intellij.util.xmlb.Accessor; -import com.intellij.util.xmlb.XmlSerializerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.cli.common.arguments.CommonCompilerArguments; import org.jetbrains.jet.cli.common.arguments.K2JSCompilerArguments; @@ -73,49 +71,28 @@ public class JpsKotlinCompilerSettings extends JpsElementBase T merge(@NotNull CommonCompilerArguments from, @NotNull T to) { - Class fromClass = CommonCompilerArguments.class; - - assert fromClass.isAssignableFrom(to.getClass()) : to.getClass() + " is not assignable to " + fromClass; - - T mergedCopy = XmlSerializerUtil.createCopy(to); - - for (Accessor accessor : XmlSerializerUtil.getAccessors(fromClass)) { - accessor.write(mergedCopy, accessor.read(from)); - } - - return mergedCopy; + getOrCreateSettings(project).k2JsCompilerSettings = k2JsCompilerSettings; } } diff --git a/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java b/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java index 24f12b14800..5c47f983ee1 100644 --- a/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java +++ b/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java @@ -21,10 +21,14 @@ import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.cli.common.KotlinVersion; +import org.jetbrains.jet.cli.common.arguments.CommonCompilerArguments; +import org.jetbrains.jet.cli.common.arguments.K2JSCompilerArguments; +import org.jetbrains.jet.cli.common.arguments.K2JVMCompilerArguments; import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation; import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity; import org.jetbrains.jet.cli.common.messages.MessageCollector; import org.jetbrains.jet.compiler.runner.*; +import org.jetbrains.jet.jps.JpsKotlinCompilerSettings; import org.jetbrains.jet.utils.PathUtil; import org.jetbrains.jps.ModuleChunk; import org.jetbrains.jps.builders.DirtyFilesHolder; @@ -33,6 +37,7 @@ import org.jetbrains.jps.incremental.*; import org.jetbrains.jps.incremental.java.JavaBuilder; import org.jetbrains.jps.incremental.messages.BuildMessage; import org.jetbrains.jps.incremental.messages.CompilerMessage; +import org.jetbrains.jps.model.JpsProject; import org.jetbrains.jps.model.module.JpsModule; import java.io.File; @@ -42,11 +47,15 @@ import java.lang.reflect.Modifier; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Set; import static org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity.EXCEPTION; import static org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity.INFO; import static org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity.WARNING; +import static org.jetbrains.jet.compiler.runner.KotlinCompilerRunner.runK2JsCompiler; +import static org.jetbrains.jet.compiler.runner.KotlinCompilerRunner.runK2JvmCompiler; + public class KotlinBuilder extends ModuleLevelBuilder { private static final String KOTLIN_BUILDER_NAME = "Kotlin Builder"; @@ -104,6 +113,9 @@ public class KotlinBuilder extends ModuleLevelBuilder { OutputItemsCollectorImpl outputItemCollector = new OutputItemsCollectorImpl(outputDir); + JpsProject project = representativeTarget.getModule().getProject(); + CommonCompilerArguments commonSettings = JpsKotlinCompilerSettings.getCommonSettings(project); + if (JpsUtils.isJsKotlinModule(representativeTarget)) { if (chunk.getModules().size() > 1) { // We do not support circular dependencies, but if they are present, we do our best should not break the build, @@ -124,14 +136,10 @@ public class KotlinBuilder extends ModuleLevelBuilder { } File outputFile = new File(outputDir, representativeTarget.getModule().getName() + ".js"); + Set libraryFiles = JpsJsModuleUtils.getLibraryFilesAndDependencies(representativeTarget); + K2JSCompilerArguments k2JsSettings = JpsKotlinCompilerSettings.getK2JsSettings(project); - KotlinCompilerRunner.runK2JsCompiler( - messageCollector, - environment, - outputItemCollector, - sourceFiles, - JpsJsModuleUtils.getLibraryFilesAndDependencies(representativeTarget), - outputFile); + runK2JsCompiler(commonSettings, k2JsSettings, messageCollector, environment, outputItemCollector, sourceFiles, libraryFiles, outputFile); } else { if (chunk.getModules().size() > 1) { @@ -148,11 +156,9 @@ public class KotlinBuilder extends ModuleLevelBuilder { return ExitCode.NOTHING_DONE; } - KotlinCompilerRunner.runK2JvmCompiler( - messageCollector, - environment, - moduleFile, - outputItemCollector); + K2JVMCompilerArguments k2JvmSettings = JpsKotlinCompilerSettings.getK2JvmSettings(project); + + runK2JvmCompiler(commonSettings, k2JvmSettings, messageCollector, environment, moduleFile, outputItemCollector); } for (SimpleOutputItem outputItem : outputItemCollector.getOutputs()) {