simplify AST (idea like)

This commit is contained in:
develar
2012-10-25 08:42:06 +04:00
parent a5b212e975
commit c41bf918bf
60 changed files with 1085 additions and 1232 deletions
@@ -11,7 +11,6 @@ import com.google.dart.compiler.backend.js.ast.*;
* normally be surrounded by parentheses. * normally be surrounded by parentheses.
*/ */
public class JsConstructExpressionVisitor extends JsVisitor { public class JsConstructExpressionVisitor extends JsVisitor {
public static boolean exec(JsExpression expression) { public static boolean exec(JsExpression expression) {
if (JsPrecedenceVisitor.exec(expression) < JsPrecedenceVisitor.PRECEDENCE_NEW) { if (JsPrecedenceVisitor.exec(expression) < JsPrecedenceVisitor.PRECEDENCE_NEW) {
return true; return true;
@@ -21,7 +20,7 @@ public class JsConstructExpressionVisitor extends JsVisitor {
return visitor.containsInvocation; return visitor.containsInvocation;
} }
private boolean containsInvocation = false; private boolean containsInvocation;
private JsConstructExpressionVisitor() { private JsConstructExpressionVisitor() {
} }
@@ -85,7 +84,7 @@ public class JsConstructExpressionVisitor extends JsVisitor {
* We only look at nodes that would not normally be surrounded by parentheses. * We only look at nodes that would not normally be surrounded by parentheses.
*/ */
@Override @Override
public <T extends JsVisitable> T accept(T node) { public <T extends JsNode> T accept(T node) {
// Assign to Object to prevent 'inconvertible types' compile errors due // Assign to Object to prevent 'inconvertible types' compile errors due
// to http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6548436 // to http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6548436
// reproducible in jdk1.6.0_02. // reproducible in jdk1.6.0_02.
@@ -112,9 +112,4 @@ public class JsFirstExpressionVisitor extends JsVisitor {
public boolean visit(JsPrefixOperation x, JsContext ctx) { public boolean visit(JsPrefixOperation x, JsContext ctx) {
return false; return false;
} }
@Override
public boolean visit(JsRegExp x, JsContext ctx) {
return false;
}
} }
@@ -10,22 +10,22 @@ import com.google.dart.compiler.backend.js.ast.JsVars.JsVar;
/** /**
* Precedence indices from "JavaScript - The Definitive Guide" 4th Edition (page * Precedence indices from "JavaScript - The Definitive Guide" 4th Edition (page
* 57) * 57)
* * <p/>
* Precedence 17 is for indivisible primaries that either don't have children, * Precedence 17 is for indivisible primaries that either don't have children,
* or provide their own delimiters. * or provide their own delimiters.
* * <p/>
* Precedence 16 is for really important things that have their own AST classes. * Precedence 16 is for really important things that have their own AST classes.
* * <p/>
* Precedence 15 is for the new construct. * Precedence 15 is for the new construct.
* * <p/>
* Precedence 14 is for unary operators. * Precedence 14 is for unary operators.
* * <p/>
* Precedences 12 through 4 are for non-assigning binary operators. * Precedences 12 through 4 are for non-assigning binary operators.
* * <p/>
* Precedence 3 is for the tertiary conditional. * Precedence 3 is for the tertiary conditional.
* * <p/>
* Precedence 2 is for assignments. * Precedence 2 is for assignments.
* * <p/>
* Precedence 1 is for comma operations. * Precedence 1 is for comma operations.
*/ */
class JsPrecedenceVisitor extends JsVisitor { class JsPrecedenceVisitor extends JsVisitor {
@@ -116,7 +116,7 @@ class JsPrecedenceVisitor extends JsVisitor {
} }
@Override @Override
public boolean visit(JsEmpty x, JsContext ctx) { public void visit(JsEmpty x, JsContext ctx) {
throw new RuntimeException("Only expressions have precedence."); throw new RuntimeException("Only expressions have precedence.");
} }
@@ -161,7 +161,8 @@ class JsPrecedenceVisitor extends JsVisitor {
public boolean visit(JsNameRef x, JsContext ctx) { public boolean visit(JsNameRef x, JsContext ctx) {
if (x.isLeaf()) { if (x.isLeaf()) {
answer = 17; // primary answer = 17; // primary
} else { }
else {
answer = 16; // property access answer = 16; // property access
} }
return false; return false;
@@ -174,21 +175,18 @@ class JsPrecedenceVisitor extends JsVisitor {
} }
@Override @Override
public boolean visit(JsNullLiteral x, JsContext ctx) { public void visit(JsNullLiteral x, JsContext ctx) {
answer = 17; // primary answer = 17; // primary
return false;
} }
@Override @Override
public boolean visit(JsNumberLiteral.JsIntLiteral x, JsContext ctx) { public void visit(JsNumberLiteral.JsIntLiteral x, JsContext ctx) {
answer = 17; // primary answer = 17; // primary
return false;
} }
@Override @Override
public boolean visit(JsNumberLiteral.JsDoubleLiteral x, JsContext ctx) { public void visit(JsNumberLiteral.JsDoubleLiteral x, JsContext ctx) {
answer = 17; // primary answer = 17; // primary
return false;
} }
@Override @Override
@@ -226,9 +224,8 @@ class JsPrecedenceVisitor extends JsVisitor {
} }
@Override @Override
public boolean visit(JsRegExp x, JsContext ctx) { public void visit(JsRegExp x, JsContext ctx) {
answer = 17; // primary answer = 17; // primary
return false;
} }
@Override @Override
@@ -237,9 +234,8 @@ class JsPrecedenceVisitor extends JsVisitor {
} }
@Override @Override
public boolean visit(JsStringLiteral x, JsContext ctx) { public void visit(JsStringLiteral x, JsContext ctx) {
answer = 17; // primary answer = 17; // primary
return false;
} }
@Override @Override
@@ -55,11 +55,6 @@ public class JsRequiresSemiVisitor extends JsVisitor {
return false; return false;
} }
@Override
public boolean visit(JsEmpty x, JsContext ctx) {
return false;
}
@Override @Override
public boolean visit(JsExpressionStatement x, JsContext ctx) { public boolean visit(JsExpressionStatement x, JsContext ctx) {
return false; return false;
@@ -323,7 +323,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
public boolean visit(JsCase x, JsContext ctx) { public boolean visit(JsCase x, JsContext ctx) {
p.print(CHARS_CASE); p.print(CHARS_CASE);
space(); space();
accept(x.getCaseExpr()); accept(x.getCaseExpression());
_colon(); _colon();
newlineOpt(); newlineOpt();
@@ -450,8 +450,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
} }
@Override @Override
public boolean visit(JsEmpty x, JsContext ctx) { public void visit(JsEmpty x, JsContext ctx) {
return false;
} }
@Override @Override
@@ -650,12 +649,12 @@ public class JsToStringGenerationVisitor extends JsVisitor {
p.print(CHARS_NEW); p.print(CHARS_NEW);
space(); space();
JsExpression ctorExpr = x.getConstructorExpression(); JsExpression constructorExpression = x.getConstructorExpression();
boolean needsParens = JsConstructExpressionVisitor.exec(ctorExpr); boolean needsParens = JsConstructExpressionVisitor.exec(constructorExpression);
if (needsParens) { if (needsParens) {
leftParen(); leftParen();
} }
accept(ctorExpr); accept(constructorExpression);
if (needsParens) { if (needsParens) {
rightParen(); rightParen();
} }
@@ -668,21 +667,18 @@ public class JsToStringGenerationVisitor extends JsVisitor {
} }
@Override @Override
public boolean visit(JsNullLiteral x, JsContext ctx) { public void visit(JsNullLiteral x, JsContext ctx) {
p.print(CHARS_NULL); p.print(CHARS_NULL);
return false;
} }
@Override @Override
public boolean visit(JsIntLiteral x, JsContext ctx) { public void visit(JsIntLiteral x, JsContext ctx) {
p.print(x.value); p.print(x.value);
return false;
} }
@Override @Override
public boolean visit(JsDoubleLiteral x, JsContext ctx) { public void visit(JsDoubleLiteral x, JsContext ctx) {
p.print(x.value); p.print(x.value);
return false;
} }
@Override @Override
@@ -788,7 +784,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
} }
@Override @Override
public boolean visit(JsRegExp x, JsContext ctx) { public void visit(JsRegExp x, JsContext ctx) {
_slash(); _slash();
p.print(x.getPattern()); p.print(x.getPattern());
_slash(); _slash();
@@ -796,13 +792,12 @@ public class JsToStringGenerationVisitor extends JsVisitor {
if (flags != null) { if (flags != null) {
p.print(flags); p.print(flags);
} }
return false;
} }
@Override @Override
public boolean visit(JsReturn x, JsContext ctx) { public boolean visit(JsReturn x, JsContext ctx) {
p.print(CHARS_RETURN); p.print(CHARS_RETURN);
JsExpression expr = x.getExpr(); JsExpression expr = x.getExpression();
if (expr != null) { if (expr != null) {
space(); space();
accept(expr); accept(expr);
@@ -811,9 +806,8 @@ public class JsToStringGenerationVisitor extends JsVisitor {
} }
@Override @Override
public boolean visit(JsStringLiteral x, JsContext ctx) { public void visit(JsStringLiteral x, JsContext ctx) {
p.print(javaScriptString(x.getValue())); p.print(javaScriptString(x.getValue()));
return false;
} }
@Override @Override
@@ -1,7 +1,5 @@
package com.google.dart.compiler.backend.js.ast; package com.google.dart.compiler.backend.js.ast;
import com.google.dart.compiler.common.SourceInfo;
public class ChameleonJsExpression implements JsExpression { public class ChameleonJsExpression implements JsExpression {
private JsExpression expression; private JsExpression expression;
@@ -47,8 +45,13 @@ public class ChameleonJsExpression implements JsExpression {
} }
@Override @Override
public void traverse(JsVisitor visitor, JsContext context) { public void accept(JsVisitor visitor, JsContext context) {
expression.traverse(visitor, context); expression.accept(visitor, context);
}
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
expression.acceptChildren(visitor, context);
} }
@Override @Override
@@ -10,6 +10,5 @@ import java.util.List;
* Implemented by JavaScript objects that accept arguments. * Implemented by JavaScript objects that accept arguments.
*/ */
public interface HasArguments extends JsExpression { public interface HasArguments extends JsExpression {
List<JsExpression> getArguments(); List<JsExpression> getArguments();
} }
@@ -52,12 +52,14 @@ public final class JsArrayAccess extends JsExpressionImpl {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
arrayExpression = v.accept(arrayExpression);
indexExpression = v.accept(indexExpression);
} }
v.endVisit(this, context);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
arrayExpression = visitor.accept(arrayExpression);
indexExpression = visitor.accept(indexExpression);
} }
@Override @Override
@@ -57,11 +57,13 @@ public final class JsArrayLiteral extends JsLiteral {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
v.acceptWithInsertRemove(expressions);
} }
v.endVisit(this, context);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
visitor.acceptWithInsertRemove(expressions);
} }
@Override @Override
@@ -57,40 +57,31 @@ public final class JsBinaryOperation extends JsExpressionImpl {
} }
// AND and OR can return nulls // AND and OR can return nulls
if (op.isAssignment()) { if (op.isAssignment()) {
if (op == JsBinaryOperator.ASG) { return op != JsBinaryOperator.ASG || arg2.isDefinitelyNotNull();
return arg2.isDefinitelyNotNull();
} else {
// All other ASG's are math ops.
return true;
}
} }
if (op == JsBinaryOperator.COMMA) { return op == JsBinaryOperator.COMMA && arg2.isDefinitelyNotNull();
return arg2.isDefinitelyNotNull();
}
return false;
} }
@Override @Override
public boolean isDefinitelyNull() { public boolean isDefinitelyNull() {
if (op == JsBinaryOperator.AND) { return op == JsBinaryOperator.AND && arg1.isDefinitelyNull();
return arg1.isDefinitelyNull();
}
return false;
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
}
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
if (op.isAssignment()) { if (op.isAssignment()) {
arg1 = v.acceptLvalue(arg1); arg1 = visitor.acceptLvalue(arg1);
} else {
arg1 = v.accept(arg1);
} }
arg2 = v.accept(arg2); else {
arg1 = visitor.accept(arg1);
} }
v.endVisit(this, context); arg2 = visitor.accept(arg2);
} }
@Override @Override
@@ -44,11 +44,13 @@ public class JsBlock extends JsNodeImpl implements JsStatement {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
v.acceptWithInsertRemove(statements);
} }
v.endVisit(this, context);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
visitor.acceptWithInsertRemove(statements);
} }
@Override @Override
@@ -22,8 +22,7 @@ public final class JsBreak extends JsContinue {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
v.visit(this, context); v.visit(this, context);
v.endVisit(this, context);
} }
} }
@@ -8,28 +8,29 @@ package com.google.dart.compiler.backend.js.ast;
* Represents the JavaScript case statement. * Represents the JavaScript case statement.
*/ */
public final class JsCase extends JsSwitchMember { public final class JsCase extends JsSwitchMember {
private JsExpression caseExpression;
private JsExpression caseExpr;
public JsCase() { public JsCase() {
super(); super();
} }
public JsExpression getCaseExpr() { public JsExpression getCaseExpression() {
return caseExpr; return caseExpression;
} }
public void setCaseExpr(JsExpression caseExpr) { public void setCaseExpression(JsExpression caseExpression) {
this.caseExpr = caseExpr; this.caseExpression = caseExpression;
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
caseExpr = v.accept(caseExpr);
v.acceptWithInsertRemove(statements);
} }
v.endVisit(this, context);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
caseExpression = visitor.accept(caseExpression);
super.acceptChildren(visitor, context);
} }
@Override @Override
@@ -48,15 +48,17 @@ public class JsCatch extends JsNodeImpl implements HasCondition {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
param = v.accept(param); }
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
param = visitor.accept(param);
if (condition != null) { if (condition != null) {
condition = v.accept(condition); condition = visitor.accept(condition);
} }
body = v.accept(body); body = visitor.accept(body);
}
v.endVisit(this, context);
} }
@Override @Override
@@ -61,13 +61,15 @@ public final class JsConditional extends JsExpressionImpl {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
testExpr = v.accept(testExpr);
thenExpr = v.accept(thenExpr);
elseExpr = v.accept(elseExpr);
} }
v.endVisit(this, context);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
testExpr = visitor.accept(testExpr);
thenExpr = visitor.accept(thenExpr);
elseExpr = visitor.accept(elseExpr);
} }
@Override @Override
@@ -14,13 +14,13 @@ public interface JsContext {
boolean canRemove(); boolean canRemove();
void insertAfter(JsVisitable node); void insertAfter(JsNode node);
void insertBefore(JsVisitable node); void insertBefore(JsNode node);
boolean isLvalue(); boolean isLvalue();
void removeMe(); void removeMe();
void replaceMe(JsVisitable node); void replaceMe(JsNode node);
} }
@@ -6,9 +6,6 @@ package com.google.dart.compiler.backend.js.ast;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
/**
* Represents the JavaScript continue statement.
*/
public class JsContinue extends JsNodeImpl implements JsStatement { public class JsContinue extends JsNodeImpl implements JsStatement {
protected final String label; protected final String label;
@@ -26,9 +23,13 @@ public class JsContinue extends JsNodeImpl implements JsStatement {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
v.visit(this, context); v.visit(this, context);
v.endVisit(this, context); }
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
} }
@Override @Override
@@ -13,9 +13,13 @@ public class JsDebugger extends JsNodeImpl implements JsStatement {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
v.visit(this, context); v.visit(this, context);
v.endVisit(this, context); }
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
} }
@Override @Override
@@ -8,17 +8,9 @@ package com.google.dart.compiler.backend.js.ast;
* Represents the default option in a JavaScript swtich statement. * Represents the default option in a JavaScript swtich statement.
*/ */
public final class JsDefault extends JsSwitchMember { public final class JsDefault extends JsSwitchMember {
public JsDefault() {
super();
}
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
v.acceptWithInsertRemove(statements);
}
v.endVisit(this, context);
} }
@Override @Override
@@ -21,11 +21,10 @@ public class JsDoWhile extends JsWhile {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { if (v.visit(this, context)) {
condition = v.accept(condition); condition = v.accept(condition);
body = v.accept(body); body = v.accept(body);
} }
v.endVisit(this, context);
} }
} }
@@ -28,10 +28,15 @@ public class JsDocComment extends JsExpressionImpl {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
v.visit(this, context); v.visit(this, context);
} }
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
}
@Override @Override
public boolean hasSideEffects() { public boolean hasSideEffects() {
return false; return false;
@@ -4,18 +4,17 @@
package com.google.dart.compiler.backend.js.ast; package com.google.dart.compiler.backend.js.ast;
/**
* Represents an empty statement in JavaScript.
*/
public class JsEmpty extends JsNodeImpl implements JsStatement { public class JsEmpty extends JsNodeImpl implements JsStatement {
// Interned by JsProgram
JsEmpty() { JsEmpty() {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
v.visit(this, context); v.visit(this, context);
v.endVisit(this, context); }
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
} }
@Override @Override
@@ -2,7 +2,7 @@ package com.google.dart.compiler.backend.js.ast;
import com.google.dart.compiler.common.HasSourceInfo; import com.google.dart.compiler.common.HasSourceInfo;
public interface JsExpression extends JsNode, HasSourceInfo, JsVisitable { public interface JsExpression extends JsNode, HasSourceInfo {
/** /**
* Determines whether the expression can cause side effects. * Determines whether the expression can cause side effects.
*/ */
@@ -4,6 +4,8 @@
package com.google.dart.compiler.backend.js.ast; package com.google.dart.compiler.backend.js.ast;
import java.util.List;
abstract class JsExpressionImpl extends JsNodeImpl implements JsExpression { abstract class JsExpressionImpl extends JsNodeImpl implements JsExpression {
protected JsExpressionImpl() { protected JsExpressionImpl() {
} }
@@ -24,4 +26,17 @@ abstract class JsExpressionImpl extends JsNodeImpl implements JsExpression {
public JsStatement makeStmt() { public JsStatement makeStmt() {
return new JsExpressionStatement(this); return new JsExpressionStatement(this);
} }
protected abstract static class JsExpressionHasArguments extends JsExpressionImpl implements HasArguments {
protected final List<JsExpression> arguments;
public JsExpressionHasArguments(List<JsExpression> arguments) {
this.arguments = arguments;
}
@Override
public List<JsExpression> getArguments() {
return arguments;
}
}
} }
@@ -16,11 +16,13 @@ public final class JsExpressionStatement extends AbstractNode implements JsState
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
expression = v.accept(expression);
} }
v.endVisit(this, context);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
expression = visitor.accept(expression);
} }
@Override @Override
@@ -71,27 +71,29 @@ public class JsFor extends JsNodeImpl implements JsStatement {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
}
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
assert (!(initExpression != null && initVars != null)); assert (!(initExpression != null && initVars != null));
if (initExpression != null) { if (initExpression != null) {
initExpression = v.accept(initExpression); initExpression = visitor.accept(initExpression);
} }
else if (initVars != null) { else if (initVars != null) {
initVars = v.accept(initVars); initVars = visitor.accept(initVars);
} }
if (condition != null) { if (condition != null) {
condition = v.accept(condition); condition = visitor.accept(condition);
} }
if (incrementExpression != null) { if (incrementExpression != null) {
incrementExpression = v.accept(incrementExpression); incrementExpression = visitor.accept(incrementExpression);
} }
body = v.accept(body); body = visitor.accept(body);
}
v.endVisit(this, context);
} }
@Override @Override
@@ -8,7 +8,6 @@ package com.google.dart.compiler.backend.js.ast;
* Represents a JavaScript for..in statement. * Represents a JavaScript for..in statement.
*/ */
public class JsForIn extends JsNodeImpl implements JsStatement { public class JsForIn extends JsNodeImpl implements JsStatement {
private JsStatement body; private JsStatement body;
private JsExpression iterExpr; private JsExpression iterExpr;
private JsExpression objExpr; private JsExpression objExpr;
@@ -53,15 +52,19 @@ public class JsForIn extends JsNodeImpl implements JsStatement {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { if (v.visit(this, context)) {
}
}
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
if (iterExpr != null) { if (iterExpr != null) {
iterExpr = v.acceptLvalue(iterExpr); iterExpr = visitor.acceptLvalue(iterExpr);
} }
objExpr = v.accept(objExpr); objExpr = visitor.accept(objExpr);
body = v.accept(body); body = visitor.accept(body);
}
v.endVisit(this, context);
} }
@Override @Override
@@ -90,12 +90,14 @@ public final class JsFunction extends JsLiteral implements HasName {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
v.acceptWithInsertRemove(params);
body = v.accept(body);
} }
v.endVisit(this, context);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
visitor.acceptWithInsertRemove(params);
body = visitor.accept(body);
} }
@Override @Override
@@ -51,16 +51,18 @@ public final class JsIf extends JsNodeImpl implements JsStatement {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
ifExpression = v.accept(ifExpression); }
thenStatement = v.accept(thenStatement);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
ifExpression = visitor.accept(ifExpression);
thenStatement = visitor.accept(thenStatement);
if (elseStatement != null) { if (elseStatement != null) {
elseStatement = v.accept(elseStatement); elseStatement = visitor.accept(elseStatement);
} }
} }
v.endVisit(this, context);
}
@Override @Override
public NodeKind getKind() { public NodeKind getKind() {
@@ -13,17 +13,16 @@ import java.util.List;
/** /**
* Represents a JavaScript invocation. * Represents a JavaScript invocation.
*/ */
public final class JsInvocation extends JsExpressionImpl implements HasArguments { public final class JsInvocation extends JsExpressionImpl.JsExpressionHasArguments {
private final List<JsExpression> arguments;
private JsExpression qualifier; private JsExpression qualifier;
public JsInvocation() { public JsInvocation() {
arguments = new SmartList<JsExpression>(); super(new SmartList<JsExpression>());
} }
public JsInvocation(JsExpression qualifier, List<JsExpression> arguments) { public JsInvocation(JsExpression qualifier, List<JsExpression> arguments) {
super(arguments);
this.qualifier = qualifier; this.qualifier = qualifier;
this.arguments = arguments;
} }
public JsInvocation(JsExpression qualifier, JsExpression arg) { public JsInvocation(JsExpression qualifier, JsExpression arg) {
@@ -68,12 +67,14 @@ public final class JsInvocation extends JsExpressionImpl implements HasArguments
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
qualifier = v.accept(qualifier);
v.acceptList(arguments);
} }
v.endVisit(this, context);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
qualifier = visitor.accept(qualifier);
visitor.acceptList(arguments);
} }
@Override @Override
@@ -42,11 +42,13 @@ public class JsLabel extends JsNodeImpl implements JsStatement, HasName {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
statement = v.accept(statement);
} }
v.endVisit(this, context);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
statement = visitor.accept(statement);
} }
@Override @Override
@@ -43,9 +43,8 @@ public abstract class JsLiteral extends JsExpressionImpl implements CanBooleanEv
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
v.visit(this, context); v.visit(this, context);
v.endVisit(this, context);
} }
@Override @Override
@@ -87,9 +86,8 @@ public abstract class JsLiteral extends JsExpressionImpl implements CanBooleanEv
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
v.visit(this, context); v.visit(this, context);
v.endVisit(this, context);
} }
@Override @Override
@@ -97,4 +95,26 @@ public abstract class JsLiteral extends JsExpressionImpl implements CanBooleanEv
return NodeKind.BOOLEAN; return NodeKind.BOOLEAN;
} }
} }
/**
* A JavaScript string literal expression.
*/
public abstract static class JsValueLiteral extends JsLiteral {
protected JsValueLiteral() {
}
@Override
public final boolean hasSideEffects() {
return false;
}
@Override
public final boolean isLeaf() {
return true;
}
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
}
}
} }
@@ -56,14 +56,7 @@ public final class JsNameRef extends JsExpressionImpl implements CanBooleanEval,
@Override @Override
public boolean hasSideEffects() { public boolean hasSideEffects() {
if (qualifier == null) { return qualifier != null && (!qualifier.isDefinitelyNotNull() || qualifier.hasSideEffects());
return false;
}
if (!qualifier.isDefinitelyNotNull()) {
// Could trigger NPE.
return true;
}
return qualifier.hasSideEffects();
} }
@Override @Override
@@ -83,25 +76,17 @@ public final class JsNameRef extends JsExpressionImpl implements CanBooleanEval,
@Override @Override
public boolean isDefinitelyNull() { public boolean isDefinitelyNull() {
if (name != null) { return name != null && (JsLiteral.UNDEFINED.getName() == name);
return (JsLiteral.UNDEFINED.getName() == name);
}
return false;
} }
@Override @Override
public boolean isLeaf() { public boolean isLeaf() {
if (qualifier == null) { return qualifier == null;
return true;
}
else {
return false;
}
} }
public void resolve(JsName name) { public void resolve(JsName name) {
this.name = name; this.name = name;
this.ident = null; ident = null;
} }
public void setQualifier(JsExpression qualifier) { public void setQualifier(JsExpression qualifier) {
@@ -109,14 +94,16 @@ public final class JsNameRef extends JsExpressionImpl implements CanBooleanEval,
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
}
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
if (qualifier != null) { if (qualifier != null) {
qualifier = v.accept(qualifier); qualifier = visitor.accept(qualifier);
} }
} }
v.endVisit(this, context);
}
@Override @Override
public NodeKind getKind() { public NodeKind getKind() {
@@ -8,29 +8,20 @@ import com.intellij.util.SmartList;
import java.util.List; import java.util.List;
/** public final class JsNew extends JsExpressionImpl.JsExpressionHasArguments {
* Represents the JavaScript new expression. private JsExpression constructorExpression;
*/
public final class JsNew extends JsExpressionImpl implements HasArguments {
private final List<JsExpression> arguments;
private JsExpression ctorExpression;
public JsNew(JsExpression ctorExpression) { public JsNew(JsExpression constructorExpression) {
this(ctorExpression, new SmartList<JsExpression>()); this(constructorExpression, new SmartList<JsExpression>());
} }
public JsNew(JsExpression ctorExpression, List<JsExpression> arguments) { public JsNew(JsExpression constructorExpression, List<JsExpression> arguments) {
this.ctorExpression = ctorExpression; super(arguments);
this.arguments = arguments; this.constructorExpression = constructorExpression;
}
@Override
public List<JsExpression> getArguments() {
return arguments;
} }
public JsExpression getConstructorExpression() { public JsExpression getConstructorExpression() {
return ctorExpression; return constructorExpression;
} }
@Override @Override
@@ -51,12 +42,14 @@ public final class JsNew extends JsExpressionImpl implements HasArguments {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
ctorExpression = v.accept(ctorExpression);
v.acceptList(arguments);
} }
v.endVisit(this, context);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
constructorExpression = visitor.accept(constructorExpression);
visitor.acceptList(arguments);
} }
@Override @Override
@@ -4,6 +4,16 @@
package com.google.dart.compiler.backend.js.ast; package com.google.dart.compiler.backend.js.ast;
public interface JsNode extends JsVisitable { public interface JsNode {
NodeKind getKind(); NodeKind getKind();
/**
* Causes this object to have the visitor visit itself and its children.
*
* @param visitor the visitor that should traverse this node
* @param context the context of an existing traversal
*/
void accept(JsVisitor visitor, JsContext context);
void acceptChildren(JsVisitor visitor, JsContext context);
} }
@@ -1,7 +1,5 @@
package com.google.dart.compiler.backend.js.ast; package com.google.dart.compiler.backend.js.ast;
import com.google.dart.compiler.common.SourceInfo;
abstract class JsNodeImpl extends AbstractNode { abstract class JsNodeImpl extends AbstractNode {
private Object sourceInfo; private Object sourceInfo;
@@ -4,7 +4,7 @@
package com.google.dart.compiler.backend.js.ast; package com.google.dart.compiler.backend.js.ast;
public final class JsNullLiteral extends JsValueLiteral { public final class JsNullLiteral extends JsLiteral.JsValueLiteral {
JsNullLiteral() { JsNullLiteral() {
} }
@@ -29,9 +29,8 @@ public final class JsNullLiteral extends JsValueLiteral {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
v.visit(this, context); v.visit(this, context);
v.endVisit(this, context);
} }
@Override @Override
@@ -4,7 +4,7 @@
package com.google.dart.compiler.backend.js.ast; package com.google.dart.compiler.backend.js.ast;
public abstract class JsNumberLiteral extends JsValueLiteral { public abstract class JsNumberLiteral extends JsLiteral.JsValueLiteral {
@Override @Override
public boolean isDefinitelyNotNull() { public boolean isDefinitelyNotNull() {
return true; return true;
@@ -38,9 +38,8 @@ public abstract class JsNumberLiteral extends JsValueLiteral {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
v.visit(this, context); v.visit(this, context);
v.endVisit(this, context);
} }
public String toString() { public String toString() {
@@ -66,9 +65,8 @@ public abstract class JsNumberLiteral extends JsValueLiteral {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
v.visit(this, context); v.visit(this, context);
v.endVisit(this, context);
} }
public String toString() { public String toString() {
@@ -69,11 +69,13 @@ public final class JsObjectLiteral extends JsLiteral {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
v.acceptWithInsertRemove(properties);
} }
v.endVisit(this, context);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
visitor.acceptWithInsertRemove(properties);
} }
@Override @Override
@@ -27,9 +27,13 @@ public final class JsParameter extends JsNodeImpl implements HasName {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
v.visit(this, context); v.visit(this, context);
v.endVisit(this, context); }
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
} }
@Override @Override
@@ -28,11 +28,8 @@ public final class JsPostfixOperation extends JsUnaryOperation {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
super.traverse(v, context);
}
v.endVisit(this, context);
} }
@Override @Override
@@ -4,9 +4,6 @@
package com.google.dart.compiler.backend.js.ast; package com.google.dart.compiler.backend.js.ast;
/**
* A JavaScript prefix operation.
*/
public final class JsPrefixOperation extends JsUnaryOperation implements CanBooleanEval { public final class JsPrefixOperation extends JsUnaryOperation implements CanBooleanEval {
public JsPrefixOperation(JsUnaryOperator op) { public JsPrefixOperation(JsUnaryOperator op) {
@@ -35,18 +32,12 @@ public final class JsPrefixOperation extends JsUnaryOperation implements CanBool
CanBooleanEval eval = (CanBooleanEval) getArg(); CanBooleanEval eval = (CanBooleanEval) getArg();
return eval.isBooleanFalse(); return eval.isBooleanFalse();
} }
if (getOperator() == JsUnaryOperator.TYPEOF) { return getOperator() == JsUnaryOperator.TYPEOF;
return true;
}
return false;
} }
@Override @Override
public boolean isDefinitelyNotNull() { public boolean isDefinitelyNotNull() {
if (getOperator() == JsUnaryOperator.TYPEOF) { return getOperator() == JsUnaryOperator.TYPEOF || getOperator() != JsUnaryOperator.VOID;
return true;
}
return getOperator() != JsUnaryOperator.VOID;
} }
@Override @Override
@@ -55,11 +46,8 @@ public final class JsPrefixOperation extends JsUnaryOperation implements CanBool
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
super.traverse(v, context);
}
v.endVisit(this, context);
} }
@Override @Override
@@ -18,7 +18,7 @@ import static com.google.dart.compiler.backend.js.ast.JsNumberLiteral.JsIntLiter
* A JavaScript program. * A JavaScript program.
*/ */
public final class JsProgram extends JsNodeImpl { public final class JsProgram extends JsNodeImpl {
private final JsEmpty emptyStmt; private final JsEmpty emptyStatement;
private JsProgramFragment[] fragments; private JsProgramFragment[] fragments;
@@ -29,19 +29,16 @@ public final class JsProgram extends JsNodeImpl {
private final Map<String, JsStringLiteral> stringLiteralMap = new THashMap<String, JsStringLiteral>(); private final Map<String, JsStringLiteral> stringLiteralMap = new THashMap<String, JsStringLiteral>();
private final JsScope topScope; private final JsScope topScope;
/**
* Constructs a JavaScript program object.
*/
public JsProgram(String unitId) { public JsProgram(String unitId) {
rootScope = new JsRootScope(this); rootScope = new JsRootScope(this);
topScope = new JsScope(rootScope, "Global", unitId); topScope = new JsScope(rootScope, "Global", unitId);
setFragmentCount(1); setFragmentCount(1);
emptyStmt = new JsEmpty(); emptyStatement = new JsEmpty();
} }
public JsEmpty getEmptyStmt() { public JsEmpty getEmptyStatement() {
return emptyStmt; return emptyStatement;
} }
public JsBlock getFragmentBlock(int fragment) { public JsBlock getFragmentBlock(int fragment) {
@@ -112,14 +109,16 @@ public final class JsProgram extends JsNodeImpl {
} }
@Override @Override
public void traverse(JsVisitor v, @Nullable JsContext context) { public void accept(JsVisitor v, @Nullable JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
}
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
for (JsProgramFragment fragment : fragments) { for (JsProgramFragment fragment : fragments) {
v.accept(fragment); visitor.accept(fragment);
} }
} }
v.endVisit(this, context);
}
@Override @Override
public NodeKind getKind() { public NodeKind getKind() {
@@ -8,11 +8,10 @@ package com.google.dart.compiler.backend.js.ast;
* One independently loadable fragment of a {@link JsProgram}. * One independently loadable fragment of a {@link JsProgram}.
*/ */
public class JsProgramFragment extends JsNodeImpl { public class JsProgramFragment extends JsNodeImpl {
private final JsGlobalBlock globalBlock; private final JsGlobalBlock globalBlock;
public JsProgramFragment() { public JsProgramFragment() {
this.globalBlock = new JsGlobalBlock(); globalBlock = new JsGlobalBlock();
} }
public JsBlock getGlobalBlock() { public JsBlock getGlobalBlock() {
@@ -20,11 +19,13 @@ public class JsProgramFragment extends JsNodeImpl {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
v.accept(globalBlock);
} }
v.endVisit(this, context);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
visitor.accept(globalBlock);
} }
@Override @Override
@@ -39,12 +39,14 @@ public class JsPropertyInitializer extends JsNodeImpl {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
labelExpr = v.accept(labelExpr);
valueExpr = v.accept(valueExpr);
} }
v.endVisit(this, context);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
labelExpr = visitor.accept(labelExpr);
valueExpr = visitor.accept(valueExpr);
} }
@Override @Override
@@ -7,8 +7,7 @@ package com.google.dart.compiler.backend.js.ast;
/** /**
* A JavaScript regular expression. * A JavaScript regular expression.
*/ */
public final class JsRegExp extends JsValueLiteral { public final class JsRegExp extends JsLiteral.JsValueLiteral {
private String flags; private String flags;
private String pattern; private String pattern;
@@ -44,17 +43,16 @@ public final class JsRegExp extends JsValueLiteral {
} }
public void setFlags(String suffix) { public void setFlags(String suffix) {
this.flags = suffix; flags = suffix;
} }
public void setPattern(String re) { public void setPattern(String re) {
this.pattern = re; pattern = re;
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
v.visit(this, context); v.visit(this, context);
v.endVisit(this, context);
} }
@Override @Override
@@ -8,32 +8,33 @@ package com.google.dart.compiler.backend.js.ast;
* A JavaScript return statement. * A JavaScript return statement.
*/ */
public final class JsReturn extends JsNodeImpl implements JsStatement { public final class JsReturn extends JsNodeImpl implements JsStatement {
private JsExpression expression;
private JsExpression expr;
public JsReturn() { public JsReturn() {
} }
public JsReturn(JsExpression expr) { public JsReturn(JsExpression expression) {
this.expr = expr; this.expression = expression;
} }
public JsExpression getExpr() { public JsExpression getExpression() {
return expr; return expression;
} }
public void setExpr(JsExpression expr) { public void setExpression(JsExpression expression) {
this.expr = expr; this.expression = expression;
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
if (expr != null) {
expr = v.accept(expr);
} }
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
if (expression != null) {
expression = visitor.accept(expression);
} }
v.endVisit(this, context);
} }
@Override @Override
@@ -67,8 +67,8 @@ public class JsScope {
protected JsScope(@Nullable String description) { protected JsScope(@Nullable String description) {
this.description = description; this.description = description;
this.parent = null; parent = null;
this.scopeId = null; scopeId = null;
} }
/** /**
@@ -7,7 +7,7 @@ package com.google.dart.compiler.backend.js.ast;
/** /**
* A JavaScript string literal expression. * A JavaScript string literal expression.
*/ */
public final class JsStringLiteral extends JsValueLiteral { public final class JsStringLiteral extends JsLiteral.JsValueLiteral {
private final String value; private final String value;
@@ -41,9 +41,8 @@ public final class JsStringLiteral extends JsValueLiteral {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
v.visit(this, context); v.visit(this, context);
v.endVisit(this, context);
} }
@Override @Override
@@ -32,12 +32,14 @@ public class JsSwitch extends JsNodeImpl implements JsStatement {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
expr = v.accept(expr);
v.acceptWithInsertRemove(cases);
} }
v.endVisit(this, context);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
expr = visitor.accept(expr);
visitor.acceptWithInsertRemove(cases);
} }
@Override @Override
@@ -21,4 +21,9 @@ public abstract class JsSwitchMember extends JsNodeImpl {
public List<JsStatement> getStatements() { public List<JsStatement> getStatements() {
return statements; return statements;
} }
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
visitor.acceptWithInsertRemove(statements);
}
} }
@@ -23,11 +23,13 @@ public class JsThrow extends JsNodeImpl implements JsStatement {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
expression = v.accept(expression);
} }
v.endVisit(this, context);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
visitor.accept(expression);
} }
@Override @Override
@@ -40,7 +40,7 @@ public class JsTry extends JsNodeImpl implements JsStatement {
} }
public void setFinallyBlock(JsBlock block) { public void setFinallyBlock(JsBlock block) {
this.finallyBlock = block; finallyBlock = block;
} }
public void setTryBlock(JsBlock block) { public void setTryBlock(JsBlock block) {
@@ -48,16 +48,18 @@ public class JsTry extends JsNodeImpl implements JsStatement {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
tryBlock = v.accept(tryBlock); }
v.acceptWithInsertRemove(catches);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
tryBlock = visitor.accept(tryBlock);
visitor.acceptWithInsertRemove(catches);
if (finallyBlock != null) { if (finallyBlock != null) {
finallyBlock = v.accept(finallyBlock); finallyBlock = visitor.accept(finallyBlock);
} }
} }
v.endVisit(this, context);
}
@Override @Override
public NodeKind getKind() { public NodeKind getKind() {
@@ -41,13 +41,14 @@ public abstract class JsUnaryOperation extends JsExpressionImpl {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void acceptChildren(JsVisitor visitor, JsContext context) {
if (op.isModifying()) { if (op.isModifying()) {
// The delete operator is practically like an assignment of undefined, so // The delete operator is practically like an assignment of undefined, so
// for practical purposes we're treating it as an lvalue. // for practical purposes we're treating it as an lvalue.
arg = v.acceptLvalue(arg); arg = visitor.acceptLvalue(arg);
} else { }
arg = v.accept(arg); else {
arg = visitor.accept(arg);
} }
} }
} }
@@ -1,23 +0,0 @@
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.google.dart.compiler.backend.js.ast;
/**
* A JavaScript string literal expression.
*/
public abstract class JsValueLiteral extends JsLiteral {
protected JsValueLiteral() {
}
@Override
public final boolean hasSideEffects() {
return false;
}
@Override
public final boolean isLeaf() {
return true;
}
}
@@ -81,14 +81,16 @@ public class JsVars extends JsNodeImpl implements JsStatement, Iterable<JsVars.J
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
}
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
if (initExpression != null) { if (initExpression != null) {
initExpression = v.accept(initExpression); initExpression = visitor.accept(initExpression);
} }
} }
v.endVisit(this, context);
}
@Override @Override
public NodeKind getKind() { public NodeKind getKind() {
@@ -116,11 +118,13 @@ public class JsVars extends JsNodeImpl implements JsStatement, Iterable<JsVars.J
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
v.acceptWithInsertRemove(vars);
} }
v.endVisit(this, context);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
visitor.acceptWithInsertRemove(vars);
} }
@Override @Override
@@ -1,17 +0,0 @@
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.google.dart.compiler.backend.js.ast;
import com.google.dart.compiler.common.HasSourceInfo;
public interface JsVisitable extends HasSourceInfo {
/**
* Causes this object to have the visitor visit itself and its children.
*
* @param visitor the visitor that should traverse this node
* @param context the context of an existing traversal
*/
void traverse(JsVisitor visitor, JsContext context);
}
@@ -8,10 +8,7 @@ import com.google.dart.compiler.backend.js.ast.JsVars.JsVar;
import java.util.List; import java.util.List;
/** public abstract class JsVisitor {
* Implemented by nodes that will visit child nodes.
*/
abstract public class JsVisitor {
protected static final JsContext LVALUE_CONTEXT = new JsContext() { protected static final JsContext LVALUE_CONTEXT = new JsContext() {
@Override @Override
public boolean canInsert() { public boolean canInsert() {
@@ -24,12 +21,12 @@ abstract public class JsVisitor {
} }
@Override @Override
public void insertAfter(JsVisitable node) { public void insertAfter(JsNode node) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public void insertBefore(JsVisitable node) { public void insertBefore(JsNode node) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@@ -44,13 +41,12 @@ abstract public class JsVisitor {
} }
@Override @Override
public void replaceMe(JsVisitable node) { public void replaceMe(JsNode node) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
}; };
protected static final JsContext UNMODIFIABLE_CONTEXT = new JsContext() { protected static final JsContext UNMODIFIABLE_CONTEXT = new JsContext() {
@Override @Override
public boolean canInsert() { public boolean canInsert() {
return false; return false;
@@ -62,12 +58,12 @@ abstract public class JsVisitor {
} }
@Override @Override
public void insertAfter(JsVisitable node) { public void insertAfter(JsNode node) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public void insertBefore(JsVisitable node) { public void insertBefore(JsNode node) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@@ -82,17 +78,17 @@ abstract public class JsVisitor {
} }
@Override @Override
public void replaceMe(JsVisitable node) { public void replaceMe(JsNode node) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
}; };
public <T extends JsVisitable> T accept(T node) { public <T extends JsNode> T accept(T node) {
doTraverse(node, UNMODIFIABLE_CONTEXT); doTraverse(node, UNMODIFIABLE_CONTEXT);
return node; return node;
} }
public final <T extends JsVisitable> void acceptList(List<T> collection) { public final <T extends JsNode> void acceptList(List<T> collection) {
for (T node : collection) { for (T node : collection) {
doTraverse(node, UNMODIFIABLE_CONTEXT); doTraverse(node, UNMODIFIABLE_CONTEXT);
} }
@@ -103,138 +99,12 @@ abstract public class JsVisitor {
return expr; return expr;
} }
public final <T extends JsVisitable> void acceptWithInsertRemove(List<T> collection) { public final <T extends JsNode> void acceptWithInsertRemove(List<T> collection) {
for (T node : collection) { for (T node : collection) {
doTraverse(node, UNMODIFIABLE_CONTEXT); doTraverse(node, UNMODIFIABLE_CONTEXT);
} }
} }
public void endVisit(JsArrayAccess x, JsContext ctx) {
}
public void endVisit(JsArrayLiteral x, JsContext ctx) {
}
public void endVisit(JsBinaryOperation x, JsContext ctx) {
}
public void endVisit(JsBlock x, JsContext ctx) {
}
public void endVisit(JsLiteral.JsBooleanLiteral x, JsContext ctx) {
}
public void endVisit(JsBreak x, JsContext ctx) {
}
public void endVisit(JsCase x, JsContext ctx) {
}
public void endVisit(JsCatch x, JsContext ctx) {
}
public void endVisit(JsConditional x, JsContext ctx) {
}
public void endVisit(JsContinue x, JsContext ctx) {
}
public void endVisit(JsDebugger x, JsContext ctx) {
}
public void endVisit(JsDefault x, JsContext ctx) {
}
public void endVisit(JsDoWhile x, JsContext ctx) {
}
public void endVisit(JsEmpty x, JsContext ctx) {
}
public void endVisit(JsExpressionStatement x, JsContext ctx) {
}
public void endVisit(JsFor x, JsContext ctx) {
}
public void endVisit(JsForIn x, JsContext ctx) {
}
public void endVisit(JsFunction x, JsContext ctx) {
}
public void endVisit(JsIf x, JsContext ctx) {
}
public void endVisit(JsInvocation x, JsContext ctx) {
}
public void endVisit(JsLabel x, JsContext ctx) {
}
public void endVisit(JsNameRef x, JsContext ctx) {
}
public void endVisit(JsNew x, JsContext ctx) {
}
public void endVisit(JsNullLiteral x, JsContext ctx) {
}
public void endVisit(JsNumberLiteral x, JsContext ctx) {
}
public void endVisit(JsObjectLiteral x, JsContext ctx) {
}
public void endVisit(JsParameter x, JsContext ctx) {
}
public void endVisit(JsPostfixOperation x, JsContext ctx) {
}
public void endVisit(JsPrefixOperation x, JsContext ctx) {
}
public void endVisit(JsProgram x, JsContext ctx) {
}
public void endVisit(JsProgramFragment x, JsContext ctx) {
}
public void endVisit(JsPropertyInitializer x, JsContext ctx) {
}
public void endVisit(JsRegExp x, JsContext ctx) {
}
public void endVisit(JsReturn x, JsContext ctx) {
}
public void endVisit(JsStringLiteral x, JsContext ctx) {
}
public void endVisit(JsSwitch x, JsContext ctx) {
}
public void endVisit(JsLiteral.JsThisRef x, JsContext ctx) {
}
public void endVisit(JsThrow x, JsContext ctx) {
}
public void endVisit(JsTry x, JsContext ctx) {
}
public void endVisit(JsVar x, JsContext ctx) {
}
public void endVisit(JsVars x, JsContext ctx) {
}
public void endVisit(JsWhile x, JsContext ctx) {
}
public boolean visit(JsArrayAccess x, JsContext ctx) { public boolean visit(JsArrayAccess x, JsContext ctx) {
return true; return true;
} }
@@ -287,8 +157,7 @@ abstract public class JsVisitor {
return true; return true;
} }
public boolean visit(JsEmpty x, JsContext ctx) { public void visit(JsEmpty x, JsContext ctx) {
return true;
} }
public boolean visit(JsExpressionStatement x, JsContext ctx) { public boolean visit(JsExpressionStatement x, JsContext ctx) {
@@ -327,16 +196,13 @@ abstract public class JsVisitor {
return true; return true;
} }
public boolean visit(JsNullLiteral x, JsContext ctx) { public void visit(JsNullLiteral x, JsContext ctx) {
return true;
} }
public boolean visit(JsNumberLiteral.JsIntLiteral x, JsContext ctx) { public void visit(JsNumberLiteral.JsIntLiteral x, JsContext ctx) {
return true;
} }
public boolean visit(JsNumberLiteral.JsDoubleLiteral x, JsContext ctx) { public void visit(JsNumberLiteral.JsDoubleLiteral x, JsContext ctx) {
return true;
} }
public boolean visit(JsObjectLiteral x, JsContext ctx) { public boolean visit(JsObjectLiteral x, JsContext ctx) {
@@ -367,16 +233,14 @@ abstract public class JsVisitor {
return true; return true;
} }
public boolean visit(JsRegExp x, JsContext ctx) { public void visit(JsRegExp x, JsContext ctx) {
return true;
} }
public boolean visit(JsReturn x, JsContext ctx) { public boolean visit(JsReturn x, JsContext ctx) {
return true; return true;
} }
public boolean visit(JsStringLiteral x, JsContext ctx) { public void visit(JsStringLiteral x, JsContext ctx) {
return true;
} }
public boolean visit(JsSwitch x, JsContext ctx) { public boolean visit(JsSwitch x, JsContext ctx) {
@@ -411,7 +275,7 @@ abstract public class JsVisitor {
return true; return true;
} }
protected void doTraverse(JsVisitable node, JsContext context) { protected void doTraverse(JsNode node, JsContext context) {
node.traverse(this, context); node.accept(this, context);
} }
} }
@@ -36,12 +36,14 @@ public class JsWhile extends JsNodeImpl implements JsStatement {
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void accept(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { v.visit(this, context);
condition = v.accept(condition);
body = v.accept(body);
} }
v.endVisit(this, context);
@Override
public void acceptChildren(JsVisitor visitor, JsContext context) {
condition = visitor.accept(condition);
body = visitor.accept(body);
} }
@Override @Override
@@ -0,0 +1,4 @@
package com.google.dart.compiler.backend.js.ast;
public abstract class RecursiveJsVisitor extends JsVisitor {
}