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); |
- |
} |
/** |