Skip to content

Commit b001477

Browse files
authored
chore(AttributeTable): support inheritdoc xml node (#7547)
* wip: 临时提交 * refactor: 支持 inheritdoc 语法
1 parent 9ffc3d4 commit b001477

1 file changed

Lines changed: 33 additions & 35 deletions

File tree

src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -34,30 +34,23 @@ public static List<AttributeItem> GetAttributes(Type componentType)
3434

3535
private static List<AttributeItem> GetAttributeCore(Type type)
3636
{
37-
var attributes = new List<AttributeItem>();
3837
var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
3938

4039
// 检查是否为 IComponent 实现类
4140
if (typeof(IComponent).IsAssignableFrom(type))
4241
{
43-
properties = properties
44-
.Where(p => p.GetCustomAttribute<ParameterAttribute>() != null)
42+
properties = properties.Where(p => p.GetCustomAttribute<ParameterAttribute>() != null)
4543
.ToArray();
4644
}
4745

4846
var xmlDoc = GetXmlDocumentation(type.Assembly);
49-
foreach (var property in properties)
47+
return properties.Select(property => new AttributeItem
5048
{
51-
var item = new AttributeItem
52-
{
53-
Name = property.Name,
54-
Type = GetFriendlyTypeName(property.PropertyType),
55-
Description = GetSummary(xmlDoc, property) ?? "",
56-
Version = GetVersion(xmlDoc, property) ?? "10.0.0"
57-
};
58-
attributes.Add(item);
59-
}
60-
return attributes.OrderBy(i => i.Name).ToList();
49+
Name = property.Name,
50+
Type = GetFriendlyTypeName(property.PropertyType),
51+
Description = GetSummary(xmlDoc, property) ?? "",
52+
Version = GetVersion(xmlDoc, property) ?? "10.0.0"
53+
}).OrderBy(i => i.Name).ToList();
6154
}
6255

6356
/// <summary>
@@ -68,37 +61,44 @@ private static List<AttributeItem> GetAttributeCore(Type type)
6861
if (xmlDoc == null) return null;
6962

7063
var memberName = $"P:{property.DeclaringType?.FullName}.{property.Name}";
64+
var summaryElement = FindSummaryElement(xmlDoc, memberName);
65+
return summaryElement == null ? null : GetLocalizedSummary(summaryElement);
66+
}
67+
68+
private static XElement? FindSummaryElement(XDocument xmlDoc, string memberName)
69+
{
7170
var memberElement = xmlDoc.Descendants("member")
7271
.FirstOrDefault(x => x.Attribute("name")?.Value == memberName);
7372

74-
if (memberElement == null) return null;
73+
var summaryElement = memberElement?.Element("summary");
74+
if (summaryElement == null)
75+
{
76+
return null;
77+
}
7578

76-
var summaryElement = memberElement.Element("summary");
77-
if (summaryElement == null) return null;
79+
var inheritDoc = summaryElement.Element("inheritdoc");
80+
var cref = inheritDoc?.Attribute("cref")?.Value;
81+
return cref != null ? FindSummaryElement(xmlDoc, cref) : summaryElement;
82+
}
7883

79-
// 获取当前语言(zh-CN -> zh, en-US -> en)
80-
var currentLanguage = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;
84+
private static string? GetLocalizedSummary(XElement? summaryElement)
85+
{
86+
if (summaryElement == null)
87+
{
88+
return null;
89+
}
8190

82-
// 查找匹配当前语言的 para 元素
91+
var currentLanguage = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;
8392
var langPara = summaryElement.Elements("para")
8493
.FirstOrDefault(p => p.Attribute("lang")?.Value == currentLanguage);
85-
8694
if (langPara != null)
8795
{
8896
return langPara.Value.Trim();
8997
}
9098

91-
// 如果找不到当前语言,回退到第一个有 lang 属性的 para(通常是 zh)
9299
var firstLangPara = summaryElement.Elements("para")
93100
.FirstOrDefault(p => p.Attribute("lang") != null);
94-
95-
if (firstLangPara != null)
96-
{
97-
return firstLangPara.Value.Trim();
98-
}
99-
100-
// 如果都没有,返回整个 summary 的文本(向后兼容旧格式)
101-
return summaryElement.Value.Trim();
101+
return firstLangPara != null ? firstLangPara.Value.Trim() : summaryElement.Value.Trim();
102102
}
103103

104104
/// <summary>
@@ -112,16 +112,13 @@ private static List<AttributeItem> GetAttributeCore(Type type)
112112
var memberElement = xmlDoc.Descendants("member")
113113
.FirstOrDefault(x => x.Attribute("name")?.Value == memberName);
114114

115-
if (memberElement == null) return null;
116-
117115
// 在 summary 节点下查找包含 version 的 para 节点
118116
// XML 格式: <summary><para><version>10.2.2</version></para></summary>
119-
var summaryElement = memberElement.Element("summary");
120-
if (summaryElement == null) return null;
117+
var summaryElement = memberElement?.Element("summary");
121118

122119
// 查找第一个包含 version 元素的 para
123120
// 直接在循环中返回,避免创建中间变量
124-
return summaryElement.Elements("para")
121+
return summaryElement?.Elements("para")
125122
.Select(p => p.Element("version"))
126123
.FirstOrDefault(v => v != null)
127124
?.Value.Trim();
@@ -140,6 +137,7 @@ private static string GetFriendlyTypeName(Type type)
140137
{
141138
genericTypeName = genericTypeName.Substring(0, backtickIndex);
142139
}
140+
143141
var genericArgs = string.Join(", ", type.GetGenericArguments().Select(GetFriendlyTypeName));
144142
return $"{genericTypeName}<{genericArgs}>";
145143
}

0 commit comments

Comments
 (0)