2
// BinaryOperatorExpression.cs
5
// Mike KrĆ¼ger <mkrueger@novell.com>
7
// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
10
// of this software and associated documentation files (the "Software"), to deal
11
// in the Software without restriction, including without limitation the rights
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
// copies of the Software, and to permit persons to whom the Software is
14
// furnished to do so, subject to the following conditions:
16
// The above copyright notice and this permission notice shall be included in
17
// all copies or substantial portions of the Software.
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28
using System.Linq.Expressions;
30
namespace ICSharpCode.NRefactory.CSharp
33
/// Left Operator Right
35
public class BinaryOperatorExpression : Expression
37
public readonly static TokenRole BitwiseAndRole = new TokenRole ("&");
38
public readonly static TokenRole BitwiseOrRole = new TokenRole ("|");
39
public readonly static TokenRole ConditionalAndRole = new TokenRole ("&&");
40
public readonly static TokenRole ConditionalOrRole = new TokenRole ("||");
41
public readonly static TokenRole ExclusiveOrRole = new TokenRole ("^");
42
public readonly static TokenRole GreaterThanRole = new TokenRole (">");
43
public readonly static TokenRole GreaterThanOrEqualRole = new TokenRole (">=");
44
public readonly static TokenRole EqualityRole = new TokenRole ("==");
45
public readonly static TokenRole InEqualityRole = new TokenRole ("!=");
46
public readonly static TokenRole LessThanRole = new TokenRole ("<");
47
public readonly static TokenRole LessThanOrEqualRole = new TokenRole ("<=");
48
public readonly static TokenRole AddRole = new TokenRole ("+");
49
public readonly static TokenRole SubtractRole = new TokenRole ("-");
50
public readonly static TokenRole MultiplyRole = new TokenRole ("*");
51
public readonly static TokenRole DivideRole = new TokenRole ("/");
52
public readonly static TokenRole ModulusRole = new TokenRole ("%");
53
public readonly static TokenRole ShiftLeftRole = new TokenRole ("<<");
54
public readonly static TokenRole ShiftRightRole = new TokenRole (">>");
55
public readonly static TokenRole NullCoalescingRole = new TokenRole ("??");
57
public readonly static Role<Expression> LeftRole = new Role<Expression>("Left", Expression.Null);
58
public readonly static Role<Expression> RightRole = new Role<Expression>("Right", Expression.Null);
60
public BinaryOperatorExpression()
64
public BinaryOperatorExpression(Expression left, BinaryOperatorType op, Expression right)
71
public BinaryOperatorType Operator {
76
public Expression Left {
77
get { return GetChildByRole (LeftRole); }
78
set { SetChildByRole(LeftRole, value); }
81
public CSharpTokenNode OperatorToken {
82
get { return GetChildByRole (GetOperatorRole (Operator)); }
85
public Expression Right {
86
get { return GetChildByRole (RightRole); }
87
set { SetChildByRole (RightRole, value); }
90
public override void AcceptVisitor (IAstVisitor visitor)
92
visitor.VisitBinaryOperatorExpression (this);
95
public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
97
return visitor.VisitBinaryOperatorExpression (this);
100
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
102
return visitor.VisitBinaryOperatorExpression (this, data);
105
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
107
BinaryOperatorExpression o = other as BinaryOperatorExpression;
108
return o != null && (this.Operator == BinaryOperatorType.Any || this.Operator == o.Operator)
109
&& this.Left.DoMatch(o.Left, match) && this.Right.DoMatch(o.Right, match);
112
public static TokenRole GetOperatorRole (BinaryOperatorType op)
115
case BinaryOperatorType.BitwiseAnd:
116
return BitwiseAndRole;
117
case BinaryOperatorType.BitwiseOr:
118
return BitwiseOrRole;
119
case BinaryOperatorType.ConditionalAnd:
120
return ConditionalAndRole;
121
case BinaryOperatorType.ConditionalOr:
122
return ConditionalOrRole;
123
case BinaryOperatorType.ExclusiveOr:
124
return ExclusiveOrRole;
125
case BinaryOperatorType.GreaterThan:
126
return GreaterThanRole;
127
case BinaryOperatorType.GreaterThanOrEqual:
128
return GreaterThanOrEqualRole;
129
case BinaryOperatorType.Equality:
131
case BinaryOperatorType.InEquality:
132
return InEqualityRole;
133
case BinaryOperatorType.LessThan:
135
case BinaryOperatorType.LessThanOrEqual:
136
return LessThanOrEqualRole;
137
case BinaryOperatorType.Add:
139
case BinaryOperatorType.Subtract:
141
case BinaryOperatorType.Multiply:
143
case BinaryOperatorType.Divide:
145
case BinaryOperatorType.Modulus:
147
case BinaryOperatorType.ShiftLeft:
148
return ShiftLeftRole;
149
case BinaryOperatorType.ShiftRight:
150
return ShiftRightRole;
151
case BinaryOperatorType.NullCoalescing:
152
return NullCoalescingRole;
154
throw new NotSupportedException("Invalid value for BinaryOperatorType");
158
public static ExpressionType GetLinqNodeType(BinaryOperatorType op, bool checkForOverflow)
161
case BinaryOperatorType.BitwiseAnd:
162
return ExpressionType.And;
163
case BinaryOperatorType.BitwiseOr:
164
return ExpressionType.Or;
165
case BinaryOperatorType.ConditionalAnd:
166
return ExpressionType.AndAlso;
167
case BinaryOperatorType.ConditionalOr:
168
return ExpressionType.OrElse;
169
case BinaryOperatorType.ExclusiveOr:
170
return ExpressionType.ExclusiveOr;
171
case BinaryOperatorType.GreaterThan:
172
return ExpressionType.GreaterThan;
173
case BinaryOperatorType.GreaterThanOrEqual:
174
return ExpressionType.GreaterThanOrEqual;
175
case BinaryOperatorType.Equality:
176
return ExpressionType.Equal;
177
case BinaryOperatorType.InEquality:
178
return ExpressionType.NotEqual;
179
case BinaryOperatorType.LessThan:
180
return ExpressionType.LessThan;
181
case BinaryOperatorType.LessThanOrEqual:
182
return ExpressionType.LessThanOrEqual;
183
case BinaryOperatorType.Add:
184
return checkForOverflow ? ExpressionType.AddChecked : ExpressionType.Add;
185
case BinaryOperatorType.Subtract:
186
return checkForOverflow ? ExpressionType.SubtractChecked : ExpressionType.Subtract;
187
case BinaryOperatorType.Multiply:
188
return checkForOverflow ? ExpressionType.MultiplyChecked : ExpressionType.Multiply;
189
case BinaryOperatorType.Divide:
190
return ExpressionType.Divide;
191
case BinaryOperatorType.Modulus:
192
return ExpressionType.Modulo;
193
case BinaryOperatorType.ShiftLeft:
194
return ExpressionType.LeftShift;
195
case BinaryOperatorType.ShiftRight:
196
return ExpressionType.RightShift;
197
case BinaryOperatorType.NullCoalescing:
198
return ExpressionType.Coalesce;
200
throw new NotSupportedException("Invalid value for BinaryOperatorType");
205
public enum BinaryOperatorType
208
/// Any binary operator (used in pattern matching)
212
// We avoid 'logical or' on purpose, because it's not clear if that refers to the bitwise
213
// or to the short-circuiting (conditional) operator:
214
// MCS and old NRefactory used bitwise='|', logical='||'
215
// but the C# spec uses logical='|', conditional='||'
216
/// <summary>left & right</summary>
218
/// <summary>left | right</summary>
220
/// <summary>left && right</summary>
222
/// <summary>left || right</summary>
224
/// <summary>left ^ right</summary>
227
/// <summary>left > right</summary>
229
/// <summary>left >= right</summary>
231
/// <summary>left == right</summary>
233
/// <summary>left != right</summary>
235
/// <summary>left < right</summary>
237
/// <summary>left <= right</summary>
240
/// <summary>left + right</summary>
242
/// <summary>left - right</summary>
244
/// <summary>left * right</summary>
246
/// <summary>left / right</summary>
248
/// <summary>left % right</summary>
251
/// <summary>left << right</summary>
253
/// <summary>left >> right</summary>
256
/// <summary>left ?? right</summary>