Refactor script definitions and resolving/refining infrastructure:
- implement wrappers to wrap old and new API providers and resolvers - make old API deprecated (with error where possible) - drop old internal classes related to the old API - refactor usages accordingly - fix and add missing features to the scripting API where necessary
This commit is contained in:
@@ -76,6 +76,10 @@ sealed class ResultWithDiagnostics<out R> {
|
||||
) : ResultWithDiagnostics<Nothing>() {
|
||||
constructor(vararg reports: ScriptDiagnostic) : this(reports.asList())
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean = this === other || (other is ResultWithDiagnostics<*> && this.reports == other.reports)
|
||||
|
||||
override fun hashCode(): Int = reports.hashCode()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,9 +166,10 @@ fun makeFailureResult(message: String, path: String? = null, location: SourceCod
|
||||
fun Throwable.asDiagnostics(
|
||||
customMessage: String? = null,
|
||||
path: String? = null,
|
||||
location: SourceCode.Location? = null
|
||||
location: SourceCode.Location? = null,
|
||||
severity: ScriptDiagnostic.Severity = ScriptDiagnostic.Severity.ERROR
|
||||
): ScriptDiagnostic =
|
||||
ScriptDiagnostic(customMessage ?: message ?: "$this", ScriptDiagnostic.Severity.ERROR, path, location, this)
|
||||
ScriptDiagnostic(customMessage ?: message ?: "$this", severity, path, location, this)
|
||||
|
||||
/**
|
||||
* Converts the receiver String to error diagnostic report with optional [path] and [location]
|
||||
@@ -175,7 +180,7 @@ fun String.asErrorDiagnostics(path: String? = null, location: SourceCode.Locatio
|
||||
/**
|
||||
* Extracts the result value from the receiver wrapper or null if receiver represents a Failure
|
||||
*/
|
||||
fun <R> ResultWithDiagnostics<R>.resultOrNull(): R? = when (this) {
|
||||
fun <R> ResultWithDiagnostics<R>.valueOrNull(): R? = when (this) {
|
||||
is ResultWithDiagnostics.Success<R> -> value
|
||||
else -> null
|
||||
}
|
||||
@@ -183,7 +188,7 @@ fun <R> ResultWithDiagnostics<R>.resultOrNull(): R? = when (this) {
|
||||
/**
|
||||
* Extracts the result value from the receiver wrapper or run non-returning lambda if receiver represents a Failure
|
||||
*/
|
||||
inline fun <R> ResultWithDiagnostics<R>.resultOr(body: (ResultWithDiagnostics.Failure) -> Nothing): R = when (this) {
|
||||
inline fun <R> ResultWithDiagnostics<R>.valueOr(body: (ResultWithDiagnostics.Failure) -> Nothing): R = when (this) {
|
||||
is ResultWithDiagnostics.Success<R> -> value
|
||||
is ResultWithDiagnostics.Failure -> body(this)
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ val ScriptCompilationConfigurationKeys.fileExtension by PropertiesCollection.key
|
||||
/**
|
||||
* The superclass for target script class
|
||||
*/
|
||||
val ScriptCompilationConfigurationKeys.baseClass by PropertiesCollection.key<KotlinType>() // script base class
|
||||
val ScriptCompilationConfigurationKeys.baseClass by PropertiesCollection.key<KotlinType>(KotlinType(Any::class)) // script base class
|
||||
|
||||
/**
|
||||
* The list of classes that will be used as implicit receivers in the script body, as if the whole body is wrapped with "with" calls:
|
||||
|
||||
@@ -41,10 +41,14 @@ fun getMergedScriptText(script: SourceCode, configuration: ScriptCompilationConf
|
||||
}
|
||||
}
|
||||
|
||||
abstract class FileBasedScriptSource() : ExternalSourceCode {
|
||||
abstract val file: File
|
||||
}
|
||||
|
||||
/**
|
||||
* The implementation of the SourceCode for a script located in a file
|
||||
*/
|
||||
open class FileScriptSource(val file: File, private val preloadedText: String? = null) : ExternalSourceCode {
|
||||
open class FileScriptSource(override val file: File, private val preloadedText: String? = null) : FileBasedScriptSource() {
|
||||
override val externalLocation: URL get() = file.toURI().toURL()
|
||||
override val text: String by lazy { preloadedText ?: file.readText() }
|
||||
override val name: String? get() = file.name
|
||||
|
||||
+7
-7
@@ -18,13 +18,13 @@ import java.util.jar.JarFile
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.script.experimental.api.*
|
||||
import kotlin.script.experimental.host.BasicScriptingHost
|
||||
import kotlin.script.experimental.host.FileScriptSource
|
||||
import kotlin.script.experimental.host.FileBasedScriptSource
|
||||
import kotlin.script.experimental.host.toScriptSource
|
||||
import kotlin.script.experimental.jvm.BasicJvmScriptEvaluator
|
||||
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
|
||||
import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
|
||||
import kotlin.script.experimental.jvmhost.*
|
||||
import kotlin.script.experimental.jvmhost.impl.CompiledScriptClassLoader
|
||||
import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
|
||||
import kotlin.script.templates.standard.SimpleScriptTemplate
|
||||
|
||||
class ScriptingHostTest : TestCase() {
|
||||
@@ -86,7 +86,7 @@ class ScriptingHostTest : TestCase() {
|
||||
val scriptName = "SavedRunnableScript"
|
||||
val compiledScript = runBlocking {
|
||||
compiler("println(\"$greeting\")".toScriptSource(name = "$scriptName.kts"), compilationConfiguration).throwOnFailure()
|
||||
.resultOrNull()!!
|
||||
.valueOrNull()!!
|
||||
}
|
||||
val saver = BasicJvmScriptJarGenerator(outJar)
|
||||
runBlocking {
|
||||
@@ -353,8 +353,8 @@ class ScriptingHostTest : TestCase() {
|
||||
val compiledScriptClassRes = runBlocking { compiledScript!!.getClass(null) }
|
||||
val cachedScriptClassRes = runBlocking { cachedScript!!.getClass(null) }
|
||||
|
||||
val compiledScriptClass = compiledScriptClassRes.resultOrNull()
|
||||
val cachedScriptClass = cachedScriptClassRes.resultOrNull()
|
||||
val compiledScriptClass = compiledScriptClassRes.valueOrNull()
|
||||
val cachedScriptClass = cachedScriptClassRes.valueOrNull()
|
||||
|
||||
Assert.assertEquals(compiledScriptClass!!.qualifiedName, cachedScriptClass!!.qualifiedName)
|
||||
Assert.assertEquals(compiledScriptClass!!.supertypes, cachedScriptClass!!.supertypes)
|
||||
@@ -380,7 +380,7 @@ class ScriptingHostTest : TestCase() {
|
||||
val res = compiler(script.toScriptSource(), scriptCompilationConfiguration).throwOnFailure()
|
||||
(res as ResultWithDiagnostics.Success<CompiledScript<*>>).value
|
||||
}
|
||||
val compiledScriptClass = runBlocking { compiledScript.getClass(null).throwOnFailure().resultOrNull()!! as KClass<*> }
|
||||
val compiledScriptClass = runBlocking { compiledScript.getClass(null).throwOnFailure().valueOrNull()!! as KClass<*> }
|
||||
val classLoader = compiledScriptClass.java.classLoader
|
||||
|
||||
Assert.assertTrue(classLoader is CompiledScriptClassLoader)
|
||||
@@ -463,7 +463,7 @@ private fun ScriptCompilationConfiguration.Builder.makeSimpleConfigurationWithTe
|
||||
refineConfiguration {
|
||||
beforeCompiling { ctx ->
|
||||
val importedScript = File(ScriptingHostTest.TEST_DATA_DIR, "importTest/helloWithVal.kts")
|
||||
if ((ctx.script as? FileScriptSource)?.file?.canonicalFile == importedScript.canonicalFile) {
|
||||
if ((ctx.script as? FileBasedScriptSource)?.file?.canonicalFile == importedScript.canonicalFile) {
|
||||
ctx.compilationConfiguration
|
||||
} else {
|
||||
ScriptCompilationConfiguration(ctx.compilationConfiguration) {
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ class KJvmCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) : KJvm
|
||||
|
||||
val mainKtFile =
|
||||
getScriptKtFile(script, context.baseScriptCompilationConfiguration, context.environment.project, messageCollector)
|
||||
.resultOr { return it }
|
||||
.valueOr { return it }
|
||||
|
||||
context.scriptCompilationState.configureFor(script, context.baseScriptCompilationConfiguration)
|
||||
|
||||
|
||||
+3
-3
@@ -31,7 +31,7 @@ class KJvmReplCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) :
|
||||
override fun createReplCompilationState(scriptCompilationConfiguration: ScriptCompilationConfiguration): JvmReplCompilerState.Compilation {
|
||||
val context = withMessageCollectorAndDisposable(disposeOnSuccess = false) { messageCollector, disposable ->
|
||||
createSharedCompilationContext(scriptCompilationConfiguration, hostConfiguration, messageCollector, disposable).asSuccess()
|
||||
}.resultOr { throw IllegalStateException("Unable to initialize repl compiler:\n ${it.reports.joinToString("\n ")}") }
|
||||
}.valueOr { throw IllegalStateException("Unable to initialize repl compiler:\n ${it.reports.joinToString("\n ")}") }
|
||||
return ReplCompilationState(context)
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ class KJvmReplCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) :
|
||||
): ResultWithDiagnostics<Boolean> =
|
||||
withMessageCollector(script) { messageCollector ->
|
||||
val ktFile = getScriptKtFile(script, scriptCompilationConfiguration, project, messageCollector)
|
||||
.resultOr { return it }
|
||||
.valueOr { return it }
|
||||
val errorHolder = object : MessageCollectorBasedReporter {
|
||||
override val messageCollector = messageCollector
|
||||
}
|
||||
@@ -80,7 +80,7 @@ class KJvmReplCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) :
|
||||
|
||||
val snippetKtFile =
|
||||
getScriptKtFile(snippet, context.baseScriptCompilationConfiguration, context.environment.project, messageCollector)
|
||||
.resultOr { return it }
|
||||
.valueOr { return it }
|
||||
|
||||
val (sourceFiles, sourceDependencies) = collectRefinedSourcesAndUpdateEnvironment(context, snippetKtFile, messageCollector)
|
||||
|
||||
|
||||
+7
-3
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.config.JvmTarget
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar
|
||||
import org.jetbrains.kotlin.scripting.configuration.ScriptingConfigurationKeys
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
||||
import org.jetbrains.kotlin.scripting.dependencies.ScriptsCompilationDependencies
|
||||
import org.jetbrains.kotlin.scripting.dependencies.collectScriptsCompilationDependencies
|
||||
import kotlin.script.experimental.api.ScriptCompilationConfiguration
|
||||
@@ -88,10 +89,13 @@ internal fun createInitialConfigurations(
|
||||
|
||||
kotlinCompilerConfiguration.add(
|
||||
ScriptingConfigurationKeys.SCRIPT_DEFINITIONS,
|
||||
BridgeScriptDefinition(
|
||||
scriptCompilationConfiguration,
|
||||
ScriptDefinition.FromLegacy(
|
||||
hostConfiguration,
|
||||
scriptCompilationState
|
||||
BridgeScriptDefinition(
|
||||
scriptCompilationConfiguration,
|
||||
hostConfiguration,
|
||||
scriptCompilationState
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
+3
-15
@@ -8,11 +8,8 @@ package kotlin.script.experimental.jvmhost.impl
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.openapi.vfs.CharsetToolkit
|
||||
import com.intellij.psi.PsiFileFactory
|
||||
import com.intellij.psi.impl.PsiFileFactoryImpl
|
||||
import com.intellij.testFramework.LightVirtualFile
|
||||
import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
@@ -20,24 +17,15 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtScript
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.scripting.dependencies.ScriptsCompilationDependencies
|
||||
import org.jetbrains.kotlin.scripting.resolve.ScriptLightVirtualFile
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import java.util.*
|
||||
import kotlin.script.experimental.api.*
|
||||
import kotlin.script.experimental.host.FileBasedScriptSource
|
||||
import kotlin.script.experimental.host.FileScriptSource
|
||||
import kotlin.script.experimental.host.getMergedScriptText
|
||||
import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
|
||||
|
||||
internal class ScriptLightVirtualFile(name: String, private val _path: String?, text: String) :
|
||||
LightVirtualFile(name, KotlinLanguage.INSTANCE, StringUtil.convertLineSeparators(text)) {
|
||||
|
||||
init {
|
||||
charset = CharsetToolkit.UTF8_CHARSET
|
||||
}
|
||||
|
||||
override fun getPath(): String = _path ?: super.getPath()
|
||||
override fun getCanonicalPath(): String? = path
|
||||
}
|
||||
|
||||
internal fun makeCompiledModule(generationState: GenerationState) =
|
||||
KJvmCompiledModuleInMemory(
|
||||
generationState.factory.asList()
|
||||
@@ -98,7 +86,7 @@ internal fun getScriptKtFile(
|
||||
val scriptText = getMergedScriptText(script, scriptCompilationConfiguration)
|
||||
val virtualFile = ScriptLightVirtualFile(
|
||||
script.scriptFileName(script, scriptCompilationConfiguration),
|
||||
(script as? FileScriptSource)?.file?.path,
|
||||
(script as? FileBasedScriptSource)?.file?.path,
|
||||
scriptText
|
||||
)
|
||||
val ktFile = psiFileFactory.trySetupPsiForFile(virtualFile, KotlinLanguage.INSTANCE, true, false) as KtFile?
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ open class BasicJvmScriptEvaluator : ScriptEvaluator {
|
||||
?.onFailure {
|
||||
return@invoke ResultWithDiagnostics.Failure(it.reports)
|
||||
}
|
||||
?.resultOrNull()
|
||||
?.valueOrNull()
|
||||
?: configuration
|
||||
|
||||
val instance =
|
||||
|
||||
+7
-2
@@ -48,8 +48,13 @@ fun mapLegacyScriptPosition(pos: ScriptReport.Position?): SourceCode.Location? =
|
||||
}
|
||||
|
||||
fun mapToLegacyScriptReportPosition(pos: SourceCode.Location?): ScriptReport.Position? =
|
||||
pos?.let { ScriptReport.Position(pos.start.line, pos.start.col) }
|
||||
pos?.let { ScriptReport.Position(pos.start.line, pos.start.col, pos.end?.line, pos.end?.col) }
|
||||
|
||||
fun Iterable<ScriptReport>.mapToDiagnostics(): List<ScriptDiagnostic> = map { (message, severity, position: ScriptReport.Position?) ->
|
||||
fun Iterable<ScriptReport>.mapToDiagnostics(): List<ScriptDiagnostic> = map { (message, severity, position) ->
|
||||
ScriptDiagnostic(message, mapLegacyDiagnosticSeverity(severity), null, mapLegacyScriptPosition(position))
|
||||
}
|
||||
|
||||
fun Iterable<ScriptDiagnostic>.mapToLegacyReports(): List<ScriptReport> = map { (message, severity, _, location, exception) ->
|
||||
val reportMessage = if (exception == null) message else "$message ($exception)"
|
||||
ScriptReport(reportMessage, mapToLegacyScriptReportSeverity(severity), mapToLegacyScriptReportPosition(location))
|
||||
}
|
||||
|
||||
+12
-11
@@ -41,16 +41,6 @@ class BridgeDependenciesResolver(
|
||||
)
|
||||
)
|
||||
|
||||
val defaultImports = scriptCompilationConfiguration[ScriptCompilationConfiguration.defaultImports]?.toList() ?: emptyList()
|
||||
|
||||
fun ScriptCompilationConfiguration.toDependencies(classpath: List<File>): ScriptDependencies =
|
||||
ScriptDependencies(
|
||||
classpath = classpath,
|
||||
sources = this[ScriptCompilationConfiguration.ide.dependenciesSources].toClassPathOrEmpty(),
|
||||
imports = defaultImports,
|
||||
scripts = this[ScriptCompilationConfiguration.importScripts].toFilesOrEmpty()
|
||||
)
|
||||
|
||||
val script = getScriptSource(scriptContents) ?: scriptContents.toScriptSource()
|
||||
|
||||
val refineResults = scriptCompilationConfiguration.refineWith(
|
||||
@@ -92,6 +82,17 @@ class BridgeDependenciesResolver(
|
||||
}
|
||||
}
|
||||
|
||||
fun ScriptCompilationConfiguration.toDependencies(classpath: List<File>): ScriptDependencies {
|
||||
val defaultImports = this[ScriptCompilationConfiguration.defaultImports]?.toList() ?: emptyList()
|
||||
|
||||
return ScriptDependencies(
|
||||
classpath = classpath,
|
||||
sources = this[ScriptCompilationConfiguration.ide.dependenciesSources].toClassPathOrEmpty(),
|
||||
imports = defaultImports,
|
||||
scripts = this[ScriptCompilationConfiguration.importScripts].toFilesOrEmpty()
|
||||
)
|
||||
}
|
||||
|
||||
internal fun List<ScriptDiagnostic>.mapScriptReportsToDiagnostics() =
|
||||
map { ScriptReport(it.message, mapToLegacyScriptReportSeverity(it.severity), mapToLegacyScriptReportPosition(it.location)) }
|
||||
|
||||
@@ -101,7 +102,7 @@ internal fun ScriptContents.toScriptSource(): SourceCode = when {
|
||||
else -> throw IllegalArgumentException("Unable to convert script contents $this into script source")
|
||||
}
|
||||
|
||||
internal fun List<ScriptDependency>?.toClassPathOrEmpty() = this?.flatMap { (it as JvmDependency).classpath } ?: emptyList()
|
||||
fun List<ScriptDependency>?.toClassPathOrEmpty() = this?.flatMap { (it as JvmDependency).classpath } ?: emptyList()
|
||||
|
||||
internal fun List<SourceCode>?.toFilesOrEmpty() = this?.map {
|
||||
val externalSource = it as? ExternalSourceCode
|
||||
|
||||
@@ -9,6 +9,7 @@ package kotlin.script.experimental.jvm
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.script.experimental.api.*
|
||||
import kotlin.script.experimental.host.ScriptingHostConfiguration
|
||||
import kotlin.script.experimental.util.PropertiesCollection
|
||||
|
||||
interface JvmScriptEvaluationConfigurationKeys
|
||||
@@ -21,7 +22,10 @@ open class JvmScriptEvaluationConfigurationBuilder : PropertiesCollection.Builde
|
||||
/**
|
||||
* The base classloader to use for script classes loading
|
||||
*/
|
||||
val JvmScriptEvaluationConfigurationKeys.baseClassLoader by PropertiesCollection.key<ClassLoader?>(Thread.currentThread().contextClassLoader)
|
||||
val JvmScriptEvaluationConfigurationKeys.baseClassLoader by PropertiesCollection.key<ClassLoader?> {
|
||||
get(ScriptEvaluationConfiguration.hostConfiguration)?.get(ScriptingHostConfiguration.jvm.baseClassLoader)
|
||||
?: Thread.currentThread().contextClassLoader
|
||||
}
|
||||
|
||||
/**
|
||||
* Load script dependencies before evaluation, true by default
|
||||
|
||||
+16
-7
@@ -11,6 +11,7 @@ import java.net.URLClassLoader
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.script.experimental.api.*
|
||||
import kotlin.script.experimental.host.*
|
||||
import kotlin.script.experimental.jvm.impl.toClassPathOrEmpty
|
||||
import kotlin.script.experimental.util.PropertiesCollection
|
||||
|
||||
interface JvmScriptingHostConfigurationKeys
|
||||
@@ -25,6 +26,12 @@ val JvmScriptingHostConfigurationKeys.javaHome by PropertiesCollection.key<File>
|
||||
|
||||
val JvmScriptingHostConfigurationKeys.jdkHome by PropertiesCollection.key<File>()
|
||||
|
||||
val JvmScriptingHostConfigurationKeys.baseClassLoader by PropertiesCollection.key<ClassLoader> {
|
||||
get(ScriptingHostConfiguration.configurationDependencies)?.let {
|
||||
URLClassLoader(it.toClassPathOrEmpty().map { f -> f.toURI().toURL() }.toTypedArray())
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
val ScriptingHostConfigurationKeys.jvm
|
||||
get() = JvmScriptingHostConfigurationBuilder()
|
||||
@@ -49,15 +56,17 @@ class JvmGetScriptingClass : GetScriptingClass, Serializable {
|
||||
@Transient
|
||||
private var baseClassLoader: ClassLoader? = null
|
||||
|
||||
override fun invoke(classType: KotlinType, contextClass: KClass<*>, hostConfiguration: ScriptingHostConfiguration): KClass<*> =
|
||||
invoke(classType, contextClass.java.classLoader, hostConfiguration)
|
||||
|
||||
@Synchronized
|
||||
override fun invoke(classType: KotlinType, contextClass: KClass<*>, hostConfiguration: ScriptingHostConfiguration): KClass<*> {
|
||||
operator fun invoke(classType: KotlinType, contextClassLoader: ClassLoader?, hostConfiguration: ScriptingHostConfiguration): KClass<*> {
|
||||
|
||||
// checking if class already loaded in the same context
|
||||
val contextClassloader = contextClass.java.classLoader
|
||||
val fromClass = classType.fromClass
|
||||
if (fromClass != null) {
|
||||
if (fromClass.java.classLoader == null) return fromClass // root classloader
|
||||
val actualClassLoadersChain = generateSequence(contextClassloader) { it.parent }
|
||||
val actualClassLoadersChain = generateSequence(contextClassLoader) { it.parent }
|
||||
if (actualClassLoadersChain.any { it == fromClass.java.classLoader }) return fromClass
|
||||
}
|
||||
|
||||
@@ -71,7 +80,7 @@ class JvmGetScriptingClass : GetScriptingClass, Serializable {
|
||||
}
|
||||
|
||||
if (baseClassLoaderIsInitialized != true) {
|
||||
baseClassLoader = contextClassloader
|
||||
baseClassLoader = contextClassLoader
|
||||
baseClassLoaderIsInitialized = true
|
||||
}
|
||||
// TODO: this check breaks testLazyScriptDefinition, find out the reason and fix
|
||||
@@ -88,12 +97,12 @@ class JvmGetScriptingClass : GetScriptingClass, Serializable {
|
||||
}
|
||||
}
|
||||
classLoader =
|
||||
if (classpath == null || classpath.isEmpty()) baseClassLoader
|
||||
else URLClassLoader(classpath.toTypedArray(), baseClassLoader)
|
||||
if (classpath == null || classpath.isEmpty()) baseClassLoader
|
||||
else URLClassLoader(classpath.toTypedArray(), baseClassLoader)
|
||||
}
|
||||
|
||||
return try {
|
||||
classLoader!!.loadClass(classType.typeName).kotlin
|
||||
(classLoader ?: ClassLoader.getSystemClassLoader()).loadClass(classType.typeName).kotlin
|
||||
} catch (e: Throwable) {
|
||||
throw IllegalArgumentException("unable to load class $classType", e)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user