Extract product-agnostic workflow engine from Ablera.Serdica.Workflow into standalone StellaOps.Workflow.* libraries targeting net10.0. Libraries (14): - Contracts, Abstractions (compiler, decompiler, expression runtime) - Engine (execution, signaling, scheduling, projections, hosted services) - ElkSharp (generic graph layout algorithm) - Renderer.ElkSharp, Renderer.ElkJs, Renderer.Msagl, Renderer.Svg - Signaling.Redis, Signaling.OracleAq - DataStore.MongoDB, DataStore.PostgreSQL, DataStore.Oracle WebService: ASP.NET Core Minimal API with 22 endpoints Tests (8 projects, 109 tests pass): - Engine.Tests (105 pass), WebService.Tests (4 E2E pass) - Renderer.Tests, DataStore.MongoDB/Oracle/PostgreSQL.Tests - Signaling.Redis.Tests, IntegrationTests.Shared Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
86 lines
2.9 KiB
C#
86 lines
2.9 KiB
C#
using System.Text.RegularExpressions;
|
|
|
|
namespace StellaOps.ElkSharp;
|
|
|
|
public sealed record ElkSharpSourceProfile
|
|
{
|
|
public required string SourceName { get; init; }
|
|
public int LineCount { get; init; }
|
|
public int CharacterCount { get; init; }
|
|
public int FunctionCount { get; init; }
|
|
public int DefineClassCount { get; init; }
|
|
public int CreateForClassCount { get; init; }
|
|
public int InternConstantCount { get; init; }
|
|
public int LayoutCommandCount { get; init; }
|
|
public int RegisterAlgorithmCount { get; init; }
|
|
}
|
|
|
|
public static partial class ElkSharpSourceAnalyzer
|
|
{
|
|
[GeneratedRegex(@"(?m)^\s*function\s+[A-Za-z0-9_$]+\s*\(", RegexOptions.CultureInvariant)]
|
|
private static partial Regex FunctionRegex();
|
|
|
|
[GeneratedRegex(@"defineClass\(", RegexOptions.CultureInvariant)]
|
|
private static partial Regex DefineClassRegex();
|
|
|
|
[GeneratedRegex(@"createForClass\(", RegexOptions.CultureInvariant)]
|
|
private static partial Regex CreateForClassRegex();
|
|
|
|
[GeneratedRegex(@"\$intern_", RegexOptions.CultureInvariant)]
|
|
private static partial Regex InternConstantRegex();
|
|
|
|
[GeneratedRegex(@"cmd:\s*'layout'|layout_[0-9]+\(", RegexOptions.CultureInvariant)]
|
|
private static partial Regex LayoutCommandRegex();
|
|
|
|
[GeneratedRegex(@"registerLayoutAlgorithms\(", RegexOptions.CultureInvariant)]
|
|
private static partial Regex RegisterAlgorithmRegex();
|
|
|
|
public static ElkSharpSourceProfile Analyze(string sourceName, string sourceText)
|
|
{
|
|
ArgumentException.ThrowIfNullOrWhiteSpace(sourceName);
|
|
ArgumentNullException.ThrowIfNull(sourceText);
|
|
|
|
return new ElkSharpSourceProfile
|
|
{
|
|
SourceName = sourceName,
|
|
LineCount = CountLines(sourceText),
|
|
CharacterCount = sourceText.Length,
|
|
FunctionCount = FunctionRegex().Matches(sourceText).Count,
|
|
DefineClassCount = DefineClassRegex().Matches(sourceText).Count,
|
|
CreateForClassCount = CreateForClassRegex().Matches(sourceText).Count,
|
|
InternConstantCount = InternConstantRegex().Matches(sourceText).Count,
|
|
LayoutCommandCount = LayoutCommandRegex().Matches(sourceText).Count,
|
|
RegisterAlgorithmCount = RegisterAlgorithmRegex().Matches(sourceText).Count,
|
|
};
|
|
}
|
|
|
|
public static async Task<ElkSharpSourceProfile> AnalyzeFileAsync(
|
|
string path,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
ArgumentException.ThrowIfNullOrWhiteSpace(path);
|
|
|
|
var sourceText = await File.ReadAllTextAsync(path, cancellationToken);
|
|
return Analyze(Path.GetFileName(path), sourceText);
|
|
}
|
|
|
|
private static int CountLines(string text)
|
|
{
|
|
if (text.Length == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
var lines = 1;
|
|
foreach (var character in text)
|
|
{
|
|
if (character == '\n')
|
|
{
|
|
++lines;
|
|
}
|
|
}
|
|
|
|
return lines;
|
|
}
|
|
}
|