| Index: pkg/js_ast/lib/src/nodes.dart
|
| diff --git a/pkg/js_ast/lib/src/nodes.dart b/pkg/js_ast/lib/src/nodes.dart
|
| index 7c8293e8d9e5ae5896583167499a28236375793f..8dc7f8f637ed121298fb3a59cf3d84c93002dee4 100644
|
| --- a/pkg/js_ast/lib/src/nodes.dart
|
| +++ b/pkg/js_ast/lib/src/nodes.dart
|
| @@ -49,11 +49,17 @@ abstract class NodeVisitor<T> {
|
| T visitNamedFunction(NamedFunction node);
|
| T visitFun(Fun node);
|
|
|
| + T visitDeferredExpression(DeferredExpression node);
|
| + T visitDeferredNumber(DeferredNumber node);
|
| + T visitDeferredString(DeferredString node);
|
| +
|
| T visitLiteralBool(LiteralBool node);
|
| T visitLiteralString(LiteralString node);
|
| T visitLiteralNumber(LiteralNumber node);
|
| T visitLiteralNull(LiteralNull node);
|
|
|
| + T visitStringConcatenation(StringConcatenation node);
|
| +
|
| T visitArrayInitializer(ArrayInitializer node);
|
| T visitArrayHole(ArrayHole node);
|
| T visitObjectInitializer(ObjectInitializer node);
|
| @@ -139,6 +145,12 @@ class BaseVisitor<T> implements NodeVisitor<T> {
|
| T visitNamedFunction(NamedFunction node) => visitExpression(node);
|
| T visitFun(Fun node) => visitExpression(node);
|
|
|
| + T visitToken(DeferredToken node) => visitExpression(node);
|
| +
|
| + T visitDeferredExpression(DeferredExpression node) => visitExpression(node);
|
| + T visitDeferredNumber(DeferredNumber node) => visitToken(node);
|
| + T visitDeferredString(DeferredString node) => visitToken(node);
|
| +
|
| T visitLiteral(Literal node) => visitExpression(node);
|
|
|
| T visitLiteralBool(LiteralBool node) => visitLiteral(node);
|
| @@ -146,6 +158,8 @@ class BaseVisitor<T> implements NodeVisitor<T> {
|
| T visitLiteralNumber(LiteralNumber node) => visitLiteral(node);
|
| T visitLiteralNull(LiteralNull node) => visitLiteral(node);
|
|
|
| + T visitStringConcatenation(StringConcatenation node) => visitLiteral(node);
|
| +
|
| T visitArrayInitializer(ArrayInitializer node) => visitExpression(node);
|
| T visitArrayHole(ArrayHole node) => visitExpression(node);
|
| T visitObjectInitializer(ObjectInitializer node) => visitExpression(node);
|
| @@ -675,7 +689,9 @@ class Call extends Expression {
|
|
|
| void visitChildren(NodeVisitor visitor) {
|
| target.accept(visitor);
|
| - for (Expression arg in arguments) arg.accept(visitor);
|
| + for (Expression arg in arguments) {
|
| + arg.accept(visitor);
|
| + }
|
| }
|
|
|
| Call _clone() => new Call(target, arguments);
|
| @@ -916,6 +932,46 @@ class PropertyAccess extends Expression {
|
| int get precedenceLevel => CALL;
|
| }
|
|
|
| +/// A [DeferredToken] is a placeholder for some [Expression] that is not known
|
| +/// at construction time of an ast. Unlike [InterpolatedExpression],
|
| +/// [DeferredToken] is not limited to templates but may also occur in
|
| +/// fully instantiated asts.
|
| +abstract class DeferredToken extends Expression {
|
| + void visitChildren(NodeVisitor visitor) {}
|
| +
|
| + DeferredToken _clone() => this;
|
| +}
|
| +
|
| +/// Interace for a deferred integer value. An implementation has to provide
|
| +/// a value via the [value] getter the latest when the ast is printed.
|
| +abstract class DeferredNumber extends DeferredToken implements Literal {
|
| + accept(NodeVisitor visitor) => visitor.visitDeferredNumber(this);
|
| +
|
| + int get value;
|
| +
|
| + int get precedenceLevel => PRIMARY;
|
| +}
|
| +
|
| +/// Interace for a deferred string value. An implementation has to provide
|
| +/// a value via the [value] getter the latest when the ast is printed.
|
| +abstract class DeferredString extends DeferredToken implements Literal {
|
| + accept(NodeVisitor visitor) => visitor.visitDeferredString(this);
|
| +
|
| + String get value;
|
| +
|
| + int get precedenceLevel => PRIMARY;
|
| +}
|
| +
|
| +/// Interace for a deferred [Expression] value. An implementation has to provide
|
| +/// a value via the [value] getter the latest when the ast is printed.
|
| +/// Also, [precedenceLevel] has to return the same value that
|
| +/// [value.precedenceLevel] returns once [value] is bound to an [Expression].
|
| +abstract class DeferredExpression extends DeferredToken {
|
| + accept(NodeVisitor visitor) => visitor.visitDeferredExpression(this);
|
| +
|
| + Expression get value;
|
| +}
|
| +
|
| abstract class Literal extends Expression {
|
| void visitChildren(NodeVisitor visitor) {}
|
|
|
| @@ -946,7 +1002,7 @@ class LiteralString extends Literal {
|
| * Constructs a LiteralString from a string value.
|
| *
|
| * The constructor does not add the required quotes. If [value] is not
|
| - * surrounded by quotes and property escaped, the resulting object is invalid
|
| + * surrounded by quotes and properly escaped, the resulting object is invalid
|
| * as a JS value.
|
| *
|
| * TODO(sra): Introduce variants for known valid strings that don't allocate a
|
| @@ -958,6 +1014,25 @@ class LiteralString extends Literal {
|
| LiteralString _clone() => new LiteralString(value);
|
| }
|
|
|
| +class StringConcatenation extends Literal {
|
| + final List<Literal> parts;
|
| +
|
| + /**
|
| + * Constructs a StringConcatenation from a list of Literal elements.
|
| + * The constructor does not add surrounding quotes to the resulting
|
| + * concatenated string.
|
| + */
|
| + StringConcatenation(this.parts);
|
| +
|
| + accept(NodeVisitor visitor) => visitor.visitStringConcatenation(this);
|
| +
|
| + void visitChildren(NodeVisitor visitor) {
|
| + for (Literal part in parts) part.accept(visitor);
|
| + }
|
| +
|
| + StringConcatenation _clone() => new StringConcatenation(this.parts);
|
| +}
|
| +
|
| class LiteralNumber extends Literal {
|
| final String value; // Must be a valid JavaScript number literal.
|
|
|
| @@ -1161,7 +1236,6 @@ class Await extends Expression {
|
| accept(NodeVisitor visitor) => visitor.visitAwait(this);
|
| void visitChildren(NodeVisitor visitor) => expression.accept(visitor);
|
| Await _clone() => new Await(expression);
|
| -
|
| }
|
|
|
| /**
|
|
|