Equal() public static method

Creates a BinaryExpression that represents an equality comparison.
public static Equal ( Expression left, Expression right ) : BinaryExpression
left Expression An to set the property equal to.
right Expression An to set the property equal to.
return BinaryExpression
コード例 #1
0
        private static Expression <Func <T, bool> > PrimaryKeyEquals(PropertyInfo property, int value)
        {
            var param = Expression.Parameter(typeof(T));
            var body  = Expression.Equal(Expression.Property(param, property), Expression.Constant(value));

            return(Expression.Lambda <Func <T, bool> >(body, param));
        }
コード例 #2
0
        public void TestWhereComparison()
        {
            // Partial LINQ expression (x => x.Number1)
            var parameter = LinqExpression.Parameter(typeof(NumbersModel), "x");
            var n1        = LinqExpression.Property(parameter, "Number1");

            var l3    = new Func <int, bool>(n => n < 3);
            var le3   = new Func <int, bool>(n => n <= 3);
            var g6    = new Func <int, bool>(n => n > 6);
            var ge6   = new Func <int, bool>(n => n >= 6);
            var e7    = new Func <int, bool>(n => n == 7);
            var ne7   = new Func <int, bool>(n => n != 7);
            var cases = new[] {
                Tuple.Create((LinqExpression)LinqExpression.LessThan(n1, LinqExpression.Constant(3)),
                             (Func <NumbersModel, object, bool>)TestWhereCompareValidator, (object)l3, parameter),
                Tuple.Create((LinqExpression)LinqExpression.LessThanOrEqual(n1, LinqExpression.Constant(3)),
                             (Func <NumbersModel, object, bool>)TestWhereCompareValidator, (object)le3, parameter),
                Tuple.Create((LinqExpression)LinqExpression.GreaterThan(n1, LinqExpression.Constant(6)),
                             (Func <NumbersModel, object, bool>)TestWhereCompareValidator, (object)g6, parameter),
                Tuple.Create((LinqExpression)LinqExpression.GreaterThanOrEqual(n1, LinqExpression.Constant(6)),
                             (Func <NumbersModel, object, bool>)TestWhereCompareValidator, (object)ge6, parameter),
                Tuple.Create((LinqExpression)LinqExpression.Equal(n1, LinqExpression.Constant(7)),
                             (Func <NumbersModel, object, bool>)TestWhereCompareValidator, (object)e7, parameter),
                Tuple.Create((LinqExpression)LinqExpression.NotEqual(n1, LinqExpression.Constant(7)),
                             (Func <NumbersModel, object, bool>)TestWhereCompareValidator, (object)ne7, parameter)
            };

            LoadModelNumbers(10);
            Db.Count.Should().Be(10);
            RunTestWithNumbers(new[] { 2, 3, 4, 5, 1, 9 }, cases);
        }
コード例 #3
0
        internal bool AddSplattedArgumentTest(object value, Expression /*!*/ expression, out int listLength, out ParameterExpression /*!*/ listVariable)
        {
            if (value == null)
            {
                AddRestriction(Ast.Equal(expression, Ast.Constant(null)));
            }
            else
            {
                // test exact type:
                AddTypeRestriction(value.GetType(), expression);

                List <object> list = value as List <object>;
                if (list != null)
                {
                    Type type = typeof(List <object>);
                    listLength   = list.Count;
                    listVariable = GetTemporary(type, "#list");
                    AddCondition(Ast.Equal(
                                     Ast.Property(Ast.Assign(listVariable, Ast.Convert(expression, type)), type.GetProperty("Count")),
                                     Ast.Constant(list.Count))
                                 );
                    return(true);
                }
            }

            listLength   = -1;
            listVariable = null;
            return(false);
        }
コード例 #4
0
ファイル: RubyMethodInfo.cs プロジェクト: gaybro8777/ironruby
        /// <summary>
        /// Takes current result and wraps it into try-filter(MethodUnwinder)-finally block that ensures correct "break" behavior for
        /// Ruby method calls with a block given in arguments.
        ///
        /// Sets up a RFC frame similarly to MethodDeclaration.
        /// </summary>
        internal static void ApplyBlockFlowHandlingInternal(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            // TODO (improvement):
            // We don't special case null block here, although we could (we would need a test for that then).
            // We could also statically know (via call-site flag) that the current method is not a proc-converter (passed by ref),
            // which would make such calls faster.
            if (metaBuilder.Error || !args.Signature.HasBlock)
            {
                return;
            }

            Expression          rfcVariable    = metaBuilder.GetTemporary(typeof(RuntimeFlowControl), "#rfc");
            ParameterExpression methodUnwinder = metaBuilder.GetTemporary(typeof(MethodUnwinder), "#unwinder");
            Expression          resultVariable = metaBuilder.GetTemporary(typeof(object), "#result");

            metaBuilder.Result = Ast.Block(
                // initialize frame (RFC):
                Ast.Assign(rfcVariable, Methods.CreateRfcForMethod.OpCall(AstUtils.Convert(args.GetBlockExpression(), typeof(Proc)))),
                AstUtils.Try(
                    Ast.Assign(resultVariable, metaBuilder.Result)
                    ).Filter(methodUnwinder, Ast.Equal(Ast.Field(methodUnwinder, MethodUnwinder.TargetFrameField), rfcVariable),

                             // return unwinder.ReturnValue;
                             Ast.Assign(resultVariable, Ast.Field(methodUnwinder, MethodUnwinder.ReturnValueField))

                             ).Finally(
                    // we need to mark the RFC dead snce the block might escape and break later:
                    Ast.Assign(Ast.Field(rfcVariable, RuntimeFlowControl.IsActiveMethodField), Ast.Constant(false))
                    ),
                resultVariable
                );
        }
