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: 1.11 $
39   */
40  public class SourcePrinterTest extends GroovyTestCase {
41  
42  
43      public void testAnnotations() throws Exception{
44          //todo assertEquals("@Property foo", pretty("@Property foo"));
45      }
46  
47      public void testAssign() throws Exception {
48          assertEquals("a = 12", pretty("a=12"));
49      }
50  
51      public void testClassDef() throws Exception {
52          assertEquals("class Foo {def bar}", pretty("class Foo{def bar}"));
53      }
54  
55      public void testClosedBlock() throws Exception {
56          assertEquals("[1, 2, 3].each {println(it)}", pretty("[1,2,3].each{println it}"));
57          //assertEquals("def x = foo.bar(mooky) {x ->wibble(x)}", pretty("def x = foo.bar(mooky) {x-> wibble(x)}"));
58      }
59      public void testCtorIdent() throws Exception {
60          assertEquals("class Foo {private Foo() {}}", pretty("class Foo {private Foo() {}}"));
61      }
62  
63      public void testDot() throws Exception {
64          assertEquals("foo.bar.mooky()", pretty("foo.bar.mooky()"));
65      }
66  
67      public void testElist() throws Exception {
68          assertEquals("foo(bar, mooky)", pretty("foo( bar , mooky )"));
69      }
70  
71      public void testEqual() throws Exception {
72          assertEquals("a == b", pretty("a==b"));
73      }
74  
75      public void testExpr() throws Exception {
76          //todo assertEquals("foo(bar) mooky(bar)", pretty("foo(bar) mooky(bar)"));
77      }
78  
79      public void testExtendsClause() throws Exception {
80          assertEquals("class Foo extends Bar {}", pretty("class Foo extends Bar {}"));
81      }
82      public void testForInIterable() throws Exception {
83          assertEquals("for (i in [1, 2]) {}", pretty("for (i in [1,2]) {}"));
84      }
85      public void testGt() throws Exception {
86          assertEquals("if (2070 > 354) {}", pretty("if (2070 > 354) {}"));
87      }
88  
89      public void testIdent() throws Exception {
90          assertEquals("foo.bar", pretty("foo.bar"));
91      }
92  
93      public void testImplementsClause() throws Exception {
94          assertEquals("class Foo implements Bar {}", pretty("class Foo implements Bar {}"));
95      }
96  
97      public void testImport() throws Exception {
98          assertEquals("import foo.bar.Wibble", pretty("import foo.bar.Wibble"));
99      }
100 
101     public void testIndexOp() throws Exception {
102         assertEquals("foo.bar()[fred.wilma()]", pretty("foo.bar()[fred.wilma()]"));
103     }
104 
105     public void testLabeledArg() throws Exception {
106         //todo assertEquals("myMethod(argOne:123,argTwo:123)", pretty("myMethod(argOne:123,argTwo:123)"));
107     }
108     public void testLand() throws Exception {
109         assertEquals("true && false", pretty("true && false"));
110     }
111     public void testListConstructor() throws Exception {
112         assertEquals("[a, b]", pretty("[a,b]"));
113     }
114 
115     public void testLiteralAssert() throws Exception {
116         assertEquals("assert a == true", pretty("assert a== true"));
117     }
118 
119     public void testLiteralBoolean() throws Exception {
120         assertEquals("boolean b = true", pretty("boolean b =true"));
121     }
122 
123     public void testLiteralCatch() throws Exception {
124         assertEquals("try {} catch (Exception e) {}", pretty("try {} catch (Exception e) {}"));
125     }
126 
127     public void testLiteralFalse() throws Exception {
128         assertEquals("if (false) {}", pretty("if (false) {}"));
129     }
130 
131     public void testLiteralFloat() throws Exception {
132         assertEquals("float x", pretty("float x"));
133     }
134 
135     public void testLiteralFor() throws Exception {
136         assertEquals("for (i in [1, 2, 3]) {}", pretty("for (i in [1,2,3]) {}"));
137     }
138 
139     public void testLiteralIf() throws Exception {
140         assertEquals("if (a == b) return false", pretty("if (a==b) return false"));
141         assertEquals("if (a == b) {}", pretty("if (a==b) {}"));
142     }
143 
144     public void testLiteralInstanceOf() throws Exception {
145         assertEquals("if (a instanceof String) {}", pretty("if (a instanceof String) {}"));
146     }
147     public void testLiteralInt() throws Exception {
148         assertEquals("int a", pretty("int a"));
149     }
150 
151     public void testLiteralNew() throws Exception {
152         assertEquals("new Foo()", pretty("new Foo()"));
153     }
154 
155     public void testLiteralNull() throws Exception {
156         assertEquals("def foo = null", pretty("def foo=null"));
157     }
158 
159     public void testLiteralPrivate() throws Exception {
160         //todo assertEquals("private bar", pretty("private bar"));
161     }
162 
163     public void testLiteralProtected() throws Exception {
164         //todo assertEquals("protected mooky", pretty("protected mooky"));
165     }
166 
167     public void testLiteralPublic() throws Exception {
168         //todo assertEquals("public foo", pretty("public foo"));
169     }
170 
171     public void testLiteralReturn() throws Exception {
172         assertEquals("def foo() {return false}", pretty("def  foo() { return false }"));
173     }
174 
175     public void testLiteralStatic() throws Exception {
176         assertEquals("static void foo() {}", pretty("static void foo() {}"));
177     }
178 
179     public void testLiteralThis() throws Exception {
180         assertEquals("this.x = this.y", pretty("this.x=this.y"));
181     }
182     public void testLiteralThrow() throws Exception {
183         assertEquals("def foo() {if (false) throw new RuntimeException()}", pretty("def foo() {if (false) throw new RuntimeException()}"));
184     }
185     public void testLiteralTrue() throws Exception {
186         assertEquals("foo = true", pretty("foo = true"));
187     }
188 
189     public void testLiteralTry() throws Exception {
190         assertEquals("try {} catch (Exception e) {}", pretty("try {} catch (Exception e) {}"));
191     }
192 
193     public void testLiteralVoid() throws Exception {
194         assertEquals("void foo() {}", pretty("void foo(){}"));
195     }
196 
197     public void testLiteralWhile() throws Exception {
198         assertEquals("while (true) {}", pretty("while(true){}"));
199     }
200 
201     public void testLnot() throws Exception {
202             assertEquals("if (!isRaining) {}", pretty("if (!isRaining) {}"));
203         }
204 
205     public void testLt() throws Exception {
206         assertEquals("if (3.4f < 12f) {}", pretty("if (3.4f < 12f) {}"));
207     }
208     public void testMapConstructor() throws Exception {
209         assertEquals("Map foo = [:]", pretty("Map foo = [:]"));
210         //assertEquals("[a:1,b:2]", pretty("[a:1,b:2]"));
211     }
212 
213     public void testMemberPointer() throws Exception {
214         assertEquals("def x = foo.&bar()", pretty("def x=foo.&bar()"));
215     }
216     public void testMethodCall() throws Exception {
217         assertEquals("foo(bar)", pretty("foo(bar)"));
218         assertEquals("[1, 2, 3].each {println(it)}", pretty("[1,2,3].each{println it}"));
219         assertEquals("foo(bar){mooky()}", pretty("foo(bar){mooky()}"));
220     }
221 
222     public void testMethodDef() throws Exception {
223         assertEquals("def foo(int bar, boolean boo) {}", pretty("def foo(int bar,boolean boo) {}"));
224         //todo assertEquals("void foo(){} void bar(){}", pretty("void foo(){} void bar(){}"));
225     }
226 
227     public void testMinus() throws Exception {
228         assertEquals("def bar = 4 - foo", pretty("def bar=4-foo"));
229     }
230 
231     public void testModifiers() throws Exception {
232         //todo assertEquals("", pretty(""));
233     }
234     public void testNotEqual() throws Exception {
235         assertEquals("a != b", pretty("a!=b"));
236     }
237     public void testNumInt() throws Exception {
238         assertEquals("a = 12", pretty("a=12"));
239     }
240 
241     public void testNumFloat() throws Exception {
242         assertEquals("b = 34.4f", pretty("b=34.4f"));
243     }
244 
245     public void testObjblock() throws Exception {
246         assertEquals("class Foo {def bar}", pretty("class Foo {def bar}"));
247     }
248 
249     public void testPackageDef() throws Exception {
250         assertEquals("package foo.bar", pretty("package foo.bar"));
251     }
252 
253     public void testParameterDef() throws Exception {
254         //todo assertEquals("", pretty(""));
255     }
256 
257     public void testParameters() throws Exception {
258         //todo assertEquals("", pretty(""));
259     }
260     public void testPlus() throws Exception {
261         assertEquals("a + b", pretty("a+b"));
262     }
263     public void testQuestion() throws Exception {
264         assertEquals("foo == bar?10:20", pretty("foo==bar?10:20"));
265     }
266     public void testRangeExclusive() throws Exception {
267         assertEquals("foo[45..<89]", pretty("foo[45 ..< 89]"));
268     }
269     public void testRangeInclusive() throws Exception {
270         assertEquals("foo[bar..12]", pretty("foo[bar .. 12]"));
271     }
272     public void testSlist() throws Exception {
273         assertEquals("if (true) {foo}", pretty("if (true) {foo}"));
274     }
275 
276     public void testStar() throws Exception {
277         assertEquals("import foo.*", pretty("import foo.*"));
278         assertEquals("a*b", pretty("a*b"));
279     }
280 
281     public void testStringConstructor() throws Exception {
282         //todo assertEquals("\"foo$bar\"", pretty("\"foo$bar\""));
283     }
284 
285     public void testStringLiteral() throws Exception {
286         assertEquals("\"mooky\"", pretty("\"mooky\""));
287         //todo assertEquals("'mooky'", pretty("'mooky'"));
288     }
289 
290     public void testType() throws Exception {
291         assertEquals("String bar", pretty("String bar"));
292     }
293 
294     public void testTypecast() throws Exception {
295         assertEquals("foo = (String)bar", pretty("foo = (String)bar"));
296     }
297 
298     public void testVariableDef() throws Exception {
299         assertEquals("def x = 1", pretty("def x = 1"));
300     }
301 
302     public String pretty(String input) throws Exception{
303         GroovyRecognizer parser = null;
304         SourceBuffer sourceBuffer = new SourceBuffer();
305         UnicodeEscapingReader unicodeReader = new UnicodeEscapingReader(new StringReader(input),sourceBuffer);
306         GroovyLexer lexer = new GroovyLexer(unicodeReader);
307         unicodeReader.setLexer(lexer);
308         parser = GroovyRecognizer.make(lexer);
309         parser.setSourceBuffer(sourceBuffer);
310 
311         String[] tokenNames;
312         tokenNames = parser.getTokenNames();
313         parser.compilationUnit();
314         AST ast = parser.getAST();
315 
316         ByteArrayOutputStream baos = new ByteArrayOutputStream();
317         Visitor visitor = new SourcePrinter(new PrintStream(baos),tokenNames,false);
318         AntlrASTProcessor traverser = new SourceCodeTraversal(visitor);
319 
320         traverser.process(ast);
321 
322         return new String(baos.toByteArray());
323     }
324 
325 }