Add tests with partial classpath for script compilation
This commit is contained in:
Vendored
+16
@@ -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)
|
||||||
|
|
||||||
@@ -22,31 +22,59 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.psi.KtScript
|
import org.jetbrains.kotlin.psi.KtScript
|
||||||
import org.jetbrains.kotlin.script.*
|
import org.jetbrains.kotlin.script.*
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import java.io.File
|
||||||
|
import java.net.URLClassLoader
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
abstract class BaseScriptDefinition (val extension: String) : KotlinScriptDefinition {
|
abstract class BaseScriptDefinition (val extension: String, val classpath: List<String>? = null) : KotlinScriptDefinition {
|
||||||
override val name = "Test Kotlin Script"
|
override val name = "Test Kotlin Script"
|
||||||
override fun isScript(file: VirtualFile): Boolean = file.name.endsWith(extension)
|
override fun isScript(file: VirtualFile): Boolean = file.name.endsWith(extension)
|
||||||
override fun getScriptName(script: KtScript): Name = ScriptNameUtil.fileNameWithExtensionStripped(script, extension)
|
override fun getScriptName(script: KtScript): Name = ScriptNameUtil.fileNameWithExtensionStripped(script, extension)
|
||||||
|
override fun getScriptDependenciesClasspath(): List<String> =
|
||||||
|
classpath ?: (classpathFromProperty() + classpathFromClassloader(BaseScriptDefinition::class.java.classLoader)).distinct()
|
||||||
}
|
}
|
||||||
|
|
||||||
open class SimpleParamsTestScriptDefinition(extension: String, val parameters: List<ScriptParameter>) : BaseScriptDefinition(extension) {
|
open class SimpleParamsWithClasspathTestScriptDefinition(extension: String, val parameters: List<ScriptParameter>, classpath: List<String>? = null)
|
||||||
|
: BaseScriptDefinition(extension, classpath)
|
||||||
|
{
|
||||||
override fun getScriptParameters(scriptDescriptor: ScriptDescriptor) = parameters
|
override fun getScriptParameters(scriptDescriptor: ScriptDescriptor) = parameters
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReflectedParamClassTestScriptDefinition(extension: String, val paramName: String, val parameter: KClass<out Any>) : BaseScriptDefinition(extension) {
|
open class SimpleParamsTestScriptDefinition(extension: String, parameters: List<ScriptParameter>) : SimpleParamsWithClasspathTestScriptDefinition(extension, parameters)
|
||||||
|
|
||||||
|
class ReflectedParamClassTestScriptDefinition(extension: String, val paramName: String, val parameter: KClass<out Any>, classpath: List<String>? = null)
|
||||||
|
: BaseScriptDefinition(extension, classpath)
|
||||||
|
{
|
||||||
override fun getScriptParameters(scriptDescriptor: ScriptDescriptor) =
|
override fun getScriptParameters(scriptDescriptor: ScriptDescriptor) =
|
||||||
listOf(makeReflectedClassScriptParameter(scriptDescriptor, Name.identifier(paramName), parameter))
|
listOf(makeReflectedClassScriptParameter(scriptDescriptor, Name.identifier(paramName), parameter))
|
||||||
}
|
}
|
||||||
|
|
||||||
open class ReflectedSuperclassTestScriptDefinition(extension: String, parameters: List<ScriptParameter>, val superclass: KClass<out Any>) : SimpleParamsTestScriptDefinition(extension, parameters) {
|
open class ReflectedSuperclassTestScriptDefinition(extension: String, parameters: List<ScriptParameter>, val superclass: KClass<out Any>, classpath: List<String>? = null)
|
||||||
|
: SimpleParamsWithClasspathTestScriptDefinition(extension, parameters, classpath)
|
||||||
|
{
|
||||||
override fun getScriptSupertypes(scriptDescriptor: ScriptDescriptor): List<KotlinType> =
|
override fun getScriptSupertypes(scriptDescriptor: ScriptDescriptor): List<KotlinType> =
|
||||||
listOf(getKotlinType(scriptDescriptor, superclass))
|
listOf(getKotlinType(scriptDescriptor, superclass))
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReflectedSuperclassWithParamsTestScriptDefinition(extension: String, parameters: List<ScriptParameter>, superclass: KClass<out Any>, val superclassParameters: List<ScriptParameter>)
|
class ReflectedSuperclassWithParamsTestScriptDefinition(extension: String,
|
||||||
: ReflectedSuperclassTestScriptDefinition(extension, parameters, superclass)
|
parameters: List<ScriptParameter>,
|
||||||
|
superclass: KClass<out Any>,
|
||||||
|
val superclassParameters: List<ScriptParameter>,
|
||||||
|
classpath: List<String>? = null)
|
||||||
|
: ReflectedSuperclassTestScriptDefinition(extension, parameters, superclass, classpath)
|
||||||
{
|
{
|
||||||
override fun getScriptParametersToPassToSuperclass(scriptDescriptor: ScriptDescriptor): List<Name> =
|
override fun getScriptParametersToPassToSuperclass(scriptDescriptor: ScriptDescriptor): List<Name> =
|
||||||
superclassParameters.map { it.name }
|
superclassParameters.map { it.name }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun classpathFromProperty(): List<String> =
|
||||||
|
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<String> =
|
||||||
|
(classLoader as? URLClassLoader)?.urLs
|
||||||
|
?.map { File(it.toURI()).canonicalPath }
|
||||||
|
?: emptyList()
|
||||||
|
|
||||||
|
|||||||
@@ -38,8 +38,6 @@ import org.jetbrains.kotlin.utils.PathUtil
|
|||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URLClassLoader
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class ScriptTest {
|
class ScriptTest {
|
||||||
@Test
|
@Test
|
||||||
@@ -94,13 +92,28 @@ class ScriptTest {
|
|||||||
aClass!!.getConstructor(Integer.TYPE).newInstance(4)
|
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(
|
private fun compileScript(
|
||||||
scriptPath: String,
|
scriptPath: String,
|
||||||
scriptDefinition: KotlinScriptDefinition,
|
scriptDefinition: KotlinScriptDefinition,
|
||||||
runIsolated: Boolean = true): Class<*>?
|
runIsolated: Boolean = true,
|
||||||
|
suppressOutput: Boolean = false): Class<*>?
|
||||||
{
|
{
|
||||||
val paths = PathUtil.getKotlinPathsForDistDirectory()
|
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()
|
val rootDisposable = Disposer.newDisposable()
|
||||||
try {
|
try {
|
||||||
@@ -108,8 +121,7 @@ class ScriptTest {
|
|||||||
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
|
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
|
||||||
configuration.addKotlinSourceRoot("compiler/testData/script/" + scriptPath)
|
configuration.addKotlinSourceRoot("compiler/testData/script/" + scriptPath)
|
||||||
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, scriptDefinition)
|
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, scriptDefinition)
|
||||||
if (!runIsolated)
|
scriptDefinition.getScriptDependenciesClasspath().forEach { configuration.addJvmClasspathRoot(File(it)) }
|
||||||
configuration.addCurrentClasspathAsRoots()
|
|
||||||
|
|
||||||
val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
||||||
|
|
||||||
@@ -133,19 +145,6 @@ class ScriptTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CompilerConfiguration.addCurrentClasspathAsRoots() {
|
|
||||||
|
|
||||||
val cp: MutableSet<File> = System.getProperty("java.class.path")?.let {
|
|
||||||
it.split(String.format("\\%s", File.pathSeparatorChar).toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
|
||||||
.map { File(it).canonicalFile }.toMutableSet()
|
|
||||||
} ?: LinkedHashSet<File>()
|
|
||||||
(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<ScriptParameter> {
|
private fun numIntParam(name: String = "num"): List<ScriptParameter> {
|
||||||
return listOf(ScriptParameter(Name.identifier(name), DefaultBuiltIns.Instance.intType))
|
return listOf(ScriptParameter(Name.identifier(name), DefaultBuiltIns.Instance.intType))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user