static IMethod ImplementIntoCaseConversion(this VirtualType type, IType valueType, IMethod caseCtor, bool isImplicit = true) { Debug.Assert(valueType == caseCtor.Parameters.Single().Type); Debug.Assert(valueType.Kind != TypeKind.Interface); // can't have conversion from interface Debug.Assert(valueType != type); // can't have conversion from itself var caseFactory = new VirtualMethod(type, Accessibility.Public, isImplicit ? "op_Implicit" : "op_Explicit", new[] { new VirtualParameter(valueType, "item") }, returnType: type, isStatic: true ); caseFactory.BodyFactory = () => { var @this = new IL.ILVariable(IL.VariableKind.Parameter, valueType, 0); IL.ILInstruction body = new IL.NewObj(caseCtor) { Arguments = { new IL.LdLoc(@this) } }; if (valueType.IsReferenceType == true) { // pass nulls body = new IL.IfInstruction( new IL.Comp(IL.ComparisonKind.Inequality, Sign.None, new IL.LdLoc(@this), new IL.LdNull()), body, new IL.LdNull() ); } return(EmitExtensions.CreateExpressionFunction(caseFactory, body)); }; type.Methods.Add(caseFactory); return(caseFactory); }
public static IProperty AddExplicitInterfaceProperty(this VirtualType declaringType, IProperty ifcProperty, IMember baseMember) { Debug.Assert(declaringType.Equals(baseMember.DeclaringType) || declaringType.GetAllBaseTypeDefinitions().Contains(baseMember.DeclaringType)); Debug.Assert(ifcProperty.DeclaringType.Kind == TypeKind.Interface); var getter = new VirtualMethod(declaringType, Accessibility.Private, "get_" + ifcProperty.FullName, new IParameter[0], ifcProperty.ReturnType, explicitImplementations: new [] { ifcProperty.Getter }, isHidden: true); getter.BodyFactory = () => { var thisParam = new IL.ILVariable(IL.VariableKind.Parameter, declaringType, -1); return(CreateExpressionFunction(getter, new IL.LdLoc(thisParam).AccessMember(baseMember))); }; var setter = ifcProperty.Setter == null ? null : new VirtualMethod(declaringType, Accessibility.Private, "get_" + ifcProperty.FullName, ifcProperty.Setter.Parameters, ifcProperty.Setter.ReturnType, explicitImplementations: new [] { ifcProperty.Setter }, isHidden: true); if (setter != null) { setter.BodyFactory = () => { var thisParam = new IL.ILVariable(IL.VariableKind.Parameter, declaringType, -1); var valueParam = new IL.ILVariable(IL.VariableKind.Parameter, declaringType, 0); return(CreateExpressionFunction(getter, new IL.LdLoc(thisParam).AssignMember(baseMember, new IL.LdLoc(valueParam)))); } } ; var prop = new VirtualProperty(declaringType, Accessibility.Private, ifcProperty.FullName, getter, setter, explicitImplementations: new [] { ifcProperty }); getter.ApplyAction(declaringType.Methods.Add); setter?.ApplyAction(declaringType.Methods.Add); prop.ApplyAction(declaringType.Properties.Add); return(prop); }
public MatchInstruction(ILVariable variable, ILInstruction testedOperand) : this(variable, method : null, testedOperand) { }
internal static bool IsConversionStLoc(ILInstruction inst, out ILVariable variable, out ILVariable inputVariable) { inputVariable = null; if (!inst.MatchStLoc(out variable, out var value)) { return(false); } ILInstruction input; switch (value) { case Conv conv: input = conv.Argument; break; //case Call { Method: { IsOperator: true, Name: "op_Implicit" }, Arguments: { Count: 1 } } call: // input = call.Arguments[0]; // break; default: return(false); } return(input.MatchLdLoc(out inputVariable) || input.MatchLdLoca(out inputVariable)); }
/// <summary> /// Matches either ldloc (if the variable is a reference type), or ldloca (otherwise). /// </summary> public bool MatchLdLocRef(ILVariable variable) { return(MatchLdLocRef(out var v) && v == variable); }
public bool MatchLdLoca(ILVariable variable) { var inst = this as LdLoca; return(inst != null && inst.Variable == variable); }