From 834bb5164349cc8bc1225c8fb9dbdb7af61766f8 Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Thu, 7 Apr 2016 17:08:28 +0200 Subject: [PATCH] Add tests with partial classpath for script compilation --- compiler/testData/script/fib_ext.kts | 16 ++++++++ .../kotlin/scripts/TestScriptDefinitions.kt | 40 ++++++++++++++++--- .../jetbrains/kotlin/scripts/ScriptTest.kt | 37 +++++++++-------- 3 files changed, 68 insertions(+), 25 deletions(-) create mode 100644 compiler/testData/script/fib_ext.kts diff --git a/compiler/testData/script/fib_ext.kts b/compiler/testData/script/fib_ext.kts new file mode 100644 index 00000000000..31ee5058bd3 --- /dev/null +++ b/compiler/testData/script/fib_ext.kts @@ -0,0 +1,16 @@ + +// this script expected parameter num : Int + +fun fib(n: Int): Int { + val v = if(n < 2) 1 else fib(n-1) + fib(n-2) + System.out.println("fib($n)=$v") + return v +} + +val hdr = "Num".decapitalize() + +org.junit.Assert.assertTrue(false) + +System.out.println("$hdr: $num") +val result = fib(num) + diff --git a/compiler/tests-common/org/jetbrains/kotlin/scripts/TestScriptDefinitions.kt b/compiler/tests-common/org/jetbrains/kotlin/scripts/TestScriptDefinitions.kt index 51df406ebd6..d0e97388e50 100644 --- a/compiler/tests-common/org/jetbrains/kotlin/scripts/TestScriptDefinitions.kt +++ b/compiler/tests-common/org/jetbrains/kotlin/scripts/TestScriptDefinitions.kt @@ -22,31 +22,59 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtScript import org.jetbrains.kotlin.script.* import org.jetbrains.kotlin.types.KotlinType +import java.io.File +import java.net.URLClassLoader import kotlin.reflect.KClass -abstract class BaseScriptDefinition (val extension: String) : KotlinScriptDefinition { +abstract class BaseScriptDefinition (val extension: String, val classpath: List? = null) : KotlinScriptDefinition { override val name = "Test Kotlin Script" override fun isScript(file: VirtualFile): Boolean = file.name.endsWith(extension) override fun getScriptName(script: KtScript): Name = ScriptNameUtil.fileNameWithExtensionStripped(script, extension) + override fun getScriptDependenciesClasspath(): List = + classpath ?: (classpathFromProperty() + classpathFromClassloader(BaseScriptDefinition::class.java.classLoader)).distinct() } -open class SimpleParamsTestScriptDefinition(extension: String, val parameters: List) : BaseScriptDefinition(extension) { +open class SimpleParamsWithClasspathTestScriptDefinition(extension: String, val parameters: List, classpath: List? = null) + : BaseScriptDefinition(extension, classpath) +{ override fun getScriptParameters(scriptDescriptor: ScriptDescriptor) = parameters } -class ReflectedParamClassTestScriptDefinition(extension: String, val paramName: String, val parameter: KClass) : BaseScriptDefinition(extension) { +open class SimpleParamsTestScriptDefinition(extension: String, parameters: List) : SimpleParamsWithClasspathTestScriptDefinition(extension, parameters) + +class ReflectedParamClassTestScriptDefinition(extension: String, val paramName: String, val parameter: KClass, classpath: List? = null) + : BaseScriptDefinition(extension, classpath) +{ override fun getScriptParameters(scriptDescriptor: ScriptDescriptor) = listOf(makeReflectedClassScriptParameter(scriptDescriptor, Name.identifier(paramName), parameter)) } -open class ReflectedSuperclassTestScriptDefinition(extension: String, parameters: List, val superclass: KClass) : SimpleParamsTestScriptDefinition(extension, parameters) { +open class ReflectedSuperclassTestScriptDefinition(extension: String, parameters: List, val superclass: KClass, classpath: List? = null) + : SimpleParamsWithClasspathTestScriptDefinition(extension, parameters, classpath) +{ override fun getScriptSupertypes(scriptDescriptor: ScriptDescriptor): List = listOf(getKotlinType(scriptDescriptor, superclass)) } -class ReflectedSuperclassWithParamsTestScriptDefinition(extension: String, parameters: List, superclass: KClass, val superclassParameters: List) - : ReflectedSuperclassTestScriptDefinition(extension, parameters, superclass) +class ReflectedSuperclassWithParamsTestScriptDefinition(extension: String, + parameters: List, + superclass: KClass, + val superclassParameters: List, + classpath: List? = null) + : ReflectedSuperclassTestScriptDefinition(extension, parameters, superclass, classpath) { override fun getScriptParametersToPassToSuperclass(scriptDescriptor: ScriptDescriptor): List = superclassParameters.map { it.name } } + +fun classpathFromProperty(): List = + System.getProperty("java.class.path")?.let { + it.split(String.format("\\%s", File.pathSeparatorChar).toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + .map { File(it).canonicalPath } + } ?: emptyList() + +fun classpathFromClassloader(classLoader: ClassLoader): List = + (classLoader as? URLClassLoader)?.urLs + ?.map { File(it.toURI()).canonicalPath } + ?: emptyList() + diff --git a/compiler/tests/org/jetbrains/kotlin/scripts/ScriptTest.kt b/compiler/tests/org/jetbrains/kotlin/scripts/ScriptTest.kt index ed1456489b2..d440b706b17 100644 --- a/compiler/tests/org/jetbrains/kotlin/scripts/ScriptTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/scripts/ScriptTest.kt @@ -38,8 +38,6 @@ import org.jetbrains.kotlin.utils.PathUtil import org.junit.Assert import org.junit.Test import java.io.File -import java.net.URLClassLoader -import java.util.* class ScriptTest { @Test @@ -94,13 +92,28 @@ class ScriptTest { aClass!!.getConstructor(Integer.TYPE).newInstance(4) } + @Test + fun testScriptWithClasspath() { + val aClass1 = compileScript("fib_ext.kts", SimpleParamsWithClasspathTestScriptDefinition(".kts", numIntParam(), classpath = emptyList()), runIsolated = true, suppressOutput = true) + Assert.assertNull(aClass1) + + val cp = classpathFromClassloader(ScriptTest::class.java.classLoader).filter { it.contains("kotlin-runtime") || it.contains("junit") } + Assert.assertFalse(cp.isEmpty()) + + val aClass2 = compileScript("fib_ext.kts", SimpleParamsWithClasspathTestScriptDefinition(".kts", numIntParam(), classpath = cp), runIsolated = true) + Assert.assertNotNull(aClass2) + } + private fun compileScript( scriptPath: String, scriptDefinition: KotlinScriptDefinition, - runIsolated: Boolean = true): Class<*>? + runIsolated: Boolean = true, + suppressOutput: Boolean = false): Class<*>? { val paths = PathUtil.getKotlinPathsForDistDirectory() - val messageCollector = PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, false) + val messageCollector = + if (suppressOutput) MessageCollector.NONE + else PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, false) val rootDisposable = Disposer.newDisposable() try { @@ -108,8 +121,7 @@ class ScriptTest { configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector) configuration.addKotlinSourceRoot("compiler/testData/script/" + scriptPath) configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, scriptDefinition) - if (!runIsolated) - configuration.addCurrentClasspathAsRoots() + scriptDefinition.getScriptDependenciesClasspath().forEach { configuration.addJvmClasspathRoot(File(it)) } val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) @@ -133,19 +145,6 @@ class ScriptTest { } } - private fun CompilerConfiguration.addCurrentClasspathAsRoots() { - - val cp: MutableSet = System.getProperty("java.class.path")?.let { - it.split(String.format("\\%s", File.pathSeparatorChar).toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() - .map { File(it).canonicalFile }.toMutableSet() - } ?: LinkedHashSet() - (this.javaClass.classLoader as? URLClassLoader)?.urLs - ?.map { File(it.toURI()).canonicalFile } - ?.filter { it.exists() } - ?.forEach { cp.add(it) } - cp.forEach { addJvmClasspathRoot(it) } - } - private fun numIntParam(name: String = "num"): List { return listOf(ScriptParameter(Name.identifier(name), DefaultBuiltIns.Instance.intType)) }