/CSharpFactoryVS2010/CSharpTreeBuilderTest/Ast/ExpressionTests.cs

# · C# · 1332 lines · 870 code · 150 blank · 312 comment · 0 complexity · d0437401c395fe73f1398fd3f3d4ec59 MD5 · raw file

  1. using Microsoft.VisualStudio.TestTools.UnitTesting;
  2. using SoftwareApproach.TestingExtensions;
  3. using CSharpTreeBuilder.Ast;
  4. using CSharpTreeBuilder.ProjectContent;
  5. namespace CSharpTreeBuilderTest.Ast
  6. {
  7. // ================================================================================================
  8. /// <summary>
  9. /// Tests the parsing of expressions
  10. /// </summary>
  11. // ================================================================================================
  12. [TestClass]
  13. public class ExpressionTests : ParserTestBed
  14. {
  15. // ----------------------------------------------------------------------------------------------
  16. /// <summary>
  17. /// Tests the parsing of the expressions:
  18. /// int i1 = 1;
  19. /// long i2 = 2L;
  20. /// uint i3 = 3U;
  21. /// ulong i4 = 4UL;
  22. /// </summary>
  23. // ----------------------------------------------------------------------------------------------
  24. [TestMethod]
  25. public void IntegerLiteral()
  26. {
  27. var project = new CSharpProject(WorkingFolder);
  28. project.AddFile(@"Expressions\IntegerLiteral.cs");
  29. InvokeParser(project, true, false).ShouldBeTrue();
  30. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  31. {
  32. var decl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  33. var init = decl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  34. ((Int32LiteralNode)init.Expression).Value.ShouldEqual(1);
  35. }
  36. {
  37. var decl = method.Body.Statements[1] as VariableDeclarationStatementNode;
  38. var init = decl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  39. ((Int64LiteralNode)init.Expression).Value.ShouldEqual(2);
  40. }
  41. {
  42. var decl = method.Body.Statements[2] as VariableDeclarationStatementNode;
  43. var init = decl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  44. ((UInt32LiteralNode)init.Expression).Value.ShouldEqual<uint>(3);
  45. }
  46. {
  47. var decl = method.Body.Statements[3] as VariableDeclarationStatementNode;
  48. var init = decl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  49. ((UInt64LiteralNode)init.Expression).Value.ShouldEqual<ulong>(4);
  50. }
  51. }
  52. // ----------------------------------------------------------------------------------------------
  53. /// <summary>
  54. /// Tests the parsing of the expressions:
  55. /// float f1 = 1F;
  56. /// double f2 = 2D;
  57. /// decimal f3 = 3M;
  58. /// </summary>
  59. // ----------------------------------------------------------------------------------------------
  60. [TestMethod]
  61. public void RealLiteral()
  62. {
  63. var project = new CSharpProject(WorkingFolder);
  64. project.AddFile(@"Expressions\RealLiteral.cs");
  65. InvokeParser(project, true, false).ShouldBeTrue();
  66. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  67. {
  68. var decl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  69. var init = decl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  70. ((SingleLiteralNode)init.Expression).Value.ShouldEqual(1);
  71. }
  72. {
  73. var decl = method.Body.Statements[1] as VariableDeclarationStatementNode;
  74. var init = decl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  75. ((DoubleLiteralNode)init.Expression).Value.ShouldEqual(2);
  76. }
  77. {
  78. var decl = method.Body.Statements[2] as VariableDeclarationStatementNode;
  79. var init = decl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  80. ((DecimalLiteralNode)init.Expression).Value.ShouldEqual(3);
  81. }
  82. }
  83. // ----------------------------------------------------------------------------------------------
  84. /// <summary>
  85. /// Tests the parsing of the expressions:
  86. /// char c = 'a';
  87. /// </summary>
  88. // ----------------------------------------------------------------------------------------------
  89. [TestMethod]
  90. public void CharLiteral()
  91. {
  92. var project = new CSharpProject(WorkingFolder);
  93. project.AddFile(@"Expressions\CharLiteral.cs");
  94. InvokeParser(project, true, false).ShouldBeTrue();
  95. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  96. var decl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  97. var init = decl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  98. ((CharLiteralNode)init.Expression).Value.ShouldEqual('a');
  99. }
  100. // ----------------------------------------------------------------------------------------------
  101. /// <summary>
  102. /// Tests the parsing of the expressions:
  103. /// string s = "a";
  104. /// </summary>
  105. // ----------------------------------------------------------------------------------------------
  106. [TestMethod]
  107. public void StringLiteral()
  108. {
  109. var project = new CSharpProject(WorkingFolder);
  110. project.AddFile(@"Expressions\StringLiteral.cs");
  111. InvokeParser(project, true, false).ShouldBeTrue();
  112. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  113. var decl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  114. var init = decl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  115. ((StringLiteralNode)init.Expression).Value.ShouldEqual("a");
  116. }
  117. // ----------------------------------------------------------------------------------------------
  118. /// <summary>
  119. /// Tests the parsing of the expressions:
  120. /// int i = (1);
  121. /// </summary>
  122. // ----------------------------------------------------------------------------------------------
  123. [TestMethod]
  124. public void ParenthesizedExpression()
  125. {
  126. var project = new CSharpProject(WorkingFolder);
  127. project.AddFile(@"Expressions\ParenthesizedExpression.cs");
  128. InvokeParser(project, true, false).ShouldBeTrue();
  129. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  130. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  131. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  132. var parenthesizedExpressionNode = initializer.Expression as ParenthesizedExpressionNode;
  133. ((Int32LiteralNode)parenthesizedExpressionNode.Expression).Value.ShouldEqual(1);
  134. }
  135. // ----------------------------------------------------------------------------------------------
  136. /// <summary>
  137. /// Tests the parsing of the expressions:
  138. /// ++i;
  139. /// --i;
  140. /// i++;
  141. /// i--;
  142. /// </summary>
  143. // ----------------------------------------------------------------------------------------------
  144. [TestMethod]
  145. public void PrePostIncDecrementExpression()
  146. {
  147. var project = new CSharpProject(WorkingFolder);
  148. project.AddFile(@"Expressions\PrePostIncDecrementExpression.cs");
  149. InvokeParser(project, true, false).ShouldBeTrue();
  150. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  151. {
  152. var op = ((ExpressionStatementNode) method.Body.Statements[0]).Expression as PreIncrementExpressionNode;
  153. op.ShouldNotBeNull();
  154. }
  155. {
  156. var op = ((ExpressionStatementNode) method.Body.Statements[1]).Expression as PreDecrementExpressionNode;
  157. op.ShouldNotBeNull();
  158. }
  159. {
  160. var op = ((ExpressionStatementNode) method.Body.Statements[2]).Expression as PostIncrementExpressionNode;
  161. op.ShouldNotBeNull();
  162. }
  163. {
  164. var op = ((ExpressionStatementNode) method.Body.Statements[3]).Expression as PostDecrementExpressionNode;
  165. op.ShouldNotBeNull();
  166. }
  167. }
  168. // ----------------------------------------------------------------------------------------------
  169. /// <summary>
  170. /// Tests the parsing of the expression:
  171. /// int y = x = 8;
  172. /// </summary>
  173. // ----------------------------------------------------------------------------------------------
  174. [TestMethod]
  175. public void SimpleAssignment()
  176. {
  177. var project = new CSharpProject(WorkingFolder);
  178. project.AddFile(@"Expressions\SimpleAssignment.cs");
  179. InvokeParser(project, true, false).ShouldBeTrue();
  180. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  181. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  182. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  183. var assignment = initializer.Expression as AssignmentExpressionNode;
  184. assignment.Operator.ShouldEqual(AssignmentOperator.SimpleAssignment);
  185. ((SimpleNameNode) assignment.LeftOperand).Identifier.ShouldEqual("x");
  186. ((Int32LiteralNode) assignment.RightOperand).Value.ShouldEqual(8);
  187. }
  188. // ----------------------------------------------------------------------------------------------
  189. /// <summary>
  190. /// Tests the parsing of the expression:
  191. /// int a1 = 2 * 3 * 4;
  192. /// </summary>
  193. // ----------------------------------------------------------------------------------------------
  194. [TestMethod]
  195. public void Multiplications()
  196. {
  197. var project = new CSharpProject(WorkingFolder);
  198. project.AddFile(@"Expressions\Multiplications.cs");
  199. InvokeParser(project, true, false).ShouldBeTrue();
  200. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  201. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  202. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  203. var binary1 = initializer.Expression as BinaryExpressionNode;
  204. binary1.Operator.ShouldEqual(BinaryOperator.Multiplication);
  205. var binary1RightOperand = binary1.RightOperand as Int32LiteralNode;
  206. binary1RightOperand.Value.ShouldEqual(4);
  207. var binary2 = binary1.LeftOperand as BinaryExpressionNode;
  208. binary2.Operator.ShouldEqual(BinaryOperator.Multiplication);
  209. var binary2RightOperand = binary2.RightOperand as Int32LiteralNode;
  210. binary2RightOperand.Value.ShouldEqual(3);
  211. var binary2LeftOperand = binary2.LeftOperand as Int32LiteralNode;
  212. binary2LeftOperand.Value.ShouldEqual(2);
  213. }
  214. // ----------------------------------------------------------------------------------------------
  215. /// <summary>
  216. /// Tests the parsing of the expression:
  217. /// int a2 = 2 + 3 + 4;
  218. /// </summary>
  219. // ----------------------------------------------------------------------------------------------
  220. [TestMethod]
  221. public void Additions()
  222. {
  223. var project = new CSharpProject(WorkingFolder);
  224. project.AddFile(@"Expressions\Additions.cs");
  225. InvokeParser(project, true, false).ShouldBeTrue();
  226. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  227. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  228. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  229. var binary1 = initializer.Expression as BinaryExpressionNode;
  230. binary1.Operator.ShouldEqual(BinaryOperator.Addition);
  231. var binary1RightOperand = binary1.RightOperand as Int32LiteralNode;
  232. binary1RightOperand.Value.ShouldEqual(4);
  233. var binary2 = binary1.LeftOperand as BinaryExpressionNode;
  234. binary2.Operator.ShouldEqual(BinaryOperator.Addition);
  235. var binary2RightOperand = binary2.RightOperand as Int32LiteralNode;
  236. binary2RightOperand.Value.ShouldEqual(3);
  237. var binary2LeftOperand = binary2.LeftOperand as Int32LiteralNode;
  238. binary2LeftOperand.Value.ShouldEqual(2);
  239. }
  240. // ----------------------------------------------------------------------------------------------
  241. /// <summary>
  242. /// Tests the parsing of the expression:
  243. /// int a3 = 2 + 3 * 4 + 5;
  244. /// </summary>
  245. // ----------------------------------------------------------------------------------------------
  246. [TestMethod]
  247. public void AddAndMultiplyPrecedence()
  248. {
  249. var project = new CSharpProject(WorkingFolder);
  250. project.AddFile(@"Expressions\AddAndMultiplyPrecedence.cs");
  251. InvokeParser(project, true, false).ShouldBeTrue();
  252. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  253. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  254. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  255. var binary1 = initializer.Expression as BinaryExpressionNode;
  256. binary1.Operator.ShouldEqual(BinaryOperator.Addition);
  257. var binary1RightOperand = binary1.RightOperand as Int32LiteralNode;
  258. binary1RightOperand.Value.ShouldEqual(5);
  259. var binary2 = binary1.LeftOperand as BinaryExpressionNode;
  260. binary2.Operator.ShouldEqual(BinaryOperator.Addition);
  261. var binary2LeftOperand = binary2.LeftOperand as Int32LiteralNode;
  262. binary2LeftOperand.Value.ShouldEqual(2);
  263. var binary3 = binary2.RightOperand as BinaryExpressionNode;
  264. binary3.Operator.ShouldEqual(BinaryOperator.Multiplication);
  265. var binary3LeftOperand = binary3.LeftOperand as Int32LiteralNode;
  266. binary3LeftOperand.Value.ShouldEqual(3);
  267. var binary3RightOperand = binary3.RightOperand as Int32LiteralNode;
  268. binary3RightOperand.Value.ShouldEqual(4);
  269. }
  270. // ----------------------------------------------------------------------------------------------
  271. /// <summary>
  272. /// Tests the parsing of the expression:
  273. /// int a = x += x -= x *= x /= 1;
  274. /// </summary>
  275. // ----------------------------------------------------------------------------------------------
  276. [TestMethod]
  277. public void AssignmentExpressions()
  278. {
  279. var project = new CSharpProject(WorkingFolder);
  280. project.AddFile(@"Expressions\AssignmentExpressions.cs");
  281. InvokeParser(project, true, false).ShouldBeTrue();
  282. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  283. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  284. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  285. // Assignment is right-associative: (x += (x -= (x *= (x /= 1))))
  286. // The topmost expression is (x += assignment-expression)
  287. var op1 = initializer.Expression as AssignmentExpressionNode;
  288. op1.Operator.ShouldEqual(AssignmentOperator.AdditionAssignment);
  289. ((SimpleNameNode) (op1.LeftOperand)).Identifier.ShouldEqual("x");
  290. // The next expression is (x -= assignment-expression)
  291. var op2 = op1.RightOperand as AssignmentExpressionNode;
  292. op2.Operator.ShouldEqual(AssignmentOperator.SubtractionAssignment);
  293. ((SimpleNameNode)(op2.LeftOperand)).Identifier.ShouldEqual("x");
  294. // The next expression is (x *= assignment-expression)
  295. var op3 = op2.RightOperand as AssignmentExpressionNode;
  296. op3.Operator.ShouldEqual(AssignmentOperator.MultiplicationAssignment);
  297. ((SimpleNameNode)(op3.LeftOperand)).Identifier.ShouldEqual("x");
  298. // The next expression is (x /= x)
  299. var op4 = op3.RightOperand as AssignmentExpressionNode;
  300. op4.Operator.ShouldEqual(AssignmentOperator.DivisionAssignment);
  301. ((SimpleNameNode)(op4.LeftOperand)).Identifier.ShouldEqual("x");
  302. ((Int32LiteralNode)(op4.RightOperand)).Value.ShouldEqual(1);
  303. }
  304. // ----------------------------------------------------------------------------------------------
  305. /// <summary>
  306. /// Tests the parsing of the expression:
  307. /// string s1 = "a" ?? "b";
  308. /// </summary>
  309. // ----------------------------------------------------------------------------------------------
  310. [TestMethod]
  311. public void NullCoalescingExpression()
  312. {
  313. var project = new CSharpProject(WorkingFolder);
  314. project.AddFile(@"Expressions\NullCoalescingExpression.cs");
  315. InvokeParser(project, true, false).ShouldBeTrue();
  316. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  317. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  318. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  319. var binary = initializer.Expression as BinaryExpressionNode;
  320. binary.Operator.ShouldEqual(BinaryOperator.NullCoalescing);
  321. ((StringLiteralNode) (binary.LeftOperand)).Value.ShouldEqual("a");
  322. ((StringLiteralNode) (binary.RightOperand)).Value.ShouldEqual("b");
  323. }
  324. // ----------------------------------------------------------------------------------------------
  325. /// <summary>
  326. /// Tests the parsing of the expression:
  327. /// bool t = true;
  328. /// </summary>
  329. // ----------------------------------------------------------------------------------------------
  330. [TestMethod]
  331. public void TrueLiteral()
  332. {
  333. var project = new CSharpProject(WorkingFolder);
  334. project.AddFile(@"Expressions\TrueLiteral.cs");
  335. InvokeParser(project, true, false).ShouldBeTrue();
  336. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  337. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  338. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  339. var trueLiteral = ((TrueLiteralNode)(initializer.Expression));
  340. trueLiteral.Value.ShouldEqual(true);
  341. }
  342. // ----------------------------------------------------------------------------------------------
  343. /// <summary>
  344. /// Tests the parsing of the expression:
  345. /// bool f = false;
  346. /// </summary>
  347. // ----------------------------------------------------------------------------------------------
  348. [TestMethod]
  349. public void FalseLiteral()
  350. {
  351. var project = new CSharpProject(WorkingFolder);
  352. project.AddFile(@"Expressions\FalseLiteral.cs");
  353. InvokeParser(project, true, false).ShouldBeTrue();
  354. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  355. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  356. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  357. var falseLiteral = ((FalseLiteralNode)(initializer.Expression));
  358. falseLiteral.Value.ShouldEqual(false);
  359. }
  360. // ----------------------------------------------------------------------------------------------
  361. /// <summary>
  362. /// Tests the parsing of the expression:
  363. /// int i1 = "a".Length;
  364. /// </summary>
  365. // ----------------------------------------------------------------------------------------------
  366. [TestMethod]
  367. public void PrimaryMemberAccessExpression()
  368. {
  369. var project = new CSharpProject(WorkingFolder);
  370. project.AddFile(@"Expressions\PrimaryMemberAccessExpression.cs");
  371. InvokeParser(project, true, false).ShouldBeTrue();
  372. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  373. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  374. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  375. var expr = initializer.Expression as PrimaryExpressionMemberAccessNode;
  376. expr.Identifier.ShouldEqual("Length");
  377. var embeddedExpression = (StringLiteralNode) expr.PrimaryExpression;
  378. embeddedExpression.Value.ShouldEqual("a");
  379. embeddedExpression.ParentNode.ShouldEqual(expr);
  380. }
  381. // ----------------------------------------------------------------------------------------------
  382. /// <summary>
  383. /// Tests the parsing of the expression:
  384. /// string s2 = bool.FalseString;
  385. /// </summary>
  386. // ----------------------------------------------------------------------------------------------
  387. [TestMethod]
  388. public void PredefinedTypeMemberAccessExpression()
  389. {
  390. var project = new CSharpProject(WorkingFolder);
  391. project.AddFile(@"Expressions\PredefinedTypeMemberAccessExpression.cs");
  392. InvokeParser(project, true, false).ShouldBeTrue();
  393. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  394. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  395. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  396. var expr = initializer.Expression as PredefinedTypeMemberAccessNode;
  397. expr.Identifier.ShouldEqual("FalseString");
  398. expr.TypeName.TypeTags[0].Identifier.ShouldEqual("bool");
  399. }
  400. // ----------------------------------------------------------------------------------------------
  401. /// <summary>
  402. /// Tests the parsing of the expression:
  403. /// string s3 = myAlias::Boolean.FalseString;
  404. /// </summary>
  405. // ----------------------------------------------------------------------------------------------
  406. [TestMethod]
  407. public void QualifiedAliasMemberAccessExpression()
  408. {
  409. var project = new CSharpProject(WorkingFolder);
  410. project.AddFile(@"Expressions\QualifiedAliasMemberAccessExpression.cs");
  411. InvokeParser(project, true, false).ShouldBeTrue();
  412. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  413. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  414. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  415. var expr = initializer.Expression as QualifiedAliasMemberAccessNode;
  416. expr.Identifier.ShouldEqual("FalseString");
  417. expr.QualifiedAliasMember.Qualifier.ShouldEqual("myAlias");
  418. expr.QualifiedAliasMember.Identifier.ShouldEqual("Boolean");
  419. }
  420. // ----------------------------------------------------------------------------------------------
  421. /// <summary>
  422. /// Tests the parsing of the expression:
  423. /// int i2 = myAlias::Boolean.FalseString.Length;
  424. /// </summary>
  425. // ----------------------------------------------------------------------------------------------
  426. [TestMethod]
  427. public void MultipleMemberAccessExpressions()
  428. {
  429. var project = new CSharpProject(WorkingFolder);
  430. project.AddFile(@"Expressions\MultipleMemberAccessExpressions.cs");
  431. InvokeParser(project, true, false).ShouldBeTrue();
  432. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  433. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  434. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  435. var expr = initializer.Expression as PrimaryExpressionMemberAccessNode;
  436. expr.Identifier.ShouldEqual("Length");
  437. var embeddedExpr = expr.PrimaryExpression as QualifiedAliasMemberAccessNode;
  438. embeddedExpr.Identifier.ShouldEqual("FalseString");
  439. embeddedExpr.QualifiedAliasMember.Qualifier.ShouldEqual("myAlias");
  440. embeddedExpr.QualifiedAliasMember.Identifier.ShouldEqual("Boolean");
  441. }
  442. // ----------------------------------------------------------------------------------------------
  443. /// <summary>
  444. /// Tests the parsing of the expression:
  445. /// p->x = 1; (inside a fixed statement)
  446. /// </summary>
  447. // ----------------------------------------------------------------------------------------------
  448. [TestMethod]
  449. public void PointerMemberAccessExpressions()
  450. {
  451. var project = new CSharpProject(WorkingFolder);
  452. project.AddFile(@"Expressions\PointerMemberAccessExpressions.cs");
  453. InvokeParser(project, true, false).ShouldBeTrue();
  454. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  455. var fixedStatementNode = method.Body.Statements[0] as FixedStatementNode;
  456. var bodyBlock = fixedStatementNode.Statement as BlockStatementNode;
  457. var exprStatement = bodyBlock.Statements[0] as ExpressionStatementNode;
  458. var expression = exprStatement.Expression as AssignmentExpressionNode;
  459. var pointerExpr = expression.LeftOperand as PointerMemberAccessNode;
  460. ((SimpleNameNode)pointerExpr.PrimaryExpression).Identifier.ShouldEqual("p");
  461. pointerExpr.Identifier.ShouldEqual("x");
  462. }
  463. // ----------------------------------------------------------------------------------------------
  464. /// <summary>
  465. /// Tests the parsing of the expression:
  466. /// var e1 = this;
  467. /// </summary>
  468. // ----------------------------------------------------------------------------------------------
  469. [TestMethod]
  470. public void ThisAccessExpression()
  471. {
  472. var project = new CSharpProject(WorkingFolder);
  473. project.AddFile(@"Expressions\ThisAccessExpression.cs");
  474. InvokeParser(project, true, false).ShouldBeTrue();
  475. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  476. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  477. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  478. var thisNode = initializer.Expression as ThisAccessNode;
  479. thisNode.ShouldNotBeNull();
  480. }
  481. // ----------------------------------------------------------------------------------------------
  482. /// <summary>
  483. /// Tests the parsing of the expression:
  484. /// int i3 = base.Field;
  485. /// </summary>
  486. // ----------------------------------------------------------------------------------------------
  487. [TestMethod]
  488. public void BaseMemberAccessExpression()
  489. {
  490. var project = new CSharpProject(WorkingFolder);
  491. project.AddFile(@"Expressions\BaseMemberAccessExpression.cs");
  492. InvokeParser(project, true, false).ShouldBeTrue();
  493. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  494. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  495. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  496. var expr = initializer.Expression as BaseMemberAccessNode;
  497. expr.MemberName.Identifier.ShouldEqual("Field");
  498. }
  499. // ----------------------------------------------------------------------------------------------
  500. /// <summary>
  501. /// Tests the parsing of the expression:
  502. /// int i4 = base[1];
  503. /// </summary>
  504. // ----------------------------------------------------------------------------------------------
  505. [TestMethod]
  506. public void BaseElementAccessExpression()
  507. {
  508. var project = new CSharpProject(WorkingFolder);
  509. project.AddFile(@"Expressions\BaseElementAccessExpression.cs");
  510. InvokeParser(project, true, false).ShouldBeTrue();
  511. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  512. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  513. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  514. var expr = initializer.Expression as BaseElementAccessNode;
  515. ((Int32LiteralNode) expr.Expressions[0]).Value.ShouldEqual(1);
  516. }
  517. // ----------------------------------------------------------------------------------------------
  518. /// <summary>
  519. /// Tests the parsing of the expression:
  520. /// DummyMethod();
  521. /// </summary>
  522. // ----------------------------------------------------------------------------------------------
  523. [TestMethod]
  524. public void InvocationExpression()
  525. {
  526. var project = new CSharpProject(WorkingFolder);
  527. project.AddFile(@"Expressions\InvocationExpression.cs");
  528. InvokeParser(project, true, false).ShouldBeTrue();
  529. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  530. var invocation = ((ExpressionStatementNode) method.Body.Statements[0]).Expression as InvocationExpressionNode;
  531. ((SimpleNameNode) invocation.PrimaryExpression).Identifier.ShouldEqual("DummyMethod");
  532. invocation.Arguments.Count.ShouldEqual(0);
  533. }
  534. // ----------------------------------------------------------------------------------------------
  535. /// <summary>
  536. /// Tests the parsing of the expression:
  537. /// Equals(null);
  538. /// </summary>
  539. // ----------------------------------------------------------------------------------------------
  540. [TestMethod]
  541. public void InvocationExpressionWithArgument()
  542. {
  543. var project = new CSharpProject(WorkingFolder);
  544. project.AddFile(@"Expressions\InvocationExpressionWithArgument.cs");
  545. InvokeParser(project, true, false).ShouldBeTrue();
  546. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  547. var invocation = ((ExpressionStatementNode)method.Body.Statements[0]).Expression as InvocationExpressionNode;
  548. ((SimpleNameNode)invocation.PrimaryExpression).Identifier.ShouldEqual("Equals");
  549. var nullLiteral = invocation.Arguments[0].Expression as NullLiteralNode;
  550. nullLiteral.ShouldNotBeNull();
  551. }
  552. // ----------------------------------------------------------------------------------------------
  553. /// <summary>
  554. /// Tests the parsing of the expression:
  555. /// char c1 = "a"[0];
  556. /// </summary>
  557. // ----------------------------------------------------------------------------------------------
  558. [TestMethod]
  559. public void ElementAccessExpression()
  560. {
  561. var project = new CSharpProject(WorkingFolder);
  562. project.AddFile(@"Expressions\ElementAccessExpression.cs");
  563. InvokeParser(project, true, false).ShouldBeTrue();
  564. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  565. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  566. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  567. var expr = initializer.Expression as ElementAccessNode;
  568. ((StringLiteralNode)expr.PrimaryExpression).Value.ShouldEqual("a");
  569. ((Int32LiteralNode)expr.Expressions[0]).Value.ShouldEqual(0);
  570. }
  571. // ----------------------------------------------------------------------------------------------
  572. /// <summary>
  573. /// Tests the parsing of the expression:
  574. /// bool b1 = true is bool;
  575. /// </summary>
  576. // ----------------------------------------------------------------------------------------------
  577. [TestMethod]
  578. public void IsExpression()
  579. {
  580. var project = new CSharpProject(WorkingFolder);
  581. project.AddFile(@"Expressions\IsExpression.cs");
  582. InvokeParser(project, true, false).ShouldBeTrue();
  583. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  584. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  585. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  586. var expr = initializer.Expression as TypeTestingExpressionNode;
  587. expr.Operator.ShouldEqual(TypeTestingOperator.Is);
  588. ((TrueLiteralNode) expr.LeftOperand).Value.ShouldEqual(true);
  589. expr.RightOperand.TypeName.TypeTags[0].Identifier.ShouldEqual("bool");
  590. }
  591. // ----------------------------------------------------------------------------------------------
  592. /// <summary>
  593. /// Tests the parsing of the expression:
  594. /// bool b2 = b1 && x + y is bool;
  595. /// </summary>
  596. // ----------------------------------------------------------------------------------------------
  597. [TestMethod]
  598. public void EmbeddedIsExpression()
  599. {
  600. var project = new CSharpProject(WorkingFolder);
  601. project.AddFile(@"Expressions\EmbeddedIsExpression.cs");
  602. InvokeParser(project, true, false).ShouldBeTrue();
  603. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  604. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  605. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  606. var expr1 = initializer.Expression as BinaryExpressionNode;
  607. expr1.Operator.ShouldEqual(BinaryOperator.ConditionalAnd);
  608. ((TrueLiteralNode) expr1.LeftOperand).Value.ShouldEqual(true);
  609. var expr2 = expr1.RightOperand as TypeTestingExpressionNode;
  610. expr2.Operator.ShouldEqual(TypeTestingOperator.Is);
  611. expr2.RightOperand.TypeName.TypeTags[0].Identifier.ShouldEqual("bool");
  612. var expr3 = expr2.LeftOperand as BinaryExpressionNode;
  613. expr3.Operator.ShouldEqual(BinaryOperator.Addition);
  614. ((Int32LiteralNode)expr3.LeftOperand).Value.ShouldEqual(1);
  615. ((Int32LiteralNode)expr3.RightOperand).Value.ShouldEqual(2);
  616. }
  617. // ----------------------------------------------------------------------------------------------
  618. /// <summary>
  619. /// Tests the parsing of the expression:
  620. /// string s4 = s1 as string;
  621. /// </summary>
  622. // ----------------------------------------------------------------------------------------------
  623. [TestMethod]
  624. public void AsExpression()
  625. {
  626. var project = new CSharpProject(WorkingFolder);
  627. project.AddFile(@"Expressions\AsExpression.cs");
  628. InvokeParser(project, true, false).ShouldBeTrue();
  629. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  630. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  631. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  632. var expr = initializer.Expression as TypeTestingExpressionNode;
  633. expr.Operator.ShouldEqual(TypeTestingOperator.As);
  634. ((StringLiteralNode)expr.LeftOperand).Value.ShouldEqual("a");
  635. expr.RightOperand.TypeName.TypeTags[0].Identifier.ShouldEqual("string");
  636. }
  637. // ----------------------------------------------------------------------------------------------
  638. /// <summary>
  639. /// Tests the parsing of the expression:
  640. /// Type t1 = typeof(int);
  641. /// Type t2 = typeof(Generic<,>);
  642. /// Type t3 = typeof(Generic<int, int>);
  643. /// Type t4 = typeof(myAlias::IList<>);
  644. /// Type t5 = typeof(Generic<,>.EmbeddedGeneric<>);
  645. /// Type t6 = typeof(void);
  646. /// </summary>
  647. /// <remarks>
  648. /// Also tests unbound type names, because they are valid in typeof expressions only.
  649. /// </remarks>
  650. // ----------------------------------------------------------------------------------------------
  651. [TestMethod]
  652. public void TypeofExpression()
  653. {
  654. var project = new CSharpProject(WorkingFolder);
  655. project.AddFile(@"Expressions\TypeofExpression.cs");
  656. InvokeParser(project, true, false).ShouldBeTrue();
  657. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  658. {
  659. var decl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  660. var init = decl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  661. var typeName = ((TypeofExpressionNode)init.Expression).Type;
  662. typeName.TypeName.TypeTags[0].Identifier.ShouldEqual("int");
  663. typeName.TypeName.TypeTags[0].IsUnbound.ShouldBeFalse();
  664. typeName.TypeName.TypeTags[0].GenericDimensions.ShouldEqual(0);
  665. }
  666. {
  667. var decl = method.Body.Statements[1] as VariableDeclarationStatementNode;
  668. var init = decl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  669. var typeName = ((TypeofExpressionNode)init.Expression).Type;
  670. typeName.TypeName.TypeTags[0].Identifier.ShouldEqual("Generic");
  671. typeName.TypeName.TypeTags[0].IsUnbound.ShouldBeTrue();
  672. typeName.TypeName.TypeTags[0].GenericDimensions.ShouldEqual(2);
  673. }
  674. {
  675. var decl = method.Body.Statements[2] as VariableDeclarationStatementNode;
  676. var init = decl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  677. var typeName = ((TypeofExpressionNode)init.Expression).Type;
  678. typeName.TypeName.TypeTags[0].Identifier.ShouldEqual("Generic");
  679. typeName.TypeName.TypeTags[0].IsUnbound.ShouldBeFalse();
  680. typeName.TypeName.TypeTags[0].GenericDimensions.ShouldEqual(2);
  681. typeName.TypeName.TypeTags[0].Arguments[0].TypeName.TypeTags[0].Identifier.ShouldEqual("int");
  682. typeName.TypeName.TypeTags[0].Arguments[1].TypeName.TypeTags[0].Identifier.ShouldEqual("int");
  683. }
  684. {
  685. var decl = method.Body.Statements[3] as VariableDeclarationStatementNode;
  686. var init = decl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  687. var typeName = ((TypeofExpressionNode)init.Expression).Type;
  688. typeName.TypeName.Qualifier.ShouldEqual("myAlias");
  689. typeName.TypeName.TypeTags[0].Identifier.ShouldEqual("IList");
  690. typeName.TypeName.TypeTags[0].IsUnbound.ShouldBeTrue();
  691. typeName.TypeName.TypeTags[0].GenericDimensions.ShouldEqual(1);
  692. }
  693. {
  694. var decl = method.Body.Statements[4] as VariableDeclarationStatementNode;
  695. var init = decl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  696. var typeName = ((TypeofExpressionNode)init.Expression).Type;
  697. typeName.TypeName.Qualifier.ShouldBeNull();
  698. typeName.TypeName.TypeTags[0].Identifier.ShouldEqual("Generic");
  699. typeName.TypeName.TypeTags[0].IsUnbound.ShouldBeTrue();
  700. typeName.TypeName.TypeTags[0].GenericDimensions.ShouldEqual(2);
  701. typeName.TypeName.TypeTags[1].Identifier.ShouldEqual("EmbeddedGeneric");
  702. typeName.TypeName.TypeTags[1].IsUnbound.ShouldBeTrue();
  703. typeName.TypeName.TypeTags[1].GenericDimensions.ShouldEqual(1);
  704. }
  705. {
  706. var decl = method.Body.Statements[5] as VariableDeclarationStatementNode;
  707. var init = decl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  708. var typeName = ((TypeofExpressionNode)init.Expression).Type;
  709. typeName.TypeName.TypeTags[0].Identifier.ShouldEqual("void");
  710. typeName.TypeName.TypeTags[0].IsUnbound.ShouldBeFalse();
  711. typeName.TypeName.TypeTags[0].GenericDimensions.ShouldEqual(0);
  712. }
  713. }
  714. // ----------------------------------------------------------------------------------------------
  715. /// <summary>
  716. /// Tests the parsing of the expression:
  717. /// int i = sizeof (int);
  718. /// </summary>
  719. // ----------------------------------------------------------------------------------------------
  720. [TestMethod]
  721. public void SizeofExpression()
  722. {
  723. var project = new CSharpProject(WorkingFolder);
  724. project.AddFile(@"Expressions\SizeofExpression.cs");
  725. InvokeParser(project, true, false).ShouldBeTrue();
  726. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  727. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  728. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  729. var expr = initializer.Expression as SizeofExpressionNode;
  730. expr.Type.TypeName.TypeTags[0].Identifier.ShouldEqual("int");
  731. }
  732. // ----------------------------------------------------------------------------------------------
  733. /// <summary>
  734. /// Tests the parsing of the expression:
  735. /// int i = default(int);
  736. /// </summary>
  737. // ----------------------------------------------------------------------------------------------
  738. [TestMethod]
  739. public void DefaultValueExpression()
  740. {
  741. var project = new CSharpProject(WorkingFolder);
  742. project.AddFile(@"Expressions\DefaultValueExpression.cs");
  743. InvokeParser(project, true, false).ShouldBeTrue();
  744. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  745. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  746. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  747. var expr = initializer.Expression as DefaultValueExpressionNode;
  748. expr.Type.TypeName.TypeTags[0].Identifier.ShouldEqual("int");
  749. }
  750. // ----------------------------------------------------------------------------------------------
  751. /// <summary>
  752. /// Tests the parsing of the expression:
  753. /// int i = checked(p++);
  754. /// </summary>
  755. // ----------------------------------------------------------------------------------------------
  756. [TestMethod]
  757. public void CheckedExpression()
  758. {
  759. var project = new CSharpProject(WorkingFolder);
  760. project.AddFile(@"Expressions\CheckedExpression.cs");
  761. InvokeParser(project, true, false).ShouldBeTrue();
  762. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  763. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  764. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  765. var expression = initializer.Expression as CheckedExpressionNode;
  766. var embeddedExpression = expression.Expression as PostIncrementExpressionNode;
  767. embeddedExpression.ShouldNotBeNull();
  768. }
  769. // ----------------------------------------------------------------------------------------------
  770. /// <summary>
  771. /// Tests the parsing of the expression:
  772. /// int i = unchecked(p++);
  773. /// </summary>
  774. // ----------------------------------------------------------------------------------------------
  775. [TestMethod]
  776. public void UncheckedExpression()
  777. {
  778. var project = new CSharpProject(WorkingFolder);
  779. project.AddFile(@"Expressions\UncheckedExpression.cs");
  780. InvokeParser(project, true, false).ShouldBeTrue();
  781. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  782. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  783. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  784. var expression = initializer.Expression as UncheckedExpressionNode;
  785. var embeddedExpression = expression.Expression as PostIncrementExpressionNode;
  786. embeddedExpression.ShouldNotBeNull();
  787. }
  788. // ----------------------------------------------------------------------------------------------
  789. /// <summary>
  790. /// Tests the parsing of the expression:
  791. /// var i1 = +1;
  792. /// var i2 = -2;
  793. /// var i3 = !true;
  794. /// var i4 = ~0;
  795. /// var i5 = &i1;
  796. /// var i6 = *i5;
  797. /// </summary>
  798. // ----------------------------------------------------------------------------------------------
  799. [TestMethod]
  800. public void UnaryOperatorExpressions()
  801. {
  802. var project = new CSharpProject(WorkingFolder);
  803. project.AddFile(@"Expressions\UnaryOperatorExpressions.cs");
  804. InvokeParser(project, true, false).ShouldBeTrue();
  805. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  806. {
  807. var var = method.Body.Statements[0] as VariableDeclarationStatementNode;
  808. var init = var.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  809. var op = init.Expression as UnaryOperatorExpressionNode;
  810. op.Operator.ShouldEqual(UnaryOperator.Identity);
  811. ((Int32LiteralNode)op.Operand).Value.ShouldEqual(1);
  812. }
  813. {
  814. var var = method.Body.Statements[1] as VariableDeclarationStatementNode;
  815. var init = var.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  816. var op = init.Expression as UnaryOperatorExpressionNode;
  817. op.Operator.ShouldEqual(UnaryOperator.Negation);
  818. ((Int32LiteralNode)op.Operand).Value.ShouldEqual(2);
  819. }
  820. {
  821. var var = method.Body.Statements[2] as VariableDeclarationStatementNode;
  822. var init = var.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  823. var op = init.Expression as UnaryOperatorExpressionNode;
  824. op.Operator.ShouldEqual(UnaryOperator.LogicalNegation);
  825. ((BooleanLiteralNode)op.Operand).Value.ShouldEqual(true);
  826. }
  827. {
  828. var var = method.Body.Statements[3] as VariableDeclarationStatementNode;
  829. var init = var.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  830. var op = init.Expression as UnaryOperatorExpressionNode;
  831. op.Operator.ShouldEqual(UnaryOperator.BitwiseNegation);
  832. ((Int32LiteralNode)op.Operand).Value.ShouldEqual(0);
  833. }
  834. {
  835. var var = method.Body.Statements[4] as VariableDeclarationStatementNode;
  836. var init = var.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  837. var op = init.Expression as UnaryOperatorExpressionNode;
  838. op.Operator.ShouldEqual(UnaryOperator.AddressOf);
  839. ((SimpleNameNode)op.Operand).Identifier.ShouldEqual("i1");
  840. }
  841. {
  842. var var = method.Body.Statements[5] as VariableDeclarationStatementNode;
  843. var init = var.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  844. var op = init.Expression as UnaryOperatorExpressionNode;
  845. op.Operator.ShouldEqual(UnaryOperator.PointerIndirection);
  846. ((SimpleNameNode) op.Operand).Identifier.ShouldEqual("i5");
  847. }
  848. }
  849. // ----------------------------------------------------------------------------------------------
  850. /// <summary>
  851. /// Tests the parsing of the expression:
  852. /// var i1 = (int)0;
  853. /// </summary>
  854. // ----------------------------------------------------------------------------------------------
  855. [TestMethod]
  856. public void CastExpression()
  857. {
  858. var project = new CSharpProject(WorkingFolder);
  859. project.AddFile(@"Expressions\CastExpression.cs");
  860. InvokeParser(project, true, false).ShouldBeTrue();
  861. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  862. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  863. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  864. var typecast = initializer.Expression as CastExpressionNode;
  865. typecast.Type.TypeName.TypeTags[0].Identifier.ShouldEqual("int");
  866. ((Int32LiteralNode) typecast.Operand).Value.ShouldEqual(0);
  867. }
  868. // ----------------------------------------------------------------------------------------------
  869. /// <summary>
  870. /// Tests the parsing of the expression:
  871. /// var i1 = true ? 0 : 1;
  872. ///
  873. /// // right-associativity test
  874. /// var i2 = true ? 2 : false ? 3 : 4;
  875. /// </summary>
  876. // ----------------------------------------------------------------------------------------------
  877. [TestMethod]
  878. public void ConditionalExpression()
  879. {
  880. var project = new CSharpProject(WorkingFolder);
  881. project.AddFile(@"Expressions\ConditionalExpression.cs");
  882. InvokeParser(project, true, false).ShouldBeTrue();
  883. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  884. {
  885. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  886. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  887. var conditional = initializer.Expression as ConditionalExpressionNode;
  888. ((BooleanLiteralNode)conditional.Condition).Value.ShouldEqual(true);
  889. ((Int32LiteralNode)conditional.TrueExpression).Value.ShouldEqual(0);
  890. ((Int32LiteralNode)conditional.FalseExpression).Value.ShouldEqual(1);
  891. }
  892. {
  893. var varDecl = method.Body.Statements[1] as VariableDeclarationStatementNode;
  894. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  895. var conditional = initializer.Expression as ConditionalExpressionNode;
  896. ((BooleanLiteralNode) conditional.Condition).Value.ShouldEqual(true);
  897. ((Int32LiteralNode) conditional.TrueExpression).Value.ShouldEqual(2);
  898. var embeddedConditional = conditional.FalseExpression as ConditionalExpressionNode;
  899. ((Int32LiteralNode) embeddedConditional.TrueExpression).Value.ShouldEqual(3);
  900. ((Int32LiteralNode) embeddedConditional.FalseExpression).Value.ShouldEqual(4);
  901. }
  902. {
  903. var varDecl = method.Body.Statements[2] as VariableDeclarationStatementNode;
  904. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  905. var conditional = initializer.Expression as ConditionalExpressionNode;
  906. var isExpression = (conditional.Condition) as TypeTestingExpressionNode;
  907. ((Int32LiteralNode)isExpression.LeftOperand).Value.ShouldEqual(5);
  908. isExpression.Operator.ShouldEqual(TypeTestingOperator.Is);
  909. isExpression.RightOperand.TypeName.TypeTags[0].Identifier.ShouldEqual("int");
  910. var castExp = conditional.TrueExpression as CastExpressionNode;
  911. castExp.Type.TypeName.TypeTags[0].Identifier.ShouldEqual("int");
  912. ((Int32LiteralNode)castExp.Operand).Value.ShouldEqual(6);
  913. ((Int32LiteralNode)conditional.FalseExpression).Value.ShouldEqual(7);
  914. }
  915. }
  916. // ----------------------------------------------------------------------------------------------
  917. /// <summary>
  918. /// Tests the parsing of the expression:
  919. /// <code>
  920. /// // Lamba expression with block body, no parameters
  921. /// Dvoid d1 = () =&gt; { };
  922. ///
  923. /// // Lambda expression with expression body, no parameters
  924. /// Expression&lt;Func&lt;int&gt;&gt; d2 = () =&gt; 1;
  925. ///
  926. /// // Lambda expression with block body, explicit-anonymous-function-signature
  927. /// Dint d3 = (int i, ref int j, out int k) =&gt; { k = 1; return i; };
  928. ///
  929. /// // Lambda expression with expression body, implicit-anonymous-function-signature
  930. /// Expression&lt;Func&lt;int, int, int&gt;&gt; d4 = (i, j) =&gt; i + j;
  931. ///
  932. /// // Lambda expression are right-associative
  933. /// Expression&lt;Func&lt;Func&lt;int&gt;&gt;&gt; d5 = () =&gt; () =&gt; 2;
  934. /// </code>
  935. /// </summary>
  936. // ----------------------------------------------------------------------------------------------
  937. [TestMethod]
  938. public void LambdaExpressions()
  939. {
  940. var project = new CSharpProject(WorkingFolder);
  941. project.AddFile(@"Expressions\LambdaExpressions.cs");
  942. InvokeParser(project, true, false).ShouldBeTrue();
  943. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  944. {
  945. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  946. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  947. var lambda = initializer.Expression as LambdaExpressionNode;
  948. lambda.FormalParameters.Count.ShouldEqual(0);
  949. lambda.IsSimpleExpression.ShouldBeFalse();
  950. lambda.Expression.ShouldBeNull();
  951. lambda.Block.Statements.Count.ShouldEqual(0);
  952. }
  953. {
  954. var varDecl = method.Body.Statements[1] as VariableDeclarationStatementNode;
  955. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  956. var lambda = initializer.Expression as LambdaExpressionNode;
  957. lambda.FormalParameters.Count.ShouldEqual(0);
  958. lambda.IsSimpleExpression.ShouldBeTrue();
  959. ((Int32LiteralNode)lambda.Expression).Value.ShouldEqual(1);
  960. lambda.Block.ShouldBeNull();
  961. }
  962. {
  963. var varDecl = method.Body.Statements[2] as VariableDeclarationStatementNode;
  964. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  965. var lambda = initializer.Expression as LambdaExpressionNode;
  966. lambda.FormalParameters.Count.ShouldEqual(3);
  967. lambda.FormalParameters[0].Type.TypeName.TypeTags[0].Identifier.ShouldEqual("int");
  968. lambda.FormalParameters[0].Identifier.ShouldEqual("i");
  969. lambda.FormalParameters[0].Modifier.ShouldEqual(FormalParameterModifier.In);
  970. lambda.FormalParameters[1].Type.TypeName.TypeTags[0].Identifier.ShouldEqual("int");
  971. lambda.FormalParameters[1].Identifier.ShouldEqual("j");
  972. lambda.FormalParameters[1].Modifier.ShouldEqual(FormalParameterModifier.Ref);
  973. lambda.FormalParameters[2].Type.TypeName.TypeTags[0].Identifier.ShouldEqual("int");
  974. lambda.FormalParameters[2].Identifier.ShouldEqual("k");
  975. lambda.FormalParameters[2].Modifier.ShouldEqual(FormalParameterModifier.Out);
  976. lambda.IsSimpleExpression.ShouldBeFalse();
  977. lambda.Expression.ShouldBeNull();
  978. lambda.Block.Statements.Count.ShouldEqual(2);
  979. }
  980. {
  981. var varDecl = method.Body.Statements[3] as VariableDeclarationStatementNode;
  982. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  983. var lambda = initializer.Expression as LambdaExpressionNode;
  984. lambda.FormalParameters.Count.ShouldEqual(2);
  985. lambda.FormalParameters[0].Type.IsEmpty.ShouldBeTrue();
  986. lambda.FormalParameters[0].Identifier.ShouldEqual("i");
  987. lambda.FormalParameters[1].Type.IsEmpty.ShouldBeTrue();
  988. lambda.FormalParameters[1].Identifier.ShouldEqual("j");
  989. lambda.IsSimpleExpression.ShouldBeTrue();
  990. ((BinaryExpressionNode)lambda.Expression).Operator.ShouldEqual(BinaryOperator.Addition);
  991. ((SimpleNameNode)((BinaryExpressionNode)lambda.Expression).LeftOperand).Identifier.ShouldEqual("i");
  992. ((SimpleNameNode)((BinaryExpressionNode)lambda.Expression).RightOperand).Identifier.ShouldEqual("j");
  993. lambda.Block.ShouldBeNull();
  994. }
  995. {
  996. var varDecl = method.Body.Statements[4] as VariableDeclarationStatementNode;
  997. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  998. var lambda = initializer.Expression as LambdaExpressionNode;
  999. lambda.FormalParameters.Count.ShouldEqual(0);
  1000. var embeddedLambda = lambda.Expression as LambdaExpressionNode;
  1001. embeddedLambda.FormalParameters.Count.ShouldEqual(0);
  1002. ((Int32LiteralNode) embeddedLambda.Expression).Value.ShouldEqual(2);
  1003. }
  1004. }
  1005. // ----------------------------------------------------------------------------------------------
  1006. /// <summary>
  1007. /// Tests the parsing of the expression:
  1008. /// <code>
  1009. /// // Anonymous method without signature
  1010. /// Dvoid d1 = delegate { };
  1011. /// // Anonymous method with empty signature
  1012. /// Dvoid d2 = delegate() { };
  1013. /// // Anonymous method with signature
  1014. /// Dint d3 = delegate(int i, ref int j, out int k) { k = 1; return i; };
  1015. /// </code>
  1016. /// </summary>
  1017. // ----------------------------------------------------------------------------------------------
  1018. [TestMethod]
  1019. public void AnonymousMethodExpressions()
  1020. {
  1021. var project = new CSharpProject(WorkingFolder);
  1022. project.AddFile(@"Expressions\AnonymousMethodExpressions.cs");
  1023. InvokeParser(project, true, false).ShouldBeTrue();
  1024. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  1025. {
  1026. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  1027. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  1028. var anonym = initializer.Expression as AnonymousMethodExpressionNode;
  1029. anonym.FormalParameters.Count.ShouldEqual(0);
  1030. anonym.Body.Statements.Count.ShouldEqual(0);
  1031. }
  1032. {
  1033. var varDecl = method.Body.Statements[1] as VariableDeclarationStatementNode;
  1034. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  1035. var anonym = initializer.Expression as AnonymousMethodExpressionNode;
  1036. anonym.FormalParameters.Count.ShouldEqual(0);
  1037. anonym.Body.Statements.Count.ShouldEqual(0);
  1038. }
  1039. {
  1040. var varDecl = method.Body.Statements[2] as VariableDeclarationStatementNode;
  1041. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  1042. var anonym = initializer.Expression as AnonymousMethodExpressionNode;
  1043. anonym.FormalParameters.Count.ShouldEqual(3);
  1044. anonym.FormalParameters[0].Type.TypeName.TypeTags[0].Identifier.ShouldEqual("int");
  1045. anonym.FormalParameters[0].Identifier.ShouldEqual("i");
  1046. anonym.FormalParameters[0].Modifier.ShouldEqual(FormalParameterModifier.In);
  1047. anonym.FormalParameters[1].Type.TypeName.TypeTags[0].Identifier.ShouldEqual("int");
  1048. anonym.FormalParameters[1].Identifier.ShouldEqual("j");
  1049. anonym.FormalParameters[1].Modifier.ShouldEqual(FormalParameterModifier.Ref);
  1050. anonym.FormalParameters[2].Type.TypeName.TypeTags[0].Identifier.ShouldEqual("int");
  1051. anonym.FormalParameters[2].Identifier.ShouldEqual("k");
  1052. anonym.FormalParameters[2].Modifier.ShouldEqual(FormalParameterModifier.Out);
  1053. anonym.Body.Statements.Count.ShouldEqual(2);
  1054. }
  1055. }
  1056. // ----------------------------------------------------------------------------------------------
  1057. /// <summary>
  1058. /// Tests the parsing of the expression:
  1059. /// <code>
  1060. /// // simplest query with select: from-clause select-clause
  1061. /// var a1 = from i in array
  1062. /// select i;
  1063. ///
  1064. /// // simplest query with group: from-clause group-clause
  1065. /// var a2 = from int i in array
  1066. /// group i by i;
  1067. ///
  1068. /// // query with all possible clauses
  1069. /// var a3 = from i in array
  1070. /// from int j in array
  1071. /// let k = j
  1072. /// where true
  1073. /// join l in array on i equals l
  1074. /// join int p in array on i equals p
  1075. /// join n in array on i equals n into o
  1076. /// join int q in array on i equals q into r
  1077. /// orderby k ascending , j descending
  1078. /// select i
  1079. /// into m
  1080. /// select m;
  1081. /// </code>
  1082. /// </summary>
  1083. // ----------------------------------------------------------------------------------------------
  1084. [TestMethod]
  1085. public void QueryExpressions()
  1086. {
  1087. var project = new CSharpProject(WorkingFolder);
  1088. project.AddFile(@"Expressions\QueryExpressions.cs");
  1089. InvokeParser(project, true, false).ShouldBeTrue();
  1090. var method = project.SyntaxTree.CompilationUnitNodes[0].TypeDeclarations[0].MemberDeclarations[0] as MethodDeclarationNode;
  1091. {
  1092. var varDecl = method.Body.Statements[0] as VariableDeclarationStatementNode;
  1093. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  1094. var query = initializer.Expression as QueryExpressionNode;
  1095. query.FromClause.Type.IsEmpty.ShouldBeTrue();
  1096. query.FromClause.Identifier.ShouldEqual("i1");
  1097. ((SimpleNameNode)query.FromClause.Expression).Identifier.ShouldEqual("array");
  1098. query.QueryBody.BodyClauses.Count.ShouldEqual(0);
  1099. ((SimpleNameNode)query.QueryBody.SelectClause.Expression).Identifier.ShouldEqual("i1");
  1100. query.QueryBody.GroupClause.ShouldBeNull();
  1101. query.QueryBody.QueryContinuation.ShouldBeNull();
  1102. }
  1103. {
  1104. var varDecl = method.Body.Statements[1] as VariableDeclarationStatementNode;
  1105. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  1106. var query = initializer.Expression as QueryExpressionNode;
  1107. query.FromClause.Type.IsEmpty.ShouldBeFalse();
  1108. query.FromClause.Type.TypeName.TypeTags[0].Identifier.ShouldEqual("int");
  1109. query.FromClause.Identifier.ShouldEqual("i2");
  1110. ((SimpleNameNode)query.FromClause.Expression).Identifier.ShouldEqual("array");
  1111. query.QueryBody.BodyClauses.Count.ShouldEqual(0);
  1112. query.QueryBody.SelectClause.ShouldBeNull();
  1113. ((SimpleNameNode)query.QueryBody.GroupClause.GroupExpression).Identifier.ShouldEqual("i2");
  1114. var unaryNode = query.QueryBody.GroupClause.ByExpression as UnaryOperatorExpressionNode;
  1115. unaryNode.Operator.ShouldEqual(UnaryOperator.Negation);
  1116. ((SimpleNameNode)unaryNode.Operand).Identifier.ShouldEqual("i2");
  1117. query.QueryBody.QueryContinuation.ShouldBeNull();
  1118. }
  1119. {
  1120. var varDecl = method.Body.Statements[2] as VariableDeclarationStatementNode;
  1121. var initializer = varDecl.Declaration.VariableTags[0].Initializer as ExpressionInitializerNode;
  1122. var query = initializer.Expression as QueryExpressionNode;
  1123. query.FromClause.Type.IsEmpty.ShouldBeTrue();
  1124. query.FromClause.Identifier.ShouldEqual("i");
  1125. ((SimpleNameNode)query.FromClause.Expression).Identifier.ShouldEqual("array");
  1126. query.QueryBody.BodyClauses.Count.ShouldEqual(8);
  1127. var fromClause = query.QueryBody.BodyClauses[0] as FromClauseNode;
  1128. fromClause.Type.IsEmpty.ShouldBeFalse();
  1129. fromClause.Type.TypeName.TypeTags[0].Identifier.ShouldEqual("int");
  1130. fromClause.Identifier.ShouldEqual("j");
  1131. ((SimpleNameNode) fromClause.Expression).Identifier.ShouldEqual("array");
  1132. var letClause = query.QueryBody.BodyClauses[1] as LetClauseNode;
  1133. letClause.Identifier.ShouldEqual("k");
  1134. ((SimpleNameNode) letClause.Expression).Identifier.ShouldEqual("j");
  1135. var whereClause = query.QueryBody.BodyClauses[2] as WhereClauseNode;
  1136. ((TrueLiteralNode)whereClause.Expression).Value.ShouldEqual(true);
  1137. var joinClause = query.QueryBody.BodyClauses[3] as JoinClauseNode;
  1138. joinClause.Type.IsEmpty.ShouldBeTrue();
  1139. joinClause.Identifier.ShouldEqual("l");
  1140. ((SimpleNameNode) joinClause.InExpression).Identifier.ShouldEqual("array");
  1141. ((SimpleNameNode)joinClause.OnExpression).Identifier.ShouldEqual("i");
  1142. ((SimpleNameNode)joinClause.EqualsExpression).Identifier.ShouldEqual("l");
  1143. var joinClauseWithTypeName = query.QueryBody.BodyClauses[4] as JoinClauseNode;
  1144. joinClauseWithTypeName.Type.IsEmpty.ShouldBeFalse();
  1145. joinClauseWithTypeName.Type.TypeName.TypeTags[0].Identifier.ShouldEqual("int");
  1146. joinClauseWithTypeName.Identifier.ShouldEqual("p");
  1147. ((SimpleNameNode)joinClauseWithTypeName.InExpression).Identifier.ShouldEqual("array");
  1148. ((SimpleNameNode)joinClauseWithTypeName.OnExpression).Identifier.ShouldEqual("i");
  1149. ((SimpleNameNode)joinClauseWithTypeName.EqualsExpression).Identifier.ShouldEqual("p");
  1150. var joinIntoClause = query.QueryBody.BodyClauses[5] as JoinIntoClauseNode;
  1151. joinIntoClause.Type.IsEmpty.ShouldBeTrue();
  1152. joinIntoClause.Identifier.ShouldEqual("n");
  1153. ((SimpleNameNode)joinIntoClause.InExpression).Identifier.ShouldEqual("array");
  1154. ((SimpleNameNode)joinIntoClause.OnExpression).Identifier.ShouldEqual("i");
  1155. ((SimpleNameNode)joinIntoClause.EqualsExpression).Identifier.ShouldEqual("n");
  1156. joinIntoClause.IntoIdentifier.ShouldEqual("o");
  1157. var joinIntoClauseWithTypeName = query.QueryBody.BodyClauses[6] as JoinIntoClauseNode;
  1158. joinIntoClauseWithTypeName.Type.IsEmpty.ShouldBeFalse();
  1159. joinIntoClauseWithTypeName.Type.TypeName.TypeTags[0].Identifier.ShouldEqual("int");
  1160. joinIntoClauseWithTypeName.Identifier.ShouldEqual("q");
  1161. ((SimpleNameNode)joinIntoClauseWithTypeName.InExpression).Identifier.ShouldEqual("array");
  1162. ((SimpleNameNode)joinIntoClauseWithTypeName.OnExpression).Identifier.ShouldEqual("i");
  1163. ((SimpleNameNode)joinIntoClauseWithTypeName.EqualsExpression).Identifier.ShouldEqual("q");
  1164. joinIntoClauseWithTypeName.IntoIdentifier.ShouldEqual("r");
  1165. var orderbyClause = query.QueryBody.BodyClauses[7] as OrderByClauseNode;
  1166. orderbyClause.Orderings.Count.ShouldEqual(2);
  1167. ((SimpleNameNode) orderbyClause.Orderings[0].Expression).Identifier.ShouldEqual("k");
  1168. orderbyClause.Orderings[0].IsAscending.ShouldBeTrue();
  1169. ((SimpleNameNode)orderbyClause.Orderings[1].Expression).Identifier.ShouldEqual("j");
  1170. orderbyClause.Orderings[1].IsAscending.ShouldBeFalse();
  1171. ((SimpleNameNode)query.QueryBody.SelectClause.Expression).Identifier.ShouldEqual("i");
  1172. query.QueryBody.GroupClause.ShouldBeNull();
  1173. query.QueryBody.QueryContinuation.Identifier.ShouldEqual("m");
  1174. var embeddedQuery = query.QueryBody.QueryContinuation.QueryBody;
  1175. embeddedQuery.BodyClauses.Count.ShouldEqual(0);
  1176. ((SimpleNameNode) embeddedQuery.SelectClause.Expression).Identifier.ShouldEqual("m");
  1177. embeddedQuery.GroupClause.ShouldBeNull();
  1178. embeddedQuery.QueryContinuation.ShouldBeNull();
  1179. }
  1180. }
  1181. }
  1182. }