Run dartfmt on js_ast

BUG=
R=sra@google.com

Review-Url: https://codereview.chromium.org/2748103010 .
This commit is contained in:
Jacob Richman 2017-03-15 21:22:40 -07:00
parent 33717e010a
commit 11950984e4
7 changed files with 498 additions and 428 deletions

View file

@ -7,7 +7,6 @@
part of js_ast;
/**
* Global template manager. We should aim to have a fixed number of
* templates. This implies that we do not use js('xxx') to parse text that is
@ -18,7 +17,6 @@ part of js_ast;
*/
TemplateManager templateManager = new TemplateManager();
/**
[js] is a singleton instace of JsBuilder. JsBuilder is a set of conveniences
@ -187,7 +185,6 @@ What is not implemented:
*/
const JsBuilder js = const JsBuilder();
class JsBuilder {
const JsBuilder();
@ -271,8 +268,8 @@ class JsBuilder {
Template uncachedExpressionTemplate(String source) {
MiniJsParser parser = new MiniJsParser(source);
Expression expression = parser.expression();
return new Template(
source, expression, isExpression: true, forceCopy: false);
return new Template(source, expression,
isExpression: true, forceCopy: false);
}
/**
@ -281,8 +278,8 @@ class JsBuilder {
Template uncachedStatementTemplate(String source) {
MiniJsParser parser = new MiniJsParser(source);
Statement statement = parser.statement();
return new Template(
source, statement, isExpression: false, forceCopy: false);
return new Template(source, statement,
isExpression: false, forceCopy: false);
}
/**
@ -306,13 +303,20 @@ class JsBuilder {
// string literal anyway.
escaped = escaped.replaceAllMapped(new RegExp('\n|"|\b|\t|\v|\r'), (match) {
switch (match.group(0)) {
case "\n" : return r"\n";
case "\"" : return r'\"';
case "\b" : return r"\b";
case "\t" : return r"\t";
case "\f" : return r"\f";
case "\r" : return r"\r";
case "\v" : return r"\v";
case "\n":
return r"\n";
case "\"":
return r'\"';
case "\b":
return r"\b";
case "\t":
return r"\t";
case "\f":
return r"\f";
case "\r":
return r"\r";
case "\v":
return r"\v";
}
});
LiteralString result = string(escaped);
@ -340,12 +344,16 @@ class JsBuilder {
++singleQuotes;
} else if (rune == charCodes.$DQ) {
++doubleQuotes;
} else if (rune == charCodes.$LF || rune == charCodes.$CR ||
rune == charCodes.$LS || rune == charCodes.$PS) {
} else if (rune == charCodes.$LF ||
rune == charCodes.$CR ||
rune == charCodes.$LS ||
rune == charCodes.$PS) {
// Line terminators.
++otherEscapes;
} else if (rune == charCodes.$BS || rune == charCodes.$TAB ||
rune == charCodes.$VTAB || rune == charCodes.$FF) {
} else if (rune == charCodes.$BS ||
rune == charCodes.$TAB ||
rune == charCodes.$VTAB ||
rune == charCodes.$FF) {
++otherEscapes;
} else if (_isUnpairedSurrogate(rune)) {
++unpairedSurrogates;
@ -408,15 +416,24 @@ class JsBuilder {
static String _irregularEscape(int code, bool useSingleQuotes) {
switch (code) {
case charCodes.$SQ: return useSingleQuotes ? r"\'" : r"'";
case charCodes.$DQ: return useSingleQuotes ? r'"' : r'\"';
case charCodes.$BACKSLASH: return r'\\';
case charCodes.$BS: return r'\b';
case charCodes.$TAB: return r'\t';
case charCodes.$LF: return r'\n';
case charCodes.$VTAB: return r'\v';
case charCodes.$FF: return r'\f';
case charCodes.$CR: return r'\r';
case charCodes.$SQ:
return useSingleQuotes ? r"\'" : r"'";
case charCodes.$DQ:
return useSingleQuotes ? r'"' : r'\"';
case charCodes.$BACKSLASH:
return r'\\';
case charCodes.$BS:
return r'\b';
case charCodes.$TAB:
return r'\t';
case charCodes.$LF:
return r'\n';
case charCodes.$VTAB:
return r'\v';
case charCodes.$FF:
return r'\f';
case charCodes.$CR:
return r'\r';
}
return null;
}
@ -472,9 +489,8 @@ class JsBuilder {
Comment comment(String text) => new Comment(text);
Call propertyCall(Expression receiver,
Expression fieldName,
List<Expression> arguments) {
Call propertyCall(
Expression receiver, Expression fieldName, List<Expression> arguments) {
return new Call(new PropertyAccess(receiver, fieldName), arguments);
}
@ -491,10 +507,12 @@ LiteralString string(String value) => js.string(value);
LiteralString quoteName(Name name, {allowNull: false}) {
return js.quoteName(name, allowNull: allowNull);
}
LiteralString stringPart(String value) => js.stringPart(value);
Iterable<Literal> joinLiterals(Iterable<Literal> list, Literal separator) {
return js.joinLiterals(list, separator);
}
StringConcatenation concatenateStrings(Iterable<Literal> parts,
{addQuotes: false}) {
return js.concatenateStrings(parts, addQuotes: addQuotes);
@ -503,11 +521,11 @@ StringConcatenation concatenateStrings(Iterable<Literal> parts,
LiteralNumber number(num value) => js.number(value);
ArrayInitializer numArray(Iterable<int> list) => js.numArray(list);
ArrayInitializer stringArray(Iterable<String> list) => js.stringArray(list);
Call propertyCall(Expression receiver,
Expression fieldName,
List<Expression> arguments) {
Call propertyCall(
Expression receiver, Expression fieldName, List<Expression> arguments) {
return js.propertyCall(receiver, fieldName, arguments);
}
ObjectInitializer objectLiteral(Map<String, Expression> map) {
return js.objectLiteral(map);
}
@ -610,26 +628,46 @@ class MiniJsParser {
static String categoryToString(int cat) {
switch (cat) {
case NONE: return "NONE";
case ALPHA: return "ALPHA";
case NUMERIC: return "NUMERIC";
case SYMBOL: return "SYMBOL";
case ASSIGNMENT: return "ASSIGNMENT";
case DOT: return "DOT";
case LPAREN: return "LPAREN";
case RPAREN: return "RPAREN";
case LBRACE: return "LBRACE";
case RBRACE: return "RBRACE";
case LSQUARE: return "LSQUARE";
case RSQUARE: return "RSQUARE";
case STRING: return "STRING";
case COMMA: return "COMMA";
case QUERY: return "QUERY";
case COLON: return "COLON";
case SEMICOLON: return "SEMICOLON";
case HASH: return "HASH";
case WHITESPACE: return "WHITESPACE";
case OTHER: return "OTHER";
case NONE:
return "NONE";
case ALPHA:
return "ALPHA";
case NUMERIC:
return "NUMERIC";
case SYMBOL:
return "SYMBOL";
case ASSIGNMENT:
return "ASSIGNMENT";
case DOT:
return "DOT";
case LPAREN:
return "LPAREN";
case RPAREN:
return "RPAREN";
case LBRACE:
return "LBRACE";
case RBRACE:
return "RBRACE";
case LSQUARE:
return "LSQUARE";
case RSQUARE:
return "RSQUARE";
case STRING:
return "STRING";
case COMMA:
return "COMMA";
case QUERY:
return "QUERY";
case COLON:
return "COLON";
case SEMICOLON:
return "SEMICOLON";
case HASH:
return "HASH";
case WHITESPACE:
return "WHITESPACE";
case OTHER:
return "OTHER";
}
return "Unknown: $cat";
}
@ -652,7 +690,8 @@ class MiniJsParser {
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, // abcdefgh
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, // ijklmnop
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, // qrstuvwx
ALPHA, ALPHA, LBRACE, SYMBOL, RBRACE, SYMBOL]; // yz{|}~
ALPHA, ALPHA, LBRACE, SYMBOL, RBRACE, SYMBOL
]; // yz{|}~
// This must be a >= the highest precedence number handled by parseBinary.
static var HIGHEST_PARSE_BINARY_PRECEDENCE = 16;
@ -660,22 +699,54 @@ class MiniJsParser {
// From https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Operator_Precedence
static final BINARY_PRECEDENCE = {
'+=': 17, '-=': 17, '*=': 17, '/=': 17, '%=': 17, '^=': 17, '|=': 17,
'&=': 17, '<<=': 17, '>>=': 17, '>>>=': 17, '=': 17,
'+=': 17,
'-=': 17,
'*=': 17,
'/=': 17,
'%=': 17,
'^=': 17,
'|=': 17,
'&=': 17,
'<<=': 17,
'>>=': 17,
'>>>=': 17,
'=': 17,
'||': 14,
'&&': 13,
'|': 12,
'^': 11,
'&': 10,
'!=': 9, '==': 9, '!==': 9, '===': 9,
'<': 8, '<=': 8, '>=': 8, '>': 8, 'in': 8, 'instanceof': 8,
'<<': 7, '>>': 7, '>>>': 7,
'+': 6, '-': 6,
'*': 5, '/': 5, '%': 5
'!=': 9,
'==': 9,
'!==': 9,
'===': 9,
'<': 8,
'<=': 8,
'>=': 8,
'>': 8,
'in': 8,
'instanceof': 8,
'<<': 7,
'>>': 7,
'>>>': 7,
'+': 6,
'-': 6,
'*': 5,
'/': 5,
'%': 5
};
static final UNARY_OPERATORS =
['++', '--', '+', '-', '~', '!', 'typeof', 'void', 'delete', 'await']
.toSet();
static final UNARY_OPERATORS = [
'++',
'--',
'+',
'-',
'~',
'!',
'typeof',
'void',
'delete',
'await'
].toSet();
static final OPERATORS_THAT_LOOK_LIKE_IDENTIFIERS =
['typeof', 'void', 'delete', 'in', 'instanceof', 'await'].toSet();
@ -697,8 +768,10 @@ class MiniJsParser {
if (currentCode == charCodes.$BACKSLASH) {
if (++position >= src.length) error("Unterminated literal");
int escaped = src.codeUnitAt(position);
if (escaped == charCodes.$x || escaped == charCodes.$X ||
escaped == charCodes.$u || escaped == charCodes.$U ||
if (escaped == charCodes.$x ||
escaped == charCodes.$X ||
escaped == charCodes.$u ||
escaped == charCodes.$U ||
category(escaped) == NUMERIC) {
error('Numeric and hex escapes are not allowed in literals');
}
@ -714,8 +787,7 @@ class MiniJsParser {
if (position >= src.length) break;
int code = src.codeUnitAt(position);
// Skip '//' and '/*' style comments.
if (code == charCodes.$SLASH &&
position + 1 < src.length) {
if (code == charCodes.$SLASH && position + 1 < src.length) {
if (src.codeUnitAt(position + 1) == charCodes.$SLASH) {
int nextPosition = src.indexOf('\n', position);
if (nextPosition == -1) nextPosition = src.length;
@ -777,8 +849,7 @@ class MiniJsParser {
// Special code to disallow !, ~ and / in non-first position in token,
// so that !! and ~~ parse as two tokens and != parses as one, while =/
// parses as a an equals token followed by a regexp literal start.
newCat =
(code == charCodes.$BANG ||
newCat = (code == charCodes.$BANG ||
code == charCodes.$SLASH ||
code == charCodes.$TILDE)
? NONE
@ -984,7 +1055,8 @@ class MiniJsParser {
propertyName = new LiteralString('"$identifier"');
} else if (acceptCategory(STRING)) {
propertyName = new LiteralString(identifier);
} else if (acceptCategory(SYMBOL)) { // e.g. void
} else if (acceptCategory(SYMBOL)) {
// e.g. void
propertyName = new LiteralString('"$identifier"');
} else if (acceptCategory(HASH)) {
var nameOrPosition = parseHash();
@ -1034,9 +1106,9 @@ class MiniJsParser {
expectCategory(COMMA);
}
}
receiver = constructor ?
new New(receiver, arguments) :
new Call(receiver, arguments);
receiver = constructor
? new New(receiver, arguments)
: new Call(receiver, arguments);
constructor = false;
} else if (!constructor && acceptCategory(LSQUARE)) {
Expression inBraces = parseExpression();
@ -1091,7 +1163,8 @@ class MiniJsParser {
Expression parseUnaryHigh() {
String operator = lastToken;
if (lastCategory == SYMBOL && UNARY_OPERATORS.contains(operator) &&
if (lastCategory == SYMBOL &&
UNARY_OPERATORS.contains(operator) &&
(acceptString("++") || acceptString("--") || acceptString('await'))) {
if (operator == "await") return new Await(parsePostfix());
return new Prefix(operator, parsePostfix());
@ -1101,8 +1174,10 @@ class MiniJsParser {
Expression parseUnaryLow() {
String operator = lastToken;
if (lastCategory == SYMBOL && UNARY_OPERATORS.contains(operator) &&
operator != "++" && operator != "--") {
if (lastCategory == SYMBOL &&
UNARY_OPERATORS.contains(operator) &&
operator != "++" &&
operator != "--") {
expectCategory(SYMBOL);
if (operator == "await") return new Await(parsePostfix());
return new Prefix(operator, parseUnaryLow());
@ -1146,7 +1221,6 @@ class MiniJsParser {
return new Conditional(lhs, ifTrue, ifFalse);
}
Expression parseAssignment() {
Expression lhs = parseConditional();
String assignmentOperator = lastToken;
@ -1280,7 +1354,6 @@ class MiniJsParser {
if (lastToken == 'with') {
error('Not implemented in mini parser');
}
}
bool checkForInterpolatedStatement = lastCategory == HASH;
@ -1387,8 +1460,8 @@ class MiniJsParser {
expectCategory(RPAREN);
Statement body = parseStatement();
return new ForIn(
new VariableDeclarationList([
new VariableInitialization(declaration, null)]),
new VariableDeclarationList(
[new VariableInitialization(declaration, null)]),
objectExpression,
body);
}

View file

@ -95,8 +95,7 @@ class BaseVisitor<T> implements NodeVisitor<T> {
T visitJump(Statement node) => visitStatement(node);
T visitBlock(Block node) => visitStatement(node);
T visitExpressionStatement(ExpressionStatement node)
=> visitStatement(node);
T visitExpressionStatement(ExpressionStatement node) => visitStatement(node);
T visitEmptyStatement(EmptyStatement node) => visitStatement(node);
T visitIf(If node) => visitStatement(node);
T visitFor(For node) => visitLoop(node);
@ -109,8 +108,7 @@ class BaseVisitor<T> implements NodeVisitor<T> {
T visitThrow(Throw node) => visitJump(node);
T visitTry(Try node) => visitStatement(node);
T visitSwitch(Switch node) => visitStatement(node);
T visitFunctionDeclaration(FunctionDeclaration node)
=> visitStatement(node);
T visitFunctionDeclaration(FunctionDeclaration node) => visitStatement(node);
T visitLabeledStatement(LabeledStatement node) => visitStatement(node);
T visitLiteralStatement(LiteralStatement node) => visitStatement(node);
@ -122,8 +120,8 @@ class BaseVisitor<T> implements NodeVisitor<T> {
T visitVariableReference(VariableReference node) => visitExpression(node);
T visitLiteralExpression(LiteralExpression node) => visitExpression(node);
T visitVariableDeclarationList(VariableDeclarationList node)
=> visitExpression(node);
T visitVariableDeclarationList(VariableDeclarationList node) =>
visitExpression(node);
T visitAssignment(Assignment node) => visitExpression(node);
T visitVariableInitialization(VariableInitialization node) {
if (node.value != null) {
@ -132,6 +130,7 @@ class BaseVisitor<T> implements NodeVisitor<T> {
return visitExpression(node);
}
}
T visitConditional(Conditional node) => visitExpression(node);
T visitNew(New node) => visitExpression(node);
T visitCall(Call node) => visitExpression(node);
@ -141,8 +140,8 @@ class BaseVisitor<T> implements NodeVisitor<T> {
T visitAccess(PropertyAccess node) => visitExpression(node);
T visitVariableUse(VariableUse node) => visitVariableReference(node);
T visitVariableDeclaration(VariableDeclaration node)
=> visitVariableReference(node);
T visitVariableDeclaration(VariableDeclaration node) =>
visitVariableReference(node);
T visitParameter(Parameter node) => visitVariableDeclaration(node);
T visitThis(This node) => visitParameter(node);
@ -174,16 +173,16 @@ class BaseVisitor<T> implements NodeVisitor<T> {
T visitInterpolatedNode(InterpolatedNode node) => visitNode(node);
T visitInterpolatedExpression(InterpolatedExpression node)
=> visitInterpolatedNode(node);
T visitInterpolatedLiteral(InterpolatedLiteral node)
=> visitInterpolatedNode(node);
T visitInterpolatedParameter(InterpolatedParameter node)
=> visitInterpolatedNode(node);
T visitInterpolatedSelector(InterpolatedSelector node)
=> visitInterpolatedNode(node);
T visitInterpolatedStatement(InterpolatedStatement node)
=> visitInterpolatedNode(node);
T visitInterpolatedExpression(InterpolatedExpression node) =>
visitInterpolatedNode(node);
T visitInterpolatedLiteral(InterpolatedLiteral node) =>
visitInterpolatedNode(node);
T visitInterpolatedParameter(InterpolatedParameter node) =>
visitInterpolatedNode(node);
T visitInterpolatedSelector(InterpolatedSelector node) =>
visitInterpolatedNode(node);
T visitInterpolatedStatement(InterpolatedStatement node) =>
visitInterpolatedNode(node);
T visitInterpolatedDeclaration(InterpolatedDeclaration node) {
return visitInterpolatedNode(node);
}
@ -244,6 +243,7 @@ class Program extends Node {
void visitChildren(NodeVisitor visitor) {
for (Statement statement in body) statement.accept(visitor);
}
Program _clone() => new Program(body);
}
@ -260,6 +260,7 @@ class Block extends Statement {
void visitChildren(NodeVisitor visitor) {
for (Statement statement in statements) statement.accept(visitor);
}
Block _clone() => new Block(statements);
}
@ -270,7 +271,10 @@ class ExpressionStatement extends Statement {
}
accept(NodeVisitor visitor) => visitor.visitExpressionStatement(this);
void visitChildren(NodeVisitor visitor) { expression.accept(visitor); }
void visitChildren(NodeVisitor visitor) {
expression.accept(visitor);
}
ExpressionStatement _clone() => new ExpressionStatement(expression);
}
@ -577,9 +581,7 @@ abstract class Expression extends Node {
Statement toStatement() => new ExpressionStatement(this);
}
abstract class Declaration implements VariableReference {
}
abstract class Declaration implements VariableReference {}
/// An implementation of [Name] represents a potentially late bound name in
/// the generated ast.
@ -663,8 +665,7 @@ class Assignment extends Expression {
final String op; // Null, if the assignment is not compound.
final Expression value; // May be null, for [VariableInitialization]s.
Assignment(leftHandSide, value)
: this.compound(leftHandSide, null, value);
Assignment(leftHandSide, value) : this.compound(leftHandSide, null, value);
// If `this.op == null` this will be a non-compound assignment.
Assignment.compound(this.leftHandSide, this.op, this.value);
@ -679,8 +680,7 @@ class Assignment extends Expression {
if (value != null) value.accept(visitor);
}
Assignment _clone() =>
new Assignment.compound(leftHandSide, op, value);
Assignment _clone() => new Assignment.compound(leftHandSide, op, value);
}
class VariableInitialization extends Assignment {
@ -840,7 +840,6 @@ class Postfix extends Expression {
argument.accept(visitor);
}
int get precedenceLevel => UNARY;
}
@ -902,6 +901,7 @@ class NamedFunction extends Expression {
name.accept(visitor);
function.accept(visitor);
}
NamedFunction _clone() => new NamedFunction(name, function);
int get precedenceLevel => LEFT_HAND_SIDE;
@ -1170,8 +1170,7 @@ class InterpolatedExpression extends Expression with InterpolatedNode {
accept(NodeVisitor visitor) => visitor.visitInterpolatedExpression(this);
void visitChildren(NodeVisitor visitor) {}
InterpolatedExpression _clone() =>
new InterpolatedExpression(nameOrPosition);
InterpolatedExpression _clone() => new InterpolatedExpression(nameOrPosition);
int get precedenceLevel => PRIMARY;
}
@ -1186,11 +1185,15 @@ class InterpolatedLiteral extends Literal with InterpolatedNode {
InterpolatedLiteral _clone() => new InterpolatedLiteral(nameOrPosition);
}
class InterpolatedParameter extends Expression with InterpolatedNode
class InterpolatedParameter extends Expression
with InterpolatedNode
implements Parameter {
final nameOrPosition;
String get name { throw "InterpolatedParameter.name must not be invoked"; }
String get name {
throw "InterpolatedParameter.name must not be invoked";
}
bool get allowRename => false;
InterpolatedParameter(this.nameOrPosition);

View file

@ -4,7 +4,6 @@
part of js_ast;
typedef String Renamer(Name);
class JavaScriptPrintingOptions {
@ -22,12 +21,13 @@ class JavaScriptPrintingOptions {
static String identityRenamer(Name name) => name.name;
}
/// An environment in which JavaScript printing is done. Provides emitting of
/// text and pre- and post-visit callbacks.
abstract class JavaScriptPrintingContext {
/// Signals an error. This should happen only for serious internal errors.
void error(String message) { throw message; }
void error(String message) {
throw message;
}
/// Adds [string] to the output.
void emit(String string);
@ -46,10 +46,8 @@ abstract class JavaScriptPrintingContext {
/// [Fun] nodes and is `null` otherwise.
///
/// [enterNode] is called in post-traversal order.
void exitNode(Node node,
int startPosition,
int endPosition,
int closingPosition) {}
void exitNode(
Node node, int startPosition, int endPosition, int closingPosition) {}
}
/// A simple implementation of [JavaScriptPrintingContext] suitable for tests.
@ -63,7 +61,6 @@ class SimpleJavaScriptPrintingContext extends JavaScriptPrintingContext {
String getText() => buffer.toString();
}
class Printer implements NodeVisitor {
final JavaScriptPrintingOptions options;
final JavaScriptPrintingContext context;
@ -85,22 +82,21 @@ class Printer implements NodeVisitor {
static final identifierCharacterRegExp = new RegExp(r'^[a-zA-Z_0-9$]');
static final expressionContinuationRegExp = new RegExp(r'^[-+([]');
Printer(JavaScriptPrintingOptions options,
JavaScriptPrintingContext context)
Printer(JavaScriptPrintingOptions options, JavaScriptPrintingContext context)
: options = options,
context = context,
shouldCompressOutput = options.shouldCompressOutput,
danglingElseVisitor = new DanglingElseVisitor(context),
localNamer = determineRenamer(options.shouldCompressOutput,
options.minifyLocalVariables);
localNamer = determineRenamer(
options.shouldCompressOutput, options.minifyLocalVariables);
static LocalNamer determineRenamer(bool shouldCompressOutput,
bool allowVariableMinification) {
static LocalNamer determineRenamer(
bool shouldCompressOutput, bool allowVariableMinification) {
return (shouldCompressOutput && allowVariableMinification)
? new MinifyRenamer() : new IdentityNamer();
? new MinifyRenamer()
: new IdentityNamer();
}
// The current indentation string.
String get indentation {
// Lazily add new indentation strings as required.
@ -244,8 +240,7 @@ class Printer implements NodeVisitor {
spaceOut();
}
visitNestedExpression(nodes[i], hasRequiredType,
newInForInit: newInForInit,
newAtStatementBegin: newAtStatementBegin);
newInForInit: newInForInit, newAtStatementBegin: newAtStatementBegin);
}
}
@ -628,7 +623,6 @@ class Printer implements NodeVisitor {
blockOut(fun.body, shouldIndent: false, needsNewline: false);
localNamer.leaveScope();
return closingPosition;
}
@override
@ -653,7 +647,8 @@ class Printer implements NodeVisitor {
(newInForInit && node is Binary && node.op == "in") ||
// (function() { ... })().
// ({a: 2, b: 3}.toString()).
(newAtStatementBegin && (node is NamedFunction ||
(newAtStatementBegin &&
(node is NamedFunction ||
node is Fun ||
node is ObjectInitializer));
if (needsParentheses) {
@ -679,8 +674,7 @@ class Printer implements NodeVisitor {
@override
visitAssignment(Assignment assignment) {
visitNestedExpression(assignment.leftHandSide, CALL,
newInForInit: inForInit,
newAtStatementBegin: atStatementBegin);
newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
if (assignment.value != null) {
spaceOut();
String op = assignment.op;
@ -688,8 +682,7 @@ class Printer implements NodeVisitor {
out("=");
spaceOut();
visitNestedExpression(assignment.value, ASSIGNMENT,
newInForInit: inForInit,
newAtStatementBegin: false);
newInForInit: inForInit, newAtStatementBegin: false);
}
}
@ -701,8 +694,7 @@ class Printer implements NodeVisitor {
@override
visitConditional(Conditional cond) {
visitNestedExpression(cond.condition, LOGICAL_OR,
newInForInit: inForInit,
newAtStatementBegin: atStatementBegin);
newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
spaceOut();
out("?");
spaceOut();
@ -730,8 +722,7 @@ class Printer implements NodeVisitor {
@override
visitCall(Call call) {
visitNestedExpression(call.target, CALL,
newInForInit: inForInit,
newAtStatementBegin: atStatementBegin);
newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
out("(");
visitCommaSeparated(call.arguments, ASSIGNMENT,
newInForInit: false, newAtStatementBegin: false);
@ -822,8 +813,7 @@ class Printer implements NodeVisitor {
}
visitNestedExpression(left, leftPrecedenceRequirement,
newInForInit: inForInit,
newAtStatementBegin: atStatementBegin);
newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
if (op == "in" || op == "instanceof") {
// There are cases where the space is not required but without further
@ -837,8 +827,7 @@ class Printer implements NodeVisitor {
spaceOut();
}
visitNestedExpression(right, rightPrecedenceRequirement,
newInForInit: inForInit,
newAtStatementBegin: false);
newInForInit: inForInit, newAtStatementBegin: false);
}
@override
@ -873,8 +862,7 @@ class Printer implements NodeVisitor {
@override
void visitPostfix(Postfix postfix) {
visitNestedExpression(postfix.argument, CALL,
newInForInit: inForInit,
newAtStatementBegin: atStatementBegin);
newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
out(postfix.op);
}
@ -927,8 +915,7 @@ class Printer implements NodeVisitor {
@override
void visitAccess(PropertyAccess access) {
visitNestedExpression(access.receiver, CALL,
newInForInit: inForInit,
newAtStatementBegin: atStatementBegin);
newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
Node selector = access.selector;
if (selector is LiteralString) {
LiteralString selectorString = selector;
@ -1070,8 +1057,7 @@ class Printer implements NodeVisitor {
// property. Ideally, we would use a proper pretty-printer to make the
// decision based on layout.
bool exitOneLinerMode(Expression value) {
return
value is Fun ||
return value is Fun ||
value is ArrayInitializer && value.elements.any((e) => e is Fun);
}
@ -1205,12 +1191,13 @@ class Printer implements NodeVisitor {
}
}
class OrderedSet<T> {
final Set<T> set;
final List<T> list;
OrderedSet() : set = new Set<T>(), list = <T>[];
OrderedSet()
: set = new Set<T>(),
list = <T>[];
void add(T x) {
if (set.add(x)) {
@ -1235,7 +1222,8 @@ class VarCollector extends BaseVisitor {
static final String disableVariableMinificationPattern = "::norenaming::";
static final String enableVariableMinificationPattern = "::dorenaming::";
VarCollector() : nested = false,
VarCollector()
: nested = false,
vars = new OrderedSet<String>(),
params = new OrderedSet<String>();
@ -1284,7 +1272,6 @@ class VarCollector extends BaseVisitor {
}
}
/**
* Returns true, if the given node must be wrapped into braces when used
* as then-statement in an [If] that has an else branch.
@ -1308,6 +1295,7 @@ class DanglingElseVisitor extends BaseVisitor<bool> {
if (!node.hasElse) return true;
return node.otherwise.accept(this);
}
bool visitFor(For node) => node.body.accept(this);
bool visitForIn(ForIn node) => node.body.accept(this);
bool visitWhile(While node) => node.body.accept(this);
@ -1323,19 +1311,18 @@ class DanglingElseVisitor extends BaseVisitor<bool> {
return node.catchPart.accept(this);
}
}
bool visitCatch(Catch node) => node.body.accept(this);
bool visitSwitch(Switch node) => false;
bool visitCase(Case node) => false;
bool visitDefault(Default node) => false;
bool visitFunctionDeclaration(FunctionDeclaration node) => false;
bool visitLabeledStatement(LabeledStatement node)
=> node.body.accept(this);
bool visitLabeledStatement(LabeledStatement node) => node.body.accept(this);
bool visitLiteralStatement(LiteralStatement node) => true;
bool visitExpression(Expression node) => false;
}
abstract class LocalNamer {
String getName(String oldName);
String declareVariable(String oldName);
@ -1344,7 +1331,6 @@ abstract class LocalNamer {
void leaveScope();
}
class IdentityNamer implements LocalNamer {
String getName(String oldName) => oldName;
String declareVariable(String oldName) => oldName;
@ -1353,7 +1339,6 @@ class IdentityNamer implements LocalNamer {
void leaveScope() {}
}
class MinifyRenamer implements LocalNamer {
final List<Map<String, String>> maps = [];
final List<int> parameterNumberStack = [];
@ -1392,9 +1377,9 @@ class MinifyRenamer implements LocalNamer {
static const DIGITS = 10;
static int nthLetter(int n) {
return (n < LOWER_CASE_LETTERS) ?
charCodes.$a + n :
charCodes.$A + n - LOWER_CASE_LETTERS;
return (n < LOWER_CASE_LETTERS)
? charCodes.$a + n
: charCodes.$A + n - LOWER_CASE_LETTERS;
}
// Parameters go from a to z and variables go from z to a. This makes each

View file

@ -10,7 +10,6 @@ class TemplateManager {
TemplateManager();
Template lookupExpressionTemplate(String source) {
return expressionTemplates[source];
}
@ -61,7 +60,9 @@ class Template {
}
Template.withExpressionResult(this.ast)
: source = null, isExpression = true, forceCopy = false {
: source = null,
isExpression = true,
forceCopy = false {
assert(ast is Expression);
assert(_checkNoPlaceholders());
positionalArgumentCount = 0;
@ -69,7 +70,9 @@ class Template {
}
Template.withStatementResult(this.ast)
: source = null, isExpression = false, forceCopy = false {
: source = null,
isExpression = false,
forceCopy = false {
assert(ast is Statement);
assert(_checkNoPlaceholders());
positionalArgumentCount = 0;
@ -128,14 +131,12 @@ class Template {
*/
typedef Node Instantiator(var arguments);
/**
* InstantiatorGeneratorVisitor compiles a template. This class compiles a tree
* containing [InterpolatedNode]s into a function that will create a copy of the
* tree with the interpolated nodes substituted with provided values.
*/
class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
final bool forceCopy;
InterpolatedNodeAnalysis analysis = new InterpolatedNodeAnalysis();
@ -222,6 +223,7 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
return error('Interpolated value #$nameOrPosition is not '
'an Expression or List of Expressions: $value');
}
if (value is Iterable) return value.map(toExpression);
return toExpression(value);
};
@ -249,6 +251,7 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
return error('Interpolated value #$nameOrPosition is not a Parameter or'
' List of Parameters: $value');
}
if (value is Iterable) return value.map(toParameter);
return toParameter(value);
};
@ -283,10 +286,12 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
var value = arguments[nameOrPosition];
Statement toStatement(item) {
if (item is Statement) return item;
if (item is Expression) return item.toStatement();;
if (item is Expression) return item.toStatement();
;
return error('Interpolated value #$nameOrPosition is not '
'a Statement or List of Statements: $value');
}
if (value is Iterable) return value.map(toStatement);
return toStatement(value);
};
@ -306,6 +311,7 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
statements.add(node.toStatement());
}
}
for (Instantiator instantiator in instantiators) {
add(instantiator(arguments));
}
@ -327,6 +333,7 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
statements.add(node.toStatement());
}
}
for (Instantiator instantiator in instantiators) {
add(instantiator(arguments));
}
@ -360,11 +367,13 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
var value = arguments[nameOrPosition];
if (value is bool) return value;
if (value is Expression) return value;
if (value is String) return convertStringToVariableUse(value);;
if (value is String) return convertStringToVariableUse(value);
;
error('Interpolated value #$nameOrPosition '
'is not an Expression: $value');
};
}
var makeCondition = compileCondition(node.condition);
Instantiator makeThen = visit(node.then);
Instantiator makeOtherwise = visit(node.otherwise);
@ -377,10 +386,7 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
return makeOtherwise(arguments);
}
}
return new If(
condition,
makeThen(arguments),
makeOtherwise(arguments));
return new If(condition, makeThen(arguments), makeOtherwise(arguments));
};
}
@ -389,9 +395,7 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
Instantiator makeThen = visit(node.then);
Instantiator makeOtherwise = visit(node.otherwise);
return (arguments) {
return new If(
makeCondition(arguments),
makeThen(arguments),
return new If(makeCondition(arguments), makeThen(arguments),
makeOtherwise(arguments));
};
}
@ -402,9 +406,8 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
Instantiator makeUpdate = visitNullable(node.update);
Instantiator makeBody = visit(node.body);
return (arguments) {
return new For(
makeInit(arguments), makeCondition(arguments), makeUpdate(arguments),
makeBody(arguments));
return new For(makeInit(arguments), makeCondition(arguments),
makeUpdate(arguments), makeBody(arguments));
};
}
@ -413,9 +416,7 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
Instantiator makeObject = visit(node.object);
Instantiator makeBody = visit(node.body);
return (arguments) {
return new ForIn(
makeLeftHandSide(arguments),
makeObject(arguments),
return new ForIn(makeLeftHandSide(arguments), makeObject(arguments),
makeBody(arguments));
};
}
@ -453,7 +454,8 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
Instantiator visitDartYield(DartYield node) {
Instantiator makeExpression = visit(node.expression);
return (arguments) => new DartYield(makeExpression(arguments), node.hasStar);
return (arguments) =>
new DartYield(makeExpression(arguments), node.hasStar);
}
Instantiator visitThrow(Throw node) {
@ -472,16 +474,18 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
Instantiator visitCatch(Catch node) {
Instantiator makeDeclaration = visit(node.declaration);
Instantiator makeBody = visit(node.body);
return (arguments) => new Catch(
makeDeclaration(arguments), makeBody(arguments));
return (arguments) =>
new Catch(makeDeclaration(arguments), makeBody(arguments));
}
Instantiator visitSwitch(Switch node) {
Instantiator makeKey = visit(node.key);
Iterable<Instantiator> makeCases = node.cases.map(visit);
return (arguments) {
return new Switch(makeKey(arguments),
makeCases.map((Instantiator makeCase) => makeCase(arguments))
return new Switch(
makeKey(arguments),
makeCases
.map((Instantiator makeCase) => makeCase(arguments))
.toList());
};
}
@ -537,9 +541,7 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
Instantiator makeValue = visitNullable(node.value);
return (arguments) {
return new Assignment.compound(
makeLeftHandSide(arguments),
op,
makeValue(arguments));
makeLeftHandSide(arguments), op, makeValue(arguments));
};
}
@ -556,10 +558,8 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
Instantiator makeCondition = visit(cond.condition);
Instantiator makeThen = visit(cond.then);
Instantiator makeOtherwise = visit(cond.otherwise);
return (arguments) => new Conditional(
makeCondition(arguments),
makeThen(arguments),
makeOtherwise(arguments));
return (arguments) => new Conditional(makeCondition(arguments),
makeThen(arguments), makeOtherwise(arguments));
}
Instantiator visitNew(New node) =>
@ -658,8 +658,7 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
Instantiator visitDeferredNumber(DeferredNumber node) => same(node);
Instantiator visitDeferredString(DeferredString node) =>
(arguments) => node;
Instantiator visitDeferredString(DeferredString node) => (arguments) => node;
Instantiator visitLiteralBool(LiteralBool node) =>
(arguments) => new LiteralBool(node.value);
@ -674,9 +673,8 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
(arguments) => new LiteralNull();
Instantiator visitStringConcatenation(StringConcatenation node) {
List<Instantiator> partMakers = node.parts
.map(visit)
.toList(growable: false);
List<Instantiator> partMakers =
node.parts.map(visit).toList(growable: false);
return (arguments) {
List<Literal> parts = partMakers
.map((Instantiator instantiator) => instantiator(arguments))
@ -689,9 +687,8 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
Instantiator visitArrayInitializer(ArrayInitializer node) {
// TODO(sra): Implement splicing?
List<Instantiator> elementMakers = node.elements
.map(visit)
.toList(growable: false);
List<Instantiator> elementMakers =
node.elements.map(visit).toList(growable: false);
return (arguments) {
List<Expression> elements = elementMakers
.map((Instantiator instantiator) => instantiator(arguments))

View file

@ -25,9 +25,7 @@ class TestCase {
/// Map from template names to the inserted values.
final Map<String, String> environment;
const TestCase(
this.data,
[this.environment = const {}]);
const TestCase(this.data, [this.environment = const {}]);
}
const List<TestCase> DATA = const <TestCase>[
@ -49,7 +47,6 @@ function(a@1, b@2) {
return null@5;
@4}@3@0"""
}),
const TestCase(const {
TestMode.NONE: """
function() {
@ -108,7 +105,6 @@ function() {
@26 }@22
@20}@1@0""",
}),
const TestCase(const {
TestMode.NONE: """
function() {
@ -131,7 +127,6 @@ function() {
}@5@3
@2}@1@0"""
}),
const TestCase(const {
TestMode.INPUT: """
function() {
@ -159,14 +154,15 @@ function() {
@2 [1@8,,@9 2@10]@7;
@6}@1@0""",
}),
const TestCase(const {
TestMode.INPUT: "a.#nameTemplate = #nameTemplate",
TestMode.NONE: "a.nameValue = nameValue",
TestMode.ENTER: "@0@1@2a.@3nameValue = @3nameValue",
TestMode.DELIMITER: "a.nameValue = nameValue",
TestMode.EXIT: "a@2.nameValue@3@1 = nameValue@3@0",
}, const {'nameTemplate': 'nameValue'}),
}, const {
'nameTemplate': 'nameValue'
}),
];
class FixedName extends Name {
@ -221,10 +217,8 @@ class Context extends SimpleJavaScriptPrintingContext {
}
}
void exitNode(Node node,
int startPosition,
int endPosition,
int delimiterPosition) {
void exitNode(
Node node, int startPosition, int endPosition, int delimiterPosition) {
int value = id(node);
if (mode == TestMode.DELIMITER && delimiterPosition != null) {
tagMap.putIfAbsent(delimiterPosition, () => []).add(tag(value));

View file

@ -59,7 +59,6 @@ void main() {
check([0, 1, 2, 3], [$DQ, 0, 1, 2, 3, $DQ], utf8: true);
});
test('line-separator', () {
// Legacy escaper is broken.
// check([$LS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $8, $DQ]);
@ -84,15 +83,10 @@ void main() {
check('"', [$SQ, $DQ, $SQ], ascii: true);
check("'", [$DQ, $SQ, $DQ], ascii: true);
// Legacy always double-quotes
check([$DQ, $DQ, $SQ],
[$DQ, $BACKSLASH, $DQ, $BACKSLASH, $DQ, $SQ, $DQ]);
check([$DQ, $DQ, $SQ], [$DQ, $BACKSLASH, $DQ, $BACKSLASH, $DQ, $SQ, $DQ]);
// Using single quotes saves us one backslash:
check([$DQ, $DQ, $SQ],
[$SQ, $DQ, $DQ, $BACKSLASH, $SQ, $SQ],
ascii: true);
check([$DQ, $SQ, $SQ],
[$DQ, $BACKSLASH, $DQ, $SQ, $SQ, $DQ],
ascii: true);
check([$DQ, $DQ, $SQ], [$SQ, $DQ, $DQ, $BACKSLASH, $SQ, $SQ], ascii: true);
check([$DQ, $SQ, $SQ], [$DQ, $BACKSLASH, $DQ, $SQ, $SQ, $DQ], ascii: true);
});
test('u1234', () {
@ -108,10 +102,24 @@ void main() {
// [$DQ, $BACKSLASH, $u, $LCURLY, $1, $2, $3, $4, $5, $RCURLY, $DQ],
// ascii: true);
check([0x12345], r'''"\ud808\udf45"''', ascii: true);
check([0x12345],
[$DQ, $BACKSLASH, $u, $d, $8, $0, $8,
$BACKSLASH, $u, $d, $f, $4, $5, $DQ],
ascii: true);
check([
0x12345
], [
$DQ,
$BACKSLASH,
$u,
$d,
$8,
$0,
$8,
$BACKSLASH,
$u,
$d,
$f,
$4,
$5,
$DQ
], ascii: true);
check([0x12345], [$DQ, 55304, 57157, $DQ], utf8: true);
});
@ -127,22 +135,32 @@ void main() {
check([0xDD1E], [$DQ, $BACKSLASH, $u, $d, $d, $1, $e, $DQ], ascii: true);
check([0xDD1E], [$DQ, $BACKSLASH, $u, $d, $d, $1, $e, $DQ], utf8: true);
check([0xD834, $A],
[$DQ, 0xD834, $A, $DQ]); // Legacy escapedString broken.
check([0xD834, $A],
[$DQ, $BACKSLASH, $u, $d, $8, $3, $4, $A, $DQ],
check([0xD834, $A], [$DQ, 0xD834, $A, $DQ]); // Legacy escapedString broken.
check([0xD834, $A], [$DQ, $BACKSLASH, $u, $d, $8, $3, $4, $A, $DQ],
ascii: true);
check([0xD834, $A],
[$DQ, $BACKSLASH, $u, $d, $8, $3, $4, $A, $DQ],
check([0xD834, $A], [$DQ, $BACKSLASH, $u, $d, $8, $3, $4, $A, $DQ],
utf8: true);
check([0xD834, 0xDD1E], [$DQ, 0xD834, 0xDD1E, $DQ]); // Legacy ok.
check([0xD834, 0xDD1E],
[$DQ,
$BACKSLASH, $u, $d, $8, $3, $4,
$BACKSLASH, $u, $d, $d, $1, $e,
$DQ],
ascii: true);
check([
0xD834,
0xDD1E
], [
$DQ,
$BACKSLASH,
$u,
$d,
$8,
$3,
$4,
$BACKSLASH,
$u,
$d,
$d,
$1,
$e,
$DQ
], ascii: true);
check([0xD834, 0xDD1E], r'''"\ud834\udd1e"''', ascii: true);
check([0xD834, 0xDD1E], [$DQ, 0xD834, 0xDD1E, $DQ], utf8: true);
});