Skip to content

Commit e73e114

Browse files
authored
XDoc Refactoring (#21)
1 parent 35d7152 commit e73e114

24 files changed

+440
-557
lines changed

src/BitzArt.XDoc/BitzArt.XDoc.csproj

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,15 @@
1717
<PackageReadmeFile>README.md</PackageReadmeFile>
1818
<PackageIcon>xdoc-logo.png</PackageIcon>
1919
</PropertyGroup>
20-
21-
<ItemGroup>
22-
<None Include="..\..\assets\xdoc-logo.png" Pack="True" Visible="false" PackagePath="\"/>
23-
<None Include="..\..\README.md" Pack="True" Visible="false" PackagePath="\"/>
24-
</ItemGroup>
25-
20+
2621
<ItemGroup>
2722
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
2823
<_Parameter1>BitzArt.XDoc.Tests</_Parameter1>
2924
</AssemblyAttribute>
30-
</ItemGroup>
3125

26+
<AssemblyAttribute Include="JetBrains.Annotations.PublicAPIAttribute" />
27+
</ItemGroup>
28+
3229
<ItemGroup>
3330
<None Include="..\..\assets\xdoc-logo.png" Pack="True" Visible="false" PackagePath="\"/>
3431
<None Include="..\..\README.md" Pack="True" Visible="false" PackagePath="\"/>
Lines changed: 31 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.Xml;
2-
using BitzArt.XDoc.Resolvers;
32

43
namespace BitzArt.XDoc;
54

@@ -9,6 +8,8 @@ namespace BitzArt.XDoc;
98
/// </summary>
109
public abstract class MemberDocumentation
1110
{
11+
private readonly Dictionary<XmlNode, DocumentationReference?> _references = [];
12+
1213
// Documentation of a code member:
1314
// - Type as a member of an Assembly;
1415
// - MemberInfo as a member of Type.
@@ -18,39 +19,46 @@ public abstract class MemberDocumentation
1819
/// </summary>
1920
public XmlNode? Node { get; private init; }
2021

21-
internal XDoc Source { get; private init; }
22-
23-
private bool _isResolved = false;
24-
private InheritanceMemberDocumentationReference? _inherited;
25-
private IReadOnlyCollection<MemberDocumentationReference>? _references;
22+
public XDoc Source { get; private init; }
2623

27-
/// <summary>
28-
/// Contains references to inherited documentation.
29-
/// </summary>
30-
public InheritanceMemberDocumentationReference? Inherited
24+
private bool IsMyNode(XmlNode node)
3125
{
32-
get
26+
while (node.ParentNode != null)
3327
{
34-
OnRequireResolve();
28+
if (node.ParentNode == Node)
29+
{
30+
return true;
31+
}
3532

36-
return _inherited;
33+
node = node.ParentNode;
3734
}
38-
}
3935

40-
/// <summary>
41-
/// Contains references to other documentation.
42-
/// </summary>
43-
public IReadOnlyCollection<MemberDocumentationReference> References
36+
return false;
37+
}
38+
39+
public DocumentationReference? GetReference(XmlNode node)
4440
{
45-
get
41+
// // <dsffsf cref="BitzArt.XDoc.Models.TypeDocumentation" />
42+
// // <inheritdoc cref="Name" />
43+
// // <inheritdoc />
44+
45+
if (_references.TryGetValue(node, out var result))
4646
{
47-
OnRequireResolve();
47+
return result;
48+
}
4849

49-
return _references!;
50+
if (!IsMyNode(node))
51+
{
52+
throw new InvalidOperationException("The provided node is not defined in this documentation.");
5053
}
54+
55+
var documentationReference = Source.ReferenceResolver.GetReference(Source, node);
56+
57+
_references[node] = documentationReference;
58+
59+
return documentationReference;
5160
}
52-
53-
61+
5462
/// <summary>
5563
/// Initializes a new instance of the <see cref="MemberDocumentation"/> class.
5664
/// </summary>
@@ -61,20 +69,4 @@ protected MemberDocumentation(XDoc source, XmlNode? node)
6169
Source = source;
6270
Node = node;
6371
}
64-
65-
/// <summary>
66-
/// Resolves the documentation.
67-
/// </summary>
68-
private void OnRequireResolve()
69-
{
70-
if (_isResolved)
71-
{
72-
return;
73-
}
74-
75-
_inherited = InheritanceResolver.Resolve(this);
76-
_references = CrefResolver.Resolve(this);
77-
78-
_isResolved = true;
79-
}
8072
}

