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 Params { get; } = new(); } internal sealed class XmlDocReader { private readonly Dictionary _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; } } }