package org.glassfish.pfl.dynamic.codegen.impl;
import java.util.Date ;
import java.lang.reflect.Modifier ;
import org.glassfish.pfl.dynamic.codegen.spi.ImportList ;
import org.glassfish.pfl.dynamic.codegen.spi.Type ;
import org.glassfish.pfl.dynamic.codegen.spi.Variable ;
import org.glassfish.pfl.dynamic.codegen.spi.FieldInfo ;
import org.glassfish.pfl.basic.contain.Pair;
public class SourceStatementVisitor extends TreeWalker {
private ImportList imports ;
CodegenPrinter pr ;
private String className ;
private String typeName( Type type ) {
if (imports.contains( type ))
return type.className() ;
else
return type.name() ;
}
public SourceStatementVisitor( TreeWalkerContext context,
ImportList imports, CodegenPrinter pr ) {
super( context ) ;
context.push( this ) ;
this.imports = imports ;
this.pr = pr ;
this.className = "" ;
}
@Override
public boolean preClassGenerator( final ClassGeneratorImpl arg ) {
className = arg.className() ;
pr.p("/* ").p(arg.isInterface() ? "Interface" : "Class")
.p(" generated by codegen source writer version 1.24." ) ;
pr.nl().p( " * Generated on " ).p(new Date().toString()) ;
pr.nl().p( " */" ) ;
pr.nl() ;
if ((arg.pkgName() != null) && (arg.pkgName().length() > 0))
pr.nl().p( "package " ).p( arg.pkgName() ).p( " ;" ) ;
String lastPackage = "" ;
for (Pair<String,String> data : imports.getInOrderList()) {
String packageName = data.first() ;
String lcName = data.second() ;
if (!lastPackage.equals( packageName )) {
pr.nl() ;
}
if (packageName.equals( "" )) {
pr.nl().p( "import " + lcName + " ;" ) ;
} else {
pr.nl().p( "import " + packageName + "." + lcName + " ;" ) ;
}
lastPackage = packageName ;
}
pr.nl() ;
int modifiers = arg.modifiers() ;
if (arg.isInterface()) {
modifiers &= ~Modifier.INTERFACE ;
modifiers &= ~Modifier.ABSTRACT ;
}
pr.nl().p(Modifier.toString(modifiers))
.p(arg.isInterface() ? " interface " : " class ").p( arg.className() ) ;
if (!arg.isInterface()) {
if (!arg.superType().equals(Type._Object())) {
pr.in().nl().p( "extends " ).p(typeName(arg.superType())).out() ;
}
}
if (arg.impls().size() > 0) {
pr.in().nl().p( arg.isInterface() ? "extends " : "implements " ) ;
int ctr = 0 ;
for (Type type : arg.impls()) {
if (ctr > 0) {
pr.p( ", " ) ;
}
pr.p( typeName(type) ) ;
ctr++ ;
}
pr.out() ;
}
pr.nl().p( "{" ).in() ;
if (!arg.isInterface()) {
for (FieldInfo fld : arg.fieldInfo().values()) {
pr.nl().p(Modifier.toString(fld.modifiers()))
.p(" ").p(typeName(fld.type())).p(" ").p(fld.name()).p(" ;") ;
}
pr.nl() ;
}
if (!arg.isInterface() && (arg.constructors().size() == 0))
throw new IllegalStateException(
"All classes must define at least one constructor" ) ;
return true ;
}
@Override
public boolean classGeneratorBeforeFields( ClassGeneratorImpl arg ) {
return false ;
}
@Override
public void classGeneratorBeforeInitializer( ClassGeneratorImpl arg ) {
pr.nl().p( "static {" ).in() ;
}
@Override
public void classGeneratorBeforeMethod( ClassGeneratorImpl arg ) {
pr.nl() ;
}
@Override
public void classGeneratorBeforeConstructor( ClassGeneratorImpl arg ) {
pr.nl() ;
}
@Override
public void postClassGenerator( ClassGeneratorImpl arg ) {
pr.out().nl().p( "}" ).nl() ;
}
@Override
public boolean methodGeneratorBeforeArguments( MethodGenerator arg ) {
return false ;
}
@Override
public boolean preMethodGenerator( MethodGenerator arg ) {
ClassGeneratorImpl parent = ClassGeneratorImpl.class.cast( arg.parent() ) ;
if (arg.isConstructor())
pr.nl().p(Modifier.toString(arg.modifiers())).p(" ")
.p(className).p("(") ;
else if (parent.isInterface())
pr.nl().p(typeName(arg.returnType())).p(" ").p(arg.name()).p("(") ;
else
pr.nl().p(Modifier.toString(arg.modifiers())).p(" ")
.p(typeName(arg.returnType())).p(" ").p(arg.name()).p("(") ;
int ctr = 0 ;
for (Variable var : arg.arguments()) {
VariableInternal ivar = (VariableInternal)var ;
if (ctr > 0)
pr.p(", ") ;
pr.p(typeName(ivar.type())).p(" ").p(ivar.ident()) ;
ctr++ ;
}
pr.p(")") ;
boolean hasExceptions = arg.exceptions().size() > 0 ;
boolean isAbstract = Modifier.isAbstract( arg.modifiers() ) ;
if (hasExceptions) {
pr.in().nl().p("throws ") ;
ctr = 0 ;
for (Type type : arg.exceptions()) {
if (ctr > 0)
pr.p( ", " ) ;
pr.p(typeName(type)) ;
ctr++ ;
}
}
if (isAbstract) {
pr.p(" ;") ;
if (hasExceptions)
pr.out() ;
} else {
pr.p(" {") ;
if (!hasExceptions)
pr.in() ;
}
return true ;
}
@Override
public void postMethodGenerator( MethodGenerator arg ) {
}
@Override
public boolean preThrowStatement( ThrowStatement arg ) {
new SourceExpressionVisitor( context, imports ) ;
return true ;
}
@Override
public void postThrowStatement( ThrowStatement arg ) {
SourceExpressionVisitor sev = SourceExpressionVisitor.class.cast(
context.pop() ) ;
pr.nl(arg).p( "throw " ).p( sev.value() ).p( " ;" ) ;
}
@Override
public boolean preAssignmentStatement( AssignmentStatement arg ) {
new SourceExpressionVisitor( context, imports ) ;
return true ;
}
@Override
public void assignmentStatementBeforeLeftSide( AssignmentStatement arg ) {
new SourceExpressionVisitor( context, imports ) ;
}
@Override
public void postAssignmentStatement( AssignmentStatement arg ) {
SourceExpressionVisitor var = SourceExpressionVisitor.class.cast(
context.pop() ) ;
SourceExpressionVisitor expr = SourceExpressionVisitor.class.cast(
context.pop() ) ;
pr.nl(arg).p(var.value()).p(" = ").p(expr.value()).p(" ;") ;
}
@Override
public boolean preBlockStatement( BlockStatement arg ) {
return true ;
}
@Override
public void blockStatementBeforeBodyStatement( BlockStatement arg, Statement stmt ) {
}
@Override
public void postBlockStatement( BlockStatement arg ) {
if (arg.parent() instanceof MethodGenerator)
pr.out().nl(arg).p("}") ;
else
pr.out().nl().p("}") ;
}
@Override
public boolean preCaseBranch( CaseBranch arg ) {
pr.nl(arg).p("case ").p(Integer.toString(arg.label())).p(":").in() ;
return true ;
}
@Override
public void caseBranchBeforeBodyStatement( CaseBranch arg ) {
}
@Override
public void postCaseBranch( CaseBranch arg ) {
pr.out() ;
}
@Override
public boolean preDefinitionStatement( DefinitionStatement arg ) {
new NopVisitor( context ) ;
return preStatement( arg ) ;
}
@Override
public boolean definitionStatementBeforeExpr( DefinitionStatement arg ) {
context.pop() ;
new SourceExpressionVisitor( context, imports ) ;
return true ;
}
@Override
public void postDefinitionStatement( DefinitionStatement arg ) {
SourceExpressionVisitor sev =
SourceExpressionVisitor.class.cast(context.pop()) ;
VariableInternal ivar = (VariableInternal)arg.var() ;
pr.nl(arg).p(typeName(ivar.type())).p(" ")
.p(ivar.ident()).p(" = ").p(sev.value()).p(" ;") ;
}
@Override
public boolean preIfStatement( IfStatement arg ) {
new SourceExpressionVisitor( context, imports ) ;
return true ;
}
@Override
public void ifStatementBeforeTruePart( IfStatement arg ) {
SourceExpressionVisitor sev =
SourceExpressionVisitor.class.cast(context.pop()) ;
pr.nl(arg).p("if (").p(sev.value()).p(")").p(" {").in() ;
}
@Override
public boolean ifStatementBeforeFalsePart( IfStatement arg ) {
boolean result = !arg.falsePart().isEmpty() ;
if (result)
pr.p(" else {").in() ;
return result ;
}
@Override
public void postIfStatement( IfStatement arg ) {
pr.nl() ;
}
@Override
public boolean preBreakStatement( BreakStatement arg ) {
return true ;
}
@Override
public void postBreakStatement( BreakStatement arg ) {
pr.nl(arg).p( "break ; " ) ;
}
@Override
public boolean preReturnStatement( ReturnStatement arg ) {
new SourceExpressionVisitor( context, imports ) ;
return true ;
}
@Override
public void postReturnStatement( ReturnStatement arg ) {
SourceExpressionVisitor sev = SourceExpressionVisitor.class.cast(
context.pop() ) ;
pr.nl(arg).p( "return " ).p( sev.value() ).p( " ;" ) ;
}
@Override
public boolean preSwitchStatement( SwitchStatement arg ) {
new SourceExpressionVisitor( context, imports ) ;
return true ;
}
@Override
public boolean switchStatementBeforeCaseBranches( SwitchStatement arg) {
SourceExpressionVisitor sev = SourceExpressionVisitor.class.cast(
context.pop() ) ;
pr.nl(arg).p("switch (").p(sev.value()).p(") {").in() ;
return true ;
}
@Override
public boolean switchStatementBeforeDefault( SwitchStatement arg ) {
boolean result = !arg.defaultCase().isEmpty() ;
if (result)
pr.nl().p("default :").in() ;
return result ;
}
@Override
public void postSwitchStatement( SwitchStatement arg ) {
pr.out().nl().p("}") ;
}
@Override
public boolean preTryStatement( TryStatement arg ) {
pr.nl().p("try {").in() ;
return true ;
}
@Override
public void tryStatementBeforeBlock( TryStatement arg,
Type type, Variable var, BlockStatement block ) {
VariableInternal ivar = (VariableInternal)var ;
pr.p(" catch (").p(typeName(type)).p(" ").p(ivar.ident()).p(") {").in() ;
}
@Override
public boolean tryStatementBeforeFinalPart( TryStatement arg ) {
boolean result = !arg.finalPart().isEmpty() ;
if (result)
pr.p(" finally {").in() ;
return result ;
}
@Override
public void postTryStatement( TryStatement arg ) {
}
@Override
public boolean preWhileStatement( WhileStatement arg ) {
new SourceExpressionVisitor( context, imports ) ;
return true ;
}
@Override
public void whileStatementBeforeBody( WhileStatement arg ) {
SourceExpressionVisitor sev = SourceExpressionVisitor.class.cast(
context.pop() ) ;
pr.nl(arg).p("while (").p(sev.value()).p(") {").in() ;
}
@Override
public void postWhileStatement( WhileStatement arg ) {
}
@Override
public boolean preExpression( ExpressionInternal arg ) {
SourceExpressionVisitor sev = new SourceExpressionVisitor( context, imports ) ;
arg.accept( context.current() ) ;
context.pop() ;
pr.nl(arg).p(sev.value()).p(" ;") ;
return false ;
}
@Override
public void postExpression( ExpressionInternal arg ) {
}
}