diff --git a/compiler/cli/bin/kotlinc-dce-js b/compiler/cli/bin/kotlinc-dce-js new file mode 100755 index 00000000000..aa4cfdd952e --- /dev/null +++ b/compiler/cli/bin/kotlinc-dce-js @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +# Copyright 2010-2017 JetBrains s.r.o. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +export KOTLIN_COMPILER=org.jetbrains.kotlin.cli.js.dce.K2JSDce + +DIR="${BASH_SOURCE[0]%/*}" +: ${DIR:="."} + +"${DIR}"/kotlinc "$@" diff --git a/compiler/cli/bin/kotlinc-dce-js.bat b/compiler/cli/bin/kotlinc-dce-js.bat new file mode 100644 index 00000000000..ff6a9ce21c3 --- /dev/null +++ b/compiler/cli/bin/kotlinc-dce-js.bat @@ -0,0 +1,20 @@ +@echo off + +rem Copyright 2010-2015 JetBrains s.r.o. +rem +rem Licensed under the Apache License, Version 2.0 (the "License"); +rem you may not use this file except in compliance with the License. +rem You may obtain a copy of the License at +rem +rem http://www.apache.org/licenses/LICENSE-2.0 +rem +rem Unless required by applicable law or agreed to in writing, software +rem distributed under the License is distributed on an "AS IS" BASIS, +rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +rem See the License for the specific language governing permissions and +rem limitations under the License. + +setlocal +set _KOTLIN_COMPILER=org.jetbrains.kotlin.cli.js.dce.K2JSDce + +call %~dps0kotlinc.bat %* diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.java index 908f36e59c6..baee38efbf7 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.java +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.java @@ -16,15 +16,9 @@ package org.jetbrains.kotlin.cli.common.arguments; -import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; -import java.io.Serializable; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -public abstract class CommonCompilerArguments implements Serializable { +public abstract class CommonCompilerArguments extends CommonToolArguments { public static final long serialVersionUID = 0L; public static final String PLUGIN_OPTION_FORMAT = "plugin::="; @@ -45,23 +39,6 @@ public abstract class CommonCompilerArguments implements Serializable { ) public String apiVersion; - @GradleOption(DefaultValues.BooleanFalseDefault.class) - @Argument(value = "-nowarn", description = "Generate no warnings") - public boolean suppressWarnings; - - @GradleOption(DefaultValues.BooleanFalseDefault.class) - @Argument(value = "-verbose", description = "Enable verbose logging output") - public boolean verbose; - - @Argument(value = "-version", description = "Display compiler version") - public boolean version; - - @Argument(value = "-help", shortName = "-h", description = "Print a synopsis of standard options") - public boolean help; - - @Argument(value = "-X", description = "Print a synopsis of advanced options") - public boolean extraHelp; - @Argument(value = "-P", valueDescription = PLUGIN_OPTION_FORMAT, description = "Pass an option to a plugin") public String[] pluginOptions; @@ -110,10 +87,6 @@ public abstract class CommonCompilerArguments implements Serializable { ) public String coroutinesState = WARN; - public List freeArgs = new SmartList<>(); - - public transient ArgumentParseErrors errors = new ArgumentParseErrors(); - @NotNull public static CommonCompilerArguments createDefaultInstance() { return new DummyImpl(); diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonToolArguments.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonToolArguments.java new file mode 100644 index 00000000000..93df6ebb1e9 --- /dev/null +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonToolArguments.java @@ -0,0 +1,47 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.cli.common.arguments; + +import org.jetbrains.kotlin.utils.SmartList; + +import java.io.Serializable; +import java.util.List; + +public abstract class CommonToolArguments implements Serializable { + private static final long serialVersionUID = 0L; + + public List freeArgs = new SmartList<>(); + + public transient ArgumentParseErrors errors = new ArgumentParseErrors(); + + @Argument(value = "-help", shortName = "-h", description = "Print a synopsis of standard options") + public boolean help; + + @Argument(value = "-X", description = "Print a synopsis of advanced options") + public boolean extraHelp; + + @Argument(value = "-version", description = "Display compiler version") + public boolean version; + + @GradleOption(DefaultValues.BooleanFalseDefault.class) + @Argument(value = "-verbose", description = "Enable verbose logging output") + public boolean verbose; + + @GradleOption(DefaultValues.BooleanFalseDefault.class) + @Argument(value = "-nowarn", description = "Generate no warnings") + public boolean suppressWarnings; +} diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSDceArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSDceArguments.kt new file mode 100644 index 00000000000..3bb2131f413 --- /dev/null +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSDceArguments.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.cli.common.arguments + +class K2JSDceArguments : CommonToolArguments() { + companion object { + const val serialVersionUID = 0L + } + + @field:GradleOption(DefaultValues.StringNullDefault::class) + @field:Argument(value = "-output-dir", valueDescription = "", description = "Output directory") + @JvmField + var outputDirectory: String? = null + + @field:GradleOption(DefaultValues.BooleanFalseDefault::class) + @field:Argument(value = "-Xprint-reachability-info", description = "Print declarations marked as reachable") + @JvmField + var printReachabilityInfo: Boolean = false +} diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/parseCommandLineArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/parseCommandLineArguments.kt index c6fc83f8e9c..d60948347c3 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/parseCommandLineArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/parseCommandLineArguments.kt @@ -50,7 +50,7 @@ data class ArgumentParseErrors( ) // Parses arguments in the passed [result] object, or throws an [IllegalArgumentException] with the message to be displayed to the user -fun parseCommandLineArguments(args: Array, result: A) { +fun parseCommandLineArguments(args: Array, result: A) { data class ArgumentField(val field: Field, val argument: Argument) val fields = result::class.java.fields.mapNotNull { field -> @@ -118,7 +118,7 @@ fun parseCommandLineArguments(args: Array, } } -private fun updateField(field: Field, result: A, value: Any, delimiter: String) { +private fun updateField(field: Field, result: A, value: Any, delimiter: String) { when (field.type) { Boolean::class.java, String::class.java -> field.set(result, value) Array::class.java -> { diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLICompiler.java b/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLICompiler.java index dad9a56f06a..8161501f4b3 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLICompiler.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLICompiler.java @@ -19,15 +19,14 @@ package org.jetbrains.kotlin.cli.common; import com.intellij.openapi.Disposable; import com.intellij.openapi.util.Disposer; import kotlin.collections.ArraysKt; -import org.fusesource.jansi.AnsiConsole; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.cli.common.arguments.ArgumentParseErrors; import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments; -import org.jetbrains.kotlin.cli.common.arguments.ParseCommandLineArgumentsKt; -import org.jetbrains.kotlin.cli.common.messages.*; +import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector; +import org.jetbrains.kotlin.cli.common.messages.MessageCollector; +import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil; +import org.jetbrains.kotlin.cli.common.messages.MessageRenderer; import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler; -import org.jetbrains.kotlin.cli.jvm.compiler.CompileEnvironmentException; import org.jetbrains.kotlin.cli.jvm.compiler.CompilerJarLocator; import org.jetbrains.kotlin.config.*; import org.jetbrains.kotlin.progress.CompilationCanceledException; @@ -39,19 +38,12 @@ import java.io.PrintStream; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.Predicate; import static org.jetbrains.kotlin.cli.common.ExitCode.*; import static org.jetbrains.kotlin.cli.common.environment.UtilKt.setIdeaIoUseFallback; import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*; -public abstract class CLICompiler { - - @NotNull - public ExitCode exec(@NotNull PrintStream errStream, @NotNull String... args) { - return exec(errStream, Services.EMPTY, MessageRenderer.PLAIN_RELATIVE_PATHS, args); - } - +public abstract class CLICompiler extends CLITool { // Used in CompilerRunnerUtil#invokeExecMethod, in Eclipse plugin (KotlinCLICompiler) and in kotlin-gradle-plugin (GradleCompilerRunner) @NotNull public ExitCode execAndOutputXml(@NotNull PrintStream errStream, @NotNull Services services, @NotNull String... args) { @@ -65,90 +57,9 @@ public abstract class CLICompiler { return exec(errStream, Services.EMPTY, MessageRenderer.PLAIN_FULL_PATHS, args); } - @Nullable - private A parseArguments(@NotNull MessageCollector messageCollector, @NotNull String[] args) { - try { - A arguments = createArguments(); - parseArguments(args, arguments); - return arguments; - } - catch (IllegalArgumentException e) { - throw e; - } - catch (Throwable t) { - messageCollector.report(EXCEPTION, OutputMessageUtil.renderException(t), null); - return null; - } - } - - // Used in kotlin-maven-plugin (KotlinCompileMojoBase) and in kotlin-gradle-plugin (KotlinJvmOptionsImpl, KotlinJsOptionsImpl) - public void parseArguments(@NotNull String[] args, @NotNull A arguments) { - ParseCommandLineArgumentsKt.parseCommandLineArguments(args, arguments); - String message = ParseCommandLineArgumentsKt.validateArguments(arguments.errors); - if (message != null) { - throw new IllegalArgumentException(message); - } - } - @NotNull - protected abstract A createArguments(); - - @NotNull - private ExitCode exec( - @NotNull PrintStream errStream, - @NotNull Services services, - @NotNull MessageRenderer messageRenderer, - @NotNull String[] args - ) { - K2JVMCompiler.Companion.resetInitStartTime(); - - MessageCollector parseArgumentsCollector = new PrintingMessageCollector(errStream, messageRenderer, false); - A arguments; - try { - arguments = parseArguments(parseArgumentsCollector, args); - if (arguments == null) return INTERNAL_ERROR; - } - catch (IllegalArgumentException e) { - parseArgumentsCollector.report(ERROR, e.getMessage(), null); - parseArgumentsCollector.report(INFO, "Use -help for more information", null); - return COMPILATION_ERROR; - } - - if (arguments.help || arguments.extraHelp) { - Usage.print(errStream, this, arguments); - return OK; - } - - MessageCollector collector = new PrintingMessageCollector(errStream, messageRenderer, arguments.verbose); - - try { - if (PlainTextMessageRenderer.COLOR_ENABLED) { - AnsiConsole.systemInstall(); - } - - errStream.print(messageRenderer.renderPreamble()); - return exec(collector, services, arguments); - } - finally { - errStream.print(messageRenderer.renderConclusion()); - - if (PlainTextMessageRenderer.COLOR_ENABLED) { - AnsiConsole.systemUninstall(); - } - } - } - - // Used in kotlin-maven-plugin (KotlinCompileMojoBase) - @NotNull - public ExitCode exec(@NotNull MessageCollector messageCollector, @NotNull Services services, @NotNull A arguments) { - printVersionIfNeeded(messageCollector, arguments); - - if (arguments.suppressWarnings) { - messageCollector = new FilteringMessageCollector(messageCollector, Predicate.isEqual(WARNING)); - } - - reportArgumentParseProblems(messageCollector, arguments.errors); - + @Override + public ExitCode execImpl(@NotNull MessageCollector messageCollector, @NotNull Services services, @NotNull A arguments) { GroupingMessageCollector groupingCollector = new GroupingMessageCollector(messageCollector); CompilerConfiguration configuration = new CompilerConfiguration(); @@ -328,63 +239,10 @@ public abstract class CLICompiler { @NotNull CompilerConfiguration configuration, @NotNull A arguments, @NotNull Services services ); - private static void reportArgumentParseProblems(@NotNull MessageCollector collector, @NotNull ArgumentParseErrors errors) { - for (String flag : errors.getUnknownExtraFlags()) { - collector.report(STRONG_WARNING, "Flag is not supported by this version of the compiler: " + flag, null); - } - for (String argument : errors.getExtraArgumentsPassedInObsoleteForm()) { - collector.report(STRONG_WARNING, "Advanced option value is passed in an obsolete form. Please use the '=' character " + - "to specify the value: " + argument + "=...", null); - } - for (Map.Entry argument : errors.getDuplicateArguments().entrySet()) { - collector.report(STRONG_WARNING, "Argument " + argument.getKey() + " is passed multiple times. " + - "Only the last value will be used: " + argument.getValue(), null); - } - } - @NotNull protected abstract ExitCode doExecute( @NotNull A arguments, @NotNull CompilerConfiguration configuration, @NotNull Disposable rootDisposable ); - - private void printVersionIfNeeded(@NotNull MessageCollector messageCollector, @NotNull A arguments) { - if (arguments.version) { - messageCollector.report( - CompilerMessageSeverity.INFO, - executableScriptFileName() + " " + KotlinCompilerVersion.VERSION + - " (JRE " + System.getProperty("java.runtime.version") + ")", - null - ); - } - } - - @NotNull - public abstract String executableScriptFileName(); - - /** - * Useful main for derived command line tools - */ - public static void doMain(@NotNull CLICompiler compiler, @NotNull String[] args) { - // We depend on swing (indirectly through PSI or something), so we want to declare headless mode, - // to avoid accidentally starting the UI thread - System.setProperty("java.awt.headless", "true"); - ExitCode exitCode = doMainNoExit(compiler, args); - if (exitCode != OK) { - System.exit(exitCode.getCode()); - } - } - - @SuppressWarnings("UseOfSystemOutOrSystemErr") - @NotNull - public static ExitCode doMainNoExit(@NotNull CLICompiler compiler, @NotNull String[] args) { - try { - return compiler.exec(System.err, args); - } - catch (CompileEnvironmentException e) { - System.err.println(e.getMessage()); - return INTERNAL_ERROR; - } - } } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLITool.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLITool.kt new file mode 100644 index 00000000000..e717a99d989 --- /dev/null +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLITool.kt @@ -0,0 +1,179 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.cli.common + +import org.fusesource.jansi.AnsiConsole +import org.jetbrains.kotlin.cli.common.arguments.ArgumentParseErrors +import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments +import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments +import org.jetbrains.kotlin.cli.common.arguments.validateArguments +import org.jetbrains.kotlin.cli.common.messages.* +import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler +import org.jetbrains.kotlin.cli.jvm.compiler.CompileEnvironmentException +import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.config.Services +import java.io.PrintStream +import java.util.function.Predicate + +abstract class CLITool { + fun exec(errStream: PrintStream, vararg args: String): ExitCode { + return exec(errStream, Services.EMPTY, MessageRenderer.PLAIN_RELATIVE_PATHS, args) + } + + protected fun exec( + errStream: PrintStream, + services: Services, + messageRenderer: MessageRenderer, + args: Array + ): ExitCode { + K2JVMCompiler.resetInitStartTime() + + val parseArgumentsCollector = PrintingMessageCollector(errStream, messageRenderer, false) + val arguments = try { + parseArguments(parseArgumentsCollector, args) ?: return ExitCode.INTERNAL_ERROR + } + catch (e: IllegalArgumentException) { + parseArgumentsCollector.report(CompilerMessageSeverity.ERROR, e.message!!, null) + parseArgumentsCollector.report(CompilerMessageSeverity.INFO, "Use -help for more information", null) + return ExitCode.COMPILATION_ERROR + } + + if (arguments.help || arguments.extraHelp) { + Usage.print(errStream, this, arguments) + return ExitCode.OK + } + + val collector = PrintingMessageCollector(errStream, messageRenderer, arguments.verbose) + + try { + if (PlainTextMessageRenderer.COLOR_ENABLED) { + AnsiConsole.systemInstall() + } + + errStream.print(messageRenderer.renderPreamble()) + return exec(collector, services, arguments) + } + finally { + errStream.print(messageRenderer.renderConclusion()) + + if (PlainTextMessageRenderer.COLOR_ENABLED) { + AnsiConsole.systemUninstall() + } + } + } + + fun exec(messageCollector: MessageCollector, services: Services, arguments: A): ExitCode { + printVersionIfNeeded(messageCollector, arguments) + + val fixedMessageCollector = if (arguments.suppressWarnings) { + FilteringMessageCollector(messageCollector, Predicate.isEqual(CompilerMessageSeverity.WARNING)) + } + else { + messageCollector + } + + reportArgumentParseProblems(fixedMessageCollector, arguments.errors) + return execImpl(fixedMessageCollector, services, arguments) + } + + // Used in kotlin-maven-plugin (KotlinCompileMojoBase) + protected abstract fun execImpl(messageCollector: MessageCollector, services: Services, arguments: A): ExitCode + + private fun parseArguments(messageCollector: MessageCollector, args: Array): A? { + return try { + createArguments().also { parseArguments(args, it) } + } + catch (e: IllegalArgumentException) { + throw e + } + catch (t: Throwable) { + messageCollector.report(CompilerMessageSeverity.EXCEPTION, OutputMessageUtil.renderException(t), null) + null + } + } + + protected abstract fun createArguments(): A + + // Used in kotlin-maven-plugin (KotlinCompileMojoBase) and in kotlin-gradle-plugin (KotlinJvmOptionsImpl, KotlinJsOptionsImpl) + fun parseArguments(args: Array, arguments: A) { + parseCommandLineArguments(args, arguments) + val message = validateArguments(arguments.errors) + if (message != null) { + throw IllegalArgumentException(message) + } + } + + private fun reportArgumentParseProblems(collector: MessageCollector, errors: ArgumentParseErrors) { + for (flag in errors.unknownExtraFlags) { + collector.report( + CompilerMessageSeverity.STRONG_WARNING, + "Flag is not supported by this version of the compiler: " + flag, null) + } + for (argument in errors.extraArgumentsPassedInObsoleteForm) { + collector.report( + CompilerMessageSeverity.STRONG_WARNING, + "Advanced option value is passed in an obsolete form. Please use the '=' character " + + "to specify the value: " + argument + "=...", null) + } + for ((key, value) in errors.duplicateArguments) { + collector.report( + CompilerMessageSeverity.STRONG_WARNING, + "Argument $key is passed multiple times. Only the last value will be used: $value", null) + } + } + + protected fun printVersionIfNeeded(messageCollector: MessageCollector, arguments: A) { + if (!arguments.version) return + + if (arguments.version) { + val jreVersion = System.getProperty("java.runtime.version") + messageCollector.report(CompilerMessageSeverity.INFO, + "${executableScriptFileName()} ${KotlinCompilerVersion.VERSION} (JRE $jreVersion)", + null + ) + } + } + + abstract fun executableScriptFileName(): String + + companion object { + /** + * Useful main for derived command line tools + */ + @JvmStatic + fun doMain(compiler: CLITool<*>, args: Array) { + // We depend on swing (indirectly through PSI or something), so we want to declare headless mode, + // to avoid accidentally starting the UI thread + System.setProperty("java.awt.headless", "true") + val exitCode = doMainNoExit(compiler, args) + if (exitCode != ExitCode.OK) { + System.exit(exitCode.code) + } + } + + @JvmStatic + fun doMainNoExit(compiler: CLITool<*>, args: Array): ExitCode { + try { + return compiler.exec(System.err, *args) + } + catch (e: CompileEnvironmentException) { + System.err.println(e.message) + return ExitCode.INTERNAL_ERROR + } + } + } +} \ No newline at end of file diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/Usage.java b/compiler/cli/src/org/jetbrains/kotlin/cli/common/Usage.java index e7d4755a014..753d6d7a0b4 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/Usage.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/Usage.java @@ -19,7 +19,7 @@ package org.jetbrains.kotlin.cli.common; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.cli.common.arguments.Argument; -import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments; +import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments; import org.jetbrains.kotlin.cli.common.arguments.ParseCommandLineArgumentsKt; import java.io.PrintStream; @@ -29,8 +29,8 @@ class Usage { // The magic number 29 corresponds to the similar padding width in javac and scalac command line compilers private static final int OPTION_NAME_PADDING_WIDTH = 29; - public static void print( - @NotNull PrintStream target, @NotNull CLICompiler compiler, @NotNull A arguments + public static void print( + @NotNull PrintStream target, @NotNull CLITool compiler, @NotNull A arguments ) { target.println("Usage: " + compiler.executableScriptFileName() + " "); target.println("where " + (arguments.extraHelp ? "advanced" : "possible") + " options include:"); diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/js/dce/K2JSDce.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/js/dce/K2JSDce.kt index fff1eaf5981..68b70da2070 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/js/dce/K2JSDce.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/js/dce/K2JSDce.kt @@ -14,20 +14,91 @@ * limitations under the License. */ -@file:JvmName("K2JSDce") package org.jetbrains.kotlin.cli.js.dce +import org.jetbrains.kotlin.cli.common.CLITool +import org.jetbrains.kotlin.cli.common.ExitCode +import org.jetbrains.kotlin.cli.common.arguments.K2JSDceArguments +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity +import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import org.jetbrains.kotlin.config.Services import org.jetbrains.kotlin.js.dce.DeadCodeElimination import org.jetbrains.kotlin.js.dce.InputFile import org.jetbrains.kotlin.js.dce.extractRoots import org.jetbrains.kotlin.js.dce.printTree +import java.io.File -fun main(args: Array) { - val files = args.map { InputFile(it) } - val nodes = DeadCodeElimination.run(files, emptySet()) { println(it) } +class K2JSDce : CLITool() { + override fun createArguments(): K2JSDceArguments = K2JSDceArguments() - println() - for (node in nodes.extractRoots()) { - printTree(node, { println(it) }, printNestedMembers = false, showLocations = true) + override fun execImpl(messageCollector: MessageCollector, services: Services, arguments: K2JSDceArguments): ExitCode { + val baseDir = File(arguments.outputDirectory ?: "min") + val files = arguments.freeArgs.map { arg -> + val parts = arg.split(File.pathSeparator, ignoreCase = false, limit = 2) + val inputName = parts[0] + val moduleName = parts.getOrNull(1) ?: "" + val resolvedModuleName = if (!moduleName.isEmpty()) moduleName else File(inputName).nameWithoutExtension + InputFile(inputName, File(baseDir, resolvedModuleName + ".js").absolutePath, resolvedModuleName) + } + + if (files.isEmpty() && !arguments.version) { + messageCollector.report(CompilerMessageSeverity.ERROR, "no source files") + return ExitCode.COMPILATION_ERROR + } + if (!checkSourceFiles(messageCollector, files)) { + return ExitCode.COMPILATION_ERROR + } + + val dceResult = DeadCodeElimination.run(files, emptySet()) { + messageCollector.report(CompilerMessageSeverity.LOGGING, it) + } + val nodes = dceResult.reachableNodes + + val reachabilitySeverity = if (arguments.printReachabilityInfo) CompilerMessageSeverity.INFO else CompilerMessageSeverity.LOGGING + messageCollector.report(reachabilitySeverity, "") + for (node in nodes.extractRoots()) { + printTree(node, { messageCollector.report(reachabilitySeverity, it) }, + printNestedMembers = false, showLocations = true) + } + + return ExitCode.OK + } + + private fun checkSourceFiles(messageCollector: MessageCollector, files: List): Boolean { + return files.fold(true) { ok, file -> + val inputFile = File(file.path) + val outputFile = File(file.outputPath) + + val inputOk = when { + !inputFile.exists() -> { + messageCollector.report(CompilerMessageSeverity.ERROR, "source file or directory not found: " + file.path) + false + } + inputFile.isDirectory -> { + messageCollector.report(CompilerMessageSeverity.ERROR, "input file '" + file.path + "' is a directory") + false + } + else -> true + } + + val outputOk = when { + outputFile.exists() && outputFile.isDirectory -> { + messageCollector.report(CompilerMessageSeverity.ERROR, "cannot open output file '${outputFile.path}': is a directory") + false + } + else -> true + } + + ok and inputOk and outputOk + } + } + + override fun executableScriptFileName(): String = "kotlin-dce-js" + + companion object { + @JvmStatic + fun main(args: Array) { + CLITool.doMain(K2JSDce(), args) + } } } \ No newline at end of file diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt index 40c0ed01649..1d3a5302280 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt @@ -20,6 +20,7 @@ import com.intellij.ide.highlighter.JavaFileType import com.intellij.openapi.Disposable import org.jetbrains.kotlin.cli.common.CLICompiler import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys +import org.jetbrains.kotlin.cli.common.CLITool import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.ExitCode.* import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments @@ -309,7 +310,7 @@ class K2JVMCompiler : CLICompiler() { } @JvmStatic fun main(args: Array) { - CLICompiler.doMain(K2JVMCompiler(), args) + CLITool.doMain(K2JVMCompiler(), args) } fun reportPerf(configuration: CompilerConfiguration, message: String) { diff --git a/compiler/testData/cli/js-dce/dceHelp.args b/compiler/testData/cli/js-dce/dceHelp.args new file mode 100644 index 00000000000..97f455ac44e --- /dev/null +++ b/compiler/testData/cli/js-dce/dceHelp.args @@ -0,0 +1 @@ +-help diff --git a/compiler/testData/cli/js-dce/dceHelp.out b/compiler/testData/cli/js-dce/dceHelp.out new file mode 100644 index 00000000000..8c4328da1ca --- /dev/null +++ b/compiler/testData/cli/js-dce/dceHelp.out @@ -0,0 +1,9 @@ +Usage: kotlin-dce-js +where possible options include: + -output-dir Output directory + -help (-h) Print a synopsis of standard options + -X Print a synopsis of advanced options + -version Display compiler version + -verbose Enable verbose logging output + -nowarn Generate no warnings +OK \ No newline at end of file diff --git a/compiler/testData/cli/js-dce/emptySources.args b/compiler/testData/cli/js-dce/emptySources.args new file mode 100644 index 00000000000..3d717fcf439 --- /dev/null +++ b/compiler/testData/cli/js-dce/emptySources.args @@ -0,0 +1,2 @@ +-output-dir +$TESTDATA_DIR$/min \ No newline at end of file diff --git a/compiler/testData/cli/js-dce/emptySources.out b/compiler/testData/cli/js-dce/emptySources.out new file mode 100644 index 00000000000..997aed27463 --- /dev/null +++ b/compiler/testData/cli/js-dce/emptySources.out @@ -0,0 +1,2 @@ +error: no source files +COMPILATION_ERROR diff --git a/compiler/testData/cli/js-dce/includeDeclarations.out b/compiler/testData/cli/js-dce/includeDeclarations.out new file mode 100644 index 00000000000..c56c76104d5 --- /dev/null +++ b/compiler/testData/cli/js-dce/includeDeclarations.out @@ -0,0 +1,8 @@ +info: +info: +info: global +info: bar (reachable) +info: foo (reachable) +info: include +info: baz (reachable from include.js:14) +OK \ No newline at end of file diff --git a/compiler/testData/cli/js-dce/jsExtraHelp.args b/compiler/testData/cli/js-dce/jsExtraHelp.args new file mode 100644 index 00000000000..653774072c9 --- /dev/null +++ b/compiler/testData/cli/js-dce/jsExtraHelp.args @@ -0,0 +1 @@ +-X diff --git a/compiler/testData/cli/js-dce/jsExtraHelp.out b/compiler/testData/cli/js-dce/jsExtraHelp.out new file mode 100644 index 00000000000..09a48bbfe9c --- /dev/null +++ b/compiler/testData/cli/js-dce/jsExtraHelp.out @@ -0,0 +1,6 @@ +Usage: kotlin-dce-js +where advanced options include: + -Xprint-reachability-info Print declarations marked as reachable + +Advanced options are non-standard and may be changed or removed without any notice. +OK diff --git a/compiler/testData/cli/js-dce/min/simple.js/.gitkeep b/compiler/testData/cli/js-dce/min/simple.js/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/compiler/testData/cli/js-dce/min/simple.kt b/compiler/testData/cli/js-dce/min/simple.kt new file mode 100644 index 00000000000..15a5a333f1e --- /dev/null +++ b/compiler/testData/cli/js-dce/min/simple.kt @@ -0,0 +1,4 @@ +function bar() { + return 'bar'; +} +console.log(bar()); diff --git a/compiler/testData/cli/js-dce/nonExistingSourcePath.args b/compiler/testData/cli/js-dce/nonExistingSourcePath.args new file mode 100644 index 00000000000..3a9557695c6 --- /dev/null +++ b/compiler/testData/cli/js-dce/nonExistingSourcePath.args @@ -0,0 +1,3 @@ +nonExistingSourceFile.js +-output-dir +$TEMP_DIR/min \ No newline at end of file diff --git a/compiler/testData/cli/js-dce/nonExistingSourcePath.out b/compiler/testData/cli/js-dce/nonExistingSourcePath.out new file mode 100644 index 00000000000..d86a0cb24d2 --- /dev/null +++ b/compiler/testData/cli/js-dce/nonExistingSourcePath.out @@ -0,0 +1,2 @@ +error: source file or directory not found: nonExistingSourceFile.js +COMPILATION_ERROR diff --git a/compiler/testData/cli/js-dce/nonExistingSourcePath.test b/compiler/testData/cli/js-dce/nonExistingSourcePath.test new file mode 100644 index 00000000000..e5ed30d77ac --- /dev/null +++ b/compiler/testData/cli/js-dce/nonExistingSourcePath.test @@ -0,0 +1 @@ +// ABSENT: min/nonExistingSourceFile.js diff --git a/compiler/testData/cli/js-dce/notFile.args b/compiler/testData/cli/js-dce/notFile.args new file mode 100644 index 00000000000..f3f1f6cb35c --- /dev/null +++ b/compiler/testData/cli/js-dce/notFile.args @@ -0,0 +1,3 @@ +$TESTDATA_DIR$ +-output-dir +$TEMP_DIR/min \ No newline at end of file diff --git a/compiler/testData/cli/js-dce/notFile.out b/compiler/testData/cli/js-dce/notFile.out new file mode 100644 index 00000000000..7657d6798fc --- /dev/null +++ b/compiler/testData/cli/js-dce/notFile.out @@ -0,0 +1,2 @@ +error: input file 'compiler/testData/cli/js-dce' is a directory +COMPILATION_ERROR diff --git a/compiler/testData/cli/js-dce/outputIsDirectory.args b/compiler/testData/cli/js-dce/outputIsDirectory.args new file mode 100644 index 00000000000..1fe5fe0b406 --- /dev/null +++ b/compiler/testData/cli/js-dce/outputIsDirectory.args @@ -0,0 +1,3 @@ +$TESTDATA_DIR$/simple.js +-output-dir +$TESTDATA_DIR$/min diff --git a/compiler/testData/cli/js-dce/outputIsDirectory.out b/compiler/testData/cli/js-dce/outputIsDirectory.out new file mode 100644 index 00000000000..2ca5ba23ff5 --- /dev/null +++ b/compiler/testData/cli/js-dce/outputIsDirectory.out @@ -0,0 +1,2 @@ +error: cannot open output file '$TESTDATA_DIR$/min/simple.js': is a directory +COMPILATION_ERROR diff --git a/compiler/testData/cli/js-dce/outputIsDirectory.test b/compiler/testData/cli/js-dce/outputIsDirectory.test new file mode 100644 index 00000000000..8c8bba65ee6 --- /dev/null +++ b/compiler/testData/cli/js-dce/outputIsDirectory.test @@ -0,0 +1 @@ +// ABSENT: out.js diff --git a/compiler/testData/cli/js-dce/overrideOutputName.args b/compiler/testData/cli/js-dce/overrideOutputName.args new file mode 100644 index 00000000000..70eaab3b498 --- /dev/null +++ b/compiler/testData/cli/js-dce/overrideOutputName.args @@ -0,0 +1,3 @@ +$TESTDATA_DIR$/simple.js:bar +-output-dir +$TEMP_DIR$/min \ No newline at end of file diff --git a/compiler/testData/cli/js-dce/overrideOutputName.out b/compiler/testData/cli/js-dce/overrideOutputName.out new file mode 100644 index 00000000000..d86bac9de59 --- /dev/null +++ b/compiler/testData/cli/js-dce/overrideOutputName.out @@ -0,0 +1 @@ +OK diff --git a/compiler/testData/cli/js-dce/overrideOutputName.test b/compiler/testData/cli/js-dce/overrideOutputName.test new file mode 100644 index 00000000000..1223b61909c --- /dev/null +++ b/compiler/testData/cli/js-dce/overrideOutputName.test @@ -0,0 +1 @@ +// EXISTS: min/bar.js \ No newline at end of file diff --git a/compiler/testData/cli/js-dce/printReachability.args b/compiler/testData/cli/js-dce/printReachability.args new file mode 100644 index 00000000000..624bff2424d --- /dev/null +++ b/compiler/testData/cli/js-dce/printReachability.args @@ -0,0 +1,4 @@ +$TESTDATA_DIR$/simple.js +-output-dir +$TEMP_DIR$/min +-Xprint-reachability-info \ No newline at end of file diff --git a/compiler/testData/cli/js-dce/printReachability.out b/compiler/testData/cli/js-dce/printReachability.out new file mode 100644 index 00000000000..5172f9d1db6 --- /dev/null +++ b/compiler/testData/cli/js-dce/printReachability.out @@ -0,0 +1,6 @@ +info: +info: +info: bar (reachable from simple.js:7) +info: console +info: log (reachable from simple.js:7) +OK diff --git a/compiler/testData/cli/js-dce/printReachability.test b/compiler/testData/cli/js-dce/printReachability.test new file mode 100644 index 00000000000..9c68c76678e --- /dev/null +++ b/compiler/testData/cli/js-dce/printReachability.test @@ -0,0 +1 @@ +// EXISTS: min/simple.js \ No newline at end of file diff --git a/compiler/testData/cli/js-dce/simple.args b/compiler/testData/cli/js-dce/simple.args new file mode 100644 index 00000000000..ba86e5c89c3 --- /dev/null +++ b/compiler/testData/cli/js-dce/simple.args @@ -0,0 +1,3 @@ +$TESTDATA_DIR$/simple.js +-output-dir +$TEMP_DIR$/min \ No newline at end of file diff --git a/compiler/testData/cli/js-dce/simple.js b/compiler/testData/cli/js-dce/simple.js new file mode 100644 index 00000000000..f40195aa8e7 --- /dev/null +++ b/compiler/testData/cli/js-dce/simple.js @@ -0,0 +1,7 @@ +function foo() { + return "foo"; +} +function bar() { + return "bar"; +} +console.log(bar()); \ No newline at end of file diff --git a/compiler/testData/cli/js-dce/simple.out b/compiler/testData/cli/js-dce/simple.out new file mode 100644 index 00000000000..d86bac9de59 --- /dev/null +++ b/compiler/testData/cli/js-dce/simple.out @@ -0,0 +1 @@ +OK diff --git a/compiler/testData/cli/js-dce/simple.test b/compiler/testData/cli/js-dce/simple.test new file mode 100644 index 00000000000..9c68c76678e --- /dev/null +++ b/compiler/testData/cli/js-dce/simple.test @@ -0,0 +1 @@ +// EXISTS: min/simple.js \ No newline at end of file diff --git a/compiler/testData/cli/js/jsHelp.out b/compiler/testData/cli/js/jsHelp.out index 7355ba35e89..ce9b772c35e 100644 --- a/compiler/testData/cli/js/jsHelp.out +++ b/compiler/testData/cli/js/jsHelp.out @@ -13,11 +13,11 @@ where possible options include: -output-postfix Path to file which will be added to the end of output file -language-version Provide source compatibility with specified language version -api-version Allow to use declarations only from the specified version of bundled libraries - -nowarn Generate no warnings - -verbose Enable verbose logging output - -version Display compiler version - -help (-h) Print a synopsis of standard options - -X Print a synopsis of advanced options -P plugin::= Pass an option to a plugin + -help (-h) Print a synopsis of standard options + -X Print a synopsis of advanced options + -version Display compiler version + -verbose Enable verbose logging output + -nowarn Generate no warnings OK \ No newline at end of file diff --git a/compiler/testData/cli/jvm/help.out b/compiler/testData/cli/jvm/help.out index 4d1710521ad..1c3859c8b0c 100644 --- a/compiler/testData/cli/jvm/help.out +++ b/compiler/testData/cli/jvm/help.out @@ -17,11 +17,11 @@ where possible options include: -java-parameters Generate metadata for Java 1.8 reflection on method parameters -language-version Provide source compatibility with specified language version -api-version Allow to use declarations only from the specified version of bundled libraries - -nowarn Generate no warnings - -verbose Enable verbose logging output - -version Display compiler version - -help (-h) Print a synopsis of standard options - -X Print a synopsis of advanced options -P plugin::= Pass an option to a plugin + -help (-h) Print a synopsis of standard options + -X Print a synopsis of advanced options + -version Display compiler version + -verbose Enable verbose logging output + -nowarn Generate no warnings OK \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/cli/AbstractCliTest.java b/compiler/tests/org/jetbrains/kotlin/cli/AbstractCliTest.java index 66e9ad56fe8..93434e49e40 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/AbstractCliTest.java +++ b/compiler/tests/org/jetbrains/kotlin/cli/AbstractCliTest.java @@ -25,8 +25,10 @@ import kotlin.io.FilesKt; import kotlin.text.Charsets; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.cli.common.CLICompiler; +import org.jetbrains.kotlin.cli.common.CLITool; import org.jetbrains.kotlin.cli.common.ExitCode; import org.jetbrains.kotlin.cli.js.K2JSCompiler; +import org.jetbrains.kotlin.cli.js.dce.K2JSDce; import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler; import org.jetbrains.kotlin.config.KotlinCompilerVersion; import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion; @@ -48,12 +50,12 @@ import java.util.List; public abstract class AbstractCliTest extends TestCaseWithTmpdir { @NotNull - public static Pair executeCompilerGrabOutput(@NotNull CLICompiler compiler, @NotNull List args) { + public static Pair executeCompilerGrabOutput(@NotNull CLITool compiler, @NotNull List args) { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); PrintStream origErr = System.err; try { System.setErr(new PrintStream(bytes)); - ExitCode exitCode = CLICompiler.doMainNoExit(compiler, ArrayUtil.toStringArray(args)); + ExitCode exitCode = CLITool.doMainNoExit(compiler, ArrayUtil.toStringArray(args)); return new Pair<>(bytes.toString("utf-8"), exitCode); } catch (Exception e) { @@ -79,7 +81,7 @@ public abstract class AbstractCliTest extends TestCaseWithTmpdir { return normalizedOutputWithoutExitCode + exitCode; } - private void doTest(@NotNull String fileName, @NotNull CLICompiler compiler) throws Exception { + private void doTest(@NotNull String fileName, @NotNull CLITool compiler) throws Exception { System.setProperty("java.awt.headless", "true"); Pair outputAndExitCode = executeCompilerGrabOutput(compiler, readArgs(fileName, tmpdir.getPath())); String actual = getNormalizedCompilerOutput( @@ -153,6 +155,10 @@ public abstract class AbstractCliTest extends TestCaseWithTmpdir { doTest(fileName, new K2JSCompiler()); } + protected void doJsDceTest(@NotNull String fileName) throws Exception { + doTest(fileName, new K2JSDce()); + } + public static String removePerfOutput(String output) { String[] lines = StringUtil.splitByLinesKeepSeparators(output); StringBuilder result = new StringBuilder(); diff --git a/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java index cf55f24f422..f4bb2576814 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java @@ -539,4 +539,67 @@ public class CliTestGenerated extends AbstractCliTest { doJsTest(fileName); } } + + @TestMetadata("compiler/testData/cli/js-dce") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Js_dce extends AbstractCliTest { + public void testAllFilesPresentInJs_dce() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/cli/js-dce"), Pattern.compile("^(.+)\\.args$"), TargetBackend.ANY, false); + } + + @TestMetadata("dceHelp.args") + public void testDceHelp() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/js-dce/dceHelp.args"); + doJsDceTest(fileName); + } + + @TestMetadata("emptySources.args") + public void testEmptySources() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/js-dce/emptySources.args"); + doJsDceTest(fileName); + } + + @TestMetadata("jsExtraHelp.args") + public void testJsExtraHelp() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/js-dce/jsExtraHelp.args"); + doJsDceTest(fileName); + } + + @TestMetadata("nonExistingSourcePath.args") + public void testNonExistingSourcePath() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/js-dce/nonExistingSourcePath.args"); + doJsDceTest(fileName); + } + + @TestMetadata("notFile.args") + public void testNotFile() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/js-dce/notFile.args"); + doJsDceTest(fileName); + } + + @TestMetadata("outputIsDirectory.args") + public void testOutputIsDirectory() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/js-dce/outputIsDirectory.args"); + doJsDceTest(fileName); + } + + @TestMetadata("overrideOutputName.args") + public void testOverrideOutputName() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/js-dce/overrideOutputName.args"); + doJsDceTest(fileName); + } + + @TestMetadata("printReachability.args") + public void testPrintReachability() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/js-dce/printReachability.args"); + doJsDceTest(fileName); + } + + @TestMetadata("simple.args") + public void testSimple() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/js-dce/simple.args"); + doJsDceTest(fileName); + } + } } diff --git a/generators/src/org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt b/generators/src/org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt index df28004acbf..b4abbb13358 100644 --- a/generators/src/org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt +++ b/generators/src/org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt @@ -40,7 +40,7 @@ fun generateKotlinGradleOptions(withPrinterToFile: (targetFile: File, Printer.() // common interface val commonInterfaceFqName = FqName("org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions") - val commonOptions = gradleOptions() + val commonOptions = gradleOptions() + gradleOptions() val additionalOptions = gradleOptions() withPrinterToFile(File(srcDir, commonInterfaceFqName)) { generateInterface(commonInterfaceFqName, diff --git a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index 15b50f0b72e..4a241bc2c08 100755 --- a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -377,6 +377,7 @@ fun main(args: Array) { testClass { model("cli/jvm", extension = "args", testMethod = "doJvmTest", recursive = false) model("cli/js", extension = "args", testMethod = "doJsTest", recursive = false) + model("cli/js-dce", extension = "args", testMethod = "doJsDceTest", recursive = false) } testClass { diff --git a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt index 5ee3047d185..a5f50fcdab2 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt @@ -207,7 +207,7 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner() { private fun setupK2JsArguments(_outputFile: File, sourceFiles: Collection, _libraries: List, _friendModules: List, settings: K2JSCompilerArguments) { with(settings) { noStdlib = true - freeArgs = sourceFiles.map { it.path } + freeArgs = sourceFiles.map { it.path }.toMutableList() outputFile = _outputFile.path metaInfo = true libraries = _libraries.joinToString(File.pathSeparator) diff --git a/plugins/source-sections/source-sections-compiler/tests/org/jetbrains/kotlin/sourceSections/SourceSectionsTest.kt b/plugins/source-sections/source-sections-compiler/tests/org/jetbrains/kotlin/sourceSections/SourceSectionsTest.kt index a47996a4b7f..f4705bb43dc 100644 --- a/plugins/source-sections/source-sections-compiler/tests/org/jetbrains/kotlin/sourceSections/SourceSectionsTest.kt +++ b/plugins/source-sections/source-sections-compiler/tests/org/jetbrains/kotlin/sourceSections/SourceSectionsTest.kt @@ -18,8 +18,8 @@ package org.jetbrains.kotlin.sourceSections import com.intellij.openapi.vfs.StandardFileSystems import junit.framework.TestCase -import org.jetbrains.kotlin.cli.common.CLICompiler import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys +import org.jetbrains.kotlin.cli.common.CLITool import org.jetbrains.kotlin.cli.common.messages.* import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles @@ -179,7 +179,7 @@ class SourceSectionsTest : TestCaseWithTmpdir() { "-Xplugin=${sourceSectionsPluginJar.canonicalPath}", "-P", TEST_ALLOWED_SECTIONS.joinToString(",") { "plugin:${SourceSectionsCommandLineProcessor.PLUGIN_ID}:${SourceSectionsCommandLineProcessor.SECTIONS_OPTION.name}=$it" }) val (output, code) = captureOut { - CLICompiler.doMainNoExit(K2JVMCompiler(), args) + CLITool.doMainNoExit(K2JVMCompiler(), args) } TestCase.assertEquals("Compilation failed:\n$output", 0, code.code)