Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(290)

Unified Diff: compiler/java/com/google/dart/compiler/backend/js/JsToStringGenerationVisitor.java

Issue 9479013: Remove backends. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: More clean up Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: compiler/java/com/google/dart/compiler/backend/js/JsToStringGenerationVisitor.java
diff --git a/compiler/java/com/google/dart/compiler/backend/js/JsToStringGenerationVisitor.java b/compiler/java/com/google/dart/compiler/backend/js/JsToStringGenerationVisitor.java
deleted file mode 100644
index ed0666c9d97fcc37f303f4d5370e3a774a89c210..0000000000000000000000000000000000000000
--- a/compiler/java/com/google/dart/compiler/backend/js/JsToStringGenerationVisitor.java
+++ /dev/null
@@ -1,1354 +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.common.collect.Lists;
-import com.google.dart.compiler.backend.js.ast.HasName;
-import com.google.dart.compiler.backend.js.ast.JsArrayAccess;
-import com.google.dart.compiler.backend.js.ast.JsArrayLiteral;
-import com.google.dart.compiler.backend.js.ast.JsBinaryOperation;
-import com.google.dart.compiler.backend.js.ast.JsBinaryOperator;
-import com.google.dart.compiler.backend.js.ast.JsBlock;
-import com.google.dart.compiler.backend.js.ast.JsBooleanLiteral;
-import com.google.dart.compiler.backend.js.ast.JsBreak;
-import com.google.dart.compiler.backend.js.ast.JsCase;
-import com.google.dart.compiler.backend.js.ast.JsCatch;
-import com.google.dart.compiler.backend.js.ast.JsConditional;
-import com.google.dart.compiler.backend.js.ast.JsContext;
-import com.google.dart.compiler.backend.js.ast.JsContinue;
-import com.google.dart.compiler.backend.js.ast.JsDebugger;
-import com.google.dart.compiler.backend.js.ast.JsDefault;
-import com.google.dart.compiler.backend.js.ast.JsDoWhile;
-import com.google.dart.compiler.backend.js.ast.JsEmpty;
-import com.google.dart.compiler.backend.js.ast.JsExprStmt;
-import com.google.dart.compiler.backend.js.ast.JsExpression;
-import com.google.dart.compiler.backend.js.ast.JsFor;
-import com.google.dart.compiler.backend.js.ast.JsForIn;
-import com.google.dart.compiler.backend.js.ast.JsFunction;
-import com.google.dart.compiler.backend.js.ast.JsIf;
-import com.google.dart.compiler.backend.js.ast.JsInvocation;
-import com.google.dart.compiler.backend.js.ast.JsLabel;
-import com.google.dart.compiler.backend.js.ast.JsName;
-import com.google.dart.compiler.backend.js.ast.JsNameRef;
-import com.google.dart.compiler.backend.js.ast.JsNew;
-import com.google.dart.compiler.backend.js.ast.JsNullLiteral;
-import com.google.dart.compiler.backend.js.ast.JsNumberLiteral;
-import com.google.dart.compiler.backend.js.ast.JsObjectLiteral;
-import com.google.dart.compiler.backend.js.ast.JsOperator;
-import com.google.dart.compiler.backend.js.ast.JsParameter;
-import com.google.dart.compiler.backend.js.ast.JsPostfixOperation;
-import com.google.dart.compiler.backend.js.ast.JsPrefixOperation;
-import com.google.dart.compiler.backend.js.ast.JsProgram;
-import com.google.dart.compiler.backend.js.ast.JsProgramFragment;
-import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer;
-import com.google.dart.compiler.backend.js.ast.JsRegExp;
-import com.google.dart.compiler.backend.js.ast.JsReturn;
-import com.google.dart.compiler.backend.js.ast.JsStatement;
-import com.google.dart.compiler.backend.js.ast.JsStringLiteral;
-import com.google.dart.compiler.backend.js.ast.JsSwitch;
-import com.google.dart.compiler.backend.js.ast.JsThisRef;
-import com.google.dart.compiler.backend.js.ast.JsThrow;
-import com.google.dart.compiler.backend.js.ast.JsTry;
-import com.google.dart.compiler.backend.js.ast.JsUnaryOperator;
-import com.google.dart.compiler.backend.js.ast.JsVars;
-import com.google.dart.compiler.backend.js.ast.JsVisitable;
-import com.google.dart.compiler.backend.js.ast.JsVisitor;
-import com.google.dart.compiler.backend.js.ast.JsWhile;
-import com.google.dart.compiler.backend.js.ast.JsVars.JsVar;
-import com.google.dart.compiler.common.HasSourceInfo;
-import com.google.dart.compiler.util.TextOutput;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.regex.Pattern;
-
-/**
- * Produces text output from a JavaScript AST.
- */
-public class JsToStringGenerationVisitor extends JsVisitor {
-
- private static final char[] CHARS_BREAK = "break".toCharArray();
- private static final char[] CHARS_CASE = "case".toCharArray();
- private static final char[] CHARS_CATCH = "catch".toCharArray();
- private static final char[] CHARS_CONTINUE = "continue".toCharArray();
- private static final char[] CHARS_DEBUGGER = "debugger".toCharArray();
- private static final char[] CHARS_DEFAULT = "default".toCharArray();
- private static final char[] CHARS_DO = "do".toCharArray();
- private static final char[] CHARS_ELSE = "else".toCharArray();
- private static final char[] CHARS_FALSE = "false".toCharArray();
- private static final char[] CHARS_FINALLY = "finally".toCharArray();
- private static final char[] CHARS_FOR = "for".toCharArray();
- private static final char[] CHARS_FUNCTION = "function".toCharArray();
- private static final char[] CHARS_IF = "if".toCharArray();
- private static final char[] CHARS_IN = "in".toCharArray();
- private static final char[] CHARS_NEW = "new".toCharArray();
- private static final char[] CHARS_NULL = "null".toCharArray();
- private static final char[] CHARS_RETURN = "return".toCharArray();
- private static final char[] CHARS_SWITCH = "switch".toCharArray();
- private static final char[] CHARS_THIS = "this".toCharArray();
- private static final char[] CHARS_THROW = "throw".toCharArray();
- private static final char[] CHARS_TRUE = "true".toCharArray();
- private static final char[] CHARS_TRY = "try".toCharArray();
- private static final char[] CHARS_VAR = "var".toCharArray();
- private static final char[] CHARS_WHILE = "while".toCharArray();
- private static final char[] HEX_DIGITS = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
-
- /**
- * How many lines of code to print inside of a JsBlock when printing terse.
- */
- private static final int JSBLOCK_LINES_TO_PRINT = 3;
-
- /**
- * A variable name is valid if it contains only letters, numbers, _, $ and
- * does not begin with a number. There are actually other valid variable
- * names, such as ones that contain escaped Unicode characters, but we
- * surround those names with quotes in property initializers to be safe.
- */
- private static final Pattern VALID_NAME_PATTERN = Pattern.compile("[a-zA-Z_$][\\w$]*");
-
- public static String javaScriptString(String value) {
- return javaScriptString(value, false);
- }
-
- /**
- * Generate JavaScript code that evaluates to the supplied string. Adapted
- * from {@link ScriptRuntime#escapeString(String)}
- * . The difference is that we quote with either " or ' depending on
- * which one is used less inside the string.
- */
- public static String javaScriptString(String value, boolean forceDoubleQuote) {
- char[] chars = value.toCharArray();
- final int n = chars.length;
- int quoteCount = 0;
- int aposCount = 0;
- for (int i = 0; i < n; ++i) {
- switch (chars[i]) {
- case '"':
- ++quoteCount;
- break;
- case '\'':
- ++aposCount;
- break;
- }
- }
-
- StringBuffer result = new StringBuffer(value.length() + 16);
-
- char quoteChar = (quoteCount < aposCount || forceDoubleQuote) ? '"' : '\'';
- result.append(quoteChar);
-
- for (int i = 0; i < n; ++i) {
- char c = chars[i];
-
- if (' ' <= c && c <= '~' && c != quoteChar && c != '\\') {
- // an ordinary print character (like C isprint())
- result.append(c);
- continue;
- }
-
- int escape = -1;
- switch (c) {
- case '\b':
- escape = 'b';
- break;
- case '\f':
- escape = 'f';
- break;
- case '\n':
- escape = 'n';
- break;
- case '\r':
- escape = 'r';
- break;
- case '\t':
- escape = 't';
- break;
- case '"':
- escape = '"';
- break; // only reach here if == quoteChar
- case '\'':
- escape = '\'';
- break; // only reach here if == quoteChar
- case '\\':
- escape = '\\';
- break;
- }
-
- if (escape >= 0) {
- // an \escaped sort of character
- result.append('\\');
- result.append((char) escape);
- } else {
- /*
- * Emit characters from 0 to 31 that don't have a single character
- * escape sequence in octal where possible. This saves one or two
- * characters compared to the hexadecimal format '\xXX'.
- *
- * These short octal sequences may only be used at the end of the string
- * or where the following character is a non-digit. Otherwise, the
- * following character would be incorrectly interpreted as belonging to
- * the sequence.
- */
- if (c < ' ' && (i == n - 1 || chars[i + 1] < '0' || chars[i + 1] > '9')) {
- result.append('\\');
- if (c > 0x7) {
- result.append((char) ('0' + (0x7 & (c >> 3))));
- }
- result.append((char) ('0' + (0x7 & c)));
- } else {
- int hexSize;
- if (c < 256) {
- // 2-digit hex
- result.append("\\x");
- hexSize = 2;
- } else {
- // Unicode.
- result.append("\\u");
- hexSize = 4;
- }
- // append hexadecimal form of ch left-padded with 0
- for (int shift = (hexSize - 1) * 4; shift >= 0; shift -= 4) {
- int digit = 0xf & (c >> shift);
- result.append(HEX_DIGITS[digit]);
- }
- }
- }
- }
- result.append(quoteChar);
- escapeClosingTags(result);
- String resultString = result.toString();
- return resultString;
- }
-
- /**
- * Escapes any closing XML tags embedded in <code>str</code>, which could
- * potentially cause a parse failure in a browser, for example, embedding a
- * closing <code>&lt;script&gt;</code> tag.
- *
- * @param str an unescaped literal; May be null
- */
- private static void escapeClosingTags(StringBuffer str) {
- if (str == null) {
- return;
- }
-
- int index = 0;
-
- while ((index = str.indexOf("</", index)) != -1) {
- str.insert(index + 1, '\\');
- }
- }
-
- protected boolean needSemi = true;
-
- /**
- * "Global" blocks are either the global block of a fragment, or a block
- * nested directly within some other global block. This definition matters
- * because the statements designated by statementEnds and statementStarts are
- * those that appear directly within these global blocks.
- */
- private Set<JsBlock> globalBlocks = new HashSet<JsBlock>();
- private final TextOutput p;
- private ArrayList<Integer> statementEnds = new ArrayList<Integer>();
- private ArrayList<Integer> statementStarts = new ArrayList<Integer>();
-
- public JsToStringGenerationVisitor(TextOutput out) {
- this.p = out;
- }
-
- @Override
- public boolean visit(JsArrayAccess x, JsContext ctx) {
- JsExpression arrayExpr = x.getArrayExpr();
- _parenPush(x, arrayExpr, false);
- accept(arrayExpr);
- _parenPop(x, arrayExpr, false);
- _lsquare();
- accept(x.getIndexExpr());
- _rsquare();
- return false;
- }
-
- @Override
- public boolean visit(JsArrayLiteral x, JsContext ctx) {
- _lsquare();
- boolean sep = false;
- for (Object element : x.getExpressions()) {
- JsExpression arg = (JsExpression) element;
- sep = _sepCommaOptSpace(sep);
- _parenPushIfCommaExpr(arg);
- accept(arg);
- _parenPopIfCommaExpr(arg);
- }
- _rsquare();
- return false;
- }
-
- @Override
- public boolean visit(JsBinaryOperation x, JsContext ctx) {
- JsBinaryOperator op = x.getOperator();
- JsExpression arg1 = x.getArg1();
- _parenPush(x, arg1, !op.isLeftAssociative());
- accept(arg1);
- if (op.isKeyword()) {
- _parenPopOrSpace(x, arg1, !op.isLeftAssociative());
- } else {
- _parenPop(x, arg1, !op.isLeftAssociative());
- _spaceOpt();
- }
- p.print(op.getSymbol());
- JsExpression arg2 = x.getArg2();
- if (_spaceCalc(op, arg2)) {
- _parenPushOrSpace(x, arg2, op.isLeftAssociative());
- } else {
- _spaceOpt();
- _parenPush(x, arg2, op.isLeftAssociative());
- }
- accept(arg2);
- _parenPop(x, arg2, op.isLeftAssociative());
- return false;
- }
-
- @Override
- public boolean visit(JsBlock x, JsContext ctx) {
- printJsBlock(x, true, true);
- return false;
- }
-
- @Override
- public boolean visit(JsBooleanLiteral x, JsContext ctx) {
- if (x.getValue()) {
- _true();
- } else {
- _false();
- }
- return false;
- }
-
- @Override
- public boolean visit(JsBreak x, JsContext ctx) {
- _break();
-
- JsNameRef label = x.getLabel();
- if (label != null) {
- _space();
- _nameRef(label);
- }
-
- return false;
- }
-
- @Override
- public boolean visit(JsCase x, JsContext ctx) {
- _case();
- _space();
- accept(x.getCaseExpr());
- _colon();
- _newlineOpt();
-
- indent();
- for (Object element : x.getStmts()) {
- JsStatement stmt = (JsStatement) element;
- needSemi = true;
- accept(stmt);
- if (needSemi) {
- _semi();
- }
- _newlineOpt();
- }
- outdent();
- needSemi = false;
- return false;
- }
-
- @Override
- public boolean visit(JsCatch x, JsContext ctx) {
- _spaceOpt();
- _catch();
- _spaceOpt();
- _lparen();
- _nameDef(x.getParameter().getName());
-
- // Optional catch condition.
- //
- JsExpression catchCond = x.getCondition();
- if (catchCond != null) {
- _space();
- _if();
- _space();
- accept(catchCond);
- }
-
- _rparen();
- _spaceOpt();
- accept(x.getBody());
-
- return false;
- }
-
- @Override
- public boolean visit(JsConditional x, JsContext ctx) {
- // Associativity: for the then and else branches, it is safe to insert
- // another
- // ternary expression, but if the test expression is a ternary, it should
- // get parentheses around it.
- {
- JsExpression testExpression = x.getTestExpression();
- _parenPush(x, testExpression, true);
- accept(testExpression);
- _parenPop(x, testExpression, true);
- }
- _questionMark();
- {
- JsExpression thenExpression = x.getThenExpression();
- _parenPush(x, thenExpression, false);
- accept(thenExpression);
- _parenPop(x, thenExpression, false);
- }
- _colon();
- {
- JsExpression elseExpression = x.getElseExpression();
- _parenPush(x, elseExpression, false);
- accept(elseExpression);
- _parenPop(x, elseExpression, false);
- }
- return false;
- }
-
- @Override
- public boolean visit(JsContinue x, JsContext ctx) {
- _continue();
-
- JsNameRef label = x.getLabel();
- if (label != null) {
- _space();
- _nameRef(label);
- }
-
- return false;
- }
-
- @Override
- public boolean visit(JsDebugger x, JsContext ctx) {
- _debugger();
- return false;
- }
-
- @Override
- public boolean visit(JsDefault x, JsContext ctx) {
- _default();
- _colon();
-
- indent();
- for (Object element : x.getStmts()) {
- JsStatement stmt = (JsStatement) element;
- needSemi = true;
- accept(stmt);
- if (needSemi) {
- _semi();
- }
- _newlineOpt();
- }
- outdent();
- needSemi = false;
- return false;
- }
-
- @Override
- public boolean visit(JsDoWhile x, JsContext ctx) {
- _do();
- _nestedPush(x.getBody(), true);
- accept(x.getBody());
- _nestedPop(x.getBody());
- if (needSemi) {
- _semi();
- _newlineOpt();
- } else {
- _spaceOpt();
- needSemi = true;
- }
- _while();
- _spaceOpt();
- _lparen();
- accept(x.getCondition());
- _rparen();
- return false;
- }
-
- @Override
- public boolean visit(JsEmpty x, JsContext ctx) {
- return false;
- }
-
- @Override
- public boolean visit(JsExprStmt x, JsContext ctx) {
- boolean surroundWithParentheses = JsFirstExpressionVisitor.exec(x);
- if (surroundWithParentheses) {
- _lparen();
- }
- JsExpression expr = x.getExpression();
- accept(expr);
- if (surroundWithParentheses) {
- _rparen();
- }
- return false;
- }
-
- @Override
- public boolean visit(JsFor x, JsContext ctx) {
- _for();
- _spaceOpt();
- _lparen();
-
- // The init expressions or var decl.
- //
- if (x.getInitExpr() != null) {
- accept(x.getInitExpr());
- } else if (x.getInitVars() != null) {
- accept(x.getInitVars());
- }
-
- _semi();
-
- // The loop test.
- //
- if (x.getCondition() != null) {
- _spaceOpt();
- accept(x.getCondition());
- }
-
- _semi();
-
- // The incr expression.
- //
- if (x.getIncrExpr() != null) {
- _spaceOpt();
- accept(x.getIncrExpr());
- }
-
- _rparen();
- _nestedPush(x.getBody(), false);
- accept(x.getBody());
- _nestedPop(x.getBody());
- return false;
- }
-
- @Override
- public boolean visit(JsForIn x, JsContext ctx) {
- _for();
- _spaceOpt();
- _lparen();
-
- if (x.getIterVarName() != null) {
- _var();
- _space();
- _nameDef(x.getIterVarName());
-
- if (x.getIterExpr() != null) {
- _spaceOpt();
- _assignment();
- _spaceOpt();
- accept(x.getIterExpr());
- }
- } else {
- // Just a name ref.
- //
- accept(x.getIterExpr());
- }
-
- _space();
- _in();
- _space();
- accept(x.getObjExpr());
-
- _rparen();
- _nestedPush(x.getBody(), false);
- accept(x.getBody());
- _nestedPop(x.getBody());
- return false;
- }
-
- // function foo(a, b) {
- // stmts...
- // }
- //
- @Override
- public boolean visit(JsFunction x, JsContext ctx) {
- _function();
-
- // Functions can be anonymous.
- //
- if (x.getName() != null) {
- _space();
- _nameOf(x);
- }
-
- _lparen();
- boolean sep = false;
- for (Object element : x.getParameters()) {
- JsParameter param = (JsParameter) element;
- sep = _sepCommaOptSpace(sep);
- accept(param);
- }
- _rparen();
-
- accept(x.getBody());
- needSemi = true;
- return false;
- }
-
- @Override
- public boolean visit(JsIf x, JsContext ctx) {
- _if();
- _spaceOpt();
- _lparen();
- accept(x.getIfExpr());
- _rparen();
- JsStatement thenStmt = x.getThenStmt();
- _nestedPush(thenStmt, false);
- accept(thenStmt);
- _nestedPop(thenStmt);
- JsStatement elseStmt = x.getElseStmt();
- if (elseStmt != null) {
- if (needSemi) {
- _semi();
- _newlineOpt();
- } else {
- _spaceOpt();
- needSemi = true;
- }
- _else();
- boolean elseIf = elseStmt instanceof JsIf;
- if (!elseIf) {
- _nestedPush(elseStmt, true);
- } else {
- _space();
- }
- accept(elseStmt);
- if (!elseIf) {
- _nestedPop(elseStmt);
- }
- }
- return false;
- }
-
- @Override
- public boolean visit(JsInvocation x, JsContext ctx) {
- JsExpression qualifier = x.getQualifier();
- _parenPush(x, qualifier, false);
- accept(qualifier);
- _parenPop(x, qualifier, false);
-
- _lparen();
- boolean sep = false;
- for (Object element : x.getArguments()) {
- JsExpression arg = (JsExpression) element;
- sep = _sepCommaOptSpace(sep);
- _parenPushIfCommaExpr(arg);
- accept(arg);
- _parenPopIfCommaExpr(arg);
- }
- _rparen();
- return false;
- }
-
- @Override
- public boolean visit(JsLabel x, JsContext ctx) {
- _nameOf(x);
- _colon();
- _spaceOpt();
- accept(x.getStmt());
- return false;
- }
-
- @Override
- public boolean visit(JsNameRef x, JsContext ctx) {
- JsExpression q = x.getQualifier();
- if (q != null) {
- _parenPush(x, q, false);
- if (q instanceof JsNumberLiteral) {
- /**
- * Fix for Issue #3796. "42.foo" is not allowed, but "(42).foo" is.
- */
- _lparen();
- }
- accept(q);
- if (q instanceof JsNumberLiteral) {
- _rparen();
- }
- _parenPop(x, q, false);
- _dot();
- }
- _nameRef(x);
- return false;
- }
-
- @Override
- public boolean visit(JsNew x, JsContext ctx) {
- _new();
- _space();
-
- JsExpression ctorExpr = x.getConstructorExpression();
- boolean needsParens = JsConstructExpressionVisitor.exec(ctorExpr);
- if (needsParens) {
- _lparen();
- }
- accept(ctorExpr);
- if (needsParens) {
- _rparen();
- }
-
- /*
- * If a constructor call has no arguments, it may simply be replaced with
- * "new Constructor" with no parentheses.
- */
- List<JsExpression> args = x.getArguments();
- if (args.size() > 0) {
- _lparen();
- boolean sep = false;
- for (JsExpression arg : args) {
- sep = _sepCommaOptSpace(sep);
- _parenPushIfCommaExpr(arg);
- accept(arg);
- _parenPopIfCommaExpr(arg);
- }
- _rparen();
- }
-
- return false;
- }
-
- @Override
- public boolean visit(JsNullLiteral x, JsContext ctx) {
- _null();
- return false;
- }
-
- @Override
- public boolean visit(JsNumberLiteral x, JsContext ctx) {
- double dvalue = x.getValue();
- long lvalue = (long) dvalue;
- if (lvalue == dvalue) {
- p.print(Long.toString(lvalue));
- } else {
- p.print(Double.toString(dvalue));
- }
- return false;
- }
-
- @Override
- public boolean visit(JsObjectLiteral x, JsContext ctx) {
- _lbrace();
- boolean sep = false;
- for (Object element : x.getPropertyInitializers()) {
- sep = _sepCommaOptSpace(sep);
- JsPropertyInitializer propInit = (JsPropertyInitializer) element;
- printLabel : {
- JsExpression labelExpr = propInit.getLabelExpr();
- // labels can be either string, integral, or decimal literals
- if (labelExpr instanceof JsStringLiteral) {
- String propName = ((JsStringLiteral) labelExpr).getValue();
- if (VALID_NAME_PATTERN.matcher(propName).matches()
- && !JsReservedIdentifiers.isKeyword(propName)) {
- p.print(propName);
- break printLabel;
- }
- }
- accept(labelExpr);
- }
- _colon();
- JsExpression valueExpr = propInit.getValueExpr();
- _parenPushIfCommaExpr(valueExpr);
- accept(valueExpr);
- _parenPopIfCommaExpr(valueExpr);
- }
- _rbrace();
- return false;
- }
-
- @Override
- public boolean visit(JsParameter x, JsContext ctx) {
- _nameOf(x);
- return false;
- }
-
- @Override
- public boolean visit(JsPostfixOperation x, JsContext ctx) {
- JsUnaryOperator op = x.getOperator();
- JsExpression arg = x.getArg();
- // unary operators always associate correctly (I think)
- _parenPush(x, arg, false);
- accept(arg);
- _parenPop(x, arg, false);
- p.print(op.getSymbol());
- return false;
- }
-
- @Override
- public boolean visit(JsPrefixOperation x, JsContext ctx) {
- JsUnaryOperator op = x.getOperator();
- p.print(op.getSymbol());
- JsExpression arg = x.getArg();
- if (_spaceCalc(op, arg)) {
- _space();
- }
- // unary operators always associate correctly (I think)
- _parenPush(x, arg, false);
- accept(arg);
- _parenPop(x, arg, false);
- return false;
- }
-
- @Override
- public boolean visit(JsProgram x, JsContext ctx) {
- p.print("<JsProgram>");
- return false;
- }
-
- @Override
- public boolean visit(JsProgramFragment x, JsContext ctx) {
- p.print("<JsProgramFragment>");
- return false;
- }
-
- @Override
- public boolean visit(JsPropertyInitializer x, JsContext ctx) {
- // Since there are separators, we actually print the property init
- // in visit(JsObjectLiteral).
- //
- return false;
- }
-
- @Override
- public boolean visit(JsRegExp x, JsContext ctx) {
- _slash();
- p.print(x.getPattern());
- _slash();
- String flags = x.getFlags();
- if (flags != null) {
- p.print(flags);
- }
- return false;
- }
-
- @Override
- public boolean visit(JsReturn x, JsContext ctx) {
- _return();
- JsExpression expr = x.getExpr();
- if (expr != null) {
- _space();
- accept(expr);
- }
- return false;
- }
-
- @Override
- public boolean visit(JsStringLiteral x, JsContext ctx) {
- printStringLiteral(x.getValue());
- return false;
- }
-
- @Override
- public boolean visit(JsSwitch x, JsContext ctx) {
- _switch();
- _spaceOpt();
- _lparen();
- accept(x.getExpr());
- _rparen();
- _spaceOpt();
- _blockOpen();
- acceptList(x.getCases());
- _blockClose();
- return false;
- }
-
- @Override
- public boolean visit(JsThisRef x, JsContext ctx) {
- _this();
- return false;
- }
-
- @Override
- public boolean visit(JsThrow x, JsContext ctx) {
- _throw();
- _space();
- accept(x.getExpr());
- return false;
- }
-
- @Override
- public boolean visit(JsTry x, JsContext ctx) {
- _try();
- _spaceOpt();
- accept(x.getTryBlock());
-
- acceptList(x.getCatches());
-
- JsBlock finallyBlock = x.getFinallyBlock();
- if (finallyBlock != null) {
- _spaceOpt();
- _finally();
- _spaceOpt();
- accept(finallyBlock);
- }
-
- return false;
- }
-
- @Override
- public boolean visit(JsVar x, JsContext ctx) {
- _nameOf(x);
- JsExpression initExpr = x.getInitExpr();
- if (initExpr != null) {
- _spaceOpt();
- _assignment();
- _spaceOpt();
- _parenPushIfCommaExpr(initExpr);
- accept(initExpr);
- _parenPopIfCommaExpr(initExpr);
- }
- return false;
- }
-
- @Override
- public boolean visit(JsVars x, JsContext ctx) {
- _var();
- _space();
- boolean sep = false;
- for (JsVar var : x) {
- sep = _sepCommaOptSpace(sep);
- accept(var);
- }
- return false;
- }
-
- @Override
- public boolean visit(JsWhile x, JsContext ctx) {
- _while();
- _spaceOpt();
- _lparen();
- accept(x.getCondition());
- _rparen();
- _nestedPush(x.getBody(), false);
- accept(x.getBody());
- _nestedPop(x.getBody());
- return false;
- }
-
- // CHECKSTYLE_NAMING_OFF
- protected void _newline() {
- p.newline();
- }
-
- protected void _newlineOpt() {
- p.newlineOpt();
- }
-
- protected void printJsBlock(JsBlock x, boolean truncate, boolean finalNewline) {
- boolean needBraces = !x.isGlobalBlock();
-
- if (needBraces) {
- // Open braces.
- //
- _blockOpen();
- }
-
- int count = 0;
- for (Iterator<JsStatement> iter = x.getStatements().iterator(); iter.hasNext(); ++count) {
- boolean isGlobal = x.isGlobalBlock() || globalBlocks.contains(x);
-
- if (truncate && count > JSBLOCK_LINES_TO_PRINT) {
- p.print("[...]");
- _newlineOpt();
- break;
- }
- JsStatement stmt = iter.next();
- needSemi = true;
- boolean shouldRecordPositions = isGlobal && !(stmt instanceof JsBlock);
- boolean stmtIsGlobalBlock = false;
- if (isGlobal) {
- if (stmt instanceof JsBlock) {
- // A block inside a global block is still considered global
- stmtIsGlobalBlock = true;
- globalBlocks.add((JsBlock) stmt);
- }
- }
- if (shouldRecordPositions) {
- statementStarts.add(p.getPosition());
- }
- accept(stmt);
- if (stmtIsGlobalBlock) {
- globalBlocks.remove(stmt);
- }
- if (needSemi) {
- /*
- * Special treatment of function decls: If they are the only item in a
- * statement (i.e. not part of an assignment operation), just give them
- * a newline instead of a semi.
- */
- boolean functionStmt =
- stmt instanceof JsExprStmt && ((JsExprStmt) stmt).getExpression() instanceof JsFunction;
- /*
- * Special treatment of the last statement in a block: only a few
- * statements at the end of a block require semicolons.
- */
- boolean lastStatement = !iter.hasNext() && needBraces && !JsRequiresSemiVisitor.exec(stmt);
- if (functionStmt) {
- if (lastStatement) {
- _newlineOpt();
- } else {
- _newline();
- }
- } else {
- if (lastStatement) {
- _semiOpt();
- } else {
- _semi();
- }
- _newlineOpt();
- }
- }
- if (shouldRecordPositions) {
- assert (statementStarts.size() == statementEnds.size() + 1);
- statementEnds.add(p.getPosition());
- }
- }
-
- if (needBraces) {
- // _blockClose() modified
- p.indentOut();
- p.print('}');
- if (finalNewline) {
- _newlineOpt();
- }
- }
- needSemi = false;
- }
-
- private void _assignment() {
- p.print('=');
- }
-
- private void _blockClose() {
- p.indentOut();
- p.print('}');
- _newlineOpt();
- }
-
- private void _blockOpen() {
- p.print('{');
- p.indentIn();
- _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() {
- 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 _finally() {
- p.print(CHARS_FINALLY);
- }
-
- private void _for() {
- p.print(CHARS_FOR);
- }
-
- private void _function() {
- p.print(CHARS_FUNCTION);
- }
-
- private void _if() {
- p.print(CHARS_IF);
- }
-
- private void _in() {
- p.print(CHARS_IN);
- }
-
- private void _lbrace() {
- p.print('{');
- }
-
- private void _lparen() {
- p.print('(');
- }
-
- private void _lsquare() {
- p.print('[');
- }
-
- private void _nameDef(JsName name) {
- p.print(name.getShortIdent());
- }
-
- private void _nameOf(HasName hasName) {
- _nameDef(hasName.getName());
- }
-
- private void _nameRef(JsNameRef nameRef) {
- p.print(nameRef.getShortIdent());
- }
-
- private boolean _nestedPop(JsStatement statement) {
- boolean pop = !(statement instanceof JsBlock);
- if (pop) {
- p.indentOut();
- }
- return pop;
- }
-
- private boolean _nestedPush(JsStatement statement, boolean needSpace) {
- boolean push = !(statement instanceof JsBlock);
- if (push) {
- if (needSpace) {
- _space();
- }
- p.indentIn();
- _newlineOpt();
- } else {
- _spaceOpt();
- }
- return push;
- }
-
- private void _new() {
- p.print(CHARS_NEW);
- }
-
- private void _null() {
- p.print(CHARS_NULL);
- }
-
- private boolean _parenCalc(JsExpression parent, JsExpression child, boolean wrongAssoc) {
- int parentPrec = JsPrecedenceVisitor.exec(parent);
- int childPrec = JsPrecedenceVisitor.exec(child);
- return (parentPrec > childPrec || (parentPrec == childPrec && wrongAssoc));
- }
-
- private boolean _parenPop(JsExpression parent, JsExpression child, boolean wrongAssoc) {
- boolean doPop = _parenCalc(parent, child, wrongAssoc);
- if (doPop) {
- _rparen();
- }
- return doPop;
- }
-
- private boolean _parenPopIfCommaExpr(JsExpression x) {
- boolean doPop =
- x instanceof JsBinaryOperation
- && ((JsBinaryOperation) x).getOperator() == JsBinaryOperator.COMMA;
- if (doPop) {
- _rparen();
- }
- return doPop;
- }
-
- private boolean _parenPopOrSpace(JsExpression parent, JsExpression child, boolean wrongAssoc) {
- boolean doPop = _parenCalc(parent, child, wrongAssoc);
- if (doPop) {
- _rparen();
- } else {
- _space();
- }
- return doPop;
- }
-
- private boolean _parenPush(JsExpression parent, JsExpression child, boolean wrongAssoc) {
- boolean doPush = _parenCalc(parent, child, wrongAssoc);
- if (doPush) {
- _lparen();
- }
- return doPush;
- }
-
- private boolean _parenPushIfCommaExpr(JsExpression x) {
- boolean doPush =
- x instanceof JsBinaryOperation
- && ((JsBinaryOperation) x).getOperator() == JsBinaryOperator.COMMA;
- if (doPush) {
- _lparen();
- }
- return doPush;
- }
-
- private boolean _parenPushOrSpace(JsExpression parent, JsExpression child, boolean wrongAssoc) {
- boolean doPush = _parenCalc(parent, child, wrongAssoc);
- if (doPush) {
- _lparen();
- } else {
- _space();
- }
- return doPush;
- }
-
- private void _questionMark() {
- p.print('?');
- }
-
- private void _rbrace() {
- p.print('}');
- }
-
- private void _return() {
- p.print(CHARS_RETURN);
- }
-
- private void _rparen() {
- p.print(')');
- }
-
- private void _rsquare() {
- p.print(']');
- }
-
- private void _semi() {
- p.print(';');
- }
-
- private void _semiOpt() {
- p.printOpt(';');
- }
-
- private boolean _sepCommaOptSpace(boolean sep) {
- if (sep) {
- p.print(',');
- _spaceOpt();
- }
- return true;
- }
-
- private void _slash() {
- p.print('/');
- }
-
- private void _space() {
- p.print(' ');
- }
-
- /**
- * Decide whether, if <code>op</code> is printed followed by <code>arg</code>,
- * there needs to be a space between the operator and expression.
- *
- * @return <code>true</code> if a space needs to be printed
- */
- private boolean _spaceCalc(JsOperator op, JsExpression arg) {
- if (op.isKeyword()) {
- return true;
- }
- if (arg instanceof JsBinaryOperation) {
- JsBinaryOperation binary = (JsBinaryOperation) arg;
- /*
- * If the binary operation has a higher precedence than op, then it won't
- * be parenthesized, so check the first argument of the binary operation.
- */
- if (binary.getOperator().getPrecedence() > op.getPrecedence()) {
- return _spaceCalc(op, binary.getArg1());
- }
- return false;
- }
- if (arg instanceof JsPrefixOperation) {
- JsOperator op2 = ((JsPrefixOperation) arg).getOperator();
- return (op == JsBinaryOperator.SUB || op == JsUnaryOperator.NEG)
- && (op2 == JsUnaryOperator.DEC || op2 == JsUnaryOperator.NEG)
- || (op == JsBinaryOperator.ADD && op2 == JsUnaryOperator.INC);
- }
- if (arg instanceof JsNumberLiteral) {
- JsNumberLiteral literal = (JsNumberLiteral) arg;
- return (op == JsBinaryOperator.SUB || op == JsUnaryOperator.NEG) && (literal.getValue() < 0);
- }
- return false;
- }
-
- private void _spaceOpt() {
- p.printOpt(' ');
- }
-
- private void _switch() {
- p.print(CHARS_SWITCH);
- }
-
- private void _this() {
- p.print(CHARS_THIS);
- }
-
- private void _throw() {
- p.print(CHARS_THROW);
- }
-
- private void _true() {
- p.print(CHARS_TRUE);
- }
-
- private void _try() {
- p.print(CHARS_TRY);
- }
-
- private void _var() {
- p.print(CHARS_VAR);
- }
-
- private void _while() {
- p.print(CHARS_WHILE);
- }
-
- // CHECKSTYLE_NAMING_ON
-
- private void indent() {
- p.indentIn();
- }
-
- private void outdent() {
- p.indentOut();
- }
-
- private void printStringLiteral(String value) {
- String resultString = javaScriptString(value);
- p.print(resultString);
- }
-}

Powered by Google App Engine
This is Rietveld 408576698