    1   /***
    2    *
    3    * Copyright 2005 Jeremy Rayner
    4    *
    5    * Licensed under the Apache License, Version 2.0 (the "License");
    6    * you may not use this file except in compliance with the License.
    7    * You may obtain a copy of the License at
    8    *
    9    * http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   **/
    18  package org.codehaus.groovy.antlr.treewalker;
    19
    20  import groovy.util.GroovyTestCase;
    21
    22  import java.io.ByteArrayOutputStream;
    23  import java.io.PrintStream;
    24  import java.io.StringReader;
    25
    26  import org.codehaus.groovy.antlr.AntlrASTProcessor;
    27  import org.codehaus.groovy.antlr.SourceBuffer;
    28  import org.codehaus.groovy.antlr.UnicodeEscapingReader;
    29  import org.codehaus.groovy.antlr.parser.GroovyLexer;
    30  import org.codehaus.groovy.antlr.parser.GroovyRecognizer;
    31
    32  import antlr.collections.AST;
    33
    34  /***
    35   * Testcases for the antlr AST visitor that prints groovy source code.
    36   *
    37   * @author <a href="mailto:groovy@ross-rayner.com">Jeremy Rayner</a>
    38   * @version $Revision: 4653 $
    39   */
    40  public class SourcePrinterTest extends GroovyTestCase {
    41
    42  	public void testAbstract() throws Exception {
    43  		assertEquals("public abstract class Foo {}", pretty("public abstract class Foo{}"));
    44  	}
    45
    46      public void testAnnotation() throws Exception{
    47          assertEquals("@Crimson foo", pretty("@Crimson foo"));
    48          assertEquals("@Override int hashCode() {return 0}", pretty("@Override int hashCode() {return 0}"));
    49      }
    50
    51      public void testAnnotations() throws Exception{
    52      	assertEquals("@Important @Blue package foo.bar",pretty("@Important @Blue package foo.bar"));
    53      }
    54
    55      public void testAnnotationArrayInit() throws Exception{
    56      	// obsolete java syntax
    57      }
    58
    59      public void testAnnotationDef() throws Exception{
    60      	// todo - 17 July 2006 - test fine, however this parses but causes error in AntlrParserPlugin
    61          assertEquals("public @interface Foo{}", pretty("public @interface Foo{}"));
    62      }
    63
    64      public void testAnnotationFieldDef() throws Exception{
    65      	assertEquals("public @interface Foo{int bar() default 123}", pretty("public @interface Foo{int bar() default 123}"));
    66      }
    67
    68      public void testAnnotationMemberValuePair() throws Exception{
    69      	assertEquals("@Prime(value = 17) int foo",pretty("@Prime(value=17) int foo"));
    70      	assertEquals("@Blue(v = 3, v = 5) int bar",pretty("@Blue(v = 3, v = 5) int bar"));
    71      }
    72
    73      public void testArrayDeclarator() throws Exception {
    74      	assertEquals("int[] primes = new int[5]", pretty("int[] primes = new int[5]"));
    75      }
    76
    77      public void testAssign() throws Exception {
    78          assertEquals("a = 12", pretty("a=12"));
    79      }
    80
    81      public void testBand() throws Exception {
    82      	assertEquals("def x = 1 & 2", pretty("def x=1&2"));
    83      }
    84
    85      public void testBandAssign() throws Exception {
    86      	assertEquals("x &= 2", pretty("x&=2"));
    87      }
    88
    89      public void testBnot() throws Exception {
    90      	assertEquals("def z = ~123", pretty("def z = ~123"));
    91      }
    92
    93      public void testBor() throws Exception {
    94      	assertEquals("def y = 1 | 2", pretty("def y = 1 | 2"));
    95      }
    96
    97      public void testBorAssign() throws Exception {
    98      	assertEquals("y |= 2", pretty("y|=2"));
    99      }
    100
    101     public void testBsr() throws Exception {
    102     	// unsigned right shift
    103     	assertEquals("def q = 1 >>> 2", pretty("def q = 1 >>> 2"));
    104     }
    105
    106     public void testBsrAssign() throws Exception {
    107     	assertEquals("y >>>= 2", pretty("y>>>=2"));
    108     }
    109
    110     public void testBxor() throws Exception {
    111     	assertEquals("def y = true ^ false", pretty("def y = true ^ false"));
    112     }
    113
    114     public void testBxorAssign() throws Exception {
    115     	assertEquals("y ^= false", pretty("y^=false"));
    116     }
    117
    118     public void testCaseGroup() throws Exception {
    119         assertEquals("switch (foo) {case bar:x = 1}", pretty("switch(foo){case bar:x=1}"));
    120     }
    121
    122     public void testClassDef() throws Exception {
    123         assertEquals("class Foo {def bar}", pretty("class Foo{def bar}"));
    124     }
    125
    126     public void testClosedBlock() throws Exception{
    127         assertEquals("[1, 2, 3].each {println it}", pretty("[1,2,3].each{println it}"));
    128         assertEquals("def x = foo.bar(mooky){ x, y -> wibble(y, x)}", pretty("def x = foo.bar(mooky) {x,y-> wibble(y,x)}"));
    129         // todo: above is not quite the spacing I would expect, but good enough for now...
    130     }
    131
    132     public void testCompareTo() throws Exception{
    133     	assertEquals("1 <=> 2", pretty("1<=>2"));
    134     }
    135
    136     public void testCtorCall() throws Exception{
    137     	assertEquals("class Foo {Foo(int x) {this()}}",pretty("class Foo{Foo(int x) {this()}}"));
    138     	assertEquals("class Foo {Foo( x) {this()}}",pretty("class Foo{Foo(x) {this()}}"));
    139         // todo: above is not quite the spacing I would expect, but good enough for now...
    140     }
    141
    142     public void testCtorIdent() throws Exception {
    143         assertEquals("class Foo {private Foo() {}}", pretty("class Foo {private Foo() {}}"));
    144     }
    145
    146     public void testDec() throws Exception {
    147     	assertEquals("--b", pretty("--b"));
    148     }
    149
    150     public void testDiv() throws Exception {
    151     	assertEquals("1 / 2", pretty("1/2"));
    152     }
    153
    154     public void testDivAssign() throws Exception {
    155     	assertEquals("x /= 2", pretty("x/=2"));
    156     }
    157
    158     public void testDot() throws Exception {
    159     	assertEquals("java.util.Date d = new java.util.Date()", pretty("java.util.Date d = new java.util.Date()"));
    160     	assertEquals("class Foo extends java.util.Date {}", pretty("class Foo extends java.util.Date {}"));
    161     	assertEquals("foo.bar.mooky()", pretty("foo.bar.mooky()"));
    162     	assertEquals("package foo.bar", pretty("package foo.bar"));
    163     	assertEquals("import java.util.Date", pretty("import java.util.Date"));
    164     	assertEquals("import java.io.*", pretty("import java.io.*"));
    165     	assertEquals("@foo.Bar mooky", pretty("@foo.Bar mooky"));
    166     	assertEquals("def foo() throws bar.MookyException{}", pretty("def foo() throws bar.MookyException{}"));
    167     	assertEquals("def x = \"${foo.bar}\"", pretty("def x = \"${foo.bar}\""));
    168     }
    169
    170     public void testDynamicMember() throws Exception{
    171     	assertEquals("foo.(bar)", pretty("foo.(bar)"));
    172     	assertEquals("foo.\"${bar}\"", pretty("foo.\"${bar}\""));
    173     }
    174
    175     public void testElist() throws Exception {
    176     	assertEquals("println 2 + 2", pretty("println 2 + 2"));
    177     	assertEquals("for (i = 0, j = 2 ; i < 10 ; i++, j--){print i}", pretty("for (i = 0,j = 2;i < 10; i++, j--) {print i}"));
    178     	assertEquals("foo()", pretty("foo()")); // empty ELIST
    179     	assertEquals("foo(bar, mooky)", pretty("foo( bar , mooky )"));
    180     }
    181
    182     public void testEnumConstantDef() throws Exception {
    183     	assertEquals("enum Coin {PENNY(1), DIME(10), QUARTER(25)}", pretty("enum Coin {PENNY(1), DIME(10), QUARTER(25)}"));
    184     }
    185
    186     public void testEnumDef() throws Exception {
    187     	assertEquals("enum Season {WINTER, SPRING, SUMMER, AUTUMN}", pretty("enum Season{WINTER,SPRING,SUMMER,AUTUMN}"));
    188     	//todo: more strange spacing in following line
    189     	assertEquals("enum Operation {ADDITION{double eval( x,  y) {return x + y}}}",pretty("enum Operation {ADDITION {double eval(x,y) {return x + y}}}"));
    190     }
    191
    192     public void testEqual() throws Exception {
    193         assertEquals("a == b", pretty("a==b"));
    194     }
    195
    196     public void testEsc_FAILS() throws Exception { if (notYetImplemented()) return;
    197     	// dquote-tab-dquote
    198     	assertEquals("println \"//\"\t//\"\"", pretty("println \"//\"\t//\"\""));
    199     }
    200
    201     public void testExponent() throws Exception {
    202     	assertEquals("println 1.2e-10", pretty("println 1.2e-10"));
    203     }
    204
    205     public void testExpr_FAILS() throws Exception { if (notYetImplemented()) return;
    206     	assertEquals("System.out.println(x)", pretty("System.out.println(x)"));
    207     	assertEquals("return f", pretty("return f"));
    208         assertEquals("foo(bar);mooky(bar)", pretty("foo(bar);mooky(bar)"));
    209     }
    210
    211     public void testExtendsClause() throws Exception {
    212         assertEquals("class Foo extends Bar {}", pretty("class Foo extends Bar {}"));
    213         assertEquals("interface Wibble extends Mooky{}", pretty("interface Wibble extends Mooky {}"));
    214         //todo spacing is odd, c.f. last space in class vs interface above
    215     }
    216
    217     public void testFinal() throws Exception {
    218     	assertEquals("public final int getX() {return 0}", pretty("public final int getX() {return 0}"));
    219     }
    220     public void testForCondition() throws Exception {
    221     	assertEquals("for (i = 0 ; i < 10 ; i++){println i}", pretty("for (i=0;i<10;i++) {println i}"));
    222     }
    223
    224     // testForInit() covered by testForCondition()
    225
    226     public void testForInIterable() throws Exception {
    227         assertEquals("for (i in [1, 2]) {}", pretty("for (i in [1,2]) {}"));
    228     }
    229
    230     // testForIterator() covered by testForCondition()
    231
    232     public void testGe() throws Exception {
    233     	assertEquals("if (60 >= 70) {}", pretty("if (60>=70) {}"));
    234     }
    235
    236     public void testGt() throws Exception {
    237         assertEquals("if (2070 > 354) {}", pretty("if (2070 > 354) {}"));
    238     }
    239
    240     public void testHexDigit() throws Exception {
    241         assertEquals("def bar = 0xCaFe", pretty("def bar = 0xCaFe"));
    242     }
    243     public void testHexDigitInUnicodeEscape_FAILS() throws Exception { if (notYetImplemented()) return;
    244       assertEquals("def foo = '//ubabe'", pretty("def foo = '//ubabe'"));
    245     }
    246
    247     public void testIdent() throws Exception {
    248     	// used _everywhere_ , lets assume that the other specific
    249     	// testcases include enough ident usage for now.
    250         assertEquals("foo.bar", pretty("foo.bar"));
    251     }
    252
    253     public void testImplementsClause() throws Exception {
    254         assertEquals("class Foo implements Bar {}", pretty("class Foo implements Bar {}"));
    255     }
    256
    257     public void testImplicitParameters() throws Exception {
    258     	assertEquals("[1, 2, 3].each {println it}", pretty("[1,2,3].each{println it}"));
    259     }
    260
    261     public void testImport() throws Exception {
    262         assertEquals("import foo.bar.Wibble", pretty("import foo.bar.Wibble"));
    263     }
    264
    265     public void testInc() throws Exception {
    266     	assertEquals("++x",pretty("++x"));
    267     }
    268
    269     public void testIndexOp() throws Exception {
    270         assertEquals("foo.bar()[fred.wilma()]", pretty("foo.bar()[fred.wilma()]"));
    271     }
    272
    273     public void testInterfaceDef() throws Exception {
    274     	//todo, the spacing here is... unusual
    275     	assertEquals("interface Foo{void blah() }", pretty("interface Foo{void blah()}"));
    276     }
    277
    278     public void testInstanceInit() throws Exception {
    279     	assertEquals("class Foo {{x = 1}}", pretty("class Foo {{x=1}}"));
    280     }
    281
    282     public void testLabeledArg() throws Exception {
    283         assertEquals("myMethod(argOne:123, argTwo:123)", pretty("myMethod(argOne:123,argTwo:123)"));
    284         assertEquals("myMap = [keyOne:123, keyTwo:234]", pretty("myMap = [keyOne:123,keyTwo:234]"));
    285     }
    286
    287     public void testLabeledStat() throws Exception {
    288      	assertEquals("foo:x = 1", pretty("foo:x = 1"));
    289     }
    290
    291     public void testLand() throws Exception {
    292         assertEquals("true && false", pretty("true && false"));
    293     }
    294
    295     public void testLe() throws Exception {
    296     	assertEquals("if (60 <= 70) {}", pretty("if (60<=70) {}"));
    297     }
    298
    299     public void testListConstructor() throws Exception {
    300         assertEquals("[a, b]", pretty("[a,b]"));
    301     }
    302
    303     public void testLiteralAny() throws Exception {
    304         assertEquals("any x = 2", pretty("any x = 2"));
    305     }
    306
    307     public void testLiteralAs() throws Exception {
    308         assertEquals("import java.util.Date as MyDate", pretty("import java.util.Date as MyDate"));
    309         // todo suspicious spacing in the following assertion
    310         assertEquals("x = 12 as Long ", pretty("x = 12 as Long"));
    311     }
    312
    313     public void testLiteralAssert() throws Exception {
    314         assertEquals("assert a == true", pretty("assert a== true"));
    315         assertEquals("assert b == true : 99", pretty("assert b==true:99"));
    316         // todo is ',' deprecated now?
    317         //assertEquals("assert b == true , 99", pretty("assert b==true,99"));
    318     }
    319
    320     public void testLiteralBoolean() throws Exception {
    321         assertEquals("boolean b = true", pretty("boolean b =true"));
    322     }
    323
    324     public void testLiteralBreak() throws Exception {
    325     	assertEquals("for (i in 1..100) {break }", pretty("for (i in 1..100) {break}"));
    326         assertEquals("switch (foo) {default:break }", pretty("switch(foo){default:break}"));
    327         assertEquals("def myMethod() {break }", pretty("def myMethod(){break}"));
    328     	assertEquals("for (i in 1..100) {break 2}", pretty("for (i in 1..100) {break 2}"));
    329     	//todo should the colon be postfixed to the label?
    330     	assertEquals("for (i in 1..100) {break label1:}", pretty("for (i in 1..100) {break label1:}"));
    331     }
    332
    333     public void testLiteralByte() throws Exception {
    334         assertEquals("byte b = 1", pretty("byte b=1"));
    335     }
    336
    337     public void testLiteralCase() throws Exception {
    338         assertEquals("switch (foo) {case 1:x = 3}", pretty("switch(foo){case 1:x=3}"));
    339     }
    340
    341     public void testLiteralCatch() throws Exception {
    342         assertEquals("try {} catch (Exception e) {}", pretty("try {} catch (Exception e) {}"));
    343         assertEquals("try {} catch (Exception e1) {} catch (Exception2 e2) {}", pretty("try {} catch (Exception e1) {} catch (Exception2 e2) {}"));
    344     }
    345
    346     public void testLiteralChar() throws Exception {
    347         assertEquals("char c = \"a\"", pretty("char c = \"a\""));
    348     }
    349
    350     public void testLiteralClass() throws Exception {
    351     	assertEquals("public class Foo {int bar}", pretty("public class Foo{int bar}"));
    352     }
    353
    354     public void testLiteralContinue() throws Exception {
    355     	assertEquals("for (i in 1..100) {continue }", pretty("for (i in 1..100) {continue}"));
    356     	assertEquals("for (i in 1..100) {continue 2}", pretty("for (i in 1..100) {continue 2}"));
    357     	//todo should the colon be postfixed to the label?
    358     	assertEquals("for (i in 1..100) {continue label1:}", pretty("for (i in 1..100) {continue label1:}"));
    359     	assertEquals("[1, 2, 3].each {continue }", pretty("[1,2,3].each{continue}"));
    360     }
    361
    362     public void testLiteralDef() throws Exception {
    363     	assertEquals("def x = 123", pretty("def x=123"));
    364     	assertEquals("def myMethod() {return 0}", pretty("def myMethod(){return 0}"));
    365     	// note: def not needed in parameter declarations, but it is valid
    366     	//todo: is it ok to strip out 'def' from parameter declarations?
    367     	assertEquals("def foo( bar) {}", pretty("def foo(def bar){}"));
    368     }
    369
    370     public void testLiteralDefault() throws Exception {
    371         assertEquals("switch (foo) {default:x = 2}", pretty("switch(foo){default:x=2}"));
    372     	assertEquals("public @interface Foo{int bar() default 123}", pretty("public @interface Foo{int bar() default 123}"));
    373     }
    374
    375     public void testLiteralDouble() throws Exception {
    376     	assertEquals("double d = 1.0", pretty("double d = 1.0"));
    377     }
    378
    379     public void testLiteralElse() throws Exception {
    380     	assertEquals("if (false) {a = 1} else {a = 2}", pretty("if (false) {a=1} else {a=2}"));
    381     }
    382
    383     public void testLiteralEnum() throws Exception {
    384     	assertEquals("enum Season {WINTER, SPRING, SUMMER, AUTUMN}", pretty("enum Season{WINTER,SPRING,SUMMER,AUTUMN}"));
    385     }
    386
    387     public void testLiteralExtends() throws Exception {
    388     	assertEquals("class Foo extends java.util.Date {}", pretty("class Foo extends java.util.Date {}"));
    389         assertEquals("class Foo extends Bar {}", pretty("class Foo extends Bar {}"));
    390         assertEquals("interface Wibble extends Mooky{}", pretty("interface Wibble extends Mooky {}"));
    391         //todo spacing is odd, c.f. last space in class vs interface above
    392     	assertEquals("public boolean process(Set<? extends TypeElement> annotations) {println annotations}", pretty("public boolean process(Set<? extends TypeElement> annotations) {println annotations}"));
    393     }
    394
    395     public void testLiteralFalse() throws Exception {
    396         assertEquals("if (false) {}", pretty("if (false) {}"));
    397     }
    398
    399     public void testLiteralFinally() throws Exception {
    400         assertEquals("try {}finally {}", pretty("try {}finally {}"));
    401     }
    402
    403     public void testLiteralFloat() throws Exception {
    404         assertEquals("float x", pretty("float x"));
    405     }
    406
    407     public void testLiteralFor() throws Exception {
    408         assertEquals("for (i in [1, 2, 3]) {}", pretty("for (i in [1,2,3]) {}"));
    409         // check non-braced single statement
    410         assertEquals("for (i in 1..100) rotateAntiClockwise()", pretty("for (i in 1..100) rotateAntiClockwise()"));
    411     }
    412
    413     public void testLiteralIf() throws Exception {
    414         assertEquals("if (a == b) return false", pretty("if (a==b) return false"));
    415         assertEquals("if (a == b) {}", pretty("if (a==b) {}"));
    416     }
    417
    418     public void testLiteralImplements() throws Exception {
    419         assertEquals("class Foo implements Bar {}", pretty("class Foo implements Bar {}"));
    420         //todo the following is legal Java, but pretty strange...?
    421         assertEquals("enum EarthSeason implements Season {SPRING}", pretty("enum EarthSeason implements Season{SPRING}"));
    422     }
    423
    424     public void testLiteralImport() throws Exception {
    425     	assertEquals("import foo.Bar", pretty("import foo.Bar"));
    426     	assertEquals("import mooky.*", pretty("import mooky.*"));
    427     }
    428
    429     public void testLiteralIn() throws Exception {
    430     	assertEquals("for (i in 1..10) {}", pretty("for (i in 1..10) {}"));
    431     	assertEquals("if (i in myList) {}", pretty("if (i in myList) {}"));
    432     }
    433
    434     public void testLiteralInstanceOf() throws Exception {
    435         assertEquals("if (a instanceof String) {}", pretty("if (a instanceof String) {}"));
    436     }
    437     public void testLiteralInt() throws Exception {
    438         assertEquals("int a", pretty("int a"));
    439     }
    440
    441     public void testLiteralInterface() throws Exception {
    442     	assertEquals("interface Foo{}", pretty("interface Foo{}"));
    443     }
    444     public void testLiteralLong() throws Exception {
    445         assertEquals("long a = 1", pretty("long a = 1"));
    446     }
    447     public void testLiteralNative() throws Exception {
    448         assertEquals("public class R {public native void seek(long pos) }", pretty("public class R{public native void seek(long pos)}"));
    449         assertEquals("native foo() ", pretty("native foo()"));
    450     }
    451     public void testLiteralNew() throws Exception {
    452         assertEquals("new Foo()", pretty("new Foo()"));
    453         assertEquals("def x = new int[5]", pretty("def x = new int[5]"));
    454     }
    455
    456     public void testLiteralNull() throws Exception {
    457         assertEquals("def foo = null", pretty("def foo=null"));
    458     }
    459
    460     public void testLiteralPackage() throws Exception {
    461     	assertEquals("package foo.bar", pretty("package foo.bar"));
    462     }
    463     public void testLiteralPrivate() throws Exception{
    464         assertEquals("private bar", pretty("private bar"));
    465     }
    466
    467     public void testLiteralProtected() throws Exception{
    468         assertEquals("protected mooky", pretty("protected mooky"));
    469     }
    470
    471     public void testLiteralPublic() throws Exception{
    472         assertEquals("public foo", pretty("public foo"));
    473     }
    474
    475     public void testLiteralReturn() throws Exception {
    476         assertEquals("def foo() {return false}", pretty("def  foo() { return false }"));
    477         assertEquals("void bar() {return }", pretty("void bar() {return}"));
    478     }
    479
    480     public void testLiteralShort() throws Exception {
    481         assertEquals("short a = 1", pretty("short a = 1"));
    482     }
    483
    484     public void testLiteralStatic() throws Exception {
    485         assertEquals("static void foo() {}", pretty("static void foo() {}"));
    486         //classes, interfaces, class/instance vars and methods
    487         assertEquals("static int bar = 1", pretty("static int bar = 1"));
    488         //todo: this should parse... assertEquals("private static <T> void foo(List<T> list){}", pretty("private static <T> void foo(List<T> list){}"));
    489         assertEquals("class Foo {static {bar = 1}}", pretty("class Foo{static {bar=1}}"));
    490     }
    491
    492     public void testLiteralSuper() throws Exception {
    493     	assertEquals("class Foo {public Foo() {super()}}", pretty("class Foo{public Foo(){super()}}"));
    494     	// todo will 'super' be allowed in non-parentheses method call styles?
    495     	assertEquals("class Bar {public Bar() {super 99}}", pretty("class Bar{public Bar(){super 99}}"));
    496     	assertEquals("class Bar {public Bar() {super(1, 2, 3)}}", pretty("class Bar{public Bar(){super(1,2,3)}}"));
    497     	assertEquals("println(super.toString())", pretty("println(super.toString())"));
    498     	//todo: doesn't parse correctly...   assertEquals("class Foo<T super C> {T t}",pretty("class Foo<T super C> {T t}"));
    499     }
    500     public void testLiteralSwitch() throws Exception {
    501         assertEquals("switch (foo) {case bar:x = 2}", pretty("switch(foo){case bar:x=2}"));
    502     }
    503
    504     public void testLiteralSynchronized() throws Exception {
    505     	assertEquals("synchronized foo() {}", pretty("synchronized foo(){}"));
    506     	assertEquals("synchronized (t) {doStuff(t)}", pretty("synchronized (t) {doStuff(t)}"));
    507     }
    508
    509     public void testLiteralThis() throws Exception {
    510     	assertEquals("this",pretty("this"));
    511     	assertEquals("this 2",pretty("this 2"));
    512     	assertEquals("this()",pretty("this()"));
    513     	assertEquals("this(1, 2, 3)",pretty("this(1,2,3)"));
    514         assertEquals("this.x = this.y", pretty("this.x=this.y"));
    515     }
    516
    517     public void testLiteralThreadsafe() throws Exception {
    518     	assertEquals("threadsafe foo() {}", pretty("threadsafe foo() {}"));
    519     }
    520
    521     public void testLiteralThrow() throws Exception {
    522         assertEquals("def foo() {if (false) throw new RuntimeException()}", pretty("def foo() {if (false) throw new RuntimeException()}"));
    523     }
    524     public void testLiteralThrows() throws Exception {
    525     	//todo AntlrParserPlugin: Unexpected node type: '.' found when expecting type: an identifier
    526     	assertEquals("def foo() throws java.io.IOException{}", pretty("def foo() throws java.io.IOException{}"));
    527     }
    528     public void testLiteralTransient() throws Exception {
    529     	assertEquals("transient bar", pretty("transient bar"));
    530     }
    531
    532     public void testLiteralTrue() throws Exception {
    533         assertEquals("foo = true", pretty("foo = true"));
    534     }
    535
    536     public void testLiteralTry() throws Exception {
    537         assertEquals("try {} catch (Exception e) {}", pretty("try {} catch (Exception e) {}"));
    538     }
    539
    540     public void testLiteralVoid() throws Exception {
    541         assertEquals("void foo() {}", pretty("void foo(){}"));
    542     }
    543     public void testLiteralVolatile() throws Exception {
    544     	assertEquals("volatile mooky", pretty("volatile mooky"));
    545     }
    546
    547     public void testLiteralWhile() throws Exception {
    548         assertEquals("while (true) {}", pretty("while(true){}"));
    549     }
    550
    551     public void testLiteralWith() throws Exception {
    552         assertEquals("with (myObject) {x = 1}", pretty("with(myObject) {x = 1}"));
    553     }
    554     public void testLnot() throws Exception {
    555         assertEquals("if (!isRaining) {}", pretty("if (!isRaining) {}"));
    556     }
    557
    558     public void testLor() throws Exception {
    559         assertEquals("true || false", pretty("true || false"));
    560     }
    561     public void testLparen_FAILS() throws Exception { if (notYetImplemented()) return;
    562     	assertEquals("for (i in (history.size() - 1)..0) {}", pretty("for (i in (history.size() - 1)..0) {}"));
    563     }
    564     public void testLt() throws Exception {
    565         assertEquals("if (3.4f < 12f) {}", pretty("if (3.4f < 12f) {}"));
    566     }
    567     public void testMapConstructor() throws Exception{
    568         assertEquals("Map foo = [:]", pretty("Map foo = [:]"));
    569         assertEquals("[a:1, b:2]", pretty("[a:1,b:2]"));
    570     }
    571
    572     public void testMemberPointer() throws Exception {
    573         assertEquals("def x = foo.&bar()", pretty("def x=foo.&bar()"));
    574     }
    575     public void testMethodCall() throws Exception {
    576         assertEquals("foo(bar)", pretty("foo(bar)"));
    577         assertEquals("[1, 2, 3].each {println it}", pretty("[1,2,3].each{println it}"));
    578         assertEquals("foo(bar){mooky()}", pretty("foo(bar){mooky()}"));
    579     }
    580
    581     public void testMethodDef() throws Exception{
    582         assertEquals("def foo(int bar, boolean boo) {}", pretty("def foo(int bar,boolean boo) {}"));
    583     }
    584
    585     public void testMinus() throws Exception {
    586         assertEquals("def bar = 4 - foo", pretty("def bar=4-foo"));
    587     }
    588
    589     public void testMinusAssign() throws Exception {
    590         assertEquals("x -= 23", pretty("x -= 23"));
    591     }
    592
    593     public void testMod() throws Exception {
    594         assertEquals("x = 4 % 3", pretty("x = 4 % 3"));
    595     }
    596
    597     public void testModifiers() throws Exception {
    598     	assertEquals("public static transient final native threadsafe synchronized volatile strictfp foo() {}", pretty("public static transient final native threadsafe synchronized volatile strictfp foo() {}"));
    599     }
    600
    601     public void testModAssign() throws Exception {
    602         assertEquals("x %= 23", pretty("x %= 23"));
    603     }
    604
    605     public void testNotEqual() throws Exception {
    606         assertEquals("a != b", pretty("a!=b"));
    607     }
    608
    609     public void testNumBigDecimal() throws Exception {
    610     	assertEquals("a = 9.8g", pretty("a  =9.8g"));
    611     }
    612     public void testNumBigInt() throws Exception {
    613     	assertEquals("a = 12g", pretty("a=   12g"));
    614     }
    615
    616     public void testNumDouble() throws Exception {
    617         assertEquals("b = 34.4d", pretty("b=34.4d"));
    618         assertEquals("b = 34.4D", pretty("b=34.4D"));
    619     }
    620     public void testNumFloat() throws Exception {
    621         assertEquals("b = 34.4f", pretty("b=34.4f"));
    622         assertEquals("b = 34.4F", pretty("b=34.4F"));
    623     }
    624     public void testNumInt() throws Exception {
    625         assertEquals("a = 12", pretty("a=12"));
    626     }
    627
    628     public void testNumLong() throws Exception {
    629     	assertEquals("a = 12l", pretty("a=12l"));
    630     }
    631     public void testObjblock() throws Exception {
    632         assertEquals("class Foo {def bar}", pretty("class Foo {def bar}"));
    633     }
    634     public void testOptionalDot() throws Exception {
    635         assertEquals("foo = england.london.kings?.head", pretty("foo = england.london.kings?.head"));
    636     }
    637
    638     public void testPackageDef() throws Exception {
    639         assertEquals("package foo.bar", pretty("package foo.bar"));
    640     }
    641
    642     public void testParameterDef() throws Exception {
    643     	//todo spacing slightly suspect with "foo( bar)"
    644     	assertEquals("def foo( bar) {}", pretty("def foo(bar){}"));
    645         assertEquals("def foo(String bar, String mooky) {}", pretty("def foo(String bar, String mooky){}"));
    646         assertEquals("def c = { x -> println x}", pretty("def c = {x->println x}"));
    647         assertEquals("def c = { x, y -> println(x + y)}", pretty("def c={x,y->println(x+y)}"));
    648         assertEquals("def c = {int x,int y -> println(x + y)}", pretty("def c={int x, int y->println(x+y)}"));
    649     }
    650
    651     public void testParameters() throws Exception {
    652         assertEquals("def foo(String bar, String mooky) {}", pretty("def foo(String bar, String mooky){}"));
    653     }
    654     public void testPlus() throws Exception {
    655         assertEquals("a + b", pretty("a+b"));
    656     }
    657
    658     public void testPlusAssign() throws Exception {
    659         assertEquals("x += 23", pretty("x += 23"));
    660     }
    661
    662     public void testPostDec() throws Exception {
    663     	assertEquals("a--", pretty("a--"));
    664     }
    665     public void testPostInc() throws Exception {
    666     	assertEquals("a++", pretty("a++"));
    667     }
    668     public void testQuestion() throws Exception {
    669         assertEquals("foo == bar?10:20", pretty("foo==bar?10:20"));
    670     	assertEquals("public boolean process(Set<? extends B> a) {println a}", pretty("public boolean process(Set<? extends B> a) {println a}"));
    671     	assertEquals("public boolean process(Set<? extends B, ? super C> a) {println a}", pretty("public boolean process(Set<? extends B, ? super C> a) {println a}"));
    672     }
    673     public void testRangeExclusive() throws Exception {
    674         assertEquals("foo[45..<89]", pretty("foo[45 ..< 89]"));
    675     }
    676     public void testRangeInclusive() throws Exception {
    677         assertEquals("foo[bar..12]", pretty("foo[bar .. 12]"));
    678     }
    679     public void testRegexpLiteral() throws Exception {
    680     	assertEquals("println", pretty("println //")); // empty regexp_literal should be treated as single line comment
    681     }
    682
    683     public void testRegexpLiteral_FAILS() throws Exception { if (notYetImplemented()) return;
    684 		//todo: these fail because regexp_literals are converted into string_literals on the antlr AST
    685 		assertEquals("def x = /./", pretty("def x = /./"));
    686 		assertEquals("def z = /blah//s/", pretty("def z = /blah//s/")); // actually: def z = /blah\s/
    687     }
    688
    689     public void testRegexFind() throws Exception {
    690     	assertEquals("def m = foo =~ \"bar\"", pretty("def m = foo =~ \"bar\""));
    691     	assertEquals("if (foo =~ \"bar\") {}", pretty("if (foo=~\"bar\"){}"));
    692     }
    693
    694     public void testRegexMatch() throws Exception {
    695     	assertEquals("if (foo ==~ \"bar\") {}", pretty("if (foo==~\"bar\"){}"));
    696     }
    697
    698     public void testScopeEscape() throws Exception {
    699     	// todo - 31 July + 14 Dec 2006 - test fine, however this parses but causes error in AntlrParserPlugin
    700     	assertEquals("println([$x, x, y])", pretty("println([$x, x, y])"));
    701     }
    702
    703     public void testSelectSlot() throws Exception {
    704     	assertEquals("def x = foo.@bar", pretty("def x = foo . @ bar"));
    705     }
    706
    707     public void testSl() throws Exception {
    708     	assertEquals("foo << 123", pretty("foo << 123"));
    709     }
    710
    711     public void testSlAssign() throws Exception {
    712     	assertEquals("foo <<= 123", pretty("foo <<= 123")); // does this operator make any sense?
    713     }
    714
    715     public void testSlist() throws Exception {
    716     	assertEquals("class Foo {private Foo() {println bar}}",pretty("class Foo {private Foo() {println bar}}"));
    717     	assertEquals("if (true) {foo}", pretty("if (true) {foo}"));
    718     	assertEquals("def x = foo.{bar}", pretty("def x = foo.{bar}")); // todo - inline open block is great, but it doesn't work as one would expect (yet). (c.f. with)
    719     	assertEquals("def foo() {l:{x = 2}}", pretty("def foo(){l:{x=2}}")); // slist inside a method body (needed label to distinguish from a closure)
    720     	assertEquals("switch (f) {case 1:break }", pretty("switch(f){case 1:break}")); // slist inside each case body...
    721     }
    722
    723     public void testSpreadArg() throws Exception {
    724     	assertEquals("myList {*name}", pretty("myList{*name}"));
    725         assertEquals("\"foo$*bar\"", pretty("\"foo$*bar\"")); // this doesn't work beyond parser (AntlrParserPlugin)
    726         assertEquals("\"foo${*bar}\"", pretty("\"foo${*bar}\"")); // this doesn't work beyond parser (AntlrParserPlugin)
    727         assertEquals("f(*[a, b, c])", pretty("f(*[a,b,c])"));
    728         assertEquals("f(*null)", pretty("f(*null)")); // equiv to f()
    729     }
    730     public void testSpreadMapArg() throws Exception {
    731     	assertEquals("f(*:myMap)", pretty("f(*:myMap)"));
    732     }
    733     public void testSr() throws Exception {
    734     	assertEquals("foo >> 123", pretty("foo >> 123"));
    735     }
    736
    737     public void testSrAssign() throws Exception {
    738     	assertEquals("foo >>= 123", pretty("foo >>= 123")); // does this operator make any sense?
    739     }
    740
    741     public void testStar() throws Exception {
    742         assertEquals("import foo.*", pretty("import foo.*"));
    743         assertEquals("a*b", pretty("a*b"));
    744     }
    745
    746     public void testStarAssign() throws Exception {
    747     	assertEquals("foo *= 123", pretty("foo *= 123"));
    748     }
    749
    750     public void testStarStar() throws Exception {
    751         assertEquals("def square = +5**2", pretty("def square=+5**2"));
    752         assertEquals("def cube = 5**3", pretty("def cube = 5**3"));
    753     }
    754
    755     public void testStarStarAssign() throws Exception {
    756     	assertEquals("cubeMe **= 3", pretty("cubeMe **= 3"));
    757     }
    758
    759     public void testStaticImport() throws Exception {
    760     	assertEquals("import static foo.Bar.mooky", pretty("import static foo.Bar.mooky"));
    761     	assertEquals("import static foo.Bar.*", pretty("import static foo.Bar.*"));
    762     }
    763
    764     public void testStaticInit() throws Exception {
    765     	assertEquals("class Foo {static {println(1 + 1)}}", pretty("class Foo{static{println(1+1)}}"));
    766     }
    767
    768     public void testStrictFp() throws Exception {
    769     	assertEquals("private strictfp flibble = 1.2", pretty("private strictfp flibble = 1.2"));
    770     }
    771
    772     public void testStringConstructor() throws Exception{
    773         assertEquals("def x = \"foo$bar\"", pretty("def x=\"foo$bar\""));
    774         assertEquals("def y = \"foo${mooky}\"", pretty("def y = \"foo${mooky}\""));
    775     }
    776
    777     public void testStringLiteral_FAILS() throws Exception{ if (notYetImplemented()) return;
    778         assertEquals("\"mooky\"", pretty("\"mooky\""));
    779         assertEquals("'mooky'", pretty("'mooky'"));
    780     	assertEquals("def x = '''can go over newline'''", pretty("def x = '''can go over newline'''"));
    781     	assertEquals("def x = \"\"\"can go over newline\"\"\"", pretty("def x = \"\"\"can go over newline\"\"\""));
    782     	//todo test newlines inside strings somehow...
    783     }
    784
    785     public void testSuperCtorCall() throws Exception{
    786     	assertEquals("class Foo {Foo(int x) {super(12, 3)}}",pretty("class Foo{Foo(int x) {super(12, 3)}}"));
    787     	assertEquals("class Foo {Foo( x) {super()}}",pretty("class Foo{Foo(x) {super()}}"));
    788         // todo: above is not quite the spacing I would expect, but good enough for now...
    789     	// todo not yet implemented in parser: assertEquals("(new Outer()).super()", pretty("(new Outer()).super()"));
    790     }
    791
    792     public void testType() throws Exception {
    793     	assertEquals("def bar", pretty("def bar"));
    794         assertEquals("public bar", pretty("public bar"));
    795         assertEquals("public String bar", pretty("public String bar"));
    796         assertEquals("String bar", pretty("String bar"));
    797     }
    798
    799     public void testTypecast() throws Exception {
    800         assertEquals("foo = (int)bar", pretty("foo = (int)bar"));
    801         assertEquals("foo = (int[])bar", pretty("foo = (int[])bar"));
    802         assertEquals("foo = (String)bar", pretty("foo = (String)bar"));
    803         assertEquals("foo = (String[])bar", pretty("foo = (String[])bar"));
    804     }
    805
    806     public void testTypeArguments() throws Exception {
    807     	assertEquals("void printCollection(Collection<?> c) {}", pretty("void printCollection(Collection<?> c) {}"));
    808     }
    809     public void testTypeLowerBounds() throws Exception {
    810     	assertEquals("void printCollection(Collection<? super X> c) {}", pretty("void printCollection(Collection<? super X> c) {}"));
    811     }
    812     public void testTypeUpperBounds() throws Exception {
    813     	assertEquals("void printCollection(Collection<? extends X> c) {}", pretty("void printCollection(Collection<? extends X> c) {}"));
    814     }
    815
    816     public void testTypeParameters() throws Exception {
    817     	assertEquals("class Foo<T extends C & I> {T t}",pretty("class Foo<T extends C & I> {T t}"));
    818     }
    819     public void testUnaryMinus() throws Exception {
    820         assertEquals("def x = -3", pretty("def x= -3"));
    821     }
    822     public void testUnaryPlus() throws Exception {
    823         assertEquals("def x = +2", pretty("def x= +2"));
    824     }
    825
    826     public void testVariableDef() throws Exception {
    827         assertEquals("def x = 1", pretty("def x = 1"));
    828         assertEquals("int y = 2", pretty("int y = 2"));
    829         assertEquals("String y", pretty("String y"));
    830         assertEquals("def foo() {int b = 9}", pretty("def foo(){int b = 9}"));
    831     }
    832     public void testVariableDef_FAILS() throws Exception { if (notYetImplemented()) return;
    833     	assertEquals("boolean x, y, z = false", pretty("boolean x,y,z = false"));
    834     }
    835
    836     public void testVaribleParameterDef() throws Exception {
    837     	assertEquals("void myMethod(String param1, String ... others) {}", pretty("void myMethod(String param1, String ... others) {}"));
    838     	assertEquals("void myMethod(final int ... others) {}", pretty("void myMethod(final int ... others) {}"));
    839     	assertEquals("void myMethod(def ... others) {}", pretty("void myMethod(def ... others) {}"));
    840     }
    841
    842     public void testWildcardType() throws Exception {
    843     	assertEquals("public boolean process(Set<? extends TypeElement> annotations) {println annotations}", pretty("public boolean process(Set<? extends TypeElement> annotations) {println annotations}"));
    844     }
    845
    846     public String pretty(String input) throws Exception{
    847         GroovyRecognizer parser = null;
    848         SourceBuffer sourceBuffer = new SourceBuffer();
    849         UnicodeEscapingReader unicodeReader = new UnicodeEscapingReader(new StringReader(input),sourceBuffer);
    850         GroovyLexer lexer = new GroovyLexer(unicodeReader);
    851         unicodeReader.setLexer(lexer);
    852         parser = GroovyRecognizer.make(lexer);
    853         parser.setSourceBuffer(sourceBuffer);
    854
    855         String[] tokenNames;
    856         tokenNames = parser.getTokenNames();
    857         parser.compilationUnit();
    858         AST ast = parser.getAST();
    859
    860         ByteArrayOutputStream baos = new ByteArrayOutputStream();
    861         Visitor visitor = new SourcePrinter(new PrintStream(baos),tokenNames,false);
    862         AntlrASTProcessor traverser = new SourceCodeTraversal(visitor);
    863
    864         traverser.process(ast);
    865
    866         return new String(baos.toByteArray());
    867     }
    868
    869 }