private static ASTType?InferVarPush(ILASTExpression expr)
        {
            var method = (IMethod)expr.Operand;

            if (method.MethodSig.RetType.ElementType == ElementType.Void)
            {
                return(null);
            }

            var genArgs = new GenericArguments();

            if (method is MethodSpec)
            {
                genArgs.PushMethodArgs(((MethodSpec)method).GenericInstMethodSig.GenericArguments);
            }
            if (method.DeclaringType.TryGetGenericInstSig() != null)
            {
                genArgs.PushTypeArgs(method.DeclaringType.TryGetGenericInstSig().GenericArguments);
            }


            return(TypeInference.ToASTType(genArgs.ResolveType(method.MethodSig.RetType)));
        }
 /// <summary>
 /// Pushes the method generic arguments into resolver stack.
 /// </summary>
 /// <param name="genericArgs">The generic arguments.</param>
 public void PushMethodGenericArguments(IList <TypeSig> genericArgs)
 {
     genericArguments.PushMethodArgs(genericArgs);
 }
        public bool Instantiate(MethodSpec methodSpec, out MethodDef def)
        {
            if (instantiations.TryGetValue(methodSpec, out def))
            {
                return(true);
            }

            var genericArguments = new GenericArguments();

            genericArguments.PushMethodArgs(methodSpec.GenericInstMethodSig.GenericArguments);
            var originDef = methodSpec.Method.ResolveMethodDefThrow();

            var newSig = ResolveMethod(originDef.MethodSig, genericArguments);

            newSig.Generic       = false;
            newSig.GenParamCount = 0;

            string newName = originDef.Name;

            foreach (var typeArg in methodSpec.GenericInstMethodSig.GenericArguments)
            {
                newName += ";" + typeArg.TypeName;
            }

            def = new MethodDefUser(newName, newSig, originDef.ImplAttributes, originDef.Attributes);
            var thisParam = originDef.HasThis ? originDef.Parameters[0].Type : null;

            def.DeclaringType2 = originDef.DeclaringType2;
            if (thisParam != null)
            {
                def.Parameters[0].Type = thisParam;
            }

            foreach (var declSec in originDef.DeclSecurities)
            {
                def.DeclSecurities.Add(declSec);
            }
            def.ImplMap = originDef.ImplMap;
            foreach (var ov in originDef.Overrides)
            {
                def.Overrides.Add(ov);
            }

            def.Body            = new CilBody();
            def.Body.InitLocals = originDef.Body.InitLocals;
            def.Body.MaxStack   = originDef.Body.MaxStack;
            foreach (var variable in originDef.Body.Variables)
            {
                var newVar = new Local(variable.Type);
                def.Body.Variables.Add(newVar);
            }

            var instrMap = new Dictionary <Instruction, Instruction>();

            foreach (var instr in originDef.Body.Instructions)
            {
                var newInstr = new Instruction(instr.OpCode, ResolveOperand(instr.Operand, genericArguments));
                def.Body.Instructions.Add(newInstr);
                instrMap[instr] = newInstr;
            }
            foreach (var instr in def.Body.Instructions)
            {
                if (instr.Operand is Instruction)
                {
                    instr.Operand = instrMap[(Instruction)instr.Operand];
                }
                else if (instr.Operand is Instruction[])
                {
                    var targets = (Instruction[])((Instruction[])instr.Operand).Clone();
                    for (int i = 0; i < targets.Length; i++)
                    {
                        targets[i] = instrMap[targets[i]];
                    }
                    instr.Operand = targets;
                }
            }
            def.Body.UpdateInstructionOffsets();

            foreach (var eh in originDef.Body.ExceptionHandlers)
            {
                var newEH = new ExceptionHandler(eh.HandlerType);
                newEH.TryStart     = instrMap[eh.TryStart];
                newEH.HandlerStart = instrMap[eh.HandlerStart];
                if (eh.TryEnd != null)
                {
                    newEH.TryEnd = instrMap[eh.TryEnd];
                }
                if (eh.HandlerEnd != null)
                {
                    newEH.HandlerEnd = instrMap[eh.HandlerEnd];
                }
                if (eh.CatchType != null)
                {
                    newEH.CatchType = genericArguments.Resolve(newEH.CatchType.ToTypeSig()).ToTypeDefOrRef();
                }
                else if (eh.FilterStart != null)
                {
                    newEH.FilterStart = instrMap[eh.FilterStart];
                }

                def.Body.ExceptionHandlers.Add(newEH);
            }

            instantiations[methodSpec] = def;
            return(false);
        }