Beispiel #1
0
            internal IncrementDecrementOperatorNode(InternalUnaryOperatorType type, ExpressionNode operand, MethodReference overload)
                : base(operand.SequencePoint)
            {
                OverloadedOperatorMethod = overload;
                this.operand             = operand;
                switch (type)
                {
                case InternalUnaryOperatorType.PreIncrement:
                    IncrementDecrementType = IncrementDecrementOperatorType.PreIncrement;
                    break;

                case InternalUnaryOperatorType.PreDecrement:
                    IncrementDecrementType = IncrementDecrementOperatorType.PreDecrement;
                    break;

                case InternalUnaryOperatorType.PostIncrement:
                    IncrementDecrementType = IncrementDecrementOperatorType.PostIncrement;
                    break;

                case InternalUnaryOperatorType.PostDecrement:
                    IncrementDecrementType = IncrementDecrementOperatorType.PostDecrement;
                    break;

                default:
                    throw new ArgumentException();
                }
            }
Beispiel #2
0
        private static bool IsIncrementDecrement(InternalUnaryOperatorType op)
        {
            switch (op)
            {
            case InternalUnaryOperatorType.BinaryNot:
            case InternalUnaryOperatorType.LogicalNot:
            case InternalUnaryOperatorType.Negation:
                return(false);

            case InternalUnaryOperatorType.PreIncrement:
            case InternalUnaryOperatorType.PreDecrement:
            case InternalUnaryOperatorType.PostIncrement:
            case InternalUnaryOperatorType.PostDecrement:
                return(true);

            default:
                throw new ArgumentException();
            }
        }
Beispiel #3
0
            internal UnaryOperatorNode(InternalUnaryOperatorType type, ExpressionNode operand)
                : base(operand.SequencePoint)
            {
                this.operand = operand;
                switch (type)
                {
                case InternalUnaryOperatorType.BinaryNot:
                    this.UnaryOperatorType = UnaryOperatorNodeType.BinaryNot;
                    break;

                case InternalUnaryOperatorType.LogicalNot:
                    this.UnaryOperatorType = UnaryOperatorNodeType.LogicalNot;
                    break;

                case InternalUnaryOperatorType.Negation:
                    this.UnaryOperatorType = UnaryOperatorNodeType.Negation;
                    break;

                default:
                    throw new ArgumentException();
                }
            }
Beispiel #4
0
 private static void OperatorMissmatch(SequencePoint point, InternalUnaryOperatorType op, TypeReference operand)
 {
     ErrorCode.TypeMismatch.ReportAndThrow(point,
                                           "Unable to perform {0} on operand {1}, no built int operation or operaror overload found",
                                           op, operand.FullName);
 }
Beispiel #5
0
 private static ExpressionNode AsBinary(ExpressionNode expression, InternalUnaryOperatorType op)
 {
     return(expression.ExpressionReturnType.IsIntegerType() ? new UnaryOperatorNode(op, expression) : null);
 }
Beispiel #6
0
 private static ExpressionNode AsLogical(ExpressionNode expression, InternalUnaryOperatorType op)
 {
     return(expression.ExpressionReturnType.IsBooleanType() ? new UnaryOperatorNode(op, expression) : null);
 }
Beispiel #7
0
 private static ExpressionNode AsNegation(ExpressionNode expression, InternalUnaryOperatorType op)
 {
     return(expression.ExpressionReturnType.IsSignedInteger() ? new UnaryOperatorNode(op, expression) : null);
 }
Beispiel #8
0
 private static ExpressionNode AsInc(ExpressionNode expression, InternalUnaryOperatorType op)
 {
     return(expression.ExpressionReturnType.IsNumericType() ? new IncrementDecrementOperatorNode(op, expression, null) : null);
 }
Beispiel #9
0
        public static ExpressionNode Create(ContextNode context, ExpressionNode expression, InternalUnaryOperatorType op)
        {
            if (!expression.IsGettable)
            {
                ErrorCode.NotAnRValue.ReportAndThrow(expression.SequencePoint, "Unary operands must be gettable");
            }
            if (!expression.IsSettable && IsIncrementDecrement(op))
            {
                ErrorCode.NotAnLValue.ReportAndThrow(expression.SequencePoint, "Unary operation {0} requires a settable operand", op);
            }

            ExpressionNode result = AsBuiltIn(context, expression, op);

            if (result == null)
            {
                result = AsOverload(context, expression, op);
            }

            if (result == null)
            {
                OperatorMissmatch(expression.SequencePoint, op, expression.ExpressionReturnType);
            }

            Contract.Assume(result != null);
            return(result);
        }
Beispiel #10
0
        private static ExpressionNode CreateOverload(ContextNode context, ExpressionNode expression, InternalUnaryOperatorType op, MethodReference method)
        {
            var point = expression.SequencePoint;

            if (IsIncrementDecrement(op))
            {
                TypeUtils.VerifyAccessible(method, context.GetClass().TypeReference, point);
                return(new IncrementDecrementOperatorNode(op, expression, method));
            }
            else
            {
                return(MethodCallNode.Create(context, new MethodNode(method, null, context, point), expression.Enumerate(), point));
            }
        }
Beispiel #11
0
        private static ExpressionNode AsOverload(ContextNode context, ExpressionNode expression, InternalUnaryOperatorType op)
        {
            string name      = Overloads[op];
            var    point     = expression.SequencePoint;
            var    methods   = TypeUtils.GetOperatorMethods(context.Assembly, expression, name);
            var    argsTypes = expression.ExpressionReturnType.Enumerate();

            methods = methods.Where(m => MetadataHelpers.MatchesArgumentList(m, argsTypes));

            var method = AssemblyRegistry.GetCompatibleMethod(methods, argsTypes);

            if (method != null)
            {
                return(CreateOverload(context, expression, op, method));
            }
            else
            {
                if (methods.Count() == 0)
                {
                    return(null);
                }
                else
                {
                    ErrorCode.TypeMismatch.ReportAndThrow(point,
                                                          "Overloaded operator {0} for operand {1} is ambiguous",
                                                          name, expression.ExpressionReturnType.FullName);
                    return(null);//unreachable
                }
            }
        }
Beispiel #12
0
        private static ExpressionNode AsBuiltIn(ContextNode context, ExpressionNode expression, InternalUnaryOperatorType op)
        {
            ExpressionNode instance = null;

            switch (op)
            {
            case InternalUnaryOperatorType.BinaryNot:
                instance = AsBinary(expression, op);
                break;

            case InternalUnaryOperatorType.LogicalNot:
                instance = AsLogical(expression, op);
                break;

            case InternalUnaryOperatorType.Negation:
                instance = AsNegation(expression, op);
                break;

            case InternalUnaryOperatorType.PostDecrement:
            case InternalUnaryOperatorType.PostIncrement:
            case InternalUnaryOperatorType.PreDecrement:
            case InternalUnaryOperatorType.PreIncrement:
                instance = AsInc(expression, op);
                break;

            default:
                ErrorCode.InvalidStructure.ReportAndThrow(expression.SequencePoint, "Unary op expected, '{0}' received", op);
                break;    //unreachable
            }
            return(instance);
        }