diff options
author | Joel Martinez <joelmartinez@gmail.com> | 2015-10-29 22:36:29 +0300 |
---|---|---|
committer | Joel Martinez <joelmartinez@gmail.com> | 2015-11-03 23:13:51 +0300 |
commit | 85bde33bf26818f3860a0bef5da990de993cb6be (patch) | |
tree | 393bdf58054edc1edb2d3a62757f5f401556a0e8 /mcs/class/monodoc | |
parent | 3a78c7b0933d7704670f0d711d606b5f31005589 (diff) |
[monodoc] Fixed several issues with `.ToEcmaCRef` method.
In particular:
- Issues with cref formatting for subtypes.
- Added support for Explicitly implemented members.
- Added support for generic member parameters.
A number of unit tests were added to verify this functionality.
Diffstat (limited to 'mcs/class/monodoc')
-rw-r--r-- | mcs/class/monodoc/Monodoc.Ecma/EcmaDesc.cs | 54 | ||||
-rw-r--r-- | mcs/class/monodoc/Test/Monodoc.Ecma/EcmaUrlTests.cs | 396 |
2 files changed, 409 insertions, 41 deletions
diff --git a/mcs/class/monodoc/Monodoc.Ecma/EcmaDesc.cs b/mcs/class/monodoc/Monodoc.Ecma/EcmaDesc.cs index ccf4b4bb12d..2f46c6cc0fd 100644 --- a/mcs/class/monodoc/Monodoc.Ecma/EcmaDesc.cs +++ b/mcs/class/monodoc/Monodoc.Ecma/EcmaDesc.cs @@ -226,32 +226,24 @@ namespace Monodoc.Ecma return sb.ToString (); } - void ConstructCRef (StringBuilder sb) + void ConstructCRef (StringBuilder sb, bool skipLeadingDot = false) { + if (string.IsNullOrEmpty (Namespace)) + skipLeadingDot = true; + sb.Append (Namespace); if (DescKind == Kind.Namespace) return; - sb.Append ('.'); + if (!skipLeadingDot) + sb.Append ('.'); + sb.Append (TypeName); - if (GenericTypeArguments != null && GenericTypeArgumentsIsNumeric) { - sb.AppendFormat ("`{0}", GenericTypeArgumentsCount); - } else if (GenericTypeArguments != null) { - sb.Append ('<'); - int i=0; - foreach (var t in GenericTypeArguments) { - if (i > 0) { - sb.Append (","); - } - t.ConstructCRef (sb); + AppendGenericArguments (sb, GenericTypeArguments, GenericTypeArgumentsIsNumeric, GenericTypeArgumentsCount); - i++; - } - sb.Append ('>'); - } if (NestedType != null) { sb.Append ('+'); - NestedType.ConstructCRef (sb); + NestedType.ConstructCRef (sb, skipLeadingDot: true); } if (ArrayDimensions != null && ArrayDimensions.Count > 0) { for (int i = 0; i < ArrayDimensions.Count; i++) { @@ -263,9 +255,18 @@ namespace Monodoc.Ecma if (DescKind == Kind.Type) return; + if (ExplicitImplMember != null) { + sb.Append ('$'); + ExplicitImplMember.DescKind = this.DescKind; + ExplicitImplMember.ConstructCRef (sb, skipLeadingDot: false); + return; + } + sb.Append ("."); sb.Append (MemberName); + AppendGenericArguments (sb, GenericMemberArguments, GenericMemberArgumentsIsNumeric, GenericMemberArgumentsCount); + if (MemberArguments != null && MemberArgumentsCount > 0) { sb.Append ("("); int i=0; @@ -280,6 +281,25 @@ namespace Monodoc.Ecma } } + void AppendGenericArguments (StringBuilder sb, IEnumerable<EcmaDesc> arguments, bool isNumeric, int argumentsCount) + { + if (arguments != null && isNumeric) { + sb.AppendFormat ("`{0}", argumentsCount); + } else if (arguments != null) { + sb.Append ('<'); + int i=0; + foreach (var t in arguments) { + if (i > 0) { + sb.Append (","); + } + t.ConstructCRef (sb); + + i++; + } + sb.Append ('>'); + } + } + public override string ToString () { return string.Format ("({8}) {0}::{1}{2}{3}{7} {4}{5}{6} {9} {10}", diff --git a/mcs/class/monodoc/Test/Monodoc.Ecma/EcmaUrlTests.cs b/mcs/class/monodoc/Test/Monodoc.Ecma/EcmaUrlTests.cs index 1c8d44311e6..8e27bc08b13 100644 --- a/mcs/class/monodoc/Test/Monodoc.Ecma/EcmaUrlTests.cs +++ b/mcs/class/monodoc/Test/Monodoc.Ecma/EcmaUrlTests.cs @@ -52,6 +52,22 @@ namespace MonoTests.Monodoc.Ecma Assert.AreEqual (expected, actual, "Converted URL differs"); } + void AssertEcmaString (string expected, EcmaDesc actual) + { + string actualString = actual.ToEcmaCref (); + Assert.AreEqual (expected, actualString); + } + + IEnumerable<EcmaDesc> GenericTypeArgumentsList (params string[] parameters) + { + foreach (var p in parameters) + yield return new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + TypeName = p, + Namespace = string.Empty + }; + } + [Test] public void CommonMethodUrlIsValidTest () { @@ -454,38 +470,370 @@ namespace MonoTests.Monodoc.Ecma AssertUrlDesc (ast, "P:System.Web.SessionState.HttpSessionStateContainer$System.Web.SessionState.IHttpSessionState.Item(System.Int32)"); } - /* [Test] - public void TreeParsabilityTest () + [Test] + public void ToEcmaCref_Namespace () { - var rootTree = RootTree.LoadTree ("/home/jeremie/monodoc/"); - Node result; - var generator = new CheckGenerator (); + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Namespace, + Namespace = "System.IO", + }; - foreach (var leaf in GetLeaves (rootTree.RootNode).Where (IsEcmaNode)) - AssertUrl (leaf.PublicUrl); + AssertEcmaString ("N:System.IO", actual); } - IEnumerable<Node> GetLeaves (Node node) + [Test] + public void ToEcmaCref_SimpleType () { - if (node == null) - yield break; + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = "System.IO", + TypeName = "Path", + }; - if (node.IsLeaf) - yield return node; - else { - foreach (var child in node.Nodes) { - if (!string.IsNullOrEmpty (child.Element) && !child.Element.StartsWith ("root:/")) - yield return child; - foreach (var childLeaf in GetLeaves (child)) - yield return childLeaf; - } - } + AssertEcmaString ("T:System.IO.Path", actual); + } + + [Test] + public void ToEcmaCref_NestedType () + { + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = "System.IO", + TypeName = "Path", + NestedType = new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + TypeName = "TheNestedType", + }, + }; + + AssertEcmaString ("T:System.IO.Path+TheNestedType", actual); + } + + [Test] + public void ToEcmaCref_NestedType_FourDeep () + { + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = "Mono", + TypeName = "DocTest", + NestedType = new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + TypeName = "NestedClass", + NestedType = new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + TypeName = "Double", + NestedType = new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + TypeName = "Triple", + NestedType = new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + TypeName = "Quadruple", + }, + }, + }, + }, + }; + + string targetUrl = "T:Mono.DocTest+NestedClass+Double+Triple+Quadruple"; + AssertEcmaString (targetUrl, actual); + AssertUrlDesc (actual, targetUrl); + } + + [Test] + public void ToEcmaCref_NestedType_Field () + { + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Field, + Namespace = "System.IO", + TypeName = "Path", + NestedType = new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + TypeName = "TheNestedType", + }, + MemberName = "NestedField" + }; + + AssertEcmaString ("F:System.IO.Path+TheNestedType.NestedField", actual); + } + + [Test] + public void ToEcmaCref_SimpleType_WithGenerics () + { + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = "System.IO", + TypeName = "Path", + GenericTypeArguments = GenericTypeArgumentsList ("K").ToArray () + }; + + AssertEcmaString ("T:System.IO.Path<K>", actual); + } + + [Test] + public void ToEcmaCref_Nestedype_WithGenerics () + { + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = "System.IO", + TypeName = "Path", + NestedType = new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + TypeName = "TheNestedType", + }, + GenericTypeArguments = GenericTypeArgumentsList ("K").ToArray () + }; + + AssertEcmaString ("T:System.IO.Path<K>+TheNestedType", actual); + } + + [Test] + public void ToEcmaCref_Nestedype_WithGenericsOnBoth () + { + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = "System.IO", + TypeName = "Path", + NestedType = new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + TypeName = "TheNestedType", + GenericTypeArguments = GenericTypeArgumentsList ("T", "V").ToArray (), + }, + GenericTypeArguments = GenericTypeArgumentsList ("K").ToArray () + }; + + AssertEcmaString ("T:System.IO.Path<K>+TheNestedType<T,V>", actual); + } + + [Test] + public void ToEcmaCref_Nestedype_Property_WithGenericsOnBoth () + { + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Property, + Namespace = "System.IO", + TypeName = "Path", + NestedType = new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + TypeName = "TheNestedType", + GenericTypeArguments = GenericTypeArgumentsList ("T", "V").ToArray (), + }, + GenericTypeArguments = GenericTypeArgumentsList ("K").ToArray (), + MemberName = "TheProperty" + }; + + AssertEcmaString ("P:System.IO.Path<K>+TheNestedType<T,V>.TheProperty", actual); + } + + [Test] + public void ToEcmaCref_Field () + { + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Field, + Namespace = "System.IO", + TypeName = "Path", + MemberName = "TheField" + }; + + AssertEcmaString ("F:System.IO.Path.TheField", actual); + } + + [Test] + public void ToEcmaCref_ExplicitlyImplemented_Field () + { + var explicitImpl = new EcmaDesc { + Namespace = "System.Web.SessionState", + TypeName = "IHttpSessionState", + MemberName = "Item", + }; + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Field, + TypeName = "HttpSessionStateContainer", + Namespace = "System.Web.SessionState", + ExplicitImplMember = explicitImpl, + }; + AssertEcmaString ("F:System.Web.SessionState.HttpSessionStateContainer$System.Web.SessionState.IHttpSessionState.Item", actual); + } + + [Test] + public void ToEcmaCref_Property () + { + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Property, + Namespace = "System.IO", + TypeName = "Path", + MemberName = "TheProperty", + }; + + AssertEcmaString ("P:System.IO.Path.TheProperty", actual); + } + + [Test] + public void ToEcmaCref_ExplicitlyImplemented_Property () + { + var explicitImpl = new EcmaDesc { + Namespace = "System.Web.SessionState", + TypeName = "IHttpSessionState", + MemberName = "Item", + }; + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Property, + TypeName = "HttpSessionStateContainer", + Namespace = "System.Web.SessionState", + ExplicitImplMember = explicitImpl, + }; + AssertEcmaString ("P:System.Web.SessionState.HttpSessionStateContainer$System.Web.SessionState.IHttpSessionState.Item", actual); + } + + [Test] + public void ToEcmaCref_ExplicitlyImplemented_Method () + { + var explicitImpl = new EcmaDesc { + Namespace = "System.Web.SessionState", + TypeName = "IHttpSessionState", + MemberName = "Item", + MemberArguments = new [] { + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = "System", + TypeName = "Int32", + }, + }, + }; + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Method, + TypeName = "HttpSessionStateContainer", + Namespace = "System.Web.SessionState", + ExplicitImplMember = explicitImpl, + }; + AssertEcmaString ("M:System.Web.SessionState.HttpSessionStateContainer$System.Web.SessionState.IHttpSessionState.Item(System.Int32)", actual); + } + + [Test] + public void ToEcmaCref_Event () + { + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Event, + Namespace = "System.IO", + TypeName = "Path", + MemberName = "TheEvent", + }; + + AssertEcmaString ("E:System.IO.Path.TheEvent", actual); } - bool IsEcmaNode (Node node) + [Test] + public void ToEcmaCref_Operator () { - var url = node.PublicUrl; - return url != null && url.Length > 2 && url[1] == ':'; - }*/ + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Operator, + Namespace = "System", + TypeName = "Int32", + MemberName = "Addition", + }; + + AssertEcmaString ("O:System.Int32.Addition", actual); + } + + [Test] + public void ToEcmaCref_Operator_Conversion () + { + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Operator, + Namespace = "System", + TypeName = "Int32", + MemberName = "ExplicitConversion", + MemberArguments = new [] { + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = "System", + TypeName = "Double", + }, + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = "System", + TypeName = "Int32", + } + }, + }; + + AssertEcmaString ("O:System.Int32.ExplicitConversion(System.Double,System.Int32)", actual); + } + + [Test] + public void ToEcmaCref_Method () + { + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Method, + Namespace = "System", + TypeName = "Int32", + MemberName = "Add" + }; + + AssertEcmaString ("M:System.Int32.Add", actual); + } + + [Test] + public void ToEcmaCref_Method_Parameters () + { + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Method, + Namespace = "System", + TypeName = "Int32", + MemberName = "Add", + MemberArguments = new [] { + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = "System", + TypeName = "Double", + }, + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = "System", + TypeName = "Int32", + }, + }, + }; + + AssertEcmaString ("M:System.Int32.Add(System.Double,System.Int32)", actual); + } + + [Test] + public void ToEcmaCref_Method_Generics () + { + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Method, + Namespace = "System", + TypeName = "Int32", + MemberName = "Add", + GenericMemberArguments = GenericTypeArgumentsList ("T", "K").ToArray (), + }; + + AssertEcmaString ("M:System.Int32.Add<T,K>", actual); + } + + [Test] + public void ToEcmaCref_Method_Generics_PlusParameters () + { + var actual = new EcmaDesc { + DescKind = EcmaDesc.Kind.Method, + Namespace = "System", + TypeName = "Int32", + MemberName = "Add", + GenericMemberArguments = GenericTypeArgumentsList ("T", "K").ToArray (), + MemberArguments = new [] { + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = "", + TypeName = "T", + }, + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = "", + TypeName = "K", + }, + }, + }; + + AssertEcmaString ("M:System.Int32.Add<T,K>(T,K)", actual); + } } } |