public void DocMemberEnumerator2() { var context = InitContext <MyClass>(string.Format(typeFrameXml, multiFrameworkXml), 2, forceAlignment: true); FrameworkTypeEntry typeEntry = context.fx.Frameworks[2].Types.First(); var enumerator = new DocumentationEnumerator(); var matches = enumerator.GetDocumentationMembers(context.doc, context.method.DeclaringType.Resolve(), typeEntry); Assert.IsTrue(matches.Any(m => m.Member == context.method && m.Node != null), "didn't match the member"); }
public void Parameters_Updating_Existing_MultiFramework222() { var context = InitContext <MyClass2> (XmlConsts.MultiFrameworkXml2, 2); FrameworkTypeEntry typeEntry = context.fx.Frameworks[2].Types.First(); bool fxAlternateTriggered = false; context.updater.MakeParameters(context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry, ref fxAlternateTriggered); var afterXML = context.doc.OuterXml; Assert.AreEqual(context.beforeXML, Normalize(afterXML)); }
public void Parameters_Updating_Normal() { var context = InitContext <MyClass>(startingEmptyXml, 0); FrameworkTypeEntry typeEntry = context.fx.Frameworks[0].Types.First(); bool fxAlternateTriggered = false; context.updater.MakeParameters(context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry, ref fxAlternateTriggered); var afterXML = context.doc.OuterXml; Assert.AreEqual(Normalize(normalSingleXml), afterXML); }
public void Parameters_Updating_Normal22() { var context = InitContext <MyClass2> (XmlConsts.NormalSingleXml2, 1); FrameworkTypeEntry typeEntry = context.fx.Frameworks[1].Types.First(); bool fxAlternateTriggered = false; context.updater.MakeParameters(context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry, ref fxAlternateTriggered); var afterXML = context.doc.OuterXml; Assert.AreEqual(Normalize(XmlConsts.MultiFrameworkXml2Second), afterXML); }
public void Parameters_Updating_Existing_MultiFramework() { var context = InitContext <MyClass>(multiFrameworkXml, 0); FrameworkTypeEntry typeEntry = context.fx.Frameworks[0].Types.First(); bool fxAlternateTriggered = false; context.updater.MakeParameters(context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry, ref fxAlternateTriggered); var afterXML = context.doc.OuterXml; // the original state was cleared out on account that this was the first of the frameworks Assert.AreEqual(Normalize(XmlConsts.NormalSingleXml), Normalize(afterXML)); }
public void Parameters_Updating_Existing_Align2() { var context = InitContext <MyClass2> (XmlConsts.MultiFrameworkXml2, 1, forceAlignment: true); FrameworkTypeEntry typeEntry = context.fx.Frameworks[1].Types.First(); bool fxAlternateTriggered = false; context.updater.MakeParameters(context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry, ref fxAlternateTriggered); var afterXML = context.doc.OuterXml; Assert.IsFalse(fxAlternateTriggered); Assert.AreEqual(Normalize(XmlConsts.MultiFrameworkAligned2), Normalize(afterXML)); }
public void MemberSignature_Updating_Existing_NoChange_regular() { var context = InitContext <MyClass> (SigRegular, 1, forceAlignment: false); FrameworkTypeEntry typeEntry = context.fx.Frameworks[1].Types.First(); var sig = new CSharpMemberFormatter(); MDocUpdater.UpdateSignature(sig, context.method, context.doc.FirstChild as XmlElement, typeEntry, fxAlternateTriggered: false); var afterXML = context.doc.OuterXml; Assert.AreEqual(Normalize(SigRegular), Normalize(afterXML)); }
public void MemberSignature_Updating_Existing_Align() { var context = InitContext <MyClass>(SigmultiFrameworkXml, 0, forceAlignment: true); FrameworkTypeEntry typeEntry = context.fx.Frameworks[0].Types.First(); var sig = new CSharpMemberFormatter(); MDocUpdater.UpdateSignature(sig, context.method, context.doc.FirstChild as XmlElement, typeEntry, fxAlternateTriggered: false); var afterXML = context.doc.OuterXml; // first framework looks like it already looked, so no need to update Assert.AreEqual(Normalize(SigmultiFrameworkXml), Normalize(afterXML)); }
public void Attributes_TypeOrMethod_AttributeRemoved() { var context = InitContext <MyClass> (string.Format(typeFrameXml, multiFrameworkXml), 2, forceAlignment: false); var fx = context.fx.Frameworks[1]; FrameworkTypeEntry typeEntry = fx.Types.First(); string[] attributeList = new[] { "One" }; MDocUpdater.MakeAttributes(context.doc.FirstChild as XmlElement, attributeList, fx, typeEntry); MDocUpdater.MakeAttributes(context.doc.FirstChild as XmlElement, new string[0], fx, typeEntry); MDocUpdater.MakeAttributes(context.doc.FirstChild as XmlElement, new string[0], context.fx.Frameworks[2], typeEntry); var attrNode = context.doc.FirstChild.SelectSingleNode("Attributes"); Assert.IsNull(attrNode); }
public void Attributes_TypeOrMethod() { var context = InitContext <MyClass>(string.Format(typeFrameXml, multiFrameworkXml), 2, forceAlignment: false); var fx = context.fx.Frameworks[1]; FrameworkTypeEntry typeEntry = fx.Types.First(); string[] attributeList = new[] { "One" }; MDocUpdater.MakeAttributes(context.doc.FirstChild as XmlElement, attributeList, fx, typeEntry); var attrNode = context.doc.FirstChild.SelectSingleNode("Attributes"); var attributes = attrNode.SelectNodes("Attribute").Cast <XmlElement>().ToArray(); Assert.IsTrue(attributes.Count() == 1); Assert.AreEqual("One", attributes[0].FirstChild.InnerText); Assert.AreEqual("Three", attributes[0].GetAttribute(Consts.FrameworkAlternate)); }
public void MemberSignature_Updating_Existing_NameChanged_SingleFX() { // handles the case var context = InitContext <MyClass> (SigRegular, 2, forceAlignment: false); FrameworkTypeEntry typeEntry = context.fx.Frameworks[0].Types.First(); context.fx.Frameworks.RemoveAt(2); context.fx.Frameworks.RemoveAt(1); var sig = new CSharpMemberFormatter(); MDocUpdater.UpdateSignature(sig, context.method, context.doc.FirstChild as XmlElement, typeEntry, fxAlternateTriggered: true); var afterXML = context.doc.OuterXml; Assert.AreEqual(Normalize(SigRegularChanged), Normalize(afterXML)); }
public void FxElementTest_Two() { XmlDocument doc = new XmlDocument(); doc.LoadXml(@"<Parent><X>old value</X></Parent>"); var context = InitContext <MyClass>(string.Format(typeFrameXml, multiFrameworkXml), 0, forceAlignment: false); var fx = context.fx.Frameworks[1]; FrameworkTypeEntry typeEntry = fx.Types.First(); XmlElement parentx = doc.DocumentElement; System.Func <FrameworkTypeEntry, string, bool> runfx = (te, value) => { DocUtils.AddElementWithFx( te, parentx, isFirst: te.Framework.IsFirstFrameworkForType(te), isLast: te.Framework.IsLastFrameworkForType(te), allfxstring: new Lazy <string>(() => typeEntry.Framework.AllFrameworksWithType(typeEntry)), clear: parent => { parent.RemoveAll(); }, findExisting: parent => { return(parent.ChildNodes.Cast <XmlElement>().SingleOrDefault(e => e.Name == "X" && e.Value == value)); }, addItem: parent => { var item = parent.OwnerDocument.CreateElement("X"); item.InnerText = value; parent.AppendChild(item); return(item); }); return(true); }; runfx(context.fx.Frameworks[0].Types.First(), "one"); runfx(context.fx.Frameworks[1].Types.First(), "two"); Assert.AreEqual(parentx.ChildNodes.Count, 2); Assert.IsTrue(parentx.ChildNodes.Cast <XmlElement>().Any(e => e.HasAttribute(Consts.FrameworkAlternate)), "fx check"); }
public void FxElementTest_Three() { XmlDocument doc = new XmlDocument(); doc.LoadXml(@"<Parent><X>old value</X></Parent>"); var context = InitContext <MyClass>(string.Format(typeFrameXml, multiFrameworkXml), 2, forceAlignment: false); var fx = context.fx.Frameworks[1]; FrameworkTypeEntry typeEntry = fx.Types.First(); XmlElement parentx = doc.DocumentElement; System.Func <FrameworkTypeEntry, bool> runfx = (te) => { DocUtils.AddElementWithFx( te, parentx, isFirst: typeEntry.Framework.IsFirstFrameworkForType(typeEntry), isLast: typeEntry.Framework.IsLastFrameworkForType(typeEntry), allfxstring: new Lazy <string>(() => typeEntry.Framework.AllFrameworksWithType(typeEntry)), clear: parent => { parent.RemoveAll(); }, findExisting: parent => { return(parent.SelectSingleNode("X") as XmlElement); }, addItem: parent => { var item = parent.OwnerDocument.CreateElement("X"); item.InnerText = "value"; parent.AppendChild(item); return(item); }); return(true); }; runfx(context.fx.Frameworks[0].Types.First()); runfx(context.fx.Frameworks[1].Types.First()); runfx(context.fx.Frameworks[2].Types.First()); Assert.AreEqual(parentx.ChildNodes.Count, 1); }
public void Parameters3_Making_NameDiff() { var context = InitContext <mdoc.Test3.MyClass>(startingEmptyXml, 0, false, ns1: "mdoc.Test3", ns2: "mdoc.Test3"); var context2 = InitContext <mdoc.Test3.MyClass2>(startingEmptyXml, 1, false, ns1: "mdoc.Test3", ns2: "mdoc.Test3"); FrameworkTypeEntry typeEntry = context.fx.Frameworks[0].Types.First(); FrameworkTypeEntry typeEntry2 = context.fx.Frameworks[1].Types.First(); bool fxAlternateTriggered = false; context.updater.MakeParameters(context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry, ref fxAlternateTriggered); context.updater.MakeParameters(context.doc.FirstChild as XmlElement, context2.method, context2.parameters, typeEntry2, ref fxAlternateTriggered); var afterXML = context.doc.OuterXml; Assert.IsTrue(afterXML.Contains("Parameter Name=\"a\""), "missing 'a'"); Assert.IsTrue(afterXML.Contains("Parameter Name=\"b\""), "missing 'b'"); Assert.IsTrue(afterXML.Contains("Parameter Name=\"c\""), "missing 'c'"); Assert.IsTrue(afterXML.Contains("Parameter Name=\"A\""), "missing 'A'"); Assert.IsTrue(afterXML.Contains("Parameter Name=\"B\""), "missing 'B'"); Assert.IsTrue(afterXML.Contains("Parameter Name=\"C\""), "missing 'C'"); }
public void Attributes_TypeOrMethod_AllFX_RunExisting_First() { var context = InitContext <MyClass> (string.Format(typeFrameXml, multiFrameworkXml), 2, forceAlignment: false); // first, go through and add "One" and "Two" to all of them foreach (var fx in context.fx.Frameworks) { FrameworkTypeEntry typeEntry = fx.Types.First(); string[] attributeList = new[] { "One", "Two" }; MDocUpdater.MakeAttributes(context.doc.FirstChild as XmlElement, attributeList, fx, typeEntry); } // Now, to test the first deployment on an existing set // in this case, the truth of the matter is that `Two` only exists in the middle foreach (var fx in context.fx.Frameworks) { FrameworkTypeEntry typeEntry = fx.Types.First(); string[] attributeList = new[] { "One" }; if (fx.IsFirstFramework) { attributeList = new[] { "One", "Two" }; } MDocUpdater.MakeAttributes(context.doc.FirstChild as XmlElement, attributeList, fx, typeEntry); } var attrNode = context.doc.FirstChild.SelectSingleNode("Attributes"); var attributes = attrNode.SelectNodes("Attribute").Cast <XmlElement> ().ToArray(); Assert.IsTrue(attributes.Count() == 2); Assert.AreEqual("One", attributes[0].FirstChild.InnerText); Assert.IsFalse(attributes[0].HasAttribute(Consts.FrameworkAlternate)); Assert.AreEqual("Two", attributes[1].FirstChild.InnerText); Assert.IsTrue(attributes[1].HasAttribute(Consts.FrameworkAlternate)); Assert.AreEqual("One", attributes[1].GetAttribute(Consts.FrameworkAlternate)); }
public void Attributes_Assembly_OtherAssembly() { var context = InitContext <MyClass> (string.Format(typeFrameXml, multiFrameworkXml), 2, forceAlignment: false); var fx = context.fx.Frameworks[1]; FrameworkTypeEntry typeEntry = fx.Types.First(); string[] attributeList = new[] { "One" }; // this is the 'second' fx, and we've changed the expected assembly name, // so the attribute, while it doesn't exist yet, shouldn't have an FX made since it doesn't exist in any other FX MDocUpdater.MakeAttributes(context.doc.FirstChild as XmlElement, attributeList, fx, typeEntry); var attrNode = context.doc.FirstChild.SelectSingleNode("Attributes"); var attributes = attrNode.SelectNodes("Attribute").Cast <XmlElement> ().ToArray(); Assert.IsTrue(attributes.Count() == 1); Assert.AreEqual("One", attributes[0].FirstChild.InnerText); Assert.IsTrue(attributes[0].HasAttribute(Consts.FrameworkAlternate)); }
public void FxElementTest() { XmlDocument doc = new XmlDocument(); doc.LoadXml(@"<Parent><X>old value</X></Parent>"); var context = InitContext <MyClass>(string.Format(typeFrameXml, multiFrameworkXml), 0, forceAlignment: false); var fx = context.fx.Frameworks[0]; FrameworkTypeEntry typeEntry = fx.Types.First(); XmlElement parentx = doc.DocumentElement; DocUtils.AddElementWithFx( typeEntry, parentx, clear: parent => { parent.RemoveAll(); }, findExisting: parent => { return(parent.SelectSingleNode("X") as XmlElement); }, addItem: parent => { var item = parent.OwnerDocument.CreateElement("X"); item.InnerText = "value"; parent.AppendChild(item); return(item); }); Assert.AreEqual(1, parentx.ChildNodes.Count); Assert.AreEqual("value", parentx.ChildNodes[0].InnerText); Assert.AreEqual("One", parentx.ChildNodes[0].Attributes[0].Value); }
public virtual IEnumerable <DocsNodeInfo> GetDocumentationMembers(XmlDocument basefile, TypeDefinition type, FrameworkTypeEntry typeEntry) { foreach (XmlElement oldmember in basefile.SelectNodes("Type/Members/Member")) { if (oldmember.GetAttribute("__monodocer-seen__") == "true") { oldmember.RemoveAttribute("__monodocer-seen__"); continue; } if (oldmember.ParentNode == null) { continue; } MemberReference m = GetMember(type, new DocumentationMember(oldmember, typeEntry)); if (m == null) { yield return(new DocsNodeInfo(oldmember)); } else { yield return(new DocsNodeInfo(oldmember, m)); } } }
public override IEnumerable <DocsNodeInfo> GetDocumentationMembers(XmlDocument basefile, TypeDefinition type, FrameworkTypeEntry typeEntry) { return(GetMembers(basefile, type, typeEntry) .Concat(base.GetDocumentationMembers(basefile, type, typeEntry))); }
private IEnumerable <DocsNodeInfo> GetMembers(XmlDocument basefile, TypeDefinition type, FrameworkTypeEntry typeEntry) { while (ecmadocs.Name != "Members" && ecmadocs.Read()) { // do nothing } if (ecmadocs.IsEmptyElement) { yield break; } int membersDepth = ecmadocs.Depth; bool go = true; while (go && ecmadocs.Read()) { switch (ecmadocs.Name) { case "Member": { if (membersDepth != ecmadocs.Depth - 1 || ecmadocs.NodeType != XmlNodeType.Element) { continue; } DocumentationMember dm = new DocumentationMember(ecmadocs); string xp = MDocUpdater.GetXPathForMember(dm); XmlElement oldmember = (XmlElement)basefile.SelectSingleNode(xp); MemberReference m; if (oldmember == null) { m = GetMember(type, dm); if (m == null) { app.Warning("Could not import ECMA docs for `{0}'s `{1}': Member not found.", type.FullName, dm.MemberSignatures["C#"]); // SelectSingleNode (ecmaDocsMember, "MemberSignature[@Language=\"C#\"]/@Value").Value); continue; } // oldmember lookup may have failed due to type parameter renames. // Try again. oldmember = (XmlElement)basefile.SelectSingleNode(MDocUpdater.GetXPathForMember(m)); if (oldmember == null) { XmlElement members = MDocUpdater.WriteElement(basefile.DocumentElement, "Members"); oldmember = basefile.CreateElement("Member"); oldmember.SetAttribute("MemberName", dm.MemberName); members.AppendChild(oldmember); foreach (string key in MDocUpdater.Sort(dm.MemberSignatures.Keys)) { XmlElement ms = basefile.CreateElement("MemberSignature"); ms.SetAttribute("Language", key); ms.SetAttribute("Value", (string)dm.MemberSignatures[key]); oldmember.AppendChild(ms); } oldmember.SetAttribute("__monodocer-seen__", "true"); Console.WriteLine("Member Added: {0}", oldmember.SelectSingleNode("MemberSignature[@Language='C#']/@Value").InnerText); app.additions++; } } else { m = GetMember(type, new DocumentationMember(oldmember, typeEntry)); if (m == null) { app.Warning("Could not import ECMA docs for `{0}'s `{1}': Member not found.", type.FullName, dm.MemberSignatures["C#"]); continue; } oldmember.SetAttribute("__monodocer-seen__", "true"); } DocsNodeInfo node = new DocsNodeInfo(oldmember, m); if (ecmadocs.Name != "Docs") { throw new InvalidOperationException("Found " + ecmadocs.Name + "; expected <Docs/>!"); } yield return(node); break; } case "Members": if (membersDepth == ecmadocs.Depth && ecmadocs.NodeType == XmlNodeType.EndElement) { go = false; } break; } } }
public static void MakeParameters(XmlElement root, MemberReference member, IList <ParameterDefinition> parameters, FrameworkTypeEntry typeEntry, ref bool fxAlternateTriggered) { XmlElement e = DocUtils.WriteElement(root, "Parameters"); /// addParameter does the work of adding the actual parameter to the XML Action <ParameterDefinition, XmlElement, string, int, bool, string, bool> addParameter = (ParameterDefinition param, XmlElement nextTo, string paramType, int index, bool addIndex, string fx, bool addfx) => { var pe = root.OwnerDocument.CreateElement("Parameter"); if (nextTo == null) { e.AppendChild(pe); } else { e.InsertAfter(pe, nextTo); } pe.SetAttribute("Name", param.Name); pe.SetAttribute("Type", paramType); if (param.ParameterType is ByReferenceType) { if (param.IsOut) { pe.SetAttribute("RefType", "out"); } else { pe.SetAttribute("RefType", "ref"); } } if (addIndex) { pe.SetAttribute("Index", index.ToString()); } if (addfx) { pe.SetAttribute(Consts.FrameworkAlternate, fx); } MakeAttributes(pe, GetCustomAttributes(param.CustomAttributes, "")); }; /// addFXAttributes, adds the index attribute to all existing elements. /// Used when we first detect the scenario which requires this. Action <XmlNodeList> addFXAttributes = nodes => { var i = 0; foreach (var node in nodes.Cast <XmlElement> ()) { node.SetAttribute("Index", i.ToString()); i++; } }; int parameterIndex = 0; int parameterIndexOffset = 0; var paramNodes = e.GetElementsByTagName("Parameter"); bool inFXMode = frameworksCache.Frameworks.Count() > 1; foreach (ParameterDefinition p in parameters) { var ptype = GetDocParameterType(p.ParameterType); if (parameterIndex >= paramNodes.Count) { // this parameter hasn't been added yet bool hasParameterName = string.IsNullOrWhiteSpace(p.Name); addParameter(p, null, ptype, parameterIndex, false, "", false); } else // there's enough nodes, see if it truly exists { //look for < parameter > that matches position XmlElement parameterNode = e.ChildNodes[parameterIndex + parameterIndexOffset] as XmlElement; if (parameterNode != null) { //Assert Type Matches (if not, throw?) if (parameterNode.HasAttribute("Name") && parameterNode.Attributes["Name"].Value == p.Name) { // we're good, continue on. } else { // name doesn't match if (parameterNode.HasAttribute("Index")) { // TODO: add a FrameworkAlternate check, and set offset correctly int pindex; if (int.TryParse(parameterNode.GetAttribute("Index"), out pindex) && pindex < parameterIndex) { parameterIndexOffset++; continue; } } else { if (!inFXMode) { throw new Exception("shit"); } addFXAttributes(paramNodes); //-find type in previous frameworks string fxList = FXUtils.PreviouslyProcessedFXString(typeEntry); //-find < parameter where index = currentIndex > var currentNode = paramNodes[parameterIndex] as XmlElement; currentNode.SetAttribute(Consts.FrameworkAlternate, fxList); addParameter(p, parameterNode, ptype, parameterIndex - parameterIndexOffset, true, typeEntry.Framework.Name, true); parameterIndexOffset++; fxAlternateTriggered = true; } } } else { // no element at this index // TODO: does this ever happen? throw new Exception("This wasn't supposed to happen"); //addParameter (p); } /* * - If found * - Assert Type Matches (if not, throw?) * -If Name Matches … * - if “FrameworkAlternate” * -Add typeEntry.Framework.Name to list * - done! * -Else (exists, but name doesn’t match … FrameworkAlternate path) * - check if inFXMode if not, throw * -AddFXParameters * - adds Index to all existing<parameters * -find type in previous frameworks * -find < parameter where index = currentIndex > * -Add FrameworkAlternate = allPreviousFrameworks and Index = currentIndex * - Add new node with Index = currentIndex * - else not found * -add */ } parameterIndex++; } //-purge `typeEntry.Framework` from any<parameter> that // has FrameworkAlternate, and “name” doesn’t match any // `parameters` var alternates = paramNodes .Cast <XmlElement> () .Select(p => new { Element = p, Name = p.GetAttribute("Name"), FrameworkAlternate = p.GetAttribute(Consts.FrameworkAlternate) }) .Where(p => !string.IsNullOrWhiteSpace(p.FrameworkAlternate) && p.FrameworkAlternate.Contains(typeEntry.Framework.Name) && !parameters.Any(param => param.Name == p.Name)) .ToArray(); if (alternates.Any()) { foreach (var a in alternates) { string newValue = FXUtils.RemoveFXFromList(a.FrameworkAlternate, typeEntry.Framework.Name); if (string.IsNullOrWhiteSpace(newValue)) { a.Element.RemoveAttribute(Consts.FrameworkAlternate); } else { a.Element.SetAttribute(Consts.FrameworkAlternate, newValue); } } } return; /* * // old code * foreach (ParameterDefinition p in parameters) * { * XmlElement pe; * * // param info * var ptype = GetDocParameterType (p.ParameterType); * var newPType = ptype; * * if (MDocUpdater.SwitchingToMagicTypes) * { * newPType = NativeTypeManager.ConvertFromNativeType (ptype); * } * * // now find the existing node, if it's there so we can reuse it. * var nodes = root.SelectSingleNode ("Parameters").SelectNodes ("Parameter") * .Cast<XmlElement> ().Where (x => x.GetAttribute ("Name") == p.Name) * .ToArray (); * * // FYI: Exists? No? * if (nodes.Count () == 0) * { * // TODO: instead of this. Needs to be replaced with a better * // check for Parameter index ... should I add parameter index? * * // are we in frameworks mode? * // add Index to all existing parameter nodes if they don't have them * // match existing to position and type * bool _inFXMode = typeEntry.Framework.Frameworks.Count () > 1; * * // when I find the one, name won't match ... * * // find all "previous" frameworks * // Add FrameworkAlternate with previous frameworks to found/pre-existing node * var allPreviousTypes_ = typeEntry.Framework.Frameworks * .Where (f => f.index < typeEntry.Framework.index) * .Select (f => f.FindTypeEntry (typeEntry)) * .ToArray (); * * var allPreviousFrameworks = allPreviousTypes.Value.Select (previous => previous.Framework.Name).ToArray (); * string fxList = string.Join (";", allPreviousFrameworks); * * // find the parameters in `root` that have an index == this parameter's index * // if they don't match, then we need to make a new one for this * * // Create new "Parameter" node, with FrameworkAlternate = this * * // Legacy: wasn't found, let's make sure it wasn't just cause the param name was changed * nodes = root.SelectSingleNode ("Parameters").SelectNodes ("Parameter") * .Cast<XmlElement> () * .Skip (parameterIndex) // this makes sure we don't inadvertently "reuse" nodes when adding new ones * .Where (x => x.GetAttribute ("Name") != p.Name && (x.GetAttribute ("Type") == ptype || x.GetAttribute ("Type") == newPType)) * .Take (1) // there might be more than one that meets this parameter ... only take the first. * .ToArray (); * } * * AddXmlNode (nodes, * x => x.GetAttribute ("Type") == ptype, * x => x.SetAttribute ("Type", ptype), * () => * { * pe = root.OwnerDocument.CreateElement ("Parameter"); * e.AppendChild (pe); * * pe.SetAttribute ("Name", p.Name); * pe.SetAttribute ("Type", ptype); * if (p.ParameterType is ByReferenceType) * { * if (p.IsOut) * pe.SetAttribute ("RefType", "out"); * else * pe.SetAttribute ("RefType", "ref"); * } * * MakeAttributes (pe, GetCustomAttributes (p.CustomAttributes, "")); * return pe; * }, * member); * * parameterIndex++; * } * * // TODO: was there a `Parameter` that we didn't process that has FrameworkAlternate? * // if yes, remove this framework from that FrameworkAlternate * // if that makes the list empty, remove the node and corresponding /Docs/parameter node */ }
public DocumentationMember(XmlNode node, FrameworkTypeEntry typeEntry) { MemberName = node.Attributes["MemberName"].Value; foreach (XmlNode n in node.SelectNodes("MemberSignature")) { XmlAttribute l = n.Attributes["Language"]; XmlAttribute v = n.Attributes["Value"]; XmlAttribute apistyle = n.Attributes["apistyle"]; bool shouldUse = apistyle == null || apistyle.Value == "classic"; if (l != null && v != null && shouldUse) { MemberSignatures[l.Value] = v.Value; } } MemberType = node.SelectSingleNode("MemberType").InnerText; Func <string, string, string> processType = (reftype, typename) => !typename.EndsWith("&", StringComparison.Ordinal) && (reftype == "ref" || reftype == "out" || reftype == "Readonly" || reftype == "this") ? typename + '&' : typename; XmlNode rt = node.SelectSingleNode("ReturnValue/ReturnType[not(@apistyle) or @apistyle='classic']"); XmlNode rtrt = null;// node.SelectSingleNode("ReturnValue/@RefType"); if (rt != null) { ReturnType = processType(rtrt?.Value, rt.InnerText); } var p = node.SelectNodes("Parameters/Parameter[not(@apistyle) or @apistyle='classic']").Cast <XmlElement>().ToArray(); if (p.Length > 0) { if (p.Any(para => para.HasAttribute("Index"))) { var pgroup = p .Select(para => new { Index = para.GetAttribute("Index"), Type = para.GetAttribute("Type"), RefType = para.GetAttribute("RefType") }) .GroupBy(para => new { para.Index, Type = processType(para.RefType, para.Type) }) .ToArray(); Parameters = new StringList(pgroup.Length); Parameters.AddRange(pgroup.Select(pg => pg.Key.Type)); } else { var ptypes = p .Select(para => new { Type = para.GetAttribute("Type"), RefType = para.GetAttribute("RefType") }) .Select(para => processType(para.RefType, para.Type)) .ToArray(); Parameters = new StringList(ptypes); } } XmlNodeList tp = node.SelectNodes("TypeParameters/TypeParameter[not(@apistyle) or @apistyle='classic']"); if (tp.Count > 0) { TypeParameters = new StringList(tp.Count); for (int i = 0; i < tp.Count; ++i) { TypeParameters.Add(tp[i].Attributes["Name"].Value); } } else { DiscernTypeParameters(); } CleanTypes(); }