Skip to content

Commit 5f13987

Browse files
authored
Feat #608072: Monikerize type parameters name (#649)
* feat #608072: Monikerize type parameters name * update * update * update * update * update * update * update * Fix * refactor * update * Add unit test * Add integration test * update test case * update * update * update
1 parent 796b1e1 commit 5f13987

File tree

16 files changed

+499
-103
lines changed

16 files changed

+499
-103
lines changed

mdoc/Consts.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public static class Consts
4141
public const string FrameworksIndex = "FrameworksIndex";
4242
public const string FrameworkAlternate = "FrameworkAlternate";
4343
public const string Index = "Index";
44+
public const string Name = "Name";
4445

4546
public static bool CollapseInheritedInterfaces = true;
4647

mdoc/Makefile

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,14 @@ Test/DocTest-differentTypeDefinitions-Second.dll:
150150
rm -f $@
151151
$(CSCOMPILE) $(TEST_CSCFLAGS) -unsafe -debug -optimize -target:library -out:$@ Test/DocTest-differentTypeDefinitions.cs /define:SECOND
152152

153+
Test/DocTest-differentTypeParameterNames-First.dll:
154+
rm -f $@
155+
$(CSCOMPILE) $(TEST_CSCFLAGS) -unsafe -debug -optimize -target:library -out:$@ Test/DocTest-differentTypeParameterNames.cs /define:FIRST
156+
157+
Test/DocTest-differentTypeParameterNames-Second.dll:
158+
rm -f $@
159+
$(CSCOMPILE) $(TEST_CSCFLAGS) -unsafe -debug -optimize -target:library -out:$@ Test/DocTest-differentTypeParameterNames.cs /define:SECOND
160+
153161
Test/DocTest-typeForwards-First.dll:
154162
rm -f $@
155163
$(CSCOMPILE) $(TEST_CSCFLAGS) -unsafe -debug -optimize -target:library -out:$@ Test/DocTest-typeForwards.cs /define:FIRST
@@ -232,6 +240,21 @@ check-monodocer-differentTypeDefinitions : Test/DocTest-differentTypeDefinitions
232240
$(MONO) $(PROGRAM) update -o Test/en.actual -frameworks Test/FrameworkTestData-fx-differentTypeDefinitions
233241
$(DIFF) Test/en.expected.differentTypeDefinitions Test/en.actual
234242

243+
.PHONY: check-monodocer-differentTypeParameterNames
244+
check-monodocer-differentTypeParameterNames : Test/DocTest-differentTypeParameterNames-First.dll Test/DocTest-differentTypeParameterNames-Second.dll
245+
-rm -Rf Test/en.actual
246+
247+
-rm -Rf Test/FrameworkTestData-fx-differentTypeParameterNames
248+
mkdir Test/FrameworkTestData-fx-differentTypeParameterNames
249+
mkdir Test/FrameworkTestData-fx-differentTypeParameterNames/One
250+
mkdir Test/FrameworkTestData-fx-differentTypeParameterNames/Two
251+
cp Test/DocTest-differentTypeParameterNames-First.dll Test/FrameworkTestData-fx-differentTypeParameterNames/One
252+
cp Test/DocTest-differentTypeParameterNames-Second.dll Test/FrameworkTestData-fx-differentTypeParameterNames/Two
253+
$(MONO) $(PROGRAM) fx-bootstrap Test/FrameworkTestData-fx-differentTypeParameterNames
254+
255+
$(MONO) $(PROGRAM) update -o Test/en.actual -frameworks Test/FrameworkTestData-fx-differentTypeParameterNames
256+
$(DIFF) Test/en.expected.differentTypeParameterNames Test/en.actual
257+
235258
.PHONY: check-monodocer-typeForwards
236259
check-monodocer-typeForwards : Test/DocTest-typeForwards-First.dll Test/DocTest-typeForwards-Second.dll Test/DocTest-typeForwards-Third.dll
237260
-rm -Rf Test/en.actual
@@ -951,7 +974,8 @@ check-doc-tools: \
951974
check-ignored-namespace-generic \
952975
check-multiple-mdoc \
953976
check-type-projection \
954-
check-long-file-name
977+
check-long-file-name \
978+
check-monodocer-differentTypeParameterNames
955979

