package org.glassfish.pfl.dynamic.codegen.impl;
import java.io.PrintStream ;
import java.util.Set ;
import java.util.Map ;
import java.util.IdentityHashMap ;
import java.lang.reflect.Modifier ;
import org.glassfish.pfl.dynamic.codegen.spi.Type ;
import org.glassfish.pfl.dynamic.codegen.spi.Variable ;
public final class Util {
private Util() {}
public static void close( Node node ) {
TreeWalkerContext context = new TreeWalkerContext() ;
Visitor visitor = new TreeWalker( context ) {
@Override
public void blockStatementBeforeBodyStatement( BlockStatement arg,
Statement stmt ) {
if (stmt instanceof DefinitionStatement) {
DefinitionStatement ds =
DefinitionStatement.class.cast( stmt ) ;
((VariableInternal)ds.var()).close() ;
}
}
@Override
public void visitMethodGenerator( MethodGenerator arg ) {
for (Variable var : arg.arguments()) {
((VariableInternal)var).close() ;
}
}
@Override
public void tryStatementBeforeBlock( TryStatement arg,
Type type, Variable var, BlockStatement block ) {
((VariableInternal)var).close() ;
}
} ;
context.push( visitor ) ;
node.accept( visitor ) ;
}
public static void checkScope( ExpressionInternal expr ) {
TreeWalkerContext context = new TreeWalkerContext() ;
Visitor visitor = new TreeWalker( context ) {
@Override
public boolean preVariable( Variable arg ) {
if (!((VariableInternal)arg).isAvailable())
throw new IllegalStateException( arg + " is no longer in scope" ) ;
return false ;
}
} ;
context.push( visitor ) ;
expr.accept( visitor ) ;
}
public static void checkTree( final Node node, final PrintStream pw ) {
TreeWalkerContext context = new TreeWalkerContext() ;
final Map<Node,Integer> map = new IdentityHashMap<Node,Integer>() ;
Visitor visitor = new TreeWalker( context ) {
@Override
public boolean preNode( Node arg ) {
Integer val = map.get( arg ) ;
if (val == null) {
val = 1 ;
} else {
val++ ;
}
map.put( arg, val ) ;
return false ;
}
} ;
context.push( visitor ) ;
node.accept( visitor ) ;
for (Map.Entry<Node,Integer> entry : map.entrySet()) {
if (entry.getValue() > 1) {
pw.print( "Node " + entry.getKey()
+ " appeared " + entry.getValue() + " times in the AST" ) ;
}
}
}
private static void displayAttributes( final Node node, final CodegenPrinter pr ) {
Set<Attribute<?>> attrs = Attribute.getAttributes( node ) ;
for (Attribute<?> attr : attrs) {
String typeName = attr.type().getName() ;
int lastIndex = typeName.lastIndexOf( '.' ) ;
if (lastIndex >= 0)
typeName = typeName.substring( lastIndex + 1 ) ;
Object obj = attr.get(node) ;
String value = attr.get( node ).toString() ;
pr.nl().p("|__:").p(attr.name()).p(":").p(typeName).p("=").p(value) ;
if (obj instanceof Node) {
pr.in() ;
displayAttributes( Node.class.cast(obj), pr ) ;
pr.out() ;
}
}
}
public static String getNodeIdString( Node obj ) {
return "@" + obj.id() ;
}
public static void display( final Node node, final PrintStream pw ) {
TreeWalkerContext context = new TreeWalkerContext() ;
Visitor visitor = new TreeWalker( context ) {
final CodegenPrinter pr = new CodegenPrinter( pw, 2, '.' ) ;
private boolean done( Node node ) {
displayAttributes( node, pr ) ;
pr.in() ;
return true ;
}
@Override
public boolean preNode( Node arg ) {
pr.nl().p("Node").p(getNodeIdString(arg))
.p("[").p(arg.toString()).p("]") ;
return done( arg ) ;
}
@Override
public void postNode( Node arg ) {
pr.out() ;
}
@Override
public boolean preClassGenerator( ClassGeneratorImpl arg ) {
pr.nl().p("ClassGenerator").p(getNodeIdString(arg))
.p("[").p(Modifier.toString(arg.modifiers()))
.p(" ").p((arg.isInterface() ? "interface" : "class"))
.p(" ").p(arg.name()).p("]") ;
return done( arg ) ;
}
@Override
public boolean preMethodGenerator( MethodGenerator arg ) {
pr.nl().p( "MethodGenerator").p(getNodeIdString(arg))
.p("[").p(Modifier.toString(arg.modifiers()))
.p(" ").p(arg.returnType().name()).p(" ").p(arg.name()).p("]") ;
return done( arg ) ;
}
@Override
public boolean preThrowStatement( ThrowStatement arg ) {
pr.nl().p("ThrowStatement").p(getNodeIdString(arg)) ;
return done( arg ) ;
}
@Override
public boolean preAssignmentStatement( AssignmentStatement arg ) {
pr.nl().p("AssignmentStatement").p(getNodeIdString(arg)) ;
return done( arg ) ;
}
@Override
public boolean preBlockStatement( BlockStatement arg ) {
pr.nl().p("BlockStatement").p(getNodeIdString(arg)) ;
return done( arg ) ;
}
@Override
public boolean preCaseBranch( CaseBranch arg ) {
pr.nl().p("CaseBranch").p(getNodeIdString(arg))
.p("[").p(Integer.toString(arg.label())).p("]") ;
return done( arg ) ;
}
@Override
public boolean preDefinitionStatement( DefinitionStatement arg ) {
pr.nl().p("DefinitionStatement").p(getNodeIdString(arg)) ;
return done( arg ) ;
}
@Override
public boolean preIfStatement( IfStatement arg ) {
pr.nl().p("IfStatement").p(getNodeIdString(arg)) ;
return done( arg ) ;
}
@Override
public void ifStatementBeforeTruePart( IfStatement arg ) {
pr.out().nl().p("IfStatement:true").in() ;
}
@Override
public boolean ifStatementBeforeFalsePart( IfStatement arg ) {
pr.out().nl().p("IfStatement:false").in() ;
return true ;
}
@Override
public boolean preBreakStatement( BreakStatement arg ) {
pr.nl().p("BreakStatement").p(getNodeIdString(arg)) ;
return done( arg ) ;
}
@Override
public boolean preReturnStatement( ReturnStatement arg ) {
pr.nl().p("ReturnStatement").p(getNodeIdString(arg)) ;
return done( arg ) ;
}
@Override
public boolean preSwitchStatement( SwitchStatement arg ) {
pr.nl().p("SwitchStatement").p(getNodeIdString(arg)) ;
return done( arg ) ;
}
@Override
public boolean preTryStatement( TryStatement arg ) {
pr.nl().p("TryStatement").p(getNodeIdString(arg)) ;
return done( arg ) ;
}
@Override
public void tryStatementBeforeBlock( TryStatement arg,
Type type, Variable var, BlockStatement block ) {
VariableInternal ivar = (VariableInternal)var ;
pr.out().nl().p("TryStatement:catch[").p("type=").p(type.name())
.p(",var=").p(ivar.ident()).p("]").in() ;
ivar.accept( this ) ;
}
@Override
public boolean tryStatementBeforeFinalPart( TryStatement arg ) {
pr.out().nl().p("TryStatement:finally").in() ;
return true ;
}
@Override
public boolean preWhileStatement( WhileStatement arg ) {
pr.nl().p("WhileStatement").p(getNodeIdString(arg)) ;
return done( arg ) ;
}
@Override
public boolean preExpression( ExpressionInternal arg ) {
pr.nl().p(arg.toString()) ;
return done( arg ) ;
}
@Override
public boolean preFieldGenerator( FieldGenerator arg ) {
pr.nl().p(arg.toString()) ;
return done( arg ) ;
}
} ;
context.push( visitor ) ;
node.accept( visitor ) ;
}
}