KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > google > gwt > dev > jjs > impl > ToStringGenerationVisitor


1 /*
2  * Copyright 2007 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */

16 package com.google.gwt.dev.jjs.impl;
17
18 import com.google.gwt.dev.jjs.ast.CanBeAbstract;
19 import com.google.gwt.dev.jjs.ast.CanBeFinal;
20 import com.google.gwt.dev.jjs.ast.CanBeNative;
21 import com.google.gwt.dev.jjs.ast.CanBeStatic;
22 import com.google.gwt.dev.jjs.ast.Context;
23 import com.google.gwt.dev.jjs.ast.HasName;
24 import com.google.gwt.dev.jjs.ast.HasType;
25 import com.google.gwt.dev.jjs.ast.JAbsentArrayDimension;
26 import com.google.gwt.dev.jjs.ast.JArrayRef;
27 import com.google.gwt.dev.jjs.ast.JArrayType;
28 import com.google.gwt.dev.jjs.ast.JAssertStatement;
29 import com.google.gwt.dev.jjs.ast.JBinaryOperation;
30 import com.google.gwt.dev.jjs.ast.JBlock;
31 import com.google.gwt.dev.jjs.ast.JBooleanLiteral;
32 import com.google.gwt.dev.jjs.ast.JBreakStatement;
33 import com.google.gwt.dev.jjs.ast.JCaseStatement;
34 import com.google.gwt.dev.jjs.ast.JCastOperation;
35 import com.google.gwt.dev.jjs.ast.JCharLiteral;
36 import com.google.gwt.dev.jjs.ast.JClassLiteral;
37 import com.google.gwt.dev.jjs.ast.JClassType;
38 import com.google.gwt.dev.jjs.ast.JConditional;
39 import com.google.gwt.dev.jjs.ast.JContinueStatement;
40 import com.google.gwt.dev.jjs.ast.JDoStatement;
41 import com.google.gwt.dev.jjs.ast.JDoubleLiteral;
42 import com.google.gwt.dev.jjs.ast.JExpression;
43 import com.google.gwt.dev.jjs.ast.JExpressionStatement;
44 import com.google.gwt.dev.jjs.ast.JField;
45 import com.google.gwt.dev.jjs.ast.JFieldRef;
46 import com.google.gwt.dev.jjs.ast.JFloatLiteral;
47 import com.google.gwt.dev.jjs.ast.JForStatement;
48 import com.google.gwt.dev.jjs.ast.JIfStatement;
49 import com.google.gwt.dev.jjs.ast.JInstanceOf;
50 import com.google.gwt.dev.jjs.ast.JIntLiteral;
51 import com.google.gwt.dev.jjs.ast.JInterfaceType;
52 import com.google.gwt.dev.jjs.ast.JLabel;
53 import com.google.gwt.dev.jjs.ast.JLabeledStatement;
54 import com.google.gwt.dev.jjs.ast.JLocal;
55 import com.google.gwt.dev.jjs.ast.JLocalDeclarationStatement;
56 import com.google.gwt.dev.jjs.ast.JLocalRef;
57 import com.google.gwt.dev.jjs.ast.JLongLiteral;
58 import com.google.gwt.dev.jjs.ast.JMethod;
59 import com.google.gwt.dev.jjs.ast.JMethodCall;
60 import com.google.gwt.dev.jjs.ast.JNewArray;
61 import com.google.gwt.dev.jjs.ast.JNewInstance;
62 import com.google.gwt.dev.jjs.ast.JNode;
63 import com.google.gwt.dev.jjs.ast.JNullLiteral;
64 import com.google.gwt.dev.jjs.ast.JNullType;
65 import com.google.gwt.dev.jjs.ast.JParameter;
66 import com.google.gwt.dev.jjs.ast.JParameterRef;
67 import com.google.gwt.dev.jjs.ast.JPostfixOperation;
68 import com.google.gwt.dev.jjs.ast.JPrefixOperation;
69 import com.google.gwt.dev.jjs.ast.JPrimitiveType;
70 import com.google.gwt.dev.jjs.ast.JProgram;
71 import com.google.gwt.dev.jjs.ast.JReferenceType;
72 import com.google.gwt.dev.jjs.ast.JReturnStatement;
73 import com.google.gwt.dev.jjs.ast.JStatement;
74 import com.google.gwt.dev.jjs.ast.JStringLiteral;
75 import com.google.gwt.dev.jjs.ast.JSwitchStatement;
76 import com.google.gwt.dev.jjs.ast.JThisRef;
77 import com.google.gwt.dev.jjs.ast.JThrowStatement;
78 import com.google.gwt.dev.jjs.ast.JTryStatement;
79 import com.google.gwt.dev.jjs.ast.JType;
80 import com.google.gwt.dev.jjs.ast.JWhileStatement;
81 import com.google.gwt.dev.jjs.ast.js.JMultiExpression;
82 import com.google.gwt.dev.jjs.ast.js.JsniFieldRef;
83 import com.google.gwt.dev.jjs.ast.js.JsniMethod;
84 import com.google.gwt.dev.jjs.ast.js.JsniMethodRef;
85 import com.google.gwt.dev.jjs.ast.js.JsonArray;
86 import com.google.gwt.dev.jjs.ast.js.JsonObject;
87 import com.google.gwt.dev.jjs.ast.js.JsonObject.JsonPropInit;
88 import com.google.gwt.dev.util.TextOutput;
89
90 import java.util.Iterator JavaDoc;
91
92 /**
93  * Implements a reasonable toString() for all JNodes. The goal is to print a
94  * recognizable declaration for large constructs (classes, methods) for easy use
95  * in a debugger. Expressions and Statements should look like Java code
96  * fragments.
97  */

