1 34 package org.codehaus.groovy.syntax.parser; 35 36 import java.util.Iterator ; 37 import java.util.List ; 38 39 import org.codehaus.groovy.ast.ClassNode; 40 import org.codehaus.groovy.ast.MethodNode; 41 import org.codehaus.groovy.ast.ModuleNode; 42 import org.codehaus.groovy.ast.expr.BinaryExpression; 43 import org.codehaus.groovy.ast.expr.ClassExpression; 44 import org.codehaus.groovy.ast.expr.ClosureExpression; 45 import org.codehaus.groovy.ast.expr.ConstantExpression; 46 import org.codehaus.groovy.ast.expr.Expression; 47 import org.codehaus.groovy.ast.expr.MapEntryExpression; 48 import org.codehaus.groovy.ast.expr.MapExpression; 49 import org.codehaus.groovy.ast.expr.VariableExpression; 50 import org.codehaus.groovy.ast.stmt.BlockStatement; 51 import org.codehaus.groovy.ast.stmt.ExpressionStatement; 52 import org.codehaus.groovy.ast.stmt.ForStatement; 53 import org.codehaus.groovy.ast.stmt.IfStatement; 54 import org.codehaus.groovy.ast.stmt.ReturnStatement; 55 import org.codehaus.groovy.control.CompilationFailedException; 56 import org.codehaus.groovy.runtime.InvokerHelper; 57 import org.codehaus.groovy.syntax.SyntaxException; 58 import org.codehaus.groovy.syntax.Types; 59 import org.codehaus.groovy.syntax.lexer.UnexpectedCharacterException; 60 61 67 public class ASTBuilderTest extends TestParserSupport { 68 69 public void testStatementParsing() throws Exception { 70 ModuleNode module = 71 parse("import cheddar.cheese.Toast as Bread\n x = [1, 2, 3]; System.out.println(x)", "foo/Cheese.groovy"); 72 73 BlockStatement block = module.getStatementBlock(); 74 assertTrue("Contains some statements", !block.getStatements().isEmpty()); 75 76 } 78 79 public void testBlock() throws Exception { 80 ModuleNode module = 81 parse("class Foo { void testMethod() { x = someMethod(); callMethod(x) } }", "Dummy.groovy"); 82 BlockStatement statement = getCode(module, "testMethod"); 83 84 assertEquals("Statements size: " + statement.getStatements(), 2, statement.getStatements().size()); 85 86 System.out.println(statement.getStatements()); 87 } 88 89 public void testSubscript() throws Exception { 90 ModuleNode module = 91 parse("class Foo { void testMethod() { x = 1\n [1].each { println(it) }} }", "Dummy.groovy"); 92 BlockStatement statement = getCode(module, "testMethod"); 93 94 assertEquals("Statements size: " + statement.getStatements(), 2, statement.getStatements().size()); 95 96 for (Iterator iter = statement.getStatements().iterator(); iter.hasNext();) { 97 System.out.println(iter.next()); 98 } 99 } 100 101 public void testNewlinesInsideExpresssions() throws Exception { 102 ModuleNode module = parse("class Foo { void testMethod() { x = 1 +\n 5 * \n 2 / \n 5 } }", "Dummy.groovy"); 103 BlockStatement statement = getCode(module, "testMethod"); 104 105 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 106 107 for (Iterator iter = statement.getStatements().iterator(); iter.hasNext();) { 108 System.out.println(iter.next()); 109 } 110 } 111 112 public void testMethodCalls() throws Exception { 113 ModuleNode module = 114 parse( 115 "class Foo { void testMethod() { array = getMockArguments()\n \n dummyMethod(array) } }", 116 "Dummy.groovy"); 117 BlockStatement statement = getCode(module, "testMethod"); 118 119 assertEquals("Statements size: " + statement.getStatements(), 2, statement.getStatements().size()); 120 121 for (Iterator iter = statement.getStatements().iterator(); iter.hasNext();) { 122 System.out.println(iter.next()); 123 } 124 } 125 126 public void testJdk15ForLoop() throws Exception { 127 ModuleNode module = parse("class Foo { void testMethod() { for (x : foo) { println x } } }", "Dummy.groovy"); 128 BlockStatement statement = getCode(module, "testMethod"); 129 130 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 131 132 ForStatement stmt = (ForStatement) statement.getStatements().get(0); 133 assertEquals("x", stmt.getVariable()); 134 assertTrue(stmt.getVariableType().isDynamic()); 135 System.out.println(stmt); 136 } 137 138 public void testJdk15ForLoopWithType() throws Exception { 139 ModuleNode module = parse("class Foo { void testMethod() { for (Integer x : foo) { println x } } }", "Dummy.groovy"); 140 BlockStatement statement = getCode(module, "testMethod"); 141 142 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 143 144 ForStatement stmt = (ForStatement) statement.getStatements().get(0); 145 assertEquals("x", stmt.getVariable()); 146 System.out.println( stmt.getVariableType().getName() ); 147 assertEquals("java.lang.Integer", stmt.getVariableType().getName()); 148 assertFalse(stmt.getVariableType().isDynamic()); 149 System.out.println(stmt); 150 } 151 152 public void testForLoopWithType() throws Exception { 153 ModuleNode module = parse("class Foo { void testMethod() { for (Foo x in foo) { println x } } }", "Dummy.groovy"); 154 BlockStatement statement = getCode(module, "testMethod"); 155 156 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 157 158 ForStatement stmt = (ForStatement) statement.getStatements().get(0); 159 assertEquals("x", stmt.getVariable()); 160 assertEquals("Foo", stmt.getVariableType().getName()); 161 assertFalse(stmt.getVariableType().isDynamic()); 162 System.out.println(stmt); 163 } 164 165 public void testSubscriptAssignment() throws Exception { 166 ModuleNode module = parse("class Foo { void testMethod() { x[12] = 'abc' } }", "Dummy.groovy"); 167 BlockStatement statement = getCode(module, "testMethod"); 168 169 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 170 171 ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0); 172 Expression exp = exprStmt.getExpression(); 173 System.out.println(exp); 174 175 assertTrue(exp instanceof BinaryExpression); 176 BinaryExpression binExpr = (BinaryExpression) exp; 177 assertTrue("RHS is constant", binExpr.getRightExpression() instanceof ConstantExpression); 178 179 Expression lhs = binExpr.getLeftExpression(); 180 assertTrue("LHS is binary expression", lhs instanceof BinaryExpression); 181 182 BinaryExpression lhsBinExpr = (BinaryExpression) lhs; 183 assertEquals(Types.LEFT_SQUARE_BRACKET, lhsBinExpr.getOperation().getType()); 184 185 assertTrue("Left of LHS is a variable", lhsBinExpr.getLeftExpression() instanceof VariableExpression); 186 assertTrue("Right of LHS is a constant", lhsBinExpr.getRightExpression() instanceof ConstantExpression); 187 188 } 189 190 public void testNoReturn() throws Exception { 191 ModuleNode module = parse("class Foo { void testMethod() { x += 5 } }", "Dummy.groovy"); 192 BlockStatement statement = getCode(module, "testMethod"); 193 194 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 195 196 System.out.println(statement.getStatements()); 197 198 ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0); 199 Expression exp = exprStmt.getExpression(); 200 201 System.out.println("expr: " + exp); 202 } 203 204 public void testCastExpression() throws Exception { 205 ModuleNode module = parse("class Foo { void testMethod() { x = (Short) 5 } }", "Dummy.groovy"); 206 BlockStatement statement = getCode(module, "testMethod"); 207 208 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 209 210 System.out.println(statement.getStatements()); 211 212 ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0); 213 Expression exp = exprStmt.getExpression(); 214 215 System.out.println("expr: " + exp); 216 } 217 218 public void testTernaryExpression() throws Exception { 219 ModuleNode module = parse("class Foo { void testMethod() { foo() ? 'a' : 'b' } }", "Dummy.groovy"); 220 BlockStatement statement = getCode(module, "testMethod"); 221 222 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 223 224 System.out.println(statement.getStatements()); 225 226 ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0); 227 Expression exp = exprStmt.getExpression(); 228 229 System.out.println("expr: " + exp); 230 } 231 232 public void testClosureWithJustIdentifierBug() throws Exception { 233 ModuleNode module = parse("class Foo { void testMethod() { return {a} } }", "Dummy.groovy"); 234 BlockStatement statement = getCode(module, "testMethod"); 235 236 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 237 238 System.out.println(statement.getStatements()); 239 240 ReturnStatement returnStmt = (ReturnStatement)statement.getStatements().get(0); 241 Expression exp = returnStmt.getExpression(); 242 243 System.out.println("expr: " + exp); 244 } 245 246 public void testClosureWithJustIdentifierInMapBug() throws Exception { 247 ModuleNode module = parse("class Foo { void testMethod() { ['x':{a}, 'd':123] } }", "Dummy.groovy"); 248 BlockStatement statement = getCode(module, "testMethod"); 249 250 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 251 252 System.out.println(statement.getStatements()); 253 254 ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0); 255 256 MapExpression mapExp = (MapExpression) exprStmt.getExpression(); 257 MapEntryExpression entryExp = (MapEntryExpression) mapExp.getMapEntryExpressions().get(0); 258 ClosureExpression closureExp = (ClosureExpression) entryExp.getValueExpression(); 259 assertEquals("Parameters on closure", 0, closureExp.getParameters().length); 260 System.out.println("expr: " + closureExp); 261 } 262 263 public void testArrayExpression() throws Exception { 264 ModuleNode module = parse("class Foo { void testMethod() { foo = new String[] { 'a', 'b', 'c' }\n assert foo != null } }", "Dummy.groovy"); 265 BlockStatement statement = getCode(module, "testMethod"); 266 267 assertEquals("Statements size: " + statement.getStatements(), 2, statement.getStatements().size()); 268 269 System.out.println(statement.getStatements()); 270 271 ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0); 272 Expression exp = exprStmt.getExpression(); 273 274 System.out.println("expr: " + exp); 275 } 276 277 public void testTypedVariableExpression() throws Exception { 278 ModuleNode module = parse("class Foo { void testMethod() { Short x = 5 } }", "Dummy.groovy"); 279 BlockStatement statement = getCode(module, "testMethod"); 280 281 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 282 283 System.out.println(statement.getStatements()); 284 285 ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0); 286 Expression exp = exprStmt.getExpression(); 287 288 System.out.println("expr: " + exp); 289 } 290 291 public void testFullyQualifiedType() throws Exception { 292 ModuleNode module = parse("class Foo { void testMethod() { com.acme.Foo } }", "Dummy.groovy"); 293 BlockStatement statement = getCode(module, "testMethod"); 294 295 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 296 297 System.out.println(statement.getStatements()); 298 299 ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0); 300 Expression exp = exprStmt.getExpression(); 301 302 System.out.println("expr: " + exp); 303 304 System.out.println("text: " + exp.getText()); 305 } 306 307 public void testDoubleSubscript() throws Exception { 308 ModuleNode module = parse("class Foo { void testMethod() { x = foo[0][0] } }", "Dummy.groovy"); 309 BlockStatement statement = getCode(module, "testMethod"); 310 311 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 312 313 System.out.println(statement.getStatements()); 314 315 ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0); 316 Expression exp = exprStmt.getExpression(); 317 318 System.out.println("expr: " + exp); 319 320 System.out.println("text: " + exp.getText()); 321 } 322 323 public void testMethodCallWithDotAndNoParenthesis() throws Exception { 324 ModuleNode module = parse("class Foo { void testMethod() { foo.someMethod 1 } }", "Dummy.groovy"); 325 BlockStatement statement = getCode(module, "testMethod"); 326 327 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 328 329 System.out.println(statement.getStatements()); 330 331 ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0); 332 Expression exp = exprStmt.getExpression(); 333 334 System.out.println("expr: " + exp); 335 336 System.out.println("text: " + exp.getText()); 337 } 338 339 public void testMethodCallWithNoParenthesis() throws Exception { 340 ModuleNode module = parse("class Foo { void testMethod() { someMethod 1 } }", "Dummy.groovy"); 341 BlockStatement statement = getCode(module, "testMethod"); 342 343 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 344 345 System.out.println(statement.getStatements()); 346 347 ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0); 348 Expression exp = exprStmt.getExpression(); 349 350 System.out.println("expr: " + exp); 351 352 System.out.println("text: " + exp.getText()); 353 } 354 355 public void testScriptMethodCallWithNoParenthesis() throws Exception { 356 ModuleNode module = parse("someMethod 1", "Dummy.groovy"); 357 BlockStatement statement = getCode(module, "run"); 358 359 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 360 361 System.out.println(statement.getStatements()); 362 363 ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0); 364 Expression exp = exprStmt.getExpression(); 365 366 System.out.println("expr: " + exp); 367 368 System.out.println("text: " + exp.getText()); 369 } 370 371 public void testScriptWithMethodDeclaration() throws Exception { 372 ModuleNode module = parse("def foo(a) { return a + 1}\n foo(123)", "Dummy.groovy"); 373 BlockStatement statement = getCode(module, "run"); 374 375 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 376 377 System.out.println(statement.getStatements()); 378 379 ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0); 380 Expression exp = exprStmt.getExpression(); 381 382 System.out.println("expr: " + exp); 383 384 System.out.println("text: " + exp.getText()); 385 } 386 387 public void testSubscriptThenMethod() throws Exception { 388 ModuleNode module = parse("class Foo { void testMethod() { x = foo[0].foo() } }", "Dummy.groovy"); 389 BlockStatement statement = getCode(module, "testMethod"); 390 391 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 392 393 System.out.println(statement.getStatements()); 394 395 ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0); 396 Expression exp = exprStmt.getExpression(); 397 398 System.out.println("expr: " + exp); 399 400 System.out.println("text: " + exp.getText()); 401 } 402 403 public void testSubscriptThenOperation() throws Exception { 404 ModuleNode module = parse("class Foo { void testMethod() { foo[0] += 5 } }", "Dummy.groovy"); 405 BlockStatement statement = getCode(module, "testMethod"); 406 407 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 408 409 System.out.println(statement.getStatements()); 410 411 ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0); 412 Expression exp = exprStmt.getExpression(); 413 414 System.out.println("expr: " + exp); 415 416 System.out.println("text: " + exp.getText()); 417 } 418 419 420 public void testRodsBug() throws Exception { 421 ModuleNode module = parse("class Foo { void testMethod() { if (x) { String n = 'foo' } } }", "Dummy.groovy"); 422 BlockStatement statement = getCode(module, "testMethod"); 423 424 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 425 426 System.out.println(statement.getStatements()); 427 428 IfStatement ifStmt = (IfStatement) statement.getStatements().get(0); 429 BlockStatement trueStmt = (BlockStatement) ifStmt.getIfBlock(); 430 431 System.out.println("trueStmt: " + trueStmt); 432 433 assertEquals(1, trueStmt.getStatements().size()); 435 } 436 437 public void testStaticMethodCallBug() throws Exception { 438 ModuleNode module = 439 parse("class Foo { void testMethod() { ASTBuilderTest.mockHelperMethod() } }", "Dummy.groovy"); 440 BlockStatement statement = getCode(module, "testMethod"); 441 442 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 443 444 System.out.println(statement.getStatements()); 445 } 446 447 public void testInstanceofBug() throws Exception { 448 ModuleNode module = 449 parse("class Foo { void testMethod() { if (foo instanceof java.util.List) { println('hello') } } }", "Dummy.groovy"); 450 BlockStatement statement = getCode(module, "testMethod"); 451 452 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 453 454 System.out.println(statement.getStatements()); 455 456 IfStatement ifStmt = (IfStatement) statement.getStatements().get(0); 457 BinaryExpression exp = (BinaryExpression) ifStmt.getBooleanExpression().getExpression(); 458 459 System.out.println("exp: " + exp); 460 461 Expression rhs = exp.getRightExpression(); 462 assertTrue("RHS should be a class expression", rhs instanceof ClassExpression); 463 464 ClassExpression classExp = (ClassExpression) rhs; 465 assertEquals("java.util.List", classExp.getType()); 466 } 467 468 public void testMethodCallWithoutParensBug() throws Exception { 469 ModuleNode module = parse("class Foo { void testMethod() { println 3, 5 } }", "Dummy.groovy"); 470 BlockStatement statement = getCode(module, "testMethod"); 471 472 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 473 474 System.out.println(statement.getStatements()); 475 } 476 477 public void testReturnMethodClosure() throws Exception { 478 ModuleNode module = parse("class Foo { void testMethod() { System.out.println\n}}", "Dummy.groovy"); 479 BlockStatement statement = getCode(module, "testMethod"); 480 481 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 482 483 System.out.println(statement.getStatements()); 484 } 485 486 public void testDionsTypo() throws Exception { 487 ModuleNode module = parse("class Foo { void testMethod() { println ${foo}\n}}", "Dummy.groovy"); 488 BlockStatement statement = getCode(module, "testMethod"); 489 490 assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size()); 491 492 System.out.println(statement.getStatements()); 493 } 494 495 public void testMethodWithArrayTypeParam() throws Exception { 496 ModuleNode module = parse("class Foo { void main(String[] args) { println(args) } }", "Dummy.groovy"); 497 498 MethodNode method = getMethod(module, "main"); 499 500 System.out.println("Parameters: " + InvokerHelper.toString(method.getParameters())); 501 } 502 503 private void ensureOutOfRange(String script) throws Exception { 504 try { 505 ModuleNode module = parse(script, "Dummy.groovy"); 506 } catch (CompilationFailedException e) { 507 SyntaxException cause = e.getUnit().getSyntaxError(0); 508 if( cause != null && cause instanceof ParserException && cause.getMessage().indexOf("out of range") >= 0) { 509 return; 510 } 511 fail (script+" should fail with a ParserException: "+e.getMessage()); 512 } 513 fail(script+" should fail because the number is out of range."); 514 } 515 516 private void ensureInRange(String script) throws Exception { 517 ModuleNode module = parse(script, "Dummy.groovy"); 518 } 519 520 public void testLiteralIntegerRange() throws Exception { 521 ensureInRange( "x = 2147483647I;"); 522 ensureOutOfRange("x = 2147483648I;"); 523 524 ensureInRange( "x = -2147483648I;"); 525 ensureOutOfRange("x = -2147483649I;"); 526 } 527 528 public void testLiteralLongRange() throws Exception { 529 ensureInRange( "x = 9223372036854775807L;"); 530 ensureOutOfRange("x = 9223372036854775808L;"); 531 532 ensureInRange( "x = -9223372036854775808L;"); 533 ensureOutOfRange("x = -9223372036854775809L;"); 534 } 535 536 public void testLiteralDoubleRange() throws Exception { 537 ensureInRange( "x = 1.7976931348623157E308D;"); 538 ensureOutOfRange("x = 1.7976931348623167E308D;"); 539 540 ensureInRange( "x = -1.7976931348623157E308D;"); 541 ensureOutOfRange("x = -1.7976931348623167E308D;"); 542 } 543 544 public void testLiteralFloatRange() throws Exception { 545 ensureInRange( "x = 3.4028235e+38f;"); 546 ensureOutOfRange("x = 3.4028236e+38f;"); 547 548 ensureInRange( "x = -3.4028235e+38f;"); 549 ensureOutOfRange("x = -3.4028236e+38f;"); 550 } 551 552 public void testLiteralIntegerBadSuffix() throws Exception { 553 try { 554 ModuleNode module = parse("x = 2147483648J;", "Dummy.groovy"); 555 } catch (CompilationFailedException e) { 556 SyntaxException cause = e.getUnit().getSyntaxError(0); 557 if (cause instanceof UnexpectedCharacterException) { 558 return; 559 } 560 fail ("x = 2147483648J should fail with an UnexpectedCharacterException"); 561 } 562 fail("x = 2147483648J, should fail because J is an invalid numeric literal suffix."); 563 } 564 565 public void testLiteralBadExponent() throws Exception { 566 try { 567 ModuleNode module = parse("x = 2.3e;", "Dummy.groovy"); 568 } catch (CompilationFailedException e) { 569 SyntaxException cause = e.getUnit().getSyntaxError(0); 570 if (cause instanceof UnexpectedCharacterException) { 571 return; 572 } 573 fail ("x = 2.3e should fail with an UnexpectedCharacterException"); 574 } 575 fail("x = 2.3e, should fail because no exponent is specified."); 576 } 577 578 public static Object mockHelperMethod() { 579 return "cheese"; 580 } 581 582 protected BlockStatement getCode(ModuleNode module, String name) { 583 MethodNode method = getMethod(module, name); 584 585 BlockStatement statement = (BlockStatement) method.getCode(); 586 assertNotNull(statement); 587 return statement; 588 } 589 590 protected MethodNode getMethod(ModuleNode module, String name) { 591 assertEquals("class count", 1, module.getClasses().size()); 592 593 ClassNode node = (ClassNode) module.getClasses().get(0); 594 595 assertNotNull(node); 596 597 List methods = node.getDeclaredMethods(name); 598 assertTrue(methods.size() > 0); 599 return (MethodNode) methods.get(0); 600 } 601 } 602 | Popular Tags |