diff options
author | Min Huang <huangmin@microsoft.com> | 2022-08-15 11:21:26 +0300 |
---|---|---|
committer | Min Huang <huangmin@microsoft.com> | 2022-08-15 11:21:26 +0300 |
commit | 10776f4919794935749b6cb905bc758e48c889cc (patch) | |
tree | 0befc71cfd8dbe9a01b6e7940ed0a6b4aeda9d4d | |
parent | 796b1e1de6749e04b0f43ff1e7cc2c34a880e37b (diff) |
feat #608072: Monikerize type parameters name
-rw-r--r-- | mdoc/Mono.Documentation/MDocUpdater.cs | 139 | ||||
-rw-r--r-- | mdoc/Mono.Documentation/Util/MdocUpdaterHelper.cs | 100 |
2 files changed, 145 insertions, 94 deletions
diff --git a/mdoc/Mono.Documentation/MDocUpdater.cs b/mdoc/Mono.Documentation/MDocUpdater.cs index e98b068b..d6dfe305 100644 --- a/mdoc/Mono.Documentation/MDocUpdater.cs +++ b/mdoc/Mono.Documentation/MDocUpdater.cs @@ -10,6 +10,7 @@ using System.Text; using System.Xml; using System.Xml.Linq; using System.Xml.XPath; +using mdoc.Mono.Documentation.Util; using Mono.Cecil; using Mono.Documentation.Updater; using Mono.Documentation.Updater.Formatters; @@ -3279,14 +3280,6 @@ namespace Mono.Documentation return element; } - static XmlElement AppendElementText (XmlNode parent, string element, string value) - { - XmlElement n = parent.OwnerDocument.CreateElement (element); - parent.AppendChild (n); - n.InnerText = value; - return n; - } - static XmlElement AppendElementAttributeText (XmlNode parent, string element, string attribute, string value) { XmlElement n = parent.OwnerDocument.CreateElement (element); @@ -4070,47 +4063,44 @@ namespace Mono.Documentation } } - if (typeEntry.Framework.IsLastFrameworkForType(typeEntry)) - { - // Now clean up - var allFrameworks = typeEntry.Framework.AllFrameworksWithType(typeEntry); - var finalNodes = paramNodes - .Cast<XmlElement> ().ToArray (); - foreach (var parameter in finalNodes) - { - // if FXAlternate is entire list, just remove it - if (parameter.HasAttribute (Consts.FrameworkAlternate) && parameter.GetAttribute (Consts.FrameworkAlternate) == allFrameworks) - { - parameter.RemoveAttribute (Consts.FrameworkAlternate); - } - } - - // if there are no fx attributes left, just remove the indices entirely - if (!finalNodes.Any (n => n.HasAttribute (Consts.FrameworkAlternate))) - { - foreach (var parameter in finalNodes) - parameter.RemoveAttribute (Consts.Index); - } - } + MdocUpdaterHelper.CheckFrameworkAlternateAttribute(typeEntry, e, "Parameter"); } private void MakeTypeParameters (FrameworkTypeEntry entry, XmlElement root, IList<GenericParameter> typeParams, MemberReference member, bool shouldDuplicateWithNew) { - if (typeParams == null || typeParams.Count == 0) + if (ProcessedMoreThanOnce(entry)) { - XmlElement f = (XmlElement)root.SelectSingleNode ("TypeParameters"); - if (f != null) - root.RemoveChild (f); return; } - XmlElement e = WriteElement (root, "TypeParameters"); - - var nodes = e.SelectNodes ("TypeParameter").Cast<XmlElement> ().ToArray (); + XmlElement e = WriteElement(root, "TypeParameters"); - foreach (GenericParameter t in typeParams) + if (entry.Framework.IsFirstFrameworkForType(entry)) { + e.RemoveAll(); + } + var nodes = e.SelectNodes("TypeParameter") + .Cast<XmlElement>() + .Select((n, i) => + { + int index = i; + if (n.HasAttribute(Consts.Index)) + int.TryParse(n.GetAttribute(Consts.Index), out index); + + return new + { + Element = n, + Name = n.GetAttribute("Name"), + Index = index, + FrameworkAlternates = n.GetAttribute(Consts.FrameworkAlternate) + }; + }) + .ToArray(); + + for (int i = 0; i < typeParams.Count; i++) + { + var t = typeParams[i]; #if NEW_CECIL Mono.Collections.Generic.Collection<GenericParameterConstraint> constraints = t.Constraints; #else @@ -4118,76 +4108,37 @@ namespace Mono.Documentation #endif GenericParameterAttributes attrs = t.Attributes; - var existing = nodes.FirstOrDefault(x => x.GetAttribute("Name") == t.Name); + var existing = nodes.Where(node => node.Name == t.Name && node.Index == i).FirstOrDefault(); if (existing != null) { - MakeParamsAttributes(existing, AttributeFormatter.PreProcessCustomAttributes(t.CustomAttributes), entry, member); + var xElement = existing.Element; + var fxaValue = FXUtils.AddFXToList(existing.FrameworkAlternates, entry.Framework.Name); + xElement.RemoveAttribute(Consts.FrameworkAlternate); + xElement.SetAttribute(Consts.FrameworkAlternate, fxaValue); + MakeParamsAttributes(existing.Element, AttributeFormatter.PreProcessCustomAttributes(t.CustomAttributes), entry, member); } else { XmlElement pe = root.OwnerDocument.CreateElement("TypeParameter"); - e.AppendChild(pe); - pe.SetAttribute("Name", t.Name); - MakeParamsAttributes(pe, AttributeFormatter.PreProcessCustomAttributes(t.CustomAttributes), entry, member); - XmlElement ce = (XmlElement)e.SelectSingleNode("Constraints"); - if (attrs == GenericParameterAttributes.NonVariant && constraints.Count == 0) + var sameIndexElements = nodes.Where(node => node.Index == i).ToArray(); + if (sameIndexElements != null && sameIndexElements.Length > 0) { - if (ce != null) - e.RemoveChild(ce); + // order the type parameters by index + e.InsertAfter(pe, sameIndexElements.Last().Element); } - if (ce != null) - ce.RemoveAll(); else { - ce = root.OwnerDocument.CreateElement("Constraints"); - } - if ((attrs & GenericParameterAttributes.Contravariant) != 0) - AppendElementText(ce, "ParameterAttribute", "Contravariant"); - if ((attrs & GenericParameterAttributes.Covariant) != 0) - AppendElementText(ce, "ParameterAttribute", "Covariant"); - if ((attrs & GenericParameterAttributes.DefaultConstructorConstraint) != 0) - AppendElementText(ce, "ParameterAttribute", "DefaultConstructorConstraint"); - if ((attrs & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0) - AppendElementText(ce, "ParameterAttribute", "NotNullableValueTypeConstraint"); - if ((attrs & GenericParameterAttributes.ReferenceTypeConstraint) != 0) - AppendElementText(ce, "ParameterAttribute", "ReferenceTypeConstraint"); - -#if NEW_CECIL - foreach (GenericParameterConstraint c in constraints) - { - TypeDefinition cd = c.ConstraintType.Resolve (); - AppendElementText (ce, - (cd != null && cd.IsInterface) ? "InterfaceName" : "BaseTypeName", - GetDocTypeFullName (c.ConstraintType)); - } -#else - foreach (TypeReference c in constraints) - { - TypeDefinition cd = c.Resolve(); - AppendElementText(ce, - (cd != null && cd.IsInterface) ? "InterfaceName" : "BaseTypeName", - GetDocTypeFullName(c)); - } -#endif - if (ce.HasChildNodes) - { - pe.AppendChild(ce); + e.AppendChild(pe); } + pe.SetAttribute("Name", t.Name); + pe.SetAttribute(Consts.Index, i.ToString()); + pe.SetAttribute(Consts.FrameworkAlternate, entry.Framework.Name); + MakeParamsAttributes(pe, AttributeFormatter.PreProcessCustomAttributes(t.CustomAttributes), entry, member); + MdocUpdaterHelper.MakeTypeParameterConstraints(root, e, pe, attrs, constraints); } } - nodes = e.SelectNodes("TypeParameter").Cast<XmlElement>().ToArray(); - if (nodes.Length != typeParams.Count) - { - foreach (var node in nodes) - { - var existing = typeParams.FirstOrDefault(x => x.Name == node.GetAttribute("Name")); - if (existing == null) - { - node.ParentNode.RemoveChild(node); - } - } - } + MdocUpdaterHelper.CheckFrameworkAlternateAttribute(entry, e, "TypeParameter"); } private void MakeParameters (XmlElement root, MemberReference mi, FrameworkTypeEntry typeEntry, ref bool fxAlternateTriggered, bool shouldDuplicateWithNew) diff --git a/mdoc/Mono.Documentation/Util/MdocUpdaterHelper.cs b/mdoc/Mono.Documentation/Util/MdocUpdaterHelper.cs new file mode 100644 index 00000000..7cfed4a9 --- /dev/null +++ b/mdoc/Mono.Documentation/Util/MdocUpdaterHelper.cs @@ -0,0 +1,100 @@ +using Mono.Cecil; +using Mono.Documentation; +using Mono.Documentation.Updater; +using Mono.Documentation.Updater.Frameworks; +using System.Collections.Generic; +using System.Linq; +using System.Xml; + +namespace mdoc.Mono.Documentation.Util +{ + class MdocUpdaterHelper + { + internal static void MakeTypeParameterConstraints(XmlElement root, XmlElement e, XmlElement pe, GenericParameterAttributes attrs, IList<TypeReference> constraints) + { + XmlElement ce = (XmlElement)e.SelectSingleNode("Constraints"); + if (attrs == GenericParameterAttributes.NonVariant && constraints.Count == 0) + { + if (ce != null) + e.RemoveChild(ce); + } + if (ce != null) + ce.RemoveAll(); + else + { + ce = root.OwnerDocument.CreateElement("Constraints"); + } + if ((attrs & GenericParameterAttributes.Contravariant) != 0) + AppendElementText(ce, "ParameterAttribute", "Contravariant"); + if ((attrs & GenericParameterAttributes.Covariant) != 0) + AppendElementText(ce, "ParameterAttribute", "Covariant"); + if ((attrs & GenericParameterAttributes.DefaultConstructorConstraint) != 0) + AppendElementText(ce, "ParameterAttribute", "DefaultConstructorConstraint"); + if ((attrs & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0) + AppendElementText(ce, "ParameterAttribute", "NotNullableValueTypeConstraint"); + if ((attrs & GenericParameterAttributes.ReferenceTypeConstraint) != 0) + AppendElementText(ce, "ParameterAttribute", "ReferenceTypeConstraint"); + +#if NEW_CECIL + foreach (GenericParameterConstraint c in constraints) + { + TypeDefinition cd = c.ConstraintType.Resolve (); + AppendElementText (ce, + (cd != null && cd.IsInterface) ? "InterfaceName" : "BaseTypeName", + GetDocTypeFullName (c.ConstraintType)); + } +#else + foreach (TypeReference c in constraints) + { + TypeDefinition cd = c.Resolve(); + AppendElementText(ce, + (cd != null && cd.IsInterface) ? "InterfaceName" : "BaseTypeName", + GetDocTypeFullName(c)); + } +#endif + if (ce.HasChildNodes) + { + pe.AppendChild(ce); + } + } + + internal static void CheckFrameworkAlternateAttribute(FrameworkTypeEntry entry, XmlElement e, string elementName) + { + if (entry.Framework.IsLastFrameworkForType(entry)) + { + var allFrameworks = entry.Framework.AllFrameworksWithType(entry); + var finalNodes = e.GetElementsByTagName(elementName).Cast<XmlElement>().ToArray(); + foreach (var node in finalNodes) + { + // if FXAlternate is entire list, just remove it + if (node.HasAttribute(Consts.FrameworkAlternate) && node.GetAttribute(Consts.FrameworkAlternate) == allFrameworks) + { + node.RemoveAttribute(Consts.FrameworkAlternate); + } + } + + // if there are no fx attributes left, just remove the indices entirely + if (!finalNodes.Any(n => n.HasAttribute(Consts.FrameworkAlternate))) + { + foreach (var node in finalNodes) + { + node.RemoveAttribute(Consts.Index); + } + } + } + } + + internal static XmlElement AppendElementText(XmlNode parent, string element, string value) + { + XmlElement n = parent.OwnerDocument.CreateElement(element); + parent.AppendChild(n); + n.InnerText = value; + return n; + } + + internal static string GetDocTypeFullName(TypeReference type, bool useTypeProjection = true, bool isTypeofOperator = false) + { + return DocTypeFullMemberFormatter.Default.GetName(type, useTypeProjection: useTypeProjection, isTypeofOperator: isTypeofOperator); + } + } +} |