コード例 #5
0
        private Exp CheckIfZero(CompilerState state, Exp expression)
        {
            if (state == null)
            {
                throw new Exception();
            }
            if (expression == null)
            {
                throw new Exception();
            }

            if (expression.Type == typeof(int))
            {
                var constructor = typeof(Exception).GetConstructor(new Type[] { typeof(string) });
                return(Exp.Block(
                           Exp.IfThen(Exp.Equal(expression, Exp.Constant(0)),
                                      Exp.Throw(Exp.New(constructor, Exp.Constant("Division by zero")))),
                           expression));
            }

            if (expression.Type == typeof(float))
            {
                var constructor = typeof(Exception).GetConstructor(new Type[] { typeof(string) });
                return(Exp.Block(
                           Exp.IfThen(Exp.Equal(expression, Exp.Constant(0.0f)),
                                      Exp.Throw(Exp.New(constructor, Exp.Constant("Division by zero")))),
                           expression));
            }
            return(expression);
        }
コード例 #6
0
        /// <summary>
        /// Creates an expression tha defines an equality comparison
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public static Expression <Func <bool> > Equal <X>(this Expression <Func <X> > left, Expression <Func <X> > right)
        {
            var lValue = XPR.Invoke(left);
            var rValue = XPR.Invoke(right);

            return(XPR.Lambda <Func <bool> >(XPR.Equal(lValue, rValue)));
        }
コード例 #7
0
ファイル: RubyClass.cs プロジェクト: gaybro8777/ironruby
        /// <summary>
        /// Implements Class#new feature.
        /// </summary>
        public void BuildObjectConstruction(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ methodName)
        {
            Debug.Assert(!IsSingletonClass, "Cannot instantiate singletons");

            Type type = GetUnderlyingSystemType();

            RubyMemberInfo initializer           = ResolveMethod(Symbols.Initialize, true).InvalidateSitesOnOverride();
            RubyMethodInfo overriddenInitializer = initializer as RubyMethodInfo;

            // check the version of this class to ensure the initializer won't be changed without rebuilding the site:
            metaBuilder.AddCondition(
                Ast.Equal(Ast.Property(Ast.Constant(this), RubyModule.VersionProperty), Ast.Constant(this.Version))
                );

            // Initializer is overridden => initializer is invoked on an uninitialized instance.
            // Is user class (defined in Ruby code) => construct it as if it had initializer that calls super immediately
            // (we need to "inherit" factories/constructors from the base class (e.g. class S < String; self; end.new('foo')).
            if (overriddenInitializer != null || (_isRubyClass && _structInfo == null))
            {
                metaBuilder.Result = MakeAllocatorCall(args, () => Ast.Constant(Name));

                if (overriddenInitializer != null || (_isRubyClass && initializer != null && !initializer.IsEmpty))
                {
                    BuildOverriddenInitializerCall(metaBuilder, args, initializer);
                }
            }
            else if (type.IsSubclassOf(typeof(Delegate)))
            {
                metaBuilder.Result = MakeDelegateConstructorCall(type, args);
            }
            else
            {
                MethodBase[] constructionOverloads;

                bool includeSelf;
                if (_structInfo != null)
                {
                    constructionOverloads = new MethodBase[] { Methods.CreateStructInstance };
                    includeSelf           = true;
                }
                else if (_factories != null)
                {
                    constructionOverloads = (MethodBase[])ReflectionUtils.GetMethodInfos(_factories);
                    includeSelf           = true;
                }
                else
                {
                    constructionOverloads = type.GetConstructors();
                    if (constructionOverloads.Length == 0)
                    {
                        throw RubyExceptions.CreateTypeError(String.Format("allocator undefined for {0}", Name));
                    }
                    includeSelf = false;
                }

                RubyMethodGroupInfo.BuildCallNoFlow(metaBuilder, args, methodName, constructionOverloads, includeSelf, false);
                RubyMethodGroupInfo.ApplyBlockFlowHandlingInternal(metaBuilder, args);
            }
        }
コード例 #8
0
        public void MiscellaneousExpression_Block()
        {
            var variable = Expr.Variable(typeof(bool));

            var block = Expr.Block(Expr.Assign(variable, Expr.Constant(true)), variable);

            UnsupportedExpr(Property.Active, active => Expr.Equal(active, block), ExpressionType.Block);
        }
