8000 Fix inheritdoc bugs for full or partial inheritance: (#130) · dotnet/api-docs-sync@1dd98ad · GitHub
[go: up one dir, main page]

Skip to content

Commit 1dd98ad

Browse files
authored
Fix inheritdoc bugs for full or partial inheritance: (#130)
- Avoid escaping crefs except when printing to log. - Make sure params and typeparams are also ported when inheriting from base type or interface. - Add tests. Co-authored-by: carlossanlop <carlossanlop@users.noreply.github.com>
1 parent 581c344 commit 1dd98ad

File tree

5 files changed

+749
-276
lines changed

5 files changed

+749
-276
lines changed

src/PortToDocs/src/libraries/Docs/DocsAPI.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ internal abstract class DocsAPI : IDocsAPI
3737
public abstract bool Changed { get; set; }
3838
public string FilePath { get; set; } = string.Empty;
3939

40-
public string DocId => _docId ??= GetApiSignatureDocId().AsEscapedDocId();
40+
public string DocId => _docId ??= GetApiSignatureDocId();
4141

4242
public string DocIdUnprefixed => _docIdUnprefixed ??= DocId[2..];
4343

@@ -148,7 +148,7 @@ public List<string> SeeAlsoCrefs
148148
{
149149
if (Docs != null)
150150
{
151-
_seeAlsoCrefs = Docs.Elements("seealso").Select(x => XmlHelper.GetAttributeValue(x, "cref").AsEscapedDocId()).ToList();
151+
_seeAlsoCrefs = Docs.Elements("seealso").Select(x => XmlHelper.GetAttributeValue(x, "cref")).ToList();
152152
}
153153
else
154154
{
@@ -167,7 +167,7 @@ public List<string> AltMembers
167167
{
168168
if (Docs != null)
169169
{
170-
_altMemberCrefs = Docs.Elements("altmember").Select(x => XmlHelper.GetAttributeValue(x, "cref").AsEscapedDocId()).ToList();
170+
_altMemberCrefs = Docs.Elements("altmember").Select(x => XmlHelper.GetAttributeValue(x, "cref")).ToList();
171171
}
172172
else
173173
{
@@ -221,7 +221,7 @@ public string InheritDocCref
221221
XAttribute? xInheritDocCref = XInheritDoc.Attribute("cref");
222222
if (xInheritDocCref != null)
223223
{
224-
_inheritDocCref = xInheritDocCref.Value.AsEscapedDocId();
224+
_inheritDocCref = xInheritDocCref.Value;
225225
}
226226
}
227227
}
@@ -238,7 +238,7 @@ public string InheritDocCref
238238
// Non-null to add
239239
else
240240
{
241-
_inheritDocCref = value.AsEscapedDocId(); // Can be empty string too
241+
_inheritDocCref = value; // Can be empty string too
242242
if (XInheritDoc == null) // Not found in Docs
243243
{
244244
XInheritDoc = new XElement("inheritdoc");

src/PortToDocs/src/libraries/Docs/DocsException.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public IDocsAPI ParentAPI
1616
get; private set;
1717
}
1818

19-
public string Cref => XmlHelper.GetAttributeValue(XEException, "cref").AsEscapedDocId();
19+
public string Cref => XmlHelper.GetAttributeValue(XEException, "cref");
2020

2121
public string Value
2222
{

src/PortToDocs/src/libraries/IntelliSenseXml/IntelliSenseXmlMember.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public string InheritDocCref
3030
XAttribute? xInheritDocCref = XInheritDoc.Attribute("cref");
3131
if (xInheritDocCref != null)
3232
{
33-
_inheritDocCref = xInheritDocCref.Value.AsEscapedDocId();
33+
_inheritDocCref = xInheritDocCref.Value;
3434
}
3535
}
3636
}
@@ -66,7 +66,7 @@ public string Namespace
6666
/// <summary>
6767
/// The API DocId.
6868
/// </summary>
69-
public string Name => _name ??= XmlHelper.GetAttributeValue(XEMember, "name").AsEscapedDocId();
69+
public string Name => _name ??= XmlHelper.GetAttributeValue(XEMember, "name");
7070

7171
private List<IntelliSenseXmlParam>? _params;
7272
public List<IntelliSenseXmlParam> Params

src/PortToDocs/src/libraries/ToDocsPorter.cs

Lines changed: 109 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Diagnostics.SymbolStore;
67
using System.IO;
78
using System.Linq;
89
using System.Text;
@@ -212,6 +213,18 @@ private void PortMissingCommentsForType(DocsType dTypeToUpdate)
212213
Remarks = tsActualTypeToPort.Remarks
213214
};
214215

216+
// delegates
217+
foreach (IntelliSenseXmlParam tsParam in tsTypeToPort.Params)
218+
{
219+
mc.Params.Add(tsParam.Name, tsParam.Value);
220+
}
221+
222+
// type typeparams
223+
foreach (IntelliSenseXmlTypeParam tsTypeParam in tsTypeToPort.TypeParams)
224+
{
225+
mc.TypeParams.Add(tsTypeParam.Name, tsTypeParam.Value);
226+
}
227+
215228
// Rare case where the base type or interface docs should be used
216229
if (tsTypeToPort.InheritDoc)
217230
{
@@ -258,6 +271,16 @@ private void PortMissingCommentsForMember(DocsMember dMemberToUpdate)
258271
mc.Property = GetPropertyValue(tsMemberToPort.Value, tsMemberToPort.Returns);
259272
}
260273

274+
foreach (IntelliSenseXmlParam tsParam in tsMemberToPort.Params)
275+
{
276+
mc.Params.Add(tsParam.Name, tsParam.Value);
277+
}
278+
279+
foreach (IntelliSenseXmlTypeParam tsTypeParam in tsMemberToPort.TypeParams)
280+
{
281+
mc.TypeParams.Add(tsTypeParam.Name, tsTypeParam.Value);
282+
}
283+
261284
// Rare case where the base type or interface docs should be used,
262285
// but only for elements that aren't explicitly documented in the actual API
263286
if (tsMemberToPort.InheritDoc)
@@ -313,7 +336,18 @@ private void GetMissingCommentsForTypeFromInheritDoc(MissingComments mc, DocsTyp
313336
mc.Summary = tsInheritedMember.Summary;
314337
mc.Returns = tsInheritedMember.Returns;
315338
mc.Remarks = tsInheritedMember.Remarks;
316-
339+
340+
// delegates
341+
foreach (IntelliSenseXmlParam tsParam in tsInheritedMember.Params)
342+
{
343+
mc.Params.Add(tsParam.Name, tsParam.Value);
344+
}
345+
346+
// type typeparams
347+
foreach (IntelliSenseXmlTypeParam tsTypeParam in tsInheritedMember.TypeParams)
348+
{
349+
mc.TypeParams.Add(tsTypeParam.Name, tsTypeParam.Value);
350+
}
317351
}
318352
// Look for the base type from which this one inherits
319353
else if (DocsComments.Types.TryGetValue($"T:{dTypeToUpdate.BaseTypeName}", out DocsType? dBaseType) &&
@@ -329,6 +363,18 @@ private void GetMissingCommentsForTypeFromInheritDoc(MissingComments mc, DocsTyp
329363
mc.Summary = dBaseType.Summary;
330364
mc.Returns = dBaseType.Returns;
331365
mc.Remarks = dBaseType.Remarks;
366+
367+
// delegates
368+
foreach (DocsParam tsParam in dBaseType.Params)
369+
{
370+
mc.Params.Add(tsParam.Name, tsParam.Value);
371+
}
372+
373+
// type typeparams
374+
foreach (DocsTypeParam tsTypeParam in dBaseType.TypeParams)
375+
{
376+
mc.TypeParams.Add(tsTypeParam.Name, tsTypeParam.Value);
377+
}
332378
}
333379
}
334380

@@ -358,6 +404,22 @@ private void GetMissingCommentsForMemberFromInheritDoc(MissingComments mc, DocsM
358404
{
359405
mc.Property = GetPropertyValue(tsInheritedMember.Value, tsInheritedMember.Returns);
360406
}
407+
408+
foreach (IntelliSenseXmlParam tsParam in tsInheritedMember.Params)
409+
{
410+
if (!mc.Params.TryAdd(tsParam.Name, tsParam.Value))
411+
{
412+
mc.Params[tsParam.Name] = tsParam.Value;
413+
}
414+
}
415+
416+
foreach (IntelliSenseXmlTypeParam tsTypeParam in tsInheritedMember.TypeParams)
417+
{
418+
if (!mc.TypeParams.TryAdd(tsTypeParam.Name, tsTypeParam.Value))
419+
{
420+
mc.TypeParams[tsTypeParam.Name] = tsTypeParam.Value;
421+
}
422+
}
361423
}
362424
// Look for the base type and find the member from which this one inherits
363425
else if (DocsComments.Types.TryGetValue($"T:{dMemberToUpdate.ParentType.BaseTypeName}", out DocsType? dBaseType) &&
@@ -397,6 +459,22 @@ private void GetMissingCommentsForMemberFromInheritDoc(MissingComments mc, DocsM
397459
{
398460
mc.Property = GetPropertyValue(dBaseMember.Value, dBaseMember.Returns);
399461
}
462+
463+
foreach (DocsParam baseParam in dBaseMember.Params)
464+
{
465+
if (!mc.Params.TryAdd(baseParam.Name, baseParam.Value))
466+
{
467+
mc.Params[baseParam.Name] = baseParam.Value;
468+
}
469+
}
470+
471+
foreach (DocsTypeParam baseTypeParam in dBaseMember.TypeParams)
472+
{
473+
if (!mc.TypeParams.TryAdd(baseTypeParam.Name, baseTypeParam.Value))
474+
{
475+
mc.TypeParams[baseTypeParam.Name] = baseTypeParam.Value;
476+
}
477+
}
400478
}
401479
}
402480
}
@@ -413,13 +491,29 @@ private MissingComments GetMissingCommentsForMemberFromInterface(MissingComments
413491
mc.Property = GetPropertyValue(dInterfacedMember.Value, dInterfacedMember.Returns);
414492
}
415493

494+
foreach (DocsParam interfaceParam in dInterfacedMember.Params)
495+
{
496+
if (!mc.Params.TryAdd(interfaceParam.Name, interfaceParam.Value))
497+
{
498+
mc.Params[interfaceParam.Name] = interfaceParam.Value;
499+
}
500+
}
501+
502+
foreach (DocsTypeParam interfaceTypeParam in dInterfacedMember.TypeParams)
503+
{
504+
if (!mc.TypeParams.TryAdd(interfaceTypeParam.Name, interfaceTypeParam.Value))
505+
{
506+
mc.TypeParams[interfaceTypeParam.Name] = interfaceTypeParam.Value;
507+
}
508+
}
509+
416510
if (!dInterfacedMember.Remarks.IsDocsEmpty())
417511
{
418512
// Only attempt to port if the member name is the same as the interfaced member docid without prefix
419-
if (dMemberToUpdate.MemberName == dInterfacedMember.DocId[2..])
513+
if (dMemberToUpdate.MemberName == dInterfacedMember.DocIdUnprefixed)
420514
{
421-
string dMemberToUpdateTypeDocIdNoPrefix = dMemberToUpdate.ParentType.DocId[2..];
422-
string interfacedMemberTypeDocIdNoPrefix = dInterfacedMember.ParentType.DocId[2..];
515+
string dMemberToUpdateTypeDocIdNoPrefix = dMemberToUpdate.ParentType.DocIdUnprefixed;
516+
string interfacedMemberTypeDocIdNoPrefix = dInterfacedMember.ParentType.DocIdUnprefixed;
423517

424518
// Special text for EIIs in Remarks
425519
string eiiMessage = $"This member is an explicit interface member implementation. It can be used only when the <xref:{dMemberToUpdateTypeDocIdNoPrefix}> instance is cast to an <xref:{interfacedMemberTypeDocIdNoPrefix}> interface.";
@@ -840,7 +934,7 @@ private void TryPortMissingExceptionsForMember(DocsMember dMemberToUpdate, Intel
840934
// First time adding the cref
841935
if (dException == null && Config.PortExceptionsNew)
842936
{
843-
AddedExceptions.Add($"Exception=[{tsException.Cref}] in Member=[{dMemberToUpdate.DocId}]");
937+
AddedExceptions.Add($"Exception=[{tsException.Cref.AsEscapedDocId()}] in Member=[{dMemberToUpdate.DocId}]");
844938
string text = XmlHelper.ReplaceExceptionPatterns(XmlHelper.GetNodesInPlainText(tsException.XEException));
845939
dException = dMemberToUpdate.AddException(tsException.Cref, text);
846940
created = true;
@@ -852,7 +946,7 @@ private void TryPortMissingExceptionsForMember(DocsMember dMemberToUpdate, Intel
852946
string value = XmlHelper.ReplaceExceptionPatterns(XmlHelper.GetNodesInPlainText(formattedException));
853947
if (!dException.WordCountCollidesAboveThreshold(value, Config.ExceptionCollisionThreshold))
854948
{
855-
AddedExceptions.Add($"Exception=[{tsException.Cref}] in Member=[{dMemberToUpdate.DocId}]");
949+
AddedExceptions.Add($"Exception=[{tsException.Cref.AsEscapedDocId()}] in Member=[{dMemberToUpdate.DocId}]");
856950
dException.AppendException(value);
857951
created = true;
858952
}
@@ -886,7 +980,7 @@ private bool TryPromptParam(DocsParam oldDParam, IntelliSenseXmlMember tsMember,
886980
int option = -1;
887981
while (option == -1)
888982
{
889-
Log.Error($"Problem in param '{oldDParam.Name}' in member '{tsMember.Name}' in file '{oldDParam.ParentAPI.FilePath}'");
983+
Log.Error($"Problem in param '{oldDParam.Name}' in member '{tsMember.Name.AsEscapedDocId()}' in file '{oldDParam.ParentAPI.FilePath}'");
890984
Log.Error($"The param probably exists in code, but the exact name was not found in Docs. What would you like to do?");
891985
Log.Warning(" 0 - Exit program.");
892986
Log.Info(" 1 - Select the correct IntelliSense xml param from the existing ones.");
@@ -915,7 +1009,7 @@ private bool TryPromptParam(DocsParam oldDParam, IntelliSenseXmlMember tsMember,
9151009
int paramSelection = -1;
9161010
while (paramSelection == -1)
9171011
{
918-
Log.Info($"IntelliSense xml params found in member '{tsMember.Name}':");
1012+
Log.Info($"IntelliSense xml params found in member '{tsMember.Name.AsEscapedDocId()}':");
9191013
Log.Warning(" 0 - Exit program.");
9201014
Log.Info(" 1 - Ignore this param and continue.");
9211015
int paramCounter = 2;
@@ -991,7 +1085,7 @@ private bool TryPromptTypeParam(DocsTypeParam oldDTypeParam, IntelliSenseXmlMemb
9911085
int option = -1;
9921086
while (option == -1)
9931087
{
994-
Log.Error($"Problem in typeparam '{oldDTypeParam.Name}' in member '{tsMember.Name}' in file '{oldDTypeParam.ParentAPI.FilePath}'");
1088+
Log.Error($"Problem in typeparam '{oldDTypeParam.Name}' in member '{tsMember.Name.AsEscapedDocId()}' in file '{oldDTypeParam.ParentAPI.FilePath}'");
9951089
Log.Error($"The typeparam probably exists in code, but the exact name was not found in Docs. What would you like to do?");
9961090
Log.Warning(" 0 - Exit program.");
9971091
Log.Info(" 1 - Select the correct IntelliSense xml typeparam from the existing ones.");
@@ -1020,7 +1114,7 @@ private bool TryPromptTypeParam(DocsTypeParam oldDTypeParam, IntelliSenseXmlMemb
10201114
int typeParamSelection = -1;
10211115
while (typeParamSelection == -1)
10221116
{
1023-
Log.Info($"IntelliSense xml typeparams found in member '{tsMember.Name}':");
1117+
Log.Info($"IntelliSense xml typeparams found in member '{tsMember.Name.AsEscapedDocId()}':");
10241118
Log.Warning(" 0 - Exit program.");
10251119
Log.Info(" 1 - Ignore this typeparam and continue.");
10261120
int typeParamCounter = 2;
@@ -1216,7 +1310,7 @@ void TryPrintMember(ref bool undocMember, string memberDocId)
12161310
{
12171311
TryPrintMember(ref undocMember, member.DocId);
12181312

1219-
Log.Error($" Member Exception: {exception.Cref}: {exception.Value}");
1313+
Log.Error($" Member Exception: {exception.Cref.AsEscapedDocId()}: {exception.Value}");
12201314
exceptions++;
12211315
}
12221316
}
@@ -1240,6 +1334,8 @@ private class MissingComments
12401334
internal string Returns { get; set; }
12411335
internal string Remarks { get; set; }
12421336
internal string Property { get; set; }
1337+
internal Dictionary<string, string> Params { get; }
1338+
internal Dictionary<string, string> TypeParams { get; }
12431339
internal bool IsEII { get; set; }
12441340

12451341
internal MissingComments()
@@ -1248,6 +1344,8 @@ internal MissingComments()
12481344
Returns = Configuration.ToBeAdded;
12491345
Remarks = Configuration.ToBeAdded;
12501346
Property = Configuration.ToBeAdded;
1347+
Params = new Dictionary<string, string>();
1348+
TypeParams = new Dictionary<string, string>();
12511349
}
12521350
}
12531351
}

0 commit comments

Comments
 (0)
0