From 81e2e119e2949917d75b46b21ff2d23c16f8ff3b Mon Sep 17 00:00:00 2001 From: Anatoly Nikitin Date: Thu, 17 Oct 2019 19:54:36 +0300 Subject: [PATCH] Fix propagation of dependency resolution failure reports during script compilation --- .../experimental/api/scriptCompilation.kt | 16 ++--- .../ScriptsCompilationDependencies.kt | 61 +++++++++++-------- .../plugin/impl/KJvmReplCompilerImpl.kt | 8 ++- .../plugin/impl/jvmCompilationUtil.kt | 2 +- 4 files changed, 51 insertions(+), 36 deletions(-) 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 6b813cfcc43..4d89065f01b 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptCompilation.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptCompilation.kt @@ -274,13 +274,15 @@ fun ScriptCompilationConfiguration.refineOnAnnotations( val foundAnnotationNames = collectedData[ScriptCollectedData.foundAnnotations]?.mapTo(HashSet()) { it.annotationClass.java.name } if (foundAnnotationNames.isNullOrEmpty()) return this.asSuccess() - val refinedConfig = this[ScriptCompilationConfiguration.refineConfigurationOnAnnotations] - ?.fold(this) { config, (annotations, handler) -> - // checking that the collected data contains expected annotations - if (annotations.none { foundAnnotationNames.contains(it.typeName) }) config - else handler.invoke(ScriptConfigurationRefinementContext(script, config, collectedData)).valueOr { return it } - } - return (refinedConfig ?: this).asSuccess() + val thisResult: ResultWithDiagnostics = this.asSuccess() + return this[ScriptCompilationConfiguration.refineConfigurationOnAnnotations] + ?.fold(thisResult) { config, (annotations, handler) -> + config.onSuccess { + // checking that the collected data contains expected annotations + if (annotations.none { foundAnnotationNames.contains(it.typeName) }) it.asSuccess() + else handler.invoke(ScriptConfigurationRefinementContext(script, it, collectedData)) + } + } ?: thisResult } fun ScriptCompilationConfiguration.refineBeforeCompiling( diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/dependencies/ScriptsCompilationDependencies.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/dependencies/ScriptsCompilationDependencies.kt index 01888502958..d446e99056d 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/dependencies/ScriptsCompilationDependencies.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/dependencies/ScriptsCompilationDependencies.kt @@ -13,6 +13,8 @@ import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider import java.io.File +import kotlin.script.experimental.api.ResultWithDiagnostics +import kotlin.script.experimental.api.asSuccess import kotlin.script.experimental.host.FileBasedScriptSource data class ScriptsCompilationDependencies( @@ -22,7 +24,7 @@ data class ScriptsCompilationDependencies( ) { data class SourceDependencies( val scriptFile: KtFile, - val sourceDependencies: List + val sourceDependencies: ResultWithDiagnostics> ) } @@ -42,34 +44,39 @@ fun collectScriptsCompilationDependencies( while (true) { val newRemainingSources = ArrayList() for (source in remainingSources) { - val refinedConfiguration = importsProvider.getScriptConfiguration(source) - if (refinedConfiguration != null) { - collectedClassPath.addAll(refinedConfiguration.dependenciesClassPath) - - val sourceDependenciesRoots = refinedConfiguration.importedScripts.mapNotNull { - // TODO: support any kind of ScriptSource. - val path = (it as? FileBasedScriptSource)?.file?.path ?: return@mapNotNull null - KotlinSourceRoot(path, false) + when (val refinedConfiguration = importsProvider.getScriptConfigurationResult(source)) { + null -> {} + is ResultWithDiagnostics.Failure -> { + collectedSourceDependencies.add(ScriptsCompilationDependencies.SourceDependencies(source, refinedConfiguration)) } - val sourceDependencies = - createSourceFilesFromSourceRoots( - configuration, project, sourceDependenciesRoots, - // TODO: consider receiving and using precise location from the resolver in the future - source.virtualFile?.path?.let { CompilerMessageLocation.create(it) } - ) - if (sourceDependencies.isNotEmpty()) { - collectedSourceDependencies.add( - ScriptsCompilationDependencies.SourceDependencies( - source, - sourceDependencies - ) - ) + is ResultWithDiagnostics.Success -> { + collectedClassPath.addAll(refinedConfiguration.value.dependenciesClassPath) - val newSources = sourceDependencies.filterNot { knownSourcePaths.contains(it.virtualFile.path) } - for (newSource in newSources) { - collectedSources.add(newSource) - newRemainingSources.add(newSource) - knownSourcePaths.add(newSource.virtualFile.path) + val sourceDependenciesRoots = refinedConfiguration.value.importedScripts.mapNotNull { + // TODO: support any kind of ScriptSource. + val path = (it as? FileBasedScriptSource)?.file?.path ?: return@mapNotNull null + KotlinSourceRoot(path, false) + } + val sourceDependencies = + createSourceFilesFromSourceRoots( + configuration, project, sourceDependenciesRoots, + // TODO: consider receiving and using precise location from the resolver in the future + source.virtualFile?.path?.let { CompilerMessageLocation.create(it) } + ) + if (sourceDependencies.isNotEmpty()) { + collectedSourceDependencies.add( + ScriptsCompilationDependencies.SourceDependencies( + source, + sourceDependencies.asSuccess(refinedConfiguration.reports) + ) + ) + + val newSources = sourceDependencies.filterNot { knownSourcePaths.contains(it.virtualFile.path) } + for (newSource in newSources) { + collectedSources.add(newSource) + newRemainingSources.add(newSource) + knownSourcePaths.add(newSource.virtualFile.path) + } } } } diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerImpl.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerImpl.kt index 0fd6f33a81b..f62c4502b17 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerImpl.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerImpl.kt @@ -103,6 +103,12 @@ class KJvmReplCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) : messageCollector ) + val firstFailure = sourceDependencies.firstOrNull { it.sourceDependencies is ResultWithDiagnostics.Failure } + ?.let { it.sourceDependencies as ResultWithDiagnostics.Failure } + + if (firstFailure != null) + return firstFailure + if (history.isEmpty()) { val updatedConfiguration = ScriptDependenciesProvider.getInstance(context.environment.project) ?.getScriptConfiguration(snippetKtFile)?.configuration @@ -165,7 +171,7 @@ class KJvmReplCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) : ?: context.baseScriptCompilationConfiguration } - ResultWithDiagnostics.Success(compiledScript, messageCollector.diagnostics) + compiledScript.asSuccess(messageCollector.diagnostics) } } diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/jvmCompilationUtil.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/jvmCompilationUtil.kt index 00ab1e57b7f..6a2ac4e4faa 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/jvmCompilationUtil.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/jvmCompilationUtil.kt @@ -119,7 +119,7 @@ internal fun makeCompiledScript( val containingKtFile = script.containingKtFile val otherScripts: List> = - sourceDependencies.find { it.scriptFile == containingKtFile }?.sourceDependencies?.mapNotNull { sourceFile -> + sourceDependencies.find { it.scriptFile == containingKtFile }?.sourceDependencies?.valueOrThrow()?.mapNotNull { sourceFile -> sourceFile.declarations.firstIsInstanceOrNull()?.let { KJvmCompiledScript( containingKtFile.virtualFile?.path,