コード例 #9
0
        public void CanConstantExpressionBeNull()
        {
            ConstantExpression c2 = Expression.Constant(null);
            ConstantExpression c1 = Expression.Constant(null);
            BinaryExpression   a  = Expression.Equal(c1, c2);

            Assert.Pass();
        }
コード例 #10
0
        protected override Expression VisitMethodCall(MethodCallExpression expr)
        {
            switch (expr.Method.Name)
            {
            case "Any":
                CurrentCriterions.Add(GetExistsCriteria(expr));
                break;

            case "StartsWith":
                CurrentCriterions.Add(GetLikeCriteria(expr, MatchMode.Start));
                break;

            case "EndsWith":
                CurrentCriterions.Add(GetLikeCriteria(expr, MatchMode.End));
                break;

            case "Contains":
                if (expr.Object == null)
                {
                    if (expr.Arguments[0] is ConstantExpression)
                    {
                        CurrentCriterions.Add(GetCollectionContainsCriteria(expr.Arguments[0], expr.Arguments[1]));
                    }
                    else if (expr.Arguments[0] is CollectionAccessExpression)
                    {
                        CurrentCriterions.Add(GetCollectionContainsCriteria((CollectionAccessExpression)expr.Arguments[0], expr.Arguments[1]));
                    }
                    else
                    {
                        //myArray.Contains(user.Name)
                        CurrentCriterions.Add(GetCollectionContainsCriteria(expr.Arguments[0], expr.Arguments[1]));
                    }
                }
                else if (expr.Object is ConstantExpression)
                {
                    //myList.Contains(user.Name)
                    CurrentCriterions.Add(GetCollectionContainsCriteria(expr.Object, expr.Arguments[0]));
                }
                else if (expr.Object is CollectionAccessExpression)
                {
                    //timesheet.Entries.Contains(entry)
                    CurrentCriterions.Add(GetCollectionContainsCriteria((CollectionAccessExpression)expr.Object, expr.Arguments[0]));
                }
                else
                {
                    //user.Name.Contains(partialName)
                    CurrentCriterions.Add(GetLikeCriteria(expr, MatchMode.Anywhere));
                }
                break;

            case "Equals":
                VisitBinaryCriterionExpression(Expression.Equal(expr.Object, expr.Arguments[0]));
                break;
            }

            return(expr);
        }
コード例 #11
0
        public void BinaryExpression_SubtractChecked()
        {
            ExecuteExpr(Property.Id, id =>
            {
                var subtract = Expr.SubtractChecked(id, Expr.Constant(3));

                return(Expr.Equal(subtract, Expr.Constant(2)));
            }, ExpressionType.SubtractChecked);
        }
コード例 #12
0
 public static Expression /*!*/ GetObjectTypeTestExpression(object value, Expression /*!*/ expression)
 {
     if (value == null)
     {
         return(Ast.Equal(expression, Ast.Constant(null)));
     }
     else
     {
         return(RuleBuilder.MakeTypeTestExpression(value.GetType(), expression));
     }
 }
コード例 #13
0
 public void AddObjectTypeRestriction(object value, Expression /*!*/ expression)
 {
     if (value == null)
     {
         AddRestriction(Ast.Equal(expression, Ast.Constant(null)));
     }
     else
     {
         AddTypeRestriction(value.GetType(), expression);
     }
 }
コード例 #14
0
 /// <summary>
 /// 操作
 /// </summary>
 /// <param name="left">左操作数</param>
 /// <param name="operator">运算符</param>
 /// <param name="value">值</param>
 public static MicrosoftExpression Operation(this MicrosoftExpression left, Operator @operator, object value)
 {
     return(@operator switch
     {
         Operator.Equal => left.Equal(value),
         Operator.NotEqual => left.NotEqual(value),
         Operator.Greater => left.Greater(value),
         Operator.GreaterEqual => left.GreaterEqual(value),
         Operator.Less => left.Less(value),
         Operator.LessEqual => left.LessEqual(value),
         Operator.Starts => left.StartsWith(value),
         Operator.Ends => left.EndsWith(value),
         Operator.Contains => left.Contains(value),
         _ => throw new NotImplementedException()
     });
コード例 #15
0
        public void TryCatchVariableBodyFilter()
        {
            var expected = LinqExpression.TryCatch(
                LinqExpression.Constant(0L),
                LinqExpression.Catch(
                    LinqExpression.Parameter(
                        typeof(Exception)),
                    LinqExpression.Constant(0L),
                    LinqExpression.Equal(
                        LinqExpression.Constant(0L),
                        LinqExpression.Constant(0L))));

            using var g = new GraphEngine.Graph();
            g.LoadFromString(@"
@prefix : <http://example.com/> .
@prefix xt: <http://example.com/ExpressionTypes/> .

:s
    :tryBody _:zero ;
    :tryHandlers (
        [
            :catchVariable [
                :parameterType [
                    :typeName ""System.Exception"" ;
                ] ;
            ] ;
            :catchBody _:zero ;
            :catchFilter [
                :binaryExpressionType xt:Equal ;
                :binaryLeft _:zero ;
                :binaryRight _:zero ;
            ] ;
        ]
    ) ;
.
_:zero
    :constantValue 0 ;
.
");
            var s = g.GetUriNode(":s");

            var actual = Expression.Parse(s).LinqExpression;

            Console.WriteLine(actual.GetDebugView());

            actual.Should().Be(expected);
        }
コード例 #16
0
ファイル: Converters.cs プロジェクト: modulexcite/FiddlerCert
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null || parameter == null)
            {
                return(null);
            }
            if (!value.GetType().IsEnum || !parameter.GetType().IsEnum)
            {
                return(null);
            }
            var flagsParam = Expression.Parameter(typeof(object), "flags");
            var flagParam  = Expression.Parameter(typeof(object), "flag");
            var hasFlag    = Expression.Equal(Expression.And(Expression.Convert(flagsParam, value.GetType()), Expression.Convert(flagParam, parameter.GetType())), flagParam);
            var expression = Expression.Lambda <Func <object, object, bool> >(hasFlag, flagsParam, flagParam);

            return(expression.Compile()(value, parameter) ? Visibility.Visible : Visibility.Collapsed);
        }
