Пример #1
0
        public object VisitUnary(UnaryExpression node)
        {
            var value = node.Operand.Accept(this);

            if (node.NodeType == ExpressionType.Parenthesized)
            {
                node.Type = node.Operand.Type;
                return(value);
            }
            //modified a++; updated new value
            bool modified = false, updated = true;

            switch (node.NodeType)
            {
            case ExpressionType.PostfixPlusPlus:
                modified = true;
                updated  = false;
                break;

            case ExpressionType.PrefixPlusPlus:
                modified = true;
                break;

            case ExpressionType.PostfixMinusMinus:
                modified = true;
                updated  = false;
                break;

            case ExpressionType.PrefixMinusMinus:
                modified = true;
                break;

            case ExpressionType.Bang:
                // here value is null it is as not defined
                if (value is null)
                {
                    return(Boolean.True);
                }
                break;
            }
            if (value is null)
            {
                ExecutionException.ThrowNullError(node.Operand, node);
            }
            // no primitive supported it should be wrapped

            //resolve call
            if (node.Method is null)
            {
                Type type = node.Operand.Type;
                ArgumentConversions          conversions = new ArgumentConversions(1);
                System.Reflection.MethodInfo method;
                if (type.IsPrimitive)
                {
                    type   = TypeProvider.Find(Type.GetTypeCode(type));
                    method = ReflectionUtils.GetOperatorOverload(node.MethodName, conversions, type);
                    conversions.AddFirst(new ParamConversion(0, ReflectionHelpers.ToAny));
                }
                else
                {
                    method = ReflectionUtils.GetOperatorOverload(node.MethodName, conversions, type);
                }
                if (method is null)
                {
                    ExecutionException.ThrowInvalidOp(node);
                }
                node.Conversions = conversions;
                node.Method      = method;
                node.Type        = method.ReturnType;
            }
            object[] args = new object[1] {
                value
            };
            node.Conversions.Invoke(ref args);
            object obj = node.Method.Invoke(null, args);

            if (modified)
            {
                if (node.Operand.NodeType == ExpressionType.Literal)
                {
                    ExecutionException.ThrowNotSupported(node);
                }
                var exp = new AssignmentExpression(node.Operand, new LiteralExpression(obj));
                exp.Accept(this);
            }
            return(updated ? obj : value);
        }