protected override StringBuilder AppendParameter(StringBuilder buf, ParameterDefinition parameter) { if (parameter.ParameterType is ByReferenceType && parameter.IsOut) { //no notion of out -> mark with attribute to distinguish in other languages buf.Append("[Runtime::InteropServices::Out] "); } if (parameter.HasCustomAttributes) { var isParams = parameter.CustomAttributes.Any(ca => ca.AttributeType.Name == "ParamArrayAttribute"); if (isParams) { buf.AppendFormat("... "); } } buf.Append(GetTypeNameWithOptions(parameter.ParameterType, !AppendHatOnReturn)).Append(" "); buf.Append(parameter.Name); if (parameter.HasDefault && parameter.IsOptional && parameter.HasConstant) { buf.AppendFormat(" = {0}", MDocUpdater.MakeAttributesValueString(parameter.Constant, parameter.ParameterType)); } return(buf); }
public static string GetNamespace(TypeReference type) { if (type.GetElementType().IsNested) { type = type.GetElementType(); } while (type != null && type.IsNested) { type = type.DeclaringType; } if (type == null) { return(string.Empty); } string typeNS = type.Namespace; // first, make sure this isn't a type reference to another assembly/module bool isInAssembly = MDocUpdater.IsInAssemblies(type.Module.Name); if (isInAssembly && !typeNS.StartsWith("System") && MDocUpdater.HasDroppedNamespace(type)) { typeNS = string.Format("{0}.{1}", MDocUpdater.droppedNamespace, typeNS); } return(typeNS); }
public void Attributes_Assembly() { var context = InitContext <MyClass> (string.Format(typeFrameXml, multiFrameworkXml), 2, forceAlignment: false); foreach (var fx in context.fx.Frameworks) { FrameworkTypeEntry typeEntry = fx.Types.First(); string[] attributeList = new[] { "One" }; if (!fx.IsLastFramework && !fx.IsFirstFramework) { attributeList = new string[0]; } 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)); Assert.AreEqual("One;Two", attributes[0].GetAttribute(Consts.FrameworkAlternate)); }
private List <XmlElement> UpdateXml(string XmlNodeName, MemberReference mi) { List <XmlElement> returnValue = new List <XmlElement>(); List <FrameworkEntry> entries = new List <FrameworkEntry>(); FrameworkEntry singleEntry = new FrameworkEntry(entries, entries); singleEntry.Name = "dotnet-plat-ext-2.2"; FrameworkTypeEntry enttyType = new FrameworkTypeEntry(singleEntry); var type = GetType(typeof(mdoc.Test2.EiiImplementClass)); var ieeImplementList = MDocUpdater.GetTypeEiiMembers(type); var typeInterfaces = GetClassInterface(type); var doc = new XmlDocument(); doc.LoadXml(XmlConsts.EiiErrorImplement); var node = doc.SelectSingleNode($"/Type/Members/Member[@MemberName='{XmlNodeName}']"); if (node != null) { MDocUpdater.AddImplementedMembers(enttyType, mi, typeInterfaces, (XmlElement)node, ieeImplementList); returnValue = node.SelectNodes("Implements/InterfaceMember").Cast <XmlElement>().ToList(); } return(returnValue); }
public virtual bool TryFormatValue(object v, ResolvedTypeInfo type, out string returnvalue) { TypeReference valueType = type.Reference; if (v == null) { returnvalue = "null"; return(true); } if (valueType.FullName == "System.Type") { var vTypeRef = v as TypeReference; if (vTypeRef != null) { returnvalue = "typeof(" + NativeTypeManager.GetTranslatedName(vTypeRef) + ")"; // TODO: drop NS handling } else { returnvalue = "typeof(" + v.ToString() + ")"; } return(true); } if (valueType.FullName == "System.String") { returnvalue = "\"" + FilterSpecialChars(v.ToString()) + "\""; return(true); } if (valueType.FullName == "System.Char") { returnvalue = "'" + FilterSpecialChars(v.ToString()) + "'"; return(true); } if (v is Boolean) { returnvalue = (bool)v ? "true" : "false"; return(true); } TypeDefinition valueDef = type.Definition; if (valueDef == null || !valueDef.IsEnum) { returnvalue = v.ToString(); return(true); } string typename = MDocUpdater.GetDocTypeFullName(valueType); var values = GetEnumerationValues(valueDef); long c = ToInt64(v); if (values.ContainsKey(c)) { returnvalue = typename + "." + values[c]; return(true); } returnvalue = null; return(false); }
public void InternalEIITest() { XmlDocument doc = new System.Xml.XmlDocument(); doc.LoadXml(XmlConsts.internalEllXml); MemberReference oldmember = null; var type = GetType(typeof(mdoc.Test2.InternalEIICalss)); var docEnum = new DocumentationEnumerator(); bool internalEIIflagged = false; foreach (DocsNodeInfo info in docEnum.GetDocumentationMembers(doc, type, FrameworkTypeEntry.Empty)) { var flag = MDocUpdater.IsMemberNotPrivateEII(info.Member); if (!flag) { internalEIIflagged = true; oldmember = info.Member; //Note : The following operation will not be carried out, just prompt //-> DeleteMember(); //-> statisticsCollector.AddMetric(); } } Assert.IsTrue(internalEIIflagged, "Internal EII was not flagged"); Assert.AreEqual("System.String mdoc.Test2.InternalEIICalss::mdoc.Test.SampleClasses.InterfaceA.Getstring(System.Int32)", oldmember.FullName); }
private string ConvertToType(TypeReference argumentType, object argumentValue) { var valueResult = GetArgumentValue("System.Type", argumentType, argumentValue); var typeFullName = MDocUpdater.GetDocTypeFullName((TypeReference)valueResult, isTypeofOperator: true); return $"typeof({typeFullName})"; }
private StringBuilder AppendParameter(StringBuilder buf, ParameterDefinition parameter) { if (parameter.ParameterType is ByReferenceType) { if (parameter.IsOut) { buf.Append("out "); } else { buf.Append("ref "); } } if (parameter.HasCustomAttributes) { var isParams = parameter.CustomAttributes.Any(ca => ca.AttributeType.Name == "ParamArrayAttribute"); if (isParams) { buf.AppendFormat("params "); } } buf.Append(GetTypeName(parameter.ParameterType, new DynamicParserContext(parameter))).Append(" "); buf.Append(parameter.Name); if (parameter.HasDefault && parameter.IsOptional && parameter.HasConstant) { buf.AppendFormat(" = {0}", MDocUpdater.MakeAttributesValueString(parameter.Constant, parameter.ParameterType)); } return(buf); }
public void Test_GetDocParameterType_CppGenericParameterType_ReturnsTypeWithGenericParameters() { var method = GetMethod(typeof(Cpp.GenericBase <>), "BaseMethod2"); string parameterType = MDocUpdater.GetDocParameterType(method.Parameters[0].ParameterType); Assert.AreEqual("Mono_DocTest_Generic.GenericBase<U>", parameterType); }
private (string typeFullName, IDictionary<long, string> enumConstants, long enumValue) ExtractEnumTypeData(TypeReference argumentType, object argumentValue) { var argumentTypeDefinition = argumentType.Resolve(); var typeFullName = MDocUpdater.GetDocTypeFullName(argumentTypeDefinition); var enumConstants = GetEnumerationValues(argumentTypeDefinition); var enumValue = ToInt64(argumentValue); return (typeFullName, enumConstants, enumValue); }
public static string GetTranslatedName(TypeReference t) { string typename = t.FullName; bool isInAssembly = MDocUpdater.IsInAssemblies(t.Module.Name); if (isInAssembly && !typename.StartsWith("System") && MDocUpdater.HasDroppedNamespace(t)) { string nameWithDropped = string.Format("{0}.{1}", MDocUpdater.droppedNamespace, typename); return(nameWithDropped); } return(typename); }
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 static IEnumerable <TypeReference> GetUserImplementedInterfaces(TypeDefinition type) { HashSet <string> inheritedInterfaces = GetInheritedInterfaces(type); List <TypeReference> userInterfaces = new List <TypeReference> (); foreach (var ii in type.Interfaces) { var iface = ii.InterfaceType; TypeReference lookup = iface.Resolve() ?? iface; if (!inheritedInterfaces.Contains(GetQualifiedTypeName(lookup))) { userInterfaces.Add(iface); } } return(userInterfaces.Where(i => MDocUpdater.IsPublic(i.Resolve()))); }
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_MultiFX() { // handles the case var context = InitContext <MyClass> (SigRegular, 2, forceAlignment: false); Func <int, FrameworkTypeEntry> typeEntry = i => context.fx.Frameworks[i].Types.First(); var sig = new CSharpMemberFormatter(); MDocUpdater.UpdateSignature(sig, context.method, context.doc.FirstChild as XmlElement, typeEntry(0), fxAlternateTriggered: true); MDocUpdater.UpdateSignature(sig, context.method, context.doc.FirstChild as XmlElement, typeEntry(1), fxAlternateTriggered: false); MDocUpdater.UpdateSignature(sig, context.method, context.doc.FirstChild as XmlElement, typeEntry(2), fxAlternateTriggered: false); var afterXML = context.doc.OuterXml; Assert.AreEqual(Normalize(SigRegularAllAligned), Normalize(afterXML)); }
public override bool TryFormatValue(object v, ResolvedTypeInfo type, out string returnvalue) { TypeReference valueType = type.Reference; string typename = MDocUpdater.GetDocTypeFullName(valueType); TypeDefinition valueDef = type.Definition; if (typename.Contains("ObjCRuntime.Platform") && valueDef.CustomAttributes.Any(ca => ca.AttributeType.FullName == "System.FlagsAttribute")) { var values = GetEnumerationValues(valueDef); long c = ToInt64(v); returnvalue = Format(c, values, typename); return(true); } returnvalue = null; return(false); }
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 override bool TryFormatValue(object v, ResolvedTypeInfo type, out string returnvalue) { TypeReference valueType = type.Reference; TypeDefinition valueDef = type.Definition; if (valueDef.CustomAttributes.Any(ca => ca.AttributeType.FullName == "System.FlagsAttribute")) { string typename = MDocUpdater.GetDocTypeFullName(valueType); var values = MDocUpdater.GetEnumerationValues(valueDef); long c = MDocUpdater.ToInt64(v); returnvalue = string.Join(" | ", (from i in values.Keys where (c & i) == i && i != 0 select typename + "." + values[i]) .DefaultIfEmpty(c.ToString()).ToArray()); return(true); } returnvalue = null; return(false); }
private ParamContext InitComplexContext <T>(string methodXml, string ns, string methodName, FrameworkIndex fx) { var doc = new XmlDocument(); doc.LoadXml(methodXml); var beforeXML = doc.OuterXml; TypeDefinition type = GetDefinition <T>(ns); var method = type.Methods.First(m => m.Name == methodName) as MethodReference; var updater = new MDocUpdater(); return(new ParamContext() { doc = doc, beforeXML = beforeXML, method = method, parameters = method.Parameters.ToList(), fx = fx, updater = updater }); }
private StringBuilder AppendParameter(StringBuilder buf, ParameterDefinition parameter) { TypeReference parameterType = parameter.ParameterType; if (parameterType is ByReferenceType byReferenceType) { if (parameter.IsOut) { buf.Append("out "); } else if (parameter.IsIn && parameter.CustomAttributes.Any(ca => ca.AttributeType.FullName == "System.Runtime.CompilerServices.IsReadOnlyAttribute")) { buf.Append("in "); } else { buf.Append("ref "); } parameterType = byReferenceType.ElementType; } if (parameter.HasCustomAttributes) { var isParams = parameter.CustomAttributes.Any(ca => ca.AttributeType.Name == "ParamArrayAttribute"); if (isParams) { buf.AppendFormat("params "); } } buf.Append(GetTypeName(parameterType, new DynamicParserContext(parameter))).Append(" "); buf.Append(parameter.Name); if (parameter.HasDefault && parameter.IsOptional && parameter.HasConstant) { var ReturnVal = MDocUpdater.MakeAttributesValueString(parameter.Constant, parameter.ParameterType); buf.AppendFormat(" = {0}", ReturnVal == "null" ? "default" : ReturnVal); } return(buf); }
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 static string GetNamespace(TypeReference type, string delimeter = null) { if (type == null) { return(string.Empty); } if (type.GetElementType().IsNested) { type = type.GetElementType(); } while (type != null && type.IsNested && !type.IsGenericParameter) { type = type.DeclaringType; } if (type == null) { return(string.Empty); } string typeNS = type.Namespace; if (!string.IsNullOrEmpty(delimeter)) { typeNS = typeNS.Replace(".", delimeter); } // first, make sure this isn't a type reference to another assembly/module bool isInAssembly = MDocUpdater.IsInAssemblies(type.Module.Name); if (isInAssembly && !typeNS.StartsWith("System") && MDocUpdater.HasDroppedNamespace(type)) { typeNS = string.Format("{0}{1}{2}", MDocUpdater.droppedNamespace, delimeter ?? ".", typeNS); } return(typeNS); }
public override bool TryFormatValue(object v, ResolvedTypeInfo type, out string returnvalue) { returnvalue = "(" + MDocUpdater.GetDocTypeFullName(type.Reference) + ") " + MDocUpdater.FilterSpecialChars(v.ToString()); return(true); }
public static MemberReference GetMember(TypeDefinition type, DocumentationMember member) { string membertype = member.MemberType; string returntype = member.ReturnType; string docName = member.MemberName; string[] docTypeParams = GetTypeParameters(docName, member.TypeParameters); // If we're using 'magic types', then we might get false positives ... in those cases, we keep searching MemberReference likelyCandidate = null; // Loop through all members in this type with the same name var reflectedMembers = GetReflectionMembers(type, docName, membertype).ToArray(); foreach (MemberReference mi in reflectedMembers) { bool matchedMagicType = false; if (mi is TypeDefinition) { continue; } if (MDocUpdater.GetMemberType(mi) != membertype) { continue; } if (MDocUpdater.IsPrivate(mi)) { continue; } IList <ParameterDefinition> pis = null; string[] typeParams = null; if (mi is MethodDefinition) { MethodDefinition mb = (MethodDefinition)mi; pis = mb.Parameters; if (mb.IsGenericMethod()) { IList <GenericParameter> args = mb.GenericParameters; typeParams = args.Select(p => p.Name).ToArray(); } } else if (mi is PropertyDefinition) { pis = ((PropertyDefinition)mi).Parameters; } // check type parameters int methodTcount = member.TypeParameters == null ? 0 : member.TypeParameters.Count; int reflectionTcount = typeParams == null ? 0 : typeParams.Length; if (methodTcount != reflectionTcount) { continue; } // check member parameters int mcount = member.Parameters == null ? 0 : member.Parameters.Count; int pcount = pis == null ? 0 : pis.Count; if (mcount != pcount) { continue; } MethodDefinition mDef = mi as MethodDefinition; if (mDef != null && !mDef.IsConstructor && (mDef.Name.StartsWith("op_Explicit", StringComparison.Ordinal) || mDef.Name.StartsWith("op_Implicit", StringComparison.Ordinal))) { // Casting operators can overload based on return type. string rtype = GetReplacedString( MDocUpdater.GetDocTypeFullName(((MethodDefinition)mi).ReturnType), typeParams, docTypeParams); string originalRType = rtype; if (MDocUpdater.SwitchingToMagicTypes) { rtype = NativeTypeManager.ConvertFromNativeType(rtype); } if ((returntype != rtype && originalRType == rtype) || (MDocUpdater.SwitchingToMagicTypes && returntype != originalRType && returntype != rtype && originalRType != rtype)) { continue; } if (originalRType != rtype) { matchedMagicType = true; } } if (pcount == 0) { return(mi); } bool isExtensionMethod = DocUtils.IsExtensionMethod(mDef); bool good = true; for (int i = 0; i < pis.Count; i++) { bool isRefType = pis[i].ParameterType is ByReferenceType; if (i == 0 && !isRefType && isExtensionMethod) { isRefType = true; // this will be the case for generic parameter types } string paramType = GetReplacedString( MDocUpdater.GetDocParameterType(pis[i].ParameterType), typeParams, docTypeParams); // if magictypes, replace paramType to "classic value" ... so the comparison works string originalParamType = paramType; if (MDocUpdater.SwitchingToMagicTypes) { paramType = NativeTypeManager.ConvertFromNativeType(paramType); } string xmlMemberType = member.Parameters[i]; // TODO: take into account extension method reftype bool xmlIsRefType = xmlMemberType.Contains('&'); bool refTypesMatch = isRefType == xmlIsRefType; if (!refTypesMatch) { good = false; break; } xmlMemberType = xmlIsRefType ? xmlMemberType.Substring(0, xmlMemberType.Length - 1) : xmlMemberType; if ((!paramType.Equals(xmlMemberType) && paramType.Equals(originalParamType)) || (MDocUpdater.SwitchingToMagicTypes && !originalParamType.Equals(xmlMemberType) && !paramType.Equals(xmlMemberType) && !paramType.Equals(originalParamType))) { // did not match ... if we're dropping the namespace, and the paramType has the dropped // namespace, we should see if it matches when added bool stillDoesntMatch = true; if (MDocUpdater.HasDroppedNamespace(type) && paramType.StartsWith(MDocUpdater.droppedNamespace)) { string withDroppedNs = string.Format("{0}.{1}", MDocUpdater.droppedNamespace, xmlMemberType); stillDoesntMatch = withDroppedNs != paramType; } if (stillDoesntMatch) { good = false; break; } } if (originalParamType != paramType) { matchedMagicType = true; } } if (!good) { continue; } if (MDocUpdater.SwitchingToMagicTypes && likelyCandidate == null && matchedMagicType) { // we matched this on a magic type conversion ... let's keep going to see if there's another one we should look at that matches more closely likelyCandidate = mi; continue; } return(mi); } return(likelyCandidate); }
private static IEnumerable <MemberReference> GetReflectionMembersCore(TypeDefinition type, string docName, string memberType) { // In case of dropping the namespace, we have to remove the dropped NS // so that docName will match what's in the assembly/type if (MDocUpdater.HasDroppedNamespace(type) && docName.StartsWith(MDocUpdater.droppedNamespace + ".")) { int droppedNsLength = MDocUpdater.droppedNamespace.Length; docName = docName.Substring(droppedNsLength + 1, docName.Length - droppedNsLength - 1); } // need to worry about 4 forms of //@MemberName values: // 1. "Normal" (non-generic) member names: GetEnumerator // - Lookup as-is. // 2. Explicitly-implemented interface member names: System.Collections.IEnumerable.Current // - try as-is, and try type.member (due to "kludge" for property // support. // 3. "Normal" Generic member names: Sort<T> (CSC) // - need to remove generic parameters --> "Sort" // 4. Explicitly-implemented interface members for generic interfaces: // -- System.Collections.Generic.IEnumerable<T>.Current // - Try as-is, and try type.member, *keeping* the generic parameters. // --> System.Collections.Generic.IEnumerable<T>.Current, IEnumerable<T>.Current // 5. As of 2008-01-02, gmcs will do e.g. 'IFoo`1[A].Method' instead of // 'IFoo<A>.Method' for explicitly implemented methods; don't interpret // this as (1) or (2). if (docName.IndexOf('<') == -1 && docName.IndexOf('[') == -1) { int memberCount = 0; // Cases 1 & 2 foreach (MemberReference mi in type.GetMembers(docName)) { memberCount++; yield return(mi); } if (memberCount == 0 && CountChars(docName, '.') > 0) { Func <MemberReference, bool> verifyInterface = (member) => { var meth = member as MethodDefinition; if (meth == null && member is PropertyReference) { var propertyDefinition = ((PropertyReference)member).Resolve(); meth = propertyDefinition.GetMethod ?? propertyDefinition.SetMethod; } return(meth != null && (member.Name.Equals(".ctor") || DocUtils.IsExplicitlyImplemented(meth))); }; // might be a property; try only type.member instead of // namespace.type.member. var typeMember = DocUtils.GetTypeDotMember(docName); var memberName = DocUtils.GetMember(docName); foreach (MemberReference mi in type.GetMembers(typeMember).Where(verifyInterface)) { memberCount++; yield return(mi); } // some VB libraries use just the member name foreach (MemberReference mi in type.GetMembers(memberName).Where(verifyInterface)) { memberCount++; yield return(mi); } // some VB libraries use a `typemember` naming convention foreach (MemberReference mi in type.GetMembers(typeMember.Replace(".", "")).Where(verifyInterface)) { memberCount++; yield return(mi); } // if we still haven't found the member, there are some VB libraries // that use a different interface name for implementation. if (memberCount == 0) { foreach (MemberReference mi in type .GetMembers() .Where(m => m.Name.StartsWith("I", StringComparison.InvariantCultureIgnoreCase) && m.Name.EndsWith(memberName, StringComparison.InvariantCultureIgnoreCase)) .Where(verifyInterface)) { memberCount++; yield return(mi); } } if (memberCount == 0 && memberType == "Property") { foreach (MemberReference mr in type.GetMembers().Where(x => x is PropertyDefinition)) { var method = ((PropertyDefinition)mr).GetMethod ?? ((PropertyDefinition)mr).SetMethod; if (method?.Overrides != null && method.Overrides.Any()) { DocUtils.GetInfoForExplicitlyImplementedMethod(method, out TypeReference iface, out MethodReference ifaceMethod); var newName = DocUtils.GetMemberForProperty(ifaceMethod.Name); if (newName == memberName && verifyInterface(mr) && docName.Contains(iface.Name)) { yield return(mr); } } } } } yield break; } // cases 3 & 4 int numLt = 0; int numDot = 0; int startLt, startType, startMethod; startLt = startType = startMethod = -1; for (int i = 0; i < docName.Length; ++i) { switch (docName[i]) { case '<': if (numLt == 0) { startLt = i; } ++numLt; break; case '>': --numLt; if (numLt == 0 && (i + 1) < docName.Length) { // there's another character in docName, so this <...> sequence is // probably part of a generic type -- case 4. startLt = -1; } break; case '.': startType = startMethod; startMethod = i; ++numDot; break; } } string refName = startLt == -1 ? docName : docName.Substring(0, startLt); // case 3 foreach (MemberReference mi in type.GetMembers(refName)) { yield return(mi); } // case 4 foreach (MemberReference mi in type.GetMembers(refName.Substring(startType + 1))) { yield return(mi); } // If we _still_ haven't found it, we've hit another generic naming issue: // post Mono 1.1.18, gmcs generates [[FQTN]] instead of <TypeName> for // explicitly-implemented METHOD names (not properties), e.g. // "System.Collections.Generic.IEnumerable`1[[Foo, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]].GetEnumerator" // instead of "System.Collections.Generic.IEnumerable<Foo>.GetEnumerator", // which the XML docs will contain. // // Alas, we can't derive the Mono name from docName, so we need to iterate // over all member names, convert them into CSC format, and compare... :-( if (numDot == 0) { yield break; } foreach (MemberReference mi in type.GetMembers()) { if (MDocUpdater.GetMemberName(mi) == docName) { yield return(mi); } } }
new IEnumerable <TypeDefinition> GetDocumentationTypes(AssemblyDefinition assembly, List <string> forTypes, HashSet <string> seen) { int typeDepth = -1; while (ecmadocs.Read()) { switch (ecmadocs.Name) { case "Type": { if (typeDepth == -1) { typeDepth = ecmadocs.Depth; } if (ecmadocs.NodeType != XmlNodeType.Element) { continue; } if (typeDepth != ecmadocs.Depth) // nested <TypeDefinition/> element? { continue; } string typename = ecmadocs.GetAttribute("FullName"); string typename2 = MDocUpdater.GetTypeFileName(typename); if (forTypes != null && forTypes.BinarySearch(typename) < 0 && typename != typename2 && forTypes.BinarySearch(typename2) < 0) { continue; } TypeDefinition t; if ((t = assembly.GetType(typename)) == null && (t = assembly.GetType(typename2)) == null) { continue; } seen.Add(typename); if (typename != typename2) { seen.Add(typename2); } Console.WriteLine(" Import: {0}", t.FullName); if (ecmadocs.Name != "Docs") { int depth = ecmadocs.Depth; while (ecmadocs.Read()) { if (ecmadocs.Name == "Docs" && ecmadocs.Depth == depth + 1) { break; } } } if (!ecmadocs.IsStartElement("Docs")) { throw new InvalidOperationException("Found " + ecmadocs.Name + "; expecting <Docs/>!"); } yield return(t); break; } default: break; } } }
public EcmaDocumentationEnumerator(MDocUpdater app, XmlReader ecmaDocs) { this.app = app; this.ecmadocs = ecmaDocs; }
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 MDocPreserve () { updater = new MDocUpdater (); }