コード例 #17
0
        public void TestWhereArithmetic()
        {
            var parameter = LinqExpression.Parameter(typeof(NumbersModel), "x");
            var n1        = LinqExpression.Property(parameter, "Number1");
            var n2        = LinqExpression.Property(parameter, "Number2");

            var m2g8   = new Func <int, int, bool>((x1, x2) => x1 * 2 > 8);
            var d2g3   = new Func <int, int, bool>((x1, x2) => x1 / 2 > 3);
            var m2e0   = new Func <int, int, bool>((x1, x2) => (x1 % 2) == 0);
            var a5g10  = new Func <int, int, bool>((x1, x2) => x1 + 5 > 10);
            var s5g0   = new Func <int, int, bool>((x1, x2) => x1 - 5 > 0);
            var mn2g10 = new Func <int, int, bool>((x1, x2) => x1 * x2 > 10);
            var dn1g3  = new Func <int, int, bool>((x1, x2) => x2 / x1 > 3);
            var mn2e0  = new Func <int, int, bool>((x1, x2) => (x1 % x2) == 0);
            var an2e10 = new Func <int, int, bool>((x1, x2) => x1 + x2 == 10);
            var sn2g0  = new Func <int, int, bool>((x1, x2) => x1 - x2 > 0);
            var cases  = new[] {
                Tuple.Create((LinqExpression)LinqExpression.GreaterThan(LinqExpression.Multiply(n1, LinqExpression.Constant(2)), LinqExpression.Constant(8)),
                             (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)m2g8, parameter),
                Tuple.Create((LinqExpression)LinqExpression.GreaterThan(LinqExpression.Divide(n1, LinqExpression.Constant(2)), LinqExpression.Constant(3)),
                             (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)d2g3, parameter),
                Tuple.Create((LinqExpression)LinqExpression.Equal(LinqExpression.Modulo(n1, LinqExpression.Constant(2)), LinqExpression.Constant(0)),
                             (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)m2e0, parameter),
                Tuple.Create((LinqExpression)LinqExpression.GreaterThan(LinqExpression.Add(n1, LinqExpression.Constant(5)), LinqExpression.Constant(10)),
                             (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)a5g10, parameter),
                Tuple.Create((LinqExpression)LinqExpression.GreaterThan(LinqExpression.Subtract(n1, LinqExpression.Constant(5)), LinqExpression.Constant(0)),
                             (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)s5g0, parameter),
                Tuple.Create((LinqExpression)LinqExpression.GreaterThan(LinqExpression.Multiply(n1, n2), LinqExpression.Constant(10)),
                             (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)mn2g10, parameter),
                Tuple.Create((LinqExpression)LinqExpression.GreaterThan(LinqExpression.Divide(n2, n1), LinqExpression.Constant(3)),
                             (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)dn1g3, parameter),
                Tuple.Create((LinqExpression)LinqExpression.Equal(LinqExpression.Modulo(n1, n2), LinqExpression.Constant(0)),
                             (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)mn2e0, parameter),
                Tuple.Create((LinqExpression)LinqExpression.Equal(LinqExpression.Add(n1, n2), LinqExpression.Constant(10)),
                             (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)an2e10, parameter),
                Tuple.Create((LinqExpression)LinqExpression.GreaterThan(LinqExpression.Subtract(n1, n2), LinqExpression.Constant(0)),
                             (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)sn2g0, parameter)
            };

            LoadModelNumbers(10);
            RunTestWithNumbers(new[] { 6, 3, 5, 5, 5, 7, 2, 3, 10, 5 }, cases);
        }
コード例 #18
0
        public static TEntity LastOrNullBy <TEntity, TValue>(this IQueryable <TEntity> query, Expression <Func <TEntity, TValue> > keyFieldPredicate)
        {
            if (keyFieldPredicate == null)
            {
                throw new ArgumentNullException(nameof(keyFieldPredicate));
            }

            var p = keyFieldPredicate.Parameters.Single();

            if (query.LongCount() == 0)
            {
                return(default(TEntity));
            }

            var max = query.Max(keyFieldPredicate);

            var equalsOne = (Expression)Expression.Equal(keyFieldPredicate.Body, Expression.Constant(max, typeof(TValue)));

            return(query.Single(Expression.Lambda <Func <TEntity, bool> >(equalsOne, p)));
        }
