Package net.janino

Source Code of net.janino.UnparseVisitor

/*
* Janino - An embedded Java[TM] compiler
* Copyright (C) 2001-2004 Arno Unkrig
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact information:
*   Arno Unkrig
*   Ferdinand-Miller-Platz 10
*   80335 Muenchen
*   Germany
*   http://www.janino.net
*   maintainer@janino.net
*/

package net.janino;

import java.io.*;
import java.util.Iterator;

import net.janino.util.AutoIndentWriter;

/**
* A visitor that unparses (un-compiles) an AST to a {@link Writer}. See
* {@link #main(String[])} for a usage example.
*/
public class UnparseVisitor implements Visitor {
    private final AutoIndentWriter aiw;
    private final PrintWriter      pw;

    /**
     * Testing of parsing/unparsing.
     * <p>
     * Reads compilation units from the files named on the command line
     * and unparses them to {@link System#out}.
     */
    public static void main(String[] args) throws Exception {
        Writer w = new BufferedWriter(new OutputStreamWriter(System.out));
        for (int i = 0; i < args.length; ++i) {
            Java.CompilationUnit cu = new Parser(new Scanner(args[i])).parseCompilationUnit();
            UnparseVisitor.unparse(cu, w);
        }
        w.flush();
    }

    /**
     * Unparse the given {@link Java.CompilationUnit} to the given {@link Writer}.
     */
    public static void unparse(Java.CompilationUnit cu, Writer w) {
        new UnparseVisitor(w).visitCompilationUnit(cu);
    }

    public UnparseVisitor(Writer w) {
        this.aiw = new AutoIndentWriter(w);
        this.pw = new PrintWriter(this.aiw, true);
    }

    public void visitCompilationUnit(Java.CompilationUnit cu) {
        if (cu.optionalPackage != null) {
            this.pw.println("package " + cu.optionalPackage + ';');
        }
        for (Iterator it = cu.importedPackages.iterator(); it.hasNext();) {
            this.pw.println("import " + Java.join((String[]) it.next(), ".") + ".*;");
        }
        for (Iterator it = cu.singleTypeImports.values().iterator(); it.hasNext();) {
            this.pw.println("import " + Java.join((String[]) it.next(), ".") + ';');
        }
        for (Iterator it = cu.packageMemberTypeDeclarations.values().iterator(); it.hasNext();) {
            ((Java.PackageMemberTypeDeclaration) it.next()).visit(this);
            this.pw.println();
        }
    }

