Add diagnostic code to the ScriptDiagnostic
to allow checking for specific errors, e.g. incomplete statements in the REPL
This commit is contained in:
+1
@@ -55,6 +55,7 @@ fun configureMavenDepsOnAnnotations(context: ScriptConfigurationRefinementContex
|
|||||||
fun report(severity: ScriptDependenciesResolver.ReportSeverity, message: String, position: ScriptContents.Position?) {
|
fun report(severity: ScriptDependenciesResolver.ReportSeverity, message: String, position: ScriptContents.Position?) {
|
||||||
diagnostics.add(
|
diagnostics.add(
|
||||||
ScriptDiagnostic(
|
ScriptDiagnostic(
|
||||||
|
ScriptDiagnostic.unspecifiedError,
|
||||||
message,
|
message,
|
||||||
mapLegacyDiagnosticSeverity(severity),
|
mapLegacyDiagnosticSeverity(severity),
|
||||||
context.script.locationId,
|
context.script.locationId,
|
||||||
|
|||||||
@@ -14,12 +14,14 @@ import java.io.Serializable
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The single script diagnostic report
|
* The single script diagnostic report
|
||||||
|
* @param code diagnostic identifier
|
||||||
* @param message diagnostic message
|
* @param message diagnostic message
|
||||||
* @param severity diagnostic severity ({@link ScriptDiagnostic#Severity})
|
* @param severity diagnostic severity ({@link ScriptDiagnostic#Severity})
|
||||||
* @param location optional source location for the diagnostic
|
* @param location optional source location for the diagnostic
|
||||||
* @param exception optional exception caused the diagnostic
|
* @param exception optional exception caused the diagnostic
|
||||||
*/
|
*/
|
||||||
data class ScriptDiagnostic(
|
data class ScriptDiagnostic(
|
||||||
|
val code: Int,
|
||||||
val message: String,
|
val message: String,
|
||||||
val severity: Severity = Severity.ERROR,
|
val severity: Severity = Severity.ERROR,
|
||||||
val sourcePath: String? = null,
|
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]
|
* Makes Failure result with diagnostic [message] with optional [path] and [location]
|
||||||
*/
|
*/
|
||||||
fun makeFailureResult(message: String, path: String? = null, location: SourceCode.Location? = null): ResultWithDiagnostics.Failure =
|
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]
|
* Converts the receiver Throwable to the Failure results wrapper with optional [customMessage], [path] and [location]
|
||||||
*/
|
*/
|
||||||
fun Throwable.asDiagnostics(
|
fun Throwable.asDiagnostics(
|
||||||
|
code: Int = ScriptDiagnostic.unspecifiedException,
|
||||||
customMessage: String? = null,
|
customMessage: String? = null,
|
||||||
path: String? = null,
|
path: String? = null,
|
||||||
location: SourceCode.Location? = null,
|
location: SourceCode.Location? = null,
|
||||||
severity: ScriptDiagnostic.Severity = ScriptDiagnostic.Severity.ERROR
|
severity: ScriptDiagnostic.Severity = ScriptDiagnostic.Severity.ERROR
|
||||||
): ScriptDiagnostic =
|
): 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]
|
* Converts the receiver String to error diagnostic report with optional [path] and [location]
|
||||||
*/
|
*/
|
||||||
fun String.asErrorDiagnostics(path: String? = null, location: SourceCode.Location? = null): ScriptDiagnostic =
|
fun String.asErrorDiagnostics(
|
||||||
ScriptDiagnostic(this, ScriptDiagnostic.Severity.ERROR, path, location)
|
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
|
* Extracts the result value from the receiver wrapper or null if receiver represents a Failure
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ import kotlin.script.experimental.api.ScriptDiagnostic
|
|||||||
fun makeResolveFailureResult(message: String) = makeResolveFailureResult(listOf(message))
|
fun makeResolveFailureResult(message: String) = makeResolveFailureResult(listOf(message))
|
||||||
|
|
||||||
fun makeResolveFailureResult(messages: Iterable<String>) =
|
fun makeResolveFailureResult(messages: Iterable<String>) =
|
||||||
ResultWithDiagnostics.Failure(messages.map { ScriptDiagnostic(it, ScriptDiagnostic.Severity.WARNING) })
|
ResultWithDiagnostics.Failure(messages.map { ScriptDiagnostic(ScriptDiagnostic.unspecifiedError, it, ScriptDiagnostic.Severity.WARNING) })
|
||||||
|
|
||||||
fun RepositoryCoordinates.toRepositoryUrlOrNull(): URL? =
|
fun RepositoryCoordinates.toRepositoryUrlOrNull(): URL? =
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ class JsScriptEvaluator : ScriptEvaluator {
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
ResultWithDiagnostics.Failure(
|
ResultWithDiagnostics.Failure(
|
||||||
ScriptDiagnostic(
|
ScriptDiagnostic(
|
||||||
|
ScriptDiagnostic.unspecifiedError,
|
||||||
message = e.localizedMessage,
|
message = e.localizedMessage,
|
||||||
severity = ScriptDiagnostic.Severity.ERROR,
|
severity = ScriptDiagnostic.Severity.ERROR,
|
||||||
exception = e
|
exception = e
|
||||||
|
|||||||
+2
-2
@@ -44,7 +44,7 @@ open class BasicJvmScriptClassFilesGenerator(val outputDir: File) : ScriptEvalua
|
|||||||
return ResultWithDiagnostics.Success(EvaluationResult(ResultValue.NotEvaluated, scriptEvaluationConfiguration))
|
return ResultWithDiagnostics.Success(EvaluationResult(ResultValue.NotEvaluated, scriptEvaluationConfiguration))
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
return ResultWithDiagnostics.Failure(
|
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))
|
return ResultWithDiagnostics.Success(EvaluationResult(ResultValue.NotEvaluated, scriptEvaluationConfiguration))
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
return ResultWithDiagnostics.Failure(
|
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)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -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) }
|
pos?.let { ScriptReport.Position(pos.start.line, pos.start.col, pos.end?.line, pos.end?.col) }
|
||||||
|
|
||||||
fun Iterable<ScriptReport>.mapToDiagnostics(): List<ScriptDiagnostic> = map { (message, severity, position) ->
|
fun Iterable<ScriptReport>.mapToDiagnostics(): List<ScriptDiagnostic> = map { (message, severity, position) ->
|
||||||
ScriptDiagnostic(message, mapLegacyDiagnosticSeverity(severity), null, mapLegacyScriptPosition(position))
|
ScriptDiagnostic(
|
||||||
|
ScriptDiagnostic.unspecifiedError, message, mapLegacyDiagnosticSeverity(severity), null, mapLegacyScriptPosition(position)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Iterable<ScriptDiagnostic>.mapToLegacyReports(): List<ScriptReport> = map { (message, severity, _, location, exception) ->
|
fun Iterable<ScriptDiagnostic>.mapToLegacyReports(): List<ScriptReport> = map { (_, message, severity, _, location, exception) ->
|
||||||
val reportMessage = if (exception == null) message else "$message ($exception)"
|
val reportMessage = if (exception == null) message else "$message ($exception)"
|
||||||
ScriptReport(reportMessage, mapToLegacyScriptReportSeverity(severity), mapToLegacyScriptReportPosition(location))
|
ScriptReport(reportMessage, mapToLegacyScriptReportSeverity(severity), mapToLegacyScriptReportPosition(location))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ class KJvmCompiledScript<out ScriptBase : Any> internal constructor(
|
|||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
ResultWithDiagnostics.Failure(
|
ResultWithDiagnostics.Failure(
|
||||||
ScriptDiagnostic(
|
ScriptDiagnostic(
|
||||||
|
ScriptDiagnostic.unspecifiedError,
|
||||||
"Unable to instantiate class ${data.scriptClassFQName}",
|
"Unable to instantiate class ${data.scriptClassFQName}",
|
||||||
sourcePath = sourceLocationId,
|
sourcePath = sourceLocationId,
|
||||||
exception = e
|
exception = e
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ class MainKtsConfigurator : RefineScriptCompilationConfigurationHandler {
|
|||||||
fun report(severity: ScriptDependenciesResolver.ReportSeverity, message: String, position: ScriptContents.Position?) {
|
fun report(severity: ScriptDependenciesResolver.ReportSeverity, message: String, position: ScriptContents.Position?) {
|
||||||
diagnostics.add(
|
diagnostics.add(
|
||||||
ScriptDiagnostic(
|
ScriptDiagnostic(
|
||||||
|
ScriptDiagnostic.unspecifiedError,
|
||||||
message,
|
message,
|
||||||
mapLegacyDiagnosticSeverity(severity),
|
mapLegacyDiagnosticSeverity(severity),
|
||||||
context.script.locationId,
|
context.script.locationId,
|
||||||
|
|||||||
+3
-1
@@ -49,7 +49,9 @@ class ScriptCompilationConfigurationFromDefinition(
|
|||||||
}.orEmpty()
|
}.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
|
val resolvedDeps = (resolveResult as? DependenciesResolver.ResolveResult.Success)?.dependencies
|
||||||
|
|
||||||
if (resolvedDeps == null) ResultWithDiagnostics.Failure(reports)
|
if (resolvedDeps == null) ResultWithDiagnostics.Failure(reports)
|
||||||
|
|||||||
+2
-1
@@ -43,10 +43,11 @@ class JsScriptCompilerWithDependenciesProxy(private val environment: KotlinCoreE
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
is ReplCompileResult.Incomplete -> ResultWithDiagnostics.Failure(
|
is ReplCompileResult.Incomplete -> ResultWithDiagnostics.Failure(
|
||||||
ScriptDiagnostic("Incomplete code")
|
ScriptDiagnostic(ScriptDiagnostic.unspecifiedError, "Incomplete code")
|
||||||
)
|
)
|
||||||
is ReplCompileResult.Error -> ResultWithDiagnostics.Failure(
|
is ReplCompileResult.Error -> ResultWithDiagnostics.Failure(
|
||||||
ScriptDiagnostic(
|
ScriptDiagnostic(
|
||||||
|
ScriptDiagnostic.unspecifiedError,
|
||||||
message = compileResult.message,
|
message = compileResult.message,
|
||||||
severity = ScriptDiagnostic.Severity.ERROR
|
severity = ScriptDiagnostic.Severity.ERROR
|
||||||
)
|
)
|
||||||
|
|||||||
+1
-1
@@ -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)
|
parentMessageCollector?.report(severity, message, location)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -57,12 +57,14 @@ fun getScriptKtFile(
|
|||||||
return when {
|
return when {
|
||||||
ktFile == null -> ResultWithDiagnostics.Failure(
|
ktFile == null -> ResultWithDiagnostics.Failure(
|
||||||
ScriptDiagnostic(
|
ScriptDiagnostic(
|
||||||
|
ScriptDiagnostic.unspecifiedError,
|
||||||
message = "Cannot create PSI",
|
message = "Cannot create PSI",
|
||||||
severity = ScriptDiagnostic.Severity.ERROR
|
severity = ScriptDiagnostic.Severity.ERROR
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
ktFile.declarations.firstIsInstanceOrNull<KtScript>() == null -> ResultWithDiagnostics.Failure(
|
ktFile.declarations.firstIsInstanceOrNull<KtScript>() == null -> ResultWithDiagnostics.Failure(
|
||||||
ScriptDiagnostic(
|
ScriptDiagnostic(
|
||||||
|
ScriptDiagnostic.unspecifiedError,
|
||||||
message = "There is not Script",
|
message = "There is not Script",
|
||||||
severity = ScriptDiagnostic.Severity.ERROR
|
severity = ScriptDiagnostic.Severity.ERROR
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user