98 public class ToStringGenerationVisitor extends TextOutputVisitor {
99
100   protected static final char[] CHARS_ABSTRACT = "abstract ".toCharArray();
101   protected static final char[] CHARS_ASSERT = "assert ".toCharArray();
102   protected static final char[] CHARS_BREAK = "break".toCharArray();
103   protected static final char[] CHARS_CASE = "case ".toCharArray();
104   protected static final char[] CHARS_CATCH = " catch ".toCharArray();
105   protected static final char[] CHARS_CLASS = "class ".toCharArray();
106   protected static final char[] CHARS_COMMA = ", ".toCharArray();
107   protected static final char[] CHARS_CONTINUE = "continue".toCharArray();
108   protected static final char[] CHARS_DEFAULT = "default".toCharArray();
109   protected static final char[] CHARS_DO = "do".toCharArray();
110   protected static final char[] CHARS_DOTCLASS = ".class".toCharArray();
111   protected static final char[] CHARS_ELSE = "else".toCharArray();
112   protected static final char[] CHARS_EMPTYDIMS = "[]".toCharArray();
113   protected static final char[] CHARS_EXTENDS = "extends ".toCharArray();
114   protected static final char[] CHARS_FALSE = "false".toCharArray();
115   protected static final char[] CHARS_FINAL = "final ".toCharArray();
116   protected static final char[] CHARS_FINALLY = " finally ".toCharArray();
117   protected static final char[] CHARS_FOR = "for ".toCharArray();
118   protected static final char[] CHARS_IF = "if ".toCharArray();
119   protected static final char[] CHARS_IMPLEMENTS = "implements ".toCharArray();
120   protected static final char[] CHARS_INSTANCEOF = " instanceof ".toCharArray();
121   protected static final char[] CHARS_INTERFACE = "interface ".toCharArray();
122   protected static final char[] CHARS_NATIVE = "native ".toCharArray();
123   protected static final char[] CHARS_NEW = "new ".toCharArray();
124   protected static final char[] CHARS_NULL = "null".toCharArray();
125   protected static final char[] CHARS_PRIVATE = "private ".toCharArray();
126   protected static final char[] CHARS_PROTECTED = "protected ".toCharArray();
127   protected static final char[] CHARS_PUBLIC = "public ".toCharArray();
128   protected static final char[] CHARS_RETURN = "return".toCharArray();
129   protected static final char[] CHARS_SLASHSTAR = "/*".toCharArray();
130   protected static final char[] CHARS_STARSLASH = "*/".toCharArray();
131   protected static final char[] CHARS_STATIC = "static ".toCharArray();
132   protected static final char[] CHARS_SUPER = "super".toCharArray();
133   protected static final char[] CHARS_SWITCH = "switch ".toCharArray();
134   protected static final char[] CHARS_THIS = "this".toCharArray();
135   protected static final char[] CHARS_THROW = "throw".toCharArray();
136   protected static final char[] CHARS_THROWS = " throws ".toCharArray();
137   protected static final char[] CHARS_TRUE = "true".toCharArray();
138   protected static final char[] CHARS_TRY = "try ".toCharArray();
139   protected static final char[] CHARS_WHILE = "while ".toCharArray();
140
141   private boolean needSemi = true;
142
143   private boolean suppressType = false;
144
145   public ToStringGenerationVisitor(TextOutput textOutput) {
146     super(textOutput);
147   }
148
149   // @Override
150
public boolean visit(JAbsentArrayDimension x, Context ctx) {
151     // nothing to print, parent prints []
152
return false;
153   }
154
155   // @Override
156
public boolean visit(JArrayRef x, Context ctx) {
157     JExpression instance = x.getInstance();
158     parenPush(x, instance);
159     accept(instance);
160     parenPop(x, instance);
161     print('[');
162     accept(x.getIndexExpr());
163     print(']');
164     return false;
165   }
166
167   // @Override
168
public boolean visit(JArrayType x, Context ctx) {
169     accept(x.getLeafType());
170     for (int i = 0, c = x.getDims(); i < c; ++i) {
171       print("[]");
172     }
173     return false;
174   }
175
176   // @Override
177
public boolean visit(JAssertStatement x, Context ctx) {
178     print(CHARS_ASSERT);
179     accept(x.getTestExpr());
180     if (x.getArg() != null) {
181       print(" : ");
182       accept(x.getArg());
183     }
184     return false;
185   }
186
187   // @Override
188
public boolean visit(JBinaryOperation x, Context ctx) {
189     // TODO(later): associativity
190
JExpression arg1 = x.getLhs();
191     parenPush(x, arg1);
192     accept(arg1);
193     parenPop(x, arg1);
194
195     space();
196     print(x.getOp().getSymbol());
197     space();
198
199     JExpression arg2 = x.getRhs();
200     parenPush(x, arg2);
201     accept(arg2);
202     parenPop(x, arg2);
203
204     return false;
205   }
206
207   // @Override
208
public boolean visit(JBlock x, Context ctx) {
209     openBlock();
210     for (int i = 0; i < x.statements.size(); ++i) {
211       JStatement statement = (JStatement) x.statements.get(i);
212       needSemi = true;
213       accept(statement);
214       if (needSemi) {
215         semi();
216       }
217       newline();
218     }
219     closeBlock();
220     needSemi = false;
221     return false;
222   }
223
224   // @Override
225
public boolean visit(JBooleanLiteral x, Context ctx) {
226     printBooleanLiteral(x.getValue());
227     return false;
228   }
229
230   // @Override
231
public boolean visit(JBreakStatement x, Context ctx) {
232     print(CHARS_BREAK);
233     if (x.getLabel() != null) {
234       space();
235       accept(x.getLabel());
236     }
237     return false;
238   }
239
240   // @Override
241
public boolean visit(JCaseStatement x, Context ctx) {
242     if (x.getExpr() != null) {
243       print(CHARS_CASE);
244       accept(x.getExpr());
245     } else {
246       print(CHARS_DEFAULT);
247     }
248     print(':');
249     space();
250     needSemi = false;
251     return false;
252   }
253
254   // @Override
255
public boolean visit(JCastOperation x, Context ctx) {
256     lparen();
257     printType(x);
258     rparen();
259     space();
260
261     JExpression expr = x.getExpr();
262     parenPush(x, expr);
263     accept(expr);
264     parenPop(x, expr);
265     return false;
266   }
267
268   // @Override
269
public boolean visit(JCharLiteral x, Context ctx) {
270     printCharLiteral(x.getValue());
271     return false;
272   }
273
274   // @Override
275
public boolean visit(JClassLiteral x, Context ctx) {
276     printTypeName(x.getRefType());
277     print(CHARS_DOTCLASS);
278     return false;
279   }
280
281   // @Override
282
public boolean visit(JClassType x, Context ctx) {
283     printAbstractFlag(x);
284     printFinalFlag(x);
285     print(CHARS_CLASS);
286     printTypeName(x);
287     space();
288     if (x.extnds != null) {
289       print(CHARS_EXTENDS);
290       printTypeName(x.extnds);
291       space();
292     }
293
294     if (x.implments.size() > 0) {
295       print(CHARS_IMPLEMENTS);
296       for (int i = 0, c = x.implments.size(); i < c; ++i) {
297         if (i > 0) {
298           print(CHARS_COMMA);
299         }
300         printTypeName((JType) x.implments.get(i));
301       }
302       space();
303     }
304
305     return false;
306   }
307
308   // @Override
309
public boolean visit(JConditional x, Context ctx) {
310     // TODO(later): associativity
311
JExpression ifTest = x.getIfTest();
312     parenPush(x, ifTest);
313     accept(ifTest);
314     parenPop(x, ifTest);
315
316     print(" ? ");
317
318     JExpression thenExpr = x.getThenExpr();
319     parenPush(x, thenExpr);
320     accept(thenExpr);
321     parenPop(x, thenExpr);
322
323     print(" : ");
324
325     JExpression elseExpr = x.getElseExpr();
326     parenPush(x, elseExpr);
327     accept(elseExpr);
328     parenPop(x, elseExpr);
329
330     return false;
331   }
332
333   // @Override
334
public boolean visit(JContinueStatement x, Context ctx) {
335     print(CHARS_CONTINUE);
336     if (x.getLabel() != null) {
337       space();
338       accept(x.getLabel());
339     }
340     return false;
341   }
342
343   // @Override
344
public boolean visit(JDoStatement x, Context ctx) {
345     print(CHARS_DO);
346     if (x.getBody() != null) {
347       nestedStatementPush(x.getBody());
348       accept(x.getBody());
349       nestedStatementPop(x.getBody());
350     }
351     if (needSemi) {
352       semi();
353       newline();
354     } else {
355       space();
356       needSemi = true;
357     }
358     print(CHARS_WHILE);
359     lparen();
360     accept(x.getTestExpr());
361     rparen();
362     return false;
363   }
364
365   // @Override
366
public boolean visit(JDoubleLiteral x, Context ctx) {
367     printDoubleLiteral(x.getValue());
368     return false;
369   }
370
371   // @Override
372
public boolean visit(JExpressionStatement x, Context ctx) {
373     accept(x.getExpr());
374     return false;
375   }
376
377   // @Override
378
public boolean visit(JField x, Context ctx) {
379     // Due to our wacky construction model, only constant fields may be final
380
// when generating source
381
if (x.constInitializer != null) {
382       printFinalFlag(x);
383     } else {
384       printMemberFinalFlag(x);
385     }
386
387     printStaticFlag(x);
388     printType(x);
389     space();
390     printUniqueName(x);
391     return false;
392   }
393
394   // @Override
395
public boolean visit(JFieldRef x, Context ctx) {
396     JExpression instance = x.getInstance();
397     if (instance != null) {
398       parenPush(x, instance);
399       accept(instance);
400       parenPop(x, instance);
401     } else {
402       printTypeName(x.getField().getEnclosingType());
403     }
404     print('.');
405     printUniqueName(x.getField());
406     return false;
407   }
408
409   // @Override
410
public boolean visit(JFloatLiteral x, Context ctx) {
411     printFloatLiteral(x.getValue());
412     return false;
413   }
414
415   // @Override
416
public boolean visit(JForStatement x, Context ctx) {
417     print(CHARS_FOR);
418     lparen();
419
420     Iterator JavaDoc/* <JStatement> */iter = x.getInitializers().iterator();
421     if (iter.hasNext()) {
422       JStatement stmt = (JStatement) iter.next();
423       accept(stmt);
424     }
425     suppressType = true;
426     while (iter.hasNext()) {
427       print(CHARS_COMMA);
428       JStatement stmt = (JStatement) iter.next();
429       accept(stmt);
430     }
431     suppressType = false;
432
433     semi();
434     space();
435     if (x.getTestExpr() != null) {
436       accept(x.getTestExpr());
437     }
438
439     semi();
440     space();
441     visitCollectionWithCommas(x.getIncrements().iterator());
442     rparen();
443
444     if (x.getBody() != null) {
445       nestedStatementPush(x.getBody());
446       accept(x.getBody());
447       nestedStatementPop(x.getBody());
448     }
449     return false;
450   }
451
452   // @Override
453
public boolean visit(JIfStatement x, Context ctx) {
454     print(CHARS_IF);
455     lparen();
456     accept(x.getIfExpr());
457     rparen();
458
459     if (x.getThenStmt() != null) {
460       nestedStatementPush(x.getThenStmt());
461       accept(x.getThenStmt());
462       nestedStatementPop(x.getThenStmt());
463     }
464
465     if (x.getElseStmt() != null) {
466       if (needSemi) {
467         semi();
468         newline();
469       } else {
470         space();
471         needSemi = true;
472       }
473       print(CHARS_ELSE);
474       boolean elseIf = x.getElseStmt() instanceof JIfStatement;
475       if (!elseIf) {
476         nestedStatementPush(x.getElseStmt());
477       } else {
478         space();
479       }
480       accept(x.getElseStmt());
481       if (!elseIf) {
482         nestedStatementPop(x.getElseStmt());
483       }
484     }
485
486     return false;
487   }
488
489   // @Override
490
public boolean visit(JInstanceOf x, Context ctx) {
491     JExpression expr = x.getExpr();
492     parenPush(x, expr);
493     accept(expr);
494     parenPop(x, expr);
495     print(CHARS_INSTANCEOF);
496     printTypeName(x.getTestType());
497     return false;
498   }
499
500   // @Override
501
public boolean visit(JInterfaceType x, Context ctx) {
502     print(CHARS_INTERFACE);
503     printTypeName(x);
504     space();
505
506     if (x.implments.size() > 0) {
507       print(CHARS_EXTENDS);
508       for (int i = 0, c = x.implments.size(); i < c; ++i) {
509         if (i > 0) {
510           print(CHARS_COMMA);
511         }
512         printTypeName((JType) x.implments.get(i));
513       }
514       space();
515     }
516
517     return false;
518   }
519
520   // @Override
521
public boolean visit(JIntLiteral x, Context ctx) {
522     print(Integer.toString(x.getValue()).toCharArray());
523     return false;
524   }
525
526   // @Override
527
public boolean visit(JLabel x, Context ctx) {
528     printName(x);
529     return false;
530   }
531
532   // @Override
533
public boolean visit(JLabeledStatement x, Context ctx) {
534     accept(x.getLabel());
535     print(" : ");
536     accept(x.getBody());
537     return false;
538   }
539
540   // @Override
541
public boolean visit(JLocal x, Context ctx) {
542     printFinalFlag(x);
543     printType(x);
544     space();
545     printName(x);
546     return false;
547   }
548
549   // @Override
550
public boolean visit(JLocalDeclarationStatement x, Context ctx) {
551     if (!suppressType) {
552       accept(x.getLocalRef().getTarget());
553     } else {
554       accept(x.getLocalRef());
555     }
556     JExpression initializer = x.getInitializer();
557     if (initializer != null) {
558       print(" = ");
559       accept(initializer);
560     }
561     return false;
562   }
563
564   // @Override
565
public boolean visit(JLocalRef x, Context ctx) {
566     printName(x.getLocal());
567     return false;
568   }
569
570   // @Override
571
public boolean visit(JLongLiteral x, Context ctx) {
572     printLongLiteral(x.getValue());
573     return false;
574   }
575
576   // @Override
577
public boolean visit(JMethod x, Context ctx) {
578     return printMethodHeader(x);
579   }
580
581   // @Override
582
public boolean visit(JMethodCall x, Context ctx) {
583     JExpression instance = x.getInstance();
584     JMethod target = x.getTarget();
585     if (instance != null) {
586       parenPush(x, instance);
587       accept(instance);
588       parenPop(x, instance);
589     } else {
590       printTypeName(target.getEnclosingType());
591     }
592     print('.');
593     if (target.isStatic()) {
594       printUniqueName(target);
595     } else {
596       printName(target);
597     }
598     lparen();
599     visitCollectionWithCommas(x.getArgs().iterator());
600     rparen();
601     return false;
602   }
603
604   // @Override
605
public boolean visit(JMultiExpression x, Context ctx) {
606     lparen();
607     visitCollectionWithCommas(x.exprs.iterator());
608     rparen();
609     return false;
610   }
611
612   // @Override
613
public boolean visit(JNewArray x, Context ctx) {
614     print(CHARS_NEW);
615     printTypeName(x.getArrayType().getLeafType());
616     if (x.initializers != null) {
617       print('{');
618       visitCollectionWithCommas(x.initializers.iterator());
619       print('}');
620     } else {
621       for (int i = 0; i < x.dims.size(); ++i) {
622         JExpression expr = (JExpression) x.dims.get(i);
623         print('[');
624         accept(expr);
625         print(']');
626       }
627     }
628     return false;
629   }
630
631   // @Override
632
public boolean visit(JNewInstance x, Context ctx) {
633     print(CHARS_NEW);
634     printType(x);
635     lparen();
636     rparen();
637     return false;
638   }
639
640   // @Override
641
public boolean visit(JNullLiteral x, Context ctx) {
642     print(CHARS_NULL);
643     return false;
644   }
645
646   // @Override
647
public boolean visit(JNullType x, Context ctx) {
648     printTypeName(x);
649     return false;
650   }
651
652   // @Override
653
public boolean visit(JParameter x, Context ctx) {
654     printType(x);
655     space();
656     printName(x);
657     return false;
658   }
659
660   // @Override
661
public boolean visit(JParameterRef x, Context ctx) {
662     printName(x.getTarget());
663     return false;
664   }
665
666   // @Override
667
public boolean visit(JPostfixOperation x, Context ctx) {
668     // TODO(later): associativity
669
JExpression arg = x.getArg();
670     parenPush(x, arg);
671     accept(arg);
672     parenPop(x, arg);
673     print(x.getOp().getSymbol());
674     return false;
675   }
676
677   // @Override
678
public boolean visit(JPrefixOperation x, Context ctx) {
679     // TODO(later): associativity
680
print(x.getOp().getSymbol());
681     JExpression arg = x.getArg();
682     parenPush(x, arg);
683     accept(arg);
684     parenPop(x, arg);
685     return false;
686   }
687
688   // @Override
689
public boolean visit(JPrimitiveType x, Context ctx) {
690     printTypeName(x);
691     return false;
692   }
693
694   // @Override
695
public boolean visit(JProgram x, Context ctx) {
696     print("<JProgram>");
697     return false;
698   }
699
700   // @Override
701
public boolean visit(JReturnStatement x, Context ctx) {
702     print(CHARS_RETURN);
703     if (x.getExpr() != null) {
704       space();
705       accept(x.getExpr());
706     }
707     return false;
708   }
709
710   // @Override
711
public boolean visit(JsniFieldRef x, Context ctx) {
712     return visit(x.getField(), ctx);
713   }
714
715   // @Override
716
public boolean visit(JsniMethod x, Context ctx) {
717     return printMethodHeader(x);
718   }
719
720   // @Override
721
public boolean visit(JsniMethodRef x, Context ctx) {
722     return printMethodHeader(x.getTarget());
723   }
724
725   // @Override
726
public boolean visit(JsonArray x, Context ctx) {
727     print('[');
728     visitCollectionWithCommas(x.exprs.iterator());
729     print(']');
730     return false;
731   }
732
733   // @Override
734
public boolean visit(JsonObject x, Context ctx) {
735     print('{');
736     visitCollectionWithCommas(x.propInits.iterator());
737     print('}');
738     return false;
739   }
740
741   // @Override
742
public boolean visit(JsonPropInit x, Context ctx) {
743     accept(x.labelExpr);
744     print(':');
745     accept(x.valueExpr);
746     return false;
747   }
748
749   // @Override
750
public boolean visit(JStringLiteral x, Context ctx) {
751     printStringLiteral(x.getValue());
752     return false;
753   }
754
755   // @Override
756
public boolean visit(JSwitchStatement x, Context ctx) {
757     print(CHARS_SWITCH);
758     lparen();
759     accept(x.getExpr());
760     rparen();
761     space();
762     nestedStatementPush(x.getBody());
763     accept(x.getBody());
764     nestedStatementPop(x.getBody());
765     return false;
766   }
767
768   // @Override
769
public boolean visit(JThisRef x, Context ctx) {
770     print(CHARS_THIS);
771     return false;
772   }
773
774   // @Override
775
public boolean visit(JThrowStatement x, Context ctx) {
776     print(CHARS_THROW);
777     if (x.getExpr() != null) {
778       space();
779       accept(x.getExpr());
780     }
781     return false;
782   }
783
784   // @Override
785
public boolean visit(JTryStatement x, Context ctx) {
786     print(CHARS_TRY);
787     accept(x.getTryBlock());
788     for (int i = 0, c = x.getCatchArgs().size(); i < c; ++i) {
789       print(CHARS_CATCH);
790       lparen();
791       JLocalRef localRef = (JLocalRef) x.getCatchArgs().get(i);
792       accept(localRef.getTarget());
793       rparen();
794       space();
795       JBlock block = (JBlock) x.getCatchBlocks().get(i);
796       accept(block);
797     }
798     if (x.getFinallyBlock() != null) {
799       print(CHARS_FINALLY);
800       accept(x.getFinallyBlock());
801     }
802     return false;
803   }
804
805   // @Override
806
public boolean visit(JWhileStatement x, Context ctx) {
807     print(CHARS_WHILE);
808     lparen();
809     accept(x.getTestExpr());
810     rparen();
811     if (x.getBody() != null) {
812       nestedStatementPush(x.getBody());
813       accept(x.getBody());
814       nestedStatementPop(x.getBody());
815     }
816     return false;
817   }
818
819   protected void closeBlock() {
820     indentOut();
821     print('}');
822   }
823
824   protected void lparen() {
825     print('(');
826   }
827
828   protected boolean nestedStatementPop(JStatement statement) {
829     boolean pop = !(statement instanceof JBlock);
830     if (pop) {
831       indentOut();
832     }
833     return pop;
834   }
835
836   protected boolean nestedStatementPush(JStatement statement) {
837     boolean push = !(statement instanceof JBlock);
838     if (push) {
839       indentIn();
840       newline();
841     } else {
842       space();
843     }
844     return push;
845   }
846
847   protected void openBlock() {
848     print('{');
849     indentIn();
850     newline();
851   }
852
853   protected boolean parenPop(int parentPrec, JExpression child) {
854     int childPrec = JavaPrecedenceVisitor.exec(child);
855     if (parentPrec < childPrec) {
856       rparen();
857       return true;
858     } else {
859       return false;
860     }
861   }
862
863   protected boolean parenPop(JExpression parent, JExpression child) {
864     return parenPop(JavaPrecedenceVisitor.exec(parent), child);
865   }
866
867   protected boolean parenPush(int parentPrec, JExpression child) {
868     int childPrec = JavaPrecedenceVisitor.exec(child);
869     if (parentPrec < childPrec) {
870       lparen();
871       return true;
872     } else {
873       return false;
874     }
875   }
876
877   protected boolean parenPush(JExpression parent, JExpression child) {
878     return parenPush(JavaPrecedenceVisitor.exec(parent), child);
879   }
880
881   protected void printAbstractFlag(CanBeAbstract x) {
882     if (x.isAbstract()) {
883       print(CHARS_ABSTRACT);
884     }
885   }
886
887   protected void printBooleanLiteral(boolean value) {
888     print(value ? CHARS_TRUE : CHARS_FALSE);
889   }
890
891   protected void printChar(char c) {
892     switch (c) {
893       case '\b':
894         print("\\b");
895         break;
896       case '\t':
897         print("\\t");
898         break;
899       case '\n':
900         print("\\n");
901         break;
902       case '\f':
903         print("\\f");
904         break;
905       case '\r':
906         print("\\r");
907         break;
908       case '\"':
909         print("\\\"");
910         break;
911       case '\'':
912         print("\\'");
913         break;
914       case '\\':
915         print("\\\\");
916         break;
917       default:
918         if (Character.isISOControl(c)) {
919           print("\\u");
920           if (c < 0x1000) {
921             print('0');
922           }
923
924           if (c < 0x100) {
925             print('0');
926           }
927
928           if (c < 0x10) {
929             print('0');
930           }
931           print(Integer.toHexString(c));
932         } else {
933           print(c);
934         }
935     }
936   }
937
938   protected void printCharLiteral(char value) {
939     print('\'');
940     printChar(value);
941     print('\'');
942   }
943
944   protected void printDoubleLiteral(double value) {
945     print(Double.toString(value));
946   }
947
948   protected void printFinalFlag(CanBeFinal x) {
949     if (x.isFinal()) {
950       print(CHARS_FINAL);
951     }
952   }
953
954   protected void printFloatLiteral(float value) {
955     print(Float.toString(value));
956     print('f');
957   }
958
959   protected void printLongLiteral(long value) {
960     print(Long.toString(value));
961     print('L');
962   }
963
964   protected void printMemberFinalFlag(CanBeFinal x) {
965     if (x.isFinal()) {
966       print(CHARS_FINAL);
967     }
968   }
969
970   protected boolean printMethodHeader(JMethod x) {
971     // Modifiers
972
if (x.isPrivate()) {
973       print(CHARS_PRIVATE);
974     } else {
975       print(CHARS_PUBLIC);
976     }
977     printStaticFlag(x);
978     printAbstractFlag(x);
979     printNativeFlag(x);
980     printMemberFinalFlag(x);
981     printType(x);
982     space();
983     if (x.isStatic()) {
984       printUniqueName(x);
985     } else {
986       printName(x);
987     }
988
989     // Parameters
990
printParameterList(x);
991
992     if (x.thrownExceptions.size() > 0) {
993       print(CHARS_THROWS);
994       Iterator JavaDoc/* <JClassType> */iter = x.thrownExceptions.iterator();
995       if (iter.hasNext()) {
996         printTypeName((JType) iter.next());
997       }
998       while (iter.hasNext()) {
999         print(CHARS_COMMA);
1000        printTypeName((JType) iter.next());
1001      }
1002    }
1003    return false;
1004  }
1005
1006  protected void printName(HasName x) {
1007    print(x.getName());
1008  }
1009
1010  protected void printNativeFlag(CanBeNative x) {
1011    if (x.isNative()) {
1012      print(CHARS_NATIVE);
1013    }
1014  }
1015
1016  protected void printParameterList(JMethod x) {
1017    lparen();
1018    visitCollectionWithCommas(x.params.iterator());
1019    rparen();
1020  }
1021
1022  protected void printStaticFlag(CanBeStatic x) {
1023    if (x.isStatic()) {
1024      print(CHARS_STATIC);
1025    }
1026  }
1027
1028  protected void printStringLiteral(String JavaDoc string) {
1029    char[] s = string.toCharArray();
1030    print('\"');
1031    for (int i = 0; i < s.length; ++i) {
1032      printChar(s[i]);
1033    }
1034    print('\"');
1035  }
1036
1037  protected void printType(HasType hasType) {
1038    printTypeName(hasType.getType());
1039  }
1040
1041  protected void printTypeName(JType type) {
1042    if (type instanceof JReferenceType) {
1043      print(((JReferenceType) type).getShortName());
1044    } else {
1045      print(type.getName());
1046    }
1047  }
1048
1049  protected void rparen() {
1050    print(')');
1051  }
1052
1053  protected void semi() {
1054    print(';');
1055  }
1056
1057  protected void space() {
1058    print(' ');
1059  }
1060
1061  protected void visitCollectionWithCommas(Iterator JavaDoc/* <? extends JNode> */iter) {
1062    if (iter.hasNext()) {
1063      JNode node = (JNode) iter.next();
1064      accept(node);
1065    }
1066    while (iter.hasNext()) {
1067      print(CHARS_COMMA);
1068      JNode node = (JNode) iter.next();
1069      accept(node);
1070    }
1071  }
1072
1073  private void printUniqueName(HasName x) {
1074    print(x.getName());
1075  }
1076
1077}
1078
Popular Tags