From 0600abd6bd1d523259915a731d116543b565eb05 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 22 Jun 2015 17:20:39 +0200 Subject: [PATCH] K2JVMCompiler: J2K --- .../jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt | 353 +++++++++--------- .../compiler/KotlinToJVMBytecodeCompiler.java | 4 +- 2 files changed, 170 insertions(+), 187 deletions(-) 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 7c3c9e578b7..6c12f72e02d 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt @@ -14,282 +14,265 @@ * limitations under the License. */ -package org.jetbrains.kotlin.cli.jvm; +package org.jetbrains.kotlin.cli.jvm -import com.google.common.base.Splitter; -import com.google.common.collect.Lists; -import com.intellij.openapi.Disposable; -import kotlin.Unit; -import kotlin.jvm.functions.Function1; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.cli.common.CLICompiler; -import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys; -import org.jetbrains.kotlin.cli.common.ExitCode; -import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments; -import org.jetbrains.kotlin.cli.common.messages.*; -import org.jetbrains.kotlin.cli.common.modules.ModuleScriptData; -import org.jetbrains.kotlin.cli.jvm.compiler.*; -import org.jetbrains.kotlin.cli.jvm.config.JVMConfigurationKeys; -import org.jetbrains.kotlin.cli.jvm.repl.ReplFromTerminal; -import org.jetbrains.kotlin.codegen.CompilationException; -import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException; -import org.jetbrains.kotlin.compiler.plugin.PluginCliOptionProcessingException; -import org.jetbrains.kotlin.compiler.plugin.PluginPackage; -import org.jetbrains.kotlin.config.CompilerConfiguration; -import org.jetbrains.kotlin.config.IncrementalCompilation; -import org.jetbrains.kotlin.config.Services; -import org.jetbrains.kotlin.load.kotlin.incremental.cache.IncrementalCacheProvider; -import org.jetbrains.kotlin.resolve.AnalyzerScriptParameter; -import org.jetbrains.kotlin.util.PerformanceCounter; -import org.jetbrains.kotlin.utils.KotlinPaths; -import org.jetbrains.kotlin.utils.KotlinPathsFromHomeDir; -import org.jetbrains.kotlin.utils.PathUtil; +import com.google.common.base.Splitter +import com.google.common.collect.Lists +import com.intellij.openapi.Disposable +import kotlin.Unit +import org.jetbrains.kotlin.cli.common.CLICompiler +import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys +import org.jetbrains.kotlin.cli.common.ExitCode +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments +import org.jetbrains.kotlin.cli.common.messages.* +import org.jetbrains.kotlin.cli.common.modules.ModuleScriptData +import org.jetbrains.kotlin.cli.jvm.compiler.* +import org.jetbrains.kotlin.cli.jvm.config.JVMConfigurationKeys +import org.jetbrains.kotlin.cli.jvm.repl.ReplFromTerminal +import org.jetbrains.kotlin.codegen.CompilationException +import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException +import org.jetbrains.kotlin.compiler.plugin.PluginCliOptionProcessingException +import org.jetbrains.kotlin.compiler.plugin.* +import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.config.IncrementalCompilation +import org.jetbrains.kotlin.config.Services +import org.jetbrains.kotlin.load.kotlin.incremental.cache.IncrementalCacheProvider +import org.jetbrains.kotlin.resolve.AnalyzerScriptParameter +import org.jetbrains.kotlin.util.PerformanceCounter +import org.jetbrains.kotlin.utils.KotlinPaths +import org.jetbrains.kotlin.utils.KotlinPathsFromHomeDir +import org.jetbrains.kotlin.utils.PathUtil -import java.io.File; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.TimeUnit; +import java.io.File +import java.util.Collections +import java.util.concurrent.TimeUnit -import static com.google.common.base.Predicates.in; -import static org.jetbrains.kotlin.cli.common.ExitCode.*; -import static org.jetbrains.kotlin.cli.jvm.config.ConfigPackage.addJavaSourceRoot; -import static org.jetbrains.kotlin.cli.jvm.config.ConfigPackage.addJvmClasspathRoots; -import static org.jetbrains.kotlin.config.ConfigPackage.addKotlinSourceRoot; +import com.google.common.base.Predicates.`in` +import org.jetbrains.kotlin.cli.common.ExitCode.* +import org.jetbrains.kotlin.cli.jvm.config.addJavaSourceRoot +import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots +import org.jetbrains.kotlin.config.addKotlinSourceRoot -@SuppressWarnings("UseOfSystemOutOrSystemErr") -public class K2JVMCompiler extends CLICompiler { - private final long initStartNanos = System.nanoTime(); +SuppressWarnings("UseOfSystemOutOrSystemErr") +public class K2JVMCompiler : CLICompiler() { + private val initStartNanos = System.nanoTime() - public static void main(String... args) { - doMain(new K2JVMCompiler(), args); - } + override fun doExecute(arguments: K2JVMCompilerArguments, services: Services, messageCollector: MessageCollector, rootDisposable: Disposable): ExitCode { + val messageSeverityCollector = MessageSeverityCollector(messageCollector) + val paths = if (arguments.kotlinHome != null) + KotlinPathsFromHomeDir(File(arguments.kotlinHome)) + else + PathUtil.getKotlinPathsForCompiler() - @Override - @NotNull - protected ExitCode doExecute( - @NotNull K2JVMCompilerArguments arguments, - @NotNull Services services, - @NotNull MessageCollector messageCollector, - @NotNull Disposable rootDisposable - ) { - MessageSeverityCollector messageSeverityCollector = new MessageSeverityCollector(messageCollector); - KotlinPaths paths = arguments.kotlinHome != null - ? new KotlinPathsFromHomeDir(new File(arguments.kotlinHome)) - : PathUtil.getKotlinPathsForCompiler(); + messageSeverityCollector.report(CompilerMessageSeverity.LOGGING, "Using Kotlin home directory " + paths.getHomePath(), CompilerMessageLocation.NO_LOCATION) - messageSeverityCollector.report(CompilerMessageSeverity.LOGGING, - "Using Kotlin home directory " + paths.getHomePath(), CompilerMessageLocation.NO_LOCATION); - - CompilerConfiguration configuration = new CompilerConfiguration(); - configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageSeverityCollector); + val configuration = CompilerConfiguration() + configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageSeverityCollector) if (IncrementalCompilation.ENABLED) { - IncrementalCacheProvider incrementalCacheProvider = services.get(IncrementalCacheProvider.class); + val incrementalCacheProvider = services.get(javaClass()) if (incrementalCacheProvider != null) { - configuration.put(JVMConfigurationKeys.INCREMENTAL_CACHE_PROVIDER, incrementalCacheProvider); + configuration.put(JVMConfigurationKeys.INCREMENTAL_CACHE_PROVIDER, incrementalCacheProvider) } } - CompilerJarLocator locator = services.get(CompilerJarLocator.class); + val locator = services.get(javaClass()) if (locator != null) { - configuration.put(JVMConfigurationKeys.COMPILER_JAR_LOCATOR, locator); + configuration.put(JVMConfigurationKeys.COMPILER_JAR_LOCATOR, locator) } try { if (!arguments.noJdk) { - addJvmClasspathRoots(configuration, PathUtil.getJdkClassesRoots()); + configuration.addJvmClasspathRoots(PathUtil.getJdkClassesRoots()) } } - catch (Throwable t) { - MessageCollectorUtil.reportException(messageSeverityCollector, t); - return INTERNAL_ERROR; + catch (t: Throwable) { + MessageCollectorUtil.reportException(messageSeverityCollector, t) + return INTERNAL_ERROR } + try { - PluginCliParser.loadPlugins(arguments, configuration); + PluginCliParser.loadPlugins(arguments, configuration) } - catch (PluginCliOptionProcessingException e) { - String message = e.getMessage() + "\n\n" + PluginPackage.cliPluginUsageString(e.getPluginId(), e.getOptions()); - messageSeverityCollector.report(CompilerMessageSeverity.ERROR, message, CompilerMessageLocation.NO_LOCATION); - return INTERNAL_ERROR; + catch (e: PluginCliOptionProcessingException) { + val message = e.getMessage() + "\n\n" + cliPluginUsageString(e.pluginId, e.options) + messageSeverityCollector.report(CompilerMessageSeverity.ERROR, message, CompilerMessageLocation.NO_LOCATION) + return INTERNAL_ERROR } - catch (CliOptionProcessingException e) { - messageSeverityCollector.report(CompilerMessageSeverity.ERROR, e.getMessage(), CompilerMessageLocation.NO_LOCATION); - return INTERNAL_ERROR; + catch (e: CliOptionProcessingException) { + messageSeverityCollector.report(CompilerMessageSeverity.ERROR, e.getMessage(), CompilerMessageLocation.NO_LOCATION) + return INTERNAL_ERROR } - catch (Throwable t) { - MessageCollectorUtil.reportException(messageSeverityCollector, t); - return INTERNAL_ERROR; + catch (t: Throwable) { + MessageCollectorUtil.reportException(messageSeverityCollector, t) + return INTERNAL_ERROR } + if (arguments.script) { if (arguments.freeArgs.isEmpty()) { - messageSeverityCollector.report(CompilerMessageSeverity.ERROR, "Specify script source path to evaluate", - CompilerMessageLocation.NO_LOCATION); - return COMPILATION_ERROR; + messageSeverityCollector.report(CompilerMessageSeverity.ERROR, "Specify script source path to evaluate", CompilerMessageLocation.NO_LOCATION) + return COMPILATION_ERROR } - addKotlinSourceRoot(configuration, arguments.freeArgs.get(0)); + configuration.addKotlinSourceRoot(arguments.freeArgs.get(0)) } else if (arguments.module == null) { - for (String arg : arguments.freeArgs) { - addKotlinSourceRoot(configuration, arg); - File file = new File(arg); + for (arg in arguments.freeArgs) { + configuration.addKotlinSourceRoot(arg) + val file = File(arg) if (file.isDirectory()) { - addJavaSourceRoot(configuration, file); + configuration.addJavaSourceRoot(file) } } } - addJvmClasspathRoots(configuration, getClasspath(paths, arguments)); + configuration.addJvmClasspathRoots(getClasspath(paths, arguments)) - configuration.addAll(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY, getAnnotationsPath(paths, arguments)); + configuration.addAll(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY, getAnnotationsPath(paths, arguments)) if (arguments.module == null && arguments.freeArgs.isEmpty() && !arguments.version) { - ReplFromTerminal.run(rootDisposable, configuration); - return ExitCode.OK; + ReplFromTerminal.run(rootDisposable, configuration) + return ExitCode.OK } - configuration.put(JVMConfigurationKeys.SCRIPT_PARAMETERS, arguments.script - ? CommandLineScriptUtils.scriptParameters() - : Collections.emptyList()); + configuration.put>(JVMConfigurationKeys.SCRIPT_PARAMETERS, if (arguments.script) + CommandLineScriptUtils.scriptParameters() + else + emptyList()) - putAdvancedOptions(configuration, arguments); + putAdvancedOptions(configuration, arguments) - messageSeverityCollector.report(CompilerMessageSeverity.LOGGING, "Configuring the compilation environment", - CompilerMessageLocation.NO_LOCATION); + messageSeverityCollector.report(CompilerMessageSeverity.LOGGING, "Configuring the compilation environment", CompilerMessageLocation.NO_LOCATION) try { - configureEnvironment(configuration, arguments); + configureEnvironment(configuration, arguments) - String destination = arguments.destination; + val destination = arguments.destination - File jar; - File outputDir; + val jar: File? + val outputDir: File? if (destination != null) { - boolean isJar = destination.endsWith(".jar"); - jar = isJar ? new File(destination) : null; - outputDir = isJar ? null : new File(destination); + val isJar = destination.endsWith(".jar") + jar = if (isJar) File(destination) else null + outputDir = if (isJar) null else File(destination) } else { - jar = null; - outputDir = null; + jar = null + outputDir = null } - final KotlinCoreEnvironment environment; + val environment: KotlinCoreEnvironment if (arguments.module != null) { - MessageCollector sanitizedCollector = new FilteringMessageCollector(messageSeverityCollector, in(CompilerMessageSeverity.VERBOSE)); - ModuleScriptData moduleScript = CompileEnvironmentUtil.loadModuleDescriptions(arguments.module, sanitizedCollector); + val sanitizedCollector = FilteringMessageCollector(messageSeverityCollector, `in`(CompilerMessageSeverity.VERBOSE)) + val moduleScript = CompileEnvironmentUtil.loadModuleDescriptions(arguments.module, sanitizedCollector) if (outputDir != null) { - messageSeverityCollector.report(CompilerMessageSeverity.WARNING, - "The '-d' option with a directory destination is ignored because '-module' is specified", - CompilerMessageLocation.NO_LOCATION); + messageSeverityCollector.report(CompilerMessageSeverity.WARNING, "The '-d' option with a directory destination is ignored because '-module' is specified", CompilerMessageLocation.NO_LOCATION) } - File directory = new File(arguments.module).getAbsoluteFile().getParentFile(); + val directory = File(arguments.module).getAbsoluteFile().getParentFile() - CompilerConfiguration compilerConfiguration = KotlinToJVMBytecodeCompiler - .createCompilerConfiguration(configuration, moduleScript.getModules(), directory); - environment = createCoreEnvironment(rootDisposable, compilerConfiguration); + val compilerConfiguration = KotlinToJVMBytecodeCompiler.createCompilerConfiguration(configuration, moduleScript.getModules(), directory) + environment = createCoreEnvironment(rootDisposable, compilerConfiguration) - KotlinToJVMBytecodeCompiler.compileModules( - environment, configuration, moduleScript.getModules(), directory, jar, arguments.includeRuntime); + KotlinToJVMBytecodeCompiler.compileModules(environment, configuration, moduleScript.getModules(), directory, jar, arguments.includeRuntime) } else if (arguments.script) { - List scriptArgs = arguments.freeArgs.subList(1, arguments.freeArgs.size()); - environment = createCoreEnvironment(rootDisposable, configuration); - KotlinToJVMBytecodeCompiler.compileAndExecuteScript(configuration, paths, environment, scriptArgs); + val scriptArgs = arguments.freeArgs.subList(1, arguments.freeArgs.size()) + environment = createCoreEnvironment(rootDisposable, configuration) + KotlinToJVMBytecodeCompiler.compileAndExecuteScript(configuration, paths, environment, scriptArgs) } else { - environment = createCoreEnvironment(rootDisposable, configuration); + environment = createCoreEnvironment(rootDisposable, configuration) if (messageSeverityCollector.anyReported(CompilerMessageSeverity.ERROR)) { - return COMPILATION_ERROR; + return COMPILATION_ERROR } if (environment.getSourceFiles().isEmpty()) { - messageSeverityCollector.report(CompilerMessageSeverity.ERROR, "No source files", CompilerMessageLocation.NO_LOCATION); - return COMPILATION_ERROR; + messageSeverityCollector.report(CompilerMessageSeverity.ERROR, "No source files", CompilerMessageLocation.NO_LOCATION) + return COMPILATION_ERROR } - KotlinToJVMBytecodeCompiler.compileBunchOfSources(environment, jar, outputDir, arguments.includeRuntime); + KotlinToJVMBytecodeCompiler.compileBunchOfSources(environment, jar, outputDir, arguments.includeRuntime) } if (arguments.reportPerf) { - PerformanceCounter.Companion.report(new Function1() { - @Override - public Unit invoke(String s) { - reportPerf(environment.getConfiguration(), s); - return Unit.INSTANCE$; + PerformanceCounter.report(object : Function1 { + override fun invoke(s: String): Unit { + reportPerf(environment.configuration, s) } - }); + }) } - return OK; + return OK } - catch (CompilationException e) { - messageSeverityCollector.report(CompilerMessageSeverity.EXCEPTION, OutputMessageUtil.renderException(e), - MessageUtil.psiElementToMessageLocation(e.getElement())); - return INTERNAL_ERROR; + catch (e: CompilationException) { + messageSeverityCollector.report(CompilerMessageSeverity.EXCEPTION, OutputMessageUtil.renderException(e), MessageUtil.psiElementToMessageLocation(e.getElement())) + return INTERNAL_ERROR } + } - private KotlinCoreEnvironment createCoreEnvironment( - @NotNull Disposable rootDisposable, - @NotNull CompilerConfiguration configuration) { - KotlinCoreEnvironment result = KotlinCoreEnvironment.createForProduction( - rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES); + private fun createCoreEnvironment(rootDisposable: Disposable, configuration: CompilerConfiguration): KotlinCoreEnvironment { + val result = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) - long initNanos = System.nanoTime() - initStartNanos; - reportPerf(configuration, "INIT: Compiler initialized in " + TimeUnit.NANOSECONDS.toMillis(initNanos) + " ms"); - return result; - } - - public static void reportPerf(CompilerConfiguration configuration, String message) { - MessageCollector collector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY); - assert collector != null; - collector.report(CompilerMessageSeverity.INFO, "PERF: " + message, CompilerMessageLocation.NO_LOCATION); - } - - private static void putAdvancedOptions(@NotNull CompilerConfiguration configuration, @NotNull K2JVMCompilerArguments arguments) { - configuration.put(JVMConfigurationKeys.DISABLE_CALL_ASSERTIONS, arguments.noCallAssertions); - configuration.put(JVMConfigurationKeys.DISABLE_PARAM_ASSERTIONS, arguments.noParamAssertions); - configuration.put(JVMConfigurationKeys.DISABLE_INLINE, arguments.noInline); - configuration.put(JVMConfigurationKeys.DISABLE_OPTIMIZATION, arguments.noOptimize); + val initNanos = System.nanoTime() - initStartNanos + reportPerf(configuration, "INIT: Compiler initialized in " + TimeUnit.NANOSECONDS.toMillis(initNanos) + " ms") + return result } /** * Allow derived classes to add additional command line arguments */ - @NotNull - @Override - protected K2JVMCompilerArguments createArguments() { - return new K2JVMCompilerArguments(); + override fun createArguments(): K2JVMCompilerArguments { + return K2JVMCompilerArguments() } - @NotNull - private static List getClasspath(@NotNull KotlinPaths paths, @NotNull K2JVMCompilerArguments arguments) { - List classpath = Lists.newArrayList(); - if (arguments.classpath != null) { - for (String element : Splitter.on(File.pathSeparatorChar).split(arguments.classpath)) { - classpath.add(new File(element)); - } - } - if (!arguments.noStdlib) { - classpath.add(paths.getRuntimePath()); - } - return classpath; - } + companion object { - @NotNull - private static List getAnnotationsPath(@NotNull KotlinPaths paths, @NotNull K2JVMCompilerArguments arguments) { - List annotationsPath = Lists.newArrayList(); - if (arguments.annotations != null) { - for (String element : Splitter.on(File.pathSeparatorChar).split(arguments.annotations)) { - annotationsPath.add(new File(element)); + public fun main(args: Array) { + CLICompiler.doMain(K2JVMCompiler(), args) + } + + public fun reportPerf(configuration: CompilerConfiguration, message: String) { + val collector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) + assert(collector != null) + collector!!.report(CompilerMessageSeverity.INFO, "PERF: " + message, CompilerMessageLocation.NO_LOCATION) + } + + private fun putAdvancedOptions(configuration: CompilerConfiguration, arguments: K2JVMCompilerArguments) { + configuration.put(JVMConfigurationKeys.DISABLE_CALL_ASSERTIONS, arguments.noCallAssertions) + configuration.put(JVMConfigurationKeys.DISABLE_PARAM_ASSERTIONS, arguments.noParamAssertions) + configuration.put(JVMConfigurationKeys.DISABLE_INLINE, arguments.noInline) + configuration.put(JVMConfigurationKeys.DISABLE_OPTIMIZATION, arguments.noOptimize) + } + + private fun getClasspath(paths: KotlinPaths, arguments: K2JVMCompilerArguments): List { + val classpath = Lists.newArrayList() + if (arguments.classpath != null) { + for (element in Splitter.on(File.pathSeparatorChar).split(arguments.classpath)) { + classpath.add(File(element)) + } } + if (!arguments.noStdlib) { + classpath.add(paths.getRuntimePath()) + } + return classpath } - if (!arguments.noJdkAnnotations) { - annotationsPath.add(paths.getJdkAnnotationsPath()); + + private fun getAnnotationsPath(paths: KotlinPaths, arguments: K2JVMCompilerArguments): List { + val annotationsPath = Lists.newArrayList() + if (arguments.annotations != null) { + for (element in Splitter.on(File.pathSeparatorChar).split(arguments.annotations)) { + annotationsPath.add(File(element)) + } + } + if (!arguments.noJdkAnnotations) { + annotationsPath.add(paths.getJdkAnnotationsPath()) + } + return annotationsPath } - return annotationsPath; } } + +fun main(args: Array) = K2JVMCompiler.main(args) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java index 5a94d39cd00..29c1c22dbe9 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java @@ -322,7 +322,7 @@ public class KotlinToJVMBytecodeCompiler { long analysisNanos = PerformanceCounter.Companion.currentThreadCpuTime() - analysisStart; String message = "ANALYZE: " + environment.getSourceFiles().size() + " files (" + environment.getSourceLinesOfCode() + " lines) in " + TimeUnit.NANOSECONDS.toMillis(analysisNanos) + " ms"; - K2JVMCompiler.reportPerf(environment.getConfiguration(), message); + K2JVMCompiler.Companion.reportPerf(environment.getConfiguration(), message); AnalysisResult result = analyzerWithCompilerReport.getAnalysisResult(); assert result != null : "AnalysisResult should be non-null, compiling: " + environment.getSourceFiles(); @@ -383,7 +383,7 @@ public class KotlinToJVMBytecodeCompiler { long generationNanos = PerformanceCounter.Companion.currentThreadCpuTime() - generationStart; String message = "GENERATE: " + sourceFiles.size() + " files (" + environment.countLinesOfCode(sourceFiles) + " lines) in " + TimeUnit.NANOSECONDS.toMillis(generationNanos) + " ms"; - K2JVMCompiler.reportPerf(environment.getConfiguration(), message); + K2JVMCompiler.Companion.reportPerf(environment.getConfiguration(), message); AnalyzerWithCompilerReport.reportDiagnostics( new FilteredJvmDiagnostics(