Files
EonaCat.DoxaApi/DoxaApi/Generation/XmlDocReader.cs
T
2026-06-20 10:26:27 +02:00

104 lines
3.1 KiB
C#

using System.Reflection;
using System.Text;
using System.Xml.Linq;
namespace EonaCat.DoxaApi.Generation
{
internal sealed class MethodXmlDoc
{
public string? Summary { get; set; }
public string? Remarks { get; set; }
public string? Returns { get; set; }
public Dictionary<string, string> Params { get; } = new();
}
internal sealed class XmlDocReader
{
private readonly Dictionary<string, MethodXmlDoc> _members = new();
public XmlDocReader(XDocument document)
{
var members = document.Root?.Element("members")?.Elements("member");
if (members is null)
{
return;
}
foreach (var member in members)
{
var name = member.Attribute("name")?.Value;
if (name is null || !name.StartsWith("M:"))
{
continue;
}
var doc = new MethodXmlDoc
{
Summary = CleanText(member.Element("summary")?.Value),
Remarks = CleanText(member.Element("remarks")?.Value),
Returns = CleanText(member.Element("returns")?.Value)
};
foreach (var paramEl in member.Elements("param"))
{
var pName = paramEl.Attribute("name")?.Value;
if (pName is not null)
{
doc.Params[pName] = CleanText(paramEl.Value) ?? "";
}
}
_members[name] = doc;
}
}
public MethodXmlDoc? GetMethodDoc(MethodInfo method)
{
var key = BuildMemberKey(method);
return _members.GetValueOrDefault(key);
}
private static string? CleanText(string? raw)
{
if (string.IsNullOrWhiteSpace(raw))
{
return null;
}
var lines = raw.Split('\n').Select(l => l.Trim());
return string.Join(" ", lines).Trim();
}
private static string BuildMemberKey(MethodInfo method)
{
var sb = new StringBuilder("M:");
sb.Append(method.DeclaringType!.FullName!.Replace('+', '.'));
sb.Append('.');
sb.Append(method.Name);
var parameters = method.GetParameters();
if (parameters.Length > 0)
{
sb.Append('(');
sb.Append(string.Join(",", parameters.Select(p => XmlTypeName(p.ParameterType))));
sb.Append(')');
}
return sb.ToString();
}
private static string XmlTypeName(Type type)
{
if (type.IsGenericType)
{
var def = type.GetGenericTypeDefinition();
var name = def.FullName![..def.FullName!.IndexOf('`')];
var args = string.Join(",", type.GetGenericArguments().Select(XmlTypeName));
return $"{name}{{{args}}}";
}
return type.FullName?.Replace('+', '.') ?? type.Name;
}
}
}