Fix propagation of dependency resolution failure reports during script compilation
This commit is contained in:
committed by
Ilya Chernikov
parent
744dfc6bf9
commit
81e2e119e2
@@ -274,13 +274,15 @@ fun ScriptCompilationConfiguration.refineOnAnnotations(
|
|||||||
val foundAnnotationNames = collectedData[ScriptCollectedData.foundAnnotations]?.mapTo(HashSet()) { it.annotationClass.java.name }
|
val foundAnnotationNames = collectedData[ScriptCollectedData.foundAnnotations]?.mapTo(HashSet()) { it.annotationClass.java.name }
|
||||||
if (foundAnnotationNames.isNullOrEmpty()) return this.asSuccess()
|
if (foundAnnotationNames.isNullOrEmpty()) return this.asSuccess()
|
||||||
|
|
||||||
val refinedConfig = this[ScriptCompilationConfiguration.refineConfigurationOnAnnotations]
|
val thisResult: ResultWithDiagnostics<ScriptCompilationConfiguration> = this.asSuccess()
|
||||||
?.fold(this) { config, (annotations, handler) ->
|
return this[ScriptCompilationConfiguration.refineConfigurationOnAnnotations]
|
||||||
// checking that the collected data contains expected annotations
|
?.fold(thisResult) { config, (annotations, handler) ->
|
||||||
if (annotations.none { foundAnnotationNames.contains(it.typeName) }) config
|
config.onSuccess {
|
||||||
else handler.invoke(ScriptConfigurationRefinementContext(script, config, collectedData)).valueOr { return it }
|
// checking that the collected data contains expected annotations
|
||||||
}
|
if (annotations.none { foundAnnotationNames.contains(it.typeName) }) it.asSuccess()
|
||||||
return (refinedConfig ?: this).asSuccess()
|
else handler.invoke(ScriptConfigurationRefinementContext(script, it, collectedData))
|
||||||
|
}
|
||||||
|
} ?: thisResult
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ScriptCompilationConfiguration.refineBeforeCompiling(
|
fun ScriptCompilationConfiguration.refineBeforeCompiling(
|
||||||
|
|||||||
+34
-27
@@ -13,6 +13,8 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
|
|||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider
|
import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import kotlin.script.experimental.api.ResultWithDiagnostics
|
||||||
|
import kotlin.script.experimental.api.asSuccess
|
||||||
import kotlin.script.experimental.host.FileBasedScriptSource
|
import kotlin.script.experimental.host.FileBasedScriptSource
|
||||||
|
|
||||||
data class ScriptsCompilationDependencies(
|
data class ScriptsCompilationDependencies(
|
||||||
@@ -22,7 +24,7 @@ data class ScriptsCompilationDependencies(
|
|||||||
) {
|
) {
|
||||||
data class SourceDependencies(
|
data class SourceDependencies(
|
||||||
val scriptFile: KtFile,
|
val scriptFile: KtFile,
|
||||||
val sourceDependencies: List<KtFile>
|
val sourceDependencies: ResultWithDiagnostics<List<KtFile>>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,34 +44,39 @@ fun collectScriptsCompilationDependencies(
|
|||||||
while (true) {
|
while (true) {
|
||||||
val newRemainingSources = ArrayList<KtFile>()
|
val newRemainingSources = ArrayList<KtFile>()
|
||||||
for (source in remainingSources) {
|
for (source in remainingSources) {
|
||||||
val refinedConfiguration = importsProvider.getScriptConfiguration(source)
|
when (val refinedConfiguration = importsProvider.getScriptConfigurationResult(source)) {
|
||||||
if (refinedConfiguration != null) {
|
null -> {}
|
||||||
collectedClassPath.addAll(refinedConfiguration.dependenciesClassPath)
|
is ResultWithDiagnostics.Failure -> {
|
||||||
|
collectedSourceDependencies.add(ScriptsCompilationDependencies.SourceDependencies(source, refinedConfiguration))
|
||||||
val sourceDependenciesRoots = refinedConfiguration.importedScripts.mapNotNull {
|
|
||||||
// TODO: support any kind of ScriptSource.
|
|
||||||
val path = (it as? FileBasedScriptSource)?.file?.path ?: return@mapNotNull null
|
|
||||||
KotlinSourceRoot(path, false)
|
|
||||||
}
|
}
|
||||||
val sourceDependencies =
|
is ResultWithDiagnostics.Success -> {
|
||||||
createSourceFilesFromSourceRoots(
|
collectedClassPath.addAll(refinedConfiguration.value.dependenciesClassPath)
|
||||||
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
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
val newSources = sourceDependencies.filterNot { knownSourcePaths.contains(it.virtualFile.path) }
|
val sourceDependenciesRoots = refinedConfiguration.value.importedScripts.mapNotNull {
|
||||||
for (newSource in newSources) {
|
// TODO: support any kind of ScriptSource.
|
||||||
collectedSources.add(newSource)
|
val path = (it as? FileBasedScriptSource)?.file?.path ?: return@mapNotNull null
|
||||||
newRemainingSources.add(newSource)
|
KotlinSourceRoot(path, false)
|
||||||
knownSourcePaths.add(newSource.virtualFile.path)
|
}
|
||||||
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-1
@@ -103,6 +103,12 @@ class KJvmReplCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) :
|
|||||||
messageCollector
|
messageCollector
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val firstFailure = sourceDependencies.firstOrNull { it.sourceDependencies is ResultWithDiagnostics.Failure }
|
||||||
|
?.let { it.sourceDependencies as ResultWithDiagnostics.Failure }
|
||||||
|
|
||||||
|
if (firstFailure != null)
|
||||||
|
return firstFailure
|
||||||
|
|
||||||
if (history.isEmpty()) {
|
if (history.isEmpty()) {
|
||||||
val updatedConfiguration = ScriptDependenciesProvider.getInstance(context.environment.project)
|
val updatedConfiguration = ScriptDependenciesProvider.getInstance(context.environment.project)
|
||||||
?.getScriptConfiguration(snippetKtFile)?.configuration
|
?.getScriptConfiguration(snippetKtFile)?.configuration
|
||||||
@@ -165,7 +171,7 @@ class KJvmReplCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) :
|
|||||||
?: context.baseScriptCompilationConfiguration
|
?: context.baseScriptCompilationConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultWithDiagnostics.Success(compiledScript, messageCollector.diagnostics)
|
compiledScript.asSuccess(messageCollector.diagnostics)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -119,7 +119,7 @@ internal fun makeCompiledScript(
|
|||||||
|
|
||||||
val containingKtFile = script.containingKtFile
|
val containingKtFile = script.containingKtFile
|
||||||
val otherScripts: List<KJvmCompiledScript<*>> =
|
val otherScripts: List<KJvmCompiledScript<*>> =
|
||||||
sourceDependencies.find { it.scriptFile == containingKtFile }?.sourceDependencies?.mapNotNull { sourceFile ->
|
sourceDependencies.find { it.scriptFile == containingKtFile }?.sourceDependencies?.valueOrThrow()?.mapNotNull { sourceFile ->
|
||||||
sourceFile.declarations.firstIsInstanceOrNull<KtScript>()?.let {
|
sourceFile.declarations.firstIsInstanceOrNull<KtScript>()?.let {
|
||||||
KJvmCompiledScript<Any>(
|
KJvmCompiledScript<Any>(
|
||||||
containingKtFile.virtualFile?.path,
|
containingKtFile.virtualFile?.path,
|
||||||
|
|||||||
Reference in New Issue
Block a user