/*
* Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package org.visage.tools.tree;
import com.sun.source.tree.Tree.Kind;
import java.io.IOException;
import java.io.Writer;
import java.util.HashSet;
import com.sun.tools.mjavac.tree.JCTree;
import com.sun.tools.mjavac.tree.JCTree.JCAnnotation;
import com.sun.tools.mjavac.tree.JCTree.JCFieldAccess;
import com.sun.tools.mjavac.tree.JCTree.JCImport;
import com.sun.tools.mjavac.tree.Pretty;
import com.sun.tools.mjavac.tree.TreeInfo;
import com.sun.tools.mjavac.util.Context;
import com.sun.tools.mjavac.util.Name;
import org.visage.tools.comp.VisageDefs;
import com.sun.tools.mjavac.tree.JCTree.JCClassDecl;
import com.sun.tools.mjavac.tree.JCTree.JCIdent;
import com.sun.tools.mjavac.util.Options;
/** Prints out a tree as an indented Java source program.
*
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
* you write code tree depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*
* @author Robert Field
*/
public class JavaPretty extends Pretty {
private HashSet<Name> importedPackages = new HashSet<Name>();
private HashSet<Name> importedClasses = new HashSet<Name>();
private boolean seenImport;
public final boolean verbose;
public JavaPretty(Writer out, boolean sourceOutput, Context context) {
super(out, sourceOutput);
Options options = Options.instance(context);
verbose = options.get("dumpverbosejava") != null;
VisageDefs defs = VisageDefs.instance(context);
importedPackages.add(defs.runtime_PackageName);
importedPackages.add(defs.annotation_PackageName);
importedPackages.add(defs.sequence_PackageName);
importedPackages.add(defs.functions_PackageName);
importedPackages.add(defs.javaLang_PackageName);
}
@Override
public void visitAnnotation(JCAnnotation tree) {
if (verbose) {
// Super class implementation prints only simple name for
// annotation type. So, org.visage.runtime.Package is
// printed as Package which clashes with java.lang.Package!!
try {
print("@");
print(tree.annotationType);
print("(");
printExprs(tree.args);
print(")");
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
public void visitBlockExpression(BlockExprJCBlockExpression tree) {
visitBlockExpression(this, tree);
}
public static void visitBlockExpression(Pretty pretty, BlockExprJCBlockExpression tree) {
try {
pretty.printFlags(tree.flags);
pretty.print("{");
pretty.println();
pretty.indent();
pretty.printStats(tree.stats);
if (tree.value != null) {
pretty.align();
pretty.printExpr(tree.value);
pretty.print(";");
}
pretty.undent();
pretty.println();
pretty.align();
pretty.print("}");
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
public void visitImport(JCImport tree) {
printRuntimeImports();
super.visitImport(tree);
// save imports for later use
Name name = TreeInfo.name(tree.qualid);
if (name == name.table.asterisk)
if (tree.qualid.getTag() == JCTree.SELECT)
importedPackages.add(TreeInfo.fullName(((JCFieldAccess) tree.qualid).selected));
else;
else if (name.contentEquals("**")) {
// TODO: Handle import of '**'
//
} else {
importedClasses.add(TreeInfo.fullName(tree.qualid));
}
}
@Override
public void visitClassDef(JCClassDecl tree) {
printRuntimeImports();
super.visitClassDef(tree);
}
@Override
public void visitSelect(JCFieldAccess tree) {
try {
if (!importedPackages.contains(TreeInfo.fullName(tree.selected))
&& !importedClasses.contains(TreeInfo.fullName(tree))) {
printExpr(tree.selected, TreeInfo.postfixPrec);
if (tree.selected.getKind() == Kind.IDENTIFIER) {
if (! ((JCIdent)tree.selected).getName().isEmpty()) {
print(".");
}
} else {
print(".");
}
}
print(tree.name);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
private void printRuntimeImports() {
if (! seenImport) {
for (Name pkg : importedPackages) {
try {
print("import ");
print(pkg.toString());
print(".*;");
println();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
seenImport = true;
}
}