package x10.wala.tree.visit;
import x10.wala.tree.X10CAstEntity;
import x10.wala.tree.X10CastNode;
import com.ibm.wala.cast.tree.*;
import com.ibm.wala.cast.tree.visit.*;
/**
* @author Igor Peshansky
* Extend DelegatingCAstVisitor to accommodate X10 CAst nodes and entities.
* Doesn't work for visit/leaveEntity, visit/leaveNode, visit/leaveAssign...
* TODO: document me.
*/
public abstract class X10DelegatingCAstVisitor extends DelegatingCAstVisitor {
/**
* X10CAstVisitor constructor.
* Needs to have a valid (non-null) delegate visitor.
* @param delegate the visitor to delegate to for default implementation
*/
protected X10DelegatingCAstVisitor(CAstVisitor delegate) {
super(delegate);
}
/**
* X10CAstVisitor default constructor.
*/
protected X10DelegatingCAstVisitor() {
this(new JavaCAstVisitor());
}
/**
* A no-op Java CAst visitor.
*/
private static final class JavaCAstVisitor extends CAstVisitor { }
/**
* Entity processing hook; sub-classes are expected to override if they
* introduce new entity types.
* Should invoke super.doVisitEntity() for unprocessed entities.
* @return true if entity was handled
*/
protected boolean doVisitEntity(CAstEntity n, Context context, CAstVisitor visitor_) {
X10DelegatingCAstVisitor visitor = (X10DelegatingCAstVisitor)visitor_;
switch (n.getKind()) {
case X10CAstEntity.ASYNC_BODY: {
Context codeContext = visitor.makeCodeContext(context, n);
visitor.visitAsyncBodyEntity(n, context, codeContext, visitor);
// visit the AST if any
if (n.getAST() != null)
visitor.visit(n.getAST(), codeContext, visitor);
// process any remaining scoped children
visitor.visitScopedEntities(n, n.getScopedEntities(null), codeContext, visitor);
visitor.leaveAsyncBodyEntity(n, context, codeContext, visitor);
break;
}
case X10CAstEntity.CLOSURE_BODY: {
Context codeContext = visitor.makeCodeContext(context, n);
visitor.visitClosureBodyEntity(n, context, codeContext, visitor);
// visit the AST if any
if (n.getAST() != null)
visitor.visit(n.getAST(), codeContext, visitor);
// process any remaining scoped children
visitor.visitScopedEntities(n, n.getScopedEntities(null), codeContext, visitor);
visitor.leaveClosureBodyEntity(n, context, codeContext, visitor);
break;
}
default:
return super.doVisitEntity(n, context, visitor);
}
return true;
}
/**
* Visit an AsyncBody entity.
* @param n the entity to process
* @param context a visitor-specific context
* @param codeContext a visitor-specific context for this script
* @return true if no further processing is needed
*/
protected boolean visitAsyncBodyEntity(CAstEntity n, Context context, Context codeContext, CAstVisitor visitor) { return visitor.visitEntity(n, context, visitor); }
/**
* Leave an AsyncBody entity.
* @param n the entity to process
* @param context a visitor-specific context
* @param codeContext a visitor-specific context for this script
*/
protected void leaveAsyncBodyEntity(CAstEntity n, Context context, Context codeContext, CAstVisitor visitor) { visitor.leaveEntity(n, context, visitor); }
/**
* Visit an AsyncBody entity.
* @param n the entity to process
* @param context a visitor-specific context
* @param codeContext a visitor-specific context for this script
* @return true if no further processing is needed
*/
protected boolean visitClosureBodyEntity(CAstEntity n, Context context, Context codeContext, CAstVisitor visitor) { return visitor.visitEntity(n, context, visitor); }
/**
* Leave an AsyncBody entity.
* @param n the entity to process
* @param context a visitor-specific context
* @param codeContext a visitor-specific context for this script
*/
protected void leaveClosureBodyEntity(CAstEntity n, Context context, Context codeContext, CAstVisitor visitor) { visitor.leaveEntity(n, context, visitor); }
/**
* Node processing hook; sub-classes are expected to override if they
* introduce new node types.
* Should invoke super.doVisit() for unprocessed nodes.
* @return true if node was handled
*/
protected boolean doVisit(CAstNode n, Context context, CAstVisitor visitor_) {
X10DelegatingCAstVisitor visitor = (X10DelegatingCAstVisitor)visitor_;
switch (n.getKind()) {
case X10CastNode.ASYNC: {
if (visitor.visitAsyncInvoke(n, context, visitor))
break;
for(int i = 0; i < n.getChildCount(); i++) {
visitor.visit(n.getChild(i), context, visitor);
}
visitor.leaveAsyncInvoke(n, context, visitor);
break;
}
case X10CastNode.ATOMIC_ENTER: {
if (visitor.visitAtomicEnter(n, context, visitor))
break;
visitor.leaveAtomicEnter(n, context, visitor);
break;
}
case X10CastNode.ATOMIC_EXIT: {
if (visitor.visitAtomicExit(n, context, visitor))
break;
visitor.leaveAtomicExit(n, context, visitor);
break;
}
case X10CastNode.FINISH_ENTER: {
if (visitor.visitFinishEnter(n, context, visitor))
break;
visitor.leaveFinishEnter(n, context, visitor);
break;
}
case X10CastNode.FINISH_EXIT: {
if (visitor.visitFinishExit(n, context, visitor))
break;
visitor.leaveFinishExit(n, context, visitor);
break;
}
case X10CastNode.ITER_INIT: {
if (visitor.visitIterInit(n, context, visitor))
break;
visitor.visit(n.getChild(0), context, visitor);
visitor.leaveIterInit(n, context, visitor);
break;
}
case X10CastNode.ITER_HASNEXT: {
if (visitor.visitIterHasNext(n, context, visitor))
break;
visitor.visit(n.getChild(0), context, visitor);
visitor.leaveIterHasNext(n, context, visitor);
break;
}
case X10CastNode.ITER_NEXT: {
if (visitor.visitIterNext(n, context, visitor))
break;
visitor.visit(n.getChild(0), context, visitor);
visitor.leaveIterNext(n, context, visitor);
break;
}
case X10CastNode.HERE: {
if (visitor.visitHere(n, context, visitor))
break;
visitor.leaveHere(n, context, visitor);
break;
}
case X10CastNode.NEXT: {
visitor.visitNext(n, context, visitor);
break;
}
case X10CastNode.ARRAY_REF_BY_POINT: {
if (visitor.visitArrayRef(n, context, visitor))
break;
visitor.visit(n.getChild(0), context, visitor); // the array expr
// n.getChild(1) is a TypeReference for the array element type...
visitor.visit(n.getChild(2), context, visitor); // the index expr
visitor.leaveArrayRef(n, context, visitor);
break;
}
case X10CastNode.TUPLE: {
if (visitor.visitTupleExpr(n, context, visitor))
break;
// n.getChild(0) is a TypeReference for the tuple element type...
for(int i=1; i < n.getChildCount(); i++) {
visitor.visit(n.getChild(i), context, visitor);
}
visitor.leaveTupleExpr(n, context, visitor);
break;
}
case X10CastNode.AT_STMT_ENTER:
if (visitor.visitAtStmtEnter(n, context, visitor))
break;
visitor.leaveAtStmtEnter(n, context, visitor);
case X10CastNode.AT_STMT_EXIT:
if (visitor.visitAtStmtExit(n, context, visitor))
break;
visitor.leaveAtStmtExit(n, context, visitor);
default:
return super.doVisit(n, context, visitor);
}
return true;
}
/**
* Visit an Async node.
* @param n the node to process
* @param c a visitor-specific context
* @return true if no further processing is needed
*/
protected boolean visitAsyncInvoke(CAstNode n, Context c, CAstVisitor visitor) { return visitor.visitNode(n, c, visitor); }
/**
* Leave an Async node.
* @param n the node to process
* @param c a visitor-specific context
*/
protected void leaveAsyncInvoke(CAstNode n, Context c, CAstVisitor visitor) { visitor.leaveNode(n, c, visitor); }
/**
* Visit an Async node.
* @param n the node to process
* @param c a visitor-specific context
* @return true if no further processing is needed
*/
protected boolean visitAtomicEnter(CAstNode n, Context c, CAstVisitor visitor) { return visitor.visitNode(n, c, visitor); }
/**
* Leave an Async node.
* @param n the node to process
* @param c a visitor-specific context
*/
protected void leaveAtomicEnter(CAstNode n, Context c, CAstVisitor visitor) { visitor.leaveNode(n, c, visitor); }
/**
* Visit an Async node.
* @param n the node to process
* @param c a visitor-specific context
* @return true if no further processing is needed
*/
protected boolean visitAtomicExit(CAstNode n, Context c, CAstVisitor visitor) { return visitor.visitNode(n, c, visitor); }
/**
* Leave an Async node.
* @param n the node to process
* @param c a visitor-specific context
*/
protected void leaveAtomicExit(CAstNode n, Context c, CAstVisitor visitor) { visitor.leaveNode(n, c, visitor); }
/**
* Visit an Async node.
* @param n the node to process
* @param c a visitor-specific context
* @return true if no further processing is needed
*/
protected boolean visitFinishEnter(CAstNode n, Context c, CAstVisitor visitor) { return visitor.visitNode(n, c, visitor); }
/**
* Leave an Async node.
* @param n the node to process
* @param c a visitor-specific context
*/
protected void leaveFinishEnter(CAstNode n, Context c, CAstVisitor visitor) { visitor.leaveNode(n, c, visitor); }
/**
* Visit an Async node.
* @param n the node to process
* @param c a visitor-specific context
* @return true if no further processing is needed
*/
protected boolean visitFinishExit(CAstNode n, Context c, CAstVisitor visitor) { return visitor.visitNode(n, c, visitor); }
/**
* Leave an Async node.
* @param n the node to process
* @param c a visitor-specific context
*/
protected void leaveFinishExit(CAstNode n, Context c, CAstVisitor visitor) { visitor.leaveNode(n, c, visitor); }
/**
* Visit an Async node.
* @param n the node to process
* @param c a visitor-specific context
* @return true if no further processing is needed
*/
protected boolean visitForce(CAstNode n, Context c, CAstVisitor visitor) { return visitor.visitNode(n, c, visitor); }
/**
* Leave an Async node.
* @param n the node to process
* @param c a visitor-specific context
*/
protected void leaveForce(CAstNode n, Context c, CAstVisitor visitor) { visitor.leaveNode(n, c, visitor); }
/**
* Visit an Async node.
* @param n the node to process
* @param c a visitor-specific context
* @return true if no further processing is needed
*/
protected boolean visitIterInit(CAstNode n, Context c, CAstVisitor visitor) { return visitor.visitNode(n, c, visitor); }
/**
* Leave an Async node.
* @param n the node to process
* @param c a visitor-specific context
*/
protected void leaveIterInit(CAstNode n, Context c, CAstVisitor visitor) { visitor.leaveNode(n, c, visitor); }
/**
* Visit an Async node.
* @param n the node to process
* @param c a visitor-specific context
* @return true if no further processing is needed
*/
protected boolean visitIterHasNext(CAstNode n, Context c, CAstVisitor visitor) { return visitor.visitNode(n, c, visitor); }
/**
* Leave an Async node.
* @param n the node to process
* @param c a visitor-specific context
*/
protected void leaveIterHasNext(CAstNode n, Context c, CAstVisitor visitor) { visitor.leaveNode(n, c, visitor); }
/**
* Visit an Async node.
* @param n the node to process
* @param c a visitor-specific context
* @return true if no further processing is needed
*/
protected boolean visitIterNext(CAstNode n, Context c, CAstVisitor visitor) { return visitor.visitNode(n, c, visitor); }
/**
* Leave an Async node.
* @param n the node to process
* @param c a visitor-specific context
*/
protected void leaveIterNext(CAstNode n, Context c, CAstVisitor visitor) { visitor.leaveNode(n, c, visitor); }
/**
* Visit an Async node.
* @param n the node to process
* @param c a visitor-specific context
* @return true if no further processing is needed
*/
protected boolean visitHere(CAstNode n, Context c, CAstVisitor visitor) { return visitor.visitNode(n, c, visitor); }
/**
* Leave a here node.
* @param n the node to process
* @param c a visitor-specific context
*/
protected void leaveHere(CAstNode n, Context c, CAstVisitor visitor) { visitor.leaveNode(n, c, visitor); }
/**
* Visit an Async node.
* @param n the node to process
* @param c a visitor-specific context
* @return true if no further processing is needed
*/
protected boolean visitNext(CAstNode n, Context c, CAstVisitor visitor) { return visitor.visitNode(n, c, visitor); }
/**
* Leave a PLACE_OF_POINT node.
* @param n the node to process
* @param c a visitor-specific context
*/
protected void leavePlaceOfPoint(CAstNode n, Context c, CAstVisitor visitor) { visitor.leaveNode(n, c, visitor); }
/**
* Visit a PLACE_OF_POINT node.
* @param n the node to process
* @param c a visitor-specific context
*/
protected boolean visitPlaceOfPoint(CAstNode n, Context c, CAstVisitor visitor) { return visitor.visitNode(n, c, visitor); }
/**
* Visit a TUPLE_EXPR node.
* @param n the node to process
* @param c a visitor-specific context
*/
protected boolean visitTupleExpr(CAstNode n, Context c, CAstVisitor visitor) { return visitor.visitNode(n, c, visitor); }
/**
* Leave a TUPLE_EXPR node.
* @param n the node to process
* @param c a visitor-specific context
*/
protected void leaveTupleExpr(CAstNode n, Context c, CAstVisitor visitor) { visitor.leaveNode(n, c, visitor); }
/**
* Visits the AtStmt node at the beginning of the block code.
*
* @param node The node to process.
* @param context A visitor-specific context.
* @param visitor The CAst visitor for redirection.
* @return True if no further processing is needed, false otherwise.
*/
protected boolean visitAtStmtEnter(final CAstNode node, final Context context, final CAstVisitor visitor) {
return visitor.visitNode(node, context, visitor);
}
/**
* Leaves the AtStmt node at the beginning of the block code.
*
* @param node The node to process.
* @param context A visitor-specific context.
* @param visitor The CAst visitor for redirection.
*/
protected void leaveAtStmtEnter(final CAstNode node, final Context context, final CAstVisitor visitor) {
visitor.leaveNode(node, context, visitor);
}
/**
* Visits the AtStmt node at the end of the block code.
*
* @param node The node to process.
* @param context A visitor-specific context.
* @param visitor The CAst visitor for redirection.
* @return True if no further processing is needed, false otherwise.
*/
protected boolean visitAtStmtExit(final CAstNode node, final Context context, final CAstVisitor visitor) {
return visitor.visitNode(node, context, visitor);
}
/**
* Leaves the AtStmt node at the end of the block code.
*
* @param node The node to process.
* @param context A visitor-specific context.
* @param visitor The CAst visitor for redirection.
*/
protected void leaveAtStmtExit(final CAstNode node, final Context context, final CAstVisitor visitor) {
visitor.leaveNode(node, context, visitor);
}
}