Skip to content

Commit

Permalink
Fix seealso cref handling (#168)
Browse files Browse the repository at this point in the history
* Update test to correctly verify see cref vs seealso cref.

* Convert inner seealso crefs to see crefs. Preserve seealsos that are standalone children.

* Skip porting seealsos if the CLI argument for member or type is set to true.

* Add tests to verify that skipping porting works for members and for types.
  • Loading branch information
carlossanlop committed Sep 19, 2023
1 parent 842204c commit 7171357
Show file tree
Hide file tree
Showing 9 changed files with 348 additions and 28 deletions.
38 changes: 38 additions & 0 deletions src/PortToDocs/src/libraries/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ private enum Mode
PortMemberProperties,
PortMemberReturns,
PortMemberRemarks,
PortMemberSeeAlsos,
PortMemberSummaries,
PortMemberTypeParams,
PortTypeParams, // Params of a Type
PortTypeRemarks,
PortTypeSeeAlsos,
PortTypeSummaries,
PortTypeTypeParams, // TypeParams of a Type
PreserveInheritDocTag,
Expand Down Expand Up @@ -88,13 +90,15 @@ private enum Mode
public bool PortMemberProperties { get; set; } = true;
public bool PortMemberReturns { get; set; } = true;
public bool PortMemberRemarks { get; set; } = true;
public bool PortMemberSeeAlsos { get; set; } = true;
public bool PortMemberSummaries { get; set; } = true;
public bool PortMemberTypeParams { get; set; } = true;
/// <summary>
/// Params of a Type.
/// </summary>
public bool PortTypeParams { get; set; } = true;
public bool PortTypeRemarks { get; set; } = true;
public bool PortTypeSeeAlsos { get; set; } = true;
public bool PortTypeSummaries { get; set; } = true;
/// <summary>
/// TypeParams of a Type.
Expand Down Expand Up @@ -395,6 +399,10 @@ public static Configuration GetCLIArguments(string[] args)
mode = Mode.PortMemberSummaries;
break;

case "-PORTMEMBERSEEALSOS":
mode = Mode.PortMemberSeeAlsos;
break;

case "-PORTMEMBERTYPEPARAMS":
mode = Mode.PortMemberTypeParams;
break;
Expand All @@ -407,6 +415,10 @@ public static Configuration GetCLIArguments(string[] args)
mode = Mode.PortTypeRemarks;
break;

case "-PORTTYPESEEALSOS":
mode = Mode.PortTypeSeeAlsos;
break;

case "-PORTTYPESUMMARIES":
mode = Mode.PortTypeSummaries;
break;
Expand Down Expand Up @@ -516,6 +528,13 @@ public static Configuration GetCLIArguments(string[] args)
break;
}

case Mode.PortMemberSeeAlsos:
{
config.PortMemberSeeAlsos = ParseOrExit(arg, "Port member SeeAlsos");
mode = Mode.Initial;
break;
}

case Mode.PortMemberSummaries:
{
config.PortMemberSummaries = ParseOrExit(arg, "Port member Summaries");
Expand Down Expand Up @@ -544,6 +563,13 @@ public static Configuration GetCLIArguments(string[] args)
break;
}

case Mode.PortTypeSeeAlsos:
{
config.PortTypeSeeAlsos = ParseOrExit(arg, "Port type SeeAlsos");
mode = Mode.Initial;
break;
}

case Mode.PortTypeSummaries:
{
config.PortTypeSummaries = ParseOrExit(arg, "Port Type Summaries");
Expand Down Expand Up @@ -802,6 +828,12 @@ public static void PrintHelp()
Usage example:
-PortMemberRemarks false
-PortMemberSeeAlsos bool Default is true (ports Member seealsos).
Enable or disable finding and porting Member seealsos.
These are found directly under the Docs xml element.
Usage example:
-PortMemberSeeAlsos false
-PortMemberSummaries bool Default is true (ports Member summaries).
Enable or disable finding and porting Member summaries.
Usage example:
Expand All @@ -822,6 +854,12 @@ public static void PrintHelp()
Usage example:
-PortTypeRemarks false
-PortTypeSeeAlsos bool Default is true (ports Type seealsos).
Enable or disable finding and porting Type seealsos.
These are found directly under the Docs xml element.
Usage example:
-PortTypeSeeAlsos false
-PortTypeSummaries bool Default is true (ports Type summaries).
Enable or disable finding and porting Type summaries.
Usage example:
Expand Down
23 changes: 16 additions & 7 deletions src/PortToDocs/src/libraries/Docs/DocsAPI.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
Expand All @@ -18,7 +18,7 @@ internal abstract class DocsAPI : IDocsAPI
private List<DocsTypeParameter>? _typeParameters;
private List<DocsTypeParam>? _typeParams;
private List<DocsAssemblyInfo>? _assemblyInfos;
private List<string>? _seeAlsoCrefs;
private List<DocsSeeAlso>? _seeAlsos;
private List<string>? _altMemberCrefs;
private List<DocsRelated>? _relateds;
private XElement? _xInheritDoc = null;
Expand Down Expand Up @@ -140,22 +140,22 @@ public List<DocsTypeParam> TypeParams
}
}

