예제 #1
0
        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);
                }
            }
        }
예제 #2
0
        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;
            }
        }