コード例 #19
0
        public static Expression CreateLambdaExpression <T, TModel>(IEnumerable <FilterElement> filterElements, Type querytype, ParameterExpression arg)
        {
            Expression expression = Expression.Constant(true);

            foreach (var filterElement in filterElements)
            {
                string[]   props = filterElement.FilterSpecs.DataElement.Split('.');
                Expression propertyExpression = arg;
                var        type = typeof(T);

                Expression notNullExpression = Expression.Constant(true);

                foreach (var property in  props)
                {
                    PropertyInfo pi = type.GetProperty(property);
                    propertyExpression = Expression.Property(propertyExpression, pi);
                    var nullExpression = Expression.Constant(GetNullExpressionForType(pi.PropertyType), pi.PropertyType);
                    notNullExpression = Expression.AndAlso(notNullExpression, Expression.NotEqual(propertyExpression, nullExpression));
                    type = pi.PropertyType;
                }

                var isLiteralType = type.IsEquivalentTo(typeof(string));

                var valueExpression = Expression.Constant(filterElement.FieldValue, filterElement.Property.PropertyType);

                Expression inputExpression, variableExpression;
                if (filterElement.FilterSpecs.CaseSensitive && isLiteralType)
                {
                    variableExpression = Expression.Call(propertyExpression,
                                                         typeof(String).GetMethod("ToUpper", new Type[] { }));

                    inputExpression = Expression.Call(valueExpression,
                                                      typeof(String).GetMethod("ToUpper", new Type[] { }));
                }
                else
                {
                    // special case to handle nullable values
                    if (valueExpression.Type.IsNullable())
                    {
                        valueExpression = Expression.Constant(valueExpression.Value, filterElement.Property.PropertyType.NullableOf());
                    }


                    inputExpression    = valueExpression;
                    variableExpression = propertyExpression;
                }

                BinaryExpression conditionExpression = Expression.Equal(variableExpression, valueExpression);

                switch (filterElement.FilterSpecs.OperatorOption)
                {
                case Operator.Equal:
                    conditionExpression = Expression.Equal(variableExpression, inputExpression);
                    break;

                case Operator.GreaterThan:
                    conditionExpression = Expression.GreaterThan(variableExpression, inputExpression);
                    break;

                case Operator.GreaterThanOrEqualTo:
                    conditionExpression = Expression.GreaterThanOrEqual(variableExpression, inputExpression);
                    break;

                case Operator.LessThan:
                    conditionExpression = Expression.LessThan(variableExpression, inputExpression);
                    break;

                case Operator.LessThanOrEqualTo:
                    conditionExpression = Expression.LessThanOrEqual(variableExpression, inputExpression);
                    break;

                case Operator.Unequal:
                    conditionExpression = Expression.NotEqual(variableExpression, inputExpression);
                    break;

                case Operator.Like:
                    MethodInfo method             = typeof(string).GetMethod("Contains", new[] { typeof(string) });
                    var        containsMethodCall = Expression.Call(variableExpression, method, inputExpression);
                    conditionExpression = Expression.Equal(containsMethodCall, Expression.Constant(true));
                    break;
                }


                var clausePart = Expression.AndAlso(notNullExpression, conditionExpression);

                if (!filterElement.FieldValue.Equals(GetNullExpressionForType(filterElement.Property.PropertyType)))
                {
                    expression = Expression.AndAlso(expression, clausePart);
                }
            }

            return(expression);
        }
コード例 #20
0
        public void UnaryExpression_Unbox() => ExecuteExpr(Property.LastUp, lastUp =>
        {
            var unbox = Expr.Unbox(Expr.Convert(lastUp, typeof(object)), typeof(DateTime));

            return(Expr.Equal(unbox, Expr.Constant(new DateTime(2000, 10, 2, 12, 10, 5, DateTimeKind.Utc))));
        }, ExpressionType.Unbox, "filter_lastup=36801.5070023148");
コード例 #21
0
 public void UnaryExpression_IsFalse() => ExecuteExpr(Property.Active, active => Expr.Equal(active, Expr.IsFalse(Expr.Constant(false))), ExpressionType.IsFalse, "filter_active=-1");
コード例 #22
0
 protected void ExecuteBinaryExpr(Property property, Func <Expr, Expr> expr, ExpressionType nodeType, string url = "")
 {
     ExecuteExpr(property, v => Expr.Equal(expr(v), Expr.Constant(3)), nodeType, url);
 }
