docs: backfill XML documentation across 756 files
v2-ci / build (push) Failing after 1m43s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
v2-ci / build (push) Failing after 1m43s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
Adds <summary>, <param>, <typeparam>, and <inheritdoc/> tags to public members surfaced by commentchecker — resolves 5,847 of 5,869 issues (99.6%) across three /fixdocs passes.
This commit is contained in:
@@ -52,6 +52,8 @@ public sealed class CompiledScriptCache<TContext, TResult> : IDisposable
|
||||
/// the next call retries (useful during Admin UI authoring when the operator is
|
||||
/// still fixing syntax).
|
||||
/// </summary>
|
||||
/// <param name="scriptSource">The source code to compile or retrieve from cache.</param>
|
||||
/// <returns>The compiled script evaluator.</returns>
|
||||
public ScriptEvaluator<TContext, TResult> GetOrCompile(string scriptSource)
|
||||
{
|
||||
if (scriptSource is null) throw new ArgumentNullException(nameof(scriptSource));
|
||||
@@ -116,6 +118,8 @@ public sealed class CompiledScriptCache<TContext, TResult> : IDisposable
|
||||
}
|
||||
|
||||
/// <summary>True when the exact source has been compiled at least once + is still cached.</summary>
|
||||
/// <param name="scriptSource">The source code to check for in the cache.</param>
|
||||
/// <returns>True if the source is cached, false otherwise.</returns>
|
||||
public bool Contains(string scriptSource)
|
||||
=> _cache.ContainsKey(HashSource(scriptSource));
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ public static class DependencyExtractor
|
||||
/// Parse <paramref name="scriptSource"/> + return the inferred read + write tag
|
||||
/// paths, or a list of rejection messages if non-literal paths were used.
|
||||
/// </summary>
|
||||
/// <param name="scriptSource">The script source code to analyze.</param>
|
||||
public static DependencyExtractionResult Extract(string scriptSource)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(scriptSource))
|
||||
@@ -65,10 +66,14 @@ public static class DependencyExtractor
|
||||
private readonly HashSet<string> _writes = new(StringComparer.Ordinal);
|
||||
private readonly List<DependencyRejection> _rejections = [];
|
||||
|
||||
/// <summary>Gets the set of tags read by the script.</summary>
|
||||
public IReadOnlySet<string> Reads => _reads;
|
||||
/// <summary>Gets the set of tags written by the script.</summary>
|
||||
public IReadOnlySet<string> Writes => _writes;
|
||||
/// <summary>Gets the list of rejections for non-literal tag paths.</summary>
|
||||
public IReadOnlyList<DependencyRejection> Rejections => _rejections;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void VisitInvocationExpression(InvocationExpressionSyntax node)
|
||||
{
|
||||
// Only interested in ctx.GetTag(...) / ctx.SetVirtualTag(...) — member-access
|
||||
|
||||
@@ -143,6 +143,8 @@ public static class ForbiddenTypeAnalyzer
|
||||
/// Returns empty list when the script is clean; non-empty list means the script
|
||||
/// must be rejected at publish with the rejections surfaced to the operator.
|
||||
/// </summary>
|
||||
/// <param name="compilation">The compilation to analyze.</param>
|
||||
/// <returns>A list of forbidden type rejections, or empty if the script is clean.</returns>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The walker has two passes per node. Pass (1) is the member / call surface:
|
||||
@@ -314,8 +316,11 @@ public sealed record ForbiddenTypeRejection(
|
||||
/// post-compile forbidden-type analyzer finds references to denied namespaces.</summary>
|
||||
public sealed class ScriptSandboxViolationException : Exception
|
||||
{
|
||||
/// <summary>Gets the list of forbidden type rejections that triggered this exception.</summary>
|
||||
public IReadOnlyList<ForbiddenTypeRejection> Rejections { get; }
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="ScriptSandboxViolationException"/> class.</summary>
|
||||
/// <param name="rejections">The list of forbidden type rejections found in the script.</param>
|
||||
public ScriptSandboxViolationException(IReadOnlyList<ForbiddenTypeRejection> rejections)
|
||||
: base(BuildMessage(rejections))
|
||||
{
|
||||
|
||||
@@ -40,6 +40,7 @@ public abstract class ScriptContext
|
||||
/// dependency set is required for the change-driven scheduler to subscribe to the
|
||||
/// right upstream tags at load time.
|
||||
/// </remarks>
|
||||
/// <param name="path">The literal tag path to read.</param>
|
||||
public abstract DataValueSnapshot GetTag(string path);
|
||||
|
||||
/// <summary>
|
||||
@@ -53,6 +54,8 @@ public abstract class ScriptContext
|
||||
/// extractor tracks the write targets so the engine knows what downstream
|
||||
/// subscribers to notify.
|
||||
/// </remarks>
|
||||
/// <param name="path">The literal tag path to write to.</param>
|
||||
/// <param name="value">The value to write to the virtual tag.</param>
|
||||
public abstract void SetVirtualTag(string path, object? value);
|
||||
|
||||
/// <summary>
|
||||
@@ -75,6 +78,9 @@ public abstract class ScriptContext
|
||||
/// Useful for alarm predicates that shouldn't flicker on small noise. Pure
|
||||
/// function; no side effects.
|
||||
/// </summary>
|
||||
/// <param name="current">The current value to check.</param>
|
||||
/// <param name="previous">The previous value to compare against.</param>
|
||||
/// <param name="tolerance">The minimum difference threshold for a change to be detected.</param>
|
||||
public static bool Deadband(double current, double previous, double tolerance)
|
||||
=> Math.Abs(current - previous) > tolerance;
|
||||
}
|
||||
|
||||
@@ -64,6 +64,8 @@ public sealed class ScriptEvaluator<TContext, TResult> : IDisposable
|
||||
_func = func;
|
||||
}
|
||||
|
||||
/// <summary>Compiles user script source into an evaluator.</summary>
|
||||
/// <param name="scriptSource">The user script source code to compile.</param>
|
||||
public static ScriptEvaluator<TContext, TResult> Compile(string scriptSource)
|
||||
{
|
||||
if (scriptSource is null) throw new ArgumentNullException(nameof(scriptSource));
|
||||
@@ -168,7 +170,9 @@ public sealed class ScriptEvaluator<TContext, TResult> : IDisposable
|
||||
return new ScriptEvaluator<TContext, TResult>(alc, func);
|
||||
}
|
||||
|
||||
/// <summary>Run against an already-constructed context.</summary>
|
||||
/// <summary>Runs the script against an already-constructed context.</summary>
|
||||
/// <param name="context">The script context.</param>
|
||||
/// <param name="ct">Cancellation token for the operation.</param>
|
||||
public Task<TResult> RunAsync(TContext context, CancellationToken ct = default)
|
||||
{
|
||||
if (_disposed) throw new ObjectDisposedException(nameof(ScriptEvaluator<TContext, TResult>));
|
||||
@@ -384,10 +388,13 @@ public sealed class ScriptEvaluator<TContext, TResult> : IDisposable
|
||||
/// </summary>
|
||||
internal sealed class ScriptAssemblyLoadContext : AssemblyLoadContext
|
||||
{
|
||||
/// <summary>Initializes a new instance of the <see cref="ScriptAssemblyLoadContext"/> class.</summary>
|
||||
/// <param name="name">The name of the assembly load context.</param>
|
||||
public ScriptAssemblyLoadContext(string name) : base(name, isCollectible: true)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Assembly? Load(AssemblyName assemblyName) => null;
|
||||
}
|
||||
|
||||
@@ -400,8 +407,11 @@ internal sealed class ScriptAssemblyLoadContext : AssemblyLoadContext
|
||||
/// </summary>
|
||||
public sealed class CompilationErrorException : Exception
|
||||
{
|
||||
/// <summary>Gets the compilation diagnostics that caused the error.</summary>
|
||||
public IReadOnlyList<Diagnostic> Diagnostics { get; }
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="CompilationErrorException"/> class.</summary>
|
||||
/// <param name="diagnostics">The compilation diagnostics that caused the error.</param>
|
||||
public CompilationErrorException(IReadOnlyList<Diagnostic> diagnostics)
|
||||
: base(BuildMessage(diagnostics))
|
||||
{
|
||||
|
||||
@@ -15,5 +15,6 @@ namespace ZB.MOM.WW.OtOpcUa.Core.Scripting;
|
||||
public class ScriptGlobals<TContext>
|
||||
where TContext : ScriptContext
|
||||
{
|
||||
/// <summary>Gets or sets the script context available to scripts.</summary>
|
||||
public TContext ctx { get; set; } = default!;
|
||||
}
|
||||
|
||||
@@ -30,12 +30,17 @@ public sealed class ScriptLogCompanionSink : ILogEventSink
|
||||
private readonly ILogger _mainLogger;
|
||||
private readonly LogEventLevel _minMirrorLevel;
|
||||
|
||||
/// <summary>Initializes a new instance of the ScriptLogCompanionSink.</summary>
|
||||
/// <param name="mainLogger">The companion logger to mirror events to.</param>
|
||||
/// <param name="minMirrorLevel">The minimum log level to mirror (default: Error).</param>
|
||||
public ScriptLogCompanionSink(ILogger mainLogger, LogEventLevel minMirrorLevel = LogEventLevel.Error)
|
||||
{
|
||||
_mainLogger = mainLogger ?? throw new ArgumentNullException(nameof(mainLogger));
|
||||
_minMirrorLevel = minMirrorLevel;
|
||||
}
|
||||
|
||||
/// <summary>Emits a log event to the companion logger if it meets the minimum level.</summary>
|
||||
/// <param name="logEvent">The log event to emit.</param>
|
||||
public void Emit(LogEvent logEvent)
|
||||
{
|
||||
if (logEvent is null) return;
|
||||
|
||||
@@ -30,6 +30,8 @@ public sealed class ScriptLoggerFactory
|
||||
|
||||
private readonly ILogger _rootLogger;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="ScriptLoggerFactory"/> class.</summary>
|
||||
/// <param name="rootLogger">The root logger from which per-script loggers are derived.</param>
|
||||
public ScriptLoggerFactory(ILogger rootLogger)
|
||||
{
|
||||
_rootLogger = rootLogger ?? throw new ArgumentNullException(nameof(rootLogger));
|
||||
@@ -39,6 +41,8 @@ public sealed class ScriptLoggerFactory
|
||||
/// Create a per-script logger. Every event it emits carries
|
||||
/// <c>ScriptName=<paramref name="scriptName"/></c> as a structured property.
|
||||
/// </summary>
|
||||
/// <param name="scriptName">The name of the script for which to create a logger.</param>
|
||||
/// <returns>An ILogger instance bound with the script name.</returns>
|
||||
public ILogger Create(string scriptName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(scriptName))
|
||||
|
||||
@@ -42,6 +42,7 @@ public static class ScriptSandbox
|
||||
/// subclass the script's <c>ctx</c> will be of — the compiler uses its assembly
|
||||
/// to resolve <c>ctx.GetTag(...)</c> calls.
|
||||
/// </summary>
|
||||
/// <param name="contextType">The concrete script context type to use for compilation.</param>
|
||||
public static SandboxConfig Build(Type contextType)
|
||||
{
|
||||
if (contextType is null) throw new ArgumentNullException(nameof(contextType));
|
||||
|
||||
@@ -44,11 +44,16 @@ public sealed class TimedScriptEvaluator<TContext, TResult>
|
||||
/// <summary>Wall-clock budget per evaluation. Script exceeding this throws <see cref="ScriptTimeoutException"/>.</summary>
|
||||
public TimeSpan Timeout { get; }
|
||||
|
||||
/// <summary>Initializes a new instance of the TimedScriptEvaluator class with the default timeout.</summary>
|
||||
/// <param name="inner">The inner script evaluator.</param>
|
||||
public TimedScriptEvaluator(ScriptEvaluator<TContext, TResult> inner)
|
||||
: this(inner, DefaultTimeout)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Initializes a new instance of the TimedScriptEvaluator class with a custom timeout.</summary>
|
||||
/// <param name="inner">The inner script evaluator.</param>
|
||||
/// <param name="timeout">The evaluation timeout duration.</param>
|
||||
public TimedScriptEvaluator(ScriptEvaluator<TContext, TResult> inner, TimeSpan timeout)
|
||||
{
|
||||
_inner = inner ?? throw new ArgumentNullException(nameof(inner));
|
||||
@@ -57,6 +62,10 @@ public sealed class TimedScriptEvaluator<TContext, TResult>
|
||||
Timeout = timeout;
|
||||
}
|
||||
|
||||
/// <summary>Runs the script evaluation with the configured timeout.</summary>
|
||||
/// <param name="context">The script context.</param>
|
||||
/// <param name="ct">The cancellation token.</param>
|
||||
/// <returns>The evaluation result.</returns>
|
||||
public async Task<TResult> RunAsync(TContext context, CancellationToken ct = default)
|
||||
{
|
||||
if (context is null) throw new ArgumentNullException(nameof(context));
|
||||
@@ -97,8 +106,11 @@ public sealed class TimedScriptEvaluator<TContext, TResult>
|
||||
/// </summary>
|
||||
public sealed class ScriptTimeoutException : Exception
|
||||
{
|
||||
/// <summary>Gets the timeout duration that was exceeded.</summary>
|
||||
public TimeSpan Timeout { get; }
|
||||
|
||||
/// <summary>Initializes a new instance of the ScriptTimeoutException class.</summary>
|
||||
/// <param name="timeout">The timeout duration that was exceeded.</param>
|
||||
public ScriptTimeoutException(TimeSpan timeout)
|
||||
: base($"Script evaluation exceeded the configured timeout of {timeout.TotalMilliseconds:F1} ms. " +
|
||||
"The script was either CPU-bound or blocked on a slow operation; check ctx.Logger output " +
|
||||
|
||||
Reference in New Issue
Block a user