2
// <copyright see="prj:///doc/copyright.txt"/>
3
// <license see="prj:///doc/license.txt"/>
4
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
5
// <version>$Revision: 972 $</version>
10
using NUnit.Framework;
11
using ICSharpCode.NRefactory.Parser;
12
using ICSharpCode.NRefactory.Parser.AST;
13
using ICSharpCode.NRefactory.PrettyPrinter;
15
namespace ICSharpCode.NRefactory.Tests.AST
18
public class BinaryOperatorExpressionTests
20
void OperatorPrecedenceTest(string strongOperator, BinaryOperatorType strongOperatorType,
21
string weakOperator, BinaryOperatorType weakOperatorType, bool vb)
23
string program = "a " + weakOperator + " b " + strongOperator + " c";
24
BinaryOperatorExpression boe;
26
boe = ParseUtilVBNet.ParseExpression<BinaryOperatorExpression>(program);
28
boe = ParseUtilCSharp.ParseExpression<BinaryOperatorExpression>(program);
29
Assert.AreEqual(weakOperatorType, boe.Op);
30
Assert.IsTrue(boe.Left is IdentifierExpression);
31
boe = (BinaryOperatorExpression)boe.Right;
32
Assert.AreEqual(strongOperatorType, boe.Op);
33
Assert.IsTrue(boe.Left is IdentifierExpression);
34
Assert.IsTrue(boe.Right is IdentifierExpression);
36
program = "a " + strongOperator + " b " + weakOperator + " c";
38
boe = ParseUtilVBNet.ParseExpression<BinaryOperatorExpression>(program);
40
boe = ParseUtilCSharp.ParseExpression<BinaryOperatorExpression>(program);
41
Assert.AreEqual(weakOperatorType, boe.Op);
42
Assert.IsTrue(boe.Right is IdentifierExpression);
43
boe = (BinaryOperatorExpression)boe.Left;
44
Assert.AreEqual(strongOperatorType, boe.Op);
45
Assert.IsTrue(boe.Left is IdentifierExpression);
46
Assert.IsTrue(boe.Right is IdentifierExpression);
49
void SameOperatorPrecedenceTest(string firstOperator, BinaryOperatorType firstOperatorType,
50
string secondOperator, BinaryOperatorType secondOperatorType, bool vb)
52
string program = "a " + secondOperator + " b " + firstOperator + " c";
53
BinaryOperatorExpression boe;
55
boe = ParseUtilVBNet.ParseExpression<BinaryOperatorExpression>(program);
57
boe = ParseUtilCSharp.ParseExpression<BinaryOperatorExpression>(program);
58
Assert.AreEqual(firstOperatorType, boe.Op);
59
Assert.IsTrue(boe.Right is IdentifierExpression);
60
boe = (BinaryOperatorExpression)boe.Left;
61
Assert.AreEqual(secondOperatorType, boe.Op);
62
Assert.IsTrue(boe.Left is IdentifierExpression);
63
Assert.IsTrue(boe.Right is IdentifierExpression);
65
program = "a " + firstOperator + " b " + secondOperator + " c";
67
boe = ParseUtilVBNet.ParseExpression<BinaryOperatorExpression>(program);
69
boe = ParseUtilCSharp.ParseExpression<BinaryOperatorExpression>(program);
70
Assert.AreEqual(secondOperatorType, boe.Op);
71
Assert.IsTrue(boe.Right is IdentifierExpression);
72
boe = (BinaryOperatorExpression)boe.Left;
73
Assert.AreEqual(firstOperatorType, boe.Op);
74
Assert.IsTrue(boe.Left is IdentifierExpression);
75
Assert.IsTrue(boe.Right is IdentifierExpression);
79
void CSharpTestBinaryOperatorExpressionTest(string program, BinaryOperatorType op)
81
BinaryOperatorExpression boe = ParseUtilCSharp.ParseExpression<BinaryOperatorExpression>(program);
82
Assert.AreEqual(op, boe.Op);
84
Assert.IsTrue(boe.Left is IdentifierExpression);
85
Assert.IsTrue(boe.Right is IdentifierExpression);
90
public void CSharpOperatorPrecedenceTest()
92
SameOperatorPrecedenceTest("*", BinaryOperatorType.Multiply, "/", BinaryOperatorType.Divide, false);
93
SameOperatorPrecedenceTest("*", BinaryOperatorType.Multiply, "%", BinaryOperatorType.Modulus, false);
94
OperatorPrecedenceTest("*", BinaryOperatorType.Multiply, "+", BinaryOperatorType.Add, false);
95
SameOperatorPrecedenceTest("-", BinaryOperatorType.Subtract, "+", BinaryOperatorType.Add, false);
96
OperatorPrecedenceTest("+", BinaryOperatorType.Add, "<<", BinaryOperatorType.ShiftLeft, false);
97
SameOperatorPrecedenceTest(">>", BinaryOperatorType.ShiftRight, "<<", BinaryOperatorType.ShiftLeft, false);
98
OperatorPrecedenceTest("<<", BinaryOperatorType.ShiftLeft, "==", BinaryOperatorType.Equality, false);
99
SameOperatorPrecedenceTest("!=", BinaryOperatorType.InEquality, "==", BinaryOperatorType.Equality, false);
100
OperatorPrecedenceTest("==", BinaryOperatorType.Equality, "&", BinaryOperatorType.BitwiseAnd, false);
101
OperatorPrecedenceTest("&", BinaryOperatorType.BitwiseAnd, "^", BinaryOperatorType.ExclusiveOr, false);
102
OperatorPrecedenceTest("^", BinaryOperatorType.ExclusiveOr, "|", BinaryOperatorType.BitwiseOr, false);
103
OperatorPrecedenceTest("|", BinaryOperatorType.BitwiseOr, "&&", BinaryOperatorType.LogicalAnd, false);
104
OperatorPrecedenceTest("&&", BinaryOperatorType.LogicalAnd, "||", BinaryOperatorType.LogicalOr, false);
105
OperatorPrecedenceTest("||", BinaryOperatorType.LogicalOr, "??", BinaryOperatorType.NullCoalescing, false);
109
public void CSharpSubtractionLeftToRight()
111
BinaryOperatorExpression boe = ParseUtilCSharp.ParseExpression<BinaryOperatorExpression>("a - b - c");
112
Assert.IsTrue(boe.Right is IdentifierExpression);
113
Assert.IsTrue(boe.Left is BinaryOperatorExpression);
117
public void CSharpNullCoalescingRightToLeft()
119
BinaryOperatorExpression boe = ParseUtilCSharp.ParseExpression<BinaryOperatorExpression>("a ?? b ?? c");
120
Assert.IsTrue(boe.Left is IdentifierExpression);
121
Assert.IsTrue(boe.Right is BinaryOperatorExpression);
125
public void CSharpBitwiseAndTest()
127
CSharpTestBinaryOperatorExpressionTest("a & b", BinaryOperatorType.BitwiseAnd);
131
public void CSharpBitwiseOrTest()
133
CSharpTestBinaryOperatorExpressionTest("a | b", BinaryOperatorType.BitwiseOr);
137
public void CSharpLogicalAndTest()
139
CSharpTestBinaryOperatorExpressionTest("a && b", BinaryOperatorType.LogicalAnd);
143
public void CSharpLogicalOrTest()
145
CSharpTestBinaryOperatorExpressionTest("a || b", BinaryOperatorType.LogicalOr);
149
public void CSharpExclusiveOrTest()
151
CSharpTestBinaryOperatorExpressionTest("a ^ b", BinaryOperatorType.ExclusiveOr);
156
public void CSharpGreaterThanTest()
158
CSharpTestBinaryOperatorExpressionTest("a > b", BinaryOperatorType.GreaterThan);
162
public void CSharpGreaterThanOrEqualTest()
164
CSharpTestBinaryOperatorExpressionTest("a >= b", BinaryOperatorType.GreaterThanOrEqual);
168
public void CSharpEqualityTest()
170
CSharpTestBinaryOperatorExpressionTest("a == b", BinaryOperatorType.Equality);
174
public void CSharpInEqualityTest()
176
CSharpTestBinaryOperatorExpressionTest("a != b", BinaryOperatorType.InEquality);
180
public void CSharpLessThanTest()
182
CSharpTestBinaryOperatorExpressionTest("a < b", BinaryOperatorType.LessThan);
186
public void CSharpLessThanOrEqualTest()
188
CSharpTestBinaryOperatorExpressionTest("a <= b", BinaryOperatorType.LessThanOrEqual);
192
public void CSharpAddTest()
194
CSharpTestBinaryOperatorExpressionTest("a + b", BinaryOperatorType.Add);
198
public void CSharpSubtractTest()
200
CSharpTestBinaryOperatorExpressionTest("a - b", BinaryOperatorType.Subtract);
204
public void CSharpMultiplyTest()
206
CSharpTestBinaryOperatorExpressionTest("a * b", BinaryOperatorType.Multiply);
210
public void CSharpDivideTest()
212
CSharpTestBinaryOperatorExpressionTest("a / b", BinaryOperatorType.Divide);
216
public void CSharpModulusTest()
218
CSharpTestBinaryOperatorExpressionTest("a % b", BinaryOperatorType.Modulus);
222
public void CSharpShiftLeftTest()
224
CSharpTestBinaryOperatorExpressionTest("a << b", BinaryOperatorType.ShiftLeft);
228
public void CSharpShiftRightTest()
230
CSharpTestBinaryOperatorExpressionTest("a >> b", BinaryOperatorType.ShiftRight);
234
public void CSharpNullCoalescingTest()
236
CSharpTestBinaryOperatorExpressionTest("a ?? b", BinaryOperatorType.NullCoalescing);
241
void VBNetTestBinaryOperatorExpressionTest(string program, BinaryOperatorType op)
243
BinaryOperatorExpression boe = ParseUtilVBNet.ParseExpression<BinaryOperatorExpression>(program);
244
Assert.AreEqual(op, boe.Op);
246
Assert.IsTrue(boe.Left is IdentifierExpression);
247
Assert.IsTrue(boe.Right is IdentifierExpression);
252
public void VBOperatorPrecedenceTest()
254
OperatorPrecedenceTest("^", BinaryOperatorType.Power, "*", BinaryOperatorType.Multiply, true);
255
SameOperatorPrecedenceTest("*", BinaryOperatorType.Multiply, "/", BinaryOperatorType.Divide, true);
256
OperatorPrecedenceTest("/", BinaryOperatorType.Divide, "\\", BinaryOperatorType.DivideInteger, true);
257
OperatorPrecedenceTest("\\", BinaryOperatorType.DivideInteger, "Mod", BinaryOperatorType.Modulus, true);
258
OperatorPrecedenceTest("Mod", BinaryOperatorType.Modulus, "+", BinaryOperatorType.Add, true);
259
SameOperatorPrecedenceTest("+", BinaryOperatorType.Add, "-", BinaryOperatorType.Subtract, true);
260
OperatorPrecedenceTest("-", BinaryOperatorType.Subtract, "&", BinaryOperatorType.Concat, true);
261
OperatorPrecedenceTest("&", BinaryOperatorType.Concat, "<<", BinaryOperatorType.ShiftLeft, true);
262
SameOperatorPrecedenceTest("<<", BinaryOperatorType.ShiftLeft, ">>", BinaryOperatorType.ShiftRight, true);
263
OperatorPrecedenceTest("<<", BinaryOperatorType.ShiftLeft, "=", BinaryOperatorType.Equality, true);
264
SameOperatorPrecedenceTest("<>", BinaryOperatorType.InEquality, "=", BinaryOperatorType.Equality, true);
265
SameOperatorPrecedenceTest("<", BinaryOperatorType.LessThan, "=", BinaryOperatorType.Equality, true);
266
SameOperatorPrecedenceTest("<=", BinaryOperatorType.LessThanOrEqual, "=", BinaryOperatorType.Equality, true);
267
SameOperatorPrecedenceTest(">", BinaryOperatorType.GreaterThan, "=", BinaryOperatorType.Equality, true);
268
SameOperatorPrecedenceTest(">=", BinaryOperatorType.GreaterThanOrEqual, "=", BinaryOperatorType.Equality, true);
269
SameOperatorPrecedenceTest("Like", BinaryOperatorType.Like, "=", BinaryOperatorType.Equality, true);
270
SameOperatorPrecedenceTest("Is", BinaryOperatorType.ReferenceEquality, "=", BinaryOperatorType.Equality, true);
271
SameOperatorPrecedenceTest("IsNot", BinaryOperatorType.ReferenceInequality, "=", BinaryOperatorType.Equality, true);
272
OperatorPrecedenceTest("=", BinaryOperatorType.Equality, "And", BinaryOperatorType.BitwiseAnd, true);
273
SameOperatorPrecedenceTest("And", BinaryOperatorType.BitwiseAnd, "AndAlso", BinaryOperatorType.LogicalAnd, true);
274
OperatorPrecedenceTest("And", BinaryOperatorType.BitwiseAnd, "Or", BinaryOperatorType.BitwiseOr, true);
275
SameOperatorPrecedenceTest("Or", BinaryOperatorType.BitwiseOr, "OrElse", BinaryOperatorType.LogicalOr, true);
276
SameOperatorPrecedenceTest("Or", BinaryOperatorType.BitwiseOr, "Xor", BinaryOperatorType.ExclusiveOr, true);
280
public void VBNetTest()
282
VBNetTestBinaryOperatorExpressionTest("a ^ b", BinaryOperatorType.Power);
286
public void VBNetPowerTest()
288
VBNetTestBinaryOperatorExpressionTest("a ^ b", BinaryOperatorType.Power);
292
public void VBNetConcatTest()
294
VBNetTestBinaryOperatorExpressionTest("a & b", BinaryOperatorType.Concat);
298
public void VBNetLogicalAndTest()
300
VBNetTestBinaryOperatorExpressionTest("a AndAlso b", BinaryOperatorType.LogicalAnd);
303
public void VBNetLogicalAndNotLazyTest()
305
VBNetTestBinaryOperatorExpressionTest("a And b", BinaryOperatorType.BitwiseAnd);
309
public void VBNetLogicalOrTest()
311
VBNetTestBinaryOperatorExpressionTest("a OrElse b", BinaryOperatorType.LogicalOr);
314
public void VBNetLogicalOrNotLazyTest()
316
VBNetTestBinaryOperatorExpressionTest("a Or b", BinaryOperatorType.BitwiseOr);
320
public void VBNetExclusiveOrTest()
322
VBNetTestBinaryOperatorExpressionTest("a Xor b", BinaryOperatorType.ExclusiveOr);
327
public void VBNetGreaterThanTest()
329
VBNetTestBinaryOperatorExpressionTest("a > b", BinaryOperatorType.GreaterThan);
333
public void VBNetGreaterThanOrEqualTest()
335
VBNetTestBinaryOperatorExpressionTest("a >= b", BinaryOperatorType.GreaterThanOrEqual);
339
public void VBNetEqualityTest()
341
VBNetTestBinaryOperatorExpressionTest("a = b", BinaryOperatorType.Equality);
345
public void VBNetInEqualityTest()
347
VBNetTestBinaryOperatorExpressionTest("a <> b", BinaryOperatorType.InEquality);
351
public void VBNetLessThanTest()
353
VBNetTestBinaryOperatorExpressionTest("a < b", BinaryOperatorType.LessThan);
357
public void VBNetLessThanOrEqualTest()
359
VBNetTestBinaryOperatorExpressionTest("a <= b", BinaryOperatorType.LessThanOrEqual);
363
public void VBNetAddTest()
365
VBNetTestBinaryOperatorExpressionTest("a + b", BinaryOperatorType.Add);
369
public void VBNetSubtractTest()
371
VBNetTestBinaryOperatorExpressionTest("a - b", BinaryOperatorType.Subtract);
375
public void VBNetMultiplyTest()
377
VBNetTestBinaryOperatorExpressionTest("a * b", BinaryOperatorType.Multiply);
381
public void VBNetDivideTest()
383
VBNetTestBinaryOperatorExpressionTest("a / b", BinaryOperatorType.Divide);
387
public void VBNetDivideIntegerTest()
389
VBNetTestBinaryOperatorExpressionTest("a \\ b", BinaryOperatorType.DivideInteger);
393
public void VBNetModulusTest()
395
VBNetTestBinaryOperatorExpressionTest("a Mod b", BinaryOperatorType.Modulus);
399
public void VBNetShiftLeftTest()
401
VBNetTestBinaryOperatorExpressionTest("a << b", BinaryOperatorType.ShiftLeft);
405
public void VBNetShiftRightTest()
407
VBNetTestBinaryOperatorExpressionTest("a >> b", BinaryOperatorType.ShiftRight);
411
public void VBNetISTest()
413
VBNetTestBinaryOperatorExpressionTest("a is b", BinaryOperatorType.ReferenceEquality);
417
public void VBNetISNotTest()
419
VBNetTestBinaryOperatorExpressionTest("a IsNot b", BinaryOperatorType.ReferenceInequality);
423
public void VBNetLikeTest()
425
VBNetTestBinaryOperatorExpressionTest("a Like b", BinaryOperatorType.Like);
430
#region AddIntegerTests
431
string AddIntegerToBoe(string input, int number)
433
return AddInteger<BinaryOperatorExpression>(input, number);
436
string AddInteger<T>(string input, int number) where T : Expression
438
Expression e = ParseUtilCSharp.ParseExpression<T>(input);
439
e = Expression.AddInteger(e, number);
440
CSharpOutputVisitor v = new CSharpOutputVisitor();
441
e.AcceptVisitor(v, null);
446
public void AddInteger()
448
Assert.AreEqual("a + 2", AddIntegerToBoe("a + 1", 1));
449
Assert.AreEqual("a + 2", AddIntegerToBoe("a + 3", -1));
450
Assert.AreEqual("a + b + c + 2", AddIntegerToBoe("a + b + c + 1", 1));
451
Assert.AreEqual("a", AddIntegerToBoe("a + 1", -1));
452
Assert.AreEqual("2", AddInteger<PrimitiveExpression>("1", 1));
453
Assert.AreEqual("-1", AddInteger<PrimitiveExpression>("1", -2));
454
Assert.AreEqual("0", AddInteger<PrimitiveExpression>("1", -1));
455
Assert.AreEqual("a + 1", AddInteger<IdentifierExpression>("a", 1));
459
public void AddIntegerWithNegativeResult()
461
Assert.AreEqual("a - 1", AddIntegerToBoe("a + 1", -2));
462
Assert.AreEqual("a - 2", AddIntegerToBoe("a - 1", -1));
463
Assert.AreEqual("a + b + c - 2", AddIntegerToBoe("a + b + c + 2", -4));
464
Assert.AreEqual("a + b + c - 6", AddIntegerToBoe("a + b + c - 2", -4));
465
Assert.AreEqual("a + b + c", AddIntegerToBoe("a + b + c + 2", -2));
466
Assert.AreEqual("a", AddIntegerToBoe("a - 1", 1));
467
Assert.AreEqual("a + 1", AddIntegerToBoe("a - 2", 3));
468
Assert.AreEqual("a - 1", AddInteger<IdentifierExpression>("a", -1));