private static bool MatchesGeneric(this MethodMember methodMember, MethodReference methodReference) { var referenceFullName = methodReference.GetElementMethod().GetFullName(); var memberFullName = methodMember.FullName; var count = methodReference.GetElementMethod().GenericParameters.Count; if (methodMember.GenericParameters.Count != count) { return(false); } var parameters = new List <GenericParameter[]>(); for (var i = 0; i < count; i++) { parameters.Add(new[] { new GenericParameter(methodReference.GetElementMethod().GenericParameters[i].Name), methodMember.GenericParameters[i] }); } parameters = parameters.OrderByDescending(genericParameters => genericParameters[0].Name.Length).ToList(); foreach (var genericParameters in parameters.Where(genericParameters => genericParameters[0] != null) ) { referenceFullName = referenceFullName.Replace(genericParameters[0].Name, genericParameters[1].Name); memberFullName = memberFullName.Replace(genericParameters[0].Name, genericParameters[1].Name); } return(memberFullName.Equals(referenceFullName)); }
public static string GetGenericIdValue(MethodReference methodDefinition) { var spaceIndex = methodDefinition.FullName.IndexOf(" ", StringComparison.Ordinal); var signature = methodDefinition.FullName.Substring(spaceIndex + 1); var genericTypeMarkerIndex = signature.IndexOf("`", StringComparison.Ordinal); if (genericTypeMarkerIndex > -1) // is a method of a generic type and needs special logic { // has generic param but not a generic method var twoDotsIndex = signature.IndexOf("::", StringComparison.Ordinal); if (twoDotsIndex < genericTypeMarkerIndex) { if (methodDefinition.CallingConvention == MethodCallingConvention.Generic) // generic method { var elementMethod = methodDefinition.GetElementMethod().FullName; elementMethod = TypeService.ReplaceGenericPlaceholders(elementMethod); spaceIndex = elementMethod.IndexOf(" ", StringComparison.Ordinal); signature = elementMethod.Substring(spaceIndex + 1); return(signature); } return(string.Empty); } // extra generic types of method name if (signature.IndexOf("!") > -1) { try { signature = TypeService.ReplaceGenericPlaceholders(signature); var fullNameWithGenTypes = signature.Substring(0, genericTypeMarkerIndex + 2) + signature.Substring(twoDotsIndex); return(fullNameWithGenTypes); } catch (Exception ex) { } } return(string.Empty); } else if (methodDefinition.CallingConvention == MethodCallingConvention.Generic) // generic method { var elementMethod = methodDefinition.GetElementMethod().FullName; elementMethod = TypeService.ReplaceGenericPlaceholders(elementMethod); spaceIndex = elementMethod.IndexOf(" ", StringComparison.Ordinal); signature = elementMethod.Substring(spaceIndex + 1); return(signature); } return(string.Empty); }
public MethodDefinition Resolve(MethodReference method) { TypeDefinition type = Resolve(method.DeclaringType); method = method.GetElementMethod(); return(GetMethod(type, method)); }
public MethodDefinition Resolve(MethodReference method) { var type = Resolve(method.DeclaringType); if (type == null) { return(null); } method = method.GetElementMethod(); if (!type.HasMethods) { throw new Exception("Metadata resolver--type has no methods!"); } var result = GetMethod(type, method); if (result != null) { if (result.Module.MetadataResolver != this) { throw new Exception("Can't be."); } return(result); } return(result); }
/// <summary>Rewrite a method reference if needed.</summary> /// <param name="methodRef">The current method reference.</param> private bool RewriteMethodReference(MethodReference methodRef) { bool rewritten = false; rewritten |= this.RewriteTypeReference(methodRef.DeclaringType, newType => { // note: generic methods are wrapped into a MethodSpecification which doesn't allow changing the // declaring type directly. For our purposes we want to change all generic versions of a matched // method anyway, so we can use GetElementMethod to get the underlying method here. methodRef.GetElementMethod().DeclaringType = newType; }); rewritten |= this.RewriteTypeReference(methodRef.ReturnType, newType => methodRef.ReturnType = newType); foreach (var parameter in methodRef.Parameters) { rewritten |= this.RewriteTypeReference(parameter.ParameterType, newType => parameter.ParameterType = newType); } if (methodRef is GenericInstanceMethod genericRef) { for (int i = 0; i < genericRef.GenericArguments.Count; i++) { rewritten |= this.RewriteTypeReference(genericRef.GenericArguments[i], newType => genericRef.GenericArguments[i] = newType); } } return(rewritten); }
private StaticConstructorWrapper WrapConstructor(MethodReference methodRefHandle) { var declaringType = MakeDeclaredType(methodRefHandle.DeclaringType); var declaringTypeDefnHandle = (TypeDefinition)declaringType.Handle; var methodDefnHandle = FindMatchingMethod(methodRefHandle.GetElementMethod(), GetConstructors(declaringTypeDefnHandle.Methods)); return(new StaticConstructorWrapper(this, methodDefnHandle, declaringType)); }
/********* ** Private methods *********/ /// <summary>Rewrite a CIL instruction if needed.</summary> /// <param name="instruction">The current CIL instruction.</param> /// <param name="cil">The CIL instruction processor.</param> /// <param name="replaceWith">Replaces the CIL instruction with a new one.</param> private bool RewriteInstruction(Instruction instruction, ILProcessor cil, Action <Instruction> replaceWith) { bool rewritten = false; // field reference FieldReference fieldRef = RewriteHelper.AsFieldReference(instruction); if (fieldRef != null) { rewritten |= this.RewriteTypeReference(fieldRef.DeclaringType, newType => fieldRef.DeclaringType = newType); rewritten |= this.RewriteTypeReference(fieldRef.FieldType, newType => fieldRef.FieldType = newType); } // method reference MethodReference methodRef = RewriteHelper.AsMethodReference(instruction); if (methodRef != null) { rewritten |= this.RewriteTypeReference(methodRef.DeclaringType, newType => { // note: generic methods are wrapped into a MethodSpecification which doesn't allow changing the // declaring type directly. For our purposes we want to change all generic versions of a matched // method anyway, so we can use GetElementMethod to get the underlying method here. methodRef.GetElementMethod().DeclaringType = newType; }); rewritten |= this.RewriteTypeReference(methodRef.ReturnType, newType => methodRef.ReturnType = newType); foreach (var parameter in methodRef.Parameters) { rewritten |= this.RewriteTypeReference(parameter.ParameterType, newType => parameter.ParameterType = newType); } if (methodRef is GenericInstanceMethod genericRef) { for (int i = 0; i < genericRef.GenericArguments.Count; i++) { rewritten |= this.RewriteTypeReference(genericRef.GenericArguments[i], newType => genericRef.GenericArguments[i] = newType); } } } // type reference if (instruction.Operand is TypeReference typeRef) { rewritten |= this.RewriteTypeReference(typeRef, newType => replaceWith(cil.Create(instruction.OpCode, newType))); } // instruction itself // (should be done after the above type rewrites to ensure valid types) rewritten |= this.RewriteInstructionImpl(instruction, cil, newInstruction => { rewritten = true; cil.Replace(instruction, newInstruction); instruction = newInstruction; }); return(rewritten); }
private MethodReference CloneMethodWithDeclaringType(MethodReference methodRef, TypeReference declaringTypeRef) { // If the input method reference is generic, it will be wrapped in a GenericInstanceMethod object var genericRef = methodRef as GenericInstanceMethod; if (genericRef != null) { // The actual method data we need to replicate is the ElementMethod // Replace the method reference with the element method from the generic wrapper methodRef = methodRef.GetElementMethod(); } // Build a new method reference that matches the original exactly, but with a different declaring type var newRef = new MethodReference(methodRef.Name, methodRef.ReturnType, declaringTypeRef) { CallingConvention = methodRef.CallingConvention, HasThis = methodRef.HasThis, ExplicitThis = methodRef.ExplicitThis, MethodReturnType = methodRef.MethodReturnType, }; // Clone method input parameters foreach (var p in methodRef.Parameters) { newRef.Parameters.Add(new ParameterDefinition(p.Name, p.Attributes, p.ParameterType)); } // Clone method generic parameters foreach (var p in methodRef.GenericParameters) { newRef.GenericParameters.Add(new GenericParameter(p.Name, newRef)); } if (genericRef == null) { // For non-generic methods, we can simply return the new method reference return(newRef); } else { // For generic methods, copy the generic arguments into the new method refernce var newGenericRef = new GenericInstanceMethod(newRef); foreach (var typeDef in genericRef.GenericArguments) { newGenericRef.GenericArguments.Add(typeDef); } // Done return(newGenericRef); } }
private StaticMethodWrapper WrapMethod(MethodReference methodRefHandle) { var declaringType = MakeDeclaredType(methodRefHandle.DeclaringType); var declaringTypeDefnHandle = (TypeDefinition)declaringType.Handle; var methodDefnHandle = FindMatchingMethod(methodRefHandle.GetElementMethod(), declaringTypeDefnHandle.Methods); var method = new StaticMethodWrapper(this, methodDefnHandle, declaringType, declaringType, declaringType.Substitution); var genericInstance = methodRefHandle as GenericInstanceMethod; if (genericInstance != null) { var genericArguments = CollectionUtils.ConvertAllToArray <TypeReference, ITypeInfo>(genericInstance.GenericArguments, MakeType); method = method.MakeGenericMethod(genericArguments); } return(method); }
public IMethod Resolve(MethodReference methodReference) { if (methodReference == null) { throw new ArgumentNullException(nameof(methodReference)); } lock (methodLookupCache) { IMethod method; if (!methodLookupCache.TryGetValue(methodReference, out method)) { method = FindNonGenericMethod(methodReference.GetElementMethod()); if (method == null) { method = CreateFakeMethod(methodReference); } if (methodReference.CallingConvention == MethodCallingConvention.VarArg) { method = new VarArgInstanceMethod( method, methodReference.Parameters.SkipWhile(p => !p.ParameterType.IsSentinel).Select(p => Resolve(p.ParameterType)) ); } else if (methodReference.IsGenericInstance || methodReference.DeclaringType.IsGenericInstance) { IList <IType> classTypeArguments = null; IList <IType> methodTypeArguments = null; if (methodReference.IsGenericInstance) { var gim = ((GenericInstanceMethod)methodReference); methodTypeArguments = gim.GenericArguments.SelectArray(Resolve); } if (methodReference.DeclaringType.IsGenericInstance) { var git = (GenericInstanceType)methodReference.DeclaringType; classTypeArguments = git.GenericArguments.SelectArray(Resolve); } method = method.Specialize(new TypeParameterSubstitution(classTypeArguments, methodTypeArguments)); } methodLookupCache.Add(methodReference, method); } return(method); } }
public virtual MethodDefinition ResolveMethod(MethodReference methodRef) { var declaringType = ResolveType(methodRef.DeclaringType); methodRef = methodRef.GetElementMethod(); if (declaringType != null && declaringType.HasMethods) { foreach (var method in declaringType.Methods) { if (MethodRefsAreEqual(method, methodRef)) { return(method); } } } return(null); }
/// <summary> /// Check the given method reference. /// </summary> private void Check(MethodReference method, string context) { if (!Check(method.DeclaringType, context)) { return; } var error = false; try { if (method.IsGenericInstance) { Check((GenericInstanceMethod)method, context); } else { var typeDef = method.DeclaringType.GetElementType().Resolve(); var emethod = method.GetElementMethod(); var methodDef = (typeDef != null) ? typeDef.Methods.FirstOrDefault(x => x.AreSameExcludingGenericArguments(emethod, null)) : null; error = (methodDef == null); } } catch (Exception) { error = true; } CheckResolveData data; var key = method.FullName; if (!resolveErrorMethodNames.TryGetValue(key, out data)) { data = new CheckResolveData { IsAvailable = !error }; resolveErrorMethodNames.Add(key, data); if (error) { Error(MessageTypes.MissingMethod, Format(method, false), method.DeclaringType.Scope, context); } } data.CheckCount++; }
private MethodDefinition ResolveManually(MethodReference method) { var metadataResolver = method.Module.MetadataResolver; var type = metadataResolver.Resolve(method.DeclaringType); if (type == null || !type.HasMethods) { return(null); } method = method.GetElementMethod(); Func <IEnumerable <MethodDefinition>, MethodReference, MethodDefinition>[] finderMethods = { GetMethodDefinition, GetCompatibleMethodDefinition }; for (int i = 0; i < finderMethods.Length; i++) { while (type != null) { var methodDefinition = finderMethods[i](type.Methods, method); if (methodDefinition != null) { return(methodDefinition); } if (type.BaseType == null) { break; } type = metadataResolver.Resolve(type.BaseType); } type = metadataResolver.Resolve(method.DeclaringType); } return(null); }
private static ulong GetToken(MethodReference method) { return((ulong)method.DeclaringType.Module.Assembly.GetHashCode() << 32 | method.GetElementMethod().MetadataToken.ToUInt32()); }
private MethodMemberInstance CreateMethodMemberFromMethodReference( [NotNull] ITypeInstance <IType> typeInstance, [NotNull] MethodReference methodReference) { if (methodReference.IsGenericInstance) { var elementMethod = CreateMethodMemberFromMethodReference(typeInstance, methodReference.GetElementMethod()).Member; var genericInstanceMethod = (GenericInstanceMethod)methodReference; var genericArguments = genericInstanceMethod.GenericArguments .Select(CreateGenericArgumentFromTypeReference) .Where(argument => !argument.Type.IsCompilerGenerated); return(new MethodMemberInstance(elementMethod, typeInstance.GenericArguments, genericArguments)); } var returnTypeReference = methodReference.ReturnType; var returnType = GetOrCreateStubTypeInstanceFromTypeReference(returnTypeReference); var name = methodReference.BuildMethodMemberName(); var fullName = methodReference.BuildFullName(); var isGeneric = methodReference.HasGenericParameters; var isCompilerGenerated = methodReference.IsCompilerGenerated(); MethodForm methodForm; Visibility visibility; bool isStub; MethodDefinition methodDefinition; try { methodDefinition = methodReference.Resolve(); } catch (AssemblyResolutionException) { methodDefinition = null; } if (methodDefinition == null) { visibility = Public; methodForm = methodReference.HasConstructorName() ? MethodForm.Constructor : MethodForm.Normal; isStub = true; } else { visibility = methodDefinition.GetVisibility(); methodForm = methodDefinition.GetMethodForm(); isStub = false; } var methodMember = new MethodMember(name, fullName, typeInstance.Type, visibility, returnType, false, methodForm, isGeneric, isStub, isCompilerGenerated); var parameters = methodReference.GetParameters(this).ToList(); methodMember.ParameterInstances.AddRange(parameters); var genericParameters = GetGenericParameters(methodReference); methodMember.GenericParameters.AddRange(genericParameters); return(new MethodMemberInstance(methodMember, typeInstance.GenericArguments, Enumerable.Empty <GenericArgument>())); }
private bool TryToResolveInSupport(MethodReference method) { if (string.IsNullOrEmpty(Context.SupportModulePartialNamespace)) { return(false); } method = method.GetElementMethod(); var originalType = method.DeclaringType; if (originalType.IsGenericInstance || originalType.HasGenericParameters) { return(false); } var support = SupportAssemblyReference(); var ns = Context.SupportModulePartialNamespace; if (!string.IsNullOrEmpty(originalType.Namespace)) { ns += '.' + originalType.Namespace; } method.DeclaringType = new TypeReference(ns, originalType.Name, Context.TargetModule, support, originalType.IsValueType); MethodDefinition resolved = null; // We can only change declaring type like this for static methods if (!method.HasThis) { resolved = method.Resolve(); } // If our method is instance, we can have a static method in support module that has explicit "this" parameter if (resolved == null && method.HasThis) { method.HasThis = false; method.Parameters.Insert(0, new ParameterDefinition(originalType)); resolved = method.Resolve(); // Our explicit "this" parameter can be of type System.Object if (resolved == null) { method.Parameters[0] = new ParameterDefinition(method.DeclaringType.Module.TypeSystem.Object.Resolve()); resolved = method.Resolve(); } if (resolved == null) { method.HasThis = true; method.Parameters.RemoveAt(0); } } if (resolved != null) { Context.RewriteTarget = true; AddSupportReferenceIfNeeded(support); return(true); } method.DeclaringType = originalType; return(false); }
public void OnMethod(MethodDefinition method) { if (method.DeclaringType.IsInterface) { return; } if (!method.HasBody) { if (Verbosity >= 9) { Console.WriteLine("method has no body: " + method.FullName); } return; } if (method.GenericParameters.Count > 0) { if (Verbosity >= Verbosities.SkippingVerbose) { Console.WriteLine(" . Skipping generic method: " + method.FullName); } return; } var processor = method.Body.GetILProcessor(); foreach (var i in method.Body.Instructions.ToArray()) { if (i.OpCode != OpCodes.Callvirt && i.OpCode != OpCodes.Call && i.OpCode != OpCodes.Calli ) { continue; } Mono.Cecil.GenericParameter genPar = null; MethodReference mr = i.Operand as MethodReference; if (mr == null) { throw new Exception("Call method does not have MethodReference as Operand."); } if (!mr.IsGenericInstance) { continue; } if (!mr.FullName.Contains("<")) { // if(Verbosity >= 8) - shouldn't be reached Console.WriteLine("Skipping method that contains no <"); continue; } if (mr.FullName.Contains(" System.")) { if (Verbosity >= Verbosities.Skipping) { Console.WriteLine("Skipping method invocation that contains ' System.': " + mr.FullName + " in " + method.DeclaringType.FullName + "." + method.Name); } continue; } #if CUSTOM // Custom blacklist if (!mr.FullName.Contains(" LionFire.") && !mr.FullName.Contains(" Dycen.")) { if (Verbosity >= Verbosities.Skipping) { Console.WriteLine("Skipping method that is not LionFire or Dycen:" + mr.FullName + " in " + method.DeclaringType.FullName + "." + method.Name); } continue; } #endif var genPars = mr.Resolve().GenericParameters; // Console.WriteLine("TEMP2 - " + genPars.Count); // var genPars = mr.GetGenericParameters(method.Module); // Console.WriteLine("TEMP " + mr.Name); // Console.WriteLine("TEMP genPars.Count " + genPars.Count); if (genPars.Count != 1) { if (Verbosity >= Verbosities.Warning) { Console.WriteLine("[NS] Replacing methods with more than 1 generic parameter not supported: " + genPars.Count + ": " + mr.FullName + " in " + method.DeclaringType.FullName + "." + method.Name); } continue; } else { genPar = genPars[0]; // var resolved = genPar.Resolve(); // Console.WriteLine("NEW -- <" + (resolved == null ? "null" : resolved.Name) + ">"); if (Verbosity >= 10) { Console.WriteLine("NEW |- <" + genPar + ">"); } } #region string genericParameter = ...; string genericParameter; Type genericTypeParameter; TypeDefinition genericTypeParameterDefinition = null; { string n = mr.FullName.Split(' ')[1]; n = n.Split(new string[] { "::" }, StringSplitOptions.RemoveEmptyEntries)[1]; int startI = n.IndexOf('<') + 1; int stack = 0; int endI = startI + 1; while (stack > 0 || n[endI] != '>') { if (n[endI] == '<') { stack++; } if (n[endI] == '>') { stack--; } endI++; } int length = endI - startI; genericParameter = n.Substring(startI, length); // if(genericParameter.StartsWith("!!")) // { // int genParAliasIndex = Convert.ToInt32(genericParameter.Substring(2)); // // var genParAlias = genPars[genParAliasIndex]; // // // genericParameter = genParAlias.FullName; // Console.WriteLine("NEW - Generic method alias param: " + genericParameter); // } // if(genericParameter.Contains("<") || genericParameter.Contains(">")) // { // Console.WriteLine("Unsupported generic method ("+mr.FullName+") with generic parameter: " + genericParameter); // skipped++; // continue; // } if (Verbosity >= 8) { Console.WriteLine("Generic method param: " + genericParameter); } genericTypeParameter = Type.GetType(genericParameter, false); //if(genericTypeParameter == null) { foreach (ModuleDefinition modDef in ads.SelectMany(assDef => assDef.Modules)) { // foreach(var modType in modDef.Types) // { // Console.WriteLine("ccc - " + modType); // } genericTypeParameterDefinition = modDef.Types.Where(td => td.FullName == genericParameter // && !td.IsGenericInstance ).FirstOrDefault(); if (genericTypeParameterDefinition != null) { if (Verbosity >= 9) { Console.WriteLine("TODO - got genTD: " + genericTypeParameterDefinition); } break; } } if (genericTypeParameterDefinition == null) { if (Verbosity >= 8) { Console.WriteLine(" x Could not get TypeDefinition for " + genericParameter); } // No continue, this is not a problem } if (genericTypeParameter == null && genericTypeParameterDefinition == null) { if (Verbosity >= Verbosities.Error) { Console.WriteLine(" x - Failed to get Type for " + genericParameter + " in invocation: " + mr.FullName + " in method " + method.FullName); } skipped++; continue; } } } #endregion #if ONLY_VOID_OR_GENPARM // OLD, now other return types are supported if they are the same as replaced method string matchingReturnType = "!!0"; // genericTypeParameter.FullName; if (mr.ReturnType.FullName != "System.Void" && mr.ReturnType.FullName != matchingReturnType) // && mr.ReturnType.FullName != genericTypeParameter.FullName) { if (Verbosity >= 3) { Console.WriteLine(" x generic method doesn't return System.Void or '" + matchingReturnType + "': " + mr.FullName + ", but instead: " + mr.ReturnType.FullName); } continue; } #endif // if(Verbosity >= 9) Console.WriteLine("mr: " + mr.Name); TypeDefinition tr = mr.DeclaringType.Resolve(); MethodDefinition replacementMethod = null; // if(mr.DeclaringType.Name == "MultiType") // { // foreach(MethodDefinition replacementMethod_ in // tr.Methods) // { // Console.WriteLine("z " + replacementMethod_.Name + " " + replacementMethod_.FullName); // } // } bool noCast = false; foreach (MethodDefinition replacementMethod_ in tr.Methods.Where(mr_ => mr_.Name == mr.Name && !mr_.HasGenericParameters)) { noCast = false; // TODO: Verify parameters if (!replacementMethod_.HasParameters) { continue; } if (replacementMethod_.Parameters.Count != mr.Parameters.Count + 1) { if (Verbosity >= 8) { Console.WriteLine(" x - (alt) candidate replacement method has wrong parameter count: " + replacementMethod_.FullName); } continue; } // Console.WriteLine("Replacement param type: "+ replacementMethod_.Parameters[0].ParameterType.FullName); if (replacementMethod_.Parameters[replacementMethod_.Parameters.Count - 1].ParameterType.FullName != "System.Type") { if (Verbosity >= 8) { Console.WriteLine(" x - (alt) candidate replacement does not have Type parameter at the end of parameters : " + replacementMethod_.FullName); } continue; } if (mr.ReturnType.FullName == replacementMethod_.ReturnType.Resolve().FullName) { noCast = true; if (Verbosity >= 9) { Console.WriteLine(" - (alt) generic method and alt method return same type:: " + mr.ReturnType.FullName); } } else if (mr.ReturnType.FullName != "System.Void") // Replacement must return object { if (replacementMethod_.ReturnType.Resolve().FullName != "System.Object") { if (Verbosity >= 3) { Console.WriteLine(" [x?] (alt) generic method returns T but candidate replacement method does not return System.Object: " + replacementMethod_.FullName + " [[" + mr.FullName + " in " + method.DeclaringType.FullName + "." + method.Name + "]]"); } continue; } } if (Verbosity >= 8) { Console.WriteLine("FOUND ALTERNATE METHOD: " + replacementMethod_); } replacementMethod = replacementMethod_; break; // FUTURE: don't break here, keep going to see if there are multiple (ambiguous) matches and throw/output error } if (replacementMethod == null) { if (!(" " + mr.FullName).Contains(" System.")) { if (Verbosity >= Verbosities.Warning) { Console.WriteLine("[__] No alternate found for " + mr.FullName + " in " + method.DeclaringType.FullName + "." + method.Name); } // + mr.DeclaringType.FullName+"." +mr.Name + "(...)"); } skipped++; continue; } // if(mr.Name != "TestMethod") continue; // TEMP if (Verbosity >= Verbosities.Success) { Console.WriteLine(" O Replacing " + mr.FullName + " " + mr.GenericParameters.Count + " generic parameters" + " " + mr.Parameters.Count + " parameters" + " | " + mr.GetElementMethod().FullName + "" + " | " + mr.GetElementMethod().HasGenericParameters + "" + " | " + mr.GetElementMethod().GenericParameters[0].Name + "" ); } // if(Verbosity >= 6) // Console.WriteLine("Resolved non-specific generic method: " + mr.FullName); // if(Verbosity >= 8) Console.WriteLine("RESOLVED TYPE: " + genericTypeParameter); // var typeModuleDefinition = ModuleDefinition.ReadModule(type.Module.Assembly.Location); // var typeDefinition = typeModuleDefinition.Types.Where(td => td.FullName == genericParameter).FirstOrDefault(); // if(typeDefinition != null && Verbosity >= 5) // { // Console.WriteLine("Resolved typeDefinition: " + typeDefinition); // } // else // { // Console.WriteLine("Failed to resolve typeDefinition: " + type.FullName); //// foreach(var td in ModuleDefinition.ReadModule(type.Module.Assembly.Location).Types) //// { //// Console.WriteLine(" ... " + td.FullName); //// } // continue; // } // method.Module.Import(type); // try removing this // IMetadataScope scope = method.Module; // var typeRef = new TypeReference(type.Namespace, type.Name, typeModuleDefinition, scope, type.IsValueType); // Console.WriteLine("TypeRef: "+ typeRef); // method.Module.Import(type); var replacementMethodImported = method.Module.Import(replacementMethod); // IL_0000: ldtoken Rewriter.TestClass if (genericTypeParameter != null) { processor.InsertBefore(i, processor.Create(OpCodes.Ldtoken, method.Module.Import(genericTypeParameter))); } else { processor.InsertBefore(i, processor.Create(OpCodes.Ldtoken, method.Module.Import(genericTypeParameterDefinition))); } // IL_0005: call class [mscorlib]System.Type class // [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) var gtfh = typeof(Type).GetMethod("GetTypeFromHandle"); MethodReference gtfhRef = method.Module.Import(gtfh, mr); processor.InsertBefore(i, processor.Create(OpCodes.Call, gtfhRef)); // IL_000a: call void class Rewriter.TestClass::TestMethod(class [mscorlib]System.Type) var callMethod = processor.Create(i.OpCode, replacementMethodImported); processor.InsertAfter(i, callMethod); #region Cast the result, if it exists if (mr.ReturnType.FullName != "System.Void" && !noCast) { string castAssembly; string castType; if (genericTypeParameter != null) { castAssembly = genericTypeParameter.Assembly.GetName(false).Name; castType = "[" + castAssembly + "]" + genericTypeParameter.FullName; } else if (genericTypeParameterDefinition != null) { castAssembly = ""; castType = genericTypeParameterDefinition.ToString(); // var resolvedGTPD = genericTypeParameterDefinition.Resolve(); // resolvedGTPD.FullName } else { castType = "???"; Console.WriteLine("INTERNAL ERROR - genericTypeParameter not set for " + mr.FullName + ". genericTypeParameterDefinition:" + genericTypeParameterDefinition.Resolve()); continue; } // castAssembly = castAssembly.Substring(castAssembly.IndexOf(",")); if (Verbosity > 8) { Console.WriteLine("CAST to " + castType + " | " + genericTypeParameterDefinition); } var importedGenericType = mr.Module.Import(genericTypeParameterDefinition); processor.InsertAfter(callMethod, processor.Create(OpCodes.Castclass, importedGenericType)); } #endregion processor.Remove(i); replaced++; // if(Verbosity >= Verbosities.Success) // Console.WriteLine(" - " + ((MethodReference)i.Operand).Name + " replaced with " + replacementMethod.FullName); // mr.GetGenericParameters(null); // // if(method.GenericParameters.Count == 0) return; // // if(method.GenericParameters.Count > 1) // { // Console.WriteLine("Warning: cannot handle more than one generic parameter yet: " + // method.DeclaringType.FullName + "." + method.Name); // return; // } // // var body = method.Body; // body.Instructions // if(method.GenericParameters.Count == 1) // { // } } }