    public void visitLocalClassDeclaration(Java.LocalClassDeclaration lcd) {
        this.unparseNamedClassDeclaration(lcd);
    }
    public void visitMemberClassDeclaration(Java.MemberClassDeclaration mcd) {
        this.unparseNamedClassDeclaration(mcd);
    }
    public void visitMemberInterfaceDeclaration(Java.MemberInterfaceDeclaration mid) {
        this.unparseInterfaceDeclaration(mid);
    }
    public void visitPackageMemberClassDeclaration(Java.PackageMemberClassDeclaration pmcd) {
        this.unparseNamedClassDeclaration(pmcd);
    }
    public void visitPackageMemberInterfaceDeclaration(Java.PackageMemberInterfaceDeclaration pmid) {
        this.unparseInterfaceDeclaration(pmid);
    }
    public void visitConstructorDeclarator(Java.ConstructorDeclarator cd) {
        this.unparseModifiers(cd.modifiers);
        this.pw.print(((Java.NamedClassDeclaration) cd.declaringType).name);
        this.unparseFunctionDeclaratorRest(cd);
        this.pw.print(' ');
        if (cd.optionalExplicitConstructorInvocation != null) {
            this.pw.println('{');
            cd.optionalExplicitConstructorInvocation.visit(this);
            this.pw.println(';');
            for (Iterator it = cd.optionalBody.statements.iterator(); it.hasNext();) {
                ((Java.BlockStatement) it.next()).visit(this);
                this.pw.println();
            }
            this.pw.print('}');
        } else {
            cd.optionalBody.visit(this);
        }
    }
    public void visitMethodDeclarator(Java.MethodDeclarator md) {
        this.unparseModifiers(md.modifiers);
        md.type.visit(this);
        this.pw.print(' ' + md.name);
        this.unparseFunctionDeclaratorRest(md);
        if (md.optionalBody != null) {
            this.pw.print(' ');
            md.optionalBody.visit(this);
        } else {
            this.pw.print(';');
        }
    }
    public void visitFieldDeclarator(Java.FieldDeclarator fd) {
        this.unparseModifiers(fd.modifiers);
        fd.type.visit(this);
        this.pw.print(' ');
        for (int i = 0; i < fd.variableDeclarators.length; ++i) {
            if (i > 0) this.pw.print(", ");
            fd.variableDeclarators[i].visit(this);
        }
        this.pw.print(';');
    }
    public void visitInitializer(Java.Initializer i) {
        if (i.statiC) this.pw.print("static ");
        i.block.visit(this);
    }
    public void visitBlock(Java.Block b) {
        this.pw.println('{');
        for (Iterator it = b.statements.iterator(); it.hasNext();) {
            ((Java.BlockStatement) it.next()).visit(this);
            this.pw.println();
        }
        this.pw.print('}');
    }
    public void visitBreakStatement(Java.BreakStatement bs) {
        this.pw.print("break");
        if (bs.optionalLabel != null) this.pw.print(' ' + bs.optionalLabel);
        this.pw.print(';');
    }
    public void visitContinueStatement(Java.ContinueStatement cs) {
        this.pw.print("continue");
        if (cs.optionalLabel != null) this.pw.print(' ' + cs.optionalLabel);
        this.pw.print(';');
    }
    public void visitDoStatement(Java.DoStatement ds) {
        this.pw.print("do ");
        ds.body.visit(this);
        this.pw.print("while (");
        ds.condition.visit(this);
        this.pw.print(");");
    }
    public void visitEmptyStatement(Java.EmptyStatement es) {
        this.pw.print(';');
    }
    public void visitExpressionStatement(Java.ExpressionStatement es) {
        es.rvalue.visit(this);
        this.pw.print(';');
    }
    public void visitForStatement(Java.ForStatement fs) {
        this.pw.print("for (");
        if (fs.optionalInit != null) {
            fs.optionalInit.visit(this);
        } else {
            this.pw.print(';');
        }
        if (fs.optionalCondition != null) {
            this.pw.print(' ');
            fs.optionalCondition.visit(this);
        }
        this.pw.print(';');
        if (fs.optionalUpdate != null) {
            this.pw.print(' ');
            for (int i = 0; i < fs.optionalUpdate.length; ++i) {
                if (i > 0) this.pw.print(", ");
                fs.optionalUpdate[i].visit(this);
            }
        }
        this.pw.print(") ");
        fs.body.visit(this);
    }
    public void visitIfStatement(Java.IfStatement is) {
        this.pw.print("if (");
        is.condition.visit(this);
        this.pw.print(") ");
        is.thenStatement.visit(this);
        if (is.optionalElseStatement != null) {
            this.pw.print(" else ");
            is.optionalElseStatement.visit(this);
        }
    }
    public void visitLabeledStatement(Java.LabeledStatement ls) {
        this.pw.println(ls.label + ':');
        ls.body.visit(this);
    }
    public void visitLocalClassDeclarationStatement(Java.LocalClassDeclarationStatement lcds) {
        lcds.lcd.visit(this);
    }
    public void visitLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) {
        this.unparseModifiers(lvds.modifiers);
        lvds.type.visit(this);
        this.pw.print(' ');
        lvds.variableDeclarators[0].visit(this);
        for (int i = 1; i < lvds.variableDeclarators.length; ++i) {
            this.pw.print(", ");
            lvds.variableDeclarators[i].visit(this);
        }
        this.pw.print(';');
    }
    public void visitReturnStatement(Java.ReturnStatement rs) {
        this.pw.print("return");
        if (rs.optionalReturnValue != null) {
            this.pw.print(' ');
            rs.optionalReturnValue.visit(this);
        }
        this.pw.print(';');
    }
    public void visitSwitchStatement(Java.SwitchStatement ss) {
        this.pw.println("switch (" + ss.condition + ") {");
        for (Iterator it = ss.sbsgs.iterator(); it.hasNext();) {
            Java.SwitchBlockStatementGroup sbgs = (Java.SwitchBlockStatementGroup) it.next();
            this.aiw.unindent();
            try {
                for (Iterator it2 = sbgs.caseLabels.iterator(); it2.hasNext();) {
                    Java.Rvalue rv = (Java.Rvalue) it2.next();
                    this.pw.print("case ");
                    rv.visit(this);
                    this.pw.println(':');
                }
                if (sbgs.hasDefaultLabel) this.pw.println("default:");
            } finally {
                this.aiw.indent();
            }
            for (Iterator it2 = sbgs.blockStatements.iterator(); it2.hasNext();) {
                ((Java.BlockStatement) it2.next()).visit(this);
                this.pw.println();
            }
        }
        this.pw.print('}');
    }
    public void visitSynchronizedStatement(Java.SynchronizedStatement ss) {
        this.pw.print("synchronized (");
        ss.expression.visit(this);
        this.pw.print(") ");
        ss.body.visit(this);
    }
    public void visitThrowStatement(Java.ThrowStatement ts) {
        this.pw.print("throw ");
        ts.expression.visit(this);
        this.pw.print(';');
    }
    public void visitTryStatement(Java.TryStatement ts) {
        this.pw.print("try ");
        ts.body.visit(this);
        for (Iterator it = ts.catchClauses.iterator(); it.hasNext();) {
            Java.CatchClause cc = (Java.CatchClause) it.next();
            this.pw.print(" catch (");
            cc.caughtException.visit(this);
            this.pw.print(") ");
            cc.body.visit(this);
        }
        if (ts.optionalFinally != null) {
            this.pw.print(" finally ");
            ts.optionalFinally.visit(this);
        }
    }
    public void visitWhileStatement(Java.WhileStatement ws) {
        this.pw.print("while (");
        ws.condition.visit(this);
        this.pw.print(") ");
        ws.body.visit(this);
    }
    public void visitVariableDeclarator(Java.VariableDeclarator vd) {
        this.pw.print(vd.name);
        for (int i = 0; i < vd.brackets; ++i) this.pw.print("[]");
        if (vd.optionalInitializer != null) {
            this.pw.print(" = ");
            vd.optionalInitializer.visit(this);
        }
    }
    public void visitFormalParameter(Java.FormalParameter fp) {
        if (fp.finaL) this.pw.print("final ");
        fp.type.visit(this);
        this.pw.print(' ' + fp.name);
    }
    public void visitMethodInvocation(Java.MethodInvocation mi) {
        if (mi.optionalTarget != null) {
            mi.optionalTarget.visit(this);
            this.pw.print('.');
        }
        this.pw.print(mi.methodName);
        this.unparseFunctionInvocationArguments(mi.arguments);
    }
    public void visitAlternateConstructorInvocation(Java.AlternateConstructorInvocation aci) {
        this.pw.print("this");
        this.unparseFunctionInvocationArguments(aci.arguments);
    }
    public void visitSuperConstructorInvocation(Java.SuperConstructorInvocation sci) {
        if (sci.optionalQualification != null) {
            sci.optionalQualification.visit(this);
            this.pw.print('.');
        }
        this.pw.print("super");
        this.unparseFunctionInvocationArguments(sci.arguments);
    }
    public void visitNewClassInstance(Java.NewClassInstance nci) {
        if (nci.optionalQualification != null) {
            nci.optionalQualification.visit(this);
            this.pw.print('.');
        }
        this.pw.print("new " + nci.type.toString());
        this.unparseFunctionInvocationArguments(nci.arguments);
    }
    public void visitAssignment(Java.Assignment a) {
        a.lhs.visit(this);
        this.pw.print(' ' + a.operator + ' ');
        a.rhs.visit(this);
    }
    public void visitArrayInitializer(Java.ArrayInitializer ai) {
        this.pw.print("new ");
        ai.arrayType.visit(this);
        this.pw.println(" {");
        for (int i = 0; i < ai.values.length; ++i) {
            ai.values[i].visit(this);
            this.pw.println(',');
        }
        this.pw.print('}');
    }
    public void visitAmbiguousName(Java.AmbiguousName an) { this.pw.print(an.toString()); }
    public void visitArrayAccessExpression(Java.ArrayAccessExpression aae) {
        aae.lhs.visit(this);
        this.pw.print('[');
        aae.index.visit(this);
        this.pw.print(']');
    }
    public void visitArrayLength(Java.ArrayLength al) {
        al.lhs.visit(this);
        this.pw.print(".length");
    }
    public void visitArrayType(Java.ArrayType at) {
        at.componentType.visit(this);
        this.pw.print("[]");
    }
    public void visitBasicType(Java.BasicType bt) {
        this.pw.print(bt.toString());
    }
    public void visitBinaryOperation(Java.BinaryOperation bo) {
        bo.lhs.visit(this);
        this.pw.print(' ' + bo.op + ' ');
        bo.rhs.visit(this);
    }
    public void visitCast(Java.Cast c) {
        this.pw.print('(');
        c.targetType.visit(this);
        this.pw.print(") ");
        c.value.visit(this);
    }
    public void visitClassLiteral(Java.ClassLiteral cl) {
        cl.type.visit(this);
        this.pw.print(".class");
    }
    public void visitConditionalExpression(Java.ConditionalExpression ce) {
        ce.lhs.visit(this);
        this.pw.print(" ? ");
        ce.mhs.visit(this);
        this.pw.print(" : ");
        ce.rhs.visit(this);
    }
    public void visitConstantValue(Java.ConstantValue cv) { this.pw.print(cv.toString()); }
    public void visitCrement(Java.Crement c) {
        this.pw.print(
            c.pre ?
            c.operator + c.operand :
            c.operand + c.operator
        );
    }
    public void visitFieldAccess(Java.FieldAccess fa) {
        fa.lhs.visit(this);
        this.pw.print('.' + fa.field.getName());
    }
    public void visitFieldAccessExpression(Java.FieldAccessExpression fae) {
        fae.lhs.visit(this);
        this.pw.print('.' + fae.fieldName);
    }
    public void visitInstanceof(Java.Instanceof io) {
        io.lhs.visit(this);
        this.pw.print(" instanceof ");
        io.rhs.visit(this);
    }
    public void visitLiteral(Java.Literal l) { this.pw.print(l.toString()); }
    public void visitLocalVariableAccess(Java.LocalVariableAccess lva) { this.pw.print(lva.toString()); }
    public void visitNewArray(Java.NewArray na) {
        this.pw.print("new ");
        na.type.visit(this);
        for (int i = 0; i < na.dimExprs.length; ++i) {
            this.pw.print('[');
            na.dimExprs[i].visit(this);
            this.pw.print(']');
        }
        for (int i = 0; i < na.dims; ++i) {
            this.pw.print("[]");
        }
    }
    public void visitPackage(Java.Package p) { this.pw.print(p.toString()); }
    public void visitParameterAccess(Java.ParameterAccess pa) { this.pw.print(pa.toString()); }
    public void visitQualifiedThisReference(Java.QualifiedThisReference qtr) {
        qtr.qualification.visit(this);
        this.pw.print(".this");
    }
    public void visitReferenceType(Java.ReferenceType rt) { this.pw.print(rt.toString()); }
    public void visitRvalueMemberType(Java.RvalueMemberType rmt) { this.pw.print(rmt.toString()); }
    public void visitSimpleType(Java.SimpleType st) { this.pw.print(st.toString()); }
    public void visitSuperclassMethodInvocation(Java.SuperclassMethodInvocation smi) {
        this.pw.print("super." + smi.methodName);
        this.unparseFunctionInvocationArguments(smi.arguments);
    }
    public void visitThisReference(Java.ThisReference tr) {
        this.pw.print("this");
    }
    public void visitUnaryOperation(Java.UnaryOperation uo) {
        this.pw.print(uo.operator);
        uo.operand.visit(this);
    }
    public void visitParenthesizedExpression(Java.ParenthesizedExpression pe) {
        this.pw.print('(');
        pe.value.visit(this);
        this.pw.print(')');
    }

    // Helpers

    private void unparseNamedClassDeclaration(Java.NamedClassDeclaration ncd) {
        this.unparseModifiers(ncd.modifiers);
        this.pw.print("class " + ncd.name);
        if (ncd.optionalExtendedType != null) {
            this.pw.print(" extends ");
            ncd.optionalExtendedType.visit(this);
        }
        if (ncd.implementedTypes.length > 0) this.pw.print(" implements " + Java.join(ncd.implementedTypes, ", "));
        this.pw.println(" {");
        this.unparseClassDeclarationBody(ncd);
        this.pw.print('}');
    }
    public void visitAnonymousClassDeclaration(Java.AnonymousClassDeclaration acd) {
        acd.baseType.visit(this);
        this.pw.println(" {");
        this.unparseClassDeclarationBody(acd);
        this.pw.print('}');
    }
    public void visitNewAnonymousClassInstance(Java.NewAnonymousClassInstance naci) {
        if (naci.optionalQualification != null) {
            naci.optionalQualification.visit(this);
            this.pw.print('.');
        }
        this.pw.print("new " + naci.anonymousClassDeclaration.baseType.toString() + '(');
        for (int i = 0; i < naci.arguments.length; ++i) {
            if (i > 0) this.pw.print(", ");
            naci.arguments[i].visit(this);
        }
        this.pw.println(") {");
        this.unparseClassDeclarationBody(naci.anonymousClassDeclaration);
        this.pw.print('}');
    }
    // Multi-line!
    private void unparseClassDeclarationBody(Java.ClassDeclaration cd) {
        for (Iterator it = cd.constructors.iterator(); it.hasNext();) {
            ((Java.ConstructorDeclarator) it.next()).visit(this);
            this.pw.println();
        }
        this.unparseAbstractTypeDeclarationBody(cd);
        for (Iterator it = cd.variableDeclaratorsAndInitializers.iterator(); it.hasNext();) {
            ((Java.TypeBodyDeclaration) it.next()).visit(this);
            this.pw.println();
        }
    }
    private void unparseInterfaceDeclaration(Java.InterfaceDeclaration id) {
        this.unparseModifiers(id.modifiers);
        this.pw.print("interface " + id.name);
        if (id.extendedTypes.length > 0) this.pw.print(" extends " + Java.join(id.extendedTypes, ", "));
        this.pw.println(" {");
        this.unparseAbstractTypeDeclarationBody(id);
        for (Iterator it = id.constantDeclarations.iterator(); it.hasNext();) {
            ((Java.FieldDeclarator) it.next()).visit(this);
            this.pw.println();
        }
        this.pw.print('}');
    }
    // Multi-line!
    private void unparseAbstractTypeDeclarationBody(Java.AbstractTypeDeclaration atd) {
        for (Iterator it = atd.declaredMethods.iterator(); it.hasNext();) {
            ((Java.MethodDeclarator) it.next()).visit(this);
            this.pw.println();
        }
        for (Iterator it = atd.declaredClassesAndInterfaces.values().iterator(); it.hasNext();) {
            ((Java.MemberTypeDeclaration) it.next()).visit(this);
            this.pw.println();
        }
    }
    private void unparseFunctionDeclaratorRest(Java.FunctionDeclarator fd) {
        this.pw.print('(');
        for (int i = 0; i < fd.formalParameters.length; ++i) {
            if (i > 0) this.pw.print(", ");
            fd.formalParameters[i].visit(this);
        }
        this.pw.print(')');
        if (fd.thrownExceptions.length > 0) this.pw.print(" throws " + Java.join(fd.thrownExceptions, ", "));
    }
    private void unparseModifiers(short modifiers) {
        if (modifiers != 0) {
            this.pw.print(Mod.shortToString(modifiers) + ' ');
        }
    }
    private void unparseFunctionInvocationArguments(Java.Rvalue[] arguments) {
        this.pw.print('(');
        for (int i = 0; i < arguments.length; ++i) {
            if (i > 0) this.pw.print(", ");
            arguments[i].visit(this);
        }
        this.pw.print(')');
    }
}
TOP

Related Classes of net.janino.UnparseVisitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.