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); }