public List<string> SeeAlsoCrefs
public List<DocsSeeAlso> SeeAlsos
{
get
{
if (_seeAlsoCrefs == null)
if (_seeAlsos == null)
{
if (Docs != null)
{
_seeAlsoCrefs = Docs.Elements("seealso").Select(x => XmlHelper.GetAttributeValue(x, "cref")).ToList();
_seeAlsos = Docs.Elements("seealso").Select(x => new DocsSeeAlso(this, x)).ToList();
}
else
{
_seeAlsoCrefs = new();
_seeAlsos = new();
}
}
return _seeAlsoCrefs;
return _seeAlsos;
}
}

Expand Down Expand Up @@ -310,6 +310,15 @@ public DocsTypeParam AddTypeParam(string name, string value)
return new DocsTypeParam(this, typeParam);
}

public DocsSeeAlso AddSeeAlso(string cref)
{
XElement seeAlso = new XElement("seealso");
seeAlso.SetAttributeValue("cref", cref);
Docs.Add(seeAlso);
Changed = true;
return new DocsSeeAlso(this, seeAlso);
}

// For Types, these elements are called TypeSignature.
// For Members, these elements are called MemberSignature.
protected abstract string GetApiSignatureDocId();
Expand Down
2 changes: 1 addition & 1 deletion src/PortToDocs/src/libraries/Docs/DocsMember.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
Expand Down
26 changes: 26 additions & 0 deletions src/PortToDocs/src/libraries/Docs/DocsSeeAlso.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Xml.Linq;

namespace ApiDocsSync.PortToDocs.Docs;

internal class DocsSeeAlso
{
private readonly XElement XESeeAlso;

public IDocsAPI ParentAPI
{
get; private set;
}

public string Cref => XmlHelper.GetAttributeValue(XESeeAlso, "cref");

public DocsSeeAlso(IDocsAPI parentAPI, XElement xSeeAlso)
{
ParentAPI = parentAPI;
XESeeAlso = xSeeAlso;
}

public override string ToString() => $"seealso cref={Cref}";
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
Expand Down Expand Up @@ -107,6 +107,19 @@ public IEnumerable<IntelliSenseXmlException> Exceptions
}
}

private List<IntelliSenseXmlSeeAlso>? _seeAlsos;
public IEnumerable<IntelliSenseXmlSeeAlso> SeeAlsos
{
get
{
if (_seeAlsos == null)
{
_seeAlsos = XEMember.Elements("seealso").Select(x => new IntelliSenseXmlSeeAlso(x)).ToList();
}
return _seeAlsos;
}
}

private string? _summary;
public string Summary
{
Expand All @@ -116,6 +129,7 @@ public string Summary
{
XElement? xElement = XEMember.Element("summary");
_summary = (xElement != null) ? XmlHelper.GetNodesInPlainText(xElement) : string.Empty;
_summary = XmlHelper.ReplaceSeeAlsos(_summary);
}
return _summary;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Xml.Linq;

namespace ApiDocsSync.PortToDocs.IntelliSenseXml;

internal class IntelliSenseXmlSeeAlso(XElement xeSeeAlso)
{
public XElement XESeeAlso
{
get;
private set;
} = xeSeeAlso;

private string _cref = string.Empty;
public string Cref
{
get
{
if (string.IsNullOrWhiteSpace(_cref))
{
_cref = XmlHelper.GetAttributeValue(XESeeAlso, "cref");
}
return _cref;
}
}

public override string ToString() => $"SeeAlso cref={Cref}";
}
22 changes: 22 additions & 0 deletions src/PortToDocs/src/libraries/ToDocsPorter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ private void PortMissingCommentsForType(DocsType dTypeToUpdate)
TryPortMissingReturnsForMember(dTypeToUpdate, mc.Returns);
}

