mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 15:01:30 +00:00
Run dartfmt on js_ast
BUG= R=sra@google.com Review-Url: https://codereview.chromium.org/2748103010 .
This commit is contained in:
parent
33717e010a
commit
11950984e4
7 changed files with 498 additions and 428 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue