diff --git a/libraries/tools/kotlin-main-kts-test/test/org/jetbrains/kotlin/mainKts/test/mainKtsTest.kt b/libraries/tools/kotlin-main-kts-test/test/org/jetbrains/kotlin/mainKts/test/mainKtsTest.kt index edc8bad6d88..62ff3110e0f 100644 --- a/libraries/tools/kotlin-main-kts-test/test/org/jetbrains/kotlin/mainKts/test/mainKtsTest.kt +++ b/libraries/tools/kotlin-main-kts-test/test/org/jetbrains/kotlin/mainKts/test/mainKtsTest.kt @@ -7,9 +7,7 @@ package org.jetbrains.kotlin.mainKts.test import org.jetbrains.kotlin.mainKts.MainKtsScript import org.junit.Assert import org.junit.Test -import java.io.ByteArrayOutputStream -import java.io.File -import java.io.PrintStream +import java.io.* import kotlin.script.experimental.api.* import kotlin.script.experimental.host.toScriptSource import kotlin.script.experimental.jvm.baseClassLoader @@ -90,6 +88,32 @@ class MainKtsTest { Assert.assertEquals(listOf("Hi from common", "Hi from middle", "sharedVar == 5"), out) } + @Test + fun testCompilerOptions() { + + val out = captureOut { + val res = evalFile(File("$TEST_DATA_ROOT/compile-java6.main.kts")) + assertSucceeded(res) + assertIsJava6Bytecode(res) + }.lines() + + Assert.assertEquals(listOf("Hi from sub", "Hi from super", "Hi from random"), out) + } + + private fun assertIsJava6Bytecode(res: ResultWithDiagnostics) { + val scriptClassResource = res.valueOrThrow().returnValue.scriptClass!!.java.run { + getResource("$simpleName.class") + } + + DataInputStream(ByteArrayInputStream(scriptClassResource.readBytes())).use { stream -> + val header = stream.readInt() + if (0xCAFEBABE.toInt() != header) throw IOException("Invalid header class header: $header") + val minor = stream.readUnsignedShort() + val major = stream.readUnsignedShort() + Assert.assertTrue(major == 50) + } + } + private fun assertSucceeded(res: ResultWithDiagnostics) { Assert.assertTrue( "test failed:\n ${res.reports.joinToString("\n ") { it.message + if (it.exception == null) "" else ": ${it.exception}" }}", diff --git a/libraries/tools/kotlin-main-kts-test/testData/compile-java6.main.kts b/libraries/tools/kotlin-main-kts-test/testData/compile-java6.main.kts new file mode 100644 index 00000000000..45d78c35fb0 --- /dev/null +++ b/libraries/tools/kotlin-main-kts-test/testData/compile-java6.main.kts @@ -0,0 +1,18 @@ +@file:CompilerOptions("-jvm-target", "1.6") + +interface Test { + fun print() + fun printSuper() = println("Hi from super") +} + +class TestImpl : Test { + override fun print() = println("Hi from sub") +} + +inline fun printRandom() = println("Hi from random") + +TestImpl().run { + print() + printSuper() + printRandom() +} diff --git a/libraries/tools/kotlin-main-kts/src/org/jetbrains/kotlin/mainKts/scriptDef.kt b/libraries/tools/kotlin-main-kts/src/org/jetbrains/kotlin/mainKts/scriptDef.kt index d6ae7a7f41e..81b8dcd0b65 100644 --- a/libraries/tools/kotlin-main-kts/src/org/jetbrains/kotlin/mainKts/scriptDef.kt +++ b/libraries/tools/kotlin-main-kts/src/org/jetbrains/kotlin/mainKts/scriptDef.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.mainKts import org.jetbrains.kotlin.mainKts.impl.FilesAndIvyResolver +import org.jetbrains.kotlin.script.util.CompilerOptions import org.jetbrains.kotlin.script.util.DependsOn import org.jetbrains.kotlin.script.util.Import import org.jetbrains.kotlin.script.util.Repository @@ -35,17 +36,13 @@ abstract class MainKtsScript(val args: Array) object MainKtsScriptDefinition : ScriptCompilationConfiguration( { - defaultImports(DependsOn::class, Repository::class, Import::class) + defaultImports(DependsOn::class, Repository::class, Import::class, CompilerOptions::class) jvm { dependenciesFromClassContext(MainKtsScriptDefinition::class, "kotlin-main-kts", "kotlin-stdlib", "kotlin-reflect") } refineConfiguration { - onAnnotations(DependsOn::class, Repository::class, Import::class, handler = MainKtsConfigurator()) - beforeCompiling { context -> - configureProvidedPropertiesFromJsr223Context( - ScriptConfigurationRefinementContext(context.script, context.compilationConfiguration, context.collectedData) - ) - } + onAnnotations(DependsOn::class, Repository::class, Import::class, CompilerOptions::class, handler = MainKtsConfigurator()) + beforeCompiling(::configureProvidedPropertiesFromJsr223Context) } ide { acceptedLocations(ScriptAcceptedLocation.Everywhere) @@ -91,6 +88,9 @@ class MainKtsConfigurator : RefineScriptCompilationConfigurationHandler { FileScriptSource(scriptBaseDir?.resolve(sourceName) ?: File(sourceName)) } ?: emptyList() } + val compileOptions = annotations.flatMap { + (it as? CompilerOptions)?.options?.toList() ?: emptyList() + } val resolvedClassPath = try { val scriptContents = object : ScriptContents { @@ -107,6 +107,7 @@ class MainKtsConfigurator : RefineScriptCompilationConfigurationHandler { return ScriptCompilationConfiguration(context.compilationConfiguration) { if (resolvedClassPath != null) updateClasspath(resolvedClassPath) if (importedSources.isNotEmpty()) importScripts.append(importedSources) + if (compileOptions.isNotEmpty()) compilerOptions.append(compileOptions) }.asSuccess(diagnostics) } } diff --git a/libraries/tools/kotlin-script-util/src/main/kotlin/org/jetbrains/kotlin/script/util/annotations.kt b/libraries/tools/kotlin-script-util/src/main/kotlin/org/jetbrains/kotlin/script/util/annotations.kt index c1ab85a4fcb..803db866b62 100644 --- a/libraries/tools/kotlin-script-util/src/main/kotlin/org/jetbrains/kotlin/script/util/annotations.kt +++ b/libraries/tools/kotlin-script-util/src/main/kotlin/org/jetbrains/kotlin/script/util/annotations.kt @@ -37,3 +37,13 @@ annotation class Repository(val value: String = "", val id: String = "", val url @Repeatable @Retention(AnnotationRetention.SOURCE) annotation class Import(vararg val paths: String) + +/** + * Compiler options that will be applied on script compilation + * + * @see [kotlin.script.experimental.api.compilerOptions] + */ +@Target(AnnotationTarget.FILE) +@Repeatable +@Retention(AnnotationRetention.SOURCE) +annotation class CompilerOptions(vararg val options: String)