From 4dc29bf0b22ff29b44a1873b05514de7122ddb55 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Sun, 14 Jun 2015 18:26:01 +0300 Subject: [PATCH] Introduce 'kotlin' script for running programs 'kotlin' is to 'kotlinc' what 'java' is to 'javac'. However it will support much more: running class by name, jar, scripts, expressions, REPL --- .idea/modules.xml | 1 + build.xml | 37 +++-- compiler/cli/bin/kotlin | 19 +++ compiler/cli/bin/kotlin.bat | 20 +++ compiler/cli/bin/kotlinc | 30 ++-- compiler/cli/bin/kotlinc-js.bat | 3 +- compiler/cli/bin/kotlinc.bat | 19 ++- compiler/cli/cli-runner/cli-runner.iml | 12 ++ .../org/jetbrains/kotlin/runner/Classpath.kt | 34 ++++ .../src/org/jetbrains/kotlin/runner/Main.kt | 145 ++++++++++++++++++ .../src/org/jetbrains/kotlin/runner/Runner.kt | 21 +++ .../org/jetbrains/kotlin/runner/runners.kt | 119 ++++++++++++++ resources/kotlinManifest.properties | 2 + 13 files changed, 429 insertions(+), 33 deletions(-) create mode 100755 compiler/cli/bin/kotlin create mode 100644 compiler/cli/bin/kotlin.bat create mode 100644 compiler/cli/cli-runner/cli-runner.iml create mode 100644 compiler/cli/cli-runner/src/org/jetbrains/kotlin/runner/Classpath.kt create mode 100644 compiler/cli/cli-runner/src/org/jetbrains/kotlin/runner/Main.kt create mode 100644 compiler/cli/cli-runner/src/org/jetbrains/kotlin/runner/Runner.kt create mode 100644 compiler/cli/cli-runner/src/org/jetbrains/kotlin/runner/runners.kt diff --git a/.idea/modules.xml b/.idea/modules.xml index 8bd75e0c6c8..ef2bbf68e47 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -17,6 +17,7 @@ + diff --git a/build.xml b/build.xml index c67932f2408..cc3dab39509 100644 --- a/build.xml +++ b/build.xml @@ -137,10 +137,6 @@ - - - - @@ -392,8 +388,8 @@ - + source="${java.target}" target="${java.target}"> + @@ -401,16 +397,39 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/compiler/cli/cli-runner/src/org/jetbrains/kotlin/runner/Classpath.kt b/compiler/cli/cli-runner/src/org/jetbrains/kotlin/runner/Classpath.kt new file mode 100644 index 00000000000..6bb10080703 --- /dev/null +++ b/compiler/cli/cli-runner/src/org/jetbrains/kotlin/runner/Classpath.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2015 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.runner + +import java.io.File +import java.net.URL + +class Classpath { + private val classpath = arrayListOf() + + fun add(paths: String) { + for (path in paths.split(File.pathSeparator)) { + classpath.add(File(path).absoluteFile.toURI().toURL()) + } + } + + fun getURLs(): Array { + return classpath.toTypedArray() + } +} diff --git a/compiler/cli/cli-runner/src/org/jetbrains/kotlin/runner/Main.kt b/compiler/cli/cli-runner/src/org/jetbrains/kotlin/runner/Main.kt new file mode 100644 index 00000000000..16d53be3728 --- /dev/null +++ b/compiler/cli/cli-runner/src/org/jetbrains/kotlin/runner/Main.kt @@ -0,0 +1,145 @@ +/* + * Copyright 2010-2015 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.runner + +import java.io.File +import java.io.FileNotFoundException +import java.util.* + +public object Main { + private val KOTLIN_HOME: File + + init { + val home = System.getProperty("kotlin.home") + if (home == null) { + System.err.println("error: no kotlin.home system property was passed") + System.exit(1) + } + KOTLIN_HOME = File(home) + } + + private fun run(args: Array) { + val classpath = Classpath() + var runner: Runner? = null + var collectingArguments = false + val arguments = arrayListOf() + + classpath.add(".") + + var i = 0 + while (i < args.size()) { + val arg = args[i] + if (collectingArguments) { + arguments.add(arg) + i++ + continue + } + + fun next(): String { + if (++i == args.size()) { + throw RunnerException("argument expected to $arg") + } + return args[i] + } + + if ("-help" == arg || "-h" == arg) { + printUsageAndExit() + } + else if ("-version" == arg) { + printVersionAndExit() + } + else if ("-classpath" == arg || "-cp" == arg) { + classpath.add(next()) + } + else if ("-expression" == arg || "-e" == arg) { + runner = ExpressionRunner(next()) + collectingArguments = true + } + else if (arg.startsWith("-")) { + throw RunnerException("unsupported argument: $arg") + } + else if (arg.endsWith(".jar")) { + runner = JarRunner(arg) + collectingArguments = true + } + else if (arg.endsWith(".kts")) { + runner = ScriptRunner(arg) + collectingArguments = true + } + else { + runner = MainClassRunner(arg) + collectingArguments = true + } + i++ + } + + classpath.add(KOTLIN_HOME.toString() + "/lib/kotlin-runtime.jar") + + // TODO: provide a way to disable including kotlin-reflect.jar to the classpath + classpath.add(KOTLIN_HOME.toString() + "/lib/kotlin-reflect.jar") + + if (runner == null) { + runner = ReplRunner() + } + + runner.run(classpath, arguments) + } + + @jvmStatic + public fun main(args: Array) { + try { + run(args) + } + catch (e: RunnerException) { + System.err.println("error: " + e.getMessage()) + System.exit(1) + } + } + + private fun printUsageAndExit() { + println("""kotlin: run Kotlin programs, scripts or REPL. + +Usage: kotlin +where command may be one of: + foo.Bar Runs the 'main' function from the class with the given qualified name + app.jar Runs the given JAR file as 'java -jar' would do + (-classpath argument is ignored and no Kotlin runtime is added to the classpath) +""" + +// script.kts Compiles and runs the given script +// -expression (-e) '2+2' Evaluates the expression and prints the result +"""and possible options include: + -classpath (-cp) Paths where to find user class files + -Dname=value Set a system JVM property + -J