From b96109f23f4b30e73a8c9254c719754f64e7f89f Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Mon, 10 Feb 2020 18:03:00 +0100 Subject: [PATCH] Add diagnostic code to the ScriptDiagnostic to allow checking for specific errors, e.g. incomplete statements in the REPL --- .../examples/jvm/resolve/maven/scriptDef.kt | 1 + .../script/experimental/api/errorHandling.kt | 23 +++++++++++++++---- .../dependencies/impl/resolverUtils.kt | 2 +- .../scripting/repl/js/JsScriptEvaluator.kt | 1 + .../experimental/jvmhost/jvmScriptSaving.kt | 4 ++-- .../jvm/compat/diagnosticsUtil.kt | 6 +++-- .../jvm/impl/KJvmCompiledScript.kt | 1 + .../org/jetbrains/kotlin/mainKts/scriptDef.kt | 1 + ...tCompilationConfigurationFromDefinition.kt | 4 +++- .../plugin/impl/ScriptJsCompilerImpls.kt | 3 ++- .../compiler/plugin/impl/errorReporting.kt | 2 +- .../kotlin/scripting/repl/js/JsReplUtils.kt | 2 ++ 12 files changed, 38 insertions(+), 12 deletions(-) diff --git a/libraries/examples/scripting/jvm-maven-deps/script/src/org/jetbrains/kotlin/script/examples/jvm/resolve/maven/scriptDef.kt b/libraries/examples/scripting/jvm-maven-deps/script/src/org/jetbrains/kotlin/script/examples/jvm/resolve/maven/scriptDef.kt index f3ea09d9eca..0840f245ef8 100644 --- a/libraries/examples/scripting/jvm-maven-deps/script/src/org/jetbrains/kotlin/script/examples/jvm/resolve/maven/scriptDef.kt +++ b/libraries/examples/scripting/jvm-maven-deps/script/src/org/jetbrains/kotlin/script/examples/jvm/resolve/maven/scriptDef.kt @@ -55,6 +55,7 @@ fun configureMavenDepsOnAnnotations(context: ScriptConfigurationRefinementContex fun report(severity: ScriptDependenciesResolver.ReportSeverity, message: String, position: ScriptContents.Position?) { diagnostics.add( ScriptDiagnostic( + ScriptDiagnostic.unspecifiedError, message, mapLegacyDiagnosticSeverity(severity), context.script.locationId, diff --git a/libraries/scripting/common/src/kotlin/script/experimental/api/errorHandling.kt b/libraries/scripting/common/src/kotlin/script/experimental/api/errorHandling.kt index aded6656150..87d8a67510f 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/api/errorHandling.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/api/errorHandling.kt @@ -14,12 +14,14 @@ import java.io.Serializable /** * The single script diagnostic report + * @param code diagnostic identifier * @param message diagnostic message * @param severity diagnostic severity ({@link ScriptDiagnostic#Severity}) * @param location optional source location for the diagnostic * @param exception optional exception caused the diagnostic */ data class ScriptDiagnostic( + val code: Int, val message: String, val severity: Severity = Severity.ERROR, val sourcePath: String? = null, @@ -77,6 +79,14 @@ data class ScriptDiagnostic( } } } + + companion object { + private const val serialVersionUID: Long = 0L + + const val unspecifiedInfo = 0 + const val unspecifiedError = -1 + const val unspecifiedException = -2 + } } /** @@ -198,24 +208,29 @@ fun makeFailureResult(vararg reports: ScriptDiagnostic): ResultWithDiagnostics.F * Makes Failure result with diagnostic [message] with optional [path] and [location] */ fun makeFailureResult(message: String, path: String? = null, location: SourceCode.Location? = null): ResultWithDiagnostics.Failure = - ResultWithDiagnostics.Failure(message.asErrorDiagnostics(path, location)) + ResultWithDiagnostics.Failure(message.asErrorDiagnostics(ScriptDiagnostic.unspecifiedError, path, location)) /** * Converts the receiver Throwable to the Failure results wrapper with optional [customMessage], [path] and [location] */ fun Throwable.asDiagnostics( + code: Int = ScriptDiagnostic.unspecifiedException, customMessage: String? = null, path: String? = null, location: SourceCode.Location? = null, severity: ScriptDiagnostic.Severity = ScriptDiagnostic.Severity.ERROR ): ScriptDiagnostic = - ScriptDiagnostic(customMessage ?: message ?: "$this", severity, path, location, this) + ScriptDiagnostic(code, customMessage ?: message ?: "$this", severity, path, location, this) /** * Converts the receiver String to error diagnostic report with optional [path] and [location] */ -fun String.asErrorDiagnostics(path: String? = null, location: SourceCode.Location? = null): ScriptDiagnostic = - ScriptDiagnostic(this, ScriptDiagnostic.Severity.ERROR, path, location) +fun String.asErrorDiagnostics( + code: Int = ScriptDiagnostic.unspecifiedError, + path: String? = null, + location: SourceCode.Location? = null +): ScriptDiagnostic = + ScriptDiagnostic(code, this, ScriptDiagnostic.Severity.ERROR, path, location) /** * Extracts the result value from the receiver wrapper or null if receiver represents a Failure diff --git a/libraries/scripting/dependencies/src/kotlin/script/experimental/dependencies/impl/resolverUtils.kt b/libraries/scripting/dependencies/src/kotlin/script/experimental/dependencies/impl/resolverUtils.kt index effd28d74e4..cefd774f51e 100644 --- a/libraries/scripting/dependencies/src/kotlin/script/experimental/dependencies/impl/resolverUtils.kt +++ b/libraries/scripting/dependencies/src/kotlin/script/experimental/dependencies/impl/resolverUtils.kt @@ -14,7 +14,7 @@ import kotlin.script.experimental.api.ScriptDiagnostic fun makeResolveFailureResult(message: String) = makeResolveFailureResult(listOf(message)) fun makeResolveFailureResult(messages: Iterable) = - ResultWithDiagnostics.Failure(messages.map { ScriptDiagnostic(it, ScriptDiagnostic.Severity.WARNING) }) + ResultWithDiagnostics.Failure(messages.map { ScriptDiagnostic(ScriptDiagnostic.unspecifiedError, it, ScriptDiagnostic.Severity.WARNING) }) fun RepositoryCoordinates.toRepositoryUrlOrNull(): URL? = try { diff --git a/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsScriptEvaluator.kt b/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsScriptEvaluator.kt index 39708627e1f..b55815fca79 100644 --- a/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsScriptEvaluator.kt +++ b/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsScriptEvaluator.kt @@ -33,6 +33,7 @@ class JsScriptEvaluator : ScriptEvaluator { } catch (e: Exception) { ResultWithDiagnostics.Failure( ScriptDiagnostic( + ScriptDiagnostic.unspecifiedError, message = e.localizedMessage, severity = ScriptDiagnostic.Severity.ERROR, exception = e diff --git a/libraries/scripting/jvm-host/src/kotlin/script/experimental/jvmhost/jvmScriptSaving.kt b/libraries/scripting/jvm-host/src/kotlin/script/experimental/jvmhost/jvmScriptSaving.kt index e0bd9cd4b5b..0ba47e6a611 100644 --- a/libraries/scripting/jvm-host/src/kotlin/script/experimental/jvmhost/jvmScriptSaving.kt +++ b/libraries/scripting/jvm-host/src/kotlin/script/experimental/jvmhost/jvmScriptSaving.kt @@ -44,7 +44,7 @@ open class BasicJvmScriptClassFilesGenerator(val outputDir: File) : ScriptEvalua return ResultWithDiagnostics.Success(EvaluationResult(ResultValue.NotEvaluated, scriptEvaluationConfiguration)) } catch (e: Throwable) { return ResultWithDiagnostics.Failure( - e.asDiagnostics("Cannot generate script classes: ${e.message}", path = compiledScript.sourceLocationId) + e.asDiagnostics(customMessage = "Cannot generate script classes: ${e.message}", path = compiledScript.sourceLocationId) ) } } @@ -103,7 +103,7 @@ open class BasicJvmScriptJarGenerator(val outputJar: File) : ScriptEvaluator { return ResultWithDiagnostics.Success(EvaluationResult(ResultValue.NotEvaluated, scriptEvaluationConfiguration)) } catch (e: Throwable) { return ResultWithDiagnostics.Failure( - e.asDiagnostics("Cannot generate script jar: ${e.message}", path = compiledScript.sourceLocationId) + e.asDiagnostics(customMessage = "Cannot generate script jar: ${e.message}", path = compiledScript.sourceLocationId) ) } } diff --git a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/compat/diagnosticsUtil.kt b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/compat/diagnosticsUtil.kt index 3398356fd85..941d4dfdccb 100644 --- a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/compat/diagnosticsUtil.kt +++ b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/compat/diagnosticsUtil.kt @@ -51,10 +51,12 @@ fun mapToLegacyScriptReportPosition(pos: SourceCode.Location?): ScriptReport.Pos pos?.let { ScriptReport.Position(pos.start.line, pos.start.col, pos.end?.line, pos.end?.col) } fun Iterable.mapToDiagnostics(): List = map { (message, severity, position) -> - ScriptDiagnostic(message, mapLegacyDiagnosticSeverity(severity), null, mapLegacyScriptPosition(position)) + ScriptDiagnostic( + ScriptDiagnostic.unspecifiedError, message, mapLegacyDiagnosticSeverity(severity), null, mapLegacyScriptPosition(position) + ) } -fun Iterable.mapToLegacyReports(): List = map { (message, severity, _, location, exception) -> +fun Iterable.mapToLegacyReports(): List = map { (_, message, severity, _, location, exception) -> val reportMessage = if (exception == null) message else "$message ($exception)" ScriptReport(reportMessage, mapToLegacyScriptReportSeverity(severity), mapToLegacyScriptReportPosition(location)) } diff --git a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/impl/KJvmCompiledScript.kt b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/impl/KJvmCompiledScript.kt index 321bbb218b8..10821c05027 100644 --- a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/impl/KJvmCompiledScript.kt +++ b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/impl/KJvmCompiledScript.kt @@ -86,6 +86,7 @@ class KJvmCompiledScript internal constructor( } catch (e: Throwable) { ResultWithDiagnostics.Failure( ScriptDiagnostic( + ScriptDiagnostic.unspecifiedError, "Unable to instantiate class ${data.scriptClassFQName}", sourcePath = sourceLocationId, exception = e diff --git a/libraries/tools/kotlin-main-kts/src/org/jetbrains/kotlin/mainKts/scriptDef.kt b/libraries/tools/kotlin-main-kts/src/org/jetbrains/kotlin/mainKts/scriptDef.kt index f7b2bd5c958..5cd5b505724 100644 --- a/libraries/tools/kotlin-main-kts/src/org/jetbrains/kotlin/mainKts/scriptDef.kt +++ b/libraries/tools/kotlin-main-kts/src/org/jetbrains/kotlin/mainKts/scriptDef.kt @@ -109,6 +109,7 @@ class MainKtsConfigurator : RefineScriptCompilationConfigurationHandler { fun report(severity: ScriptDependenciesResolver.ReportSeverity, message: String, position: ScriptContents.Position?) { diagnostics.add( ScriptDiagnostic( + ScriptDiagnostic.unspecifiedError, message, mapLegacyDiagnosticSeverity(severity), context.script.locationId, diff --git a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptCompilationConfigurationFromDefinition.kt b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptCompilationConfigurationFromDefinition.kt index 1beba5cbcad..489542c4331 100644 --- a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptCompilationConfigurationFromDefinition.kt +++ b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptCompilationConfigurationFromDefinition.kt @@ -49,7 +49,9 @@ class ScriptCompilationConfigurationFromDefinition( }.orEmpty() ) - val reports = resolveResult.reports.map { ScriptDiagnostic(it.message, mapLegacyDiagnosticSeverity(it.severity)) } + val reports = resolveResult.reports.map { + ScriptDiagnostic(ScriptDiagnostic.unspecifiedError, it.message, mapLegacyDiagnosticSeverity(it.severity)) + } val resolvedDeps = (resolveResult as? DependenciesResolver.ResolveResult.Success)?.dependencies if (resolvedDeps == null) ResultWithDiagnostics.Failure(reports) diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJsCompilerImpls.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJsCompilerImpls.kt index 2feaf219856..5b35b73c0f8 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJsCompilerImpls.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJsCompilerImpls.kt @@ -43,10 +43,11 @@ class JsScriptCompilerWithDependenciesProxy(private val environment: KotlinCoreE ) } is ReplCompileResult.Incomplete -> ResultWithDiagnostics.Failure( - ScriptDiagnostic("Incomplete code") + ScriptDiagnostic(ScriptDiagnostic.unspecifiedError, "Incomplete code") ) is ReplCompileResult.Error -> ResultWithDiagnostics.Failure( ScriptDiagnostic( + ScriptDiagnostic.unspecifiedError, message = compileResult.message, severity = ScriptDiagnostic.Severity.ERROR ) diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/errorReporting.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/errorReporting.kt index db6481c305d..bfb7a520305 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/errorReporting.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/errorReporting.kt @@ -44,7 +44,7 @@ internal class ScriptDiagnosticsMessageCollector(private val parentMessageCollec ) ) } - _diagnostics.add(ScriptDiagnostic(message, mappedSeverity, location?.path, mappedLocation)) + _diagnostics.add(ScriptDiagnostic(ScriptDiagnostic.unspecifiedError, message, mappedSeverity, location?.path, mappedLocation)) } parentMessageCollector?.report(severity, message, location) } diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/repl/js/JsReplUtils.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/repl/js/JsReplUtils.kt index 77ac04ef37e..8bf781ca82c 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/repl/js/JsReplUtils.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/repl/js/JsReplUtils.kt @@ -57,12 +57,14 @@ fun getScriptKtFile( return when { ktFile == null -> ResultWithDiagnostics.Failure( ScriptDiagnostic( + ScriptDiagnostic.unspecifiedError, message = "Cannot create PSI", severity = ScriptDiagnostic.Severity.ERROR ) ) ktFile.declarations.firstIsInstanceOrNull() == null -> ResultWithDiagnostics.Failure( ScriptDiagnostic( + ScriptDiagnostic.unspecifiedError, message = "There is not Script", severity = ScriptDiagnostic.Severity.ERROR )