コード例 #23
0
        // TODO: do not test runtime for runtime bound sites
        // TODO: ResolveMethod invalidates modules that were not initialized yet -> snapshot version after method resolution
        // TODO: thread safety: synchronize version snapshot and method resolution
        public void AddTargetTypeTest(object target, Expression /*!*/ targetParameter, RubyContext /*!*/ context, Expression /*!*/ contextExpression)
        {
            // singleton nil:
            if (target == null)
            {
                AddRestriction(Ast.Equal(targetParameter, Ast.Constant(null)));
                context.NilClass.AddFullVersionTest(this, contextExpression);
                return;
            }

            // singletons true, false:
            if (target is bool)
            {
                AddRestriction(Ast.AndAlso(
                                   Ast.TypeIs(targetParameter, typeof(bool)),
                                   Ast.Equal(Ast.Convert(targetParameter, typeof(bool)), Ast.Constant(target))
                                   ));

                if ((bool)target)
                {
                    context.TrueClass.AddFullVersionTest(this, contextExpression);
                }
                else
                {
                    context.FalseClass.AddFullVersionTest(this, contextExpression);
                }
                return;
            }

            RubyClass immediateClass = context.GetImmediateClassOf(target);

            // user defined instance singletons, modules, classes:
            if (immediateClass.IsSingletonClass)
            {
                AddRestriction(
                    Ast.Equal(
                        Ast.Convert(targetParameter, typeof(object)),
                        Ast.Convert(Ast.Constant(target), typeof(object))
                        )
                    );

                // we need to check for a runtime (e.g. "foo" .NET string instance could be shared accross runtimes):
                immediateClass.AddFullVersionTest(this, contextExpression);
                return;
            }

            Type type = target.GetType();

            AddTypeRestriction(type, targetParameter);

            if (typeof(IRubyObject).IsAssignableFrom(type))
            {
                // Ruby objects (get the method directly to prevent interface dispatch):
                MethodInfo classGetter = type.GetMethod("get_" + RubyObject.ClassPropertyName, BindingFlags.Public | BindingFlags.Instance);
                if (classGetter != null && classGetter.ReturnType == typeof(RubyClass))
                {
                    AddCondition(
                        // (#{type})target.Class.Version == #{immediateClass.Version}
                        Ast.Equal(
                            Ast.Call(Ast.Call(Ast.Convert(targetParameter, type), classGetter), RubyModule.VersionProperty.GetGetMethod()),
                            Ast.Constant(immediateClass.Version)
                            )
                        );
                    return;
                }

                // TODO: explicit iface-implementation
                throw new NotSupportedException("Type implementing IRubyObject should have RubyClass getter");
            }
            else
            {
                // CLR objects:
                immediateClass.AddFullVersionTest(this, contextExpression);
            }
        }
コード例 #24
0
 protected void UnsupportedBinaryExpr(Property property, Func <Expr, Expr> expr, ExpressionType nodeType)
 {
     UnsupportedExpr(property, v => Expr.Equal(expr(v), Expr.Constant(3)), nodeType);
 }
コード例 #25
0
 public static Ex Eq(this Ex me, Ex other) => Ex.Equal(me, other);
        private BinaryExpression BinaryExpression(
            ExpressionType nodeType, System.Type type, JObject obj)
        {
            var left       = this.Prop(obj, "left", this.Expression);
            var right      = this.Prop(obj, "right", this.Expression);
            var method     = this.Prop(obj, "method", this.Method);
            var conversion = this.Prop(obj, "conversion", this.LambdaExpression);
            var liftToNull = this.Prop(obj, "liftToNull").Value <bool>();

            switch (nodeType)
            {
            case ExpressionType.Add: return(Expr.Add(left, right, method));

            case ExpressionType.AddAssign: return(Expr.AddAssign(left, right, method, conversion));

            case ExpressionType.AddAssignChecked: return(Expr.AddAssignChecked(left, right, method, conversion));

            case ExpressionType.AddChecked: return(Expr.AddChecked(left, right, method));

            case ExpressionType.And: return(Expr.And(left, right, method));

            case ExpressionType.AndAlso: return(Expr.AndAlso(left, right, method));

            case ExpressionType.AndAssign: return(Expr.AndAssign(left, right, method, conversion));

            case ExpressionType.ArrayIndex: return(Expr.ArrayIndex(left, right));

            case ExpressionType.Assign: return(Expr.Assign(left, right));

            case ExpressionType.Coalesce: return(Expr.Coalesce(left, right, conversion));

            case ExpressionType.Divide: return(Expr.Divide(left, right, method));

            case ExpressionType.DivideAssign: return(Expr.DivideAssign(left, right, method, conversion));

            case ExpressionType.Equal: return(Expr.Equal(left, right, liftToNull, method));

            case ExpressionType.ExclusiveOr: return(Expr.ExclusiveOr(left, right, method));

            case ExpressionType.ExclusiveOrAssign: return(Expr.ExclusiveOrAssign(left, right, method, conversion));

            case ExpressionType.GreaterThan: return(Expr.GreaterThan(left, right, liftToNull, method));

            case ExpressionType.GreaterThanOrEqual: return(Expr.GreaterThanOrEqual(left, right, liftToNull, method));

            case ExpressionType.LeftShift: return(Expr.LeftShift(left, right, method));

            case ExpressionType.LeftShiftAssign: return(Expr.LeftShiftAssign(left, right, method, conversion));

            case ExpressionType.LessThan: return(Expr.LessThan(left, right, liftToNull, method));

            case ExpressionType.LessThanOrEqual: return(Expr.LessThanOrEqual(left, right, liftToNull, method));

            case ExpressionType.Modulo: return(Expr.Modulo(left, right, method));

            case ExpressionType.ModuloAssign: return(Expr.ModuloAssign(left, right, method, conversion));

            case ExpressionType.Multiply: return(Expr.Multiply(left, right, method));

            case ExpressionType.MultiplyAssign: return(Expr.MultiplyAssign(left, right, method, conversion));

            case ExpressionType.MultiplyAssignChecked: return(Expr.MultiplyAssignChecked(left, right, method, conversion));

            case ExpressionType.MultiplyChecked: return(Expr.MultiplyChecked(left, right, method));

            case ExpressionType.NotEqual: return(Expr.NotEqual(left, right, liftToNull, method));

            case ExpressionType.Or: return(Expr.Or(left, right, method));

            case ExpressionType.OrAssign: return(Expr.OrAssign(left, right, method, conversion));

            case ExpressionType.OrElse: return(Expr.OrElse(left, right, method));

            case ExpressionType.Power: return(Expr.Power(left, right, method));

            case ExpressionType.PowerAssign: return(Expr.PowerAssign(left, right, method, conversion));

            case ExpressionType.RightShift: return(Expr.RightShift(left, right, method));

            case ExpressionType.RightShiftAssign: return(Expr.RightShiftAssign(left, right, method, conversion));

            case ExpressionType.Subtract: return(Expr.Subtract(left, right, method));

            case ExpressionType.SubtractAssign: return(Expr.SubtractAssign(left, right, method, conversion));

            case ExpressionType.SubtractAssignChecked: return(Expr.SubtractAssignChecked(left, right, method, conversion));

            case ExpressionType.SubtractChecked: return(Expr.SubtractChecked(left, right, method));

            default: throw new NotSupportedException();
            }
        }
