public static void Main (string[] args) { var input = new StringReader (args[0]); var lexer = new EcmaUrlTokenizer (input); var parser = new EcmaUrlParser (); Console.WriteLine (parser.yyparse (lexer)); }
public void TestEcmaDescToMD_GenericNestedArray() { EcmaUrlParser EcmaParser = new EcmaUrlParser(); Monodoc.Ecma.EcmaDesc desc = EcmaParser.Parse("T:System.Collections.Generic.HashSet<T>+Enumerator[]"); var md = SDPYamlConverter.DescToTypeMDString(desc); var expected = "<xref href=\"System.Collections.Generic.HashSet`1?alt=System.Collections.Generic.HashSet&text=HashSet\" data-throw-if-not-resolved=\"True\"/><T>.<xref href=\"System.Collections.Generic.HashSet`1.Enumerator?alt=System.Collections.Generic.HashSet`1.Enumerator&text=Enumerator\" data-throw-if-not-resolved=\"True\"/>[]"; Assert.AreEqual(expected, md); }
public void TestEcmaDescToDisplayName_GenericNested() { EcmaUrlParser EcmaParser = new EcmaUrlParser(); Monodoc.Ecma.EcmaDesc desc = EcmaParser.Parse("T:System.Collections.Generic.HashSet<Namespace.Class+NestedClass>+NestedClass2"); var displayName = desc.ToDisplayName(); var expected = "HashSet<Class.NestedClass>.NestedClass2"; Assert.AreEqual(expected, displayName); }
public void TestEcmaDescToMD_GenericNested() { EcmaUrlParser EcmaParser = new EcmaUrlParser(); Monodoc.Ecma.EcmaDesc desc = EcmaParser.Parse("T:System.Collections.Generic.HashSet<Namespace.Class+NestedClass>"); var md = SDPYamlConverter.DescToTypeMDString(desc); var expected = "<xref href=\"System.Collections.Generic.HashSet`1?alt=System.Collections.Generic.HashSet&text=HashSet\" data-throw-if-not-resolved=\"True\"/><<xref href=\"Namespace.Class.NestedClass?alt=Namespace.Class.NestedClass&text=Class.NestedClass\" data-throw-if-not-resolved=\"True\"/>>"; Assert.AreEqual(expected, md); }
static int GenericTypeBacktickSearch(IList <Node> childNodes, EcmaDesc desc) { /* Our strategy is to search for the non-generic variant of the type * (which in most case should fail) and then use the closest index * to linearily search for the generic variant with the right generic arg number */ var searchNode = new Node() { Caption = desc.TypeName }; int index = childNodes.BinarySearch(searchNode, EcmaTypeNodeComparer.Instance); // Place the index in the right start position if (index < 0) { index = ~index; } for (int i = index; i < childNodes.Count; i++) { var currentNode = childNodes[i]; // Find the index of the generic argument list int genericIndex = currentNode.Caption.IndexOf('<'); // If we are not on the same base type name anymore, there is no point int captionSlice = genericIndex != -1 ? genericIndex : currentNode.Caption.LastIndexOf(' '); if (string.Compare(searchNode.Caption, 0, currentNode.Caption, 0, Math.Max(captionSlice, searchNode.Caption.Length), StringComparison.Ordinal) != 0) { break; } var numGenerics = CountTypeGenericArguments(currentNode.Caption, genericIndex); if (numGenerics == desc.GenericTypeArguments.Count) { // Simple comparison if we are not looking for an inner type if (desc.NestedType == null) { return(i); } // If more complicated, we fallback to using EcmaUrlParser var caption = currentNode.Caption; caption = "T:" + caption.Substring(0, caption.LastIndexOf(' ')).Replace('.', '+'); EcmaDesc otherDesc; var parser = new EcmaUrlParser(); if (parser.TryParse(caption, out otherDesc) && desc.NestedType.Equals(otherDesc.NestedType)) { return(i); } } } return(-1); }
public void TestEcmaDesc2() { EcmaUrlParser EcmaParser = new EcmaUrlParser(); Monodoc.Ecma.EcmaDesc desc = EcmaParser.Parse("T:System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey,TValue>>"); Console.WriteLine(desc.ToSpecId()); Console.WriteLine(desc.ToSpecId(new List <string>() { "TKey", "TValue" })); }
public void TestEcmaDesc_Matrix() { EcmaUrlParser EcmaParser = new EcmaUrlParser(); Monodoc.Ecma.EcmaDesc desc = EcmaParser.Parse("T:System.Predicate<T[,]>"); var md = SDPYamlConverter.DescToTypeMDString(desc); var expected = "<xref href=\"System.Predicate`1?alt=System.Predicate&text=Predicate\" data-throw-if-not-resolved=\"True\"/><T[,]>"; Assert.AreEqual(expected, md); desc = EcmaParser.Parse("T:System.Management.Automation.Host.BufferCell[,,]"); md = SDPYamlConverter.DescToTypeMDString(desc); expected = "<xref href=\"System.Management.Automation.Host.BufferCell?alt=System.Management.Automation.Host.BufferCell&text=BufferCell\" data-throw-if-not-resolved=\"True\"/>[,,]"; Assert.AreEqual(expected, md); }
public void Setup () { parser = new EcmaUrlParser (); }
void RewriteCrefsIfNecessary (XDocument doc, string path) { // we also have to rewrite crefs var sees = doc.Descendants ().Where (d => d.Name.LocalName == "see").ToArray (); foreach (var see in sees) { var cref = see.Attribute ("cref"); if (cref == null) { continue; } EcmaUrlParser parser = new EcmaUrlParser (); EcmaDesc reference; if (!parser.TryParse (cref.Value, out reference)) { continue; } if ((new EcmaDesc.Kind[] { EcmaDesc.Kind.Constructor, EcmaDesc.Kind.Method }).Any (k => k == reference.DescKind)) { string ns = reference.Namespace; string type = reference.TypeName; string memberName = reference.MemberName; if (reference.MemberArguments != null) { XDocument refDoc = FindReferenceDoc (path, doc, ns, type); if (refDoc == null) { continue; } // look in the refDoc for the memberName, and match on parameters and # of type parameters var overloads = refDoc.XPathSelectElements ("//Member[@MemberName='" + memberName + "']").ToArray (); // Do some initial filtering to find members that could potentially match (based on parameter and typeparam counts) var members = overloads.Where (e => reference.MemberArgumentsCount == e.XPathSelectElements ("Parameters/Parameter[not(@apistyle) or @apistyle='classic']").Count () && reference.GenericMemberArgumentsCount == e.XPathSelectElements ("TypeParameters/TypeParameter[not(@apistyle) or @apistyle='classic']").Count ()).Select (m => new { Node = m, AllParameters = m.XPathSelectElements ("Parameters/Parameter").ToArray (), Parameters = m.XPathSelectElements ("Parameters/Parameter[not(@apistyle) or @apistyle='classic']").ToArray (), NewParameters = m.XPathSelectElements ("Parameters/Parameter[@apistyle='unified']").ToArray () }).ToArray (); // now find the member that matches on types var member = members.FirstOrDefault (m => reference.MemberArguments.All (r => m.Parameters.Any (mp => mp.Attribute ("Type").Value.Contains (r.TypeName)))); if (member == null || member.NewParameters.Length == 0) continue; foreach (var arg in reference.MemberArguments) { // find the "classic" parameter var oldParam = member.Parameters.First (p => p.Attribute ("Type").Value.Contains (arg.TypeName)); var newParam = member.NewParameters.FirstOrDefault (p => oldParam.Attribute ("Name").Value == p.Attribute ("Name").Value); if (newParam != null) { // this means there was a change made, and we should try to convert this cref arg.TypeName = NativeTypeManager.ConvertToNativeType (arg.TypeName); } } var rewrittenReference = reference.ToEcmaCref (); Console.WriteLine ("From {0} to {1}", cref.Value, rewrittenReference); cref.Value = rewrittenReference; } } } }
public void Setup() { parser = new EcmaUrlParser(); }
public void TestEcmaDesc_Complex() { EcmaUrlParser EcmaParser = new EcmaUrlParser(); Monodoc.Ecma.EcmaDesc desc = EcmaParser.Parse("T:System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Microsoft.Bot.Builder.Scorables.Internals.FoldScorable<Item,Score>.State>>"); }
void RewriteCrefsIfNecessary(XDocument doc, string path) { // we also have to rewrite crefs var sees = doc.Descendants().Where(d => d.Name.LocalName == "see").ToArray(); foreach (var see in sees) { var cref = see.Attribute("cref"); if (cref == null) { continue; } EcmaUrlParser parser = new EcmaUrlParser(); EcmaDesc reference; if (!parser.TryParse(cref.Value, out reference)) { continue; } if ((new EcmaDesc.Kind[] { EcmaDesc.Kind.Constructor, EcmaDesc.Kind.Method }).Any(k => k == reference.DescKind)) { string ns = reference.Namespace; string type = reference.TypeName; string memberName = reference.MemberName; if (reference.MemberArguments != null) { XDocument refDoc = FindReferenceDoc(path, doc, ns, type); if (refDoc == null) { continue; } // look in the refDoc for the memberName, and match on parameters and # of type parameters var overloads = refDoc.XPathSelectElements("//Member[@MemberName='" + memberName + "']").ToArray(); // Do some initial filtering to find members that could potentially match (based on parameter and typeparam counts) var members = overloads.Where(e => reference.MemberArgumentsCount == e.XPathSelectElements("Parameters/Parameter[not(@apistyle) or @apistyle='classic']").Count() && reference.GenericMemberArgumentsCount == e.XPathSelectElements("TypeParameters/TypeParameter[not(@apistyle) or @apistyle='classic']").Count()).Select(m => new { Node = m, AllParameters = m.XPathSelectElements("Parameters/Parameter").ToArray(), Parameters = m.XPathSelectElements("Parameters/Parameter[not(@apistyle) or @apistyle='classic']").ToArray(), NewParameters = m.XPathSelectElements("Parameters/Parameter[@apistyle='unified']").ToArray() }).ToArray(); // now find the member that matches on types var member = members.FirstOrDefault(m => reference.MemberArguments.All(r => m.Parameters.Any(mp => mp.Attribute("Type").Value.Contains(r.TypeName)))); if (member == null || member.NewParameters.Length == 0) { continue; } foreach (var arg in reference.MemberArguments) { // find the "classic" parameter var oldParam = member.Parameters.First(p => p.Attribute("Type").Value.Contains(arg.TypeName)); var newParam = member.NewParameters.FirstOrDefault(p => oldParam.Attribute("Name").Value == p.Attribute("Name").Value); if (newParam != null) { // this means there was a change made, and we should try to convert this cref arg.TypeName = NativeTypeManager.ConvertToNativeType(arg.TypeName); } } var rewrittenReference = reference.ToEcmaCref(); Console.WriteLine("From {0} to {1}", cref.Value, rewrittenReference); cref.Value = rewrittenReference; } } } }