Skip to content
This repository was archived by the owner on Jan 22, 2026. It is now read-only.

Commit adbc944

Browse files
committed
Implement processing parameters
1 parent ccd0465 commit adbc944

3 files changed

Lines changed: 82 additions & 45 deletions

File tree

src/BitzArt.XDoc/Utility/XmlParser.cs

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -75,20 +75,18 @@ private TypeDocumentation ParseTypeNode(XmlNode node, string name)
7575

7676
private PropertyDocumentation ParsePropertyNode(XmlNode node, string name)
7777
=> ParseMemberNode(name,
78-
(type, memberName) => type.GetProperty(memberName),
78+
(type, memberName, paramaters) => type.GetProperty(memberName),
7979
member => new PropertyDocumentation(_source, member, node));
8080

8181
private FieldDocumentation ParseFieldNode(XmlNode node, string name)
8282
=> ParseMemberNode(name,
83-
(type, memberName) => type.GetField(memberName),
83+
(type, memberName, parameters) => type.GetField(memberName),
8484
member => new FieldDocumentation(_source, member, node));
8585

8686
private MethodDocumentation? ParseMethodNode(XmlNode node, string name)
8787
=> ParseMemberNode(name,
88-
(type, memberName) =>
88+
(type, memberName, parameters) =>
8989
{
90-
var parameters = GetMethodParameters(memberName);
91-
9290
return type.GetMethods()
9391
.Where(method => method.Name == memberName)
9492
.Where(method =>
@@ -114,13 +112,14 @@ private FieldDocumentation ParseFieldNode(XmlNode node, string name)
114112
},
115113
member => new MethodDocumentation(_source, member, node));
116114

117-
private TDocumentation ParseMemberNode<TMember, TDocumentation>(string name, Func<Type, string, TMember?> getMember, Func<TMember, TDocumentation> getDocumentation)
115+
private TDocumentation ParseMemberNode<TMember, TDocumentation>(string name, Func<Type, string, IReadOnlyCollection<string>, TMember?> getMember, Func<TMember, TDocumentation> getDocumentation)
118116
where TMember : MemberInfo
119117
where TDocumentation : MemberDocumentation<TMember>
120118
{
121119
var (type, memberName) = ResolveTypeAndMemberName(name);
120+
var parameters = ResolveMethodParameters(name);
122121

123-
var memberInfo = getMember.Invoke(type, memberName)
122+
var memberInfo = getMember.Invoke(type, memberName, parameters)
124123
?? throw new InvalidOperationException(
125124
$"Member '{memberName}' not found in type '{type.Name}'.");
126125

@@ -133,6 +132,39 @@ private TDocumentation ParseMemberNode<TMember, TDocumentation>(string name, Fun
133132
return memberDocumentation;
134133
}
135134

135+
private static IReadOnlyCollection<string> ResolveMethodParameters(string name)
136+
{
137+
var startIndex = name.IndexOf('(');
138+
139+
if (startIndex == -1)
140+
{
141+
return Array.Empty<string>();
142+
}
143+
144+
var endIndex = name.LastIndexOf(')');
145+
146+
if (endIndex <= startIndex)
147+
{
148+
return Array.Empty<string>();
149+
}
150+
151+
var parametersString = name.Substring(startIndex + 1, endIndex - startIndex - 1);
152+
153+
if (string.IsNullOrWhiteSpace(parametersString))
154+
{
155+
return Array.Empty<string>();
156+
}
157+
158+
var result = parametersString
159+
.Split(',', StringSplitOptions.RemoveEmptyEntries)
160+
.Select(p => p.Trim())
161+
.Select(p => p.Replace("`0", ""))
162+
.Select(p => p.Replace("`", ""))
163+
.ToList();
164+
165+
return result;
166+
}
167+
136168
/// <summary>
137169
/// Get the friendly name of a type
138170
/// </summary>
@@ -166,35 +198,6 @@ private static string GetTypeFriendlyName(Type type)
166198
return friendlyName;
167199
}
168200

169-
// Fetches the parameter type names of a method from the XML documentation.
170-
private static List<string> GetMethodParameters(string xmlMember)
171-
{
172-
var start = xmlMember.IndexOf('(');
173-
var end = xmlMember.LastIndexOf(')');
174-
175-
if (start == -1 || end == -1 || end <= start)
176-
{
177-
return [];
178-
}
179-
180-
// Extract the substring that contains the parameters.
181-
var paramList = xmlMember.Substring(start + 1, end - start - 1);
182-
183-
if (string.IsNullOrWhiteSpace(paramList))
184-
{
185-
return [];
186-
}
187-
188-
// Split the parameter list by commas and trim each parameter.
189-
var methodParameters = paramList.Split([','], StringSplitOptions.RemoveEmptyEntries)
190-
.Select(p => p.Trim())
191-
.Select(p => p.Replace("`0", ""))
192-
.Select(p => p.Replace("`", ""))
193-
.ToList();
194-
195-
return methodParameters;
196-
}
197-
198201
private (Type type, string memberName) ResolveTypeAndMemberName(string name)
199202
{
200203
if (name.Contains('`'))

tests/BitzArt.XDoc.TestNodes/TestMemberNode.cs

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Diagnostics;
1+
using System.Collections.Immutable;
2+
using System.Diagnostics;
23
using System.Reflection;
34

45
namespace BitzArt.XDoc.Tests;
@@ -8,6 +9,7 @@ public class TestMemberNode
89
private readonly TestNodeType _type;
910
private readonly string _name;
1011
private readonly string _content;
12+
private readonly IReadOnlyCollection<ParameterInfo> _parameters;
1113

1214
public TestMemberNode(Type type, string content)
1315
: this(TestNodeType.Type, type.FullName!, content) { }
@@ -19,21 +21,53 @@ public TestMemberNode(PropertyInfo property, string content)
1921
: this(TestNodeType.Property, GetMemberName(property), content) { }
2022

2123
public TestMemberNode(MethodInfo method, string content)
22-
: this(TestNodeType.Method, GetMemberName(method), content) { }
24+
: this(TestNodeType.Method, GetMemberName(method), content) =>
25+
_parameters = method.GetParameters();
2326

2427
public TestMemberNode(TestNodeType type, string name, string content)
2528
{
2629
_type = type;
2730
_name = name;
2831
_content = content;
32+
_parameters = ImmutableList<ParameterInfo>.Empty;
2933
}
3034

31-
public string GetXml() =>
32-
$"""
33-
<member name="{XmlNodeTypeChar}:{_name}">
34-
{_content.Offset(4, exceptFirstLine: true)}
35-
</member>
36-
""";
35+
public string GetXml()
36+
{
37+
var xml = "";
38+
39+
if (_type == TestNodeType.Method)
40+
{
41+
var parameters = string.Join(", ", _parameters.Select(Render));
42+
43+
xml = $"""
44+
<member name="{XmlNodeTypeChar}:{_name}({parameters})">
45+
{_content.Offset(4, exceptFirstLine: true)}
46+
</member>
47+
""";
48+
49+
}
50+
else
51+
{
52+
xml = $"""
53+
<member name="{XmlNodeTypeChar}:{_name}">
54+
{_content.Offset(4, exceptFirstLine: true)}
55+
</member>
56+
""";
57+
}
58+
59+
return xml;
60+
}
61+
62+
private string Render(ParameterInfo p)
63+
{
64+
var type = p.ParameterType;
65+
var typeName = type.FullName ?? type.Name;
66+
67+
// Remove the generic parameter count indicators from the type name
68+
// (e.g., List`1 becomes List)
69+
return typeName.Replace("`0", "").Replace("`", "");
70+
}
3771

3872
private static string GetMemberName(MemberInfo member)
3973
=> $"{member.DeclaringType!.FullName}.{member.Name}";

tests/BitzArt.XDoc.Tests/TestTypes/TestClass.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ public class TestClass
44
{
55
public string TestProperty { get; set; } = null!;
66

7-
public void TestMethod() { }
7+
public void TestMethod(int a1, string b2) { }
88

99
public string TestField = null!;
1010
}

0 commit comments

Comments
 (0)