Add possibility to get location of the script.main.kts file

#KT-48414 fixed
This commit is contained in:
Alexey Subach
2021-09-19 21:53:13 +03:00
committed by Ilya Chernikov
parent 7ddf83f32d
commit ca2f37f6eb
13 changed files with 177 additions and 7 deletions
@@ -33,3 +33,11 @@ annotation class Import(vararg val paths: String)
@Repeatable
@Retention(AnnotationRetention.SOURCE)
annotation class CompilerOptions(vararg val options: String)
/**
* Option that configures the name of the variable that will hold a file pointing to the script location.
* If not specified, {@link [SCRIPT_FILE_LOCATION_DEFAULT_VARIABLE_NAME]} will be used as the variable name
*/
@Target(AnnotationTarget.FILE)
@Retention(AnnotationRetention.SOURCE)
annotation class ScriptFileLocation(val variable: String)
@@ -40,15 +40,18 @@ abstract class MainKtsScript(val args: Array<String>)
const val COMPILED_SCRIPTS_CACHE_DIR_ENV_VAR = "KOTLIN_MAIN_KTS_COMPILED_SCRIPTS_CACHE_DIR"
const val COMPILED_SCRIPTS_CACHE_DIR_PROPERTY = "kotlin.main.kts.compiled.scripts.cache.dir"
const val COMPILED_SCRIPTS_CACHE_VERSION = 1
const val SCRIPT_FILE_LOCATION_DEFAULT_VARIABLE_NAME = "__FILE__"
class MainKtsScriptDefinition : ScriptCompilationConfiguration(
{
defaultImports(DependsOn::class, Repository::class, Import::class, CompilerOptions::class)
defaultImports(DependsOn::class, Repository::class, Import::class, CompilerOptions::class, ScriptFileLocation::class)
jvm {
dependenciesFromClassContext(MainKtsScriptDefinition::class, "kotlin-main-kts", "kotlin-stdlib", "kotlin-reflect")
}
refineConfiguration {
onAnnotations(DependsOn::class, Repository::class, Import::class, CompilerOptions::class, handler = MainKtsConfigurator())
onAnnotations(ScriptFileLocation::class, handler = ScriptFileLocationCustomConfigurator())
beforeCompiling(::configureScriptFileLocationPathVariablesForCompilation)
beforeCompiling(::configureProvidedPropertiesFromJsr223Context)
}
ide {
@@ -63,6 +66,7 @@ class MainKtsScriptDefinition : ScriptCompilationConfiguration(
object MainKtsEvaluationConfiguration : ScriptEvaluationConfiguration(
{
scriptsInstancesSharing(true)
refineConfigurationBeforeEvaluate(::configureScriptFileLocationPathVariablesForEvaluation)
refineConfigurationBeforeEvaluate(::configureProvidedPropertiesFromJsr223Context)
refineConfigurationBeforeEvaluate(::configureConstructorArgsFromMainArgs)
}
@@ -90,6 +94,48 @@ class MainKtsHostConfiguration : ScriptingHostConfiguration(
}
)
fun configureScriptFileLocationPathVariablesForEvaluation(context: ScriptEvaluationConfigurationRefinementContext): ResultWithDiagnostics<ScriptEvaluationConfiguration> {
val compilationConfiguration = context.evaluationConfiguration[ScriptEvaluationConfiguration.compilationConfiguration]
?: throw RuntimeException()
val scriptFileLocation = compilationConfiguration[ScriptCompilationConfiguration.scriptFileLocation]
?: return context.evaluationConfiguration.asSuccess()
val scriptFileLocationVariable = compilationConfiguration[ScriptCompilationConfiguration.scriptFileLocationVariable]
?: return context.evaluationConfiguration.asSuccess()
val res = context.evaluationConfiguration.with {
providedProperties.put(mapOf(scriptFileLocationVariable to scriptFileLocation))
}
return res.asSuccess()
}
fun configureScriptFileLocationPathVariablesForCompilation(context: ScriptConfigurationRefinementContext): ResultWithDiagnostics<ScriptCompilationConfiguration> {
val scriptFile = (context.script as? FileBasedScriptSource)?.file ?: return context.compilationConfiguration.asSuccess()
val scriptFileLocationVariableName = context.compilationConfiguration[ScriptCompilationConfiguration.scriptFileLocationVariable]
?: SCRIPT_FILE_LOCATION_DEFAULT_VARIABLE_NAME
return ScriptCompilationConfiguration(context.compilationConfiguration) {
providedProperties.put(mapOf(scriptFileLocationVariableName to KotlinType(File::class)))
scriptFileLocation.put(scriptFile)
scriptFileLocationVariable.put(scriptFileLocationVariableName)
}.asSuccess()
}
class ScriptFileLocationCustomConfigurator : RefineScriptCompilationConfigurationHandler {
override operator fun invoke(context: ScriptConfigurationRefinementContext): ResultWithDiagnostics<ScriptCompilationConfiguration> {
val scriptLocationVariable = context.collectedData?.get(ScriptCollectedData.collectedAnnotations)
?.filterByAnnotationType<ScriptFileLocation>()?.firstOrNull()?.annotation?.variable
?: return context.compilationConfiguration.asSuccess()
val compilationConfiguration = ScriptCompilationConfiguration(context.compilationConfiguration) {
scriptFileLocationVariable.put(scriptLocationVariable)
}
return compilationConfiguration.asSuccess()
}
}
fun configureConstructorArgsFromMainArgs(context: ScriptEvaluationConfigurationRefinementContext): ResultWithDiagnostics<ScriptEvaluationConfiguration> {
val mainArgs = context.evaluationConfiguration[ScriptEvaluationConfiguration.jvm.mainArguments]
val res = if (context.evaluationConfiguration[ScriptEvaluationConfiguration.constructorArgs] == null && mainArgs != null) {