PageRenderTime 6ms CodeModel.GetById 4ms app.highlight 68ms RepoModel.GetById 1ms app.codeStats 0ms

/test/org/d/model/FormatterTest.java

https://bitbucket.org/ariovistus/d-jvm-cc
Java | 672 lines | 622 code | 34 blank | 16 comment | 17 complexity | 55a2459eb3df821fd38ccffc2faddbde MD5 | raw file
  1/*
  2 * To change this template, choose Tools | Templates
  3 * and open the template in the editor.
  4 */
  5package org.d.model;
  6
  7import org.netbeans.modules.cnd.antlr.collections.AST;
  8import java.io.StringReader;
  9import java.text.MessageFormat;
 10import junit.framework.TestCase;
 11import org.d.generated.D2Lexer;
 12import org.d.generated.D2Parser;
 13import org.d.generated.DLexer;
 14import org.d.generated.DParser;
 15
 16/**
 17 *
 18 * @author ellery
 19 */
 20public class FormatterTest extends TestCase {
 21	public static DParser parser(String s) {
 22		DLexer lexer = new DLexer(new StringReader(s));
 23		DParser parser = new DParser(lexer);
 24		parser.initWithLines();
 25		return parser;
 26	}
 27
 28	public static D2Parser parser2(String s) {
 29		D2Lexer lexer = new D2Lexer(new StringReader(s));
 30		D2Parser parser = new D2Parser(lexer);
 31		parser.initWithLines();
 32		return parser;
 33	}
 34
 35	public static AST module(String s) {
 36		DParser parser = parser(s);
 37		parser.module();
 38		if (parser.errors.isEmpty()) {
 39			return parser.getAST();
 40		}
 41		return null;
 42	}
 43
 44	public static AST module2(String s) {
 45		D2Parser parser = parser2(s);
 46		parser.module();
 47		if (parser.errors.isEmpty()) {
 48			return parser.getAST();
 49		}
 50		return null;
 51	}
 52
 53	public static AST expression(String s) {
 54		DParser parser = parser(s);
 55		parser.exp();
 56		if (parser.errors.isEmpty()) {
 57			return parser.getAST();
 58		}
 59		return null;
 60	}
 61
 62	public static AST expression2(String s) {
 63		D2Parser parser = parser2(s);
 64		parser.exp();
 65		if (parser.errors.isEmpty()) {
 66			return parser.getAST();
 67		}
 68		return null;
 69	}
 70
 71	public static AST statement(String s) {
 72		DParser parser = parser(s);
 73		parser.statement();
 74		if (parser.errors.isEmpty()) {
 75			return parser.getAST();
 76		}
 77		return null;
 78	}
 79
 80	public static AST statement2(String s) {
 81		D2Parser parser = parser2(s);
 82		parser.statement();
 83		if (parser.errors.isEmpty()) {
 84			return parser.getAST();
 85		}
 86		return null;
 87	}
 88
 89	public static AST declDef(String s) {
 90		DParser parser = parser(s);
 91		parser.declDef();
 92		if (parser.errors.isEmpty()) {
 93			return parser.getAST();
 94		}
 95		return null;
 96	}
 97
 98	public static AST declDef2(String s) {
 99		D2Parser parser = parser2(s);
100		parser.declDef();
101		if (parser.errors.isEmpty()) {
102			return parser.getAST();
103		}
104		return null;
105	}
106
107	public FormatterTest(String testName) {
108		super(testName);
109	}
110
111	@Override
112	protected void setUp() throws Exception {
113		super.setUp();
114	}
115
116	@Override
117	protected void tearDown() throws Exception {
118		super.tearDown();
119	}
120
121	/**
122	 * Test of format method, of class Formatter.
123	 */
124	public void testFormat() {
125		System.out.println("format");
126		String[][] expressions = {
127			{"a+b*c-d(e,f)^j;", "a + b * c - d(e, f) ^ j"},
128			{"-    a;", "-a"},
129			{"a & - a;", "a & -a"},
130			{"(a,b,c);", "(a, b, c)"},
131			{"delete   a;", "delete a"},
132			{"cast( int )1.0;", "cast(int) 1.0"},
133			{"int . max ;", "int.max"},
134			{"new(1,2) int[][](1,2);", "new(1, 2) int[][](1, 2)"},
135			{"a  is  null;", "a is null"},
136			{"a !is  null;", "a !is null"},
137			{"a in  null;", "a in null"},
138			{"is(int);", "is(int)"},
139			{"is(int i:j);", "is(int i: j)"},
140			{"is( int[ ] i ==  j);", "is(int[] i == j)"},
141			{"is( int ==  return);", "is(int == return)"},
142			{"is( int ==  class);", "is(int == class)"},
143			{"is( int ==  interface);", "is(int == interface)"},
144			{"is( int ==  super);", "is(int == super)"},
145			{"is( int ==  struct);", "is(int == struct)"},
146			{"is( int ==  union);", "is(int == union)"},
147			{"is( i ==  function);", "is(i == function)"},
148			{"is( i ==  delegate);", "is(i == delegate)"},
149			{"is( i ==  enum);", "is(i == enum)"},
150			{"typeid(int);", "typeid(int)"},
151			{"typeof(int.max);", "typeof(int.max)"},
152			{"import(\"waga\");", "import(\"waga\")"},
153			{"i!(i,j,k);", "i!(i, j, k)"},
154			{"[1,2,3];", "[1, 2, 3]"},
155			{"[1:\"a\",2:\"b\",3:\"c\"];", "[1: \"a\", 2: \"b\", 3: \"c\"]"},
156			{"{ return 1; };", "{return 1;}"},
157			{"delegate { return 1; };", "delegate {return 1;}"},
158			{"delegate {  };", "delegate {}"},
159			{"delegate int{ return 1; };", "delegate int{return 1;}"},
160			{"delegate int(int j){ return 1; };", "delegate int(int j){return 1;}"},
161			{"(int j){ return 1; };", "(int j){return 1;}"},
162			{"assert(false, \"hi!\");", "assert(false, \"hi!\")"},
163			{"assert(true );", "assert(true)"},
164			{"a[i ..j];", "a[i .. j]"},
165			{"a[i ];", "a[i]"},
166			{"a[i , j , k];", "a[i, j, k]"},
167			{"a?b:c;", "a ? b : c"},
168			{"&a;", "&a"},
169			{"b&a;", "b & a"},
170			{"+a;", "+a"},
171			{"b+a;", "b + a"},
172			{"-a;", "-a"},
173			{"b-a;", "b - a"},
174			{"~a;", "~a"},
175			{"b~a;", "b ~ a"},
176			{"*a;", "*a"},
177			{"b*a;", "b * a"},
178			{"++a;", "++a"},
179			{"a++;", "a++"},
180			{"--a;", "--a"},
181			{"a--;", "a--"},
182			{"!a--;", "!a--"},
183			{"`a` `b`;", "`a` `b`"},
184			{"__LINE__ is __DUMB__;", "__LINE__ is __DUMB__"},
185			{"i!();", "i!()"},
186			{"new class (1) T {};", "new class(1) T {\n}"},
187			{"mixin(hi);", "mixin(hi)"},
188			{"(int*).max;", "(int*).max"},};
189		String[][] expressions2 = {
190			{"a ^^ b;", "a ^^ b"},
191			{"a ^^= b;", "a ^^= b"},
192			{"__traits(me);", "__traits(me)"},
193			{"__traits(me,you);", "__traits(me, you)"},
194			{"__traits(me,you,us);", "__traits(me, you, us)"},
195			{"q{ /*doh*/  }c;", "q{ /*doh*/  }c"},
196			{"a ! in b;", "a !in b"},
197			{"is(I J == K, L);", "is(I J == K, L)"},
198			{"is(I J == K, L, M);", "is(I J == K, L, M)"},
199			{"i!i;", "i!i"},
200			{"to!int(`1`);", "to!int(`1`)"},};
201		String[][] statements = {
202			{"int i = 0;", "int i = 0;"},
203			{"int i = 0, b = 1, c = 2;", "int i = 0, b = 1, c = 2;"},
204			{"int* i = 1;", "int* i = 1;"},
205			{"int delegate(int)* i = 1;", "int delegate(int)* i = 1;"},
206			{"int delegate(int) delegate(double,int) i = 1;", "int delegate(int) delegate(double, int) i = 1;"},
207			{"int [int*] i = 1;", "int[int*] i = 1;"},
208			{"int[3] [ 4] i = 1;", "int[3][4] i = 1;"},
209			{"int[] *i = 1;", "int[]* i = 1;"},
210			{"typeof(1)[] i = 1;", "typeof(1)[] i = 1;"},
211			{"MAHBIGLABEL: i;", "MAHBIGLABEL: i;"},
212			{"mixin(\"It's a trap!\");", "mixin(\"It's a trap!\");"},
213			{"mixin I.I!(I);", "mixin I.I!(I);"},
214			{"mixin .I!(I);", "mixin .I!(I);"},
215			{"mixin .I.I!(I);", "mixin .I.I!(I);"},
216			{"mixin typeof(J).I.I!(I);", "mixin typeof(J).I.I!(I);"},
217			{"mixin typeof(J).I.I!(I);", "mixin typeof(J).I.I!(I);"},
218			{"mixin I.I!(I) FOO;", "mixin I.I!(I) FOO;"},
219			{"mixin .I.I!(I) FOO;", "mixin .I.I!(I) FOO;"},
220			{"mixin typeof(J).I.I!(I) FOO;", "mixin typeof(J).I.I!(I) FOO;"},
221			{"abstract class X{}", "abstract class X {\n}"},
222			{"abstract class X{int i;}", "abstract class X {\n    int i;\n}"},
223			{"static assert(1,-1);", "static assert(1, -1);"},
224			{"static assert (1);", "static assert(1);"},
225			{"version(1){ int i; };", "version(1) {\n    int i;\n}"},
226			{"version(i){ int i; };", "version(i) {\n    int i;\n}"},
227			{"version(i){ int i; }else{ int j;};", "version(i) {\n    int i;\n} else {\n    int j;\n}"},
228			{"version(i){ int i; }else version(j){ int j;};", "version(i) {\n    int i;\n} else version(j) {\n    int j;\n}"},
229			{"version(i) int i = 0;;", "version(i) int i = 0;"},
230			{"debug{ int i; };", "debug {\n    int i;\n}"},
231			{"debug(1){ int i; };", "debug(1) {\n    int i;\n}"},
232			{"debug(i){ int i; };", "debug(i) {\n    int i;\n}"},
233			{"debug(i){ int i; }else{ int j;};", "debug(i) {\n    int i;\n} else {\n    int j;\n}"},
234			{"debug(i){ int i; }else debug(j){ int j;};", "debug(i) {\n    int i;\n} else debug(j) {\n    int j;\n}"},
235			{"static if(i){ int i; };", "static if(i) {\n    int i;\n}"},
236			{"static if(i){ int i; };", "static if(i) {\n    int i;\n}"},
237			{"static if(i){ int i; }else{ int j;};", "static if(i) {\n    int i;\n} else {\n    int j;\n}"},
238			{"static if(i){ int i; }else static if(j){ int j;};", "static if(i) {\n    int i;\n} else static if(j) {\n    int j;\n}"},
239			{"if(i){};", "if(i) {\n}"},
240			{"if(int i = 0) {};", "if(int i = 0) {\n}"},
241			{"if(auto i = 0){};", "if(auto i = 0) {\n}"},
242			{"if(i){}else{};", "if(i) {\n} else {\n}"},
243			{"if(i){}else if(j){ };", "if(i) {\n} else if(j) {\n}"},
244			{"while(true){ true++; };", "while(true) {\n    true++;\n}"},
245			{"while(true) true++; ;", "while(true) true++;"},
246			{"do{ true++; }while(true);", "do {\n    true++;\n} while(true);"},
247			{"do true++; while(true);", "do true++;\nwhile(true);"},
248			{"for(;;){ writeln(i); writeln(i+1);};",
249				"for(;;) {\n    writeln(i);\n    writeln(i + 1);\n}"
250			},
251			{"for(int  i=0;;){ writeln(i); writeln(i+1);};",
252				"for(int i = 0;;) {\n    writeln(i);\n    writeln(i + 1);\n}"
253			},
254			{"for(;i < 10;){ writeln(i); writeln(i+1);};",
255				"for(; i < 10;) {\n    writeln(i);\n    writeln(i + 1);\n}"
256			},
257			{"for(;;i++){ writeln(i); writeln(i+1);};",
258				"for(;; i++) {\n    writeln(i);\n    writeln(i + 1);\n}"
259			},
260			{"for(int i =0; i<10; i ++){ writeln(i); writeln(i+1);};",
261				"for(int i = 0; i < 10; i++) {\n    writeln(i);\n    writeln(i + 1);\n}"
262			},
263			{"for(;;) i++;;", "for(;;) i++;"},
264			{"for({} i < 10; i++) writeln(c);;",
265				"for({\n} i < 10; i++) writeln(c);"
266			}, 
267			{"for({int i =1; char c = 'a';} i < 10; i++) writeln(c);;",
268				"for({\n    int i = 1;\n    char c = 'a';\n} i < 10; i++) writeln(c);"
269			}, 
270			{"foreach(i;j) i++;;", "foreach(i; j) i++;"},
271			{"foreach(ref i;j) i++;;", "foreach(ref i; j) i++;"},
272			{"foreach(inout i;j) i++;;", "foreach(inout i; j) i++;"},
273			{"foreach(int* i;j) i++;;", "foreach(int* i; j) i++;"},
274			{"foreach(ref int* i;j) i++;;", "foreach(ref int* i; j) i++;"},
275			{"foreach(i;j){i++;};", "foreach(i; j) {\n    i++;\n}"},
276			{"foreach_reverse(i;j) i++;;", "foreach_reverse(i; j) i++;"},
277			{"switch(i){};", "switch(i) {\n}"},
278			{"switch(i){ case 1,2: i++;};", "switch(i) {\n    case 1, 2: i++;\n}"},
279			{"switch(i){ case 1,2: i++; \nj--;};", "switch(i) {\n    case 1, 2:\n        i++;\n        j--;\n}"},
280			{"default:{ throw new Exception();};", "default: {\n    throw new Exception();\n}"},
281			{"switch(i){default: return -1;};", "switch(i) {\n    default: return -1;\n}"},
282			{"continue i;", "continue i;"},
283			{"continue;", "continue;"},
284			{"break;", "break;"},
285			{"return;", "return;"},
286			{"while(true) continue i;;", "while(true) continue i;"},
287			{"while(true) break i;;", "while(true) break i;"},
288			{"while(true) return i;;", "while(true) return i;"},
289			{"while(true) goto i;;", "while(true) goto i;"},
290			{"while(true) goto default;;", "while(true) goto default;"},
291			{"while(true) goto case ;;", "while(true) goto case;"},
292			{"while(true) goto case 1;;", "while(true) goto case 1;"},
293			{"with(i){};", "with(i){\n}"},
294			{"with(i)i++;", "with(i) i++;"},
295			{"synchronized(i)i++;", "synchronized(i) i++;"},
296			{"synchronized{i++;}", "synchronized {\n    i++;\n}"},
297			{"try{ i++; }catch{ i--; };", "try {\n    i++;\n} catch {\n    i--;\n}"},
298			{"try{ i++; }catch(Exception ex){ i--; };", "try {\n    i++;\n} catch(Exception ex) {\n    i--;\n}"},
299			{"try{ i++; }catch(Exception ex){ i--; }finally{};", "try {\n    i++;\n} catch(Exception ex) {\n    i--;\n} finally {\n}"},
300			{"try{ i++; }finally{ i--; };", "try {\n    i++;\n} finally {\n    i--;\n}"},
301			{"while(true) throw i;;", "while(true) throw i;"},
302			{"scope(success) i++;", "scope(success) i++;"},
303			{"asm{ cmp EAX 1;}", "asm {\n    cmp EAX 1;\n}"}, //no, I don't know jack about asm syntax
304			{"pragma(msg);", "pragma(msg);"},
305			{"pragma(msg,\"hi!\");", "pragma(msg, \"hi!\");"},
306			{"{};", "{\n}"},
307			{"volatile int i;", "volatile int i;"},
308			{"volatile{ int i;};", "volatile {\n    int i;\n}"},
309			{"LABEL: int i = 0;;", "LABEL: int i = 0;"},
310			{"LABEL: ;;", "LABEL:;"},};
311		String[][] statements2 = {
312			{"final switch(i){};", "final switch(i) {\n}"},
313			{"case 1: .. case 2: i++;", "case 1:\n..\ncase 2: i++;"},
314			{"foreach(i; 1 .. 10) i++;", "foreach(i; 1 .. 10) i++;"},};
315		String[][] decls = {
316			{"enum I{}", "enum I {\n}"},
317			{"enum I;", "enum I;"},
318			{"enum I:int{}", "enum I: int {\n}"},
319			{"enum {}", "enum {\n}"},
320			{"enum :int{}", "enum: int {\n}"},
321			{"enum I{ a}", "enum I {\n    a,\n}"},
322			{"enum I{ a,}", "enum I {\n    a,\n}"},
323			{"enum I{ a,b}", "enum I {\n    a,\n    b,\n}"},
324			{"enum I{ a=1}", "enum I {\n    a = 1,\n}"},
325			{"enum I{ a = 1, b}", "enum I {\n    a = 1,\n    b,\n}"},
326			{"class I{}", "class I {\n}"},
327			{"class I:B{}", "class I: B {\n}"},
328			{"class I(T){}", "class I(T) {\n}"},
329			{"class I(T):B{}", "class I(T): B {\n}"},
330			{"class I(T):B { static assert(green);}", "class I(T): B {\n    static assert(green);\n}"},
331			{"class I;", "class I;"},
332			{"class I:B,C,D{}", "class I: B, C, D {\n}"},
333			{"class I:private B{}", "class I: private B {\n}"},
334			{"class I:B.C.D{}", "class I: B.C.D {\n}"},
335			{"class I:B.C!(D){}", "class I: B.C!(D) {\n}"},
336			{"interface I{}", "interface I {\n}"},
337			{"interface I:B{}", "interface I: B {\n}"},
338			{"interface I(T){}", "interface I(T) {\n}"},
339			{"interface I(T):B{}", "interface I(T): B {\n}"},
340			{"interface I(T):B{ static assert(green);}", "interface I(T): B {\n    static assert(green);\n}"},
341			{"interface I;", "interface I;"},
342			{"interface I:B,C,D{}", "interface I: B, C, D {\n}"},
343			{"interface I:private B{}", "interface I: private B {\n}"},
344			{"interface I:B.C.D{}", "interface I: B.C.D {\n}"},
345			{"interface I:B.C!(D){}", "interface I: B.C!(D) {\n}"},
346			{"struct I{}", "struct I {\n}"},
347			{"struct I(T){}", "struct I(T) {\n}"},
348			{"struct I;", "struct I;"},
349			{"struct{}", "struct {\n}"},
350			{"union I{}", "union I {\n}"},
351			{"union I(T){}", "union I(T) {\n}"},
352			{"union I;", "union I;"},
353			{"union{}", "union {\n}"},
354			{"import i;", "import i;"},
355			{"import i, j;", "import i, j;"},
356			{"import i.i.i;", "import i.i.i;"},
357			{"import I = i;", "import I = i;"},
358			{"static import i;", "static import i;"},
359			{"import i:j;", "import i: j;"},
360			{"import i:j=k;", "import i: j = k;"},
361			{"template T(){}", "template T() {\n}"},
362			{"template T(alias i){}", "template T(alias i) {\n}"},
363			{"template T(alias i:int){}", "template T(alias i: int) {\n}"},
364			{"template T(alias i=int){}", "template T(alias i = int) {\n}"},
365			{"template T(i...){}", "template T(i...) {\n}"},
366			{"template T(int i:1){}", "template T(int i: 1) {\n}"},
367			{"template T(int i=1){}", "template T(int i = 1) {\n}"},
368			{"template T(i){}", "template T(i) {\n}"},
369			{"template T(i:j){}", "template T(i: j) {\n}"},
370			{"template T(i=j){}", "template T(i = j) {\n}"},
371			{"template T(i, alias i, int i){}", "template T(i, alias i, int i) {\n}"},
372			{"mixin(\"mixin(\\\"hi!\\\");\");", "mixin(\"mixin(\\\"hi!\\\");\");"},
373			{"typedef i j;", "typedef i j;"},
374			{"typedef deprecated i j;", "typedef deprecated i j;"},
375			{"typedef i j =1;", "typedef i j = 1;"},
376			{"typedef i j , k;", "typedef i j, k;"},
377			{"typedef i j =1 , k=1;", "typedef i j = 1, k = 1;"},
378			{"alias i j;", "alias i j;"},
379			{"alias static i j;", "alias static i j;"},
380			{"alias i j, k, m;", "alias i j, k, m;"},
381			{"auto i = 1;", "auto i = 1;"},
382			{"auto i = 1, j = 2;", "auto i = 1, j = 2;"},
383			{"int i(int j){}", "int i(int j) {\n}"},
384			{"int i(lazy int j){}", "int i(lazy int j) {\n}"},
385			{"int i(in int j){}", "int i(in int j) {\n}"},
386			{"int i(inout int j){}", "int i(inout int j) {\n}"},
387			{"int i(out int j){}", "int i(out int j) {\n}"},
388			{"int i(int j, int k = 1){}", "int i(int j, int k = 1) {\n}"},
389			{"int i(int j, int k ...){}", "int i(int j, int k...) {\n}"},
390			{"int i(int j, int  ...){}", "int i(int j, int...) {\n}"},
391			{"int i(int j, int  ){}", "int i(int j, int) {\n}"},
392			{"int i(...){}", "int i(...) {\n}"},
393			{"int i() body{}", "int i()\nbody {\n}"},
394			{"int i() in{}out{}body{}", "int i()\nin {\n} out {\n} body {\n}"},
395			{"int i() in{}out(result){}body{}", "int i()\nin {\n} out(result) {\n} body {\n}"},
396			{"this(){}", "this() {\n}"},
397			{"this(int i){}", "this(int i) {\n}"},
398			{"~this(){}", "~this() {\n}"},
399			{"invariant{}", "invariant() {\n}"},
400			{"unittest{}", "unittest {\n}"},
401			{"new(){}", "new() {\n}"},
402			{"new(int i){}", "new(int i) {\n}"},
403			{"delete(){}", "delete() {\n}"},
404			{"delete(int i){}", "delete(int i) {\n}"},
405			{"static this(){}", "static this() {\n}"},
406			{"static ~this(){}", "static ~this() {\n}"},
407			{"static assert(i);", "static assert(i);"},
408			{"static assert(i,j);", "static assert(i, j);"},
409			{"static if(i){}", "static if(i) {\n}"},
410			{"static if(i){}else {}", "static if(i) {\n} else {\n}"},
411			{"private{}", "private{\n}"},
412			{"static{}", "static{\n}"},
413			{"static{int i;}", "static{\n    int i;\n}"},
414			{"private:int i;", "private:\n    int i;"},
415			{"public export:int i;", "public export:\n    int i;"},
416			{"static: int i;", "static:\n    int i;"},
417			{"static private: int i;", "static private:\n    int i;"},
418			{"align(16): int i;", "align(16):\n    int i;"},
419			{"align: int i;", "align:\n    int i;"},
420			{"align int i;", "align int i;"},
421			{"export: int i;", "export:\n    int i;"},
422			{"private extern: int i;", "private extern:\n    int i;"},
423			{"private extern(C++): int i;", "private extern(C++):\n    int i;"},
424			{"private extern(Windows): int i;", "private extern(Windows):\n    int i;"},
425			{"pragma(msk): int i;", "pragma(msk):\n    int i;"},
426			{"pragma(msk,msy): int i;", "pragma(msk, msy):\n    int i;"},
427			{"debug = I;", "debug = I;"},
428			{"debug = 1;", "debug = 1;"},
429			{"version = i;", "version = i;"},
430			{"version = 1;", "version = 1;"},
431			{"debug{}", "debug {\n}"},
432			{"debug(i){}", "debug(i) {\n}"},
433			{"version(i){}", "version(i) {\n}"},
434			{"int[] i = [1,2,3,];", "int[] i = [1, 2, 3];"},
435			{"int[] i = [];", "int[] i = [];"},
436			{"int[] i = [0:1,10:2,3,];", "int[] i = [0: 1, 10: 2, 3];"},
437			{"Struct s = {1,2,3};", "Struct s = {1, 2, 3};"},
438			{"Struct s = {};", "Struct s = {};"},
439			{"Struct s = {i:1,J:2,3};", "Struct s = {i: 1, J: 2, 3};"},
440			{"Struct[] s = [{1,2,3}, {4,5,6}];", "Struct[] s = [{1, 2, 3}, {4, 5, 6}];"},
441			{"int[] i = void;", "int[] i = void;"},
442			{".i* k = 1;", ".i* k = 1;"},
443			{".i.i* k = 1;", ".i.i* k = 1;"},
444			{"typeof(i).i.i* k = 1;", "typeof(i).i.i* k = 1;"},
445			{"int[0..2] i = (1,2);", "int[0 .. 2] i = (1, 2);"},
446			{"int (*i)(int) = cast(int(*)(int))function int(int){return 1;};", "int (*i)(int) = cast(int (*)(int)) function int(int){return 1;};"},};
447		String[][] decls2 = {
448			{"@property abstract auto int i;", "@property abstract auto int i;"},
449			{"abstract private int i;", "abstract private int i;"},
450			{"@Anno private int i;", "@Anno private int i;"},
451			{"const deprecated enum int i;", "const deprecated enum int i;"},
452			{"final __gshared immutable int i;", "final __gshared immutable int i;"},
453			{"inout nothrow override pure int i;", "inout nothrow override pure int i;"},
454			{"ref scope shared int i;", "ref scope shared int i;"},
455			{"static synchronized __thread int i;", "static synchronized __thread int i;"},
456			{"auto a(int i){}", "auto a(int i) {\n}"},
457			{"enum I{ int i = 1,}", "enum I {\n    int i = 1,\n}"},
458			{"mixin template T(){}", "mixin template T() {\n}"},
459			{"template T(this I){}", "template T(this I) {\n}"},
460			{"template T(alias int i){}", "template T(alias int i) {\n}"},
461			{"version(unittest){}", "version(unittest) {\n}"},
462			{"class X(T) if(is(T == int)){}", "class X(T) if(is(T == int)) {\n}"},
463			{"alias i this;", "alias i this;"},
464			{"const(int) i;", "const(int) i;"},
465			{"const shared(int) i;", "const shared(int) i;"},
466			{"const (shared int) i;", "const(shared int) i;"},
467			{"const (shared(int)) i;", "const(shared(int)) i;"},
468			{"int i(int j) nothrow {}", "int i(int j) nothrow {\n}"},
469			{"int i(int j) pure nothrow {}", "int i(int j) pure nothrow {\n}"},
470			{"int i(I)(int j) nothrow if(is(I)) {}", "int i(I)(int j) nothrow if(is(I)) {\n}"},};
471		for (String[] raw_formatted : expressions) {
472			AST t = expression(raw_formatted[0]);
473			String s = Formatter.format(t);
474//			System.out.println(raw_formatted[1] + " " + s);
475			assertEquals(raw_formatted[1], s);
476			assertEquals(raw_formatted[1], Formatter.format2(t));
477		}
478		for (String[] raw_formatted : expressions2) {
479			AST t = expression2(raw_formatted[0]);
480			String s = Formatter.format2(t);
481//			System.out.println(raw_formatted[1] + " " + s);
482			assertEquals(raw_formatted[1], s);
483		}
484		for (String[] raw_formatted : statements) {
485			AST t = statement(raw_formatted[0]);
486			String s = Formatter.format(t);
487			System.out.println(MessageFormat.format("\"{0}\" vs \"{1}\"", raw_formatted[1],s));
488			assertEquals(raw_formatted[1], s);
489			assertEquals(raw_formatted[1], Formatter.format2(t));
490		}
491		for (String[] raw_formatted : statements2) {
492			AST t = statement2(raw_formatted[0]);
493			String s = Formatter.format2(t);
494//			System.out.println(MessageFormat.format("\"{0}\" vs \"{1}\"", raw_formatted[1],s));
495			assertEquals(raw_formatted[1], s);
496		}
497		for (String[] raw_formatted : decls) {
498			AST t = declDef(raw_formatted[0]);
499			String s = Formatter.format(t);
500			if (!s.equals(raw_formatted[1])) {
501				System.out.println(MessageFormat.format("\"{0}\" vs \"{1}\"", raw_formatted[1], s));
502//				Visitor.dump(t);
503			}
504			assertEquals(raw_formatted[1], s);
505			assertEquals(raw_formatted[1], Formatter.format2(t));
506		}
507		for (String[] raw_formatted : decls2) {
508			AST t = declDef2(raw_formatted[0]);
509			String s = Formatter.format2(t);
510			if (!s.equals(raw_formatted[1])) {
511				System.out.println(MessageFormat.format("\"{0}\" vs \"{1}\"", raw_formatted[1], s));
512//				Visitor.dump(t);
513			}
514			assertEquals(raw_formatted[1], s);
515		}
516
517		CodeStyle b4foreachParenT = new CodeStyle.DefaultCodeStyle(1) {
518
519			@Override
520			public boolean spaceBeforeForeachParen() {
521				return true;
522			}
523		};
524		CodeStyle b4foreachParenF = new CodeStyle.DefaultCodeStyle(1) {
525
526			@Override
527			public boolean spaceBeforeForeachParen() {
528				return false;
529			}
530		};
531		CodeStyle b4versionParenT = new CodeStyle.DefaultCodeStyle(1) {
532
533			@Override
534			public boolean spaceBeforeVersionParen() {
535				return true;
536			}
537		};
538		CodeStyle b4versionParenF = new CodeStyle.DefaultCodeStyle(1) {
539
540			@Override
541			public boolean spaceBeforeVersionParen() {
542				return false;
543			}
544		};
545		CodeStyle b4debugParenT = new CodeStyle.DefaultCodeStyle(1) {
546
547			@Override
548			public boolean spaceBeforeDebugParen() {
549				return true;
550			}
551		};
552		CodeStyle b4debugParenF = new CodeStyle.DefaultCodeStyle(1) {
553
554			@Override
555			public boolean spaceBeforeDebugParen() {
556				return false;
557			}
558		};
559		CodeStyle b4catchParenT = new CodeStyle.DefaultCodeStyle(1) {
560
561			@Override
562			public boolean spaceBeforeCatchParen() {
563				return true;
564			}
565		};
566		CodeStyle b4catchParenF = new CodeStyle.DefaultCodeStyle(1) {
567
568			@Override
569			public boolean spaceBeforeCatchParen() {
570				return false;
571			}
572		};
573		CodeStyle b4catchLBraceT = new CodeStyle.DefaultCodeStyle(1) {
574
575			@Override
576			public boolean spaceBeforeCatchLeftBrace() {
577				return true;
578			}
579		};
580		CodeStyle b4catchLBraceF = new CodeStyle.DefaultCodeStyle(1) {
581
582			@Override
583			public boolean spaceBeforeCatchLeftBrace() {
584				return false;
585			}
586		};
587		CodeStyle b4tryLBraceT = new CodeStyle.DefaultCodeStyle(1) {
588
589			@Override
590			public boolean spaceBeforeTryLeftBrace() {
591				return true;
592			}
593		};
594		CodeStyle b4tryLBraceF = new CodeStyle.DefaultCodeStyle(1) {
595
596			@Override
597			public boolean spaceBeforeTryLeftBrace() {
598				return false;
599			}
600		};
601		CodeStyle b4catchT = new CodeStyle.DefaultCodeStyle(1) {
602
603			@Override
604			public boolean spaceBeforeCatch() {
605				return true;
606			}
607		};
608		CodeStyle b4catchF = new CodeStyle.DefaultCodeStyle(1) {
609
610			@Override
611			public boolean spaceBeforeCatch() {
612				return false;
613			}
614		};
615		CodeStyle rndUnaryT = new CodeStyle.DefaultCodeStyle(1) {
616
617			@Override
618			public boolean spaceAroundUnaryOps() {
619				return true;
620			}
621		};
622		CodeStyle rndUnaryF = new CodeStyle.DefaultCodeStyle(1) {
623
624			@Override
625			public boolean spaceAroundUnaryOps() {
626				return false;
627			}
628		};
629		Object[] stmts = new Object[]{
630			new Object[]{"foreach(i; j){};", b4foreachParenT, "foreach (i; j) {\n}"},
631			new Object[]{"foreach(i; j){};", b4foreachParenF, "foreach(i; j) {\n}"},
632			new Object[]{"foreach_reverse(i; j){};", b4foreachParenT, "foreach_reverse (i; j) {\n}"},
633			new Object[]{"foreach_reverse(i; j){};", b4foreachParenF, "foreach_reverse(i; j) {\n}"},
634			new Object[]{"version(i){};", b4versionParenT, "version (i) {\n}"},
635			new Object[]{"version(i){};", b4versionParenF, "version(i) {\n}"},
636			new Object[]{"debug(i){};", b4debugParenT, "debug (i) {\n}"},
637			new Object[]{"debug(i){};", b4debugParenF, "debug(i) {\n}"},
638			new Object[]{"debug{};", b4debugParenT, "debug {\n}"},
639			new Object[]{"debug{};", b4debugParenF, "debug {\n}"},
640			new Object[]{"try{}catch(Exception e){}", b4catchLBraceT, "try {\n} catch(Exception e) {\n}"},
641			new Object[]{"try{}catch(Exception e){}", b4catchLBraceF, "try {\n} catch(Exception e){\n}"},
642			new Object[]{"try{}catch(Exception e){}", b4catchT, "try {\n} catch(Exception e) {\n}"},
643			new Object[]{"try{}catch(Exception e){}", b4catchF, "try {\n}catch(Exception e) {\n}"},
644			new Object[]{"try{}catch(Exception e){}", b4tryLBraceT, "try {\n} catch(Exception e) {\n}"},
645			new Object[]{"try{}catch(Exception e){}", b4tryLBraceF, "try{\n} catch(Exception e) {\n}"},
646			new Object[]{"i++;", rndUnaryT, "i ++"},
647			new Object[]{"i++;", rndUnaryF, "i++"},
648			new Object[]{"j--;", rndUnaryT, "j --"},
649			new Object[]{"j--;", rndUnaryF, "j--"},
650			new Object[]{"++k;", rndUnaryT, "++ k"},
651			new Object[]{"++k;", rndUnaryF, "++k"},
652			new Object[]{"--l;", rndUnaryT, "-- l"},
653			new Object[]{"--l;", rndUnaryF, "--l"},
654			new Object[]{"*l;", rndUnaryT, "* l"},
655			new Object[]{"*l;", rndUnaryF, "*l"},
656			new Object[]{"&l;", rndUnaryT, "& l"},
657			new Object[]{"&l;", rndUnaryF, "&l"},
658		};
659
660
661		for (Object ob : stmts) {
662			String code = (String) (((Object[]) ob)[0]);
663			CodeStyle style = (CodeStyle) (((Object[]) ob)[1]);
664			String expected = (String) (((Object[]) ob)[2]);
665			AST t = statement(code);
666			Formatter f = new Formatter(style);
667			f.visit(t);
668			String result = f.getString();
669			assertEquals(expected, result);
670		}
671	}
672}