This commit is contained in:
develar
2012-10-18 18:05:12 +04:00
parent b2b953abde
commit 5ba7a0a8fa
9 changed files with 118 additions and 290 deletions
@@ -31,7 +31,7 @@ public class JsConstructExpressionVisitor extends JsVisitor {
*/ */
@Override @Override
public boolean visit(JsArrayAccess x, JsContext ctx) { public boolean visit(JsArrayAccess x, JsContext ctx) {
accept(x.getArrayExpr()); accept(x.getArrayExpression());
return false; return false;
} }
@@ -85,13 +85,12 @@ 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
protected <T extends JsVisitable> T doAccept(T node) { public <T extends JsVisitable> 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.
Object o = node; if (node instanceof JsExpression) {
if (o instanceof JsExpression) { JsExpression expression = (JsExpression) node;
JsExpression expression = (JsExpression) o;
int precedence = JsPrecedenceVisitor.exec(expression); int precedence = JsPrecedenceVisitor.exec(expression);
// Only visit expressions that won't automatically be surrounded by // Only visit expressions that won't automatically be surrounded by
// parentheses // parentheses
@@ -99,6 +98,6 @@ public class JsConstructExpressionVisitor extends JsVisitor {
return node; return node;
} }
} }
return super.doAccept(node); return super.accept(node);
} }
} }
@@ -50,7 +50,7 @@ public class JsFirstExpressionVisitor extends JsVisitor {
@Override @Override
public boolean visit(JsArrayAccess x, JsContext ctx) { public boolean visit(JsArrayAccess x, JsContext ctx) {
accept(x.getArrayExpr()); accept(x.getArrayExpression());
return false; return false;
} }
@@ -1,36 +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;
import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.TextOutput;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.js.compiler.SourceMapBuilder;
/**
* Generates JavaScript source from an AST.
*/
public class JsSourceGenerationVisitor extends JsToStringGenerationVisitor {
public JsSourceGenerationVisitor(TextOutput out, @Nullable SourceMapBuilder sourceMapBuilder) {
super(out, sourceMapBuilder);
}
@Override
public boolean visit(JsProgram program, JsContext ctx) {
return true;
}
@Override
public boolean visit(JsProgramFragment x, JsContext ctx) {
// Descend naturally.
return true;
}
@Override
public boolean visit(JsBlock x, JsContext ctx) {
printJsBlock(x, false, true);
return false;
}
}
@@ -8,8 +8,6 @@ import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.backend.js.ast.JsVars.JsVar; import com.google.dart.compiler.backend.js.ast.JsVars.JsVar;
import com.google.dart.compiler.util.TextOutput; import com.google.dart.compiler.util.TextOutput;
import gnu.trove.THashSet; import gnu.trove.THashSet;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.js.compiler.SourceMapBuilder;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@@ -200,35 +198,26 @@ public class JsToStringGenerationVisitor extends JsVisitor {
* those that appear directly within these global blocks. * those that appear directly within these global blocks.
*/ */
private Set<JsBlock> globalBlocks = new THashSet<JsBlock>(); private Set<JsBlock> globalBlocks = new THashSet<JsBlock>();
private final TextOutput p; protected final TextOutput p;
@Nullable
private final SourceMapBuilder sourceMapBuilder;
public JsToStringGenerationVisitor(TextOutput out) { public JsToStringGenerationVisitor(TextOutput out) {
this(out, null);
}
public JsToStringGenerationVisitor(TextOutput out, @Nullable SourceMapBuilder sourceMapBuilder) {
p = out; p = out;
this.sourceMapBuilder = sourceMapBuilder;
} }
@Override @Override
public boolean visit(JsArrayAccess x, JsContext ctx) { public boolean visit(JsArrayAccess x, JsContext context) {
JsExpression arrayExpr = x.getArrayExpr(); printPair(x, x.getArrayExpression());
printPair(x, arrayExpr); leftSquare();
_lsquare(); accept(x.getIndexExpression());
accept(x.getIndexExpr()); rightSquare();
_rsquare();
return false; return false;
} }
@Override @Override
public boolean visit(JsArrayLiteral x, JsContext ctx) { public boolean visit(JsArrayLiteral x, JsContext ctx) {
_lsquare(); leftSquare();
printExpressions(x.getExpressions()); printExpressions(x.getExpressions());
_rsquare(); rightSquare();
return false; return false;
} }
@@ -245,42 +234,42 @@ public class JsToStringGenerationVisitor extends JsVisitor {
} }
@Override @Override
public boolean visit(JsBinaryOperation binaryOperation, JsContext ctx) { public boolean visit(JsBinaryOperation binaryOperation, JsContext context) {
JsBinaryOperator op = binaryOperation.getOperator(); JsBinaryOperator operator = binaryOperation.getOperator();
JsExpression arg1 = binaryOperation.getArg1(); JsExpression arg1 = binaryOperation.getArg1();
boolean isExpressionEnclosed = _parenPush(binaryOperation, arg1, !op.isLeftAssociative()); boolean isExpressionEnclosed = parenPush(binaryOperation, arg1, !operator.isLeftAssociative());
accept(arg1); accept(arg1);
if (op.isKeyword()) { if (operator.isKeyword()) {
_parenPopOrSpace(binaryOperation, arg1, !op.isLeftAssociative()); _parenPopOrSpace(binaryOperation, arg1, !operator.isLeftAssociative());
} }
else if (op != JsBinaryOperator.COMMA) { else if (operator != JsBinaryOperator.COMMA) {
if (isExpressionEnclosed) { if (isExpressionEnclosed) {
rightParen(); rightParen();
} }
spaceOpt(); spaceOpt();
} }
p.print(op.getSymbol()); p.print(operator.getSymbol());
JsExpression arg2 = binaryOperation.getArg2(); JsExpression arg2 = binaryOperation.getArg2();
boolean isParenOpened; boolean isParenOpened;
if (op == JsBinaryOperator.COMMA) { if (operator == JsBinaryOperator.COMMA) {
isParenOpened = false; isParenOpened = false;
spaceOpt(); spaceOpt();
} }
else if (arg2 instanceof JsBinaryOperation && isBinaryOperationShouldBeEnclosed(((JsBinaryOperation) arg2).getOperator())) { else if (arg2 instanceof JsBinaryOperation && ((JsBinaryOperation) arg2).getOperator() == JsBinaryOperator.AND) {
spaceOpt(); spaceOpt();
leftParen(); leftParen();
isParenOpened = true; isParenOpened = true;
} }
else { else {
if (spaceCalc(op, arg2)) { if (spaceCalc(operator, arg2)) {
isParenOpened = _parenPushOrSpace(binaryOperation, arg2, op.isLeftAssociative()); isParenOpened = _parenPushOrSpace(binaryOperation, arg2, operator.isLeftAssociative());
} }
else { else {
spaceOpt(); spaceOpt();
isParenOpened = _parenPush(binaryOperation, arg2, op.isLeftAssociative()); isParenOpened = parenPush(binaryOperation, arg2, operator.isLeftAssociative());
} }
} }
accept(arg2); accept(arg2);
@@ -291,10 +280,6 @@ public class JsToStringGenerationVisitor extends JsVisitor {
return false; return false;
} }
private static boolean isBinaryOperationShouldBeEnclosed(JsBinaryOperator operator) {
return operator == JsBinaryOperator.AND;
}
@Override @Override
public boolean visit(JsBlock x, JsContext ctx) { public boolean visit(JsBlock x, JsContext ctx) {
printJsBlock(x, true, true); printJsBlock(x, true, true);
@@ -307,21 +292,21 @@ public class JsToStringGenerationVisitor extends JsVisitor {
p.print(CHARS_TRUE); p.print(CHARS_TRUE);
} }
else { else {
_false(); p.print(CHARS_FALSE);
} }
return false; return false;
} }
@Override @Override
public boolean visit(JsBreak x, JsContext ctx) { public boolean visit(JsBreak x, JsContext ctx) {
_break(); p.print(CHARS_BREAK);
continueOrBreakLabel(x); continueOrBreakLabel(x);
return false; return false;
} }
@Override @Override
public boolean visit(JsContinue x, JsContext ctx) { public boolean visit(JsContinue x, JsContext ctx) {
_continue(); p.print(CHARS_CONTINUE);
continueOrBreakLabel(x); continueOrBreakLabel(x);
return false; return false;
} }
@@ -336,7 +321,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
@Override @Override
public boolean visit(JsCase x, JsContext ctx) { public boolean visit(JsCase x, JsContext ctx) {
_case(); p.print(CHARS_CASE);
space(); space();
accept(x.getCaseExpr()); accept(x.getCaseExpr());
_colon(); _colon();
@@ -347,7 +332,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
} }
private void printSwitchMemberStatements(JsSwitchMember x) { private void printSwitchMemberStatements(JsSwitchMember x) {
indent(); p.indentIn();
for (JsStatement stmt : x.getStatements()) { for (JsStatement stmt : x.getStatements()) {
needSemi = true; needSemi = true;
accept(stmt); accept(stmt);
@@ -356,14 +341,14 @@ public class JsToStringGenerationVisitor extends JsVisitor {
} }
newlineOpt(); newlineOpt();
} }
outdent(); p.indentOut();
needSemi = false; needSemi = false;
} }
@Override @Override
public boolean visit(JsCatch x, JsContext ctx) { public boolean visit(JsCatch x, JsContext ctx) {
spaceOpt(); spaceOpt();
_catch(); p.print(CHARS_CATCH);
spaceOpt(); spaceOpt();
leftParen(); leftParen();
nameDef(x.getParameter().getName()); nameDef(x.getParameter().getName());
@@ -416,13 +401,13 @@ public class JsToStringGenerationVisitor extends JsVisitor {
@Override @Override
public boolean visit(JsDebugger x, JsContext ctx) { public boolean visit(JsDebugger x, JsContext ctx) {
_debugger(); p.print(CHARS_DEBUGGER);
return false; return false;
} }
@Override @Override
public boolean visit(JsDefault x, JsContext ctx) { public boolean visit(JsDefault x, JsContext ctx) {
_default(); p.print(CHARS_DEFAULT);
_colon(); _colon();
printSwitchMemberStatements(x); printSwitchMemberStatements(x);
@@ -444,7 +429,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
@Override @Override
public boolean visit(JsDoWhile x, JsContext ctx) { public boolean visit(JsDoWhile x, JsContext ctx) {
_do(); p.print(CHARS_DO);
_nestedPush(x.getBody()); _nestedPush(x.getBody());
accept(x.getBody()); accept(x.getBody());
_nestedPop(x.getBody()); _nestedPop(x.getBody());
@@ -547,7 +532,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
} }
space(); space();
_in(); p.print(CHARS_IN);
space(); space();
accept(x.getObjExpr()); accept(x.getObjExpr());
@@ -560,7 +545,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
@Override @Override
public boolean visit(JsFunction x, JsContext ctx) { public boolean visit(JsFunction x, JsContext ctx) {
_function(); p.print(CHARS_FUNCTION);
space(); space();
if (x.getName() != null) { if (x.getName() != null) {
nameOf(x); nameOf(x);
@@ -593,8 +578,8 @@ public class JsToStringGenerationVisitor extends JsVisitor {
_nestedPush(thenStmt); _nestedPush(thenStmt);
accept(thenStmt); accept(thenStmt);
_nestedPop(thenStmt); _nestedPop(thenStmt);
JsStatement elseStmt = x.getElseStatement(); JsStatement elseStatement = x.getElseStatement();
if (elseStmt != null) { if (elseStatement != null) {
if (needSemi) { if (needSemi) {
semi(); semi();
newlineOpt(); newlineOpt();
@@ -603,17 +588,17 @@ public class JsToStringGenerationVisitor extends JsVisitor {
spaceOpt(); spaceOpt();
needSemi = true; needSemi = true;
} }
_else(); p.print(CHARS_ELSE);
boolean elseIf = elseStmt instanceof JsIf; boolean elseIf = elseStatement instanceof JsIf;
if (!elseIf) { if (!elseIf) {
_nestedPush(elseStmt); _nestedPush(elseStatement);
} }
else { else {
space(); space();
} }
accept(elseStmt); accept(elseStatement);
if (!elseIf) { if (!elseIf) {
_nestedPop(elseStmt); _nestedPop(elseStatement);
} }
} }
return false; return false;
@@ -642,7 +627,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
public boolean visit(JsNameRef x, JsContext ctx) { public boolean visit(JsNameRef x, JsContext ctx) {
JsExpression q = x.getQualifier(); JsExpression q = x.getQualifier();
if (q != null) { if (q != null) {
_parenPush(x, q, false); parenPush(x, q, false);
if (q instanceof JsNumberLiteral) { if (q instanceof JsNumberLiteral) {
/** /**
* Fix for Issue #3796. "42.foo" is not allowed, but "(42).foo" is. * Fix for Issue #3796. "42.foo" is not allowed, but "(42).foo" is.
@@ -654,7 +639,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
rightParen(); rightParen();
} }
parenPop(x, q, false); parenPop(x, q, false);
_dot(); p.print('.');
} }
_nameRef(x); _nameRef(x);
return false; return false;
@@ -662,7 +647,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
@Override @Override
public boolean visit(JsNew x, JsContext ctx) { public boolean visit(JsNew x, JsContext ctx) {
_new(); p.print(CHARS_NEW);
space(); space();
JsExpression ctorExpr = x.getConstructorExpression(); JsExpression ctorExpr = x.getConstructorExpression();
@@ -684,7 +669,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
@Override @Override
public boolean visit(JsNullLiteral x, JsContext ctx) { public boolean visit(JsNullLiteral x, JsContext ctx) {
_null(); p.print(CHARS_NULL);
return false; return false;
} }
@@ -702,7 +687,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
@Override @Override
public boolean visit(JsObjectLiteral objectLiteral, JsContext context) { public boolean visit(JsObjectLiteral objectLiteral, JsContext context) {
_lbrace(); p.print('{');
if (objectLiteral.isMultiline()) { if (objectLiteral.isMultiline()) {
p.indentIn(); p.indentIn();
} }
@@ -749,7 +734,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
newlineOpt(); newlineOpt();
} }
_rbrace(); p.print('}');
return false; return false;
} }
@@ -816,7 +801,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
@Override @Override
public boolean visit(JsReturn x, JsContext ctx) { public boolean visit(JsReturn x, JsContext ctx) {
_return(); p.print(CHARS_RETURN);
JsExpression expr = x.getExpr(); JsExpression expr = x.getExpr();
if (expr != null) { if (expr != null) {
space(); space();
@@ -827,13 +812,13 @@ public class JsToStringGenerationVisitor extends JsVisitor {
@Override @Override
public boolean visit(JsStringLiteral x, JsContext ctx) { public boolean visit(JsStringLiteral x, JsContext ctx) {
printStringLiteral(x.getValue()); p.print(javaScriptString(x.getValue()));
return false; return false;
} }
@Override @Override
public boolean visit(JsSwitch x, JsContext ctx) { public boolean visit(JsSwitch x, JsContext ctx) {
_switch(); p.print(CHARS_SWITCH);
spaceOpt(); spaceOpt();
leftParen(); leftParen();
accept(x.getExpr()); accept(x.getExpr());
@@ -927,13 +912,13 @@ public class JsToStringGenerationVisitor extends JsVisitor {
space(); space();
} }
else { else {
newline(); p.newline();
} }
boolean notFirst = false; boolean notFirst = false;
for (Map.Entry<String, Object> entry : comment.getTags().entrySet()) { for (Map.Entry<String, Object> entry : comment.getTags().entrySet()) {
if (notFirst) { if (notFirst) {
newline(); p.newline();
p.print(' '); p.print(' ');
p.print('*'); p.print('*');
} }
@@ -955,7 +940,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
} }
if (!asSingleLine) { if (!asSingleLine) {
newline(); p.newline();
} }
} }
@@ -974,16 +959,9 @@ public class JsToStringGenerationVisitor extends JsVisitor {
return false; return false;
} }
protected final void newline() {
if (sourceMapBuilder != null) {
sourceMapBuilder.newLine();
}
p.newline();
}
protected final void newlineOpt() { protected final void newlineOpt() {
if (!p.isCompact()) { if (!p.isCompact()) {
newline(); p.newline();
} }
} }
@@ -1046,12 +1024,12 @@ public class JsToStringGenerationVisitor extends JsVisitor {
newlineOpt(); newlineOpt();
} }
else { else {
newline(); p.newline();
} }
} }
else { else {
if (lastStatement) { if (lastStatement) {
semiOpt(); p.printOpt(';');
} }
else { else {
semi(); semi();
@@ -1089,75 +1067,23 @@ public class JsToStringGenerationVisitor extends JsVisitor {
newlineOpt(); newlineOpt();
} }
private void _break() {
p.print(CHARS_BREAK);
}
private void _case() {
p.print(CHARS_CASE);
}
private void _catch() {
p.print(CHARS_CATCH);
}
private void _colon() { private void _colon() {
p.print(':'); p.print(':');
} }
private void _continue() {
p.print(CHARS_CONTINUE);
}
private void _debugger() {
p.print(CHARS_DEBUGGER);
}
private void _default() {
p.print(CHARS_DEFAULT);
}
private void _do() {
p.print(CHARS_DO);
}
private void _dot() {
p.print('.');
}
private void _else() {
p.print(CHARS_ELSE);
}
private void _false() {
p.print(CHARS_FALSE);
}
private void _for() { private void _for() {
p.print(CHARS_FOR); p.print(CHARS_FOR);
} }
private void _function() {
p.print(CHARS_FUNCTION);
}
private void _if() { private void _if() {
p.print(CHARS_IF); p.print(CHARS_IF);
} }
private void _in() {
p.print(CHARS_IN);
}
private void _lbrace() {
p.print('{');
}
private void leftParen() { private void leftParen() {
p.print('('); p.print('(');
} }
private void _lsquare() { private void leftSquare() {
p.print('['); p.print('[');
} }
@@ -1193,14 +1119,6 @@ public class JsToStringGenerationVisitor extends JsVisitor {
return push; return push;
} }
private void _new() {
p.print(CHARS_NEW);
}
private void _null() {
p.print(CHARS_NULL);
}
private static boolean parenCalc(JsExpression parent, JsExpression child, boolean wrongAssoc) { private static boolean parenCalc(JsExpression parent, JsExpression child, boolean wrongAssoc) {
int parentPrec = JsPrecedenceVisitor.exec(parent); int parentPrec = JsPrecedenceVisitor.exec(parent);
int childPrec = JsPrecedenceVisitor.exec(child); int childPrec = JsPrecedenceVisitor.exec(child);
@@ -1226,7 +1144,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
return doPop; return doPop;
} }
private boolean _parenPush(JsExpression parent, JsExpression child, boolean wrongAssoc) { private boolean parenPush(JsExpression parent, JsExpression child, boolean wrongAssoc) {
boolean doPush = parenCalc(parent, child, wrongAssoc); boolean doPush = parenCalc(parent, child, wrongAssoc);
if (doPush) { if (doPush) {
leftParen(); leftParen();
@@ -1257,19 +1175,11 @@ public class JsToStringGenerationVisitor extends JsVisitor {
p.print('?'); p.print('?');
} }
private void _rbrace() {
p.print('}');
}
private void _return() {
p.print(CHARS_RETURN);
}
private void rightParen() { private void rightParen() {
p.print(')'); p.print(')');
} }
private void _rsquare() { private void rightSquare() {
p.print(']'); p.print(']');
} }
@@ -1277,10 +1187,6 @@ public class JsToStringGenerationVisitor extends JsVisitor {
p.print(';'); p.print(';');
} }
private void semiOpt() {
p.printOpt(';');
}
private boolean sepCommaOptSpace(boolean sep) { private boolean sepCommaOptSpace(boolean sep) {
if (sep) { if (sep) {
p.print(','); p.print(',');
@@ -1338,10 +1244,6 @@ public class JsToStringGenerationVisitor extends JsVisitor {
p.printOpt(' '); p.printOpt(' ');
} }
private void _switch() {
p.print(CHARS_SWITCH);
}
private void var() { private void var() {
p.print(CHARS_VAR); p.print(CHARS_VAR);
} }
@@ -1349,38 +1251,4 @@ public class JsToStringGenerationVisitor extends JsVisitor {
private void _while() { private void _while() {
p.print(CHARS_WHILE); p.print(CHARS_WHILE);
} }
private void indent() {
p.indentIn();
}
private void outdent() {
p.indentOut();
}
private void printStringLiteral(String value) {
p.print(javaScriptString(value));
}
@Override
protected void doTraverse(JsVisitable node, JsContext context) {
super.doTraverse(node, context);
if (sourceMapBuilder == null) {
return;
}
Object sourceInfo = node.getSourceInfo();
if (sourceInfo != null) {
sourceMapBuilder.processSourceInfo(sourceInfo);
}
}
@Override
public void endVisit(JsProgram x, JsContext context) {
super.endVisit(x, context);
if (sourceMapBuilder != null) {
sourceMapBuilder.addLink();
}
}
} }
@@ -8,30 +8,29 @@ package com.google.dart.compiler.backend.js.ast;
* Represents a javascript expression for array access. * Represents a javascript expression for array access.
*/ */
public final class JsArrayAccess extends JsExpressionImpl { public final class JsArrayAccess extends JsExpressionImpl {
private JsExpression arrayExpression;
private JsExpression arrayExpr; private JsExpression indexExpression;
private JsExpression indexExpr;
public JsArrayAccess() { public JsArrayAccess() {
super(); super();
} }
public JsArrayAccess(JsExpression arrayExpr, JsExpression indexExpr) { public JsArrayAccess(JsExpression arrayExpression, JsExpression indexExpression) {
this.arrayExpr = arrayExpr; this.arrayExpression = arrayExpression;
this.indexExpr = indexExpr; this.indexExpression = indexExpression;
} }
public JsExpression getArrayExpr() { public JsExpression getArrayExpression() {
return arrayExpr; return arrayExpression;
} }
public JsExpression getIndexExpr() { public JsExpression getIndexExpression() {
return indexExpr; return indexExpression;
} }
@Override @Override
public boolean hasSideEffects() { public boolean hasSideEffects() {
return arrayExpr.hasSideEffects() || indexExpr.hasSideEffects(); return arrayExpression.hasSideEffects() || indexExpression.hasSideEffects();
} }
@Override @Override
@@ -44,19 +43,19 @@ public final class JsArrayAccess extends JsExpressionImpl {
return false; return false;
} }
public void setArrayExpr(JsExpression arrayExpr) { public void setArrayExpression(JsExpression arrayExpression) {
this.arrayExpr = arrayExpr; this.arrayExpression = arrayExpression;
} }
public void setIndexExpr(JsExpression indexExpr) { public void setIndexExpression(JsExpression indexExpression) {
this.indexExpr = indexExpr; this.indexExpression = indexExpression;
} }
@Override @Override
public void traverse(JsVisitor v, JsContext context) { public void traverse(JsVisitor v, JsContext context) {
if (v.visit(this, context)) { if (v.visit(this, context)) {
arrayExpr = v.accept(arrayExpr); arrayExpression = v.accept(arrayExpression);
indexExpr = v.accept(indexExpr); indexExpression = v.accept(indexExpression);
} }
v.endVisit(this, context); v.endVisit(this, context);
} }
@@ -4,8 +4,6 @@
package com.google.dart.compiler.backend.js.ast; package com.google.dart.compiler.backend.js.ast;
import com.google.dart.compiler.common.SourceInfo;
public final class JsExpressionStatement extends AbstractNode implements JsStatement { public final class JsExpressionStatement extends AbstractNode implements JsStatement {
private JsExpression expression; private JsExpression expression;
@@ -32,11 +30,11 @@ public final class JsExpressionStatement extends AbstractNode implements JsState
@Override @Override
public Object getSourceInfo() { public Object getSourceInfo() {
return expression.getSourceInfo(); return null;
} }
@Override @Override
public void setSourceInfo(Object info) { public void setSourceInfo(Object info) {
expression.setSourceInfo(info); throw new IllegalStateException("You must not set source info for JsExpressionStatement, set for expression");
} }
} }
@@ -87,20 +87,26 @@ abstract public class JsVisitor {
} }
}; };
public final <T extends JsVisitable> T accept(T node) { public <T extends JsVisitable> T accept(T node) {
return doAccept(node); doTraverse(node, UNMODIFIABLE_CONTEXT);
return node;
} }
public final <T extends JsVisitable> void acceptList(List<T> collection) { public final <T extends JsVisitable> void acceptList(List<T> collection) {
doAcceptList(collection); for (T node : collection) {
doTraverse(node, UNMODIFIABLE_CONTEXT);
}
} }
public JsExpression acceptLvalue(JsExpression expr) { public JsExpression acceptLvalue(JsExpression expr) {
return doAcceptLvalue(expr); doTraverse(expr, LVALUE_CONTEXT);
return expr;
} }
public final <T extends JsVisitable> void acceptWithInsertRemove(List<T> collection) { public final <T extends JsVisitable> void acceptWithInsertRemove(List<T> collection) {
doAcceptWithInsertRemove(collection); for (T node : collection) {
doTraverse(node, UNMODIFIABLE_CONTEXT);
}
} }
public void endVisit(JsArrayAccess x, JsContext ctx) { public void endVisit(JsArrayAccess x, JsContext ctx) {
@@ -405,28 +411,6 @@ abstract public class JsVisitor {
return true; return true;
} }
protected <T extends JsVisitable> T doAccept(T node) {
doTraverse(node, UNMODIFIABLE_CONTEXT);
return node;
}
protected <T extends JsVisitable> void doAcceptList(List<T> collection) {
for (T node : collection) {
doTraverse(node, UNMODIFIABLE_CONTEXT);
}
}
protected JsExpression doAcceptLvalue(JsExpression expr) {
doTraverse(expr, LVALUE_CONTEXT);
return expr;
}
protected <T extends JsVisitable> void doAcceptWithInsertRemove(List<T> collection) {
for (T node : collection) {
doTraverse(node, UNMODIFIABLE_CONTEXT);
}
}
protected void doTraverse(JsVisitable node, JsContext context) { protected void doTraverse(JsVisitable node, JsContext context) {
node.traverse(this, context); node.traverse(this, context);
} }
@@ -37,4 +37,14 @@ public interface TextOutput {
void printOpt(String s); void printOpt(String s);
boolean isCompact(); boolean isCompact();
boolean isJustNewlined();
void setOutListener(OutListener outListener);
public interface OutListener {
void newLined();
void indentedAfterNewLine();
}
} }
@@ -6,9 +6,6 @@ package com.google.dart.compiler.util;
import java.util.Arrays; import java.util.Arrays;
/**
* An abstract base type to build TextOutput implementations.
*/
public class TextOutputImpl implements TextOutput { public class TextOutputImpl implements TextOutput {
private final boolean compact; private final boolean compact;
private int identLevel = 0; private int identLevel = 0;
@@ -20,6 +17,8 @@ public class TextOutputImpl implements TextOutput {
private int line = 0; private int line = 0;
private int column = 0; private int column = 0;
private OutListener outListener;
public TextOutputImpl() { public TextOutputImpl() {
this(false); this(false);
} }
@@ -107,30 +106,24 @@ public class TextOutputImpl implements TextOutput {
private void movePosition(int l) { private void movePosition(int l) {
position += l; position += l;
column += l; column += l;
justNewlined = false;
} }
@Override @Override
public void print(char[] s) { public void print(char[] s) {
maybeIndent(); maybeIndent();
printAndCount(s); printAndCount(s);
justNewlined = false;
} }
@Override @Override
public void print(CharSequence s) { public void print(CharSequence s) {
maybeIndent(); maybeIndent();
printAndCount(s); printAndCount(s);
justNewlined = false;
} }
@Override @Override
public void printOpt(char c) { public void printOpt(char c) {
if (!compact) { if (!compact) {
maybeIndent(); print(c);
out.append(c);
position++;
column++;
} }
} }
@@ -154,6 +147,9 @@ public class TextOutputImpl implements TextOutput {
if (justNewlined && !compact) { if (justNewlined && !compact) {
printAndCount(indents[identLevel]); printAndCount(indents[identLevel]);
justNewlined = false; justNewlined = false;
if (outListener != null) {
outListener.indentedAfterNewLine();
}
} }
} }
@@ -168,4 +164,14 @@ public class TextOutputImpl implements TextOutput {
column += chars.length; column += chars.length;
out.append(chars); out.append(chars);
} }
@Override
public boolean isJustNewlined() {
return justNewlined && !compact;
}
@Override
public void setOutListener(OutListener outListener) {
this.outListener = outListener;
}
} }