private static void ResolveMethod(ILGenerator generator, Dictionary <MethodBuilder, MethodInfo> methods, Dictionary <ConstructorBuilder, ConstructorInfo> constructors, VRage.Compiler.IlReader.IlInstruction instruction, System.Reflection.Emit.OpCode code) { bool found = false; var method = instruction.Operand as MethodBase; if (instruction.Operand is MethodInfo) { var methodInfo = instruction.Operand as MethodInfo; foreach (var met in methods) { if (met.Value == methodInfo) { generator.Emit(code, met.Key); found = true; break; } } } if (instruction.Operand is ConstructorInfo) { var methodInfo = instruction.Operand as ConstructorInfo; foreach (var met in constructors) { if (met.Value == methodInfo) { generator.Emit(code, met.Key); found = true; break; } } } if (false == found) { if (method is MethodInfo) { generator.Emit(code, method as MethodInfo); } else if (method is ConstructorInfo) { generator.Emit(code, method as ConstructorInfo); } } }
private static void ResolveMethod(ILGenerator generator, Dictionary <MethodBuilder, MethodInfo> methods, Dictionary <ConstructorBuilder, ConstructorInfo> constructors, VRage.Compiler.IlReader.IlInstruction instruction, System.Reflection.Emit.OpCode code, Dictionary <string, Type> typeLookup) { if (instruction.Operand is MethodInfo) { var methodInfo = instruction.Operand as MethodInfo; if (methodInfo.DeclaringType.IsGenericType) { Type genericTypeDefinition; var declaringType = ResolveGenericType(typeLookup, methodInfo, out genericTypeDefinition); if (declaringType != null) { var flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; if (methodInfo.IsStatic) { flags |= BindingFlags.Static; } else { flags |= BindingFlags.Instance; } var genericMethod = genericTypeDefinition.GetMethods(flags).Single(m => m.MetadataToken == methodInfo.MetadataToken); methodInfo = TypeBuilder.GetMethod(declaringType, genericMethod); } } // Handle generic calls if (methodInfo.IsGenericMethod) { var methodDefinitionInfo = methodInfo.GetGenericMethodDefinition(); var mustRegenerateMethod = false; // See if we already have the method definition foreach (var met in methods) { if (met.Value == methodDefinitionInfo) { methodDefinitionInfo = met.Key; mustRegenerateMethod = true; break; } } // Analyze all the generics arguments and replace as needed var genericArguments = methodInfo.GetGenericArguments(); for (var i = 0; i < genericArguments.Length; i++) { if (genericArguments[i].IsGenericParameter) { continue; } Type genericArgumentTypeBuilder; if (typeLookup.TryGetValue(genericArguments[i].FullName, out genericArgumentTypeBuilder)) { mustRegenerateMethod = true; genericArguments[i] = genericArgumentTypeBuilder; } } if (mustRegenerateMethod) { methodDefinitionInfo = methods.Where(m => m.Value == methodDefinitionInfo).Select(m => m.Key).SingleOrDefault() ?? methodDefinitionInfo; generator.Emit(code, methodDefinitionInfo.MakeGenericMethod(genericArguments)); return; } } else { foreach (var met in methods) { if (met.Value == methodInfo) { generator.Emit(code, met.Key); return; } } } generator.Emit(code, methodInfo); return; } if (instruction.Operand is ConstructorInfo) { var constructorInfo = instruction.Operand as ConstructorInfo; if (constructorInfo.DeclaringType.IsGenericType) { Type genericTypeDefinition; var declaringType = ResolveGenericType(typeLookup, constructorInfo, out genericTypeDefinition); if (declaringType != null) { var flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; if (constructorInfo.IsStatic) { flags |= BindingFlags.Static; } else { flags |= BindingFlags.Instance; } var genericMethod = genericTypeDefinition.GetConstructors(flags).Single(m => m.MetadataToken == constructorInfo.MetadataToken); constructorInfo = TypeBuilder.GetConstructor(declaringType, genericMethod); } } foreach (var met in constructors) { if (met.Value == constructorInfo) { generator.Emit(code, met.Key); return; } } generator.Emit(code, constructorInfo); return; } }