コード例 #27
0
 /// <summary>
 /// 创建等于运算表达式
 /// </summary>
 /// <param name="left">左操作数</param>
 /// <param name="value">值</param>
 public static MicrosoftExpression Equal(this MicrosoftExpression left, object value)
 {
     return(left.Equal(Lambda.Constant(value, left)));
 }
コード例 #28
0
 /// <summary>
 /// 创建等于运算表达式
 /// </summary>
 /// <param name="left">左操作数</param>
 /// <param name="right">右操作数</param>
 public static MicrosoftExpression Equal(this MicrosoftExpression left, MicrosoftExpression right)
 {
     return(MicrosoftExpression.Equal(left, right));
 }
コード例 #29
0
        internal void SetRule(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            Assert.NotNull(metaBuilder, args);
            Debug.Assert(args.SimpleArgumentCount == 0 && !args.Signature.HasBlock && !args.Signature.HasSplattedArgument && !args.Signature.HasRhsArgument);
            Debug.Assert(args.Signature.HasScope);

            var ec = args.RubyContext;

            // implicit conversions should only depend on a static type:
            if (TryImplicitConversion(metaBuilder, args))
            {
                if (args.Target == null)
                {
                    metaBuilder.AddRestriction(Ast.Equal(args.TargetExpression, Ast.Constant(null, args.TargetExpression.Type)));
                }
                else
                {
                    metaBuilder.AddTypeRestriction(args.Target.GetType(), args.TargetExpression);
                }
                return;
            }

            // check for type version:
            metaBuilder.AddTargetTypeTest(args);

            string     toMethodName            = ToMethodName;
            Expression targetClassNameConstant = Ast.Constant(ec.GetClassOf(args.Target).Name);

            // Kernel#respond_to? method is not overridden => we can optimize
            RubyMemberInfo respondToMethod = ec.ResolveMethod(args.Target, Symbols.RespondTo, true).InvalidateSitesOnOverride();

            if (respondToMethod == null ||
                // the method is defined in library, hasn't been replaced by user defined method (TODO: maybe we should make this check better)
                (respondToMethod.DeclaringModule == ec.KernelModule && respondToMethod is RubyMethodGroupInfo))
            {
                RubyMemberInfo conversionMethod = ec.ResolveMethod(args.Target, toMethodName, false).InvalidateSitesOnOverride();
                if (conversionMethod == null)
                {
                    // error:
                    SetError(metaBuilder, targetClassNameConstant, args);
                    return;
                }
                else
                {
                    // invoke target.to_xxx() and validate it; returns an instance of TTargetType:
                    conversionMethod.BuildCall(metaBuilder, args, toMethodName);

                    if (!metaBuilder.Error && ConversionResultValidator != null)
                    {
                        metaBuilder.Result = ConversionResultValidator.OpCall(targetClassNameConstant, AstFactory.Box(metaBuilder.Result));
                    }
                    return;
                }
            }
            else if (!RubyModule.IsMethodVisible(respondToMethod, false))
            {
                // respond_to? is private:
                SetError(metaBuilder, targetClassNameConstant, args);
                return;
            }

            // slow path: invoke respond_to?, to_xxx and result validation:

            var conversionCallSite = Ast.Dynamic(
                RubyCallAction.Make(toMethodName, RubyCallSignature.WithScope(0)),
                typeof(object),
                args.ScopeExpression, args.TargetExpression
                );

            Expression opCall;

            metaBuilder.Result = Ast.Condition(
                // If

                // respond_to?()
                Methods.IsTrue.OpCall(
                    Ast.Dynamic(
                        RubyCallAction.Make(Symbols.RespondTo, RubyCallSignature.WithScope(1)),
                        typeof(object),
                        args.ScopeExpression, args.TargetExpression, Ast.Constant(SymbolTable.StringToId(toMethodName))
                        )
                    ),

                // Then

                // to_xxx():
                opCall = (ConversionResultValidator == null) ? conversionCallSite :
                         ConversionResultValidator.OpCall(targetClassNameConstant, conversionCallSite),

                // Else

                AstUtils.Convert(
                    (ConversionResultValidator == null) ? args.TargetExpression :
                    Ast.Convert(
                        Ast.Throw(Methods.CreateTypeConversionError.OpCall(targetClassNameConstant, Ast.Constant(TargetTypeName))),
                        typeof(object)
                        ),
                    opCall.Type
                    )
                );
        }
