public IEnumerable<object> Run(IApp app, CancellationToken token) { if (typeDef == null) { yield return new AnalysisError("Failed to resolve '" + type.FullName + "'."); yield break; } var comparer = new SigComparer(); if (typeDef.IsInterface) { foreach (var type in app.Modules.GetModules().SelectMany(module => module.GetTypes())) { token.ThrowIfCancellationRequested(); if (!type.HasInterfaces) continue; foreach (var iface in type.Interfaces) { if (comparer.Equals(iface.Interface, typeDef)) yield return type; } } } else { foreach (var type in app.Modules.GetModules().SelectMany(module => module.GetTypes())) { token.ThrowIfCancellationRequested(); if (comparer.Equals(type.BaseType, typeDef)) yield return type; } } }
public DNContext(string asmToLoad) { var pa = AssemblyDef.Load(asmToLoad); reflectionOnlyAsm = Assembly.ReflectionOnlyLoadFrom(asmToLoad); var refs = reflectionOnlyAsm.GetReferencedAssemblies(); References = refs.Select(r => new AssemblyNameInfo(r)).ToArray(); //stdLibAsms = refs.Where(n => //{ // try // { // return Assembly.ReflectionOnlyLoad(n.FullName).GlobalAssemblyCache; // } // catch // { // return false; // } //}).Select(TranslateReference).Select(n => new AsmInfo(pa.MainModule.AssemblyResolver.Resolve(n))).ToList(); primaryAssembly = new AsmInfo(pa); // load types after stdlib/gac references are loaded SigComparer = new SigComparer(SigComparerOptions.PrivateScopeIsComparable); RefComparer = new DNReflectionComparer(this); Resolver = new MemberResolver(this); }
public override int GetHashCode() { int hash = new SigComparer().GetHashCode(InterfaceType); hash = hash * 7 + new SigComparer().GetHashCode(MethodSig); return(hash * 7 + Name.GetHashCode()); }
public override bool Equals(object obj) { var other = obj as FuncSig; if (other == null || other.Flags != Flags) { return(false); } if (other.ParamSigs.Length != ParamSigs.Length) { return(false); } var comparer = new SigComparer(); for (int i = 0; i < ParamSigs.Length; i++) { if (!comparer.Equals(ParamSigs[i], other.ParamSigs[i])) { return(false); } } if (!comparer.Equals(RetType, other.RetType)) { return(false); } return(true); }
protected MethodSignature SubstituteArguments(ModuleDef module, MethodSignature signature) { bool changed = false; List <Func <ModuleDef, TypeSig> > newParams = new List <Func <ModuleDef, TypeSig> >(); SigComparer comparer = new SigComparer(ComparerOptions); foreach (ParameterSignature param in signature.Parameters) { TypeSig typeSub = Substitute(param.ParameterType(module)); if (!comparer.Equals(typeSub, param.ParameterType(module))) { changed = true; } newParams.Add(Safe(typeSub)); } return(changed ? signature.DeclaringType.Method(signature.Name, signature.CallConvention, newParams) : signature); Func <ModuleDef, TypeSig> Safe(TypeSig sig) => m => { if (module != m) { throw new ArgumentException("incompatible module"); } return(sig); }; }
T[] ConvertArray <T>(TypeSig elemType, IList <CAArgument> oldList) { var list = new T[oldList.Count]; bool tIsValueType = typeof(T).IsValueType; bool tIsSystemObject = typeof(T) == typeof(object); var sigComparer = new SigComparer(SigComparerOptions.CompareAssemblyPublicKeyToken); for (int i = 0; i < list.Length; i++) { var arg = oldList[i]; if (!tIsSystemObject && !sigComparer.Equals(elemType, arg.Type)) { return(Array.Empty <T>()); } var res = ConvertFromModel(arg.Type, arg.Value); if (res is T) { list[i] = (T)res; } else if (!tIsValueType && (res == null || res == Null <T> .Instance)) { object n = null; list[i] = (T)n; } else { return(Array.Empty <T>()); } } return(list); }
public static bool SigListEquals(IList <TypeSig> x, IList <TypeSig> y) { if (x == null && y == null) { return(true); } if (x == null || y == null) { return(false); } if (x.Count != y.Count) { return(false); } var comparer = new SigComparer(); for (int i = 0; i < x.Count; ++i) { if (!comparer.Equals(x[i], y[i])) { return(false); } } return(true); }
IEnumerable <MethodDef> AnalyzeType(TypeDef type) { var comparer = new SigComparer(SigComparerOptions.CompareMethodFieldDeclaringType); foreach (var method in type.Methods) { if (!method.HasBody) { continue; } foreach (var instr in method.Body.Instructions) { switch (instr.OpCode.Code) { case Code.Stfld: case Code.Stsfld: case Code.Ldflda: // Taking address of field -> potentially assign indirectly case Code.Ldsflda: break; default: continue; } if (instr.Operand is IField && comparer.Equals((IField)instr.Operand, Item)) { yield return(method); break; } } } }
TypeRef TryResolveType(TypeRef sourceRef, AssemblyRef scope, bool followForward) { if (scope == null) { return(null); } var typeRef = Import2(sourceRef, scope); var scopeDef = TargetModule.Context.AssemblyResolver.Resolve(typeRef.DefinitionAssembly, TargetModule); if (scopeDef != null) { if (scopeDef.TypeExists(typeRef)) { return(typeRef); } var sigComparer = new SigComparer(SigComparerOptions.DontCompareTypeScope); var exportType = scopeDef.Modules.SelectMany(m => m.ExportedTypes).Where(et => sigComparer.Equals(et, typeRef)).FirstOrDefault(); if (exportType != null) { if (followForward && (corelibRef == null || exportType.Implementation.Name != corelibRef.Name)) { return(exportType.ToTypeRef()); } else { return(typeRef); } } } return(null); }
/// <summary> /// Checks if there's a constructor matching the specified signature /// in the source type or among the to-be-injected members /// </summary> /// <param name="sig">constructor signature</param> /// <returns>true if the matching constructor is found, false otherwise</returns> public bool HasInstanceCtor(MethodSig sig) { var sc = new SigComparer(); return(TypeMapping.Source.FindInstanceConstructors() .Concat(Injected.OfType <MethodDef>().Where(m => m.IsInstanceConstructor)) .Any(c => sc.Equals(c.MethodSig, sig))); }
IEnumerable <IMemberDef> AnalyzeType(TypeDef type) { var comparer = new SigComparer(SigComparerOptions.CompareMethodFieldDeclaringType); if (comparer.Equals(type.BaseType, Item)) { yield return(type); } else if (type.Interfaces.Any(iface => comparer.Equals(iface.Interface, Item))) { yield return(type); } foreach (var method in type.Methods) { if (method.Parameters.Any(param => comparer.Equals(param.Type, Item))) { yield return(method); continue; } if (comparer.Equals(method.ReturnType, Item)) { yield return(method); continue; } if (!method.HasBody) { continue; } if (method.Body.Variables.Any(var => comparer.Equals(var.Type, Item))) { yield return(method); continue; } foreach (var instr in method.Body.Instructions) { if (instr.Operand is ITypeDefOrRef && comparer.Equals((ITypeDefOrRef)instr.Operand, Item)) { yield return(method); break; } else if (instr.Operand is IMemberRef && comparer.Equals(((IMemberRef)instr.Operand).DeclaringType, Item)) { yield return(method); break; } } } }
static VTableSlot ResolveSlot(TypeDef openType, VTableSlot slot, IList <TypeSig> genArgs) { MethodSig newSig = GenericArgumentResolver.Resolve(slot.Signature.MethodSig, genArgs); TypeSig newDecl = slot.MethodDefDeclType; newDecl = new SigComparer().Equals(newDecl, openType) ? new GenericInstSig((ClassOrValueTypeSig)openType.ToTypeSig(), genArgs.ToArray()) : GenericArgumentResolver.Resolve(newDecl, genArgs); return(new VTableSlot(newDecl, slot.MethodDef, slot.DeclaringType, new VTableSignature(newSig, slot.Signature.Name), slot.Overrides)); }
public override int GetHashCode() { var comparer = new SigComparer(); int hashCode = this.Flags; foreach (ITypeDefOrRef param in this.ParamSigs) { hashCode = (hashCode * 7) + comparer.GetHashCode(param); } return((hashCode * 7) + comparer.GetHashCode(this.RetType)); }
public override int GetHashCode() { var comparer = new SigComparer(); int hashCode = Flags; foreach (var param in ParamSigs) { hashCode = (hashCode * 7) + comparer.GetHashCode(param); } return((hashCode * 7) + comparer.GetHashCode(RetType)); }
static bool Impl(MethodDef method, MethodDef ifaceMethod) { if (method.HasOverrides) { var comparer = new SigComparer(SigComparerOptions.CompareDeclaringTypes | SigComparerOptions.PrivateScopeIsComparable); if (method.Overrides.Any(m => comparer.Equals(m.MethodDeclaration, ifaceMethod))) return true; } if (method.Name != ifaceMethod.Name) return false; return TypesHierarchyHelpers.MatchInterfaceMethod(method, ifaceMethod, ifaceMethod.DeclaringType); }
/// <summary> /// Find all references to a TypeDef and replace them with another TypeDef. /// Note that field and method references from the source TypeDef will also need to be replaced serparately. /// </summary> public static void ReplaceAllTypeDefReferences(TypeDef sourceTypeDef, TypeDef destinationTypeDef, ModuleDefMD moduleDefMd) { var types = moduleDefMd.GetTypes(); var sourceTypeSig = sourceTypeDef.ToTypeSig(); var destinationTypeSig = destinationTypeDef.ToTypeSig(); var sigComparer = new SigComparer(); foreach (var type in types) { // Fields foreach (var field in type.Fields) { if (sigComparer.Equals(field.FieldType, sourceTypeSig)) { field.FieldType = destinationTypeSig; } } // Methods foreach (var method in type.Methods) { if (method.Body == null) { continue; } foreach (var instruction in method.Body.Instructions) { if (instruction.Operand != null) { if (instruction.Operand is MethodSpec methodSpec && methodSpec.GenericInstMethodSig != null) { // Replace generic parameter types for (var i = methodSpec.GenericInstMethodSig.GenericArguments.Count - 1; i >= 0; i--) { var genericArgument = methodSpec.GenericInstMethodSig.GenericArguments[i]; var genericArgumentTypeSpec = genericArgument as TypeSig; if (sigComparer.Equals(genericArgumentTypeSpec, sourceTypeSig)) { methodSpec.GenericInstMethodSig.GenericArguments.RemoveAt(i); methodSpec.GenericInstMethodSig.GenericArguments.Insert(i, destinationTypeSig); } } // Todo: Parameters // Todo: Return types. } } } } } }
/// <summary> /// Finds all custom attributes of a certain type /// </summary> /// <param name="attrType">Custom attribute type</param> /// <param name="options">Attribute type comparison flags</param> /// <returns>All <see cref="CustomAttribute"/>s of the requested type</returns> public IEnumerable <CustomAttribute> FindAll(IType attrType, SigComparerOptions options) { var comparer = new SigComparer(options); foreach (var ca in this.GetSafeEnumerable()) { if (comparer.Equals(ca.AttributeType, attrType)) { yield return(ca); } } }
/// <summary> /// Finds a custom attribute /// </summary> /// <param name="attrType">Custom attribute type</param> /// <param name="options">Attribute type comparison flags</param> /// <returns>The first <see cref="CustomAttribute"/> found or <c>null</c> if none found</returns> public CustomAttribute Find(IType attrType, SigComparerOptions options) { var comparer = new SigComparer(options); foreach (var ca in this.GetSafeEnumerable()) { if (comparer.Equals(ca.AttributeType, attrType)) { return(ca); } } return(null); }
TypeDef FindSlow(TypeRef typeRef) { InitializeTypeEnumerator(); var comparer = new SigComparer(TypeComparerOptions); while (true) { var type = GetNextTypeDef(); if (type == null || comparer.Equals(type, typeRef)) { return(type); } } }
public bool IsAttachedTo(XamlType type) { if (type == null || ResolvedMember == null || type.ResolvedType == null) return true; var declType = ResolvedMember.DeclaringType; var t = type.ResolvedType; var comparer = new SigComparer(); do { if (comparer.Equals(t, declType)) return false; t = t.GetBaseType(); } while (t != null); return true; }
/// <summary> /// Get the real decrypter method from a found helper method. /// </summary> /// <remarks>5.0</remarks> static MethodDef GetRealDecrypterMethod(MethodDef helper) { var methods = helper.DeclaringType.Methods; var sigComparer = new SigComparer(); foreach (var method in methods) { if (method.MDToken != helper.MDToken && method.IsAssembly && sigComparer.Equals(method.MethodSig, helper.MethodSig)) { return(method); } } return(null); }
static bool Impl(MethodDef method, MethodDef ifaceMethod) { if (method.HasOverrides) { var comparer = new SigComparer(SigComparerOptions.CompareDeclaringTypes | SigComparerOptions.PrivateScopeIsComparable); if (method.Overrides.Any(m => comparer.Equals(m.MethodDeclaration, ifaceMethod))) { return(true); } } if (method.Name != ifaceMethod.Name) { return(false); } return(TypesHierarchyHelpers.MatchInterfaceMethod(method, ifaceMethod, ifaceMethod.DeclaringType)); }
public IEnumerable <object> Run(IApp app, CancellationToken token) { if (typeDef == null) { yield return(new AnalysisError("Failed to resolve '" + type.FullName + "'.")); yield break; } var comparer = new SigComparer(); if (typeDef.IsInterface) { foreach (var type in app.Modules.GetModules().SelectMany(module => module.GetTypes())) { token.ThrowIfCancellationRequested(); if (!type.HasInterfaces) { continue; } foreach (var iface in type.Interfaces) { if (comparer.Equals(iface.Interface, typeDef)) { yield return(type); } } } } else { foreach (var type in app.Modules.GetModules().SelectMany(module => module.GetTypes())) { token.ThrowIfCancellationRequested(); if (comparer.Equals(type.BaseType, typeDef)) { yield return(type); } } } }
private static bool IsMatchingOverride(MethodOverride methodOverride, IMethodDefOrRef targetMethod) { SigComparer comparer = default; var targetDeclTypeDef = targetMethod.DeclaringType.ResolveTypeDef(); var overrideDeclTypeDef = methodOverride.MethodDeclaration.DeclaringType.ResolveTypeDef(); if (!comparer.Equals(targetDeclTypeDef, overrideDeclTypeDef)) { return(false); } var targetMethodSig = targetMethod.MethodSig; var overrideMethodSig = methodOverride.MethodDeclaration.MethodSig; targetMethodSig = ResolveGenericSignature(targetMethod, targetMethodSig); overrideMethodSig = ResolveGenericSignature(methodOverride.MethodDeclaration, overrideMethodSig); return(comparer.Equals(targetMethodSig, overrideMethodSig)); }
TypeDef FindCache(TypeRef typeRef) { TypeDef cachedType; if (typeRefCache.TryGetValue(typeRef, out cachedType)) { return(cachedType); } // Build the cache lazily var comparer = new SigComparer(TypeComparerOptions); while (true) { cachedType = GetNextTypeDefCache(); if (cachedType == null || comparer.Equals(cachedType, typeRef)) { return(cachedType); } } }
public bool IsAttachedTo(XamlType type) { if (type is null || ResolvedMember is null || type.ResolvedType is null) { return(true); } var declType = ResolvedMember.DeclaringType; var t = type.ResolvedType; var comparer = new SigComparer(); do { if (comparer.Equals(t, declType)) { return(false); } t = t.GetBaseType(); } while (!(t is null)); return(true); }
object ConvertEnum <T>(TypeSig elemType, IList <CAArgument> oldList) { var ary = ConvertArray <EnumInfo>(elemType, oldList); var list = new T[ary.Length]; var sigComparer = new SigComparer(SigComparerOptions.CompareAssemblyPublicKeyToken); for (int i = 0; i < list.Length; i++) { if (ary[i].Value is T && sigComparer.Equals(elemType, ary[i].EnumType)) { list[i] = (T)ary[i].Value; } } return(new EnumInfo { EnumType = elemType.ToTypeDefOrRef(), Value = list, IsArray = true, }); }
public override bool Equals(object obj) { if (!(obj is FuncSig other) || other.Flags != this.Flags) { return(false); } if (other.ParamSigs.Length != this.ParamSigs.Length) { return(false); } var comparer = new SigComparer(); for (int i = 0; i < this.ParamSigs.Length; i++) { if (!comparer.Equals(this.ParamSigs[i], other.ParamSigs[i])) { return(false); } } return(!comparer.Equals(this.RetType, other.RetType) ? false : true); }
IEnumerable <MethodDef> AnalyzeType(TypeDef type) { var comparer = new SigComparer(SigComparerOptions.CompareMethodFieldDeclaringType); foreach (var method in type.Methods) { if (!method.HasBody) { continue; } foreach (var instr in method.Body.Instructions) { if (instr.Operand is IMethod && comparer.Equals((IMethod)instr.Operand, Item)) { yield return(method); break; } } } }
private static bool IsMatchingOverride(MethodOverride methodOverride, IMethodDefOrRef targetMethod) { SigComparer comparer = default; var targetDeclTypeDef = targetMethod.DeclaringType.ResolveTypeDef(); var overrideDeclTypeDef = methodOverride.MethodDeclaration.DeclaringType.ResolveTypeDef(); if (!comparer.Equals(targetDeclTypeDef, overrideDeclTypeDef)) { return(false); } var targetMethodSig = targetMethod.MethodSig; var overrideMethodSig = methodOverride.MethodDeclaration.MethodSig; if (methodOverride.MethodDeclaration.DeclaringType is TypeSpec spec && spec.TypeSig is GenericInstSig genericInstSig) { overrideMethodSig = GenericArgumentResolver.Resolve(overrideMethodSig, genericInstSig.GenericArguments); } return(comparer.Equals(targetMethodSig, overrideMethodSig)); }
public override int GetHashCode() { int hash = new SigComparer().GetHashCode(InterfaceType); hash = hash * 7 + new SigComparer().GetHashCode(MethodSig); return hash * 7 + Name.GetHashCode(); }
public MosaMethod LoadGenericMethodInstance(IMethodDefOrRef method, IList <TypeSig> genericArguments, GenericArgumentResolver resolver) { var declType = GetType(resolver.Resolve(method.DeclaringType.ToTypeSig())); MDToken token; if (method is MethodDef) { token = ((MethodDef)method).MDToken; } else { token = ((MemberRef)method).ResolveMethodThrow().MDToken; } MosaMethod mosaMethod = null; UnitDesc <MethodDef, MethodSig> desc = null; foreach (var m in declType.Methods) { desc = m.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >(); if (desc.Token.Token == token) { mosaMethod = m; break; } } if (mosaMethod == null) { throw new AssemblyLoadException(); } var genericArgs = new List <TypeSig>(); foreach (var genericArg in genericArguments) { genericArgs.Add(resolver.Resolve(genericArg)); } resolver.PushMethodGenericArguments(genericArgs); // Check for existing generic method instance var newSig = resolver.Resolve(method.MethodSig); // Need to make sure we pop otherwise it will cause bugs resolver.PopMethodGenericArguments(); var comparer = new SigComparer(); foreach (var m in declType.Methods) { var mDesc = m.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >(); if (mDesc.Definition != desc.Definition || !comparer.Equals(mDesc.Signature, newSig)) { continue; } if (newSig.ContainsGenericParameter || newSig.GenParamCount > 0) { continue; } if (m.GenericArguments.Count != genericArgs.Count) { continue; } if (m.GenericArguments.Count > 0) { var failedGenericArgumentMatch = false; for (var i = 0; i < m.GenericArguments.Count; i++) { if (comparer.Equals(genericArguments[i], m.GenericArguments[i].GetTypeSig())) { continue; } failedGenericArgumentMatch = true; break; } if (failedGenericArgumentMatch) { continue; } } return(m); } mosaMethod = metadata.Controller.CreateMethod(mosaMethod); using (var _mosaMethod = metadata.Controller.MutateMethod(mosaMethod)) { bool hasOpening = mosaMethod.DeclaringType.HasOpenGenericParams; foreach (var genericArg in genericArgs) { hasOpening |= genericArg.HasOpenGenericParameter(); var t = GetType(genericArg); if (!_mosaMethod.GenericArguments.Contains(t)) { _mosaMethod.GenericArguments.Add(t); } } _mosaMethod.UnderlyingObject = desc.Clone(newSig); _mosaMethod.DeclaringType = declType; _mosaMethod.HasOpenGenericParams = hasOpening; } using (var decl = metadata.Controller.MutateType(declType)) decl.Methods.Add(mosaMethod); metadata.Resolver.EnqueueForResolve(mosaMethod); return(mosaMethod); }
TypeDef FindSlow(TypeRef typeRef) { InitializeTypeEnumerator(); var comparer = new SigComparer { Options = TypeComparerOptions }; while (true) { var type = GetNextTypeDef(); if (type == null || comparer.Equals(type, typeRef)) return type; } }
TypeDef FindCache(TypeRef typeRef) { TypeDef cachedType; if (typeRefCache.TryGetValue(typeRef, out cachedType)) return cachedType; // Build the cache lazily var comparer = new SigComparer { Options = TypeComparerOptions }; while (true) { cachedType = GetNextTypeDefCache(); if (cachedType == null || comparer.Equals(cachedType, typeRef)) return cachedType; } }
/// <summary> /// Get the real decrypter method from a found helper method. /// </summary> /// <remarks>5.0</remarks> static MethodDef GetRealDecrypterMethod(MethodDef helper) { var methods = helper.DeclaringType.Methods; var sigComparer = new SigComparer(); foreach (var method in methods) { if (method.MDToken != helper.MDToken && method.IsAssembly && sigComparer.Equals(method.MethodSig, helper.MethodSig)) return method; } return null; }
public bool Equals(Instruction x, Instruction y) { var sigComparer = new SigComparer(); if (x != null && y != null && x.OpCode == y.OpCode) { if (x.Operand == null && y.Operand == null) { return(true); } if (x.Operand is FieldDef xFieldDef && y.Operand is FieldDef yFieldDef) { return(sigComparer.Equals(xFieldDef, yFieldDef)); } if (x.Operand is MemberRef xMemberRef && y.Operand is MemberRef yMemberRef) { return(sigComparer.Equals(xMemberRef, yMemberRef)); } if (x.Operand is IField xIField && y.Operand is IField yIField) { return(sigComparer.Equals(xIField, yIField)); } if (x.Operand is MethodSpec xMethodSpec && y.Operand is MethodSpec yMethodSpec) { return(sigComparer.Equals(xMethodSpec, yMethodSpec)); } if (x.Operand is MethodDef xMethodDef && y.Operand is MethodDef yMethodDef) { return(sigComparer.Equals(xMethodDef, yMethodDef)); } if (x.Operand is IMethod xIMethod && y.Operand is IMethod yIMethod) { return(sigComparer.Equals(xIMethod, yIMethod)); } if (x.Operand is TypeSpec xTypeSpec && y.Operand is TypeSpec yTypeSpec) { return(sigComparer.Equals(xTypeSpec, yTypeSpec)); } if (x.Operand is TypeSig xTypeSig && y.Operand is TypeSig yTypeSig) { return(sigComparer.Equals(xTypeSig, yTypeSig)); } if (x.Operand is MethodSig xMethodSig && y.Operand is MethodSig yMethodSig) { return(sigComparer.Equals(xMethodSig, yMethodSig)); } if (x.Operand is TypeRef xTypeRef && y.Operand is TypeRef yTypeRef) { return(sigComparer.Equals(xTypeRef, yTypeRef)); } if (x.Operand is TypeDef xTypeDef && y.Operand is TypeDef yTypeDef) { return(sigComparer.Equals(xTypeDef, yTypeDef)); } if (x.Operand is FieldSig xFieldSig && y.Operand is FieldSig yFieldSig) { return(sigComparer.Equals(xFieldSig, yFieldSig)); } if (x.Operand is ITypeDefOrRef xITypeDefOrRef && y.Operand is ITypeDefOrRef yITypeDefOrRef) { return(sigComparer.Equals(xITypeDefOrRef, yITypeDefOrRef)); } if (x.Operand is GenericInstMethodSig xGenericInstMethodSig && y.Operand is GenericInstMethodSig yGenericInstMethodSig) { return(sigComparer.Equals(xGenericInstMethodSig, yGenericInstMethodSig)); } if (x.Operand is IMemberRef xIMemberRef && y.Operand is IMemberRef yIMemberRef) { return(sigComparer.Equals(xIMemberRef, yIMemberRef)); } if (x.Operand is IType xIType && y.Operand is IType yIType) { return(sigComparer.Equals(xIType, yIType)); } if (x.Operand is EventDef xEventDef && y.Operand is EventDef yEventDef) { return(sigComparer.Equals(xEventDef, yEventDef)); } if (x.Operand is PropertyDef xPropertyDef && y.Operand is PropertyDef yPropertyDef) { return(sigComparer.Equals(xPropertyDef, yPropertyDef)); } if (x.Operand is ExportedType xExportedType && y.Operand is ExportedType yExportedType) { return(sigComparer.Equals(xExportedType, yExportedType)); } if (x.Operand is LocalSig xLocalSig && y.Operand is LocalSig yLocalSig) { return(sigComparer.Equals(xLocalSig, yLocalSig)); } if (x.Operand is IList <TypeSig> xIList && y.Operand is IList <TypeSig> yIList) { return(sigComparer.Equals(xIList, yIList)); } if (x.Operand is MethodBaseSig xMethodBaseSig && y.Operand is MethodBaseSig yMethodBaseSig) { return(sigComparer.Equals(xMethodBaseSig, yMethodBaseSig)); } if (x.Operand is CallingConventionSig xCallingConventionSig && y.Operand is CallingConventionSig yCallingConventionSig) { return(sigComparer.Equals(xCallingConventionSig, yCallingConventionSig)); } return(x.Operand == y.Operand); } return(false); }
public MosaMethod LoadGenericMethodInstance(IMethodDefOrRef method, IList <TypeSig> genericArguments, GenericArgumentResolver resolver) { MosaType declType = GetType(resolver.Resolve(method.DeclaringType.ToTypeSig())); MDToken token; if (method is MethodDef) { token = ((MethodDef)method).MDToken; } else { token = ((MemberRef)method).ResolveMethodThrow().MDToken; } MosaMethod mosaMethod = null; UnitDesc <MethodDef, MethodSig> desc = null; foreach (var m in declType.Methods) { desc = m.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >(); if (desc.Token.Token == token) { mosaMethod = m; break; } } if (mosaMethod == null) { throw new AssemblyLoadException(); } List <TypeSig> genericArgs = new List <TypeSig>(); foreach (var genericArg in genericArguments) { genericArgs.Add(resolver.Resolve(genericArg)); } resolver.PushMethodGenericArguments(genericArgs); // Check for existing generic method instance var newSig = resolver.Resolve(method.MethodSig); var comparer = new SigComparer(); foreach (var m in declType.Methods) { var mDesc = m.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >(); if (mDesc.Definition == desc.Definition && comparer.Equals(mDesc.Signature, newSig)) { return(m); } } mosaMethod = metadata.Controller.CreateMethod(mosaMethod); using (var _mosaMethod = metadata.Controller.MutateMethod(mosaMethod)) { bool hasOpening = mosaMethod.DeclaringType.HasOpenGenericParams; foreach (var genericArg in genericArguments) { var newGenericArg = resolver.Resolve(genericArg); hasOpening |= newGenericArg.HasOpenGenericParameter(); _mosaMethod.GenericArguments.Add(GetType(newGenericArg)); } _mosaMethod.UnderlyingObject = desc.Clone(newSig); _mosaMethod.DeclaringType = declType; _mosaMethod.HasOpenGenericParams = hasOpening; } resolver.PopMethodGenericArguments(); using (var decl = metadata.Controller.MutateType(declType)) decl.Methods.Add(mosaMethod); metadata.Resolver.EnqueueForResolve(mosaMethod); return(mosaMethod); }