001: /*
002: * Janino - An embedded Java[TM] compiler
003: *
004: * Copyright (c) 2001-2007, Arno Unkrig
005: * All rights reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: * 2. Redistributions in binary form must reproduce the above
014: * copyright notice, this list of conditions and the following
015: * disclaimer in the documentation and/or other materials
016: * provided with the distribution.
017: * 3. The name of the author may not be used to endorse or promote
018: * products derived from this software without specific prior
019: * written permission.
020: *
021: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
022: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
023: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
024: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
025: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
026: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
027: * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
028: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
029: * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
030: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
031: * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
032: */
033:
034: package org.codehaus.janino;
035:
036: import java.io.*;
037: import java.util.*;
038:
039: import org.codehaus.janino.Java.CompilationUnit.*;
040: import org.codehaus.janino.util.AutoIndentWriter;
041:
042: /**
043: * A visitor that unparses (un-compiles) an AST to a {@link Writer}. See
044: * {@link #main(String[])} for a usage example.
045: */
046: public class UnparseVisitor implements Visitor.ComprehensiveVisitor {
047: private final AutoIndentWriter aiw;
048: private final PrintWriter pw;
049:
050: /**
051: * Testing of parsing/unparsing.
052: * <p>
053: * Reads compilation units from the files named on the command line
054: * and unparses them to {@link System#out}.
055: */
056: public static void main(String[] args) throws Exception {
057: Writer w = new BufferedWriter(
058: new OutputStreamWriter(System.out));
059: for (int i = 0; i < args.length; ++i) {
060: String fileName = args[i];
061:
062: // Parse each compilation unit.
063: FileReader r = new FileReader(fileName);
064: Java.CompilationUnit cu;
065: try {
066: cu = new Parser(new Scanner(fileName, r))
067: .parseCompilationUnit();
068: } finally {
069: r.close();
070: }
071:
072: // Unparse each compilation unit.
073: UnparseVisitor.unparse(cu, w);
074: }
075: w.flush();
076: }
077:
078: /**
079: * Unparse the given {@link Java.CompilationUnit} to the given {@link Writer}.
080: */
081: public static void unparse(Java.CompilationUnit cu, Writer w) {
082: new UnparseVisitor(w).unparseCompilationUnit(cu);
083: }
084:
085: public UnparseVisitor(Writer w) {
086: this .aiw = new AutoIndentWriter(w);
087: this .pw = new PrintWriter(this .aiw, true);
088: }
089:
090: public void unparseCompilationUnit(Java.CompilationUnit cu) {
091: if (cu.optionalPackageDeclaration != null) {
092: this .pw.println("package "
093: + cu.optionalPackageDeclaration.packageName + ';');
094: }
095: for (Iterator it = cu.importDeclarations.iterator(); it
096: .hasNext();) {
097: ((Java.CompilationUnit.ImportDeclaration) it.next())
098: .accept(this );
099: }
100: for (Iterator it = cu.packageMemberTypeDeclarations.iterator(); it
101: .hasNext();) {
102: ((Java.PackageMemberTypeDeclaration) it.next())
103: .accept(this );
104: this .pw.println();
105: }
106: }
107:
108: public void visitSingleTypeImportDeclaration(
109: Java.CompilationUnit.SingleTypeImportDeclaration stid) {
110: this .pw.println("import " + Java.join(stid.identifiers, ".")
111: + ';');
112: }
113:
114: public void visitTypeImportOnDemandDeclaration(
115: Java.CompilationUnit.TypeImportOnDemandDeclaration tiodd) {
116: this .pw.println("import " + Java.join(tiodd.identifiers, ".")
117: + ".*;");
118: }
119:
120: public void visitSingleStaticImportDeclaration(
121: SingleStaticImportDeclaration ssid) {
122: this .pw.println("import static "
123: + Java.join(ssid.identifiers, ".") + ';');
124: }
125:
126: public void visitStaticImportOnDemandDeclaration(
127: StaticImportOnDemandDeclaration siodd) {
128: this .pw.println("import static "
129: + Java.join(siodd.identifiers, ".") + ".*;");
130: }
131:
132: public void visitLocalClassDeclaration(
133: Java.LocalClassDeclaration lcd) {
134: this .unparseNamedClassDeclaration(lcd);
135: }
136:
137: public void visitMemberClassDeclaration(
138: Java.MemberClassDeclaration mcd) {
139: this .unparseNamedClassDeclaration(mcd);
140: }
141:
142: public void visitMemberInterfaceDeclaration(
143: Java.MemberInterfaceDeclaration mid) {
144: this .unparseInterfaceDeclaration(mid);
145: }
146:
147: public void visitPackageMemberClassDeclaration(
148: Java.PackageMemberClassDeclaration pmcd) {
149: this .unparseNamedClassDeclaration(pmcd);
150: }
151:
152: public void visitPackageMemberInterfaceDeclaration(
153: Java.PackageMemberInterfaceDeclaration pmid) {
154: this .unparseInterfaceDeclaration(pmid);
155: }
156:
157: public void visitConstructorDeclarator(Java.ConstructorDeclarator cd) {
158: this .unparseDocComment(cd);
159: this .unparseModifiers(cd.modifiers);
160: Java.ClassDeclaration declaringClass = cd.getDeclaringClass();
161: this .pw
162: .print(declaringClass instanceof Java.NamedClassDeclaration ? ((Java.NamedClassDeclaration) declaringClass).name
163: : "UNNAMED");
164: this .unparseFunctionDeclaratorRest(cd);
165: this .pw.print(' ');
166: if (cd.optionalConstructorInvocation != null) {
167: this .pw.println('{');
168: ((Java.BlockStatement) cd.optionalConstructorInvocation)
169: .accept(this );
170: this .pw.println(';');
171: for (Iterator it = cd.optionalBody.statements.iterator(); it
172: .hasNext();) {
173: ((Java.BlockStatement) it.next()).accept(this );
174: this .pw.println();
175: }
176: this .pw.print('}');
177: } else {
178: cd.optionalBody.accept(this );
179: }
180: }
181:
182: public void visitMethodDeclarator(Java.MethodDeclarator md) {
183: this .unparseDocComment(md);
184: this .unparseModifiers(md.modifiers);
185: ((Java.Atom) md.type).accept(this );
186: this .pw.print(' ' + md.name);
187: this .unparseFunctionDeclaratorRest(md);
188: if (md.optionalBody != null) {
189: this .pw.print(' ');
190: md.optionalBody.accept(this );
191: } else {
192: this .pw.print(';');
193: }
194: }
195:
196: public void visitFieldDeclaration(Java.FieldDeclaration fd) {
197: this .unparseDocComment(fd);
198: this .unparseModifiers(fd.modifiers);
199: ((Java.Atom) fd.type).accept(this );
200: this .pw.print(' ');
201: for (int i = 0; i < fd.variableDeclarators.length; ++i) {
202: if (i > 0)
203: this .pw.print(", ");
204: this .unparseVariableDeclarator(fd.variableDeclarators[i]);
205: }
206: this .pw.print(';');
207: }
208:
209: public void visitInitializer(Java.Initializer i) {
210: if (i.statiC)
211: this .pw.print("static ");
212: i.block.accept(this );
213: }
214:
215: public void visitBlock(Java.Block b) {
216: this .pw.println('{');
217: for (Iterator it = b.statements.iterator(); it.hasNext();) {
218: ((Java.BlockStatement) it.next()).accept(this );
219: this .pw.println();
220: }
221: this .pw.print('}');
222: }
223:
224: public void visitBreakStatement(Java.BreakStatement bs) {
225: this .pw.print("break");
226: if (bs.optionalLabel != null)
227: this .pw.print(' ' + bs.optionalLabel);
228: this .pw.print(';');
229: }
230:
231: public void visitContinueStatement(Java.ContinueStatement cs) {
232: this .pw.print("continue");
233: if (cs.optionalLabel != null)
234: this .pw.print(' ' + cs.optionalLabel);
235: this .pw.print(';');
236: }
237:
238: public void visitDoStatement(Java.DoStatement ds) {
239: this .pw.print("do ");
240: ds.body.accept(this );
241: this .pw.print("while (");
242: ((Java.Atom) ds.condition).accept(this );
243: this .pw.print(");");
244: }
245:
246: public void visitEmptyStatement(Java.EmptyStatement es) {
247: this .pw.print(';');
248: }
249:
250: public void visitExpressionStatement(Java.ExpressionStatement es) {
251: ((Java.Atom) es.rvalue).accept(this );
252: this .pw.print(';');
253: }
254:
255: public void visitForStatement(Java.ForStatement fs) {
256: this .pw.print("for (");
257: if (fs.optionalInit != null) {
258: fs.optionalInit.accept(this );
259: } else {
260: this .pw.print(';');
261: }
262: if (fs.optionalCondition != null) {
263: this .pw.print(' ');
264: ((Java.Atom) fs.optionalCondition).accept(this );
265: }
266: this .pw.print(';');
267: if (fs.optionalUpdate != null) {
268: this .pw.print(' ');
269: for (int i = 0; i < fs.optionalUpdate.length; ++i) {
270: if (i > 0)
271: this .pw.print(", ");
272: ((Java.Atom) fs.optionalUpdate[i]).accept(this );
273: }
274: }
275: this .pw.print(") ");
276: fs.body.accept(this );
277: }
278:
279: public void visitIfStatement(Java.IfStatement is) {
280: this .pw.print("if (");
281: ((Java.Atom) is.condition).accept(this );
282: this .pw.print(") ");
283: is.thenStatement.accept(this );
284: if (is.optionalElseStatement != null) {
285: this .pw.print(" else ");
286: is.optionalElseStatement.accept(this );
287: }
288: }
289:
290: public void visitLabeledStatement(Java.LabeledStatement ls) {
291: this .pw.println(ls.label + ':');
292: ls.body.accept(this );
293: }
294:
295: public void visitLocalClassDeclarationStatement(
296: Java.LocalClassDeclarationStatement lcds) {
297: lcds.lcd.accept(this );
298: }
299:
300: public void visitLocalVariableDeclarationStatement(
301: Java.LocalVariableDeclarationStatement lvds) {
302: this .unparseModifiers(lvds.modifiers);
303: ((Java.Atom) lvds.type).accept(this );
304: this .pw.print(' ');
305: this .unparseVariableDeclarator(lvds.variableDeclarators[0]);
306: for (int i = 1; i < lvds.variableDeclarators.length; ++i) {
307: this .pw.print(", ");
308: this .unparseVariableDeclarator(lvds.variableDeclarators[i]);
309: }
310: this .pw.print(';');
311: }
312:
313: public void visitReturnStatement(Java.ReturnStatement rs) {
314: this .pw.print("return");
315: if (rs.optionalReturnValue != null) {
316: this .pw.print(' ');
317: ((Java.Atom) rs.optionalReturnValue).accept(this );
318: }
319: this .pw.print(';');
320: }
321:
322: public void visitSwitchStatement(Java.SwitchStatement ss) {
323: this .pw.println("switch (" + ss.condition + ") {");
324: for (Iterator it = ss.sbsgs.iterator(); it.hasNext();) {
325: Java.SwitchStatement.SwitchBlockStatementGroup sbgs = (Java.SwitchStatement.SwitchBlockStatementGroup) it
326: .next();
327: this .aiw.unindent();
328: try {
329: for (Iterator it2 = sbgs.caseLabels.iterator(); it2
330: .hasNext();) {
331: Java.Rvalue rv = (Java.Rvalue) it2.next();
332: this .pw.print("case ");
333: ((Java.Atom) rv).accept(this );
334: this .pw.println(':');
335: }
336: if (sbgs.hasDefaultLabel)
337: this .pw.println("default:");
338: } finally {
339: this .aiw.indent();
340: }
341: for (Iterator it2 = sbgs.blockStatements.iterator(); it2
342: .hasNext();) {
343: ((Java.BlockStatement) it2.next()).accept(this );
344: this .pw.println();
345: }
346: }
347: this .pw.print('}');
348: }
349:
350: public void visitSynchronizedStatement(Java.SynchronizedStatement ss) {
351: this .pw.print("synchronized (");
352: ((Java.Atom) ss.expression).accept(this );
353: this .pw.print(") ");
354: ss.body.accept(this );
355: }
356:
357: public void visitThrowStatement(Java.ThrowStatement ts) {
358: this .pw.print("throw ");
359: ((Java.Atom) ts.expression).accept(this );
360: this .pw.print(';');
361: }
362:
363: public void visitTryStatement(Java.TryStatement ts) {
364: this .pw.print("try ");
365: ts.body.accept(this );
366: for (Iterator it = ts.catchClauses.iterator(); it.hasNext();) {
367: Java.CatchClause cc = (Java.CatchClause) it.next();
368: this .pw.print(" catch (");
369: this .unparseFormalParameter(cc.caughtException);
370: this .pw.print(") ");
371: cc.body.accept(this );
372: }
373: if (ts.optionalFinally != null) {
374: this .pw.print(" finally ");
375: ts.optionalFinally.accept(this );
376: }
377: }
378:
379: public void visitWhileStatement(Java.WhileStatement ws) {
380: this .pw.print("while (");
381: ((Java.Atom) ws.condition).accept(this );
382: this .pw.print(") ");
383: ws.body.accept(this );
384: }
385:
386: public void unparseVariableDeclarator(Java.VariableDeclarator vd) {
387: this .pw.print(vd.name);
388: for (int i = 0; i < vd.brackets; ++i)
389: this .pw.print("[]");
390: if (vd.optionalInitializer != null) {
391: this .pw.print(" = ");
392: this
393: .unparseArrayInitializerOrRvalue(vd.optionalInitializer);
394: }
395: }
396:
397: public void unparseFormalParameter(
398: Java.FunctionDeclarator.FormalParameter fp) {
399: if (fp.finaL)
400: this .pw.print("final ");
401: ((Java.Atom) fp.type).accept(this );
402: this .pw.print(' ' + fp.name);
403: }
404:
405: public void visitMethodInvocation(Java.MethodInvocation mi) {
406: if (mi.optionalTarget != null) {
407: mi.optionalTarget.accept(this );
408: this .pw.print('.');
409: }
410: this .pw.print(mi.methodName);
411: this .unparseFunctionInvocationArguments(mi.arguments);
412: }
413:
414: public void visitAlternateConstructorInvocation(
415: Java.AlternateConstructorInvocation aci) {
416: this .pw.print("this");
417: this .unparseFunctionInvocationArguments(aci.arguments);
418: }
419:
420: public void visitSuperConstructorInvocation(
421: Java.SuperConstructorInvocation sci) {
422: if (sci.optionalQualification != null) {
423: ((Java.Atom) sci.optionalQualification).accept(this );
424: this .pw.print('.');
425: }
426: this .pw.print("super");
427: this .unparseFunctionInvocationArguments(sci.arguments);
428: }
429:
430: public void visitNewClassInstance(Java.NewClassInstance nci) {
431: if (nci.optionalQualification != null) {
432: ((Java.Atom) nci.optionalQualification).accept(this );
433: this .pw.print('.');
434: }
435: this .pw.print("new " + nci.type.toString());
436: this .unparseFunctionInvocationArguments(nci.arguments);
437: }
438:
439: public void visitAssignment(Java.Assignment a) {
440: ((Java.Atom) a.lhs).accept(this );
441: this .pw.print(' ' + a.operator + ' ');
442: ((Java.Atom) a.rhs).accept(this );
443: }
444:
445: public void visitAmbiguousName(Java.AmbiguousName an) {
446: this .pw.print(an.toString());
447: }
448:
449: public void visitArrayAccessExpression(
450: Java.ArrayAccessExpression aae) {
451: ((Java.Atom) aae.lhs).accept(this );
452: this .pw.print('[');
453: ((Java.Atom) aae.index).accept(this );
454: this .pw.print(']');
455: }
456:
457: public void visitArrayLength(Java.ArrayLength al) {
458: ((Java.Atom) al.lhs).accept(this );
459: this .pw.print(".length");
460: }
461:
462: public void visitArrayType(Java.ArrayType at) {
463: ((Java.Atom) at.componentType).accept(this );
464: this .pw.print("[]");
465: }
466:
467: public void visitBasicType(Java.BasicType bt) {
468: this .pw.print(bt.toString());
469: }
470:
471: public void visitBinaryOperation(Java.BinaryOperation bo) {
472: ((Java.Atom) bo.lhs).accept(this );
473: this .pw.print(' ' + bo.op + ' ');
474: ((Java.Atom) bo.rhs).accept(this );
475: }
476:
477: public void visitCast(Java.Cast c) {
478: this .pw.print('(');
479: ((Java.Atom) c.targetType).accept(this );
480: this .pw.print(") ");
481: ((Java.Atom) c.value).accept(this );
482: }
483:
484: public void visitClassLiteral(Java.ClassLiteral cl) {
485: ((Java.Atom) cl.type).accept(this );
486: this .pw.print(".class");
487: }
488:
489: public void visitConditionalExpression(Java.ConditionalExpression ce) {
490: ((Java.Atom) ce.lhs).accept(this );
491: this .pw.print(" ? ");
492: ((Java.Atom) ce.mhs).accept(this );
493: this .pw.print(" : ");
494: ((Java.Atom) ce.rhs).accept(this );
495: }
496:
497: public void visitConstantValue(Java.ConstantValue cv) {
498: this .pw.print(cv.toString());
499: }
500:
501: public void visitCrement(Java.Crement c) {
502: this .pw.print(c.pre ? c.operator + c.operand : c.operand
503: + c.operator);
504: }
505:
506: public void visitFieldAccess(Java.FieldAccess fa) {
507: fa.lhs.accept(this );
508: this .pw.print('.' + fa.field.getName());
509: }
510:
511: public void visitFieldAccessExpression(
512: Java.FieldAccessExpression fae) {
513: fae.lhs.accept(this );
514: this .pw.print('.' + fae.fieldName);
515: }
516:
517: public void visitSuperclassFieldAccessExpression(
518: Java.SuperclassFieldAccessExpression scfae) {
519: if (scfae.optionalQualification != null) {
520: scfae.optionalQualification
521: .accept((Visitor.TypeVisitor) this );
522: this .pw.print(".super." + scfae.fieldName);
523: } else {
524: this .pw.print("super." + scfae.fieldName);
525: }
526: }
527:
528: public void visitInstanceof(Java.Instanceof io) {
529: ((Java.Atom) io.lhs).accept(this );
530: this .pw.print(" instanceof ");
531: ((Java.Atom) io.rhs).accept(this );
532: }
533:
534: public void visitLiteral(Java.Literal l) {
535: this .pw.print(l.toString());
536: }
537:
538: public void visitLocalVariableAccess(Java.LocalVariableAccess lva) {
539: this .pw.print(lva.toString());
540: }
541:
542: public void visitNewArray(Java.NewArray na) {
543: this .pw.print("new ");
544: ((Java.Atom) na.type).accept(this );
545: for (int i = 0; i < na.dimExprs.length; ++i) {
546: this .pw.print('[');
547: ((Java.Atom) na.dimExprs[i]).accept(this );
548: this .pw.print(']');
549: }
550: for (int i = 0; i < na.dims; ++i) {
551: this .pw.print("[]");
552: }
553: }
554:
555: public void visitNewInitializedArray(Java.NewInitializedArray nai) {
556: this .pw.print("new ");
557: nai.arrayType.accept(this );
558: this .pw.print(" ");
559: this .unparseArrayInitializerOrRvalue(nai.arrayInitializer);
560: }
561:
562: public void visitPackage(Java.Package p) {
563: this .pw.print(p.toString());
564: }
565:
566: public void visitParameterAccess(Java.ParameterAccess pa) {
567: this .pw.print(pa.toString());
568: }
569:
570: public void visitQualifiedThisReference(
571: Java.QualifiedThisReference qtr) {
572: ((Java.Atom) qtr.qualification).accept(this );
573: this .pw.print(".this");
574: }
575:
576: public void visitReferenceType(Java.ReferenceType rt) {
577: this .pw.print(rt.toString());
578: }
579:
580: public void visitRvalueMemberType(Java.RvalueMemberType rmt) {
581: this .pw.print(rmt.toString());
582: }
583:
584: public void visitSimpleType(Java.SimpleType st) {
585: this .pw.print(st.toString());
586: }
587:
588: public void visitSuperclassMethodInvocation(
589: Java.SuperclassMethodInvocation smi) {
590: this .pw.print("super." + smi.methodName);
591: this .unparseFunctionInvocationArguments(smi.arguments);
592: }
593:
594: public void visitThisReference(Java.ThisReference tr) {
595: this .pw.print("this");
596: }
597:
598: public void visitUnaryOperation(Java.UnaryOperation uo) {
599: this .pw.print(uo.operator);
600: ((Java.Atom) uo.operand).accept(this );
601: }
602:
603: public void visitParenthesizedExpression(
604: Java.ParenthesizedExpression pe) {
605: this .pw.print('(');
606: ((Java.Atom) pe.value).accept(this );
607: this .pw.print(')');
608: }
609:
610: // Helpers
611:
612: private void unparseNamedClassDeclaration(
613: Java.NamedClassDeclaration ncd) {
614: this .unparseDocComment(ncd);
615: this .unparseModifiers(ncd.modifiers);
616: this .pw.print("class " + ncd.name);
617: if (ncd.optionalExtendedType != null) {
618: this .pw.print(" extends ");
619: ((Java.Atom) ncd.optionalExtendedType).accept(this );
620: }
621: if (ncd.implementedTypes.length > 0)
622: this .pw.print(" implements "
623: + Java.join(ncd.implementedTypes, ", "));
624: this .pw.println(" {");
625: this .unparseClassDeclarationBody(ncd);
626: this .pw.print('}');
627: }
628:
629: private void unparseArrayInitializerOrRvalue(
630: Java.ArrayInitializerOrRvalue aiorv) {
631: if (aiorv instanceof Java.Rvalue) {
632: ((Java.Atom) aiorv).accept(this );
633: } else if (aiorv instanceof Java.ArrayInitializer) {
634: Java.ArrayInitializer ai = (Java.ArrayInitializer) aiorv;
635: if (ai.values.length == 0) {
636: this .pw.print("{}");
637: } else {
638: this .pw.print("{ ");
639: this .unparseArrayInitializerOrRvalue(ai.values[0]);
640: for (int i = 1; i < ai.values.length; ++i) {
641: this .pw.print(", ");
642: this .unparseArrayInitializerOrRvalue(ai.values[i]);
643: }
644: this .pw.print(" }");
645: }
646: } else {
647: throw new RuntimeException(
648: "Unexpected array initializer or rvalue class "
649: + aiorv.getClass().getName());
650: }
651: }
652:
653: public void visitAnonymousClassDeclaration(
654: Java.AnonymousClassDeclaration acd) {
655: ((Java.Atom) acd.baseType).accept(this );
656: this .pw.println(" {");
657: this .unparseClassDeclarationBody(acd);
658: this .pw.print('}');
659: }
660:
661: public void visitNewAnonymousClassInstance(
662: Java.NewAnonymousClassInstance naci) {
663: if (naci.optionalQualification != null) {
664: ((Java.Atom) naci.optionalQualification).accept(this );
665: this .pw.print('.');
666: }
667: this .pw.print("new "
668: + naci.anonymousClassDeclaration.baseType.toString()
669: + '(');
670: for (int i = 0; i < naci.arguments.length; ++i) {
671: if (i > 0)
672: this .pw.print(", ");
673: ((Java.Atom) naci.arguments[i]).accept(this );
674: }
675: this .pw.println(") {");
676: this
677: .unparseClassDeclarationBody(naci.anonymousClassDeclaration);
678: this .pw.print('}');
679: }
680:
681: // Multi-line!
682: private void unparseClassDeclarationBody(Java.ClassDeclaration cd) {
683: for (Iterator it = cd.constructors.iterator(); it.hasNext();) {
684: ((Java.ConstructorDeclarator) it.next()).accept(this );
685: this .pw.println();
686: }
687: this .unparseAbstractTypeDeclarationBody(cd);
688: for (Iterator it = cd.variableDeclaratorsAndInitializers
689: .iterator(); it.hasNext();) {
690: ((Java.TypeBodyDeclaration) it.next()).accept(this );
691: this .pw.println();
692: }
693: }
694:
695: private void unparseInterfaceDeclaration(
696: Java.InterfaceDeclaration id) {
697: this .unparseDocComment(id);
698: this .unparseModifiers(id.modifiers);
699: this .pw.print("interface " + id.name);
700: if (id.extendedTypes.length > 0)
701: this .pw.print(" extends "
702: + Java.join(id.extendedTypes, ", "));
703: this .pw.println(" {");
704: this .unparseAbstractTypeDeclarationBody(id);
705: for (Iterator it = id.constantDeclarations.iterator(); it
706: .hasNext();) {
707: ((Java.TypeBodyDeclaration) it.next()).accept(this );
708: this .pw.println();
709: }
710: this .pw.print('}');
711: }
712:
713: // Multi-line!
714: private void unparseAbstractTypeDeclarationBody(
715: Java.AbstractTypeDeclaration atd) {
716: for (Iterator it = atd.declaredMethods.iterator(); it.hasNext();) {
717: ((Java.MethodDeclarator) it.next()).accept(this );
718: this .pw.println();
719: }
720: for (Iterator it = atd.declaredClassesAndInterfaces.iterator(); it
721: .hasNext();) {
722: ((Java.TypeBodyDeclaration) it.next()).accept(this );
723: this .pw.println();
724: }
725: }
726:
727: private void unparseFunctionDeclaratorRest(
728: Java.FunctionDeclarator fd) {
729: this .pw.print('(');
730: for (int i = 0; i < fd.formalParameters.length; ++i) {
731: if (i > 0)
732: this .pw.print(", ");
733: this .unparseFormalParameter(fd.formalParameters[i]);
734: }
735: this .pw.print(')');
736: if (fd.thrownExceptions.length > 0)
737: this .pw.print(" throws "
738: + Java.join(fd.thrownExceptions, ", "));
739: }
740:
741: private void unparseDocComment(Java.DocCommentable dc) {
742: String optionalDocComment = dc.getDocComment();
743: if (optionalDocComment != null) {
744: this .pw.println();
745: this .pw.print("/**");
746: this .aiw.setPrefix(" *");
747: try {
748: this .pw.print(optionalDocComment);
749: } finally {
750: this .aiw.setPrefix(null);
751: }
752: this .pw.println(" */");
753: }
754: }
755:
756: private void unparseModifiers(short modifiers) {
757: if (modifiers != 0) {
758: this .pw.print(Mod.shortToString(modifiers) + ' ');
759: }
760: }
761:
762: private void unparseFunctionInvocationArguments(
763: Java.Rvalue[] arguments) {
764: this .pw.print('(');
765: for (int i = 0; i < arguments.length; ++i) {
766: if (i > 0)
767: this .pw.print(", ");
768: ((Java.Atom) arguments[i]).accept(this );
769: }
770: this .pw.print(')');
771: }
772: }
|