Restructure solution layout by module
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using StellaOps.Signals.Models;
|
||||
|
||||
namespace StellaOps.Signals.Parsing;
|
||||
|
||||
/// <summary>
|
||||
/// Simple JSON-based callgraph parser used for initial language coverage.
|
||||
/// </summary>
|
||||
internal sealed class SimpleJsonCallgraphParser : ICallgraphParser
|
||||
{
|
||||
private readonly JsonSerializerOptions serializerOptions;
|
||||
|
||||
public SimpleJsonCallgraphParser(string language)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(language);
|
||||
Language = language;
|
||||
serializerOptions = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
}
|
||||
|
||||
public string Language { get; }
|
||||
|
||||
public async Task<CallgraphParseResult> ParseAsync(Stream artifactStream, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(artifactStream);
|
||||
|
||||
var payload = await JsonSerializer.DeserializeAsync<RawCallgraphPayload>(
|
||||
artifactStream,
|
||||
serializerOptions,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (payload is null)
|
||||
{
|
||||
throw new CallgraphParserValidationException("Callgraph artifact payload is empty.");
|
||||
}
|
||||
|
||||
if (payload.Graph is null)
|
||||
{
|
||||
throw new CallgraphParserValidationException("Callgraph artifact is missing 'graph' section.");
|
||||
}
|
||||
|
||||
if (payload.Graph.Nodes is null || payload.Graph.Nodes.Count == 0)
|
||||
{
|
||||
throw new CallgraphParserValidationException("Callgraph artifact must include at least one node.");
|
||||
}
|
||||
|
||||
if (payload.Graph.Edges is null)
|
||||
{
|
||||
payload.Graph.Edges = new List<RawCallgraphEdge>();
|
||||
}
|
||||
|
||||
var nodes = new List<CallgraphNode>(payload.Graph.Nodes.Count);
|
||||
foreach (var node in payload.Graph.Nodes)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(node.Id))
|
||||
{
|
||||
throw new CallgraphParserValidationException("Callgraph node is missing an id.");
|
||||
}
|
||||
|
||||
nodes.Add(new CallgraphNode(
|
||||
Id: node.Id.Trim(),
|
||||
Name: node.Name ?? node.Id.Trim(),
|
||||
Kind: node.Kind ?? "function",
|
||||
Namespace: node.Namespace,
|
||||
File: node.File,
|
||||
Line: node.Line));
|
||||
}
|
||||
|
||||
var edges = new List<CallgraphEdge>(payload.Graph.Edges.Count);
|
||||
foreach (var edge in payload.Graph.Edges)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(edge.Source) || string.IsNullOrWhiteSpace(edge.Target))
|
||||
{
|
||||
throw new CallgraphParserValidationException("Callgraph edge requires both source and target.");
|
||||
}
|
||||
|
||||
edges.Add(new CallgraphEdge(edge.Source.Trim(), edge.Target.Trim(), edge.Type ?? "call"));
|
||||
}
|
||||
|
||||
var formatVersion = string.IsNullOrWhiteSpace(payload.FormatVersion) ? "1.0" : payload.FormatVersion.Trim();
|
||||
return new CallgraphParseResult(nodes, edges, formatVersion);
|
||||
}
|
||||
|
||||
private sealed class RawCallgraphPayload
|
||||
{
|
||||
public string? FormatVersion { get; set; }
|
||||
public RawCallgraphGraph? Graph { get; set; }
|
||||
}
|
||||
|
||||
private sealed class RawCallgraphGraph
|
||||
{
|
||||
public List<RawCallgraphNode>? Nodes { get; set; }
|
||||
public List<RawCallgraphEdge>? Edges { get; set; }
|
||||
}
|
||||
|
||||
private sealed class RawCallgraphNode
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Kind { get; set; }
|
||||
public string? Namespace { get; set; }
|
||||
public string? File { get; set; }
|
||||
public int? Line { get; set; }
|
||||
}
|
||||
|
||||
private sealed class RawCallgraphEdge
|
||||
{
|
||||
public string? Source { get; set; }
|
||||
public string? Target { get; set; }
|
||||
public string? Type { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user