protected override string GetPropertyDeclaration(PropertyDefinition property) { string getVisible = null; if (DocUtils.IsAvailablePropertyMethod(property.GetMethod)) { getVisible = AppendVisibility(new StringBuilder(), property.GetMethod)?.ToString(); } string setVisible = null; if (DocUtils.IsAvailablePropertyMethod(property.SetMethod)) { setVisible = AppendVisibility(new StringBuilder(), property.SetMethod)?.ToString(); } if (setVisible == null && getVisible == null) { return(null); } bool isField = GetFSharpFlags(property.CustomAttributes).Any(i => i == SourceConstructFlags.Field); StringBuilder buf = new StringBuilder(); if (IsRecord(property.DeclaringType)) { AppendRecordParameter(buf, property); return(buf.ToString()); } if (IsModule(property.DeclaringType)) { buf.Append($"{GetName(property.DeclaringType)}."); } else { if (isField) { buf.Append("val "); } else { buf.Append("member this."); } } buf.Append(property.Name); if (property.Parameters.Count != 0) { buf.Append("("); AppendParameters(buf, property.GetMethod ?? property.SetMethod, property.Parameters); buf.Append(")"); } buf.Append(" : "); buf.Append(GetTypeName(property.PropertyType)); if (getVisible != null && setVisible != null) { buf.Append(" with get, set"); } return(buf.ToString()); }
void SetType(TypeDefinition type) { if (type == null) { throw new ArgumentNullException("type"); } Type = type; GenericParameters = new List <GenericParameter> (type.GenericParameters); List <TypeReference> declTypes = DocUtils.GetDeclaringTypes(type); int maxGenArgs = DocUtils.GetGenericArgumentCount(type); for (int i = 0; i < declTypes.Count - 1; ++i) { int remove = System.Math.Min(maxGenArgs, DocUtils.GetGenericArgumentCount(declTypes[i])); maxGenArgs -= remove; while (remove-- > 0) { GenericParameters.RemoveAt(0); } } if (DocUtils.IsDelegate(type)) { Parameters = type.GetMethod("Invoke").Parameters; ReturnType = type.GetMethod("Invoke").ReturnType; ReturnIsReturn = true; } }
/// <summary> /// C# compiler uses complecated logic to generate docIds for Eii properties. Need to have special logic here. /// </summary> /// <param name="property">Value to process</param> /// <returns>DocId for property member wchich needs to be equal to docId generated by compiler's /doc flag </returns> protected override string EiiPropertyProcessing(PropertyReference property) { string name; PropertyDefinition propertyDef = property as PropertyDefinition; MethodDefinition method = null; if (propertyDef != null) { method = propertyDef.GetMethod ?? propertyDef.SetMethod; } if (method != null && !DocUtils.IsExplicitlyImplemented(method)) { name = property.Name; } else { DocUtils.GetInfoForExplicitlyImplementedMethod(method, out var iface, out var ifaceMethod); AddTypeCount = false; name = string.Join("#", new string[] { GetTypeName(iface).Replace(".", "#"), DocUtils.GetMember(property.Name) }); AddTypeCount = true; } return(name); }
protected override StringBuilder AppendGenericType(StringBuilder buf, TypeReference type, DynamicParserContext context, bool appendGeneric = true, bool useTypeProjection = false) { List <TypeReference> decls = DocUtils.GetDeclaringTypes( type is GenericInstanceType ? type.GetElementType() : type); bool first = true; foreach (var decl in decls) { TypeReference declDef = decl.Resolve() ?? decl; if (!first) { buf.Append(NestedTypeSeparator); } first = false; AppendTypeName(buf, declDef, context); } buf.Append('<'); first = true; foreach (TypeReference arg in GetGenericArguments(type)) { if (!first) { buf.Append(", "); } first = false; _AppendTypeName(buf, arg, context); } buf.Append('>'); return(buf); }
protected override string GetPropertyDeclaration(PropertyDefinition property) { if (DocUtils.IsExplicitlyImplemented(property)) { return(DocUtils.GetPropertyName(property, NestedTypeSeparator)); } return($"{GetName(property.DeclaringType)}.{property.Name}"); }
protected override string GetPropertyDeclaration(PropertyDefinition property) { MethodDefinition gm = null, sm = null; string get_visible = null; if ((gm = property.GetMethod) != null && (DocUtils.IsExplicitlyImplemented(gm) || (!gm.IsPrivate && !gm.IsAssembly && !gm.IsFamilyAndAssembly))) { get_visible = AppendVisibility(new StringBuilder(), gm).ToString(); } string set_visible = null; if ((sm = property.SetMethod) != null && (DocUtils.IsExplicitlyImplemented(sm) || (!sm.IsPrivate && !sm.IsAssembly && !sm.IsFamilyAndAssembly))) { set_visible = AppendVisibility(new StringBuilder(), sm).ToString(); } if ((set_visible == null) && (get_visible == null)) { return(null); } StringBuilder buf = new StringBuilder() .Append(".property "); if (!(gm ?? sm).IsStatic) { buf.Append("instance "); } _AppendTypeName(buf, property.PropertyType, new DynamicParserContext(property)); buf.Append(' ').Append(property.Name); if (!property.HasParameters || property.Parameters.Count == 0) { return(buf.ToString()); } buf.Append('('); bool first = true; foreach (ParameterDefinition p in property.Parameters) { if (!first) { buf.Append(", "); } first = false; _AppendTypeName(buf, p.ParameterType, new DynamicParserContext(p)); } buf.Append(')'); return(buf.ToString()); }
protected override StringBuilder AppendNamespace(StringBuilder buf, TypeReference type) { string ns = DocUtils.GetNamespace(type); if (GetVBType(type.FullName) == null && !string.IsNullOrEmpty(ns) && ns != "System") { buf.Append(ns).Append('.'); } return(buf); }
protected virtual StringBuilder AppendNamespace(StringBuilder buf, TypeReference type) { string ns = DocUtils.GetNamespace(type); if (ns != null && ns.Length > 0) { buf.Append(ns).Append('.'); } return(buf); }
protected override StringBuilder AppendNamespace(StringBuilder buf, TypeReference type) { string ns = DocUtils.GetNamespace(type); if (GetCSharpType(type.FullName) == null && ns != null && ns.Length > 0 && ns != "System") { buf.Append(ns).Append('.'); } return(buf); }
public static bool IsEiiIgnoredMethod(MethodReference method, MethodReference imethod) { if (DocUtils.IsExplicitlyImplemented(method.Resolve()) && !method.Resolve().IsSpecialName) { if (IsIgnored(imethod)) { return(true); } } return(false); }
protected override StringBuilder AppendMethodName(StringBuilder buf, MethodDefinition method) { if (DocUtils.IsExplicitlyImplemented(method)) { TypeReference iface; MethodReference ifaceMethod; DocUtils.GetInfoForExplicitlyImplementedMethod(method, out iface, out ifaceMethod); return(buf.Append(new CSharpMemberFormatter(this.TypeMap).GetName(iface)) .Append('.') .Append(ifaceMethod.Name)); } return(base.AppendMethodName(buf, method)); }
protected override string GetPropertyName(PropertyReference property) { string name = null; PropertyDefinition propertyDef = property as PropertyDefinition; MethodDefinition method = null; if (propertyDef != null) { method = propertyDef.GetMethod ?? propertyDef.SetMethod; } if (method != null && !DocUtils.IsExplicitlyImplemented(method)) { name = property.Name; } else { TypeReference iface; MethodReference ifaceMethod; DocUtils.GetInfoForExplicitlyImplementedMethod(method, out iface, out ifaceMethod); AddTypeCount = false; name = string.Join("#", new string[] { GetTypeName(iface).Replace(".", "#"), DocUtils.GetMember(property.Name) }); AddTypeCount = true; } StringBuilder buf = new StringBuilder(); buf.Append(GetName(property.DeclaringType)); buf.Append('.'); buf.Append(name); IList <ParameterDefinition> parameters = property.Parameters; if (parameters.Count > 0) { genDeclType = property.DeclaringType; buf.Append('('); IList <GenericParameter> genArgs = property.DeclaringType.GenericParameters; AppendParameter(buf, genArgs, parameters[0]); for (int i = 1; i < parameters.Count; ++i) { buf.Append(','); AppendParameter(buf, genArgs, parameters[i]); } buf.Append(')'); genDeclType = null; } return(buf.ToString()); }
protected IEnumerable <TypeDefinition> GetDocumentationTypes(AssemblyDefinition assembly, List <string> forTypes, HashSet <string> seen) { foreach (TypeDefinition type in assembly.GetTypes()) { if (forTypes != null && forTypes.BinarySearch(type.FullName) < 0) { continue; } if (seen != null && seen.Contains(type.FullName)) { continue; } yield return(DocUtils.FixUnnamedParameters(type)); } }
protected override StringBuilder AppendGenericType(StringBuilder buf, TypeReference type, DynamicParserContext context, bool appendGeneric = true, bool useTypeProjection = false) { List <TypeReference> decls = DocUtils.GetDeclaringTypes( type is GenericInstanceType ? type.GetElementType() : type); List <TypeReference> genArgs = GetGenericArguments(type); int argIdx = 0; int displayedInParentArguments = 0; bool insertNested = false; foreach (var decl in decls) { TypeReference declDef = decl.Resolve() ?? decl; if (insertNested) { buf.Append(NestedTypeSeparator); } insertNested = true; AppendTypeName(buf, declDef, context); int argumentCount = DocUtils.GetGenericArgumentCount(declDef); int notYetDisplayedArguments = argumentCount - displayedInParentArguments; displayedInParentArguments = argumentCount;// nested TypeReferences have parents' generic arguments, but we shouldn't display them if (notYetDisplayedArguments > 0) { buf.Append(GenericTypeContainer[0]); var origState = MemberFormatterState; MemberFormatterState = MemberFormatterState.WithinGenericTypeParameters; for (int i = 0; i < notYetDisplayedArguments; ++i) { if (i > 0) { buf.Append(", "); } var genArg = genArgs[argIdx++]; _AppendTypeName(buf, genArg, context, useTypeProjection: useTypeProjection); var genericParameter = genArg as GenericParameter; if (genericParameter != null) { AppendConstraints(buf, genericParameter); } } MemberFormatterState = origState; buf.Append(GenericTypeContainer[1]); } } return(buf); }
private string GetTypeKind(TypeDefinition type) { if (type.IsInterface) { return("interface"); } if (type.IsValueType) { return("struct"); } if (DocUtils.IsDelegate(type)) { return("delegate of"); } return("class"); }
void SetType(TypeDefinition type) { if (type == null) { throw new ArgumentNullException("type"); } Type = type; GenericParameters = DocUtils.GetGenericParameters(type); if (DocUtils.IsDelegate(type)) { Parameters = type.GetMethod("Invoke").Parameters; ReturnType = type.GetMethod("Invoke").ReturnType; ReturnIsReturn = true; } }
protected static bool IsPublicEII(EventDefinition e) { bool isPublicEII = false; if (e.AddMethod.HasOverrides) { var resolvedAddMethod = e.AddMethod.Overrides[0].Resolve(); var resolvedInterface = e.AddMethod.Overrides[0].DeclaringType.Resolve(); if (DocUtils.IsPublic(resolvedInterface) && resolvedAddMethod != null && resolvedAddMethod.IsPublic) { isPublicEII = true; } } return(isPublicEII); }
private StringBuilder AppendParameters(StringBuilder buf, MethodDefinition method, IList <ParameterDefinition> parameters, char begin, char end) { buf.Append(begin); if (parameters.Count > 0) { if (DocUtils.IsExtensionMethod(method)) { buf.Append("this "); } AppendParameter(buf, parameters[0]); for (int i = 1; i < parameters.Count; ++i) { buf.Append(", "); AppendParameter(buf, parameters[i]); } } return(buf.Append(end)); }
protected override string GetMethodName(MethodReference method) { string name = null; MethodDefinition methodDef = method as MethodDefinition; if (methodDef == null || !DocUtils.IsExplicitlyImplemented(methodDef)) { name = method.Name; } else { TypeReference iface; MethodReference ifaceMethod; DocUtils.GetInfoForExplicitlyImplementedMethod(methodDef, out iface, out ifaceMethod); AddTypeCount = false; name = GetTypeName(iface) + "." + ifaceMethod.Name; AddTypeCount = true; } return(GetMethodDefinitionName(method, name)); }
protected override string GetFieldDeclaration(FieldDefinition field) { TypeDefinition declType = (TypeDefinition)field.DeclaringType; if (declType.IsEnum && field.Name == "value__") { return(null); // This member of enums aren't documented. } StringBuilder buf = new StringBuilder(); AppendFieldVisibility(buf, field); if (buf.Length == 0) { return(null); } if (declType.IsEnum) { return(field.Name); } if (field.IsStatic && !field.IsLiteral) { buf.Append(" static"); } if (field.IsInitOnly) { buf.Append(" readonly"); } if (field.IsLiteral) { buf.Append(" const"); } buf.Append(' ').Append(GetTypeName(field.FieldType, new DynamicParserContext(field))).Append(' '); buf.Append(field.Name); DocUtils.AppendFieldValue(buf, field); buf.Append(';'); return(buf.ToString()); }
protected override StringBuilder AppendNamespace(StringBuilder buf, TypeReference type) { if (GetBuiltinType(type.FullName) != null) { return(buf); } string ns = DocUtils.GetNamespace(type); if (ns != null && ns.Length > 0) { if (type.IsValueType) { buf.Append("valuetype "); } else { buf.Append("class "); } buf.Append(ns).Append('.'); } return(buf); }
protected virtual string GetMethodDeclaration(MethodDefinition method) { if (method.HasCustomAttributes && method.CustomAttributes.Cast <CustomAttribute> ().Any( ca => ca.GetDeclaringType() == "System.Diagnostics.Contracts.ContractInvariantMethodAttribute")) { return(null); } // Special signature for destructors. if (method.Name == "Finalize" && method.Parameters.Count == 0) { return(GetFinalizerName(method)); } StringBuilder buf = new StringBuilder(); AppendVisibility(buf, method); if (buf.Length == 0 && !(DocUtils.IsExplicitlyImplemented(method) && !method.IsSpecialName)) { return(null); } AppendModifiers(buf, method); if (buf.Length != 0) { buf.Append(" "); } buf.Append(GetTypeName(method.ReturnType, new DynamicParserContext(method.MethodReturnType))).Append(" "); AppendMethodName(buf, method); AppendGenericMethod(buf, method).Append(" "); AppendParameters(buf, method, method.Parameters); AppendGenericMethodConstraints(buf, method); return(buf.ToString()); }
protected virtual StringBuilder AppendGenericType(StringBuilder buf, TypeReference type, DynamicParserContext context, bool appendGeneric = true) { List <TypeReference> decls = DocUtils.GetDeclaringTypes( type is GenericInstanceType ? type.GetElementType() : type); List <TypeReference> genArgs = GetGenericArguments(type); int argIdx = 0; int prev = 0; bool insertNested = false; foreach (var decl in decls) { TypeReference declDef = decl.Resolve() ?? decl; if (insertNested) { buf.Append(NestedTypeSeparator); } insertNested = true; AppendTypeName(buf, declDef, context); int ac = DocUtils.GetGenericArgumentCount(declDef); int c = ac - prev; prev = ac; if (appendGeneric && c > 0) { buf.Append(GenericTypeContainer[0]); var origState = MemberFormatterState; MemberFormatterState = MemberFormatterState.WithinGenericTypeParameters; _AppendTypeName(buf, genArgs[argIdx++], context); for (int i = 1; i < c; ++i) { _AppendTypeName(buf.Append(","), genArgs[argIdx++], context); } MemberFormatterState = origState; buf.Append(GenericTypeContainer[1]); } } return(buf); }
private StringBuilder AppendType(StringBuilder buf, TypeReference type, DynamicParserContext context) { List <TypeReference> decls = DocUtils.GetDeclaringTypes(type); bool insertNested = false; int prevParamCount = 0; foreach (var decl in decls) { if (insertNested) { buf.Append(NestedTypeSeparator); } insertNested = true; base.AppendTypeName(buf, decl, context); int argCount = DocUtils.GetGenericArgumentCount(decl); int numArgs = argCount - prevParamCount; prevParamCount = argCount; if (numArgs > 0) { buf.Append('`').Append(numArgs); } } return(buf); }
protected override string GetPropertyDeclaration(PropertyDefinition property) { string getVisible = null; if (DocUtils.IsAvailablePropertyMethod(property.GetMethod)) { getVisible = AppendVisibility(new StringBuilder(), property.GetMethod).ToString(); } string setVisible = null; if (DocUtils.IsAvailablePropertyMethod(property.SetMethod)) { setVisible = AppendVisibility(new StringBuilder(), property.SetMethod).ToString(); } if (setVisible == null && getVisible == null) { return(null); } StringBuilder buf = new StringBuilder(); IEnumerable <MemberReference> defs = property.DeclaringType.GetDefaultMembers(); bool indexer = false; foreach (MemberReference mi in defs) { if (mi == property) { indexer = true; break; } } if (indexer) { buf.Append("Default "); } if (getVisible != null && (setVisible == null || (setVisible != null && getVisible == setVisible))) { buf.Append(getVisible); } else if (setVisible != null && getVisible == null) { buf.Append(setVisible); } else { buf.Append("Public"); } // Pick an accessor to use for static/virtual/override/etc. checks. var method = property.SetMethod; if (method == null) { method = property.GetMethod; } string modifiers = String.Empty; if (method.IsStatic && !IsModule(method.DeclaringType)) { modifiers += " Shared"; } if (method.IsVirtual && !method.IsAbstract) { if ((method.Attributes & MethodAttributes.NewSlot) != 0) { modifiers += " Overridable"; } else { modifiers += " Overrides"; } } TypeDefinition declDef = (TypeDefinition)method.DeclaringType; if (method.IsAbstract && !declDef.IsInterface) { modifiers += " MustOverride"; } if (method.IsFinal) { modifiers += " NotOverridable"; } if (modifiers == " MustOverride NotOverridable") { modifiers = ""; } if (modifiers == " Overridable NotOverridable") { modifiers = ""; } buf.Append(modifiers).Append(' '); if (getVisible != null && setVisible == null) { buf.Append("ReadOnly "); } buf.Append("Property "); buf.Append(property.Name.Split('.').Last()); if (property.Parameters.Count != 0) { AppendParameters(buf, method, property.Parameters, '(', ')'); } buf.Append(" As "); buf.Append(GetTypeName(property.PropertyType, new DynamicParserContext(property))); if (DocUtils.IsExplicitlyImplemented(property.GetMethod)) { TypeReference iface; MethodReference ifaceMethod; DocUtils.GetInfoForExplicitlyImplementedMethod(method, out iface, out ifaceMethod); buf.Append(" Implements ") .Append(new VBMemberFormatter(this.TypeMap).GetName(iface)) .Append('.') .Append(DocUtils.GetPropertyName(property, NestedTypeSeparator).Split('.').Last()); } return(buf.ToString()); }
protected override StringBuilder AppendMethodName(StringBuilder buf, MethodDefinition method) { if (DocUtils.IsExplicitlyImplemented(method)) { return(buf.Append(method.Name.Split('.').Last())); } if (DocUtils.IsOperator(method)) { // this is an operator switch (method.Name) { case "op_Implicit": case "op_Explicit": buf.Length--; // remove the last space, which assumes a member name is coming return(buf); case "op_Addition": case "op_UnaryPlus": return(buf.Append("Operator +")); case "op_Subtraction": case "op_UnaryNegation": return(buf.Append("Operator -")); case "op_IntegerDivision": return(buf.Append("Operator \\")); case "op_Division": return(buf.Append("Operator /")); case "op_Multiply": return(buf.Append("Operator *")); case "op_Modulus": return(buf.Append("Operator Mod")); case "op_BitwiseAnd": return(buf.Append("Operator And")); case "op_BitwiseOr": return(buf.Append("Operator Or")); case "op_ExclusiveOr": return(buf.Append("Operator Xor")); case "op_LeftShift": return(buf.Append("Operator <<")); case "op_RightShift": return(buf.Append("Operator >>")); case "op_LogicalNot": return(buf.Append("Operator Not")); case "op_OnesComplement": return(buf.Append("Operator Not")); case "op_True": return(buf.Append("Operator IsTrue")); case "op_False": return(buf.Append("Operator IsFalse")); case "op_Equality": return(buf.Append("Operator ==")); case "op_Inequality": return(buf.Append("Operator !=")); case "op_LessThan": return(buf.Append("Operator <")); case "op_LessThanOrEqual": return(buf.Append("Operator <=")); case "op_GreaterThan": return(buf.Append("Operator >")); case "op_GreaterThanOrEqual": return(buf.Append("Operator >=")); case "op_Like": return(buf.Append("Operator Like")); default: return(base.AppendMethodName(buf, method)); } } else { return(base.AppendMethodName(buf, method)); } }
protected override string GetMethodDeclaration(MethodDefinition method) { if (method.HasCustomAttributes && method.CustomAttributes.Cast <CustomAttribute>().Any( ca => ca.GetDeclaringType() == "System.Diagnostics.Contracts.ContractInvariantMethodAttribute")) { return(null); } // Special signature for destructors. if (method.Name == "Finalize" && method.Parameters.Count == 0) { return(GetFinalizerName(method)); } StringBuilder buf = new StringBuilder(); if (DocUtils.IsExtensionMethod(method)) { buf.Append("<Extension()>" + GetLineEnding()); } AppendVisibility(buf, method); if (buf.Length == 0 && !(DocUtils.IsExplicitlyImplemented(method) && !method.IsSpecialName)) { return(null); } AppendModifiers(buf, method); if (buf.Length != 0) { buf.Append(" "); } bool isFunction = method.MethodReturnType.ReturnType.FullName != "System.Void"; if (!DocUtils.IsOperator(method)) { if (isFunction) { buf.Append("Function "); } else { buf.Append("Sub "); } } AppendMethodName(buf, method); AppendGenericMethod(buf, method).Append(" "); AppendParameters(buf, method, method.Parameters); AppendGenericMethodConstraints(buf, method); if (isFunction) { buf.Append(" As ").Append(GetTypeName(method.ReturnType, new DynamicParserContext(method.MethodReturnType))); } if (DocUtils.IsExplicitlyImplemented(method)) { TypeReference iface; MethodReference ifaceMethod; DocUtils.GetInfoForExplicitlyImplementedMethod(method, out iface, out ifaceMethod); buf.Append(" Implements ") .Append(new VBMemberFormatter(this.TypeMap).GetName(iface)) .Append('.') .Append(ifaceMethod.Name); } return(buf.ToString()); }
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); } } }
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); }
protected override string GetTypeDeclaration(TypeDefinition type) { string visibility = GetTypeVisibility(type.Attributes); if (visibility == null) { return(null); } StringBuilder buf = new StringBuilder(); buf.Append(visibility); buf.Append(" "); MemberFormatter full = new VBMemberFormatter(this.TypeMap); if (DocUtils.IsDelegate(type)) { buf.Append("Delegate "); MethodDefinition invoke = type.GetMethod("Invoke"); bool isFunction = invoke.ReturnType.FullName != "System.Void"; if (isFunction) { buf.Append("Function "); } else { buf.Append("Sub "); } buf.Append(GetName(type)); AppendParameters(buf, invoke, invoke.Parameters); if (isFunction) { buf.Append(" As "); buf.Append(full.GetName(invoke.ReturnType, new DynamicParserContext(invoke.MethodReturnType))).Append(" "); } return(buf.ToString()); } if (type.IsAbstract && !type.IsInterface && !IsModule(type)) { buf.Append("MustInherit "); } if (type.IsSealed && !DocUtils.IsDelegate(type) && !type.IsValueType && !IsModule(type)) { buf.Append("NotInheritable "); } buf.Replace(" MustInherit NotInheritable", ""); buf.Append(GetTypeKind(type)); buf.Append(" "); buf.Append(GetVBType(type.FullName) == null ? GetName(type) : type.Name); if (!type.IsEnum) { TypeReference basetype = type.BaseType; if (basetype != null && basetype.FullName == "System.Object" || type.IsValueType) { basetype = null; } if (basetype != null) { buf.Append(GetLineEnding()).Append("Inherits "); buf.Append(full.GetName(basetype)); } List <string> interfaceNames = DocUtils.GetUserImplementedInterfaces(type) .Select(iface => full.GetName(iface)) .OrderBy(s => s) .ToList(); if (interfaceNames.Count > 0) { buf.Append(GetLineEnding()).Append("Implements "); buf.Append(string.Join(", ", interfaceNames)); } } return(buf.ToString()); }