feat(ui/scripts): Roslyn-backed C# completions + diagnostics for Monaco
Adds Microsoft.CodeAnalysis.CSharp.Scripting (4.13.0). Scripts are
compiled as C# script fragments against a ScriptHost globals type
that mirrors what the runtime exposes (Parameters bag, CallShared,
CallScript) — Roslyn reads the signatures so those identifiers are
in scope for analysis without executing anything.
ScriptAnalysisService:
- Diagnose(code): Compilation.GetDiagnostics() projected to
Monaco-shaped DiagnosticMarker records (severity 8/4/2/1).
- Complete(code, line, col): dot-member lookup via SemanticModel
when the token at position is part of a MemberAccessExpression;
falls back to LookupSymbols at position for the general case.
Two endpoints exposed by the existing CentralUI endpoint pipeline,
both behind RequireDesign policy:
POST /api/script-analysis/diagnostics
POST /api/script-analysis/completions
monaco-init.js registers a csharp CompletionItemProvider with dot/
paren/quote trigger chars, plus a 500 ms debounced diagnostics pass
on every keystroke that pushes markers via setModelMarkers. Initial
pass fires on editor create so existing scripts surface errors right
away. Auth uses the existing cookie via credentials: same-origin.
Smoke-verified:
- Typing `DateTimeOffset.UtcNow` (no semicolon) shows the missing
semicolon squiggle in real time.
- Ctrl-Space at file scope returns the full type universe
(AccessViolationException, Action, Akka, AppDomain, ...).
Wave 2 of three. SCADA-specific extensions (declared param keys,
shared/sibling script names, forbidden-API diagnostic) follow.
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
namespace ScadaLink.CentralUI.ScriptAnalysis;
|
||||
|
||||
/// <summary>
|
||||
/// Globals type seen by user scripts. Mirrors the surface the runtime exposes
|
||||
/// today: Parameters bag plus CallShared / CallScript stubs. The methods here
|
||||
/// are never invoked — Roslyn only reads their signatures to know what's in
|
||||
/// scope while compiling for diagnostics + completions.
|
||||
/// </summary>
|
||||
public class ScriptHost
|
||||
{
|
||||
public IReadOnlyDictionary<string, object?> Parameters { get; init; } =
|
||||
new Dictionary<string, object?>();
|
||||
|
||||
/// <summary>Invokes another shared script by name and returns its result.</summary>
|
||||
public object? CallShared(string name, params object?[] args) => null;
|
||||
|
||||
/// <summary>Invokes another script on the same template and returns its result.</summary>
|
||||
public object? CallScript(string name, params object?[] args) => null;
|
||||
}
|
||||
Reference in New Issue
Block a user