diff --git a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptCompilation.kt b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptCompilation.kt index 99d59f7e7f4..7e77aad4fb7 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptCompilation.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptCompilation.kt @@ -90,13 +90,18 @@ val ScriptCompilationConfigurationKeys.compilerOptions by PropertiesCollection.k /** * The callback that will be called on the script compilation before parsing the script */ -val ScriptCompilationConfigurationKeys.refineConfigurationBeforeParsing by PropertiesCollection.key() +val ScriptCompilationConfigurationKeys.refineConfigurationBeforeParsing by PropertiesCollection.key() /** * The callback that will be called on the script compilation after parsing script file annotations */ val ScriptCompilationConfigurationKeys.refineConfigurationOnAnnotations by PropertiesCollection.key() +/** + * The callback that will be called on the script compilation immediately before starting the compilation + */ +val ScriptCompilationConfigurationKeys.refineConfigurationBeforeCompiling by PropertiesCollection.key() + /** * The list of script fragments that should be compiled intead of the whole text * (for use primary with the refinement callbacks) @@ -116,7 +121,7 @@ class RefineConfigurationBuilder : PropertiesCollection.Builder() { * @param handler the callback that will be called */ fun beforeParsing(handler: RefineScriptCompilationConfigurationHandler) { - set(ScriptCompilationConfiguration.refineConfigurationBeforeParsing, RefineConfigurationBeforeParsingData(handler)) + set(ScriptCompilationConfiguration.refineConfigurationBeforeParsing, RefineConfigurationUnconditionallyData(handler)) } /** @@ -125,6 +130,7 @@ class RefineConfigurationBuilder : PropertiesCollection.Builder() { * @param handler the callback that will be called */ fun onAnnotations(annotations: List, handler: RefineScriptCompilationConfigurationHandler) { + // TODO: implement handlers composition set(ScriptCompilationConfiguration.refineConfigurationOnAnnotations, RefineConfigurationOnAnnotationsData(annotations, handler)) } @@ -139,7 +145,7 @@ class RefineConfigurationBuilder : PropertiesCollection.Builder() { /** * The callback that will be called on the script compilation after parsing script file annotations - * @param annotations the list of annotations to trigger the callback on + * @param T the annotation to trigger the callback on * @param handler the callback that will be called */ inline fun onAnnotations(noinline handler: RefineScriptCompilationConfigurationHandler) { @@ -163,6 +169,14 @@ class RefineConfigurationBuilder : PropertiesCollection.Builder() { fun onAnnotations(annotations: Iterable>, handler: RefineScriptCompilationConfigurationHandler) { onAnnotations(annotations.map { KotlinType(it) }, handler) } + + /** + * The callback that will be called on the script compilation immediately before starting the compilation + * @param handler the callback that will be called + */ + fun beforeCompiling(handler: RefineScriptCompilationConfigurationHandler) { + set(ScriptCompilationConfiguration.refineConfigurationBeforeCompiling, RefineConfigurationUnconditionallyData(handler)) + } } /** @@ -171,7 +185,7 @@ class RefineConfigurationBuilder : PropertiesCollection.Builder() { typealias RefineScriptCompilationConfigurationHandler = (ScriptConfigurationRefinementContext) -> ResultWithDiagnostics -class RefineConfigurationBeforeParsingData( +class RefineConfigurationUnconditionallyData( val handler: RefineScriptCompilationConfigurationHandler ) : Serializable diff --git a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/impl/BridgeDependenciesResolver.kt b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/impl/BridgeDependenciesResolver.kt index ebc81d8645a..cd256927407 100644 --- a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/impl/BridgeDependenciesResolver.kt +++ b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/impl/BridgeDependenciesResolver.kt @@ -44,19 +44,22 @@ class BridgeDependenciesResolver( val defaultImports = scriptCompilationConfiguration[ScriptCompilationConfiguration.defaultImports]?.toList() ?: emptyList() - val refineFn = scriptCompilationConfiguration[ScriptCompilationConfiguration.refineConfigurationOnAnnotations]?.handler - ?: return DependenciesResolver.ResolveResult.Success( - ScriptDependencies( - classpath = oldClasspath, - sources = scriptCompilationConfiguration[ScriptCompilationConfiguration.ide.dependenciesSources].toClassPathOrEmpty(), - imports = defaultImports - ), - diagnostics - ) - - val refineResults = refineFn( - ScriptConfigurationRefinementContext(scriptContents.toScriptSource(), scriptCompilationConfiguration, processedScriptData) + fun ScriptCompilationConfiguration.toDependencies(classpath: List): ScriptDependencies = ScriptDependencies( + classpath = classpath, + sources = this[ScriptCompilationConfiguration.ide.dependenciesSources].toClassPathOrEmpty(), + imports = defaultImports ) + + val refineResults = scriptCompilationConfiguration.refineWith( + scriptCompilationConfiguration[ScriptCompilationConfiguration.refineConfigurationOnAnnotations]?.handler, + scriptContents, processedScriptData + ).onSuccess { + it.refineWith( + scriptCompilationConfiguration[ScriptCompilationConfiguration.refineConfigurationBeforeCompiling]?.handler, + scriptContents, processedScriptData + ) + } + val refinedConfiguration = when (refineResults) { is ResultWithDiagnostics.Failure -> return DependenciesResolver.ResolveResult.Failure(refineResults.reports.mapScriptReportsToDiagnostics()) @@ -98,3 +101,20 @@ internal fun ScriptContents.toScriptSource(): SourceCode = when { } internal fun List?.toClassPathOrEmpty() = this?.flatMap { (it as JvmDependency).classpath } ?: emptyList() + +internal fun List?.toFilesOrEmpty() = this?.map { + val externalSource = it as? ExternalSourceCode + externalSource?.externalLocation?.toFile() + ?: throw RuntimeException("Unsupported source in requireSources parameter - only local files are supported now (${externalSource?.externalLocation})") +} ?: emptyList() + +fun ScriptCompilationConfiguration.refineWith( + handler: RefineScriptCompilationConfigurationHandler?, scriptContents: ScriptContents, processedScriptData: ScriptCollectedData +): ResultWithDiagnostics { + + if (handler == null) return this.asSuccess() + + return handler( + ScriptConfigurationRefinementContext(scriptContents.toScriptSource(), this, processedScriptData) + ) +} \ No newline at end of file