maj
Class JavaEmitter

java.lang.Object
  extended bymaj.JavaEmitter
All Implemented Interfaces:
MetaTokenTypes

public class JavaEmitter
extends java.lang.Object
implements MetaTokenTypes

JavaEmitter: A class that can take an ANTLR Java AST and produce reasonably formatted Java code from it. To use it, create a JavaEmitter object, call setOut() if you want to print to something other than System.out, and then call print(), passing the AST. Typically, the AST node that you pass would be the root of a tree - the ROOT_ID node that represents a Java file. See main() for example usage.


Field Summary
 
Fields inherited from interface maj.MetaTokenTypes
ABSTRACT, ARRAY_DECLARATOR, ARRAY_INIT, ASPECTJ_ADVICE_AFTER, ASPECTJ_ADVICE_AROUND, ASPECTJ_ADVICE_BEFORE, ASPECTJ_ADVICE_SPEC, ASPECTJ_ARRAY_DECLARATOR, ASPECTJ_ARRAY_INIT, ASPECTJ_ASPECT_BLOCK, ASPECTJ_ASPECT_DEC, ASPECTJ_CASE_GROUP, ASPECTJ_CLASS_DEF, ASPECTJ_CONSTRUCTOR_PATTERN, ASPECTJ_CTOR_CALL, ASPECTJ_CTOR_DEF, ASPECTJ_DECLARE, ASPECTJ_ELIST, ASPECTJ_EMPTY_STAT, ASPECTJ_EXPR, ASPECTJ_EXTENDS_CLAUSE, ASPECTJ_FOR_CONDITION, ASPECTJ_FOR_INIT, ASPECTJ_FOR_ITERATOR, ASPECTJ_IMPLEMENTS_CLAUSE, ASPECTJ_IMPORT, ASPECTJ_INDEX_OP, ASPECTJ_INSTANCE_INIT, ASPECTJ_INTERFACE_DEF, ASPECTJ_LABELED_STAT, ASPECTJ_MEMBER_LIST, ASPECTJ_METHOD_CALL, ASPECTJ_METHOD_DEF, ASPECTJ_METHOD_PATTERN, ASPECTJ_MODIFIER_LIST, ASPECTJ_MODIFIER_LIST_PATTERN, ASPECTJ_OBJBLOCK, ASPECTJ_PACKAGE_DEF, ASPECTJ_PARAMETER_DEF, ASPECTJ_PARAMETERS, ASPECTJ_POINTCUT, ASPECTJ_POINTCUT_DEC, ASPECTJ_POST_DEC, ASPECTJ_POST_INC, ASPECTJ_PRIVILEGED, ASPECTJ_SIGNATURE, ASPECTJ_SIGNATURE_PATTERN, ASPECTJ_SLIST, ASPECTJ_STATEMENT, ASPECTJ_STATEMENT_LIST, ASPECTJ_STATIC_INIT, ASPECTJ_SUPER_CTOR_CALL, ASPECTJ_TYPE, ASPECTJ_TYPE_PATTERN, ASPECTJ_TYPECAST, ASPECTJ_UNARY_MINUS, ASPECTJ_UNARY_PLUS, ASPECTJ_VARDEC_PATTERN, ASPECTJ_VARIABLE_DEF, ASSIGN, BAND, BAND_ASSIGN, BLOCK, BNOT, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, CASE_GROUP, CHAR_LITERAL, CLASS_DEF, COLON, COMMA, CTOR_CALL, CTOR_DEF, DEC, DIV, DIV_ASSIGN, DOT, ELIST, ELLIPSIS, EMPTY_STAT, EOF, EQUAL, ESC, EXPONENT, EXPR, EXTENDS_CLAUSE, FINAL, FLOAT_SUFFIX, FOR_CONDITION, FOR_INIT, FOR_ITERATOR, GE, GT, HEX_DIGIT, IDENT, IMPLEMENTS_CLAUSE, IMPORT, INC, INDEX_OP, INFER_DECL, INFER_DECL_EXPR, INFER_TYPE_EXPR, INFER_TYPE_ID, INSTANCE_INIT, INTERFACE_DEF, LABELED_STAT, LAND, LBRACK, LCURLY, LE, LITERAL_AdviceDec, LITERAL_adviceexecution, LITERAL_after, LITERAL_args, LITERAL_around, LITERAL_aspect, LITERAL_AspectDec, LITERAL_AspectJCompUnitMember, LITERAL_AspectMember, LITERAL_before, LITERAL_boolean, LITERAL_break, LITERAL_byte, LITERAL_call, LITERAL_case, LITERAL_catch, LITERAL_cflow, LITERAL_cflowbelow, LITERAL_char, LITERAL_class, LITERAL_ClassDec, LITERAL_ClassMember, LITERAL_CompUnit, LITERAL_ConstructorDec, LITERAL_continue, LITERAL_declare, LITERAL_DeclareDec, LITERAL_default, LITERAL_do, LITERAL_double, LITERAL_else, LITERAL_error, LITERAL_execution, LITERAL_extends, LITERAL_false, LITERAL_finally, LITERAL_float, LITERAL_for, LITERAL_Formal, LITERAL_FormalDec, LITERAL_get, LITERAL_handler, LITERAL_IDENT, LITERAL_Identifier, LITERAL_if, LITERAL_implements, LITERAL_import, LITERAL_Import, LITERAL_infer, LITERAL_initialization, LITERAL_instanceof, LITERAL_int, LITERAL_interface, LITERAL_InterfaceDec, LITERAL_IntroducedDec, LITERAL_IntroduceDec, LITERAL_issingleton, LITERAL_JavaCompUnitMember, LITERAL_JavaExpr, LITERAL_long, LITERAL_MethodDec, LITERAL_MethodDecList, LITERAL_Modifiers, LITERAL_NamePattern, LITERAL_native, LITERAL_new, LITERAL_null, LITERAL_package, LITERAL_parents, LITERAL_Pcd, LITERAL_percflow, LITERAL_percflowbelow, LITERAL_pertarget, LITERAL_perthis, LITERAL_pointcut, LITERAL_PointcutDec, LITERAL_precedence, LITERAL_preinitialization, LITERAL_private, LITERAL_privileged, LITERAL_protected, LITERAL_public, LITERAL_return, LITERAL_returning, LITERAL_set, LITERAL_short, LITERAL_soft, LITERAL_static, LITERAL_staticinitialization, LITERAL_Stmt, LITERAL_super, LITERAL_switch, LITERAL_synchronized, LITERAL_target, LITERAL_this, LITERAL_threadsafe, LITERAL_throw, LITERAL_throwing, LITERAL_throws, LITERAL_transient, LITERAL_true, LITERAL_try, LITERAL_TypeDec, LITERAL_TypeSpec, LITERAL_VarDec, LITERAL_void, LITERAL_volatile, LITERAL_warning, LITERAL_while, LITERAL_within, LITERAL_withincode, LNOT, LOR, LPAREN, LT, MAJ_INFER_DECL, MAJ_PROMOTE, MAJ_PROMOTE_BOOLEAN, MAJ_PROMOTE_BYTE, MAJ_PROMOTE_CHAR, MAJ_PROMOTE_DOUBLE, MAJ_PROMOTE_FLOAT, MAJ_PROMOTE_INT, MAJ_PROMOTE_LONG, MAJ_PROMOTE_SHORT, MAJ_PROMOTE_STRING, MAJ_QUOTE_ADVICE_DEC, MAJ_QUOTE_ASPECT_DEC, MAJ_QUOTE_ASPECT_MEMBER_LIST, MAJ_QUOTE_ASPECTJ_COMP_UNIT_MEMBERS, MAJ_QUOTE_CLASS_DEC, MAJ_QUOTE_CLASS_MEMBER_LIST, MAJ_QUOTE_COMP_UNIT, MAJ_QUOTE_CONSTRUCTOR_DEC, MAJ_QUOTE_CONSTRUCTOR_DEC_LIST, MAJ_QUOTE_EMPTY, MAJ_QUOTE_EXPR, MAJ_QUOTE_EXPR_LIST, MAJ_QUOTE_IDENT, MAJ_QUOTE_IDENT_PATTERN, MAJ_QUOTE_IDENTIFIER, MAJ_QUOTE_IMPORT, MAJ_QUOTE_IMPORT_LIST, MAJ_QUOTE_INTERFACE_DEC, MAJ_QUOTE_INTERTYPE_DEC, MAJ_QUOTE_JAVA_COMP_UNIT_MEMBERS, MAJ_QUOTE_METHOD_DEC, MAJ_QUOTE_METHOD_DEC_LIST, MAJ_QUOTE_MODIFIERS, MAJ_QUOTE_PARAM_DEC, MAJ_QUOTE_PARAM_DEC_LIST, MAJ_QUOTE_POINTCUT, MAJ_QUOTE_POINTCUT_DEC, MAJ_QUOTE_STATEMENT, MAJ_QUOTE_STATEMENT_LIST, MAJ_QUOTE_TYPE_SPEC, MAJ_QUOTE_VAR_DEC, MAJ_QUOTE_VAR_DEC_LIST, MAJ_QUOTED_TYPED, MAJ_QUOTED_UNTYPED, MAJ_UNQUOTE_ADVICE_DEC, MAJ_UNQUOTE_ASPECT_DEC, MAJ_UNQUOTE_ASPECT_MEMBER_LIST, MAJ_UNQUOTE_ASPECTJ_COMP_UNIT_MEMBERS, MAJ_UNQUOTE_CLASS_DEC, MAJ_UNQUOTE_CLASS_MEMBER_LIST, MAJ_UNQUOTE_COMP_UNIT, MAJ_UNQUOTE_CONSTANT, MAJ_UNQUOTE_CONSTRUCTOR_DEC, MAJ_UNQUOTE_CONSTRUCTOR_DEC_LIST, MAJ_UNQUOTE_EMPTY_UNTYPED, MAJ_UNQUOTE_EXPR, MAJ_UNQUOTE_EXPR_LIST, MAJ_UNQUOTE_IDENT, MAJ_UNQUOTE_IDENT_PATTERN, MAJ_UNQUOTE_IDENTIFIER, MAJ_UNQUOTE_IMPORT, MAJ_UNQUOTE_IMPORT_LIST, MAJ_UNQUOTE_INTERFACE_DEC, MAJ_UNQUOTE_INTERTYPE_DEC, MAJ_UNQUOTE_JAVA_COMP_UNIT_MEMBERS, MAJ_UNQUOTE_METHOD_DEC, MAJ_UNQUOTE_METHOD_DEC_LIST, MAJ_UNQUOTE_MODIFIERS, MAJ_UNQUOTE_PARAM_DEC, MAJ_UNQUOTE_PARAM_DEC_LIST, MAJ_UNQUOTE_POINTCUT, MAJ_UNQUOTE_POINTCUT_DEC, MAJ_UNQUOTE_STATEMENT, MAJ_UNQUOTE_STATEMENT_LIST, MAJ_UNQUOTE_TYPE_SPEC, MAJ_UNQUOTE_VAR_DEC, MAJ_UNQUOTE_VAR_DEC_LIST, METHOD_CALL, METHOD_DEF, MINUS, MINUS_ASSIGN, ML_COMMENT, MOD, MOD_ASSIGN, MODIFIERS, NOT_EQUAL, NULL_TREE_LOOKAHEAD, NUM_DOUBLE, NUM_FLOAT, NUM_INT, NUM_LONG, OBJBLOCK, PACKAGE_DEF, PARAMETER_DEF, PARAMETERS, PLUS, PLUS_ASSIGN, POST_DEC, POST_INC, QUESTION, QUOTE, QUOTED_TYPED_DECL, QUOTED_UNTYPED_DECL, RBRACK, RCURLY, RPAREN, SEMI, SL, SL_ASSIGN, SL_COMMENT, SLIST, SR, SR_ASSIGN, STAR, STAR_ASSIGN, STATIC_INIT, STRICTFP, STRING_LITERAL, SUPER_CTOR_CALL, TYPE, TYPECAST, UNARY_MINUS, UNARY_PLUS, UNQUOTE, VARIABLE_DEF, VOCAB, WS
 
