public OverrideInformation(MethodDefinition @base, MethodDefinition @override, ITryResolveMetadata resolver, InterfaceImplementation?matchingInterfaceImplementation = null) { Base = @base; Override = @override; MatchingInterfaceImplementation = matchingInterfaceImplementation; this.resolver = resolver; }
static string GetSignaturePart(TypeReference type, ITryResolveMetadata resolver) { var builder = new StringBuilder(); DocumentationSignatureGenerator.PartVisitor.Instance.VisitTypeReference(type, builder, resolver); return(builder.ToString()); }
public void VisitArrayType(ArrayType arrayType, StringBuilder builder, ITryResolveMetadata resolver) { VisitTypeReference(arrayType.ElementType, builder, resolver); // Rank-one arrays are displayed different than rectangular arrays if (arrayType.IsVector) { builder.Append("[]"); } else { // C# arrays only support zero lower bounds if (arrayType.Dimensions[0].LowerBound != 0) { throw new NotImplementedException(); } builder.Append("[0:"); for (int i = 1; i < arrayType.Rank; i++) { if (arrayType.Dimensions[0].LowerBound != 0) { throw new NotImplementedException(); } builder.Append(",0:"); } builder.Append(']'); } }
public static IEnumerable <IMemberDefinition> GetMembersByDocumentationSignature(TypeDefinition type, string signature, ITryResolveMetadata resolver, bool acceptName = false) { int index = 0; var results = new List <IMemberDefinition> (); var nameBuilder = new StringBuilder(); var(name, arity) = DocumentationSignatureParser.ParseTypeOrNamespaceName(signature, ref index, nameBuilder); DocumentationSignatureParser.GetMatchingMembers(signature, ref index, type.Module, type, name, arity, DocumentationSignatureParser.MemberType.All, results, resolver, acceptName); return(results); }
public void VisitMethodDefinition(MethodDefinition method, StringBuilder builder, ITryResolveMetadata resolver) { VisitTypeReference(method.DeclaringType, builder, resolver); builder.Append('.').Append(GetEscapedMetadataName(method)); if (method.HasGenericParameters) { builder.Append("``").Append(method.GenericParameters.Count); } if (method.HasParameters || (method.CallingConvention == MethodCallingConvention.VarArg)) { VisitParameters(method.Parameters, method.CallingConvention == MethodCallingConvention.VarArg, builder, resolver); } if (method.Name == "op_Implicit" || method.Name == "op_Explicit") { builder.Append('~'); VisitTypeReference(method.ReturnType, builder, resolver); } }
public void VisitField(FieldDefinition field, StringBuilder builder, ITryResolveMetadata resolver) { VisitTypeReference(field.DeclaringType, builder, resolver); builder.Append('.').Append(field.Name); }
public void VisitByReferenceType(ByReferenceType byReferenceType, StringBuilder builder, ITryResolveMetadata resolver) { VisitTypeReference(byReferenceType.ElementType, builder, resolver); builder.Append('@'); }
public void VisitTypeReference(TypeReference typeReference, StringBuilder builder, ITryResolveMetadata resolver) { switch (typeReference) { case ByReferenceType byReferenceType: VisitByReferenceType(byReferenceType, builder, resolver); return; case PointerType pointerType: VisitPointerType(pointerType, builder, resolver); return; case ArrayType arrayType: VisitArrayType(arrayType, builder, resolver); return; case GenericParameter genericParameter: VisitGenericParameter(genericParameter, builder); return; } if (typeReference.IsNested) { Debug.Assert(typeReference is not SentinelType && typeReference is not PinnedType); // GetInflatedDeclaringType may return null for generic parameters, byrefs, and pointers, but these // are separately handled above. VisitTypeReference(typeReference.GetInflatedDeclaringType(resolver) !, builder, resolver); builder.Append('.'); } if (!String.IsNullOrEmpty(typeReference.Namespace)) { builder.Append(typeReference.Namespace).Append('.'); } // This includes '`n' for mangled generic types builder.Append(typeReference.Name); // For uninstantiated generic types (we already built the mangled name) // or non-generic types, we are done. if (typeReference.HasGenericParameters || typeReference is not GenericInstanceType genericInstance) { return; } // Compute arity counting only the newly-introduced generic parameters var declaringType = genericInstance.DeclaringType; var declaringArity = 0; if (declaringType != null && declaringType.HasGenericParameters) { declaringArity = declaringType.GenericParameters.Count; } var totalArity = genericInstance.GenericArguments.Count; var arity = totalArity - declaringArity; // Un-mangle the generic type name var suffixLength = arity.ToString().Length + 1; builder.Remove(builder.Length - suffixLength, suffixLength); // Append type arguments excluding arguments for re-declared parent generic parameters builder.Append('{'); bool needsComma = false; for (int i = totalArity - arity; i < totalArity; ++i) { if (needsComma) { builder.Append(','); } var typeArgument = genericInstance.GenericArguments[i]; VisitTypeReference(typeArgument, builder, resolver); needsComma = true; } builder.Append('}'); }
public void VisitProperty(PropertyDefinition property, StringBuilder builder, ITryResolveMetadata resolver) { VisitTypeReference(property.DeclaringType, builder, resolver); builder.Append('.').Append(GetEscapedMetadataName(property)); if (property.Parameters.Count > 0) { VisitParameters(property.Parameters, false, builder, resolver); } }
private static void VisitProperty(PropertyDefinition property, StringBuilder builder, ITryResolveMetadata resolver) { builder.Append(PropertyPrefix); PartVisitor.Instance.VisitProperty(property, builder, resolver); }
public static TypeReference GetInflatedDeclaringType(this TypeReference type, ITryResolveMetadata resolver) { if (type == null) { return(null); } if (type.IsGenericParameter || type.IsByReference || type.IsPointer) { return(null); } if (type is SentinelType sentinelType) { return(sentinelType.ElementType.GetInflatedDeclaringType(resolver)); } if (type is PinnedType pinnedType) { return(pinnedType.ElementType.GetInflatedDeclaringType(resolver)); } if (type is RequiredModifierType requiredModifierType) { return(requiredModifierType.ElementType.GetInflatedDeclaringType(resolver)); } if (type is GenericInstanceType genericInstance) { var declaringType = genericInstance.DeclaringType; if (declaringType.HasGenericParameters) { var result = new GenericInstanceType(declaringType); for (var i = 0; i < declaringType.GenericParameters.Count; ++i) { result.GenericArguments.Add(genericInstance.GenericArguments[i]); } return(result); } return(declaringType); } var resolved = resolver.TryResolve(type); System.Diagnostics.Debug.Assert(resolved == type); return(resolved?.DeclaringType); }
public static IEnumerable <(TypeReference InflatedInterface, InterfaceImplementation OriginalImpl)> GetInflatedInterfaces(this TypeReference typeRef, ITryResolveMetadata resolver) { var typeDef = resolver.TryResolve(typeRef); if (typeDef?.HasInterfaces != true) { yield break; } if (typeRef is GenericInstanceType genericInstance) { foreach (var interfaceImpl in typeDef.Interfaces) { // InflateGenericType only returns null when inflating generic parameters (and the generic instance type doesn't resolve). // Here we are not inflating a generic parameter but an interface type reference. yield return((InflateGenericType(genericInstance, interfaceImpl.InterfaceType, resolver), interfaceImpl) !); } } else { foreach (var interfaceImpl in typeDef.Interfaces) { yield return(interfaceImpl.InterfaceType, interfaceImpl); } } }
static bool ParseDocumentationSignature(string id, ModuleDefinition module, List <IMemberDefinition> results, ITryResolveMetadata resolver) { if (id == null) { return(false); } if (id.Length < 2) { return(false); } int index = 0; results.Clear(); ParseSignature(id, ref index, module, results, resolver); return(results.Count > 0); }
static bool AllParametersMatch(Collection <ParameterDefinition> methodParameters, List <string> expectedParameters, ITryResolveMetadata resolver) { if (methodParameters.Count != expectedParameters.Count) { return(false); } for (int i = 0; i < expectedParameters.Count; i++) { if (GetSignaturePart(methodParameters[i].ParameterType, resolver) != expectedParameters[i]) { return(false); } } return(true); }
static void GetMatchingProperties(string id, ref int index, TypeDefinition?type, string memberName, List <IMemberDefinition> results, ITryResolveMetadata resolver, bool acceptName = false) { if (type == null) { return; } int startIndex = index; int endIndex = index; List <string>?parameters = null; // Unlike Roslyn, we don't need to decode property names because we are working // directly with IL. foreach (var property in type.Properties) { index = startIndex; if (property.Name != memberName) { continue; } if (PeekNextChar(id, index) == '(') { if (parameters == null) { parameters = new List <string> (); } else { parameters.Clear(); } if (!ParseParameterList(id, ref index, property.DeclaringType, parameters)) { continue; } if (!AllParametersMatch(property.Parameters, parameters, resolver)) { continue; } } else { if (!acceptName && property.Parameters.Count != 0) { continue; } } results.Add(property); endIndex = index; } index = endIndex; }
private static void VisitField(FieldDefinition field, StringBuilder builder, ITryResolveMetadata resolver) { builder.Append(FieldPrefix); PartVisitor.Instance.VisitField(field, builder, resolver); }
private static void VisitEvent(EventDefinition evt, StringBuilder builder, ITryResolveMetadata resolver) { builder.Append(EventPrefix); PartVisitor.Instance.VisitEvent(evt, builder, resolver); }
public static IEnumerable <(TypeReference InflatedInterface, InterfaceImplementation OriginalImpl)> GetInflatedInterfaces(this TypeReference typeRef, ITryResolveMetadata resolver) { var typeDef = resolver.TryResolve(typeRef); if (typeDef?.HasInterfaces != true) { yield break; } if (typeRef is GenericInstanceType genericInstance) { foreach (var interfaceImpl in typeDef.Interfaces) { yield return(InflateGenericType(genericInstance, interfaceImpl.InterfaceType, resolver), interfaceImpl); } } else { foreach (var interfaceImpl in typeDef.Interfaces) { yield return(interfaceImpl.InterfaceType, interfaceImpl); } } }
private static void VisitTypeDefinition(TypeDefinition type, StringBuilder builder, ITryResolveMetadata resolver) { builder.Append(TypePrefix); PartVisitor.Instance.VisitTypeReference(type, builder, resolver); }
public static TypeReference InflateGenericType(GenericInstanceType genericInstanceProvider, TypeReference typeToInflate, ITryResolveMetadata resolver) { if (typeToInflate is ArrayType arrayType) { var inflatedElementType = InflateGenericType(genericInstanceProvider, arrayType.ElementType, resolver); if (inflatedElementType != arrayType.ElementType) { return(new ArrayType(inflatedElementType, arrayType.Rank)); } return(arrayType); } if (typeToInflate is GenericInstanceType genericInst) { return(MakeGenericType(genericInstanceProvider, genericInst, resolver)); } if (typeToInflate is GenericParameter genericParameter) { if (genericParameter.Owner is MethodReference) { return(genericParameter); } var elementType = resolver.TryResolve(genericInstanceProvider.ElementType); if (elementType == null) { return(null); } var parameter = elementType.GenericParameters.Single(p => p == genericParameter); return(genericInstanceProvider.GenericArguments[parameter.Position]); } if (typeToInflate is FunctionPointerType functionPointerType) { var result = new FunctionPointerType { ReturnType = InflateGenericType(genericInstanceProvider, functionPointerType.ReturnType, resolver) }; for (int i = 0; i < functionPointerType.Parameters.Count; i++) { var inflatedParameterType = InflateGenericType(genericInstanceProvider, functionPointerType.Parameters[i].ParameterType, resolver); result.Parameters.Add(new ParameterDefinition(inflatedParameterType)); } return(result); } if (typeToInflate is IModifierType modifierType) { var modifier = InflateGenericType(genericInstanceProvider, modifierType.ModifierType, resolver); var elementType = InflateGenericType(genericInstanceProvider, modifierType.ElementType, resolver); if (modifierType is OptionalModifierType) { return(new OptionalModifierType(modifier, elementType)); } return(new RequiredModifierType(modifier, elementType)); } if (typeToInflate is PinnedType pinnedType) { var elementType = InflateGenericType(genericInstanceProvider, pinnedType.ElementType, resolver); if (elementType != pinnedType.ElementType) { return(new PinnedType(elementType)); } return(pinnedType); } if (typeToInflate is PointerType pointerType) { var elementType = InflateGenericType(genericInstanceProvider, pointerType.ElementType, resolver); if (elementType != pointerType.ElementType) { return(new PointerType(elementType)); } return(pointerType); } if (typeToInflate is ByReferenceType byReferenceType) { var elementType = InflateGenericType(genericInstanceProvider, byReferenceType.ElementType, resolver); if (elementType != byReferenceType.ElementType) { return(new ByReferenceType(elementType)); } return(byReferenceType); } if (typeToInflate is SentinelType sentinelType) { var elementType = InflateGenericType(genericInstanceProvider, sentinelType.ElementType, resolver); if (elementType != sentinelType.ElementType) { return(new SentinelType(elementType)); } return(sentinelType); } return(typeToInflate); }
public void VisitEvent(EventDefinition evt, StringBuilder builder, ITryResolveMetadata resolver) { VisitTypeReference(evt.DeclaringType, builder, resolver); builder.Append('.').Append(GetEscapedMetadataName(evt)); }
private static GenericInstanceType MakeGenericType(GenericInstanceType genericInstanceProvider, GenericInstanceType type, ITryResolveMetadata resolver) { var result = new GenericInstanceType(type.ElementType); for (var i = 0; i < type.GenericArguments.Count; ++i) { result.GenericArguments.Add(InflateGenericType(genericInstanceProvider, type.GenericArguments[i], resolver)); } return(result); }
public void VisitPointerType(PointerType pointerType, StringBuilder builder, ITryResolveMetadata resolver) { VisitTypeReference(pointerType.ElementType, builder, resolver); builder.Append('*'); }
public static IEnumerable <MethodReference> GetMethods(this TypeReference type, ITryResolveMetadata resolver) { TypeDefinition typeDef = resolver.TryResolve(type); if (typeDef?.HasMethods != true) { yield break; } if (type is GenericInstanceType genericInstanceType) { foreach (var methodDef in typeDef.Methods) { yield return(MakeMethodReferenceForGenericInstanceType(genericInstanceType, methodDef)); } } else { foreach (var method in typeDef.Methods) { yield return(method); } } }
public static bool IsSubclassOf(this TypeReference type, string ns, string name, ITryResolveMetadata resolver) { TypeDefinition baseType = resolver.TryResolve(type); while (baseType != null) { if (baseType.IsTypeOf(ns, name)) { return(true); } baseType = resolver.TryResolve(baseType.BaseType); } return(false); }
public static void VisitMember(IMemberDefinition member, StringBuilder builder, ITryResolveMetadata resolver) { switch (member.MetadataToken.TokenType) { case TokenType.TypeDef: VisitTypeDefinition((TypeDefinition)member, builder, resolver); break; case TokenType.Method: VisitMethod((MethodDefinition)member, builder, resolver); break; case TokenType.Property: VisitProperty((PropertyDefinition)member, builder, resolver); break; case TokenType.Field: VisitField((FieldDefinition)member, builder, resolver); break; case TokenType.Event: VisitEvent((EventDefinition)member, builder, resolver); break; default: break; } }
private void VisitParameters(IEnumerable <ParameterDefinition> parameters, bool isVararg, StringBuilder builder, ITryResolveMetadata resolver) { builder.Append('('); bool needsComma = false; foreach (var parameter in parameters) { if (needsComma) { builder.Append(','); } // byrefs are tracked on the parameter type, not the parameter, // so we don't have VisitParameter that Roslyn uses. VisitTypeReference(parameter.ParameterType, builder, resolver); needsComma = true; } // note: the C# doc comment generator outputs an extra comma for varargs // methods that also have fixed parameters if (isVararg && needsComma) { builder.Append(','); } builder.Append(')'); }
private static void VisitMethod(MethodDefinition method, StringBuilder builder, ITryResolveMetadata resolver) { builder.Append(MethodPrefix); PartVisitor.Instance.VisitMethodDefinition(method, builder, resolver); }
public static TypeDefinition?ResolveType(this ModuleDefinition module, string typeFullName, ITryResolveMetadata resolver) { var type = module.GetType(typeFullName); if (type != null) { return(type); } if (!module.HasExportedTypes) { return(null); } // When resolving a forwarded type from a string, typeFullName should be a simple type name. int idx = typeFullName.LastIndexOf('.'); (string typeNamespace, string typeName) = idx > 0 ? (typeFullName.Substring(0, idx), typeFullName.Substring(idx + 1)) : (string.Empty, typeFullName); TypeReference typeReference = new TypeReference(typeNamespace, typeName, module, module); return(resolver.TryResolve(typeReference)); }
static void GetMatchingMethods(string id, ref int index, TypeDefinition?type, string memberName, int arity, List <IMemberDefinition> results, ITryResolveMetadata resolver, bool acceptName = false) { if (type == null) { return; } var parameters = new List <string> (); var startIndex = index; var endIndex = index; foreach (var method in type.Methods) { index = startIndex; if (method.Name != memberName) { continue; } var methodArity = method.HasGenericParameters ? method.GenericParameters.Count : 0; if (methodArity != arity) { continue; } parameters.Clear(); bool isNameOnly = true; if (PeekNextChar(id, index) == '(') { isNameOnly = false; // if the parameters cannot be identified (some error), then the symbol cannot match, try next method symbol if (!ParseParameterList(id, ref index, method, parameters)) { continue; } } // note: this allows extra characters at the end if (PeekNextChar(id, index) == '~') { isNameOnly = false; index++; string?returnType = ParseTypeSymbol(id, ref index, method); if (returnType == null) { continue; } // if return type is specified, then it must match if (GetSignaturePart(method.ReturnType, resolver) != returnType) { continue; } } if (!isNameOnly || !acceptName) { // check parameters unless we are matching a name only if (!AllParametersMatch(method.Parameters, parameters, resolver)) { continue; } } results.Add(method); endIndex = index; } index = endIndex; }