src/BitzArt.XDoc/Models/Cref.cs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
namespace BitzArt.XDoc;
2+
3+
/// <summary>
4+
/// Represents a parsed C# XML documentation code reference (cref) attribute.
5+
/// Extracts and stores the type and member information from a cref string.
6+
/// </summary>
7+
public record Cref
8+
{
9+
/// <summary>
10+
/// Initializes a new instance of the <see cref="Cref"/> record by parsing the provided cref string.
11+
/// </summary>
12+
/// <param name="cref">The cref string to parse (e.g. "T:Namespace.Type" or "M:Namespace.Type.Method").</param>
13+
public Cref(string cref)
14+
{
15+
Prefix = cref[..2];
16+
17+
var lastIndexOf = cref.LastIndexOf('.');
18+
19+
if (Prefix is "T:")
20+
{
21+
Type = cref.Substring(lastIndexOf + 1, cref.Length - lastIndexOf - 1);
22+
Member = null;
23+
}
24+
else if (Prefix is "M:" or "P:" or "F:")
25+
{
26+
Type = cref.Substring(2, lastIndexOf - 2);
27+
Member = cref.Substring(lastIndexOf + 1, cref.Length - lastIndexOf - 1);
28+
}
29+
else
30+
{
31+
throw new ArgumentException($"Invalid cref: {cref}");
32+
}
33+
34+
var typeLastIndexOf = Type.LastIndexOf('.');
35+
36+
ShortType = Type.Substring(typeLastIndexOf + 1, Type.Length - typeLastIndexOf - 1);
37+
}
38+
39+
/// <summary>
40+
/// The prefix of the cref (e.g. "T:", "M:", "P:", "F:").
41+
/// </summary>
42+
public string Prefix { get; init; }
43+
44+
/// <summary>
45+
/// The type name
46+
/// </summary>
47+
public string Type { get; init; }
48+
49+
/// <summary>
50+
/// The short type name (without namespace)
51+
/// </summary>
52+
public string ShortType { get; init; }
53+
54+
/// <summary>
55+
/// Method, property, or field name if present in the cref.
56+
/// Will be null for type references.
57+
/// </summary>
58+
public string? Member { get; init; }
59+
60+
/// <summary>
61+
/// Returns a string that represents the current object.
62+
/// </summary>
63+
public override string ToString()
64+
{
65+
return $"{Prefix}{Type}{(Member != null ? "." + Member : string.Empty)}";
66+
}
67+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System.Xml;
2+
3+
namespace BitzArt.XDoc;
4+
5+
/// <summary>
6+
/// Represents a class for documentation references.
7+
/// </summary>
8+
public class DocumentationReference
9+
{
10+
/// <summary>
11+
/// Actual XML node that caused this requirement
12+
/// </summary>
13+
public XmlNode RequirementNode { get; private init; }
14+
15+
/// <summary>
16+
/// The code reference that identifies the target element.
17+
/// </summary>
18+
public Cref? Cref { get; init; }
19+
20+
/// <summary>
21+
/// Target member documentation
22+
/// </summary>
23+
public MemberDocumentation? Target { get; private init; }
24+
25+
/// <summary>
26+
/// Default constructor
27+
/// </summary>
28+
/// <param name="requirementNode"></param>
29+
/// <param name="target"></param>
30+
/// <param name="cref"></param>
31+
public DocumentationReference(XmlNode requirementNode, MemberDocumentation? target, string? cref)
32+
{
33+
Target = target;
34+
RequirementNode = requirementNode;
35+
Cref = string.IsNullOrWhiteSpace(cref) ? null : new Cref(cref);
36+
}
37+
}

src/BitzArt.XDoc/Models/MemberDocumentationReference.cs

Lines changed: 0 additions & 62 deletions
This file was deleted.

src/BitzArt.XDoc/Models/Members/!TypeMemberDocumentation.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public abstract class TypeMemberDocumentation<TMember> : MemberDocumentation
2525
/// <summary>
2626
/// Name of the member.
2727
/// </summary>
28-
internal string MemberName => _member.Name;
28+
public string MemberName => _member.Name;
2929

3030
internal TypeMemberDocumentation(XDoc source, TypeDocumentation declaringTypeDocumentation, TMember member, XmlNode node)
3131
: base(source, node)

src/BitzArt.XDoc/Models/TypeDocumentation.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public sealed class TypeDocumentation : MemberDocumentation
1414
/// <summary>
1515
/// The <see cref="Type"/> this documentation if provided for.
1616
/// </summary>
17-
internal Type Type { get; private init; }
17+
public Type Type { get; private init; }
1818

1919
/// <summary>
2020
/// List of members declared by this <see cref="Type"/>.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System.Xml;
2+
3+
namespace BitzArt.XDoc;
4+
5+
/// <summary>
6+
/// Resolves documentation references from XML nodes.
7+
/// </summary>
8+
/// <remarks>
9+
/// This interface is used to extract documentation references from XML documentation comments,
10+
/// such as cref links and inheritdoc elements, to create structured representation of code references.
11+
/// </remarks>
12+
public interface IDocumentationReferenceResolver
13+
{
14+
/// <summary>
15+
/// Extracts a documentation reference from the provided XML node.
16+
/// </summary>
17+
/// <param name="source"></param>
18+
/// <param name="node">The XML node to extract the reference from.</param>
19+
/// <returns>
20+
/// A <see cref="DocumentationReference"/> object if a reference can be extracted;
21+
/// otherwise, <see langword="null"/>.
22+
/// </returns>
23+
DocumentationReference? GetReference(XDoc source, XmlNode node);
24+
}

src/BitzArt.XDoc/Resolvers/CrefResolver.cs

Lines changed: 0 additions & 35 deletions
This file was deleted.

0 commit comments

Comments
 (0)