TryPortMissingSeeAlsosForMember(dTypeToUpdate, tsTypeToPort);

if (dTypeToUpdate.Changed)
{
ModifiedTypes.Add(docId);
Expand Down Expand Up @@ -309,6 +311,8 @@ private void PortMissingCommentsForMember(DocsMember dMemberToUpdate)
TryPortMissingReturnsForMember(dMemberToUpdate, mc.Returns, mc.IsEII);
}

TryPortMissingSeeAlsosForMember(dMemberToUpdate, tsMemberToPort);

if (dMemberToUpdate.Changed)
{
ModifiedAPIs.Add(dMemberToUpdate.DocId);
Expand Down Expand Up @@ -964,6 +968,24 @@ private void TryPortMissingExceptionsForMember(DocsMember dMemberToUpdate, Intel
}
}

private void TryPortMissingSeeAlsosForMember(DocsAPI dAPIToUpdate, IntelliSenseXmlMember? tsMemberToPort)
{
if ((dAPIToUpdate.Kind == APIKind.Member && !Config.PortMemberSeeAlsos) || (dAPIToUpdate.Kind == APIKind.Type && !Config.PortTypeSeeAlsos) || tsMemberToPort == null)
{
return;
}

foreach (IntelliSenseXmlSeeAlso tsSeeAlso in tsMemberToPort.SeeAlsos)
{
if (!dAPIToUpdate.SeeAlsos.Any(x => x.Cref == tsSeeAlso.Cref))
{
dAPIToUpdate.AddSeeAlso(tsSeeAlso.Cref);
PrintModifiedMember("seealso", dAPIToUpdate.FilePath, tsSeeAlso.Cref, isEII: false);
TotalModifiedIndividualElements++;
}
}
}

// If a Param is found in a DocsType or a DocsMember that did not exist in the IntelliSense xml member, it's possible the param was unexpectedly saved in the IntelliSense xml comments with a different name, so the user gets prompted to look for it.
private bool TryPromptParam(DocsParam oldDParam, IntelliSenseXmlMember tsMember, out IntelliSenseXmlParam? newTsParam)
{
Expand Down
32 changes: 15 additions & 17 deletions src/PortToDocs/src/libraries/XmlHelper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
Expand Down Expand Up @@ -33,6 +33,11 @@ internal class XmlHelper
{ "></see>", " />" }
};

private static readonly Dictionary<string, string> _replaceableSeeAlsos = new Dictionary<string, string>
{
{ "seealso cref", "see cref" }
};

private static readonly Dictionary<string, string> _replaceableNormalElementRegexPatterns = new Dictionary<string, string>
{
// Replace primitives: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/built-in-types
Expand Down Expand Up @@ -297,26 +302,19 @@ private static string RemoveUndesiredEndlines(string value)
return value.Trim();
}

private static string ReplaceMarkdownPatterns(string value)
{
string updatedValue = value;
foreach (KeyValuePair<string, string> kvp in _replaceableMarkdownPatterns)
{
if (updatedValue.Contains(kvp.Key))
{
updatedValue = updatedValue.Replace(kvp.Key, kvp.Value);
}
}
return updatedValue;
}

internal static string ReplaceExceptionPatterns(string value) =>
Regex.Replace(value, @"[\r\n\t ]+\-[ ]?or[ ]?\-[\r\n\t ]+", "\n\n-or-\n\n");
Regex.Replace(value, @"[\r\n\t ]+\-[ ]*(or|OR)[ ]*\-[\r\n\t ]+", "\n\n-or-\n\n");

internal static string ReplaceSeeAlsos(string value) => ReplacePatterns(value, _replaceableSeeAlsos);

private static string ReplaceMarkdownPatterns(string value) => ReplacePatterns(value, _replaceableMarkdownPatterns);

private static string ReplaceNormalElementPatterns(string value) => ReplacePatterns(value, _replaceableNormalElementPatterns);

private static string ReplaceNormalElementPatterns(string value)
private static string ReplacePatterns(string value, Dictionary<string, string> patterns)
{
string updatedValue = value;
foreach (KeyValuePair<string, string> kvp in _replaceableNormalElementPatterns)
foreach (KeyValuePair<string, string> kvp in patterns)
{
if (updatedValue.Contains(kvp.Key))
{
Expand Down

0 comments on commit 7171357

Please sign in to comment.