コード例 #30
0
        public static Expression[] /*!*/ MakeActualArgs(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args,
                                                        bool includeSelf, bool selfIsInstance, bool calleeHasBlockParam, bool injectMissingBlockParam)
        {
            var actualArgs = new List <Expression>(args.ExplicitArgumentCount);

            // self (instance):
            if (includeSelf && selfIsInstance)
            {
                // test already added by method resolver
                Debug.Assert(args.TargetExpression != null);
                AddArgument(actualArgs, args.Target, args.TargetExpression);
            }

            Proc       block           = null;
            Expression blockExpression = null;

            // block test - we need to test for a block regardless of whether it is actually passed to the method or not
            // since the information that the block is not null is used for overload resolution.
            if (args.Signature.HasBlock)
            {
                block           = args.GetBlock();
                blockExpression = args.GetBlockExpression();

                if (block == null)
                {
                    metaBuilder.AddRestriction(Ast.Equal(blockExpression, Ast.Constant(null)));
                }
                else
                {
                    // don't need to test the exact type of the Proc since the code is subclass agnostic:
                    metaBuilder.AddRestriction(Ast.NotEqual(blockExpression, Ast.Constant(null)));
                }
            }

            // block:
            if (calleeHasBlockParam)
            {
                if (args.Signature.HasBlock)
                {
                    if (block == null)
                    {
                        // the user explicitly passed nil as a block arg:
                        actualArgs.Add(Ast.Constant(null));
                    }
                    else
                    {
                        // pass BlockParam:
                        Debug.Assert(metaBuilder.BfcVariable != null);
                        actualArgs.Add(metaBuilder.BfcVariable);
                    }
                }
                else
                {
                    // no block passed into a method with a BlockParam:
                    actualArgs.Add(Ast.Constant(null));
                }
            }
            else if (injectMissingBlockParam)
            {
                // no block passed into a method w/o a BlockParam (we still need to fill the missing block argument):
                actualArgs.Add(Ast.Constant(null));
            }

            // self (non-instance):
            if (includeSelf && !selfIsInstance)
            {
                // test already added by method resolver
                AddArgument(actualArgs, args.Target, args.TargetExpression);
            }

            // simple arguments:
            for (int i = 0; i < args.SimpleArgumentCount; i++)
            {
                var value = args.GetSimpleArgument(i);
                var expr  = args.GetSimpleArgumentExpression(i);

                metaBuilder.AddObjectTypeRestriction(value, expr);
                AddArgument(actualArgs, value, expr);
            }

            // splat argument:
            int listLength;
            ParameterExpression listVariable;

            if (args.Signature.HasSplattedArgument)
            {
                object     splattedArg           = args.GetSplattedArgument();
                Expression splattedArgExpression = args.GetSplattedArgumentExpression();

                if (metaBuilder.AddSplattedArgumentTest(splattedArg, splattedArgExpression, out listLength, out listVariable))
                {
                    // AddTestForListArg only returns 'true' if the argument is a List<object>
                    var list = (List <object>)splattedArg;

                    // get arguments, add tests
                    for (int j = 0; j < listLength; j++)
                    {
                        var value = list[j];
                        var expr  = Ast.Call(listVariable, typeof(List <object>).GetMethod("get_Item"), Ast.Constant(j));

                        metaBuilder.AddObjectTypeCondition(value, expr);
                        AddArgument(actualArgs, value, expr);
                    }
                }
                else
                {
                    // argument is not an array => add the argument itself:
                    AddArgument(actualArgs, splattedArg, splattedArgExpression);
                }
            }

            // rhs argument:
            if (args.Signature.HasRhsArgument)
            {
                var value = args.GetRhsArgument();
                var expr  = args.GetRhsArgumentExpression();

                metaBuilder.AddObjectTypeRestriction(value, expr);
                AddArgument(actualArgs, value, expr);
            }

            return(actualArgs.ToArray());
        }