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