Permalink
Browse files

CLI, Ant: add kotlin-reflect.jar to classpath by default, support "-n…

…o-reflect"

Note that now "-no-stdlib" implies "-no-reflect".

 #KT-13237 Fixed
  • Loading branch information...
1 parent 30fd224 commit 0d26087040b94acfff0434d1a12a2975ee8accd8 @udalov udalov committed Oct 31, 2015
@@ -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")
}
}
@@ -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<ClassLoader?>(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 runtimeJar: File by lazy {
- File(libPath, "kotlin-runtime.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")
- 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
+internal val Task.defaultModuleName: String?
+ get() = owningTarget?.name ?: project?.name
@@ -31,6 +31,7 @@ class KotlinCompilerAdapter : Javac13() {
var additionalArguments: MutableList<Commandline.Argument> = 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() {
View
@@ -723,8 +723,6 @@
<pathelement path="compiler/daemon/daemon-client/src"/>
</src>
<classpath>
- <pathelement path="${bootstrap.runtime}"/>
- <pathelement path="${bootstrap.reflect}"/>
<pathelement path="${kotlin-home}/lib/kotlin-compiler.jar"/>
<pathelement path="${dependencies.dir}/native-platform-uberjar.jar"/>
</classpath>
@@ -758,8 +756,6 @@
<classpath>
<pathelement path="${idea.sdk}/core/intellij-core.jar"/>
<pathelement path="${kotlin-home}/lib/kotlin-compiler.jar"/>
- <pathelement path="${bootstrap.runtime}"/>
- <pathelement path="${bootstrap.reflect}"/>
</classpath>
</javac2>
@@ -785,8 +781,6 @@
</src>
<compilerarg value="-Xlint:all"/>
<classpath>
- <file file="${bootstrap.runtime}"/>
- <file file="${bootstrap.reflect}"/>
<pathelement location="${dependencies.dir}/ant-1.8/lib/ant.jar"/>
<pathelement location="${kotlin-home}/lib/kotlin-preloader.jar"/>
</classpath>
@@ -41,6 +41,9 @@
@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("<path>")
public String module;
@@ -301,11 +301,16 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
private fun getClasspath(paths: KotlinPaths, arguments: K2JVMCompilerArguments): List<File> {
val classpath = arrayListOf<File>()
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
}
@@ -6,6 +6,7 @@ where possible options include:
-jdk-home <path> 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> Path to the module file to compile
-script Evaluate the script file
-kotlin-home <path> Path to Kotlin compiler home directory, used for runtime libraries discovery
@@ -0,0 +1,4 @@
+-no-reflect
+$TESTDATA_DIR$/noReflect.kt
+-d
+$TEMP_DIR$
@@ -0,0 +1,6 @@
+import kotlin.reflect.*
+
+fun foo() {
+ String::class.primaryConstructor
+ listOf(42)
+}
@@ -0,0 +1,4 @@
+compiler/testData/cli/jvm/noReflect.kt:4:19: error: unresolved reference: primaryConstructor
+ String::class.primaryConstructor
+ ^
+COMPILATION_ERROR
@@ -0,0 +1,4 @@
+-no-stdlib
+$TESTDATA_DIR$/noStdlib.kt
+-d
+$TEMP_DIR$
@@ -0,0 +1,6 @@
+import kotlin.reflect.*
+
+fun foo() {
+ String::class.primaryConstructor
+ listOf(42)
+}
@@ -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
@@ -7,6 +7,7 @@ where possible options include:
-jdk-home <path> 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> Path to the module file to compile
-script Evaluate the script file
-kotlin-home <path> Path to Kotlin compiler home directory, used for runtime libraries discovery
@@ -0,0 +1,6 @@
+package test;
+
+import kotlin.reflect.KClassesKt;
+import kotlin.Unit;
+
+public class J {}
@@ -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
@@ -0,0 +1,12 @@
+<project name="Ant Task Test" default="build">
+ <taskdef resource="org/jetbrains/kotlin/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
+
+ <target name="build">
+ <mkdir dir="${temp}/classes"/>
+ <javac srcdir="${test.data}" destdir="${temp}/classes" includeantruntime="false">
+ <withKotlin>
+ <compilerarg value="-no-reflect"/>
+ </withKotlin>
+ </javac>
+ </target>
+</project>
@@ -169,6 +169,18 @@ public void testMultipleTextRangesInDiagnosticsOrder() throws Exception {
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");
@@ -107,6 +107,12 @@ public void testModuleNameWithKotlin() throws Exception {
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/");
@@ -289,6 +289,7 @@ object KotlinCompilerRunner {
with(settings) {
module = moduleFile.absolutePath
noStdlib = true
+ noReflect = true
noJdk = true
}
}

0 comments on commit 0d26087

Please sign in to comment.