Refactor script definition and related parts:
- simplify script definition interface, convert it to class - create simple definitions right from base - refactor (rename and simplify) script definition with annotated template - simplify usages of script definition in many places
This commit is contained in:
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen;
|
package org.jetbrains.kotlin.codegen;
|
||||||
|
|
||||||
import kotlin.Pair;
|
|
||||||
import kotlin.jvm.functions.Function0;
|
import kotlin.jvm.functions.Function0;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||||
@@ -24,18 +23,17 @@ import org.jetbrains.kotlin.codegen.context.MethodContext;
|
|||||||
import org.jetbrains.kotlin.codegen.context.ScriptContext;
|
import org.jetbrains.kotlin.codegen.context.ScriptContext;
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -154,17 +152,19 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
|
|||||||
iv.invokespecial("java/lang/Object", "<init>", "()V", false);
|
iv.invokespecial("java/lang/Object", "<init>", "()V", false);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
List<Pair<Name, KotlinType>> superclassParamsMap = scriptDescriptor.getScriptParametersToPassToSuperclass();
|
// TODO: check if it is correct way to find a promary constructor
|
||||||
ConstructorDescriptor ctorDesc = DescriptorUtilsKt.getConstructorByParamsMap(superclass, superclassParamsMap);
|
Collection<ClassConstructorDescriptor> ctorDescriptors = superclass.getConstructors();
|
||||||
|
assert ctorDescriptors.size() == 1;
|
||||||
|
ConstructorDescriptor ctorDesc = ctorDescriptors.iterator().next();
|
||||||
assert ctorDesc != null;
|
assert ctorDesc != null;
|
||||||
|
|
||||||
iv.load(0, classType);
|
iv.load(0, classType);
|
||||||
|
|
||||||
List<ValueParameterDescriptor> valueParameters = scriptDescriptor.getUnsubstitutedPrimaryConstructor().getValueParameters();
|
List<ValueParameterDescriptor> valueParameters = scriptDescriptor.getUnsubstitutedPrimaryConstructor().getValueParameters();
|
||||||
for (Pair<Name, KotlinType> superclassParam: superclassParamsMap) {
|
for (ValueParameterDescriptor superclassParam: ctorDesc.getValueParameters()) {
|
||||||
ValueParameterDescriptor valueParam = null;
|
ValueParameterDescriptor valueParam = null;
|
||||||
for (ValueParameterDescriptor vpd: valueParameters) {
|
for (ValueParameterDescriptor vpd: valueParameters) {
|
||||||
if (vpd.getName().equals(superclassParam.getFirst())) {
|
if (vpd.getName().equals(superclassParam.getName())) {
|
||||||
valueParam = vpd;
|
valueParam = vpd;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ import org.jetbrains.kotlin.incremental.components.SourceRetentionAnnotationHand
|
|||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
|
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
||||||
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromTemplate
|
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
|
||||||
import org.jetbrains.kotlin.script.StandardScriptDefinition
|
import org.jetbrains.kotlin.script.StandardScriptDefinition
|
||||||
import org.jetbrains.kotlin.util.PerformanceCounter
|
import org.jetbrains.kotlin.util.PerformanceCounter
|
||||||
import org.jetbrains.kotlin.utils.KotlinPaths
|
import org.jetbrains.kotlin.utils.KotlinPaths
|
||||||
@@ -400,7 +400,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
|||||||
for (template in scriptTemplates) {
|
for (template in scriptTemplates) {
|
||||||
try {
|
try {
|
||||||
val cls = classloader.loadClass(template)
|
val cls = classloader.loadClass(template)
|
||||||
val def = KotlinScriptDefinitionFromTemplate(cls.kotlin, null, null, scriptResolverEnv)
|
val def = KotlinScriptDefinitionFromAnnotatedTemplate(cls.kotlin, null, null, scriptResolverEnv)
|
||||||
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, def)
|
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, def)
|
||||||
messageCollector.report(
|
messageCollector.report(
|
||||||
CompilerMessageSeverity.INFO,
|
CompilerMessageSeverity.INFO,
|
||||||
|
|||||||
@@ -43,8 +43,6 @@ import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
|||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
||||||
import org.jetbrains.kotlin.script.KotlinScriptExternalDependencies
|
import org.jetbrains.kotlin.script.KotlinScriptExternalDependencies
|
||||||
import org.jetbrains.kotlin.script.ScriptParameter
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
private val logger = Logger.getInstance(GenericRepl::class.java)
|
private val logger = Logger.getInstance(GenericRepl::class.java)
|
||||||
|
|
||||||
@@ -56,7 +54,7 @@ open class GenericReplChecker(
|
|||||||
) : ReplChecker {
|
) : ReplChecker {
|
||||||
protected val environment = run {
|
protected val environment = run {
|
||||||
compilerConfiguration.apply {
|
compilerConfiguration.apply {
|
||||||
add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, DelegatingScriptDefWithNoParams(scriptDefinition))
|
add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, scriptDefinition)
|
||||||
put<MessageCollector>(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
|
put<MessageCollector>(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
|
||||||
put(JVMConfigurationKeys.RETAIN_OUTPUT_IN_MEMORY, true)
|
put(JVMConfigurationKeys.RETAIN_OUTPUT_IN_MEMORY, true)
|
||||||
}
|
}
|
||||||
@@ -71,10 +69,6 @@ open class GenericReplChecker(
|
|||||||
val psiFile: KtFile,
|
val psiFile: KtFile,
|
||||||
val errorHolder: DiagnosticMessageHolder)
|
val errorHolder: DiagnosticMessageHolder)
|
||||||
|
|
||||||
protected class DelegatingScriptDefWithNoParams(parent: KotlinScriptDefinition) : KotlinScriptDefinition by parent {
|
|
||||||
override fun getScriptParameters(scriptDescriptor: ScriptDescriptor): List<ScriptParameter> = emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
protected var lineState: LineState? = null
|
protected var lineState: LineState? = null
|
||||||
|
|
||||||
fun createDiagnosticHolder() = ReplTerminalDiagnosticMessageHolder()
|
fun createDiagnosticHolder() = ReplTerminalDiagnosticMessageHolder()
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
|||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.KtScript
|
import org.jetbrains.kotlin.psi.KtScript
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromTemplate
|
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@ class ReplInterpreter(
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val SCRIPT_RESULT_FIELD_NAME = "\$\$result"
|
private val SCRIPT_RESULT_FIELD_NAME = "\$\$result"
|
||||||
private val REPL_LINE_AS_SCRIPT_DEFINITION = object : KotlinScriptDefinitionFromTemplate(Any::class) {
|
private val REPL_LINE_AS_SCRIPT_DEFINITION = object : KotlinScriptDefinition(Any::class) {
|
||||||
override val name = "Kotlin REPL"
|
override val name = "Kotlin REPL"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.daemon.common.RemoteInputStream
|
|||||||
import org.jetbrains.kotlin.daemon.common.RemoteOperationsTracer
|
import org.jetbrains.kotlin.daemon.common.RemoteOperationsTracer
|
||||||
import org.jetbrains.kotlin.daemon.common.RemoteOutputStream
|
import org.jetbrains.kotlin.daemon.common.RemoteOutputStream
|
||||||
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
||||||
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromTemplate
|
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
|
||||||
import org.jetbrains.kotlin.utils.PathUtil
|
import org.jetbrains.kotlin.utils.PathUtil
|
||||||
import java.io.BufferedInputStream
|
import java.io.BufferedInputStream
|
||||||
import java.io.BufferedOutputStream
|
import java.io.BufferedOutputStream
|
||||||
@@ -85,7 +85,7 @@ open class KotlinJvmReplService(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
val cls = classloader.loadClass(templateClassName)
|
val cls = classloader.loadClass(templateClassName)
|
||||||
val def = KotlinScriptDefinitionFromTemplate(cls.kotlin, null, null, emptyMap())
|
val def = KotlinScriptDefinitionFromAnnotatedTemplate(cls.kotlin, null, null, emptyMap())
|
||||||
messageCollector.report(
|
messageCollector.report(
|
||||||
CompilerMessageSeverity.INFO,
|
CompilerMessageSeverity.INFO,
|
||||||
"New script definition $templateClassName: files pattern = \"${def.scriptFilePattern}\", resolver = ${def.resolver?.javaClass?.name}",
|
"New script definition $templateClassName: files pattern = \"${def.scriptFilePattern}\", resolver = ${def.resolver?.javaClass?.name}",
|
||||||
|
|||||||
@@ -22,9 +22,8 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
import org.jetbrains.kotlin.psi.stubs.KotlinScriptStub;
|
import org.jetbrains.kotlin.psi.stubs.KotlinScriptStub;
|
||||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes;
|
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes;
|
||||||
import org.jetbrains.kotlin.script.GetScriptDefinitionKt;
|
|
||||||
import org.jetbrains.kotlin.script.KotlinScriptDefinition;
|
import org.jetbrains.kotlin.script.KotlinScriptDefinition;
|
||||||
import org.jetbrains.kotlin.script.KotlinScriptDefinitionProvider;
|
import org.jetbrains.kotlin.script.KotlinScriptDefinitionProviderKt;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -37,7 +36,7 @@ public class KtScript extends KtNamedDeclarationStub<KotlinScriptStub> implement
|
|||||||
private KotlinScriptDefinition getKotlinScriptDefinition() {
|
private KotlinScriptDefinition getKotlinScriptDefinition() {
|
||||||
if (!kotlinScriptDefinitionInitialized) {
|
if (!kotlinScriptDefinitionInitialized) {
|
||||||
KtFile ktFile = getContainingKtFile();
|
KtFile ktFile = getContainingKtFile();
|
||||||
kotlinScriptDefinitionField = GetScriptDefinitionKt.getScriptDefinition(ktFile);
|
kotlinScriptDefinitionField = KotlinScriptDefinitionProviderKt.getScriptDefinition(ktFile);
|
||||||
kotlinScriptDefinitionInitialized = true;
|
kotlinScriptDefinitionInitialized = true;
|
||||||
assert kotlinScriptDefinitionField != null : "Should not parse a script without definition: " + ktFile.toString();
|
assert kotlinScriptDefinitionField != null : "Should not parse a script without definition: " + ktFile.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
||||||
import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider
|
import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider
|
||||||
|
import org.jetbrains.kotlin.script.getScriptParameters
|
||||||
|
|
||||||
class LazyScriptClassMemberScope(
|
class LazyScriptClassMemberScope(
|
||||||
resolveSession: ResolveSession,
|
resolveSession: ResolveSession,
|
||||||
|
|||||||
+2
-11
@@ -29,8 +29,8 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProv
|
|||||||
import org.jetbrains.kotlin.resolve.source.toSourceElement
|
import org.jetbrains.kotlin.resolve.source.toSourceElement
|
||||||
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
||||||
import org.jetbrains.kotlin.script.ScriptPriorities
|
import org.jetbrains.kotlin.script.ScriptPriorities
|
||||||
|
import org.jetbrains.kotlin.script.getKotlinTypeByFqName
|
||||||
import org.jetbrains.kotlin.script.getScriptDefinition
|
import org.jetbrains.kotlin.script.getScriptDefinition
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||||
import org.jetbrains.kotlin.utils.ifEmpty
|
import org.jetbrains.kotlin.utils.ifEmpty
|
||||||
|
|
||||||
@@ -79,14 +79,5 @@ class LazyScriptDescriptor(
|
|||||||
|
|
||||||
override fun getUnsubstitutedPrimaryConstructor() = super.getUnsubstitutedPrimaryConstructor()!!
|
override fun getUnsubstitutedPrimaryConstructor() = super.getUnsubstitutedPrimaryConstructor()!!
|
||||||
|
|
||||||
override fun computeSupertypes() = scriptDefinition.getScriptSupertypes(this).ifEmpty { listOf(builtIns.anyType) }
|
override fun computeSupertypes() = listOf(getKotlinTypeByFqName(this, scriptDefinition.template.qualifiedName!!)).ifEmpty { listOf(builtIns.anyType) }
|
||||||
|
|
||||||
override fun getScriptParametersToPassToSuperclass(): List<Pair<Name, KotlinType>> {
|
|
||||||
val scriptParams = scriptDefinition.getScriptParameters(this)
|
|
||||||
return scriptDefinition.getScriptParametersToPassToSuperclass(this).map { name ->
|
|
||||||
Pair(name,
|
|
||||||
scriptParams.find { it.name == name }?.type
|
|
||||||
?: throw RuntimeException("Unknown script parameter '$name' is specified as a script base class parameter"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,48 +18,28 @@ package org.jetbrains.kotlin.script
|
|||||||
|
|
||||||
import com.intellij.openapi.fileTypes.LanguageFileType
|
import com.intellij.openapi.fileTypes.LanguageFileType
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
||||||
import org.jetbrains.kotlin.psi.KtScript
|
import org.jetbrains.kotlin.psi.KtScript
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.NotFoundClasses
|
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.findNonGenericClassAcrossDependencies
|
|
||||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
|
||||||
import org.jetbrains.kotlin.types.*
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.lang.RuntimeException
|
|
||||||
import java.lang.UnsupportedOperationException
|
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.KType
|
|
||||||
import kotlin.reflect.KTypeProjection
|
|
||||||
import kotlin.reflect.KVariance
|
|
||||||
import kotlin.script.StandardScriptTemplate
|
import kotlin.script.StandardScriptTemplate
|
||||||
|
|
||||||
interface KotlinScriptDefinition {
|
open class KotlinScriptDefinition(val template: KClass<out Any>) {
|
||||||
val name: String get() = "Kotlin Script"
|
|
||||||
|
|
||||||
val template: KClass<out Any>
|
open val name: String = "Kotlin Script"
|
||||||
|
|
||||||
// TODO: consider creating separate type (subtype? for kotlin scripts)
|
// TODO: consider creating separate type (subtype? for kotlin scripts)
|
||||||
val fileType: LanguageFileType get() = KotlinFileType.INSTANCE
|
open val fileType: LanguageFileType = KotlinFileType.INSTANCE
|
||||||
|
|
||||||
fun <TF> isScript(file: TF): Boolean =
|
open fun <TF> isScript(file: TF): Boolean =
|
||||||
getFileName(file).endsWith(KotlinParserDefinition.STD_SCRIPT_EXT)
|
getFileName(file).endsWith(KotlinParserDefinition.STD_SCRIPT_EXT)
|
||||||
|
|
||||||
// TODO: replace these 3 functions with template property
|
open fun getScriptName(script: KtScript): Name =
|
||||||
fun getScriptParameters(scriptDescriptor: ScriptDescriptor): List<ScriptParameter>
|
|
||||||
fun getScriptSupertypes(scriptDescriptor: ScriptDescriptor): List<KotlinType> = emptyList()
|
|
||||||
fun getScriptParametersToPassToSuperclass(scriptDescriptor: ScriptDescriptor): List<Name> = emptyList()
|
|
||||||
|
|
||||||
fun getScriptName(script: KtScript): Name =
|
|
||||||
ScriptNameUtil.fileNameWithExtensionStripped(script, KotlinParserDefinition.STD_SCRIPT_EXT)
|
ScriptNameUtil.fileNameWithExtensionStripped(script, KotlinParserDefinition.STD_SCRIPT_EXT)
|
||||||
|
|
||||||
fun <TF> getDependenciesFor(file: TF, project: Project, previousDependencies: KotlinScriptExternalDependencies?): KotlinScriptExternalDependencies? = null
|
open fun <TF> getDependenciesFor(file: TF, project: Project, previousDependencies: KotlinScriptExternalDependencies?): KotlinScriptExternalDependencies? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
interface KotlinScriptExternalDependencies {
|
interface KotlinScriptExternalDependencies {
|
||||||
@@ -70,54 +50,5 @@ interface KotlinScriptExternalDependencies {
|
|||||||
val scripts: Iterable<File> get() = emptyList()
|
val scripts: Iterable<File> get() = emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
class KotlinScriptExternalDependenciesUnion(val dependencies: Iterable<KotlinScriptExternalDependencies>) : KotlinScriptExternalDependencies {
|
object StandardScriptDefinition : KotlinScriptDefinition(StandardScriptTemplate::class)
|
||||||
override val javaHome: String? get() = dependencies.firstOrNull { it.javaHome != null }?.javaHome
|
|
||||||
override val classpath: Iterable<File> get() = dependencies.flatMap { it.classpath }
|
|
||||||
override val imports: Iterable<String> get() = dependencies.flatMap { it.imports }
|
|
||||||
override val sources: Iterable<File> get() = dependencies.flatMap { it.sources }
|
|
||||||
override val scripts: Iterable<File> get() = dependencies.flatMap { it.scripts }
|
|
||||||
}
|
|
||||||
|
|
||||||
data class ScriptParameter(val name: Name, val type: KotlinType)
|
|
||||||
|
|
||||||
object StandardScriptDefinition : KotlinScriptDefinitionFromTemplate(StandardScriptTemplate::class)
|
|
||||||
|
|
||||||
fun getKotlinType(scriptDescriptor: ScriptDescriptor, kClass: KClass<out Any>): KotlinType =
|
|
||||||
getKotlinTypeByFqName(scriptDescriptor,
|
|
||||||
kClass.qualifiedName ?: throw RuntimeException("Cannot get FQN from $kClass"))
|
|
||||||
|
|
||||||
fun getKotlinTypeByFqName(scriptDescriptor: ScriptDescriptor, fqName: String): KotlinType =
|
|
||||||
scriptDescriptor.module.findNonGenericClassAcrossDependencies(
|
|
||||||
ClassId.topLevel(FqName(fqName)),
|
|
||||||
NotFoundClasses(LockBasedStorageManager.NO_LOCKS, scriptDescriptor.module)
|
|
||||||
).defaultType
|
|
||||||
|
|
||||||
// TODO: support star projections
|
|
||||||
// TODO: support annotations on types and type parameters
|
|
||||||
// TODO: support type parameters on types and type projections
|
|
||||||
fun getKotlinTypeByKType(scriptDescriptor: ScriptDescriptor, kType: KType): KotlinType {
|
|
||||||
val classifier = kType.classifier
|
|
||||||
if (classifier !is KClass<*>)
|
|
||||||
throw UnsupportedOperationException("Only classes are supported as parameters in script template: $classifier")
|
|
||||||
|
|
||||||
val type = getKotlinType(scriptDescriptor, classifier)
|
|
||||||
val typeProjections = kType.arguments.map { getTypeProjection(scriptDescriptor, it) }
|
|
||||||
val isNullable = kType.isMarkedNullable
|
|
||||||
|
|
||||||
return KotlinTypeFactory.simpleType(Annotations.EMPTY, type.constructor, typeProjections, isNullable)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getTypeProjection(scriptDescriptor: ScriptDescriptor, kTypeProjection: KTypeProjection): TypeProjection {
|
|
||||||
val kType = kTypeProjection.type ?: throw UnsupportedOperationException("Star projections are not supported")
|
|
||||||
|
|
||||||
val type = getKotlinTypeByKType(scriptDescriptor, kType)
|
|
||||||
|
|
||||||
val variance = when (kTypeProjection.variance) {
|
|
||||||
KVariance.IN -> Variance.IN_VARIANCE
|
|
||||||
KVariance.OUT -> Variance.OUT_VARIANCE
|
|
||||||
KVariance.INVARIANT -> Variance.INVARIANT
|
|
||||||
null -> throw UnsupportedOperationException("Star projections are not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
return TypeProjectionImpl(variance, type)
|
|
||||||
}
|
|
||||||
+154
@@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.script
|
||||||
|
|
||||||
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.vfs.StandardFileSystems
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
|
import com.intellij.psi.PsiManager
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
||||||
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.psi.KtScript
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
import kotlin.reflect.memberFunctions
|
||||||
|
import kotlin.reflect.primaryConstructor
|
||||||
|
|
||||||
|
open class KotlinScriptDefinitionFromAnnotatedTemplate(
|
||||||
|
template: KClass<out Any>,
|
||||||
|
providedResolver: ScriptDependenciesResolver? = null,
|
||||||
|
providedScriptFilePattern: String? = null,
|
||||||
|
val environment: Map<String, Any?>? = null
|
||||||
|
) : KotlinScriptDefinition(template) {
|
||||||
|
|
||||||
|
val scriptFilePattern by lazy {
|
||||||
|
providedScriptFilePattern ?: template.annotations.firstIsInstanceOrNull<ScriptTemplateDefinition>()?.scriptFilePattern ?: DEFAULT_SCRIPT_FILE_PATTERN
|
||||||
|
}
|
||||||
|
|
||||||
|
val resolver: ScriptDependenciesResolver? by lazy {
|
||||||
|
val defAnn by lazy { template.annotations.firstIsInstanceOrNull<ScriptTemplateDefinition>() }
|
||||||
|
when {
|
||||||
|
providedResolver != null -> providedResolver
|
||||||
|
// TODO: logScriptDefMessage missing or invalid constructor
|
||||||
|
defAnn != null ->
|
||||||
|
try {
|
||||||
|
defAnn.resolver.primaryConstructor?.call() ?: null.apply {
|
||||||
|
log.error("[kts] No default constructor found for ${defAnn.resolver.qualifiedName}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ex: ClassCastException) {
|
||||||
|
log.error("[kts] Script def error ${ex.message}")
|
||||||
|
null
|
||||||
|
}
|
||||||
|
else -> BasicScriptDependenciesResolver()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val acceptedAnnotations: List<KClass<out Annotation>> by lazy {
|
||||||
|
val resolveMethod = ScriptDependenciesResolver::resolve
|
||||||
|
val resolverMethodAnnotations =
|
||||||
|
resolver::class.memberFunctions.find {
|
||||||
|
it.name == resolveMethod.name &&
|
||||||
|
sameSignature(it, resolveMethod)
|
||||||
|
}
|
||||||
|
?.annotations
|
||||||
|
?.filterIsInstance<AcceptedAnnotations>()
|
||||||
|
resolverMethodAnnotations?.flatMap {
|
||||||
|
val v = it.supportedAnnotationClasses
|
||||||
|
v.toList() // TODO: inline after KT-9453 is resolved (now it fails with "java.lang.Class cannot be cast to kotlin.reflect.KClass")
|
||||||
|
}
|
||||||
|
?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
override val name = template.simpleName!!
|
||||||
|
|
||||||
|
override fun <TF> isScript(file: TF): Boolean =
|
||||||
|
scriptFilePattern.let { Regex(it).matches(getFileName(file)) }
|
||||||
|
|
||||||
|
// TODO: implement other strategy - e.g. try to extract something from match with ScriptFilePattern
|
||||||
|
override fun getScriptName(script: KtScript): Name = ScriptNameUtil.fileNameWithExtensionStripped(script, KotlinParserDefinition.STD_SCRIPT_EXT)
|
||||||
|
|
||||||
|
override fun <TF> getDependenciesFor(file: TF, project: Project, previousDependencies: KotlinScriptExternalDependencies?): KotlinScriptExternalDependencies? {
|
||||||
|
|
||||||
|
val script = BasicScriptContents(file, getAnnotations = {
|
||||||
|
val classLoader = (template as Any).javaClass.classLoader
|
||||||
|
getAnnotationEntries(file, project)
|
||||||
|
.mapNotNull { psiAnn ->
|
||||||
|
// TODO: consider advanced matching using semantic similar to actual resolving
|
||||||
|
acceptedAnnotations.find { ann ->
|
||||||
|
psiAnn.typeName.let { it == ann.simpleName || it == ann.qualifiedName }
|
||||||
|
}?.let { KtAnnotationWrapper(psiAnn, classLoader.loadClass(it.qualifiedName).kotlin as KClass<out Annotation>) }
|
||||||
|
}
|
||||||
|
.map { it.getProxy(classLoader) }
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
val fileDeps = resolver?.resolve(script, environment, ::logScriptDefMessage, previousDependencies)
|
||||||
|
// TODO: use it as a Future
|
||||||
|
return fileDeps?.get()
|
||||||
|
}
|
||||||
|
catch (ex: ClassCastException) {
|
||||||
|
logScriptDefMessage(ScriptDependenciesResolver.ReportSeverity.ERROR, ex.message ?: "Invalid script template: ${template.qualifiedName}", null)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <TF> getAnnotationEntries(file: TF, project: Project): Iterable<KtAnnotationEntry> = when (file) {
|
||||||
|
is PsiFile -> getAnnotationEntriesFromPsiFile(file)
|
||||||
|
is VirtualFile -> getAnnotationEntriesFromVirtualFile(file, project)
|
||||||
|
is File -> {
|
||||||
|
val virtualFile = (StandardFileSystems.local().findFileByPath(file.canonicalPath)
|
||||||
|
?: throw IllegalArgumentException("Unable to find file ${file.canonicalPath}"))
|
||||||
|
getAnnotationEntriesFromVirtualFile(virtualFile, project)
|
||||||
|
}
|
||||||
|
else -> throw IllegalArgumentException("Unsupported file type $file")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getAnnotationEntriesFromPsiFile(file: PsiFile) =
|
||||||
|
if (file is KtFile) file.annotationEntries
|
||||||
|
else throw IllegalArgumentException("Unable to extract kotlin annotations from ${file.name} (${file.fileType})")
|
||||||
|
|
||||||
|
private fun getAnnotationEntriesFromVirtualFile(file: VirtualFile, project: Project): Iterable<KtAnnotationEntry> {
|
||||||
|
val psiFile: PsiFile = PsiManager.getInstance(project).findFile(file)
|
||||||
|
?: throw IllegalArgumentException("Unable to load PSI from ${file.canonicalPath}")
|
||||||
|
return getAnnotationEntriesFromPsiFile(psiFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
class BasicScriptContents<out TF>(myFile: TF, getAnnotations: () -> Iterable<Annotation>) : ScriptContents {
|
||||||
|
override val file: File? by lazy { getFile(myFile) }
|
||||||
|
override val annotations: Iterable<Annotation> by lazy { getAnnotations() }
|
||||||
|
override val text: CharSequence? by lazy { getFileContents(myFile) }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
internal val log = Logger.getInstance(KotlinScriptDefinitionFromAnnotatedTemplate::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun logScriptDefMessage(reportSeverity: ScriptDependenciesResolver.ReportSeverity, s: String, position: ScriptContents.Position?): Unit {
|
||||||
|
val msg = (position?.run { "[at $line:$col]" } ?: "") + s
|
||||||
|
when (reportSeverity) {
|
||||||
|
ScriptDependenciesResolver.ReportSeverity.ERROR -> KotlinScriptDefinitionFromAnnotatedTemplate.log.error(msg)
|
||||||
|
ScriptDependenciesResolver.ReportSeverity.WARNING -> KotlinScriptDefinitionFromAnnotatedTemplate.log.warn(msg)
|
||||||
|
ScriptDependenciesResolver.ReportSeverity.INFO -> KotlinScriptDefinitionFromAnnotatedTemplate.log.info(msg)
|
||||||
|
ScriptDependenciesResolver.ReportSeverity.DEBUG -> KotlinScriptDefinitionFromAnnotatedTemplate.log.debug(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -72,3 +72,9 @@ class KotlinScriptDefinitionProvider {
|
|||||||
ServiceManager.getService(project, KotlinScriptDefinitionProvider::class.java)
|
ServiceManager.getService(project, KotlinScriptDefinitionProvider::class.java)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getScriptDefinition(file: VirtualFile, project: Project): KotlinScriptDefinition? =
|
||||||
|
KotlinScriptDefinitionProvider.getInstance(project).findScriptDefinition(file)
|
||||||
|
|
||||||
|
fun getScriptDefinition(psiFile: PsiFile): KotlinScriptDefinition? =
|
||||||
|
KotlinScriptDefinitionProvider.getInstance(psiFile.project).findScriptDefinition(psiFile)
|
||||||
|
|||||||
+13
-11
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.script
|
|||||||
import com.intellij.openapi.components.ServiceManager
|
import com.intellij.openapi.components.ServiceManager
|
||||||
import com.intellij.openapi.diagnostic.Logger
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||||
import kotlin.concurrent.read
|
import kotlin.concurrent.read
|
||||||
@@ -40,19 +41,18 @@ class KotlinScriptExternalImportsProvider(val project: Project, private val scri
|
|||||||
val path = getFilePath(file)
|
val path = getFilePath(file)
|
||||||
return cache[path]
|
return cache[path]
|
||||||
?: if (cacheOfNulls.contains(path)) null
|
?: if (cacheOfNulls.contains(path)) null
|
||||||
else scriptDefinitionProvider.findScriptDefinition(file)
|
else scriptDefinitionProvider.findScriptDefinition(file)?.getDependenciesFor(file, project, null)
|
||||||
?.let { it.getDependenciesFor(file, project, null) }
|
.apply {
|
||||||
.apply {
|
log.info("[kts] new cached deps for $path: ${this?.classpath?.joinToString(File.pathSeparator)}")
|
||||||
log.info("[kts] new cached deps for $path: ${this?.classpath?.joinToString(File.pathSeparator)}")
|
cacheLock.write {
|
||||||
cacheLock.write {
|
if (this == null) {
|
||||||
if (this == null) {
|
cacheOfNulls.add(path)
|
||||||
cacheOfNulls.add(path)
|
}
|
||||||
}
|
else {
|
||||||
else {
|
cache.put(path, this)
|
||||||
cache.put(path, this)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// optimized for initial caching, additional handling of possible duplicates to save a call to distinct
|
// optimized for initial caching, additional handling of possible duplicates to save a call to distinct
|
||||||
@@ -162,3 +162,5 @@ internal fun Iterable<File>.isSamePathListAs(other: Iterable<File>): Boolean =
|
|||||||
!(first.hasNext() || second.hasNext())
|
!(first.hasNext() || second.hasNext())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getScriptExternalDependencies(file: VirtualFile, project: Project): KotlinScriptExternalDependencies? =
|
||||||
|
KotlinScriptExternalImportsProvider.getInstance(project)?.getExternalImports(file)
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.script
|
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
|
||||||
import com.intellij.psi.PsiFile
|
|
||||||
|
|
||||||
fun getScriptDefinition(file: VirtualFile, project: Project): KotlinScriptDefinition? =
|
|
||||||
KotlinScriptDefinitionProvider.getInstance(project).findScriptDefinition(file)
|
|
||||||
|
|
||||||
fun getScriptDefinition(psiFile: PsiFile): KotlinScriptDefinition? =
|
|
||||||
KotlinScriptDefinitionProvider.getInstance(psiFile.project).findScriptDefinition(psiFile)
|
|
||||||
|
|
||||||
fun getScriptExternalDependencies(file: VirtualFile, project: Project): KotlinScriptExternalDependencies? =
|
|
||||||
KotlinScriptExternalImportsProvider.getInstance(project)?.getExternalImports(file)
|
|
||||||
@@ -1,172 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.script
|
|
||||||
|
|
||||||
import com.intellij.openapi.diagnostic.Logger
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.vfs.StandardFileSystems
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
|
||||||
import com.intellij.psi.PsiFile
|
|
||||||
import com.intellij.psi.PsiManager
|
|
||||||
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
|
||||||
import org.jetbrains.kotlin.psi.KtScript
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
|
||||||
import java.io.File
|
|
||||||
import kotlin.reflect.KClass
|
|
||||||
import kotlin.reflect.memberFunctions
|
|
||||||
import kotlin.reflect.primaryConstructor
|
|
||||||
|
|
||||||
open class KotlinScriptDefinitionFromTemplate(final override val template: KClass<out Any>,
|
|
||||||
val resolver: ScriptDependenciesResolver? = null,
|
|
||||||
val scriptFilePattern: String? = null,
|
|
||||||
val environment: Map<String, Any?>? = null
|
|
||||||
) : KotlinScriptDefinition {
|
|
||||||
|
|
||||||
// TODO: remove this and simplify definitionAnnotation as soon as deprecated annotations will be removed
|
|
||||||
internal class ScriptTemplateDefinitionData(val resolverClass: KClass<out ScriptDependenciesResolver>,
|
|
||||||
makeResolver: () -> ScriptDependenciesResolver?,
|
|
||||||
val scriptFilePattern: String?) {
|
|
||||||
|
|
||||||
val resolver: ScriptDependenciesResolver? by lazy(makeResolver)
|
|
||||||
|
|
||||||
val acceptedAnnotations: List<KClass<out Annotation>> by lazy {
|
|
||||||
val resolveMethod = ScriptDependenciesResolver::resolve
|
|
||||||
val resolverMethodAnnotations =
|
|
||||||
resolverClass.memberFunctions.find {
|
|
||||||
it.name == resolveMethod.name &&
|
|
||||||
sameSignature(it, resolveMethod)
|
|
||||||
}
|
|
||||||
?.annotations
|
|
||||||
?.filterIsInstance<AcceptedAnnotations>()
|
|
||||||
resolverMethodAnnotations?.flatMap {
|
|
||||||
val v = it.supportedAnnotationClasses
|
|
||||||
v.toList() // TODO: inline after KT-9453 is resolved (now it fails with "java.lang.Class cannot be cast to kotlin.reflect.KClass")
|
|
||||||
}
|
|
||||||
?: emptyList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val definitionData by lazy {
|
|
||||||
val defAnn = template.annotations.firstIsInstanceOrNull<ScriptTemplateDefinition>()
|
|
||||||
val filePattern = scriptFilePattern ?: defAnn?.scriptFilePattern ?: DEFAULT_SCRIPT_FILE_PATTERN
|
|
||||||
when {
|
|
||||||
resolver != null -> ScriptTemplateDefinitionData(resolver.javaClass.kotlin, { resolver }, filePattern)
|
|
||||||
// TODO: logScriptDefMessage missing or invalid constructor
|
|
||||||
defAnn != null -> ScriptTemplateDefinitionData(defAnn.resolver,
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
defAnn.resolver.primaryConstructor?.call() ?: null.apply {
|
|
||||||
log.error("[kts] No default constructor found for ${defAnn.resolver.qualifiedName}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ex: ClassCastException) {
|
|
||||||
log.error("[kts] Script def error ${ex.message}")
|
|
||||||
null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
filePattern)
|
|
||||||
else -> ScriptTemplateDefinitionData(BasicScriptDependenciesResolver::class, ::BasicScriptDependenciesResolver, filePattern)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override val name = template.simpleName!!
|
|
||||||
|
|
||||||
override fun getScriptParameters(scriptDescriptor: ScriptDescriptor): List<ScriptParameter> =
|
|
||||||
template.primaryConstructor!!.parameters.map { ScriptParameter(Name.identifier(it.name!!), getKotlinTypeByKType(scriptDescriptor, it.type)) }
|
|
||||||
|
|
||||||
override fun getScriptSupertypes(scriptDescriptor: ScriptDescriptor): List<KotlinType> =
|
|
||||||
listOf(getKotlinTypeByFqName(scriptDescriptor, template.qualifiedName!!))
|
|
||||||
|
|
||||||
override fun getScriptParametersToPassToSuperclass(scriptDescriptor: ScriptDescriptor): List<Name> =
|
|
||||||
getScriptParameters(scriptDescriptor).map { it.name }
|
|
||||||
|
|
||||||
override fun <TF> isScript(file: TF): Boolean =
|
|
||||||
definitionData.scriptFilePattern?.let { Regex(it).matches(getFileName(file)) } ?: false
|
|
||||||
|
|
||||||
// TODO: implement other strategy - e.g. try to extract something from match with ScriptFilePattern
|
|
||||||
override fun getScriptName(script: KtScript): Name = ScriptNameUtil.fileNameWithExtensionStripped(script, KotlinParserDefinition.STD_SCRIPT_EXT)
|
|
||||||
|
|
||||||
override fun <TF> getDependenciesFor(file: TF, project: Project, previousDependencies: KotlinScriptExternalDependencies?): KotlinScriptExternalDependencies? {
|
|
||||||
|
|
||||||
val script = BasicScriptContents(file, getAnnotations = {
|
|
||||||
val classLoader = (template as Any).javaClass.classLoader
|
|
||||||
getAnnotationEntries(file, project)
|
|
||||||
.mapNotNull { psiAnn ->
|
|
||||||
// TODO: consider advanced matching using semantic similar to actual resolving
|
|
||||||
definitionData.acceptedAnnotations.find { ann ->
|
|
||||||
psiAnn.typeName.let { it == ann.simpleName || it == ann.qualifiedName }
|
|
||||||
}?.let { KtAnnotationWrapper(psiAnn, classLoader.loadClass(it.qualifiedName).kotlin as KClass<out Annotation>) }
|
|
||||||
}
|
|
||||||
.map { it.getProxy(classLoader) }
|
|
||||||
})
|
|
||||||
try {
|
|
||||||
val fileDeps = definitionData.resolver?.resolve(script, environment, ::logScriptDefMessage, previousDependencies)
|
|
||||||
// TODO: use it as a Future
|
|
||||||
return fileDeps?.get()
|
|
||||||
}
|
|
||||||
catch (ex: ClassCastException) {
|
|
||||||
logScriptDefMessage(ScriptDependenciesResolver.ReportSeverity.ERROR, ex.message ?: "Invalid script template: ${template.qualifiedName}", null)
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun <TF> getAnnotationEntries(file: TF, project: Project): Iterable<KtAnnotationEntry> = when (file) {
|
|
||||||
is PsiFile -> getAnnotationEntriesFromPsiFile(file)
|
|
||||||
is VirtualFile -> getAnnotationEntriesFromVirtualFile(file, project)
|
|
||||||
is File -> {
|
|
||||||
val virtualFile = (StandardFileSystems.local().findFileByPath(file.canonicalPath)
|
|
||||||
?: throw IllegalArgumentException("Unable to find file ${file.canonicalPath}"))
|
|
||||||
getAnnotationEntriesFromVirtualFile(virtualFile, project)
|
|
||||||
}
|
|
||||||
else -> throw IllegalArgumentException("Unsupported file type $file")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getAnnotationEntriesFromPsiFile(file: PsiFile) =
|
|
||||||
if (file is KtFile) file.annotationEntries
|
|
||||||
else throw IllegalArgumentException("Unable to extract kotlin annotations from ${file.name} (${file.fileType})")
|
|
||||||
|
|
||||||
private fun getAnnotationEntriesFromVirtualFile(file: VirtualFile, project: Project): Iterable<KtAnnotationEntry> {
|
|
||||||
val psiFile: PsiFile = PsiManager.getInstance(project).findFile(file)
|
|
||||||
?: throw IllegalArgumentException("Unable to load PSI from ${file.canonicalPath}")
|
|
||||||
return getAnnotationEntriesFromPsiFile(psiFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
class BasicScriptContents<out TF>(myFile: TF, getAnnotations: () -> Iterable<Annotation>) : ScriptContents {
|
|
||||||
override val file: File? by lazy { getFile(myFile) }
|
|
||||||
override val annotations: Iterable<Annotation> by lazy { getAnnotations() }
|
|
||||||
override val text: CharSequence? by lazy { getFileContents(myFile) }
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
internal val log = Logger.getInstance(KotlinScriptDefinitionFromTemplate::class.java)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun logScriptDefMessage(reportSeverity: ScriptDependenciesResolver.ReportSeverity, s: String, position: ScriptContents.Position?): Unit {
|
|
||||||
val msg = (position?.run { "[at $line:$col]" } ?: "") + s
|
|
||||||
when (reportSeverity) {
|
|
||||||
ScriptDependenciesResolver.ReportSeverity.ERROR -> KotlinScriptDefinitionFromTemplate.log.error(msg)
|
|
||||||
ScriptDependenciesResolver.ReportSeverity.WARNING -> KotlinScriptDefinitionFromTemplate.log.warn(msg)
|
|
||||||
ScriptDependenciesResolver.ReportSeverity.INFO -> KotlinScriptDefinitionFromTemplate.log.info(msg)
|
|
||||||
ScriptDependenciesResolver.ReportSeverity.DEBUG -> KotlinScriptDefinitionFromTemplate.log.debug(msg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+4
-4
@@ -48,13 +48,13 @@ interface ScriptTemplatesProvider {
|
|||||||
|
|
||||||
fun makeScriptDefsFromTemplatesProviderExtensions(project: Project,
|
fun makeScriptDefsFromTemplatesProviderExtensions(project: Project,
|
||||||
errorsHandler: ((ScriptTemplatesProvider, Exception) -> Unit) = { ep, ex -> throw ex }
|
errorsHandler: ((ScriptTemplatesProvider, Exception) -> Unit) = { ep, ex -> throw ex }
|
||||||
): List<KotlinScriptDefinitionFromTemplate> =
|
): List<KotlinScriptDefinitionFromAnnotatedTemplate> =
|
||||||
makeScriptDefsFromTemplatesProviders(Extensions.getArea(project).getExtensionPoint(ScriptTemplatesProvider.EP_NAME).extensions.asIterable(),
|
makeScriptDefsFromTemplatesProviders(Extensions.getArea(project).getExtensionPoint(ScriptTemplatesProvider.EP_NAME).extensions.asIterable(),
|
||||||
errorsHandler)
|
errorsHandler)
|
||||||
|
|
||||||
fun makeScriptDefsFromTemplatesProviders(providers: Iterable<ScriptTemplatesProvider>,
|
fun makeScriptDefsFromTemplatesProviders(providers: Iterable<ScriptTemplatesProvider>,
|
||||||
errorsHandler: ((ScriptTemplatesProvider, Exception) -> Unit) = { ep, ex -> throw ex }
|
errorsHandler: ((ScriptTemplatesProvider, Exception) -> Unit) = { ep, ex -> throw ex }
|
||||||
): List<KotlinScriptDefinitionFromTemplate> {
|
): List<KotlinScriptDefinitionFromAnnotatedTemplate> {
|
||||||
val idToVersion = hashMapOf<String, Int>()
|
val idToVersion = hashMapOf<String, Int>()
|
||||||
return providers.filter { it.isValid }.sortedByDescending { it.version }.flatMap { provider ->
|
return providers.filter { it.isValid }.sortedByDescending { it.version }.flatMap { provider ->
|
||||||
try {
|
try {
|
||||||
@@ -65,12 +65,12 @@ fun makeScriptDefsFromTemplatesProviders(providers: Iterable<ScriptTemplatesProv
|
|||||||
provider.templateClassNames.map {
|
provider.templateClassNames.map {
|
||||||
val cl = loader.loadClass(it)
|
val cl = loader.loadClass(it)
|
||||||
idToVersion.put(provider.id, provider.version)
|
idToVersion.put(provider.id, provider.version)
|
||||||
KotlinScriptDefinitionFromTemplate(cl.kotlin, provider.resolver, provider.filePattern, provider.environment)
|
KotlinScriptDefinitionFromAnnotatedTemplate(cl.kotlin, provider.resolver, provider.filePattern, provider.environment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ex: Exception) {
|
catch (ex: Exception) {
|
||||||
errorsHandler(provider, ex)
|
errorsHandler(provider, ex)
|
||||||
emptyList<KotlinScriptDefinitionFromTemplate>()
|
emptyList<KotlinScriptDefinitionFromAnnotatedTemplate>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.script
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.NotFoundClasses
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.findNonGenericClassAcrossDependencies
|
||||||
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
|
import org.jetbrains.kotlin.types.*
|
||||||
|
import kotlin.reflect.*
|
||||||
|
|
||||||
|
data class ScriptParameter(val name: Name, val type: KotlinType)
|
||||||
|
|
||||||
|
fun KotlinScriptDefinition.getScriptParameters(scriptDescriptor: ScriptDescriptor): List<ScriptParameter> =
|
||||||
|
template.primaryConstructor?.parameters
|
||||||
|
?.map { ScriptParameter(Name.identifier(it.name!!), getKotlinTypeByKType(scriptDescriptor, it.type)) }
|
||||||
|
?: emptyList()
|
||||||
|
|
||||||
|
fun getKotlinType(scriptDescriptor: ScriptDescriptor, kClass: KClass<out Any>): KotlinType =
|
||||||
|
getKotlinTypeByFqName(scriptDescriptor,
|
||||||
|
kClass.qualifiedName ?: throw java.lang.RuntimeException("Cannot get FQN from $kClass"))
|
||||||
|
|
||||||
|
fun getKotlinTypeByFqName(scriptDescriptor: ScriptDescriptor, fqName: String): KotlinType =
|
||||||
|
scriptDescriptor.module.findNonGenericClassAcrossDependencies(
|
||||||
|
ClassId.topLevel(FqName(fqName)),
|
||||||
|
NotFoundClasses(LockBasedStorageManager.NO_LOCKS, scriptDescriptor.module)
|
||||||
|
).defaultType
|
||||||
|
|
||||||
|
// TODO: support star projections
|
||||||
|
// TODO: support annotations on types and type parameters
|
||||||
|
// TODO: support type parameters on types and type projections
|
||||||
|
fun getKotlinTypeByKType(scriptDescriptor: ScriptDescriptor, kType: KType): KotlinType {
|
||||||
|
val classifier = kType.classifier
|
||||||
|
if (classifier !is KClass<*>)
|
||||||
|
throw java.lang.UnsupportedOperationException("Only classes are supported as parameters in script template: $classifier")
|
||||||
|
|
||||||
|
val type = getKotlinType(scriptDescriptor, classifier)
|
||||||
|
val typeProjections = kType.arguments.map { getTypeProjection(scriptDescriptor, it) }
|
||||||
|
val isNullable = kType.isMarkedNullable
|
||||||
|
|
||||||
|
return KotlinTypeFactory.simpleType(Annotations.EMPTY, type.constructor, typeProjections, isNullable)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getTypeProjection(scriptDescriptor: ScriptDescriptor, kTypeProjection: KTypeProjection): TypeProjection {
|
||||||
|
val kType = kTypeProjection.type ?: throw java.lang.UnsupportedOperationException("Star projections are not supported")
|
||||||
|
|
||||||
|
val type = getKotlinTypeByKType(scriptDescriptor, kType)
|
||||||
|
|
||||||
|
val variance = when (kTypeProjection.variance) {
|
||||||
|
KVariance.IN -> Variance.IN_VARIANCE
|
||||||
|
KVariance.OUT -> Variance.OUT_VARIANCE
|
||||||
|
KVariance.INVARIANT -> Variance.INVARIANT
|
||||||
|
null -> throw java.lang.UnsupportedOperationException("Star projections are not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
return TypeProjectionImpl(variance, type)
|
||||||
|
}
|
||||||
@@ -23,7 +23,8 @@ import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
|||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.addKotlinSourceRoots
|
import org.jetbrains.kotlin.config.addKotlinSourceRoots
|
||||||
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromTemplate
|
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
|
||||||
|
import org.jetbrains.kotlin.script.ScriptTemplateDefinition
|
||||||
import org.jetbrains.kotlin.scripts.ScriptWithIntParam
|
import org.jetbrains.kotlin.scripts.ScriptWithIntParam
|
||||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
@@ -32,8 +33,8 @@ import org.jetbrains.org.objectweb.asm.Opcodes
|
|||||||
|
|
||||||
class ScriptGenTest : CodegenTestCase() {
|
class ScriptGenTest : CodegenTestCase() {
|
||||||
companion object {
|
companion object {
|
||||||
private val FIB_SCRIPT_DEFINITION = KotlinScriptDefinitionFromTemplate(ScriptWithIntParam::class, scriptFilePattern = ".*\\.lang\\.kt")
|
private val FIB_SCRIPT_DEFINITION = KotlinScriptDefinitionFromAnnotatedTemplate(ScriptWithIntParam::class, providedScriptFilePattern = ".*\\.lang\\.kt")
|
||||||
private val NO_PARAM_SCRIPT_DEFINITION = KotlinScriptDefinitionFromTemplate(Any::class, scriptFilePattern = ".*\\.kts")
|
private val NO_PARAM_SCRIPT_DEFINITION = KotlinScriptDefinitionFromAnnotatedTemplate(Any::class, providedScriptFilePattern = ".*\\.kts")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setUp() {
|
override fun setUp() {
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ class ScriptTemplateTest {
|
|||||||
runIsolated: Boolean = true,
|
runIsolated: Boolean = true,
|
||||||
suppressOutput: Boolean = false,
|
suppressOutput: Boolean = false,
|
||||||
includeKotlinRuntime: Boolean = true): Class<*>? =
|
includeKotlinRuntime: Boolean = true): Class<*>? =
|
||||||
compileScriptImpl("compiler/testData/script/" + scriptPath, KotlinScriptDefinitionFromTemplate(scriptTemplate, null, null, environment), runIsolated, suppressOutput, includeKotlinRuntime)
|
compileScriptImpl("compiler/testData/script/" + scriptPath, KotlinScriptDefinitionFromAnnotatedTemplate(scriptTemplate, null, null, environment), runIsolated, suppressOutput, includeKotlinRuntime)
|
||||||
|
|
||||||
private fun compileScriptImpl(
|
private fun compileScriptImpl(
|
||||||
scriptPath: String,
|
scriptPath: String,
|
||||||
|
|||||||
@@ -16,12 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.descriptors;
|
package org.jetbrains.kotlin.descriptors;
|
||||||
|
|
||||||
import kotlin.Pair;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface ScriptDescriptor extends ClassDescriptor {
|
public interface ScriptDescriptor extends ClassDescriptor {
|
||||||
int getPriority();
|
int getPriority();
|
||||||
@@ -29,6 +24,4 @@ public interface ScriptDescriptor extends ClassDescriptor {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
ClassConstructorDescriptor getUnsubstitutedPrimaryConstructor();
|
ClassConstructorDescriptor getUnsubstitutedPrimaryConstructor();
|
||||||
|
|
||||||
List<Pair<Name, KotlinType>> getScriptParametersToPassToSuperclass();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -255,20 +255,6 @@ fun <D : CallableDescriptor> D.overriddenTreeUniqueAsSequence(useOriginal: Boole
|
|||||||
return doBuildOverriddenTreeAsSequence()
|
return doBuildOverriddenTreeAsSequence()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ClassDescriptor.getConstructorByParams(params: List<KotlinType>): ConstructorDescriptor? =
|
|
||||||
getConstructors().firstOrNull {
|
|
||||||
when {
|
|
||||||
it.valueParameters.isEmpty() && params.isEmpty() -> true
|
|
||||||
it.valueParameters.size != params.size -> false
|
|
||||||
else -> it.valueParameters.zip(params) { ctorP, p -> ctorP.type == p }.all { it }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: inline and remove as soon as all usage sies are converted to kotlin
|
|
||||||
fun getConstructorByParamsMap(classDescriptor: ClassDescriptor, params: List<Pair<Name, KotlinType>>): ConstructorDescriptor? =
|
|
||||||
classDescriptor.getConstructorByParams(params.map { it.second })
|
|
||||||
|
|
||||||
|
|
||||||
fun CallableDescriptor.varargParameterPosition() =
|
fun CallableDescriptor.varargParameterPosition() =
|
||||||
valueParameters.indexOfFirst { it.varargElementType != null }
|
valueParameters.indexOfFirst { it.varargElementType != null }
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -21,7 +21,7 @@ import com.intellij.openapi.vfs.VirtualFile
|
|||||||
import com.intellij.psi.ResolveScopeProvider
|
import com.intellij.psi.ResolveScopeProvider
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.idea.core.script.KotlinScriptConfigurationManager
|
import org.jetbrains.kotlin.idea.core.script.KotlinScriptConfigurationManager
|
||||||
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromTemplate
|
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
|
||||||
import org.jetbrains.kotlin.script.StandardScriptDefinition
|
import org.jetbrains.kotlin.script.StandardScriptDefinition
|
||||||
import org.jetbrains.kotlin.script.getScriptDefinition
|
import org.jetbrains.kotlin.script.getScriptDefinition
|
||||||
import kotlin.script.StandardScriptTemplate
|
import kotlin.script.StandardScriptTemplate
|
||||||
@@ -34,7 +34,7 @@ class KotlinScriptResolveScopeProvider : ResolveScopeProvider() {
|
|||||||
scriptDefinition == null -> null
|
scriptDefinition == null -> null
|
||||||
// This is a workaround for completion in scripts and REPL to provide module dependencies
|
// This is a workaround for completion in scripts and REPL to provide module dependencies
|
||||||
scriptDefinition == StandardScriptDefinition || scriptDefinition.template == Any::class -> null
|
scriptDefinition == StandardScriptDefinition || scriptDefinition.template == Any::class -> null
|
||||||
scriptDefinition is KotlinScriptDefinitionFromTemplate -> // TODO: should include the file itself
|
scriptDefinition is KotlinScriptDefinitionFromAnnotatedTemplate -> // TODO: should include the file itself
|
||||||
KotlinScriptConfigurationManager.getInstance(project).getAllScriptsClasspathScope()
|
KotlinScriptConfigurationManager.getInstance(project).getAllScriptsClasspathScope()
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ import org.jetbrains.kotlin.psi.moduleInfo
|
|||||||
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
|
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
|
||||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyScriptDescriptor
|
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyScriptDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.repl.ReplState
|
import org.jetbrains.kotlin.resolve.repl.ReplState
|
||||||
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromTemplate
|
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
||||||
import org.jetbrains.kotlin.script.KotlinScriptDefinitionProvider
|
import org.jetbrains.kotlin.script.KotlinScriptDefinitionProvider
|
||||||
import java.awt.Color
|
import java.awt.Color
|
||||||
import java.awt.Font
|
import java.awt.Font
|
||||||
@@ -124,7 +124,7 @@ class KotlinConsoleRunner(
|
|||||||
val executor = CommandExecutor(this)
|
val executor = CommandExecutor(this)
|
||||||
var compilerHelper: ConsoleCompilerHelper by Delegates.notNull()
|
var compilerHelper: ConsoleCompilerHelper by Delegates.notNull()
|
||||||
|
|
||||||
private val consoleScriptDefinition = object : KotlinScriptDefinitionFromTemplate(Any::class) {
|
private val consoleScriptDefinition = object : KotlinScriptDefinition(Any::class) {
|
||||||
override val name = "Kotlin REPL"
|
override val name = "Kotlin REPL"
|
||||||
override fun <TF> isScript(file: TF): Boolean {
|
override fun <TF> isScript(file: TF): Boolean {
|
||||||
val vf = when (file) {
|
val vf = when (file) {
|
||||||
|
|||||||
+2
-2
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
|
|||||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.addKotlinSourceRoot
|
import org.jetbrains.kotlin.config.addKotlinSourceRoot
|
||||||
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
||||||
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromTemplate
|
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
|
||||||
import org.jetbrains.kotlin.utils.PathUtil
|
import org.jetbrains.kotlin.utils.PathUtil
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@@ -99,7 +99,7 @@ done
|
|||||||
environment: Map<String, Any?>? = null,
|
environment: Map<String, Any?>? = null,
|
||||||
runIsolated: Boolean = true,
|
runIsolated: Boolean = true,
|
||||||
suppressOutput: Boolean = false): Class<*>? =
|
suppressOutput: Boolean = false): Class<*>? =
|
||||||
compileScriptImpl("src/test/resources/scripts/" + scriptFileName, KotlinScriptDefinitionFromTemplate(scriptTemplate, null, null, environment), runIsolated, suppressOutput)
|
compileScriptImpl("src/test/resources/scripts/" + scriptFileName, KotlinScriptDefinitionFromAnnotatedTemplate(scriptTemplate, null, null, environment), runIsolated, suppressOutput)
|
||||||
|
|
||||||
private fun compileScriptImpl(
|
private fun compileScriptImpl(
|
||||||
scriptPath: String,
|
scriptPath: String,
|
||||||
|
|||||||
Reference in New Issue
Block a user