Command-line tool for JS DCE

This commit is contained in:
Alexey Andreev
2017-04-24 17:20:14 +03:00
parent ca7062d776
commit 8a8fdf1968
46 changed files with 559 additions and 207 deletions
+22
View File
@@ -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 "$@"
+20
View File
@@ -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 %*
@@ -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:<pluginId>:<optionName>=<value>";
@@ -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<String> freeArgs = new SmartList<>();
public transient ArgumentParseErrors errors = new ArgumentParseErrors();
@NotNull
public static CommonCompilerArguments createDefaultInstance() {
return new DummyImpl();
@@ -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<String> 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;
}
@@ -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 = "<path>", 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
}
@@ -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 <A : CommonCompilerArguments> parseCommandLineArguments(args: Array<String>, result: A) {
fun <A : CommonToolArguments> parseCommandLineArguments(args: Array<out String>, result: A) {
data class ArgumentField(val field: Field, val argument: Argument)
val fields = result::class.java.fields.mapNotNull { field ->
@@ -118,7 +118,7 @@ fun <A : CommonCompilerArguments> parseCommandLineArguments(args: Array<String>,
}
}
private fun <A : CommonCompilerArguments> updateField(field: Field, result: A, value: Any, delimiter: String) {
private fun <A : CommonToolArguments> updateField(field: Field, result: A, value: Any, delimiter: String) {
when (field.type) {
Boolean::class.java, String::class.java -> field.set(result, value)
Array<String>::class.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<A extends CommonCompilerArguments> {
@NotNull
public ExitCode exec(@NotNull PrintStream errStream, @NotNull String... args) {
return exec(errStream, Services.EMPTY, MessageRenderer.PLAIN_RELATIVE_PATHS, args);
}
public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLITool<A> {
// 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<A extends CommonCompilerArguments> {
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<A extends CommonCompilerArguments> {
@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<String, String> 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;
}
}
}
@@ -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<A : CommonToolArguments> {
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<out String>
): 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<out String>): 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<out String>, 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 <A : CommonToolArguments> 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<String>) {
// 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<String>): ExitCode {
try {
return compiler.exec(System.err, *args)
}
catch (e: CompileEnvironmentException) {
System.err.println(e.message)
return ExitCode.INTERNAL_ERROR
}
}
}
}
@@ -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 <A extends CommonCompilerArguments> void print(
@NotNull PrintStream target, @NotNull CLICompiler<A> compiler, @NotNull A arguments
public static <A extends CommonToolArguments> void print(
@NotNull PrintStream target, @NotNull CLITool<A> compiler, @NotNull A arguments
) {
target.println("Usage: " + compiler.executableScriptFileName() + " <options> <source files>");
target.println("where " + (arguments.extraHelp ? "advanced" : "possible") + " options include:");
@@ -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<String>) {
val files = args.map { InputFile(it) }
val nodes = DeadCodeElimination.run(files, emptySet()) { println(it) }
class K2JSDce : CLITool<K2JSDceArguments>() {
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<InputFile>): 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<String>) {
CLITool.doMain(K2JSDce(), args)
}
}
}
@@ -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<K2JVMCompilerArguments>() {
}
@JvmStatic fun main(args: Array<String>) {
CLICompiler.doMain(K2JVMCompiler(), args)
CLITool.doMain(K2JVMCompiler(), args)
}
fun reportPerf(configuration: CompilerConfiguration, message: String) {