From 0d26087040b94acfff0434d1a12a2975ee8accd8 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Sat, 31 Oct 2015 15:02:55 +0300 Subject: [PATCH] CLI, Ant: add kotlin-reflect.jar to classpath by default, support "-no-reflect" Note that now "-no-stdlib" implies "-no-reflect". #KT-13237 Fixed --- .../jetbrains/kotlin/ant/Kotlin2JvmTask.kt | 3 +++ .../jetbrains/kotlin/ant/KotlinAntTaskUtil.kt | 26 ++++++++----------- .../kotlin/ant/KotlinCompilerAdapter.kt | 18 +++++++++---- build.xml | 6 ----- .../arguments/K2JVMCompilerArguments.java | 3 +++ .../jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt | 7 ++++- compiler/testData/cli/jvm/help.out | 1 + compiler/testData/cli/jvm/noReflect.args | 4 +++ compiler/testData/cli/jvm/noReflect.kt | 6 +++++ compiler/testData/cli/jvm/noReflect.out | 4 +++ compiler/testData/cli/jvm/noStdlib.args | 4 +++ compiler/testData/cli/jvm/noStdlib.kt | 6 +++++ compiler/testData/cli/jvm/noStdlib.out | 7 +++++ compiler/testData/cli/jvm/wrongArgument.out | 1 + .../ant/jvm/noReflectForJavac/J.java | 6 +++++ .../jvm/noReflectForJavac/build.log.expected | 22 ++++++++++++++++ .../ant/jvm/noReflectForJavac/build.xml | 12 +++++++++ .../kotlin/cli/CliTestGenerated.java | 12 +++++++++ .../integration/AntTaskTestGenerated.java | 6 +++++ .../compilerRunner/KotlinCompilerRunner.kt | 1 + 20 files changed, 128 insertions(+), 27 deletions(-) create mode 100644 compiler/testData/cli/jvm/noReflect.args create mode 100644 compiler/testData/cli/jvm/noReflect.kt create mode 100644 compiler/testData/cli/jvm/noReflect.out create mode 100644 compiler/testData/cli/jvm/noStdlib.args create mode 100644 compiler/testData/cli/jvm/noStdlib.kt create mode 100644 compiler/testData/cli/jvm/noStdlib.out create mode 100644 compiler/testData/integration/ant/jvm/noReflectForJavac/J.java create mode 100644 compiler/testData/integration/ant/jvm/noReflectForJavac/build.log.expected create mode 100644 compiler/testData/integration/ant/jvm/noReflectForJavac/build.xml diff --git a/ant/src/org/jetbrains/kotlin/ant/Kotlin2JvmTask.kt b/ant/src/org/jetbrains/kotlin/ant/Kotlin2JvmTask.kt index eb57107266d..aea749a85e8 100644 --- a/ant/src/org/jetbrains/kotlin/ant/Kotlin2JvmTask.kt +++ b/ant/src/org/jetbrains/kotlin/ant/Kotlin2JvmTask.kt @@ -26,6 +26,8 @@ class Kotlin2JvmTask : KotlinCompilerBaseTask() { var includeRuntime: Boolean = true var moduleName: String? = null + var noReflect: Boolean = false + private var compileClasspath: Path? = null fun setClasspath(classpath: Path) { @@ -68,6 +70,7 @@ class Kotlin2JvmTask : KotlinCompilerBaseTask() { } if (noStdlib) args.add("-no-stdlib") + if (noReflect) args.add("-no-reflect") if (includeRuntime) args.add("-include-runtime") } } diff --git a/ant/src/org/jetbrains/kotlin/ant/KotlinAntTaskUtil.kt b/ant/src/org/jetbrains/kotlin/ant/KotlinAntTaskUtil.kt index 31fe9dccebd..5cb8bb49991 100644 --- a/ant/src/org/jetbrains/kotlin/ant/KotlinAntTaskUtil.kt +++ b/ant/src/org/jetbrains/kotlin/ant/KotlinAntTaskUtil.kt @@ -24,7 +24,7 @@ import java.io.File import java.lang.ref.SoftReference import java.net.JarURLConnection -object KotlinAntTaskUtil { +internal object KotlinAntTaskUtil { private var classLoaderRef = SoftReference(null) private val libPath: File by lazy { @@ -37,19 +37,16 @@ object KotlinAntTaskUtil { antTaskJarPath.parentFile } - val compilerJar: File by lazy { - File(libPath, "kotlin-compiler.jar").assertExists() - } + val compilerJar: File by jar("kotlin-compiler.jar") + val runtimeJar: File by jar("kotlin-runtime.jar") + val reflectJar: File by jar("kotlin-reflect.jar") - val runtimeJar: File by lazy { - File(libPath, "kotlin-runtime.jar").assertExists() - } - - private fun File.assertExists(): File { - if (!this.exists()) { - throw IllegalStateException("${name} is not found in the directory of Kotlin Ant task") + private fun jar(name: String) = lazy { + File(libPath, name).apply { + if (!exists()) { + throw IllegalStateException("File is not found in the directory of Kotlin Ant task: $name") + } } - return this } @Synchronized @@ -65,8 +62,7 @@ object KotlinAntTaskUtil { return classLoader } - } -val Task.defaultModuleName: String? - get() = owningTarget?.name ?: project?.name \ No newline at end of file +internal val Task.defaultModuleName: String? + get() = owningTarget?.name ?: project?.name diff --git a/ant/src/org/jetbrains/kotlin/ant/KotlinCompilerAdapter.kt b/ant/src/org/jetbrains/kotlin/ant/KotlinCompilerAdapter.kt index fb0c4ac3f91..ccfc0bc4c30 100644 --- a/ant/src/org/jetbrains/kotlin/ant/KotlinCompilerAdapter.kt +++ b/ant/src/org/jetbrains/kotlin/ant/KotlinCompilerAdapter.kt @@ -31,6 +31,7 @@ class KotlinCompilerAdapter : Javac13() { var additionalArguments: MutableList = ArrayList(0) + @Suppress("unused") // Used via reflection by Ant fun createCompilerArg(): Commandline.Argument { val argument = Commandline.Argument() additionalArguments.add(argument) @@ -94,15 +95,22 @@ class KotlinCompilerAdapter : Javac13() { } private fun addRuntimeToJavacClasspath(kotlinc: Kotlin2JvmTask) { - for (arg in kotlinc.args) { - // If "-no-stdlib" was specified explicitly, probably the user also wanted the javac classpath to not have it - if ("-no-stdlib" == arg) return - } + // If "-no-stdlib" (or "-no-reflect") was specified explicitly, probably the user also wanted the javac classpath to not have it + val addStdlib = "-no-stdlib" !in kotlinc.args + val addReflect = "-no-reflect" !in kotlinc.args + + if (!addStdlib && !addReflect) return if (compileClasspath == null) { compileClasspath = Path(getProject()) } - compileClasspath.add(Path(getProject(), KotlinAntTaskUtil.runtimeJar.absolutePath)) + if (addStdlib) { + compileClasspath.add(Path(getProject(), KotlinAntTaskUtil.runtimeJar.absolutePath)) + } + // "-no-stdlib" implies "-no-reflect", see K2JVMCompiler.Companion.getClasspath + if (addReflect && addStdlib) { + compileClasspath.add(Path(getProject(), KotlinAntTaskUtil.reflectJar.absolutePath)) + } } private fun checkAntVersion() { diff --git a/build.xml b/build.xml index 110eea8a85b..744da7f008e 100644 --- a/build.xml +++ b/build.xml @@ -723,8 +723,6 @@ - - @@ -758,8 +756,6 @@ - - @@ -785,8 +781,6 @@ - - diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java index 442a8ba7df1..c94d93ac4c4 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java @@ -41,6 +41,9 @@ public class K2JVMCompilerArguments extends CommonCompilerArguments { @Argument(value = "no-stdlib", description = "Don't include Kotlin runtime into classpath") public boolean noStdlib; + @Argument(value = "no-reflect", description = "Don't include Kotlin reflection implementation into classpath") + public boolean noReflect; + @Argument(value = "module", description = "Path to the module file to compile") @ValueDescription("") public String module; 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 057c0fca1f5..5c24cf9b838 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt @@ -301,11 +301,16 @@ class K2JVMCompiler : CLICompiler() { private fun getClasspath(paths: KotlinPaths, arguments: K2JVMCompilerArguments): List { val classpath = arrayListOf() if (arguments.classpath != null) { - classpath.addAll(arguments.classpath.split(File.pathSeparatorChar).map { File(it) }) + classpath.addAll(arguments.classpath.split(File.pathSeparatorChar).map(::File)) } if (!arguments.noStdlib) { classpath.add(paths.runtimePath) } + // "-no-stdlib" implies "-no-reflect": otherwise we would be able to transitively read stdlib classes through kotlin-reflect, + // which is likely not what user wants since s/he manually provided "-no-stdlib" + if (!arguments.noReflect && !arguments.noStdlib) { + classpath.add(paths.reflectPath) + } return classpath } diff --git a/compiler/testData/cli/jvm/help.out b/compiler/testData/cli/jvm/help.out index d691eea5a4a..c4ca0745708 100644 --- a/compiler/testData/cli/jvm/help.out +++ b/compiler/testData/cli/jvm/help.out @@ -6,6 +6,7 @@ where possible options include: -jdk-home Path to JDK home directory to include into classpath, if differs from default JAVA_HOME -no-jdk Don't include Java runtime into classpath -no-stdlib Don't include Kotlin runtime into classpath + -no-reflect Don't include Kotlin reflection implementation into classpath -module Path to the module file to compile -script Evaluate the script file -kotlin-home Path to Kotlin compiler home directory, used for runtime libraries discovery diff --git a/compiler/testData/cli/jvm/noReflect.args b/compiler/testData/cli/jvm/noReflect.args new file mode 100644 index 00000000000..865ad5ff78a --- /dev/null +++ b/compiler/testData/cli/jvm/noReflect.args @@ -0,0 +1,4 @@ +-no-reflect +$TESTDATA_DIR$/noReflect.kt +-d +$TEMP_DIR$ diff --git a/compiler/testData/cli/jvm/noReflect.kt b/compiler/testData/cli/jvm/noReflect.kt new file mode 100644 index 00000000000..9204affe880 --- /dev/null +++ b/compiler/testData/cli/jvm/noReflect.kt @@ -0,0 +1,6 @@ +import kotlin.reflect.* + +fun foo() { + String::class.primaryConstructor + listOf(42) +} diff --git a/compiler/testData/cli/jvm/noReflect.out b/compiler/testData/cli/jvm/noReflect.out new file mode 100644 index 00000000000..c5e48a87981 --- /dev/null +++ b/compiler/testData/cli/jvm/noReflect.out @@ -0,0 +1,4 @@ +compiler/testData/cli/jvm/noReflect.kt:4:19: error: unresolved reference: primaryConstructor + String::class.primaryConstructor + ^ +COMPILATION_ERROR diff --git a/compiler/testData/cli/jvm/noStdlib.args b/compiler/testData/cli/jvm/noStdlib.args new file mode 100644 index 00000000000..a42ece542eb --- /dev/null +++ b/compiler/testData/cli/jvm/noStdlib.args @@ -0,0 +1,4 @@ +-no-stdlib +$TESTDATA_DIR$/noStdlib.kt +-d +$TEMP_DIR$ diff --git a/compiler/testData/cli/jvm/noStdlib.kt b/compiler/testData/cli/jvm/noStdlib.kt new file mode 100644 index 00000000000..9204affe880 --- /dev/null +++ b/compiler/testData/cli/jvm/noStdlib.kt @@ -0,0 +1,6 @@ +import kotlin.reflect.* + +fun foo() { + String::class.primaryConstructor + listOf(42) +} diff --git a/compiler/testData/cli/jvm/noStdlib.out b/compiler/testData/cli/jvm/noStdlib.out new file mode 100644 index 00000000000..fc650a495cc --- /dev/null +++ b/compiler/testData/cli/jvm/noStdlib.out @@ -0,0 +1,7 @@ +compiler/testData/cli/jvm/noStdlib.kt:4:19: error: unresolved reference: primaryConstructor + String::class.primaryConstructor + ^ +compiler/testData/cli/jvm/noStdlib.kt:5:5: error: unresolved reference: listOf + listOf(42) + ^ +COMPILATION_ERROR diff --git a/compiler/testData/cli/jvm/wrongArgument.out b/compiler/testData/cli/jvm/wrongArgument.out index da2021e5faf..047fea73f74 100644 --- a/compiler/testData/cli/jvm/wrongArgument.out +++ b/compiler/testData/cli/jvm/wrongArgument.out @@ -7,6 +7,7 @@ where possible options include: -jdk-home Path to JDK home directory to include into classpath, if differs from default JAVA_HOME -no-jdk Don't include Java runtime into classpath -no-stdlib Don't include Kotlin runtime into classpath + -no-reflect Don't include Kotlin reflection implementation into classpath -module Path to the module file to compile -script Evaluate the script file -kotlin-home Path to Kotlin compiler home directory, used for runtime libraries discovery diff --git a/compiler/testData/integration/ant/jvm/noReflectForJavac/J.java b/compiler/testData/integration/ant/jvm/noReflectForJavac/J.java new file mode 100644 index 00000000000..c5c341731e8 --- /dev/null +++ b/compiler/testData/integration/ant/jvm/noReflectForJavac/J.java @@ -0,0 +1,6 @@ +package test; + +import kotlin.reflect.KClassesKt; +import kotlin.Unit; + +public class J {} diff --git a/compiler/testData/integration/ant/jvm/noReflectForJavac/build.log.expected b/compiler/testData/integration/ant/jvm/noReflectForJavac/build.log.expected new file mode 100644 index 00000000000..c6a3d33f733 --- /dev/null +++ b/compiler/testData/integration/ant/jvm/noReflectForJavac/build.log.expected @@ -0,0 +1,22 @@ +OUT: +Buildfile: [TestData]/build.xml + +build: + [mkdir] Created dir: [Temp]/classes + [javac] Compiling 1 source file to [Temp]/classes + [javac] Running javac... + [javac] [TestData]/J.java:3: cannot find symbol + [javac] symbol : class KClassesKt + [javac] location: package kotlin.reflect + [javac] import kotlin.reflect.KClassesKt; + [javac] ^ + [javac] 1 error + +ERR: + +BUILD FAILED +[TestData]/build.xml:6: Compile failed; see the compiler error output for details. + +Total time: [time] + +Return code: 1 diff --git a/compiler/testData/integration/ant/jvm/noReflectForJavac/build.xml b/compiler/testData/integration/ant/jvm/noReflectForJavac/build.xml new file mode 100644 index 00000000000..9f64d599772 --- /dev/null +++ b/compiler/testData/integration/ant/jvm/noReflectForJavac/build.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java index 55dfc8f2f84..6290eded415 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java @@ -169,6 +169,18 @@ public class CliTestGenerated extends AbstractCliTest { doJvmTest(fileName); } + @TestMetadata("noReflect.args") + public void testNoReflect() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/noReflect.args"); + doJvmTest(fileName); + } + + @TestMetadata("noStdlib.args") + public void testNoStdlib() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/noStdlib.args"); + doJvmTest(fileName); + } + @TestMetadata("nonExistingClassPathAndAnnotationsPath.args") public void testNonExistingClassPathAndAnnotationsPath() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/nonExistingClassPathAndAnnotationsPath.args"); diff --git a/compiler/tests/org/jetbrains/kotlin/integration/AntTaskTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/integration/AntTaskTestGenerated.java index e38256eb99b..40db17f1fd6 100644 --- a/compiler/tests/org/jetbrains/kotlin/integration/AntTaskTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/integration/AntTaskTestGenerated.java @@ -107,6 +107,12 @@ public class AntTaskTestGenerated extends AbstractAntTaskTest { doTest(fileName); } + @TestMetadata("noReflectForJavac") + public void testNoReflectForJavac() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/integration/ant/jvm/noReflectForJavac/"); + doTest(fileName); + } + @TestMetadata("noStdlibForJavac") public void testNoStdlibForJavac() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/integration/ant/jvm/noStdlibForJavac/"); diff --git a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt index a65d1cdeee1..6a27f7074b3 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt @@ -289,6 +289,7 @@ object KotlinCompilerRunner { with(settings) { module = moduleFile.absolutePath noStdlib = true + noReflect = true noJdk = true } }