diff options
author | Daniel Below <daniel.below@tum.de> | 2021-06-02 22:58:41 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-02 22:58:41 +0200 |
commit | b4ebb47ac25e8afe8d77bb617372f6ec13bdb783 (patch) | |
tree | dc9829f9674c62c61734554615793b67c8f99bd6 | |
parent | ba2b7c89cb3cba8da9b462199ded435d4d78d63f (diff) | |
download | compiler-explorer-b4ebb47ac25e8afe8d77bb617372f6ec13bdb783.tar.gz compiler-explorer-b4ebb47ac25e8afe8d77bb617372f6ec13bdb783.zip |
Add Kotlin/JVM support (#2637)
* Add Kotlin/JVM support
* Update CONTRIBUTORS.md
* Use kotlinc-jvm instead of kotlinc
* Fix alphabetical ordering
* Filter kotlin compiler arguments
Extract user options filtering for java into a separate function to
handle filtering options with extra arguments.
Filter kotlin compiler options: -d, -jdk-home, -kotlin-home, -script, -progressive
* Filter -Xjavac user options
Filter any option that starts with '-Xjavac', as it could be used to pass unwanted options through kotlinc to javac.
* Fix year in copyright
Co-authored-by: Rubén Rincón Blanco <ruben@rinconblanco.es>
* Add kotlin.amazon.properties
* Add JAVA_HOME to kotlin default exec options
Query per-compiler property 'java_home' and set environment
* Add java_home to kotlin properties
Co-authored-by: Daniel Below <daniel.below@jetbrains.com>
Co-authored-by: Rubén Rincón Blanco <ruben@rinconblanco.es>
-rw-r--r-- | CONTRIBUTORS.md | 1 | ||||
-rw-r--r-- | etc/config/kotlin.amazon.properties | 38 | ||||
-rw-r--r-- | etc/config/kotlin.defaults.properties | 18 | ||||
-rw-r--r-- | examples/kotlin/default.kt | 2 | ||||
-rw-r--r-- | lib/compilers/_all.js | 1 | ||||
-rw-r--r-- | lib/compilers/argument-parsers.js | 7 | ||||
-rw-r--r-- | lib/compilers/java.js | 30 | ||||
-rw-r--r-- | lib/compilers/kotlin.js | 78 | ||||
-rw-r--r-- | lib/languages.js | 6 | ||||
-rw-r--r-- | test/kotlin/square/input.kt | 2 | ||||
-rw-r--r-- | test/kotlin/square/javap-square.asm | 14 | ||||
-rw-r--r-- | test/kotlin/square/output.asm | 11 | ||||
-rw-r--r-- | webpack.config.esm.js | 2 |
13 files changed, 196 insertions, 14 deletions
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 0f3166699..d1ff773e4 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -100,3 +100,4 @@ From oldest to newest contributor, we would like to thank: - [Dan Okken](https://github.com/okkenator) - [Shivam Gupta](https://github.com/xgupta) - [Tamir Bahar](https://github.com/tmr232) +- [Daniel Below](https://github.com/DanielBelow) diff --git a/etc/config/kotlin.amazon.properties b/etc/config/kotlin.amazon.properties new file mode 100644 index 000000000..5f7776fa7 --- /dev/null +++ b/etc/config/kotlin.amazon.properties @@ -0,0 +1,38 @@ +compilers=&kotlin +compilerType=kotlin +versionFlag=-version +objdumper=javap +instructionSet=java +defaultCompiler=kotlinc1500 +demangler= +postProcess= +options= +supportsBinary=false +needsMulti=false +supportsExecute=false + +group.kotlin.compilers=kotlinc1400:kotlinc1410:kotlinc1420:kotlinc1421:kotlinc1430:kotlinc1431:kotlinc1432:kotlinc1500 +compiler.kotlinc1400.exe=/opt/compiler-explorer/kotlin-jvm-1.4.0/bin/kotlinc-jvm +compiler.kotlinc1400.name=kotlinc 1.4.0 +compiler.kotlinc1400.java_home=/opt/compiler-explorer/jdk-16.0.1 +compiler.kotlinc1410.exe=/opt/compiler-explorer/kotlin-jvm-1.4.10/bin/kotlinc-jvm +compiler.kotlinc1410.name=kotlinc 1.4.10 +compiler.kotlinc1410.java_home=/opt/compiler-explorer/jdk-16.0.1 +compiler.kotlinc1420.exe=/opt/compiler-explorer/kotlin-jvm-1.4.20/bin/kotlinc-jvm +compiler.kotlinc1420.name=kotlinc 1.4.20 +compiler.kotlinc1420.java_home=/opt/compiler-explorer/jdk-16.0.1 +compiler.kotlinc1421.exe=/opt/compiler-explorer/kotlin-jvm-1.4.21/bin/kotlinc-jvm +compiler.kotlinc1421.name=kotlinc 1.4.21 +compiler.kotlinc1421.java_home=/opt/compiler-explorer/jdk-16.0.1 +compiler.kotlinc1430.exe=/opt/compiler-explorer/kotlin-jvm-1.4.30/bin/kotlinc-jvm +compiler.kotlinc1430.name=kotlinc 1.4.30 +compiler.kotlinc1430.java_home=/opt/compiler-explorer/jdk-16.0.1 +compiler.kotlinc1431.exe=/opt/compiler-explorer/kotlin-jvm-1.4.31/bin/kotlinc-jvm +compiler.kotlinc1431.name=kotlinc 1.4.31 +compiler.kotlinc1431.java_home=/opt/compiler-explorer/jdk-16.0.1 +compiler.kotlinc1432.exe=/opt/compiler-explorer/kotlin-jvm-1.4.32/bin/kotlinc-jvm +compiler.kotlinc1432.name=kotlinc 1.4.32 +compiler.kotlinc1432.java_home=/opt/compiler-explorer/jdk-16.0.1 +compiler.kotlinc1500.exe=/opt/compiler-explorer/kotlin-jvm-1.5.0/bin/kotlinc-jvm +compiler.kotlinc1500.name=kotlinc 1.5.0 +compiler.kotlinc1500.java_home=/opt/compiler-explorer/jdk-16.0.1 diff --git a/etc/config/kotlin.defaults.properties b/etc/config/kotlin.defaults.properties new file mode 100644 index 000000000..374dc6965 --- /dev/null +++ b/etc/config/kotlin.defaults.properties @@ -0,0 +1,18 @@ +# Default settings for Kotlin/JVM +compilers=&kotlin +compilerType=kotlin +versionFlag=-version +objdumper=javap +instructionSet=java + +group.kotlin.compilers=kotlincdefault +compiler.kotlincdefault.exe=/usr/bin/kotlinc-jvm +compiler.kotlincdefault.name=kotlinc default + +defaultCompiler=kotlincdefault +demangler= +postProcess= +options= +supportsBinary=false +needsMulti=false +supportsExecute=false diff --git a/examples/kotlin/default.kt b/examples/kotlin/default.kt new file mode 100644 index 000000000..b1576c436 --- /dev/null +++ b/examples/kotlin/default.kt @@ -0,0 +1,2 @@ +// Type your code here, or load an example. +fun square(num: Int): Int = num * num diff --git a/lib/compilers/_all.js b/lib/compilers/_all.js index f6e9e65af..5af9f3c70 100644 --- a/lib/compilers/_all.js +++ b/lib/compilers/_all.js @@ -42,6 +42,7 @@ export { GolangCompiler } from './golang'; export { HaskellCompiler } from './haskell'; export { ISPCCompiler } from './ispc'; export { JavaCompiler } from './java'; +export { KotlinCompiler } from './kotlin'; export { LDCCompiler } from './ldc'; export { LLCCompiler } from './llc'; export { LLVMmcaTool } from './llvm-mca'; diff --git a/lib/compilers/argument-parsers.js b/lib/compilers/argument-parsers.js index 6b139c829..750e9c2ef 100644 --- a/lib/compilers/argument-parsers.js +++ b/lib/compilers/argument-parsers.js @@ -178,6 +178,13 @@ export class JavaParser extends BaseParser { } } +export class KotlinParser extends BaseParser { + static async parse(compiler) { + await KotlinParser.getOptions(compiler, '-help'); + return compiler; + } +} + export class VCParser extends BaseParser { static async parse(compiler) { await VCParser.getOptions(compiler, '/help'); diff --git a/lib/compilers/java.js b/lib/compilers/java.js index 677eeb323..c61cc8f65 100644 --- a/lib/compilers/java.js +++ b/lib/compilers/java.js @@ -111,22 +111,10 @@ export class JavaCompiler extends BaseCompiler { return path.join(dirPath, `${path.basename(this.compileFilename, this.lang.extensions[0])}.class`); } - filterUserOptions(userOptions) { + filterUserOptionsWithArg(userOptions, oneArgForbiddenList) { const filteredOptions = []; let toSkip = 0; - const oneArgForbiddenList = new Set([ - // -d directory - // Sets the destination directory for class files. - '-d', - // -s directory - // Specifies the directory used to place the generated source files. - '-s', - // --source-path path or -sourcepath path - // Specifies where to find input source files. - '--source-path', '-sourcepath', - ]); - for (const userOption of userOptions) { if (toSkip > 0) { toSkip--; @@ -143,6 +131,22 @@ export class JavaCompiler extends BaseCompiler { return filteredOptions; } + filterUserOptions(userOptions) { + const oneArgForbiddenList = new Set([ + // -d directory + // Sets the destination directory for class files. + '-d', + // -s directory + // Specifies the directory used to place the generated source files. + '-s', + // --source-path path or -sourcepath path + // Specifies where to find input source files. + '--source-path', '-sourcepath', + ]); + + return this.filterUserOptionsWithArg(userOptions, oneArgForbiddenList); + } + processAsm(result) { // Handle "error" documents. if (!result.asm.includes('\n') && result.asm[0] === '<') { diff --git a/lib/compilers/kotlin.js b/lib/compilers/kotlin.js new file mode 100644 index 000000000..a7e21f796 --- /dev/null +++ b/lib/compilers/kotlin.js @@ -0,0 +1,78 @@ +// Copyright (c) 2021, Compiler Explorer Authors +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +import { KotlinParser } from './argument-parsers'; +import { JavaCompiler } from './java'; + +export class KotlinCompiler extends JavaCompiler { + static get key() { + return 'kotlin'; + } + + getDefaultExecOptions() { + const execOptions = super.getDefaultExecOptions(); + const javaHome = this.compilerProps(`compiler.${this.compiler.id}.java_home`); + if (javaHome) { + execOptions.env.JAVA_HOME = javaHome; + } + + return execOptions; + } + + filterUserOptions(userOptions) { + // filter options without extra arguments + userOptions = userOptions.filter(option => + option !== '-script' && option !== '-progressive' && !option.startsWith('-Xjavac')); + + const oneArgForbiddenList = new Set([ + // -d directory + // Destination for generated class files + '-d', + // -jdk-home path + // Include a custom JDK from the specified location + // into the classpath instead of the default JAVA_HOME + '-jdk-home', + // -kotlin-home path + // Path to the home directory of Kotlin compiler used for + // discovery of runtime libraries + '-kotlin-home', + ]); + + // filter options with one argument + return super.filterUserOptionsWithArg(userOptions, oneArgForbiddenList); + } + + optionsForFilter(filters) { + // Forcibly enable javap + filters.binary = true; + + return [ + '-Xjavac-arguments="-Xlint:all"', + ]; + } + + getArgumentParser() { + return KotlinParser; + } +} diff --git a/lib/languages.js b/lib/languages.js index 57ab9f70e..e77c61961 100644 --- a/lib/languages.js +++ b/lib/languages.js @@ -124,6 +124,12 @@ export const languages = { extensions: ['.java'], alias: [], }, + kotlin: { + name: 'Kotlin', + monaco: 'kotlin', + extensions: ['.kt'], + alias: [], + }, ocaml: { name: 'OCaml', monaco: 'ocaml', diff --git a/test/kotlin/square/input.kt b/test/kotlin/square/input.kt new file mode 100644 index 000000000..b1576c436 --- /dev/null +++ b/test/kotlin/square/input.kt @@ -0,0 +1,2 @@ +// Type your code here, or load an example. +fun square(num: Int): Int = num * num diff --git a/test/kotlin/square/javap-square.asm b/test/kotlin/square/javap-square.asm new file mode 100644 index 000000000..6512b25fd --- /dev/null +++ b/test/kotlin/square/javap-square.asm @@ -0,0 +1,14 @@ +Compiled from "example.kt" +public final class ExampleKt { + public static final int square(int); + Code: + 0: iload_0 + 1: iload_0 + 2: imul + 3: ireturn + LineNumberTable: + line 1: 0 + LocalVariableTable: + Start Length Slot Name Signature + 0 4 0 num I +}
\ No newline at end of file diff --git a/test/kotlin/square/output.asm b/test/kotlin/square/output.asm new file mode 100644 index 000000000..c9c853386 --- /dev/null +++ b/test/kotlin/square/output.asm @@ -0,0 +1,11 @@ +public final class ExampleKt { + public static final int square(int); +line 1: 0: iload_0 +line 1: 1: iload_0 +line 1: 2: imul +line 1: 3: ireturn + + LocalVariableTable: + Start Length Slot Name Signature + 0 4 0 num I +}
\ No newline at end of file diff --git a/webpack.config.esm.js b/webpack.config.esm.js index b7ba80068..bf1069fff 100644 --- a/webpack.config.esm.js +++ b/webpack.config.esm.js @@ -46,7 +46,7 @@ const staticPath = path.join(distPath, 'static'); const webjackJsHack = '.v4.'; const plugins = [ new MonacoEditorWebpackPlugin({ - languages: [ 'cpp', 'go', 'pascal', 'python', 'rust', 'swift', 'java' ], + languages: [ 'cpp', 'go', 'pascal', 'python', 'rust', 'swift', 'java', 'kotlin' ], filename: isDev ? '[name].worker.js' : `[name]${webjackJsHack}worker.[contenthash].js`, }), new CopyWebpackPlugin([ |