using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
namespace ZB.MOM.WW.ScadaBridge.ScriptAnalysis;
///
/// M3.1: the single authoritative Roslyn compile gate. Ported from the
/// SiteRuntime ScriptCompilationService.CompileCore, but returns
/// diagnostic messages rather than a compiled Script delegate — this is
/// the design-time gate (the deploy-time validation that previously relied on
/// the FAKE substring + brace-balance check in
/// TemplateEngine/Validation/ScriptCompiler.cs), which needs to know
/// whether the script compiles, not to execute it.
///
public static class RoslynScriptCompiler
{
///
/// Parses the script as C# script source and returns syntax-error diagnostic
/// messages (severity Error only). Empty list means the script parses.
///
/// The C# script source to parse.
/// Error-severity parse diagnostic messages; empty if the script parses.
public static IReadOnlyList ParseDiagnostics(string code)
{
var tree = CSharpSyntaxTree.ParseText(
code, new CSharpParseOptions(kind: SourceCodeKind.Script));
return tree.GetDiagnostics()
.Where(d => d.Severity == DiagnosticSeverity.Error)
.Select(d => d.GetMessage())
.ToList();
}
///
/// Compiles the script against the trust-model references and imports and
/// returns error-severity compilation diagnostic messages. Empty list means
/// the script compiles cleanly against .
///
/// The C# script source to compile.
///
/// Optional globals type the script binds against — e.g.
/// ScriptCompileSurface for instance/shared scripts or
/// TriggerCompileSurface for trigger expressions.
///
/// Optional additional metadata references.
/// Optional additional namespace imports.
/// Error-severity compile diagnostic messages; empty if the script compiles.
public static IReadOnlyList Compile(
string code,
Type? globalsType = null,
IEnumerable? extraReferences = null,
IEnumerable? extraImports = null)
{
try
{
var references = ScriptTrustPolicy.DefaultReferences.ToList();
if (extraReferences != null)
references.AddRange(extraReferences);
var imports = ScriptTrustPolicy.DefaultImports.AsEnumerable();
if (extraImports != null)
imports = imports.Concat(extraImports);
var options = ScriptOptions.Default
.WithReferences(references)
.WithImports(imports);
var script = CSharpScript.Create