1   /*
2    * $Id: ASTBuilderTest.java,v 1.32 2005/04/04 21:46:57 glaforge Exp $
3    *
4    * Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
5    *
6    * Redistribution and use of this software and associated documentation
7    * ("Software"), with or without modification, are permitted provided that the
8    * following conditions are met: 1. Redistributions of source code must retain
9    * copyright statements and notices. Redistributions must also contain a copy
10   * of this document. 2. Redistributions in binary form must reproduce the above
11   * copyright notice, this list of conditions and the following disclaimer in
12   * the documentation and/or other materials provided with the distribution. 3.
13   * The name "groovy" must not be used to endorse or promote products derived
14   * from this Software without prior written permission of The Codehaus. For
15   * written permission, please contact info@codehaus.org. 4. Products derived
16   * from this Software may not be called "groovy" nor may "groovy" appear in
17   * their names without prior written permission of The Codehaus. "groovy" is a
18   * registered trademark of The Codehaus. 5. Due credit should be given to The
19   * Codehaus - http://groovy.codehaus.org/
20   *
21   * THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS ``AS IS'' AND ANY
22   * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24   * DISCLAIMED. IN NO EVENT SHALL THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR
25   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31   * DAMAGE.
32   *
33   */
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  /***
62   * Test case for the AST builder
63   *
64   * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
65   * @version $Revision: 1.32 $
66   */
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          //System.out.println("Statements: " + block.getStatements());
77      }
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() { def 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 /*  todo should we or shouldn't we support the jdk 1.5 for loop, with the colon in lieu of the groovy 'in' keyword?
127     public void testJdk15ForLoop() throws Exception {
128         ModuleNode module = parse("class Foo { void testMethod() { for (x : foo) { println x } } }", "Dummy.groovy");
129         BlockStatement statement = getCode(module, "testMethod");
130 
131         assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size());
132 
133         ForStatement stmt = (ForStatement) statement.getStatements().get(0);
134         assertEquals("x", stmt.getVariable());
135         assertTrue(stmt.getVariableType().isDynamic());
136         System.out.println(stmt);
137     }
138 
139     public void testJdk15ForLoopWithType() throws Exception {
140         ModuleNode module = parse("class Foo { void testMethod() { for (Integer x : foo) { println x } } }", "Dummy.groovy");
141         BlockStatement statement = getCode(module, "testMethod");
142 
143         assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size());
144 
145         ForStatement stmt = (ForStatement) statement.getStatements().get(0);
146         assertEquals("x", stmt.getVariable());
147         System.out.println( stmt.getVariableType().getName() );
148         assertEquals("java.lang.Integer", stmt.getVariableType().getName());
149         assertFalse(stmt.getVariableType().isDynamic());
150         System.out.println(stmt);
151     }
152 */
153 
154     public void testForLoopWithType() throws Exception {
155         ModuleNode module = parse("class Foo { void testMethod() { for (Foo x in foo) { println x } } }", "Dummy.groovy");
156         BlockStatement statement = getCode(module, "testMethod");
157 
158         assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size());
159 
160         ForStatement stmt = (ForStatement) statement.getStatements().get(0);
161         assertEquals("x", stmt.getVariable());
162         assertEquals("Foo", stmt.getVariableType().getName());
163         assertFalse(stmt.getVariableType().isDynamic());
164         System.out.println(stmt);
165     }
166 
167     public void testSubscriptAssignment() throws Exception {
168         ModuleNode module = parse("class Foo { void testMethod() { x[12] = 'abc' } }", "Dummy.groovy");
169         BlockStatement statement = getCode(module, "testMethod");
170 
171         assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size());
172 
173         ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0);
174         Expression exp = exprStmt.getExpression();
175         System.out.println(exp);
176 
177         assertTrue(exp instanceof BinaryExpression);
178         BinaryExpression binExpr = (BinaryExpression) exp;
179         assertTrue("RHS is constant", binExpr.getRightExpression() instanceof ConstantExpression);
180 
181         Expression lhs = binExpr.getLeftExpression();
182         assertTrue("LHS is binary expression", lhs instanceof BinaryExpression);
183 
184         BinaryExpression lhsBinExpr = (BinaryExpression) lhs;
185         assertEquals(Types.LEFT_SQUARE_BRACKET, lhsBinExpr.getOperation().getType());
186 
187         assertTrue("Left of LHS is a variable", lhsBinExpr.getLeftExpression() instanceof VariableExpression);
188         assertTrue("Right of LHS is a constant", lhsBinExpr.getRightExpression() instanceof ConstantExpression);
189 
190     }
191 
192     public void testNoReturn() throws Exception {
193         ModuleNode module = parse("class Foo { void testMethod() { x += 5 } }", "Dummy.groovy");
194         BlockStatement statement = getCode(module, "testMethod");
195 
196         assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size());
197 
198         System.out.println(statement.getStatements());
199 
200         ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0);
201         Expression exp = exprStmt.getExpression();
202 
203         System.out.println("expr: " + exp);
204     }
205 
206     public void testCastExpression() throws Exception {
207         ModuleNode module = parse("class Foo { void testMethod() { x = (Short) 5 } }", "Dummy.groovy");
208         BlockStatement statement = getCode(module, "testMethod");
209 
210         assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size());
211 
212         System.out.println(statement.getStatements());
213 
214         ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0);
215         Expression exp = exprStmt.getExpression();
216 
217         System.out.println("expr: " + exp);
218     }
219 
220     public void testTernaryExpression() throws Exception {
221         ModuleNode module = parse("class Foo { void testMethod() { foo() ? 'a' : 'b' } }", "Dummy.groovy");
222         BlockStatement statement = getCode(module, "testMethod");
223 
224         assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size());
225 
226         System.out.println(statement.getStatements());
227 
228         ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0);
229         Expression exp = exprStmt.getExpression();
230 
231         System.out.println("expr: " + exp);
232     }
233 
234     public void testClosureWithJustIdentifierBug() throws Exception {
235         ModuleNode module = parse("class Foo { void testMethod() { return {a} } }", "Dummy.groovy");
236         BlockStatement statement = getCode(module, "testMethod");
237 
238         assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size());
239 
240         System.out.println(statement.getStatements());
241 
242         ReturnStatement returnStmt = (ReturnStatement)statement.getStatements().get(0);
243         Expression exp = returnStmt.getExpression();
244 
245         System.out.println("expr: " + exp);
246     }
247 
248     public void testClosureWithJustIdentifierInMapBug() throws Exception {
249         ModuleNode module = parse("class Foo { void testMethod() { ['x':{a}, 'd':123] } }", "Dummy.groovy");
250         BlockStatement statement = getCode(module, "testMethod");
251 
252         assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size());
253 
254         System.out.println(statement.getStatements());
255 
256         ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0);
257 
258         MapExpression mapExp = (MapExpression) exprStmt.getExpression();
259         MapEntryExpression entryExp = (MapEntryExpression) mapExp.getMapEntryExpressions().get(0);
260         ClosureExpression closureExp = (ClosureExpression) entryExp.getValueExpression();
261         assertEquals("Parameters on closure", 0, closureExp.getParameters().length);
262         System.out.println("expr: " + closureExp);
263     }
264 
265     public void testArrayExpression() throws Exception {
266         ModuleNode module = parse("class Foo { void testMethod() { def foo = ['a', 'b', 'c']  as String[]\n assert foo != null } }", "Dummy.groovy");
267         BlockStatement statement = getCode(module, "testMethod");
268 
269         assertEquals("Statements size: " + statement.getStatements(), 2, statement.getStatements().size());
270 
271         System.out.println(statement.getStatements());
272 
273         ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0);
274         Expression exp = exprStmt.getExpression();
275 
276         System.out.println("expr: " + exp);
277     }
278 
279     public void testArrayExpression2() throws Exception {
280         ModuleNode module = parse("class Foo { void testMethod() { String[] foo = ['a', 'b', 'c']\n assert foo != null } }", "Dummy.groovy");
281         BlockStatement statement = getCode(module, "testMethod");
282 
283         assertEquals("Statements size: " + statement.getStatements(), 2, statement.getStatements().size());
284 
285         System.out.println(statement.getStatements());
286 
287         ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0);
288         Expression exp = exprStmt.getExpression();
289 
290         System.out.println("expr: " + exp);
291     }
292 
293     public void testTypedVariableExpression() throws Exception {
294         ModuleNode module = parse("class Foo { void testMethod() { Short x = 5 } }", "Dummy.groovy");
295         BlockStatement statement = getCode(module, "testMethod");
296 
297         assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size());
298 
299         System.out.println(statement.getStatements());
300 
301         ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0);
302         Expression exp = exprStmt.getExpression();
303 
304         System.out.println("expr: " + exp);
305     }
306 
307     public void testFullyQualifiedType() throws Exception {
308         ModuleNode module = parse("class Foo { void testMethod() { com.acme.Foo } }", "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 testDoubleSubscript() throws Exception {
324         ModuleNode module = parse("class Foo { void testMethod() { x = foo[0][0] } }", "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 testMethodCallWithDotAndNoParenthesis() throws Exception {
340         ModuleNode module = parse("class Foo { void testMethod() { foo.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 testMethodCallWithNoParenthesis() throws Exception {
356         ModuleNode module = parse("class Foo { void testMethod() { someMethod 1 } }", "Dummy.groovy");
357         BlockStatement statement = getCode(module, "testMethod");
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 testScriptMethodCallWithNoParenthesis() throws Exception {
372         ModuleNode module = parse("someMethod 1", "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 testScriptWithMethodDeclaration() throws Exception {
388         ModuleNode module = parse("def foo(a) { return a + 1}\n foo(123)", "Dummy.groovy");
389         BlockStatement statement = getCode(module, "run");
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 testSubscriptThenMethod() throws Exception {
404         ModuleNode module = parse("class Foo { void testMethod() { x = foo[0].foo() } }", "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     public void testSubscriptThenOperation() throws Exception {
420         ModuleNode module = parse("class Foo { void testMethod() { foo[0] += 5 } }", "Dummy.groovy");
421         BlockStatement statement = getCode(module, "testMethod");
422 
423         assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size());
424 
425         System.out.println(statement.getStatements());
426 
427         ExpressionStatement exprStmt = (ExpressionStatement) statement.getStatements().get(0);
428         Expression exp = exprStmt.getExpression();
429 
430         System.out.println("expr: " + exp);
431 
432         System.out.println("text: " + exp.getText());
433     }
434 
435 
436     public void testRodsBug() throws Exception {
437         ModuleNode module = parse("class Foo { void testMethod() { if (x) { String n = 'foo' } } }", "Dummy.groovy");
438         BlockStatement statement = getCode(module, "testMethod");
439 
440         assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size());
441 
442         System.out.println(statement.getStatements());
443 
444         IfStatement ifStmt = (IfStatement) statement.getStatements().get(0);
445         BlockStatement trueStmt = (BlockStatement) ifStmt.getIfBlock();
446 
447         System.out.println("trueStmt: " + trueStmt);
448 
449         // ideally there would be 1 statement; though we're handling that in the verifier
450         assertEquals(1, trueStmt.getStatements().size());
451     }
452 
453     public void testStaticMethodCallBug() throws Exception {
454         ModuleNode module =
455             parse("class Foo { void testMethod() { ASTBuilderTest.mockHelperMethod() } }", "Dummy.groovy");
456         BlockStatement statement = getCode(module, "testMethod");
457 
458         assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size());
459 
460         System.out.println(statement.getStatements());
461     }
462 
463     public void testInstanceofBug() throws Exception {
464         ModuleNode module =
465         parse("class Foo { void testMethod() { if (foo instanceof java.util.List) { println('hello') } } }", "Dummy.groovy");
466         BlockStatement statement = getCode(module, "testMethod");
467 
468         assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size());
469 
470         System.out.println(statement.getStatements());
471 
472         IfStatement ifStmt = (IfStatement) statement.getStatements().get(0);
473         BinaryExpression exp = (BinaryExpression) ifStmt.getBooleanExpression().getExpression();
474 
475         System.out.println("exp: " + exp);
476 
477         Expression rhs = exp.getRightExpression();
478         assertTrue("RHS should be a class expression", rhs instanceof ClassExpression);
479 
480         ClassExpression classExp = (ClassExpression) rhs;
481         assertEquals("java.util.List", classExp.getType());
482     }
483 
484     public void testMethodCallWithoutParensBug() throws Exception {
485         ModuleNode module = parse("class Foo { void testMethod() { println 3, 5 } }", "Dummy.groovy");
486         BlockStatement statement = getCode(module, "testMethod");
487 
488         assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size());
489 
490         System.out.println(statement.getStatements());
491     }
492 
493     public void testReturnMethodClosure() throws Exception {
494         ModuleNode module = parse("class Foo { void testMethod() { System.out.println\n}}", "Dummy.groovy");
495         BlockStatement statement = getCode(module, "testMethod");
496 
497         assertEquals("Statements size: " + statement.getStatements(), 1, statement.getStatements().size());
498 
499         System.out.println(statement.getStatements());
500     }
501 
502     public void testDionsTypo() throws Exception {
503         String script = "class Foo { void testMethod() { println ${foo}\n}}";
504         try {
505             ModuleNode module = parse(script, "Dummy.groovy");
506         } catch (Exception e) {
507             // todo problem of antlr thrown exception
508             //SyntaxException cause = e.getUnit().getSyntaxError(0);
509             //if( cause != null && cause instanceof ParserException) {
510                 return;
511             //}
512             //fail (script+" should fail with a ParserException: "+e.getMessage());
513         }
514         fail(script+" should fail because the { was unexpected after the dollar sign.");
515     }
516 
517     public void testMethodWithArrayTypeParam() throws Exception {
518         ModuleNode module = parse("class Foo { void main(String[] args) { println(args) } }", "Dummy.groovy");
519 
520         MethodNode method = getMethod(module, "main");
521 
522         System.out.println("Parameters: " + InvokerHelper.toString(method.getParameters()));
523     }
524 
525     private void ensureOutOfRange(String script) throws Exception {
526         try {
527             ModuleNode module = parse(script, "Dummy.groovy");
528         } catch (Exception e) {
529             // todo problem of antlr thrown exception
530             // SyntaxException cause = e.getUnit().getSyntaxError(0);
531             // if( cause != null && cause instanceof ParserException && cause.getMessage().indexOf("out of range") >= 0) {
532                 return;
533             //}
534             //fail (script+" should fail with a ParserException: "+e.getMessage());
535         }
536         fail(script+" should fail because the number is out of range.");
537     }
538 
539     private void ensureInRange(String script) throws Exception {
540         ModuleNode module = parse(script, "Dummy.groovy");
541     }
542 
543     public void testLiteralIntegerRange() throws Exception {
544         ensureInRange(   "def x =  2147483647I;");
545         ensureOutOfRange("def x =  2147483648I;");
546 
547         ensureInRange(   "def x = -2147483648I;");
548         ensureOutOfRange("def x = -2147483649I;");
549     }
550 
551     public void testLiteralLongRange() throws Exception {
552         ensureInRange(   "def x =  9223372036854775807L;");
553         ensureOutOfRange("def x =  9223372036854775808L;");
554 
555         ensureInRange(   "def x = -9223372036854775808L;");
556         ensureOutOfRange("def x = -9223372036854775809L;");
557     }
558 
559     public void testLiteralDoubleRange() throws Exception {
560         ensureInRange(   "def x =  1.7976931348623157E308D;");
561         ensureOutOfRange("def x =  1.7976931348623167E308D;");
562 
563         ensureInRange(   "def x = -1.7976931348623157E308D;");
564         ensureOutOfRange("def x = -1.7976931348623167E308D;");
565     }
566 
567     public void testLiteralFloatRange() throws Exception {
568         ensureInRange(   "def x =  3.4028235e+38f;");
569         ensureOutOfRange("def x =  3.4028236e+38f;");
570 
571         ensureInRange(   "def x = -3.4028235e+38f;");
572         ensureOutOfRange("def x = -3.4028236e+38f;");
573     }
574 
575     public void testLiteralIntegerBadSuffix() throws Exception {
576         try {
577             ModuleNode module = parse("def x = 2147483648J;", "Dummy.groovy");
578         } catch (Exception e) {
579             // todo problem of antlr thrown exception
580             //SyntaxException cause = e.getUnit().getSyntaxError(0);
581             //if (cause instanceof UnexpectedCharacterException) {
582                 return;
583             //}
584             //fail ("x = 2147483648J should fail with an UnexpectedCharacterException");
585         }
586         fail("x = 2147483648J, should fail because J is an invalid numeric literal suffix.");
587     }
588 
589     public void testLiteralBadExponent() throws Exception {
590         try {
591             ModuleNode module = parse("def x = 2.3e;", "Dummy.groovy");
592         } catch (Exception e) {
593             // todo problem of antlr thrown exception
594             //SyntaxException cause = e.getUnit().getSyntaxError(0);
595             //if (cause instanceof UnexpectedCharacterException) {
596                 return;
597             //}
598             //fail ("x = 2.3e should fail with an UnexpectedCharacterException");
599         }
600         fail("x = 2.3e, should fail because no exponent is specified.");
601     }
602 
603     public static Object mockHelperMethod() {
604         return "cheese";
605     }
606 
607     protected BlockStatement getCode(ModuleNode module, String name) {
608         MethodNode method = getMethod(module, name);
609 
610         BlockStatement statement = (BlockStatement) method.getCode();
611         assertNotNull(statement);
612         return statement;
613     }
614 
615     protected MethodNode getMethod(ModuleNode module, String name) {
616         assertEquals("class count", 1, module.getClasses().size());
617 
618         ClassNode node = (ClassNode) module.getClasses().get(0);
619 
620         assertNotNull(node);
621 
622         List methods = node.getDeclaredMethods(name);
623         assertTrue(methods.size() > 0);
624         return (MethodNode) methods.get(0);
625     }
626 }