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);
        }
示例#2
0
        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);
        }
示例#3
0
 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));
        }
示例#5
0
 /// <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);
 }
示例#6
0
        public bool MatchLdLoca(ILVariable variable)
        {
            var inst = this as LdLoca;

            return(inst != null && inst.Variable == variable);
        }