Constructor Summary
JavaEmitter()
           
 
Method Summary
static void main(java.lang.String[] args)
          This example takes a single filename on the command line, prints the AST to stderr and the Java code to stdout.
 void print(antlr.collections.AST ast)
          Print the given AST.
 void setOut(java.io.PrintStream out)
          Specify a PrintStream to print to.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

JavaEmitter

public JavaEmitter()
Method Detail

setOut

public void setOut(java.io.PrintStream out)
Specify a PrintStream to print to. System.out is the default.

Parameters:
out - the PrintStream to print to

print

public void print(antlr.collections.AST ast)
Print the given AST. Call this function to print your Java code.

Overall Approach
It works by making recursive calls to print children. For example, the root of the AST tree has type ROOT_ID. A Java AST node generated from the ANTLR java.g file will have type ROOT_ID and will have the following children, in this order: 0 or 1 children of type PACKAGE_DEF 0 or more children of type IMPORT One child of type CLASS_DEF or type INTERFACE_DEF

So the code below is one big "switch" statement on the passed AST type. In the "ROOT_ID" case, the code here does the following:

  1. calls getChild(ast, PACKAGE_DEF) to get the child of type PACKAGE_DEF, and makes a recursive call to print() on that AST. If there is no "PACKAGE_DEF" child, getChild() would return null and the recursive print() call would print nothing.
  2. Calls printChildren(), passing the AST, the "\n" separator, and the type "IMPORT". printChildren() will print all children of the AST, separating each by the "\n" separator.
  3. Does the same thing will CLASS_DEF that it did with PACKAGE_DEF: calls getChild() to get the child of type CLASS_DEF (or null if there is none), and then makes a recursive call to print().
  4. Does the same thing for INTEFACE_DEF: call getChild() to get the child of type INTEFACE_DEF, and make a recursive call.

Indenting
One important issue is how to do proper indenting. The IndentingPrintStream class handles indenting. Here, we simply create an IndentingPrintStream from our normal PrintStream (either System.out or whatever was passed to setOut()). And then we call increaseIndent() and decreaseIndent() as we see "{" and "}" AST nodes.

Adding Parentheses
The only other tricky part here is in printing parentheses, which are not kept as AST nodes, but are built-in ("inherent") to the structure of the AST. The printWithParens() method is used to print all unary and binary operators. This method uses a precendence table to determine whether it needs to print parentheses or not.


main

public static void main(java.lang.String[] args)
This example takes a single filename on the command line, prints the AST to stderr and the Java code to stdout.