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

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

 #KT-13237 Fixed
This commit is contained in:
Alexander Udalov
2015-10-31 15:02:55 +03:00
parent 30fd22499b
commit 0d26087040
20 changed files with 128 additions and 27 deletions
@@ -26,6 +26,8 @@ class Kotlin2JvmTask : KotlinCompilerBaseTask() {
var includeRuntime: Boolean = true var includeRuntime: Boolean = true
var moduleName: String? = null var moduleName: String? = null
var noReflect: Boolean = false
private var compileClasspath: Path? = null private var compileClasspath: Path? = null
fun setClasspath(classpath: Path) { fun setClasspath(classpath: Path) {
@@ -68,6 +70,7 @@ class Kotlin2JvmTask : KotlinCompilerBaseTask() {
} }
if (noStdlib) args.add("-no-stdlib") if (noStdlib) args.add("-no-stdlib")
if (noReflect) args.add("-no-reflect")
if (includeRuntime) args.add("-include-runtime") if (includeRuntime) args.add("-include-runtime")
} }
} }
@@ -24,7 +24,7 @@ import java.io.File
import java.lang.ref.SoftReference import java.lang.ref.SoftReference
import java.net.JarURLConnection import java.net.JarURLConnection
object KotlinAntTaskUtil { internal object KotlinAntTaskUtil {
private var classLoaderRef = SoftReference<ClassLoader?>(null) private var classLoaderRef = SoftReference<ClassLoader?>(null)
private val libPath: File by lazy { private val libPath: File by lazy {
@@ -37,19 +37,16 @@ object KotlinAntTaskUtil {
antTaskJarPath.parentFile antTaskJarPath.parentFile
} }
val compilerJar: File by lazy { val compilerJar: File by jar("kotlin-compiler.jar")
File(libPath, "kotlin-compiler.jar").assertExists() val runtimeJar: File by jar("kotlin-runtime.jar")
} val reflectJar: File by jar("kotlin-reflect.jar")
val runtimeJar: File by lazy { private fun jar(name: String) = lazy {
File(libPath, "kotlin-runtime.jar").assertExists() File(libPath, name).apply {
} if (!exists()) {
throw IllegalStateException("File is not found in the directory of Kotlin Ant task: $name")
private fun File.assertExists(): File { }
if (!this.exists()) {
throw IllegalStateException("${name} is not found in the directory of Kotlin Ant task")
} }
return this
} }
@Synchronized @Synchronized
@@ -65,8 +62,7 @@ object KotlinAntTaskUtil {
return classLoader return classLoader
} }
} }
val Task.defaultModuleName: String? internal val Task.defaultModuleName: String?
get() = owningTarget?.name ?: project?.name get() = owningTarget?.name ?: project?.name
@@ -31,6 +31,7 @@ class KotlinCompilerAdapter : Javac13() {
var additionalArguments: MutableList<Commandline.Argument> = ArrayList(0) var additionalArguments: MutableList<Commandline.Argument> = ArrayList(0)
@Suppress("unused") // Used via reflection by Ant
fun createCompilerArg(): Commandline.Argument { fun createCompilerArg(): Commandline.Argument {
val argument = Commandline.Argument() val argument = Commandline.Argument()
additionalArguments.add(argument) additionalArguments.add(argument)
@@ -94,15 +95,22 @@ class KotlinCompilerAdapter : Javac13() {
} }
private fun addRuntimeToJavacClasspath(kotlinc: Kotlin2JvmTask) { private fun addRuntimeToJavacClasspath(kotlinc: Kotlin2JvmTask) {
for (arg in kotlinc.args) { // If "-no-stdlib" (or "-no-reflect") was specified explicitly, probably the user also wanted the javac classpath to not have it
// If "-no-stdlib" was specified explicitly, probably the user also wanted the javac classpath to not have it val addStdlib = "-no-stdlib" !in kotlinc.args
if ("-no-stdlib" == arg) return val addReflect = "-no-reflect" !in kotlinc.args
}
if (!addStdlib && !addReflect) return
if (compileClasspath == null) { if (compileClasspath == null) {
compileClasspath = Path(getProject()) 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() { private fun checkAntVersion() {
-6
View File
@@ -723,8 +723,6 @@
<pathelement path="compiler/daemon/daemon-client/src"/> <pathelement path="compiler/daemon/daemon-client/src"/>
</src> </src>
<classpath> <classpath>
<pathelement path="${bootstrap.runtime}"/>
<pathelement path="${bootstrap.reflect}"/>
<pathelement path="${kotlin-home}/lib/kotlin-compiler.jar"/> <pathelement path="${kotlin-home}/lib/kotlin-compiler.jar"/>
<pathelement path="${dependencies.dir}/native-platform-uberjar.jar"/> <pathelement path="${dependencies.dir}/native-platform-uberjar.jar"/>
</classpath> </classpath>
@@ -758,8 +756,6 @@
<classpath> <classpath>
<pathelement path="${idea.sdk}/core/intellij-core.jar"/> <pathelement path="${idea.sdk}/core/intellij-core.jar"/>
<pathelement path="${kotlin-home}/lib/kotlin-compiler.jar"/> <pathelement path="${kotlin-home}/lib/kotlin-compiler.jar"/>
<pathelement path="${bootstrap.runtime}"/>
<pathelement path="${bootstrap.reflect}"/>
</classpath> </classpath>
</javac2> </javac2>
@@ -785,8 +781,6 @@
</src> </src>
<compilerarg value="-Xlint:all"/> <compilerarg value="-Xlint:all"/>
<classpath> <classpath>
<file file="${bootstrap.runtime}"/>
<file file="${bootstrap.reflect}"/>
<pathelement location="${dependencies.dir}/ant-1.8/lib/ant.jar"/> <pathelement location="${dependencies.dir}/ant-1.8/lib/ant.jar"/>
<pathelement location="${kotlin-home}/lib/kotlin-preloader.jar"/> <pathelement location="${kotlin-home}/lib/kotlin-preloader.jar"/>
</classpath> </classpath>
@@ -41,6 +41,9 @@ public class K2JVMCompilerArguments extends CommonCompilerArguments {
@Argument(value = "no-stdlib", description = "Don't include Kotlin runtime into classpath") @Argument(value = "no-stdlib", description = "Don't include Kotlin runtime into classpath")
public boolean noStdlib; 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") @Argument(value = "module", description = "Path to the module file to compile")
@ValueDescription("<path>") @ValueDescription("<path>")
public String module; public String module;
@@ -301,11 +301,16 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
private fun getClasspath(paths: KotlinPaths, arguments: K2JVMCompilerArguments): List<File> { private fun getClasspath(paths: KotlinPaths, arguments: K2JVMCompilerArguments): List<File> {
val classpath = arrayListOf<File>() val classpath = arrayListOf<File>()
if (arguments.classpath != null) { 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) { if (!arguments.noStdlib) {
classpath.add(paths.runtimePath) 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 return classpath
} }
+1
View File
@@ -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 -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-jdk Don't include Java runtime into classpath
-no-stdlib Don't include Kotlin 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 -module <path> Path to the module file to compile
-script Evaluate the script file -script Evaluate the script file
-kotlin-home <path> Path to Kotlin compiler home directory, used for runtime libraries discovery -kotlin-home <path> Path to Kotlin compiler home directory, used for runtime libraries discovery
+4
View File
@@ -0,0 +1,4 @@
-no-reflect
$TESTDATA_DIR$/noReflect.kt
-d
$TEMP_DIR$
+6
View File
@@ -0,0 +1,6 @@
import kotlin.reflect.*
fun foo() {
String::class.primaryConstructor
listOf(42)
}
+4
View File
@@ -0,0 +1,4 @@
compiler/testData/cli/jvm/noReflect.kt:4:19: error: unresolved reference: primaryConstructor
String::class.primaryConstructor
^
COMPILATION_ERROR
+4
View File
@@ -0,0 +1,4 @@
-no-stdlib
$TESTDATA_DIR$/noStdlib.kt
-d
$TEMP_DIR$
+6
View File
@@ -0,0 +1,6 @@
import kotlin.reflect.*
fun foo() {
String::class.primaryConstructor
listOf(42)
}
+7
View File
@@ -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
+1
View File
@@ -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 -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-jdk Don't include Java runtime into classpath
-no-stdlib Don't include Kotlin 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 -module <path> Path to the module file to compile
-script Evaluate the script file -script Evaluate the script file
-kotlin-home <path> Path to Kotlin compiler home directory, used for runtime libraries discovery -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 class CliTestGenerated extends AbstractCliTest {
doJvmTest(fileName); 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") @TestMetadata("nonExistingClassPathAndAnnotationsPath.args")
public void testNonExistingClassPathAndAnnotationsPath() throws Exception { public void testNonExistingClassPathAndAnnotationsPath() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/nonExistingClassPathAndAnnotationsPath.args"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/nonExistingClassPathAndAnnotationsPath.args");
@@ -107,6 +107,12 @@ public class AntTaskTestGenerated extends AbstractAntTaskTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("noReflectForJavac")
public void testNoReflectForJavac() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/integration/ant/jvm/noReflectForJavac/");
doTest(fileName);
}
@TestMetadata("noStdlibForJavac") @TestMetadata("noStdlibForJavac")
public void testNoStdlibForJavac() throws Exception { public void testNoStdlibForJavac() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/integration/ant/jvm/noStdlibForJavac/"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/integration/ant/jvm/noStdlibForJavac/");
@@ -289,6 +289,7 @@ object KotlinCompilerRunner {
with(settings) { with(settings) {
module = moduleFile.absolutePath module = moduleFile.absolutePath
noStdlib = true noStdlib = true
noReflect = true
noJdk = true noJdk = true
} }
} }