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(); } }
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(); } }
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(); } }
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); }
private static ExpressionNode AsBinary(ExpressionNode expression, InternalUnaryOperatorType op) { return(expression.ExpressionReturnType.IsIntegerType() ? new UnaryOperatorNode(op, expression) : null); }
private static ExpressionNode AsLogical(ExpressionNode expression, InternalUnaryOperatorType op) { return(expression.ExpressionReturnType.IsBooleanType() ? new UnaryOperatorNode(op, expression) : null); }
private static ExpressionNode AsNegation(ExpressionNode expression, InternalUnaryOperatorType op) { return(expression.ExpressionReturnType.IsSignedInteger() ? new UnaryOperatorNode(op, expression) : null); }
private static ExpressionNode AsInc(ExpressionNode expression, InternalUnaryOperatorType op) { return(expression.ExpressionReturnType.IsNumericType() ? new IncrementDecrementOperatorNode(op, expression, null) : null); }
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); }
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)); } }
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 } } }
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); }