docs: complete XML doc coverage (returns, summaries, inheritdoc)
Resolve all 622 issues flagged by the enhanced CommentChecker: add missing <returns> tags (incl. the standard phrasing on non-generic Task methods), add missing <summary> tags, and replace misused/redundant <inheritdoc/> on members that override or implement nothing with real documentation. Documentation-only — no behavior change; solution builds clean.
This commit is contained in:
@@ -17,6 +17,7 @@ public static class CycleDetector
|
||||
/// A plain <c>ToDictionary(t => t.Id)</c> would instead throw ArgumentException.
|
||||
/// </summary>
|
||||
/// <param name="allTemplates">All templates to build lookup from.</param>
|
||||
/// <returns>A dictionary keyed by template Id; on duplicate Ids the first occurrence wins.</returns>
|
||||
internal static Dictionary<int, Template> BuildLookup(IReadOnlyList<Template> allTemplates)
|
||||
{
|
||||
var lookup = new Dictionary<int, Template>();
|
||||
|
||||
@@ -463,6 +463,7 @@ public class FlatteningService
|
||||
/// </summary>
|
||||
/// <param name="inheritedJson">The parent template's HiLo trigger JSON, or null.</param>
|
||||
/// <param name="derivedJson">The child template's HiLo trigger JSON override, or null.</param>
|
||||
/// <returns>The merged HiLo config JSON, or the derived config on parse failure of either input.</returns>
|
||||
public static string? MergeHiLoConfig(string? inheritedJson, string? derivedJson)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(inheritedJson)) return derivedJson;
|
||||
@@ -526,6 +527,7 @@ public class FlatteningService
|
||||
/// </summary>
|
||||
/// <param name="inheritedJson">The parent template's HiLo trigger JSON, or null.</param>
|
||||
/// <param name="editedJson">The user-edited HiLo trigger JSON, or null.</param>
|
||||
/// <returns>A JSON string containing only the keys that differ from the inherited config, or null if there are no differences.</returns>
|
||||
public static string? DiffHiLoConfig(string? inheritedJson, string? editedJson)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(editedJson)) return null;
|
||||
|
||||
@@ -34,6 +34,7 @@ public class RevisionHashService
|
||||
/// excluding volatile fields like GeneratedAtUtc.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The flattened configuration to hash.</param>
|
||||
/// <returns>A hex-encoded SHA-256 hash string of the canonical configuration representation.</returns>
|
||||
public string ComputeHash(FlattenedConfiguration configuration)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(configuration);
|
||||
|
||||
@@ -27,6 +27,7 @@ public static class LockEnforcer
|
||||
/// </summary>
|
||||
/// <param name="original">The parent template's attribute definition.</param>
|
||||
/// <param name="proposed">The child template's proposed override.</param>
|
||||
/// <returns>An error message string if a rule is violated; <c>null</c> if the override is permitted.</returns>
|
||||
public static string? ValidateAttributeOverride(
|
||||
TemplateAttribute original,
|
||||
TemplateAttribute proposed)
|
||||
@@ -56,6 +57,7 @@ public static class LockEnforcer
|
||||
/// </summary>
|
||||
/// <param name="original">The parent template's alarm definition.</param>
|
||||
/// <param name="proposed">The child template's proposed override.</param>
|
||||
/// <returns>An error message string if a rule is violated; <c>null</c> if the override is permitted.</returns>
|
||||
public static string? ValidateAlarmOverride(
|
||||
TemplateAlarm original,
|
||||
TemplateAlarm proposed)
|
||||
@@ -85,6 +87,7 @@ public static class LockEnforcer
|
||||
/// </summary>
|
||||
/// <param name="original">The parent template's script definition.</param>
|
||||
/// <param name="proposed">The child template's proposed override.</param>
|
||||
/// <returns>An error message string if a rule is violated; <c>null</c> if the override is permitted.</returns>
|
||||
public static string? ValidateScriptOverride(
|
||||
TemplateScript original,
|
||||
TemplateScript proposed)
|
||||
@@ -110,6 +113,7 @@ public static class LockEnforcer
|
||||
/// <param name="originalIsLocked">The current lock state of the member.</param>
|
||||
/// <param name="proposedIsLocked">The proposed lock state.</param>
|
||||
/// <param name="memberName">Name of the member being changed, for error messages.</param>
|
||||
/// <returns>An error message if unlocking is attempted; <c>null</c> if the lock change is valid.</returns>
|
||||
public static string? ValidateLockChange(bool originalIsLocked, bool proposedIsLocked, string memberName)
|
||||
{
|
||||
if (originalIsLocked && !proposedIsLocked)
|
||||
@@ -130,6 +134,7 @@ public static class LockEnforcer
|
||||
/// <param name="originalLockedInDerived">Current <c>LockedInDerived</c> state.</param>
|
||||
/// <param name="proposedLockedInDerived">Proposed <c>LockedInDerived</c> state.</param>
|
||||
/// <param name="memberName">Name of the member being changed, for error messages.</param>
|
||||
/// <returns>An error message if the locked-in-derived flag is being cleared; <c>null</c> if the change is valid.</returns>
|
||||
public static string? ValidateLockedInDerivedChange(
|
||||
bool originalLockedInDerived,
|
||||
bool proposedLockedInDerived,
|
||||
|
||||
@@ -11,6 +11,7 @@ public static class ServiceCollectionExtensions
|
||||
/// Registers all template engine services (template, flattening, validation, and domain services).
|
||||
/// </summary>
|
||||
/// <param name="services">The service collection to register into.</param>
|
||||
/// <returns>The same <paramref name="services"/> instance for chaining.</returns>
|
||||
public static IServiceCollection AddTemplateEngine(this IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<TemplateService>();
|
||||
@@ -43,6 +44,7 @@ public static class ServiceCollectionExtensions
|
||||
/// Registers Akka.NET actors for the template engine (placeholder for future actor registration).
|
||||
/// </summary>
|
||||
/// <param name="services">The service collection to register into.</param>
|
||||
/// <returns>The same <paramref name="services"/> instance for chaining.</returns>
|
||||
public static IServiceCollection AddTemplateEngineActors(this IServiceCollection services)
|
||||
{
|
||||
// Phase 0: placeholder for Akka actor registration
|
||||
|
||||
@@ -35,6 +35,7 @@ public class AreaService
|
||||
/// <param name="parentAreaId">Optional parent area identifier for hierarchical organization.</param>
|
||||
/// <param name="user">The user performing the action for audit logging.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>A task that resolves to a success result containing the new area, or a failure result with an error message.</returns>
|
||||
public async Task<Result<Area>> CreateAreaAsync(
|
||||
string name, int siteId, int? parentAreaId, string user,
|
||||
CancellationToken cancellationToken = default)
|
||||
@@ -81,6 +82,7 @@ public class AreaService
|
||||
/// <param name="name">The new name for the area.</param>
|
||||
/// <param name="user">The user performing the action for audit logging.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>A task that resolves to a success result containing the updated area, or a failure result with an error message.</returns>
|
||||
public async Task<Result<Area>> UpdateAreaAsync(
|
||||
int areaId, string name, string user,
|
||||
CancellationToken cancellationToken = default)
|
||||
@@ -118,6 +120,7 @@ public class AreaService
|
||||
/// <param name="newParentAreaId">The new parent area identifier, or null to move to site root.</param>
|
||||
/// <param name="user">The user performing the action for audit logging.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>A task that resolves to a success result containing the moved area, or a failure result with an error message.</returns>
|
||||
public async Task<Result<Area>> MoveAreaAsync(
|
||||
int areaId, int? newParentAreaId, string user,
|
||||
CancellationToken cancellationToken = default)
|
||||
@@ -175,6 +178,7 @@ public class AreaService
|
||||
/// <param name="areaId">The area identifier.</param>
|
||||
/// <param name="user">The user performing the action for audit logging.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>A task that resolves to a success result with <c>true</c>, or a failure result if deletion is blocked.</returns>
|
||||
public async Task<Result<bool>> DeleteAreaAsync(
|
||||
int areaId, string user,
|
||||
CancellationToken cancellationToken = default)
|
||||
@@ -224,6 +228,7 @@ public class AreaService
|
||||
/// </summary>
|
||||
/// <param name="siteId">The site identifier.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>A task that resolves to a read-only list of all areas for the site.</returns>
|
||||
public async Task<IReadOnlyList<Area>> GetAreasBySiteIdAsync(int siteId, CancellationToken cancellationToken = default) =>
|
||||
await _repository.GetAreasBySiteIdAsync(siteId, cancellationToken);
|
||||
|
||||
@@ -232,6 +237,7 @@ public class AreaService
|
||||
/// </summary>
|
||||
/// <param name="areaId">The area identifier.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>A task that resolves to the matching area, or null if not found.</returns>
|
||||
public async Task<Area?> GetAreaByIdAsync(int areaId, CancellationToken cancellationToken = default) =>
|
||||
await _repository.GetAreaByIdAsync(areaId, cancellationToken);
|
||||
|
||||
|
||||
@@ -112,11 +112,13 @@ public class SiteService
|
||||
/// <summary>Returns the site with the given primary key, or <c>null</c> if not found.</summary>
|
||||
/// <param name="siteId">Primary key of the site.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>A task that resolves to the matching <see cref="Site"/>, or <c>null</c> if not found.</returns>
|
||||
public async Task<Site?> GetSiteByIdAsync(int siteId, CancellationToken cancellationToken = default) =>
|
||||
await _repository.GetSiteByIdAsync(siteId, cancellationToken);
|
||||
|
||||
/// <summary>Returns all sites.</summary>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>A task that resolves to the complete list of all sites.</returns>
|
||||
public async Task<IReadOnlyList<Site>> GetAllSitesAsync(CancellationToken cancellationToken = default) =>
|
||||
await _repository.GetAllSitesAsync(cancellationToken);
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ public class TemplateDeletionService
|
||||
/// </summary>
|
||||
/// <param name="templateId">The id of the template to check.</param>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
/// <returns>A task that resolves to a successful result if the template can be deleted, or a failure with blocking reasons.</returns>
|
||||
public async Task<Result<bool>> CanDeleteTemplateAsync(int templateId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var template = await _repository.GetTemplateByIdAsync(templateId, cancellationToken);
|
||||
@@ -106,6 +107,7 @@ public class TemplateDeletionService
|
||||
/// </summary>
|
||||
/// <param name="templateId">The id of the template to delete.</param>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
/// <returns>A task that resolves to a successful result when deleted, or a failure with the blocking reason.</returns>
|
||||
public async Task<Result<bool>> DeleteTemplateAsync(int templateId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var canDelete = await CanDeleteTemplateAsync(templateId, cancellationToken);
|
||||
|
||||
@@ -28,6 +28,7 @@ public class TemplateFolderService
|
||||
/// <param name="parentFolderId">Parent folder id, or null to create at root level.</param>
|
||||
/// <param name="user">Username of the actor performing the operation (for audit).</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>A task that resolves to the created <see cref="TemplateFolder"/>, or a failure result if validation fails.</returns>
|
||||
public async Task<Result<TemplateFolder>> CreateFolderAsync(
|
||||
string name, int? parentFolderId, string user,
|
||||
CancellationToken cancellationToken = default)
|
||||
@@ -62,6 +63,7 @@ public class TemplateFolderService
|
||||
/// <param name="newName">New display name for the folder.</param>
|
||||
/// <param name="user">Username of the actor performing the operation (for audit).</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>A task that resolves to the updated <see cref="TemplateFolder"/>, or a failure result if the folder is not found or the name collides.</returns>
|
||||
public async Task<Result<TemplateFolder>> RenameFolderAsync(
|
||||
int folderId, string newName, string user,
|
||||
CancellationToken cancellationToken = default)
|
||||
@@ -94,6 +96,7 @@ public class TemplateFolderService
|
||||
/// <param name="newParentId">Target parent folder id, or null to move to root level.</param>
|
||||
/// <param name="user">Username of the actor performing the operation (for audit).</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>A task that resolves to the moved <see cref="TemplateFolder"/>, or a failure result if a cycle or name collision is detected.</returns>
|
||||
public async Task<Result<TemplateFolder>> MoveFolderAsync(
|
||||
int folderId, int? newParentId, string user,
|
||||
CancellationToken cancellationToken = default)
|
||||
@@ -155,6 +158,7 @@ public class TemplateFolderService
|
||||
/// <param name="folderId">Id of the folder to delete.</param>
|
||||
/// <param name="user">Username of the actor performing the operation (for audit).</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>A task that resolves to a success result if the folder was deleted, or a failure result if the folder is not found or not empty.</returns>
|
||||
public async Task<Result<bool>> DeleteFolderAsync(
|
||||
int folderId, string user,
|
||||
CancellationToken cancellationToken = default)
|
||||
|
||||
@@ -59,6 +59,7 @@ internal static class CSharpDelimiterScanner
|
||||
/// </summary>
|
||||
/// <param name="code">The C# source code to scan.</param>
|
||||
/// <param name="pattern">The substring to search for in code regions only.</param>
|
||||
/// <returns><c>true</c> if <paramref name="pattern"/> occurs in a code region (not inside a comment, string, or char literal); otherwise <c>false</c>.</returns>
|
||||
internal static bool ContainsInCode(string code, string pattern)
|
||||
{
|
||||
if (string.IsNullOrEmpty(pattern))
|
||||
@@ -162,6 +163,7 @@ internal static class CSharpDelimiterScanner
|
||||
/// ignored.
|
||||
/// </summary>
|
||||
/// <param name="code">The C# source code to scan for delimiter balance.</param>
|
||||
/// <returns>The first <see cref="Mismatch"/> found, or <see cref="Mismatch.None"/> if all delimiters are balanced.</returns>
|
||||
internal static Mismatch Scan(string code)
|
||||
{
|
||||
int brace = 0, bracket = 0, paren = 0;
|
||||
|
||||
@@ -25,6 +25,8 @@ public class SemanticValidator
|
||||
/// </summary>
|
||||
/// <param name="configuration">The flattened configuration to validate.</param>
|
||||
/// <param name="sharedScripts">Shared scripts available for CallShared references.</param>
|
||||
/// <param name="alarmCapableConnectionNames">Connection names that support alarm subscriptions; used to validate native alarm source bindings.</param>
|
||||
/// <returns>A <see cref="ValidationResult"/> containing all semantic errors and warnings found.</returns>
|
||||
public ValidationResult Validate(
|
||||
FlattenedConfiguration configuration,
|
||||
IReadOnlyList<ResolvedScript>? sharedScripts = null,
|
||||
@@ -288,6 +290,7 @@ public class SemanticValidator
|
||||
/// Parses a parameter definitions JSON string (JSON Schema or legacy flat array) and returns the declared parameter names.
|
||||
/// </summary>
|
||||
/// <param name="parameterDefinitionsJson">JSON Schema or legacy flat-array string; null/empty returns an empty list.</param>
|
||||
/// <returns>The list of parameter names declared in the definition.</returns>
|
||||
internal static List<string> ParseParameterDefinitions(string? parameterDefinitionsJson)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(parameterDefinitionsJson))
|
||||
@@ -325,6 +328,7 @@ public class SemanticValidator
|
||||
/// Looks for CallScript("name", ...) and CallShared("name", ...) patterns.
|
||||
/// </summary>
|
||||
/// <param name="code">The script source code to scan.</param>
|
||||
/// <returns>The list of call targets found (both <c>CallScript</c> and <c>CallShared</c> invocations).</returns>
|
||||
internal static List<CallTarget> ExtractCallTargets(string code)
|
||||
{
|
||||
var results = new List<CallTarget>();
|
||||
|
||||
@@ -45,6 +45,7 @@ public class ValidationService
|
||||
/// </summary>
|
||||
/// <param name="configuration">The flattened configuration to validate.</param>
|
||||
/// <param name="sharedScripts">Optional list of shared scripts for validation context.</param>
|
||||
/// <returns>A merged <see cref="ValidationResult"/> aggregating all pipeline stage outcomes.</returns>
|
||||
public ValidationResult Validate(FlattenedConfiguration configuration, IReadOnlyList<ResolvedScript>? sharedScripts = null)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(configuration);
|
||||
@@ -68,6 +69,7 @@ public class ValidationService
|
||||
/// Validates that flattening produced a non-empty configuration.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The flattened configuration to validate.</param>
|
||||
/// <returns>A <see cref="ValidationResult"/> with errors or warnings if the configuration is empty or missing a name; otherwise success.</returns>
|
||||
public static ValidationResult ValidateFlatteningSuccess(FlattenedConfiguration configuration)
|
||||
{
|
||||
var errors = new List<ValidationEntry>();
|
||||
@@ -97,6 +99,7 @@ public class ValidationService
|
||||
/// Canonical names must be unique within their entity type (attributes, alarms, scripts).
|
||||
/// </summary>
|
||||
/// <param name="configuration">The flattened configuration to validate.</param>
|
||||
/// <returns>A <see cref="ValidationResult"/> with errors for each duplicate canonical name, or success.</returns>
|
||||
public static ValidationResult ValidateNamingCollisions(FlattenedConfiguration configuration)
|
||||
{
|
||||
var errors = new List<ValidationEntry>();
|
||||
@@ -114,6 +117,7 @@ public class ValidationService
|
||||
/// Validates that all scripts compile successfully using the ScriptCompiler.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The flattened configuration to validate.</param>
|
||||
/// <returns>A <see cref="ValidationResult"/> with errors for each script that fails compilation.</returns>
|
||||
public ValidationResult ValidateScriptCompilation(FlattenedConfiguration configuration)
|
||||
{
|
||||
var errors = new List<ValidationEntry>();
|
||||
@@ -138,6 +142,7 @@ public class ValidationService
|
||||
/// Alarm trigger configs are JSON with an "attributeName" field referencing a canonical attribute name.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The flattened configuration to validate.</param>
|
||||
/// <returns>A <see cref="ValidationResult"/> with errors for any alarm whose trigger references a missing attribute.</returns>
|
||||
public static ValidationResult ValidateAlarmTriggerReferences(FlattenedConfiguration configuration)
|
||||
{
|
||||
var errors = new List<ValidationEntry>();
|
||||
@@ -167,6 +172,7 @@ public class ValidationService
|
||||
/// Validates that script trigger configurations reference existing attributes.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The flattened configuration to validate.</param>
|
||||
/// <returns>A <see cref="ValidationResult"/> with errors for any script whose trigger references a missing attribute.</returns>
|
||||
public static ValidationResult ValidateScriptTriggerReferences(FlattenedConfiguration configuration)
|
||||
{
|
||||
var errors = new List<ValidationEntry>();
|
||||
@@ -209,6 +215,7 @@ public class ValidationService
|
||||
/// </list>
|
||||
/// </summary>
|
||||
/// <param name="configuration">The flattened configuration to validate.</param>
|
||||
/// <returns>A <see cref="ValidationResult"/> with errors and warnings from all expression trigger checks.</returns>
|
||||
public static ValidationResult ValidateExpressionTriggers(FlattenedConfiguration configuration)
|
||||
{
|
||||
var errors = new List<ValidationEntry>();
|
||||
@@ -302,6 +309,7 @@ public class ValidationService
|
||||
/// configuration. Returns <c>null</c> on malformed JSON or a missing key.
|
||||
/// </summary>
|
||||
/// <param name="triggerConfigJson">The trigger configuration JSON to parse.</param>
|
||||
/// <returns>The expression string, or <c>null</c> if absent or the JSON is malformed.</returns>
|
||||
internal static string? ExtractExpressionFromTriggerConfig(string? triggerConfigJson)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(triggerConfigJson))
|
||||
@@ -330,6 +338,7 @@ public class ValidationService
|
||||
/// looks well-formed.
|
||||
/// </summary>
|
||||
/// <param name="expression">The expression to check for syntax errors.</param>
|
||||
/// <returns>A human-readable error message if the expression is invalid; <c>null</c> if well-formed.</returns>
|
||||
internal static string? CheckExpressionSyntax(string expression)
|
||||
{
|
||||
// Advisory forbidden-API scan (TemplateEngine-006): code-region-aware so
|
||||
@@ -439,6 +448,7 @@ public class ValidationService
|
||||
/// and skips keys built dynamically.
|
||||
/// </summary>
|
||||
/// <param name="expression">The expression to scan for attribute references.</param>
|
||||
/// <returns>The distinct attribute key strings found in self-attribute accessor positions.</returns>
|
||||
internal static IEnumerable<string> ExtractAttributeReferences(string expression)
|
||||
{
|
||||
var seen = new HashSet<string>(StringComparer.Ordinal);
|
||||
@@ -490,6 +500,7 @@ public class ValidationService
|
||||
/// Validates that all data-sourced attributes have connection bindings.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The flattened configuration to validate.</param>
|
||||
/// <returns>A <see cref="ValidationResult"/> with warnings for each data-sourced attribute that lacks a connection binding.</returns>
|
||||
public static ValidationResult ValidateConnectionBindingCompleteness(FlattenedConfiguration configuration)
|
||||
{
|
||||
var errors = new List<ValidationEntry>();
|
||||
@@ -531,6 +542,7 @@ public class ValidationService
|
||||
/// Extracts the attribute name from a trigger configuration JSON.
|
||||
/// </summary>
|
||||
/// <param name="triggerConfigJson">The trigger configuration JSON to parse.</param>
|
||||
/// <returns>The attribute name from the <c>attributeName</c> or legacy <c>attribute</c> key, or <c>null</c> if absent or malformed.</returns>
|
||||
internal static string? ExtractAttributeNameFromTriggerConfig(string triggerConfigJson)
|
||||
{
|
||||
// Accept both keys to stay consistent with FlatteningService.PrefixTriggerAttribute,
|
||||
@@ -558,6 +570,7 @@ public class ValidationService
|
||||
/// validate" and let other checks surface the deeper problem.
|
||||
/// </summary>
|
||||
/// <param name="triggerConfigJson">The trigger configuration JSON to parse.</param>
|
||||
/// <returns>A <see cref="HiLoSetpoints"/> record with the parsed setpoint values; any missing or non-numeric value is <c>null</c>.</returns>
|
||||
internal static HiLoSetpoints ExtractHiLoSetpoints(string triggerConfigJson)
|
||||
{
|
||||
try
|
||||
|
||||
Reference in New Issue
Block a user