956980
#check-monodocer-dropns-delete
957981
check-doc-tools-update: check-monodocer-since-update \
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
using Mono.Cecil;
2+
using Mono.Documentation.Updater.Frameworks;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Xml;
6+
7+
namespace Mono.Documentation
8+
{
9+
public partial class MDocUpdater
10+
{
11+
internal static void MakeTypeParameterConstraints(XmlElement root, XmlElement e, XmlElement pe, GenericParameter typeParameter)
12+
{
13+
if (typeParameter == null)
14+
{
15+
return;
16+
}
17+
18+
#if NEW_CECIL
19+
Mono.Collections.Generic.Collection<GenericParameterConstraint> constraints = typeParameter.Constraints;
20+
#else
21+
IList<TypeReference> constraints = typeParameter.Constraints;
22+
#endif
23+
GenericParameterAttributes attrs = typeParameter.Attributes;
24+
25+
XmlElement ce = (XmlElement)e.SelectSingleNode("Constraints");
26+
if (attrs == GenericParameterAttributes.NonVariant && constraints.Count == 0)
27+
{
28+
if (ce != null)
29+
e.RemoveChild(ce);
30+
}
31+
if (ce != null)
32+
ce.RemoveAll();
33+
else
34+
{
35+
ce = root.OwnerDocument.CreateElement("Constraints");
36+
}
37+
if ((attrs & GenericParameterAttributes.Contravariant) != 0)
38+
AppendElementText(ce, "ParameterAttribute", "Contravariant");
39+
if ((attrs & GenericParameterAttributes.Covariant) != 0)
40+
AppendElementText(ce, "ParameterAttribute", "Covariant");
41+
if ((attrs & GenericParameterAttributes.DefaultConstructorConstraint) != 0)
42+
AppendElementText(ce, "ParameterAttribute", "DefaultConstructorConstraint");
43+
if ((attrs & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
44+
AppendElementText(ce, "ParameterAttribute", "NotNullableValueTypeConstraint");
45+
if ((attrs & GenericParameterAttributes.ReferenceTypeConstraint) != 0)
46+
AppendElementText(ce, "ParameterAttribute", "ReferenceTypeConstraint");
47+
48+
#if NEW_CECIL
49+
foreach (GenericParameterConstraint c in constraints)
50+
{
51+
TypeDefinition cd = c.ConstraintType.Resolve ();
52+
AppendElementText (ce,
53+
(cd != null && cd.IsInterface) ? "InterfaceName" : "BaseTypeName",
54+
GetDocTypeFullName (c.ConstraintType));
55+
}
56+
#else
57+
foreach (TypeReference c in constraints)
58+
{
59+
TypeDefinition cd = c.Resolve();
60+
AppendElementText(ce,
61+
(cd != null && cd.IsInterface) ? "InterfaceName" : "BaseTypeName",
62+
GetDocTypeFullName(c));
63+
}
64+
#endif
65+
if (ce.HasChildNodes)
66+
{
67+
pe.AppendChild(ce);
68+
}
69+
}
70+
71+
internal static void ClearFrameworkAlternateIfAll(XmlElement element, string elementName, string allFrameworks)
72+
{
73+
if (element == null || string.IsNullOrEmpty(elementName) || string.IsNullOrEmpty(allFrameworks))
74+
{
75+
return;
76+
}
77+
78+
var finalNodes = element.GetElementsByTagName(elementName).Cast<XmlElement>().ToArray();
79+
foreach (var node in finalNodes)
80+
{
81+
// if FXAlternate is entire list, just remove it
82+
if (node.HasAttribute(Consts.FrameworkAlternate) && node.GetAttribute(Consts.FrameworkAlternate) == allFrameworks)
83+
{
84+
node.RemoveAttribute(Consts.FrameworkAlternate);
85+
}
86+
}
87+
88+
// if there are no fx attributes left, just remove the indices entirely
89+
if (!finalNodes.Any(n => n.HasAttribute(Consts.FrameworkAlternate)))
90+
{
91+
foreach (var node in finalNodes)
92+
{
93+
node.RemoveAttribute(Consts.Index);
94+
}
95+
}
96+
}
97+
98+
internal static XmlElement AppendElementText(XmlNode parent, string element, string value)
99+
{
100+
XmlElement n = parent.OwnerDocument.CreateElement(element);
101+
parent.AppendChild(n);
102+
n.InnerText = value;
103+
return n;
104+
}
105+
}
106+
}

mdoc/Mono.Documentation/MDocUpdater.cs

Lines changed: 58 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
namespace Mono.Documentation
2626
{
27-
public class MDocUpdater : MDocCommand
27+
public partial class MDocUpdater : MDocCommand
2828
{
2929
string srcPath;
3030
List<AssemblySet> assemblies = new List<AssemblySet> ();
@@ -2181,7 +2181,10 @@ public void UpdateType (XmlElement root, TypeDefinition type, FrameworkTypeEntry
21812181

21822182
if (type.IsGenericType ())
21832183
{
2184-
MakeTypeParameters (typeEntry, root, type.GenericParameters, type, MDocUpdater.HasDroppedNamespace (type));
2184+
if (!DocUtils.IsDelegate(type))
2185+
{
2186+
MakeTypeParameters(typeEntry, root, type.GenericParameters, type, MDocUpdater.HasDroppedNamespace(type));
2187+
}
21852188
}
21862189
else
21872190
{
@@ -3279,14 +3282,6 @@ internal static XmlElement WriteElementWithSubElementText(XmlNode parent, string
32793282
return element;
32803283
}
32813284

3282-
static XmlElement AppendElementText (XmlNode parent, string element, string value)
3283-
{
3284-
XmlElement n = parent.OwnerDocument.CreateElement (element);
3285-
parent.AppendChild (n);
3286-
n.InnerText = value;
3287-
return n;
3288-
}
3289-
32903285
static XmlElement AppendElementAttributeText (XmlNode parent, string element, string attribute, string value)
32913286
{
32923287
XmlElement n = parent.OwnerDocument.CreateElement (element);
@@ -3959,9 +3954,10 @@ public void MakeParameters (XmlElement root, MemberReference member, IList<Param
39593954
.Select ((n, i) =>
39603955
{
39613956
int actualIndex = i;
3962-
if (n.HasAttribute (Consts.Index))
3963-
int.TryParse (n.GetAttribute (Consts.Index), out actualIndex);
3964-
3957+
if (n.HasAttribute (Consts.Index) && int.TryParse(n.GetAttribute(Consts.Index), out int index))
3958+
{
3959+
actualIndex = index;
3960+
}
39653961

39663962
return new
39673963
{
@@ -4072,121 +4068,89 @@ public void MakeParameters (XmlElement root, MemberReference member, IList<Param
40724068

40734069
if (typeEntry.Framework.IsLastFrameworkForType(typeEntry))
40744070
{
4075-
// Now clean up
4076-
var allFrameworks = typeEntry.Framework.AllFrameworksWithType(typeEntry);
4077-
var finalNodes = paramNodes
4078-
.Cast<XmlElement> ().ToArray ();
4079-
foreach (var parameter in finalNodes)
4080-
{
4081-
// if FXAlternate is entire list, just remove it
4082-
if (parameter.HasAttribute (Consts.FrameworkAlternate) && parameter.GetAttribute (Consts.FrameworkAlternate) == allFrameworks)
4083-
{
4084-
parameter.RemoveAttribute (Consts.FrameworkAlternate);
4085-
}
4086-
}
4087-
4088-
// if there are no fx attributes left, just remove the indices entirely
4089-
if (!finalNodes.Any (n => n.HasAttribute (Consts.FrameworkAlternate)))
4090-
{
4091-
foreach (var parameter in finalNodes)
4092-
parameter.RemoveAttribute (Consts.Index);
4093-
}
4071+
ClearFrameworkAlternateIfAll(e, "Parameter", typeEntry.Framework.AllFrameworksWithType(typeEntry));
40944072
}
40954073
}
40964074

40974075
private void MakeTypeParameters (FrameworkTypeEntry entry, XmlElement root, IList<GenericParameter> typeParams, MemberReference member, bool shouldDuplicateWithNew)
40984076
{
4099-
if (typeParams == null || typeParams.Count == 0)
4077+
if (typeParams == null || typeParams.Count == 0 || ProcessedMoreThanOnce(entry))
41004078
{
4101-
XmlElement f = (XmlElement)root.SelectSingleNode ("TypeParameters");
4102-
if (f != null)
4103-
root.RemoveChild (f);
41044079
return;
41054080
}
41064081

4107-
XmlElement e = WriteElement (root, "TypeParameters");
4082+
XmlElement e = WriteElement(root, "TypeParameters");
41084083

4109-
var nodes = e.SelectNodes ("TypeParameter").Cast<XmlElement> ().ToArray ();
4110-
4111-
foreach (GenericParameter t in typeParams)
4084+
if (DocUtils.IsMemberOnFirstFramework(entry, member))
41124085
{
4086+
e.RemoveAll();
4087+
}
41134088

4089+
var nodes = e.SelectNodes("TypeParameter")
4090+
.Cast<XmlElement>()
4091+
.Select((n, i) =>
4092+
{
4093+
int index = i;
4094+
if (n.HasAttribute(Consts.Index) && int.TryParse(n.GetAttribute(Consts.Index), out int result))
4095+
{
4096+
index = result;
4097+
}
4098+
4099+
return new
4100+
{
4101+
Element = n,
4102+
Name = n.GetAttribute("Name"),
4103+
Index = index,
4104+
FrameworkAlternates = n.GetAttribute(Consts.FrameworkAlternate)
4105+
};
4106+
})
4107+
.ToArray();
4108+
4109+
for (int i = 0; i < typeParams.Count; i++)
4110+
{
4111+
var t = typeParams[i];
41144112
#if NEW_CECIL
41154113
Mono.Collections.Generic.Collection<GenericParameterConstraint> constraints = t.Constraints;
41164114
#else
41174115
IList<TypeReference> constraints = t.Constraints;
41184116
#endif
41194117
GenericParameterAttributes attrs = t.Attributes;
41204118

4121-
var existing = nodes.FirstOrDefault(x => x.GetAttribute("Name") == t.Name);
4119+
var existing = nodes.Where(node => node.Name == t.Name && node.Index == i).FirstOrDefault();
41224120
if (existing != null)
41234121
{
4124-
MakeParamsAttributes(existing, AttributeFormatter.PreProcessCustomAttributes(t.CustomAttributes), entry, member);
4122+
var xElement = existing.Element;
4123+
var fxaValue = FXUtils.AddFXToList(existing.FrameworkAlternates, entry.Framework.Name);
4124+
xElement.RemoveAttribute(Consts.Index);
4125+
xElement.SetAttribute(Consts.Index, i.ToString());
4126+
xElement.RemoveAttribute(Consts.FrameworkAlternate);
4127+
xElement.SetAttribute(Consts.FrameworkAlternate, fxaValue);
4128+
MakeParamsAttributes(existing.Element, AttributeFormatter.PreProcessCustomAttributes(t.CustomAttributes), entry, member);
41254129
}
41264130
else
41274131
{
41284132
XmlElement pe = root.OwnerDocument.CreateElement("TypeParameter");
4129-
e.AppendChild(pe);
4130-
pe.SetAttribute("Name", t.Name);
4131-
MakeParamsAttributes(pe, AttributeFormatter.PreProcessCustomAttributes(t.CustomAttributes), entry, member);
4132-
XmlElement ce = (XmlElement)e.SelectSingleNode("Constraints");
4133-
if (attrs == GenericParameterAttributes.NonVariant && constraints.Count == 0)
4133+
var sameIndexElements = nodes.Where(node => node.Index == i).ToArray();
4134+
if (sameIndexElements != null && sameIndexElements.Length > 0)
41344135
{
4135-
if (ce != null)
4136-
e.RemoveChild(ce);
4136+
// order the type parameters by index
4137+
e.InsertAfter(pe, sameIndexElements.Last().Element);
41374138
}
4138-
if (ce != null)
4139-
ce.RemoveAll();
41404139
else
41414140
{
4142-
ce = root.OwnerDocument.CreateElement("Constraints");
4143-
}
4144-
if ((attrs & GenericParameterAttributes.Contravariant) != 0)
4145-
AppendElementText(ce, "ParameterAttribute", "Contravariant");
4146-
if ((attrs & GenericParameterAttributes.Covariant) != 0)
4147-
AppendElementText(ce, "ParameterAttribute", "Covariant");
4148-
if ((attrs & GenericParameterAttributes.DefaultConstructorConstraint) != 0)
4149-
AppendElementText(ce, "ParameterAttribute", "DefaultConstructorConstraint");
4150-
if ((attrs & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
4151-
AppendElementText(ce, "ParameterAttribute", "NotNullableValueTypeConstraint");
4152-
if ((attrs & GenericParameterAttributes.ReferenceTypeConstraint) != 0)
4153-
AppendElementText(ce, "ParameterAttribute", "ReferenceTypeConstraint");
4154-
4155-
#if NEW_CECIL
4156-
foreach (GenericParameterConstraint c in constraints)
4157-
{
4158-
TypeDefinition cd = c.ConstraintType.Resolve ();
4159-
AppendElementText (ce,
4160-
(cd != null && cd.IsInterface) ? "InterfaceName" : "BaseTypeName",
4161-
GetDocTypeFullName (c.ConstraintType));
4162-
}
4163-
#else
4164-
foreach (TypeReference c in constraints)
4165-
{
4166-
TypeDefinition cd = c.Resolve();
4167-
AppendElementText(ce,
4168-
(cd != null && cd.IsInterface) ? "InterfaceName" : "BaseTypeName",
4169-
GetDocTypeFullName(c));
4170-
}
4171-
#endif
4172-
if (ce.HasChildNodes)
4173-
{
4174-
pe.AppendChild(ce);
4141+
e.AppendChild(pe);
41754142
}
4143+
pe.SetAttribute("Name", t.Name);
4144+
pe.SetAttribute(Consts.Index, i.ToString());
4145+
pe.SetAttribute(Consts.FrameworkAlternate, entry.Framework.Name);
4146+
MakeParamsAttributes(pe, AttributeFormatter.PreProcessCustomAttributes(t.CustomAttributes), entry, member);
4147+
MakeTypeParameterConstraints(root, e, pe, t);
41764148
}
41774149
}
41784150

4179-
nodes = e.SelectNodes("TypeParameter").Cast<XmlElement>().ToArray();
4180-
if (nodes.Length != typeParams.Count)
4151+
if (DocUtils.IsMemberOnLastFramework(entry, member))
41814152
{
4182-
foreach (var node in nodes)
4183-
{
4184-
var existing = typeParams.FirstOrDefault(x => x.Name == node.GetAttribute("Name"));
4185-
if (existing == null)
4186-
{
4187-
node.ParentNode.RemoveChild(node);
4188-
}
4189-
}
4153+
ClearFrameworkAlternateIfAll(e, "TypeParameter", DocUtils.GetAllFrameworksString(entry, member));
41904154
}
41914155
}
41924156

0 commit comments

Comments
 (0)