refactoring, javadoc, formatting

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@4135 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
msridhar1 2011-04-21 21:34:15 +00:00
parent 4f27f73bf0
commit cf13f9f071
1 changed files with 123 additions and 114 deletions

View File

@ -82,7 +82,13 @@ public class RhinoToAstTranslator {
String getForInInitVar(); String getForInInitVar();
void addInitializer(CAstNode n); /**
* Add a name declaration to this context. For variables or constants, n
* should be a {@link CAstNode#DECL_STMT}, and the initialization of the
* variable (if any) may occur in a separate assignment. For functions, n
* should be a {@link CAstNode#FUNCTION_STMT}, including the function body.
*/
void addNameDecl(CAstNode n);
} }
private static class RootContext implements WalkContext { private static class RootContext implements WalkContext {
@ -144,7 +150,7 @@ public class RhinoToAstTranslator {
return null; return null;
} }
public void addInitializer(CAstNode n) { public void addNameDecl(CAstNode n) {
} }
} }
@ -215,8 +221,8 @@ public class RhinoToAstTranslator {
return parent.getForInInitVar(); return parent.getForInInitVar();
} }
public void addInitializer(CAstNode n) { public void addNameDecl(CAstNode n) {
parent.addInitializer(n); parent.addNameDecl(n);
} }
} }
@ -225,7 +231,7 @@ public class RhinoToAstTranslator {
private final Map<CAstNode, HashSet<CAstEntity>> scopedEntities = HashMapFactory.make(); private final Map<CAstNode, HashSet<CAstEntity>> scopedEntities = HashMapFactory.make();
private final List<CAstNode> initializers = new ArrayList<CAstNode>(); private final List<CAstNode> nameDecls = new ArrayList<CAstNode>();
private final CAstSourcePositionRecorder pos = new CAstSourcePositionRecorder(); private final CAstSourcePositionRecorder pos = new CAstSourcePositionRecorder();
@ -273,8 +279,9 @@ public class RhinoToAstTranslator {
return null; return null;
} }
public void addInitializer(CAstNode n) { public void addNameDecl(CAstNode n) {
initializers.add(n); assert n.getKind() == CAstNode.FUNCTION_STMT || n.getKind() == CAstNode.DECL_STMT;
nameDecls.add(n);
} }
public CAstNode getCatchTarget() { public CAstNode getCatchTarget() {
@ -514,19 +521,19 @@ public class RhinoToAstTranslator {
// code is fishy. This should be cleaned up and the unchecked suppressWarnings // code is fishy. This should be cleaned up and the unchecked suppressWarnings
// should be removed. // should be removed.
private CAstEntity walkEntity(final ScriptOrFnNode n, WalkContext context) { private CAstEntity walkEntity(final ScriptOrFnNode n, WalkContext context) {
final FunctionContext child = (n instanceof FunctionNode) ? new FunctionContext(context, n) : new ScriptContext( final FunctionContext child = (n instanceof FunctionNode) ? new FunctionContext(context, n) : new ScriptContext(context, n,
context, n, n.getSourceName()); n.getSourceName());
CAstNode[] stmts = gatherChildren(n, child); CAstNode[] stmts = gatherChildren(n, child);
// add initializers, if any // add variable / constant / function declarations, if any
if (!child.initializers.isEmpty()) { if (!child.nameDecls.isEmpty()) {
// new first statement will be a block declaring all names.
CAstNode[] newStmts = new CAstNode[stmts.length + 1]; CAstNode[] newStmts = new CAstNode[stmts.length + 1];
newStmts[0] = Ast.makeNode(CAstNode.BLOCK_STMT, child.initializers.toArray(new CAstNode[child.initializers.size()])); newStmts[0] = Ast.makeNode(CAstNode.BLOCK_STMT, child.nameDecls.toArray(new CAstNode[child.nameDecls.size()]));
for (int i = 0; i < stmts.length; i++) System.arraycopy(stmts, 0, newStmts, 1, stmts.length);
newStmts[i + 1] = stmts[i];
stmts = newStmts; stmts = newStmts;
} }
@ -542,7 +549,7 @@ public class RhinoToAstTranslator {
if (v instanceof Collection) if (v instanceof Collection)
subs.put(k, (Set<CAstEntity>) v); subs.put(k, (Set<CAstEntity>) v);
else { else {
Set<CAstEntity> s = Collections.singleton((CAstEntity)v); Set<CAstEntity> s = Collections.singleton((CAstEntity) v);
subs.put(k, s); subs.put(k, s);
} }
} }
@ -687,7 +694,7 @@ public class RhinoToAstTranslator {
URL url = sourceModule.getURL(); URL url = sourceModule.getURL();
int line = n.getLineno(); int line = n.getLineno();
if (sourceModule instanceof MappedSourceModule) { if (sourceModule instanceof MappedSourceModule) {
Position loc = ((MappedSourceModule)sourceModule).getMapping().getAssociatedFileAndLine(line); Position loc = ((MappedSourceModule) sourceModule).getMapping().getAssociatedFileAndLine(line);
if (loc != null) { if (loc != null) {
return loc; return loc;
} }
@ -732,7 +739,7 @@ public class RhinoToAstTranslator {
return fun; return fun;
} else { } else {
context.addInitializer(Ast.makeNode(CAstNode.FUNCTION_STMT, Ast.makeConstant(fne))); context.addNameDecl(Ast.makeNode(CAstNode.FUNCTION_STMT, Ast.makeConstant(fne)));
context.addScopedEntity(null, fne); context.addScopedEntity(null, fne);
@ -795,8 +802,8 @@ public class RhinoToAstTranslator {
for (Iterator<Node> cns = catchList.iterator(); cns.hasNext();) { for (Iterator<Node> cns = catchList.iterator(); cns.hasNext();) {
catchAsts[i++] = walkNodes(cns.next(), catchChild); catchAsts[i++] = walkNodes(cns.next(), catchChild);
} }
CAstNode catchBlock = Ast.makeNode(CAstNode.CATCH, Ast.makeConstant(catchChild.getCatchVar()), Ast.makeNode( CAstNode catchBlock = Ast.makeNode(CAstNode.CATCH, Ast.makeConstant(catchChild.getCatchVar()),
CAstNode.BLOCK_STMT, catchAsts)); Ast.makeNode(CAstNode.BLOCK_STMT, catchAsts));
context.cfg().map(catchBlock, catchBlock); context.cfg().map(catchBlock, catchBlock);
i = 0; i = 0;
@ -808,8 +815,8 @@ public class RhinoToAstTranslator {
CAstNode tryBlock = Ast.makeNode(CAstNode.BLOCK_STMT, tryAsts); CAstNode tryBlock = Ast.makeNode(CAstNode.BLOCK_STMT, tryAsts);
if (finallyBlock != null) { if (finallyBlock != null) {
return Ast.makeNode(CAstNode.BLOCK_STMT, Ast.makeNode(CAstNode.UNWIND, Ast.makeNode(CAstNode.TRY, tryBlock, catchBlock), return Ast.makeNode(CAstNode.BLOCK_STMT,
finallyBlock), walkNodes(c, context)); Ast.makeNode(CAstNode.UNWIND, Ast.makeNode(CAstNode.TRY, tryBlock, catchBlock), finallyBlock), walkNodes(c, context));
} else { } else {
return Ast.makeNode(CAstNode.BLOCK_STMT, Ast.makeNode(CAstNode.TRY, tryBlock, catchBlock), walkNodes(c, context)); return Ast.makeNode(CAstNode.BLOCK_STMT, Ast.makeNode(CAstNode.TRY, tryBlock, catchBlock), walkNodes(c, context));
} }
@ -822,8 +829,10 @@ public class RhinoToAstTranslator {
} }
CAstNode tryBlock = Ast.makeNode(CAstNode.BLOCK_STMT, tryAsts); CAstNode tryBlock = Ast.makeNode(CAstNode.BLOCK_STMT, tryAsts);
return Ast.makeNode(CAstNode.BLOCK_STMT, Ast.makeNode(CAstNode.UNWIND, Ast.makeNode(CAstNode.BLOCK_STMT, tryBlock), Ast return Ast.makeNode(
.makeNode(CAstNode.BLOCK_STMT, finallyBlock)), walkNodes(c, context)); CAstNode.BLOCK_STMT,
Ast.makeNode(CAstNode.UNWIND, Ast.makeNode(CAstNode.BLOCK_STMT, tryBlock),
Ast.makeNode(CAstNode.BLOCK_STMT, finallyBlock)), walkNodes(c, context));
} }
} }
@ -853,13 +862,12 @@ public class RhinoToAstTranslator {
} }
/* /*
case Token.ENTERWITH: { * case Token.ENTERWITH: { return
return Ast.makeNode(JavaScriptCAstNode.ENTER_WITH, walkNodes(n.getFirstChild(), context)); * Ast.makeNode(JavaScriptCAstNode.ENTER_WITH,
} * walkNodes(n.getFirstChild(), context)); }
*
case Token.LEAVEWITH: { * case Token.LEAVEWITH: { return
return Ast.makeNode(JavaScriptCAstNode.EXIT_WITH, Ast.makeConstant(null)); * Ast.makeNode(JavaScriptCAstNode.EXIT_WITH, Ast.makeConstant(null)); }
}
*/ */
case Token.ENTERWITH: case Token.ENTERWITH:
case Token.LEAVEWITH: { case Token.LEAVEWITH: {
@ -899,13 +907,14 @@ public class RhinoToAstTranslator {
labelCasts.add(labelCast); labelCasts.add(labelCast);
context.cfg().add(c1, target, labelCast); context.cfg().add(c1, target, labelCast);
} }
CAstNode[] children = new CAstNode[labelCasts.size()+1]; CAstNode[] children = new CAstNode[labelCasts.size() + 1];
int i = 0; int i = 0;
children[i++] = Ast.makeNode(CAstNode.BLOCK_STMT, defaultLabel, gatherChildren(n, context, 1)); children[i++] = Ast.makeNode(CAstNode.BLOCK_STMT, defaultLabel, gatherChildren(n, context, 1));
// Note that we are placing the labels as children in the AST // Note that we are placing the labels as children in the AST
// even if they are not used, because we want them copied when AST is re-written. // even if they are not used, because we want them copied when AST is
for (CAstNode labelCast : labelCasts){ // re-written.
for (CAstNode labelCast : labelCasts) {
children[i++] = labelCast; children[i++] = labelCast;
} }
@ -935,10 +944,7 @@ public class RhinoToAstTranslator {
} }
case Token.POS: { case Token.POS: {
return return Ast.makeNode(CAstNode.UNARY_EXPR, translateOpcode(Token.ADD), walkNodes(n.getFirstChild(), context));
Ast.makeNode(CAstNode.UNARY_EXPR,
translateOpcode(Token.ADD),
walkNodes(n.getFirstChild(), context));
} }
case Token.CALL: { case Token.CALL: {
@ -949,8 +955,11 @@ public class RhinoToAstTranslator {
CAstNode fun = walkNodes(callee, child); CAstNode fun = walkNodes(callee, child);
if (child.foundBase(callee)) if (child.foundBase(callee))
return Ast.makeNode(CAstNode.LOCAL_SCOPE, Ast.makeNode(CAstNode.BLOCK_EXPR, Ast.makeNode(CAstNode.DECL_STMT, Ast return Ast.makeNode(
.makeConstant(new CAstSymbolImpl("base")), Ast.makeConstant(null)), makeCall(fun, base, callee.getNext(), context))); CAstNode.LOCAL_SCOPE,
Ast.makeNode(CAstNode.BLOCK_EXPR,
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl("base")), Ast.makeConstant(null)),
makeCall(fun, base, callee.getNext(), context)));
else else
return makeCall(fun, Ast.makeConstant(null), callee.getNext(), context); return makeCall(fun, Ast.makeConstant(null), callee.getNext(), context);
} else { } else {
@ -1030,14 +1039,14 @@ public class RhinoToAstTranslator {
List<CAstNode> result = new ArrayList<CAstNode>(); List<CAstNode> result = new ArrayList<CAstNode>();
Node nm = n.getFirstChild(); Node nm = n.getFirstChild();
while (nm != null) { while (nm != null) {
context.addInitializer(Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(nm.getString())), context.addNameDecl(Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(nm.getString())),
readName(context, "$$undefined"))); readName(context, "$$undefined")));
if (nm.getFirstChild() != null) { if (nm.getFirstChild() != null) {
WalkContext child = new ExpressionContext(context); WalkContext child = new ExpressionContext(context);
result.add(Ast.makeNode(CAstNode.ASSIGN, Ast.makeNode(CAstNode.VAR, Ast.makeConstant(nm.getString())), walkNodes(nm result.add(Ast.makeNode(CAstNode.ASSIGN, Ast.makeNode(CAstNode.VAR, Ast.makeConstant(nm.getString())),
.getFirstChild(), child))); walkNodes(nm.getFirstChild(), child)));
} }
@ -1054,8 +1063,8 @@ public class RhinoToAstTranslator {
case Token.REGEXP: { case Token.REGEXP: {
int regexIdx = n.getIntProp(Node.REGEXP_PROP, -1); int regexIdx = n.getIntProp(Node.REGEXP_PROP, -1);
assert regexIdx != -1 : "while converting: " + context.top().toStringTree(context.top()) assert regexIdx != -1 : "while converting: " + context.top().toStringTree(context.top()) + "\nlooking at bad regex:\n "
+ "\nlooking at bad regex:\n " + n.toStringTree(context.top()); + n.toStringTree(context.top());
String flags = context.top().getRegexpFlags(regexIdx); String flags = context.top().getRegexpFlags(regexIdx);
Node flagsNode = Node.newString(flags); Node flagsNode = Node.newString(flags);
@ -1100,8 +1109,8 @@ public class RhinoToAstTranslator {
case Token.IFEQ: { case Token.IFEQ: {
context.cfg().add(n, ((Node.Jump) n).target, Boolean.TRUE); context.cfg().add(n, ((Node.Jump) n).target, Boolean.TRUE);
WalkContext child = new ExpressionContext(context); WalkContext child = new ExpressionContext(context);
CAstNode gotoAst = Ast.makeNode(CAstNode.IFGOTO, translateOpcode(NT), walkNodes(n.getFirstChild(), child), Ast CAstNode gotoAst = Ast.makeNode(CAstNode.IFGOTO, translateOpcode(NT), walkNodes(n.getFirstChild(), child),
.makeConstant(1)); Ast.makeConstant(1));
context.cfg().map(n, gotoAst); context.cfg().map(n, gotoAst);
return gotoAst; return gotoAst;
@ -1167,8 +1176,8 @@ public class RhinoToAstTranslator {
Node l = n.getFirstChild(); Node l = n.getFirstChild();
CAstNode last = walkNodes(l, context); CAstNode last = walkNodes(l, context);
return Ast.makeNode((((flags & Node.POST_FLAG) != 0) ? CAstNode.ASSIGN_POST_OP : CAstNode.ASSIGN_PRE_OP), last, Ast return Ast.makeNode((((flags & Node.POST_FLAG) != 0) ? CAstNode.ASSIGN_POST_OP : CAstNode.ASSIGN_PRE_OP), last,
.makeConstant(1), op); Ast.makeConstant(1), op);
} }
case Token.NEW: { case Token.NEW: {
@ -1237,7 +1246,8 @@ public class RhinoToAstTranslator {
CAstNode get, result; CAstNode get, result;
if (baseVar != null) { if (baseVar != null) {
result = Ast.makeNode(CAstNode.BLOCK_EXPR, Ast.makeNode(CAstNode.ASSIGN, baseVar, rcvr), get = Ast.makeNode(CAstNode.OBJECT_REF, baseVar, elt)); result = Ast.makeNode(CAstNode.BLOCK_EXPR, Ast.makeNode(CAstNode.ASSIGN, baseVar, rcvr),
get = Ast.makeNode(CAstNode.OBJECT_REF, baseVar, elt));
} else { } else {
result = get = Ast.makeNode(CAstNode.OBJECT_REF, rcvr, elt); result = get = Ast.makeNode(CAstNode.OBJECT_REF, rcvr, elt);
} }
@ -1272,8 +1282,8 @@ public class RhinoToAstTranslator {
CAstNode elt = walkNodes(element, context); CAstNode elt = walkNodes(element, context);
if (baseVar != null) { if (baseVar != null) {
return Ast.makeNode(CAstNode.BLOCK_EXPR, Ast.makeNode(CAstNode.ASSIGN, baseVar, rcvr), Ast.makeNode(CAstNode.ASSIGN, Ast return Ast.makeNode(CAstNode.BLOCK_EXPR, Ast.makeNode(CAstNode.ASSIGN, baseVar, rcvr),
.makeNode(CAstNode.OBJECT_REF, baseVar, elt), Ast.makeConstant(null))); Ast.makeNode(CAstNode.ASSIGN, Ast.makeNode(CAstNode.OBJECT_REF, baseVar, elt), Ast.makeConstant(null)));
} else { } else {
return Ast.makeNode(CAstNode.ASSIGN, Ast.makeNode(CAstNode.OBJECT_REF, rcvr, elt), Ast.makeConstant(null)); return Ast.makeNode(CAstNode.ASSIGN, Ast.makeNode(CAstNode.OBJECT_REF, rcvr, elt), Ast.makeConstant(null));
} }
@ -1295,8 +1305,8 @@ public class RhinoToAstTranslator {
CAstNode rcvr = walkNodes(receiver, context); CAstNode rcvr = walkNodes(receiver, context);
return Ast.makeNode(CAstNode.ASSIGN_POST_OP, Ast.makeNode(CAstNode.OBJECT_REF, rcvr, walkNodes(elt, context)), walkNodes(op return Ast.makeNode(CAstNode.ASSIGN_POST_OP, Ast.makeNode(CAstNode.OBJECT_REF, rcvr, walkNodes(elt, context)),
.getFirstChild().getNext(), context), translateOpcode(op.getType())); walkNodes(op.getFirstChild().getNext(), context), translateOpcode(op.getType()));
} }
case Token.THROW: { case Token.THROW: {
@ -1319,23 +1329,18 @@ public class RhinoToAstTranslator {
case Token.INSTANCEOF: { case Token.INSTANCEOF: {
Node value = n.getFirstChild(); Node value = n.getFirstChild();
Node type = value.getNext(); Node type = value.getNext();
return Ast.makeNode(CAstNode.INSTANCEOF, return Ast.makeNode(CAstNode.INSTANCEOF, walkNodes(value, context), walkNodes(type, context));
walkNodes( value, context ),
walkNodes( type, context ));
} }
case Token.IN: { case Token.IN: {
Node value = n.getFirstChild(); Node value = n.getFirstChild();
Node property = value.getNext(); Node property = value.getNext();
return Ast.makeNode(CAstNode.IS_DEFINED_EXPR, return Ast.makeNode(CAstNode.IS_DEFINED_EXPR, walkNodes(value, context), walkNodes(property, context));
walkNodes( value, context ),
walkNodes( property, context ));
} }
default: { default: {
System.err.println("while converting: " + context.top().toStringTree(context.top()) + "\nlooking at unhandled:\n " System.err.println("while converting: " + context.top().toStringTree(context.top()) + "\nlooking at unhandled:\n "
+ n.toStringTree(context.top()) + "\n(of type " + NT + ") (of class " + n.getClass() + ")" + n.toStringTree(context.top()) + "\n(of type " + NT + ") (of class " + n.getClass() + ")" + " at " + n.getLineno());
+ " at " + n.getLineno());
Assertions.UNREACHABLE(); Assertions.UNREACHABLE();
return null; return null;
@ -1343,6 +1348,10 @@ public class RhinoToAstTranslator {
} }
} }
/**
* parse the JavaScript code using Rhino, and then translate the resulting AST
* to CAst
*/
public CAstEntity translate() throws java.io.IOException { public CAstEntity translate() throws java.io.IOException {
ToolErrorReporter reporter = new ToolErrorReporter(true); ToolErrorReporter reporter = new ToolErrorReporter(true);
CompilerEnvirons compilerEnv = new CompilerEnvirons(); CompilerEnvirons compilerEnv = new CompilerEnvirons();