| // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| part of js_ast; |
| |
| abstract class NodeVisitor<T> { |
| T visitProgram(Program node); |
| |
| T visitBlock(Block node); |
| T visitExpressionStatement(ExpressionStatement node); |
| T visitEmptyStatement(EmptyStatement node); |
| T visitIf(If node); |
| T visitFor(For node); |
| T visitForIn(ForIn node); |
| T visitWhile(While node); |
| T visitDo(Do node); |
| T visitContinue(Continue node); |
| T visitBreak(Break node); |
| T visitReturn(Return node); |
| T visitThrow(Throw node); |
| T visitTry(Try node); |
| T visitCatch(Catch node); |
| T visitSwitch(Switch node); |
| T visitCase(Case node); |
| T visitDefault(Default node); |
| T visitFunctionDeclaration(FunctionDeclaration node); |
| T visitLabeledStatement(LabeledStatement node); |
| T visitLiteralStatement(LiteralStatement node); |
| T visitDartYield(DartYield node); |
| |
| T visitLiteralExpression(LiteralExpression node); |
| T visitVariableDeclarationList(VariableDeclarationList node); |
| T visitAssignment(Assignment node); |
| T visitVariableInitialization(VariableInitialization node); |
| T visitConditional(Conditional cond); |
| T visitNew(New node); |
| T visitCall(Call node); |
| T visitBinary(Binary node); |
| T visitPrefix(Prefix node); |
| T visitPostfix(Postfix node); |
| |
| T visitVariableUse(VariableUse node); |
| T visitThis(This node); |
| T visitVariableDeclaration(VariableDeclaration node); |
| T visitParameter(Parameter node); |
| T visitAccess(PropertyAccess node); |
| |
| T visitNamedFunction(NamedFunction node); |
| T visitFun(Fun node); |
| T visitArrowFunction(ArrowFunction node); |
| |
| T visitDeferredStatement(DeferredStatement 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 visitName(Name node); |
| |
| T visitParentheses(Parentheses node); |
| |
| T visitArrayInitializer(ArrayInitializer node); |
| T visitArrayHole(ArrayHole node); |
| T visitObjectInitializer(ObjectInitializer node); |
| T visitProperty(Property node); |
| T visitMethodDefinition(MethodDefinition node); |
| T visitRegExpLiteral(RegExpLiteral node); |
| |
| T visitAwait(Await node); |
| |
| T visitComment(Comment node); |
| |
| T visitInterpolatedExpression(InterpolatedExpression node); |
| T visitInterpolatedLiteral(InterpolatedLiteral node); |
| T visitInterpolatedParameter(InterpolatedParameter node); |
| T visitInterpolatedSelector(InterpolatedSelector node); |
| T visitInterpolatedStatement(InterpolatedStatement node); |
| T visitInterpolatedDeclaration(InterpolatedDeclaration node); |
| } |
| |
| abstract class BaseVisitor<T> implements NodeVisitor<T> { |
| const BaseVisitor(); |
| |
| T visitNode(Node node); |
| T visitComment(Comment node); |
| |
| T visitProgram(Program node) => visitNode(node); |
| |
| T visitStatement(Statement node) => visitNode(node); |
| T visitLoop(Loop node) => visitStatement(node); |
| T visitJump(Statement node) => visitStatement(node); |
| |
| T visitBlock(Block 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); |
| T visitForIn(ForIn node) => visitLoop(node); |
| T visitWhile(While node) => visitLoop(node); |
| T visitDo(Do node) => visitLoop(node); |
| T visitContinue(Continue node) => visitJump(node); |
| T visitBreak(Break node) => visitJump(node); |
| T visitReturn(Return node) => visitJump(node); |
| 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 visitLabeledStatement(LabeledStatement node) => visitStatement(node); |
| T visitLiteralStatement(LiteralStatement node) => visitStatement(node); |
| |
| T visitCatch(Catch node) => visitNode(node); |
| T visitCase(Case node) => visitNode(node); |
| T visitDefault(Default node) => visitNode(node); |
| |
| T visitExpression(Expression node) => visitNode(node); |
| T visitVariableReference(VariableReference node) => visitExpression(node); |
| |
| T visitLiteralExpression(LiteralExpression node) => visitExpression(node); |
| T visitVariableDeclarationList(VariableDeclarationList node) => |
| visitExpression(node); |
| T visitAssignment(Assignment node) => visitExpression(node); |
| T visitVariableInitialization(VariableInitialization node) => |
| visitExpression(node); |
| |
| T visitConditional(Conditional node) => visitExpression(node); |
| T visitNew(New node) => visitExpression(node); |
| T visitCall(Call node) => visitExpression(node); |
| T visitBinary(Binary node) => visitExpression(node); |
| T visitPrefix(Prefix node) => visitExpression(node); |
| T visitPostfix(Postfix node) => visitExpression(node); |
| T visitAccess(PropertyAccess node) => visitExpression(node); |
| |
| T visitVariableUse(VariableUse node) => visitVariableReference(node); |
| T visitVariableDeclaration(VariableDeclaration node) => |
| visitVariableReference(node); |
| T visitParameter(Parameter node) => visitVariableDeclaration(node); |
| T visitThis(This node) => visitParameter(node); |
| |
| T visitNamedFunction(NamedFunction node) => visitExpression(node); |
| T visitFunctionExpression(FunctionExpression node) => visitExpression(node); |
| T visitFun(Fun node) => visitFunctionExpression(node); |
| T visitArrowFunction(ArrowFunction node) => visitFunctionExpression(node); |
| |
| T visitToken(DeferredToken node) => visitExpression(node); |
| |
| T visitDeferredStatement(DeferredStatement node) => visitStatement(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); |
| T visitLiteralString(LiteralString node) => visitLiteral(node); |
| T visitLiteralNumber(LiteralNumber node) => visitLiteral(node); |
| T visitLiteralNull(LiteralNull node) => visitLiteral(node); |
| |
| T visitStringConcatenation(StringConcatenation node) => visitLiteral(node); |
| |
| T visitName(Name node) => visitNode(node); |
| |
| T visitParentheses(Parentheses node) => visitExpression(node); |
| |
| T visitArrayInitializer(ArrayInitializer node) => visitExpression(node); |
| T visitArrayHole(ArrayHole node) => visitExpression(node); |
| T visitObjectInitializer(ObjectInitializer node) => visitExpression(node); |
| T visitProperty(Property node) => visitNode(node); |
| T visitMethodDefinition(MethodDefinition node) => visitNode(node); |
| T visitRegExpLiteral(RegExpLiteral node) => visitExpression(node); |
| |
| 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 visitInterpolatedDeclaration(InterpolatedDeclaration node) { |
| return visitInterpolatedNode(node); |
| } |
| |
| T visitAwait(Await node) => visitExpression(node); |
| T visitDartYield(DartYield node) => visitStatement(node); |
| } |
| |
| class BaseVisitorVoid extends BaseVisitor<void> { |
| void visitNode(Node node) { |
| node.visitChildren(this); |
| } |
| |
| // Ignore comments by default. |
| void visitComment(Comment node) {} |
| } |
| |
| abstract class NodeVisitor1<R, A> { |
| R visitProgram(Program node, A arg); |
| |
| R visitBlock(Block node, A arg); |
| R visitExpressionStatement(ExpressionStatement node, A arg); |
| R visitEmptyStatement(EmptyStatement node, A arg); |
| R visitIf(If node, A arg); |
| R visitFor(For node, A arg); |
| R visitForIn(ForIn node, A arg); |
| R visitWhile(While node, A arg); |
| R visitDo(Do node, A arg); |
| R visitContinue(Continue node, A arg); |
| R visitBreak(Break node, A arg); |
| R visitReturn(Return node, A arg); |
| R visitThrow(Throw node, A arg); |
| R visitTry(Try node, A arg); |
| R visitCatch(Catch node, A arg); |
| R visitSwitch(Switch node, A arg); |
| R visitCase(Case node, A arg); |
| R visitDefault(Default node, A arg); |
| R visitFunctionDeclaration(FunctionDeclaration node, A arg); |
| R visitLabeledStatement(LabeledStatement node, A arg); |
| R visitLiteralStatement(LiteralStatement node, A arg); |
| R visitDartYield(DartYield node, A arg); |
| |
| R visitLiteralExpression(LiteralExpression node, A arg); |
| R visitVariableDeclarationList(VariableDeclarationList node, A arg); |
| R visitAssignment(Assignment node, A arg); |
| R visitVariableInitialization(VariableInitialization node, A arg); |
| R visitConditional(Conditional cond, A arg); |
| R visitNew(New node, A arg); |
| R visitCall(Call node, A arg); |
| R visitBinary(Binary node, A arg); |
| R visitPrefix(Prefix node, A arg); |
| R visitPostfix(Postfix node, A arg); |
| |
| R visitVariableUse(VariableUse node, A arg); |
| R visitThis(This node, A arg); |
| R visitVariableDeclaration(VariableDeclaration node, A arg); |
| R visitParameter(Parameter node, A arg); |
| R visitAccess(PropertyAccess node, A arg); |
| |
| R visitNamedFunction(NamedFunction node, A arg); |
| R visitFun(Fun node, A arg); |
| R visitArrowFunction(ArrowFunction node, A arg); |
| |
| R visitDeferredStatement(DeferredStatement node, A arg); |
| R visitDeferredExpression(DeferredExpression node, A arg); |
| R visitDeferredNumber(DeferredNumber node, A arg); |
| R visitDeferredString(DeferredString node, A arg); |
| |
| R visitLiteralBool(LiteralBool node, A arg); |
| R visitLiteralString(LiteralString node, A arg); |
| R visitLiteralNumber(LiteralNumber node, A arg); |
| R visitLiteralNull(LiteralNull node, A arg); |
| |
| R visitStringConcatenation(StringConcatenation node, A arg); |
| |
| R visitName(Name node, A arg); |
| |
| R visitParentheses(Parentheses node, A arg); |
| |
| R visitArrayInitializer(ArrayInitializer node, A arg); |
| R visitArrayHole(ArrayHole node, A arg); |
| R visitObjectInitializer(ObjectInitializer node, A arg); |
| R visitProperty(Property node, A arg); |
| R visitMethodDefinition(MethodDefinition node, A arg); |
| R visitRegExpLiteral(RegExpLiteral node, A arg); |
| |
| R visitAwait(Await node, A arg); |
| |
| R visitComment(Comment node, A arg); |
| |
| R visitInterpolatedExpression(InterpolatedExpression node, A arg); |
| R visitInterpolatedLiteral(InterpolatedLiteral node, A arg); |
| R visitInterpolatedParameter(InterpolatedParameter node, A arg); |
| R visitInterpolatedSelector(InterpolatedSelector node, A arg); |
| R visitInterpolatedStatement(InterpolatedStatement node, A arg); |
| R visitInterpolatedDeclaration(InterpolatedDeclaration node, A arg); |
| } |
| |
| abstract class BaseVisitor1<R, A> implements NodeVisitor1<R, A> { |
| const BaseVisitor1(); |
| |
| R visitNode(Node node, A arg); |
| R visitComment(Comment node, A arg); |
| |
| R visitProgram(Program node, A arg) => visitNode(node, arg); |
| |
| R visitStatement(Statement node, A arg) => visitNode(node, arg); |
| R visitLoop(Loop node, A arg) => visitStatement(node, arg); |
| R visitJump(Statement node, A arg) => visitStatement(node, arg); |
| |
| R visitBlock(Block node, A arg) => visitStatement(node, arg); |
| R visitExpressionStatement(ExpressionStatement node, A arg) => |
| visitStatement(node, arg); |
| R visitEmptyStatement(EmptyStatement node, A arg) => |
| visitStatement(node, arg); |
| R visitIf(If node, A arg) => visitStatement(node, arg); |
| R visitFor(For node, A arg) => visitLoop(node, arg); |
| R visitForIn(ForIn node, A arg) => visitLoop(node, arg); |
| R visitWhile(While node, A arg) => visitLoop(node, arg); |
| R visitDo(Do node, A arg) => visitLoop(node, arg); |
| R visitContinue(Continue node, A arg) => visitJump(node, arg); |
| R visitBreak(Break node, A arg) => visitJump(node, arg); |
| R visitReturn(Return node, A arg) => visitJump(node, arg); |
| R visitThrow(Throw node, A arg) => visitJump(node, arg); |
| R visitTry(Try node, A arg) => visitStatement(node, arg); |
| R visitSwitch(Switch node, A arg) => visitStatement(node, arg); |
| R visitFunctionDeclaration(FunctionDeclaration node, A arg) => |
| visitStatement(node, arg); |
| R visitLabeledStatement(LabeledStatement node, A arg) => |
| visitStatement(node, arg); |
| R visitLiteralStatement(LiteralStatement node, A arg) => |
| visitStatement(node, arg); |
| |
| R visitCatch(Catch node, A arg) => visitNode(node, arg); |
| R visitCase(Case node, A arg) => visitNode(node, arg); |
| R visitDefault(Default node, A arg) => visitNode(node, arg); |
| |
| R visitExpression(Expression node, A arg) => visitNode(node, arg); |
| R visitVariableReference(VariableReference node, A arg) => |
| visitExpression(node, arg); |
| |
| R visitLiteralExpression(LiteralExpression node, A arg) => |
| visitExpression(node, arg); |
| R visitVariableDeclarationList(VariableDeclarationList node, A arg) => |
| visitExpression(node, arg); |
| R visitAssignment(Assignment node, A arg) => visitExpression(node, arg); |
| R visitVariableInitialization(VariableInitialization node, A arg) => |
| visitExpression(node, arg); |
| |
| R visitConditional(Conditional node, A arg) => visitExpression(node, arg); |
| R visitNew(New node, A arg) => visitExpression(node, arg); |
| R visitCall(Call node, A arg) => visitExpression(node, arg); |
| R visitBinary(Binary node, A arg) => visitExpression(node, arg); |
| R visitPrefix(Prefix node, A arg) => visitExpression(node, arg); |
| R visitPostfix(Postfix node, A arg) => visitExpression(node, arg); |
| R visitAccess(PropertyAccess node, A arg) => visitExpression(node, arg); |
| |
| R visitVariableUse(VariableUse node, A arg) => |
| visitVariableReference(node, arg); |
| R visitVariableDeclaration(VariableDeclaration node, A arg) => |
| visitVariableReference(node, arg); |
| R visitParameter(Parameter node, A arg) => |
| visitVariableDeclaration(node, arg); |
| R visitThis(This node, A arg) => visitParameter(node, arg); |
| |
| R visitNamedFunction(NamedFunction node, A arg) => visitExpression(node, arg); |
| R visitFun(Fun node, A arg) => visitExpression(node, arg); |
| R visitArrowFunction(ArrowFunction node, A arg) => visitExpression(node, arg); |
| |
| R visitToken(DeferredToken node, A arg) => visitExpression(node, arg); |
| |
| R visitDeferredStatement(DeferredStatement node, A arg) => |
| visitStatement(node, arg); |
| R visitDeferredExpression(DeferredExpression node, A arg) => |
| visitExpression(node, arg); |
| R visitDeferredNumber(DeferredNumber node, A arg) => visitToken(node, arg); |
| R visitDeferredString(DeferredString node, A arg) => visitToken(node, arg); |
| |
| R visitLiteral(Literal node, A arg) => visitExpression(node, arg); |
| |
| R visitLiteralBool(LiteralBool node, A arg) => visitLiteral(node, arg); |
| R visitLiteralString(LiteralString node, A arg) => visitLiteral(node, arg); |
| R visitLiteralNumber(LiteralNumber node, A arg) => visitLiteral(node, arg); |
| R visitLiteralNull(LiteralNull node, A arg) => visitLiteral(node, arg); |
| |
| R visitStringConcatenation(StringConcatenation node, A arg) => |
| visitLiteral(node, arg); |
| |
| R visitName(Name node, A arg) => visitNode(node, arg); |
| |
| R visitParentheses(Parentheses node, A arg) => visitExpression(node, arg); |
| |
| R visitArrayInitializer(ArrayInitializer node, A arg) => |
| visitExpression(node, arg); |
| R visitArrayHole(ArrayHole node, A arg) => visitExpression(node, arg); |
| R visitObjectInitializer(ObjectInitializer node, A arg) => |
| visitExpression(node, arg); |
| R visitProperty(Property node, A arg) => visitNode(node, arg); |
| R visitMethodDefinition(MethodDefinition node, A arg) => visitNode(node, arg); |
| R visitRegExpLiteral(RegExpLiteral node, A arg) => visitExpression(node, arg); |
| |
| R visitInterpolatedNode(InterpolatedNode node, A arg) => visitNode(node, arg); |
| |
| R visitInterpolatedExpression(InterpolatedExpression node, A arg) => |
| visitInterpolatedNode(node, arg); |
| R visitInterpolatedLiteral(InterpolatedLiteral node, A arg) => |
| visitInterpolatedNode(node, arg); |
| R visitInterpolatedParameter(InterpolatedParameter node, A arg) => |
| visitInterpolatedNode(node, arg); |
| R visitInterpolatedSelector(InterpolatedSelector node, A arg) => |
| visitInterpolatedNode(node, arg); |
| R visitInterpolatedStatement(InterpolatedStatement node, A arg) => |
| visitInterpolatedNode(node, arg); |
| R visitInterpolatedDeclaration(InterpolatedDeclaration node, A arg) { |
| return visitInterpolatedNode(node, arg); |
| } |
| |
| R visitAwait(Await node, A arg) => visitExpression(node, arg); |
| R visitDartYield(DartYield node, A arg) => visitStatement(node, arg); |
| } |
| |
| class BaseVisitor1Void<A> extends BaseVisitor1<void, A> { |
| void visitNode(Node node, A arg) { |
| node.visitChildren1(this, arg); |
| } |
| |
| // Ignore comments by default. |
| void visitComment(Comment node, A arg) {} |
| } |
| |
| /// This tag interface has no behaviour but must be implemented by any class |
| /// that is to be stored on a [Node] as source information. |
| abstract class JavaScriptNodeSourceInformation { |
| const JavaScriptNodeSourceInformation(); |
| } |
| |
| abstract class Node { |
| JavaScriptNodeSourceInformation get sourceInformation => _sourceInformation; |
| |
| JavaScriptNodeSourceInformation _sourceInformation; |
| |
| T accept<T>(NodeVisitor<T> visitor); |
| void visitChildren<T>(NodeVisitor<T> visitor); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg); |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg); |
| |
| /// Shallow clone of node. Does not clone positions since the only use of |
| /// this private method is create a copy with a new position. |
| Node _clone(); |
| |
| /// Returns a node equivalent to [this], but with new source position and end |
| /// source position. |
| Node withSourceInformation( |
| JavaScriptNodeSourceInformation sourceInformation) { |
| if (sourceInformation == _sourceInformation) { |
| return this; |
| } |
| Node clone = _clone(); |
| // TODO(sra): Should existing data be 'sticky' if we try to overwrite with |
| // `null`? |
| clone._sourceInformation = sourceInformation; |
| return clone; |
| } |
| |
| bool get isCommaOperator => false; |
| |
| Statement toStatement() { |
| throw UnsupportedError('toStatement'); |
| } |
| |
| String debugPrint() => DebugPrint(this); |
| |
| /// Some nodes, e.g. DeferredExpression, become finalized in a 'linking' |
| /// phase. |
| bool get isFinalized => true; |
| |
| /// If a node is not finalized, debug printing can print something indicative |
| /// of the node instead of the finalized AST. This method returns the |
| /// replacement text. |
| String nonfinalizedDebugText() { |
| assert(!isFinalized); |
| return '$runtimeType'; |
| } |
| } |
| |
| class Program extends Node { |
| final List<Statement> body; |
| Program(this.body); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitProgram(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitProgram(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| for (Statement statement in body) statement.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| for (Statement statement in body) statement.accept1(visitor, arg); |
| } |
| |
| Program _clone() => Program(body); |
| } |
| |
| abstract class Statement extends Node { |
| Statement toStatement() => this; |
| } |
| |
| /// Interface for a deferred [Statement] value. An implementation has to provide |
| /// a value via the [statement] getter the latest when the ast is printed. |
| abstract class DeferredStatement extends Statement { |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitDeferredStatement(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitDeferredStatement(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| statement.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| statement.accept1(visitor, arg); |
| } |
| |
| Statement get statement; |
| } |
| |
| class Block extends Statement { |
| final List<Statement> statements; |
| |
| Block(this.statements); |
| |
| Block.empty() : this.statements = []; |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitBlock(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitBlock(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| for (Statement statement in statements) statement.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| for (Statement statement in statements) statement.accept1(visitor, arg); |
| } |
| |
| Block _clone() => Block(statements); |
| } |
| |
| class ExpressionStatement extends Statement { |
| final Expression expression; |
| |
| ExpressionStatement(this.expression) { |
| assert(this.expression != null); |
| } |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitExpressionStatement(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitExpressionStatement(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| expression.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| expression.accept1(visitor, arg); |
| } |
| |
| ExpressionStatement _clone() => ExpressionStatement(expression); |
| } |
| |
| class EmptyStatement extends Statement { |
| EmptyStatement(); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitEmptyStatement(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitEmptyStatement(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) {} |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {} |
| |
| EmptyStatement _clone() => EmptyStatement(); |
| } |
| |
| class If extends Statement { |
| final Expression condition; |
| final Statement then; |
| final Statement otherwise; |
| |
| If(this.condition, this.then, this.otherwise); |
| |
| If.noElse(this.condition, this.then) : this.otherwise = EmptyStatement(); |
| |
| bool get hasElse => otherwise is! EmptyStatement; |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitIf(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitIf(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| condition.accept(visitor); |
| then.accept(visitor); |
| otherwise.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| condition.accept1(visitor, arg); |
| then.accept1(visitor, arg); |
| otherwise.accept1(visitor, arg); |
| } |
| |
| If _clone() => If(condition, then, otherwise); |
| } |
| |
| abstract class Loop extends Statement { |
| final Statement body; |
| |
| Loop(this.body); |
| } |
| |
| class For extends Loop { |
| final Expression init; |
| final Expression condition; |
| final Expression update; |
| |
| For(this.init, this.condition, this.update, Statement body) : super(body); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitFor(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitFor(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| if (init != null) init.accept(visitor); |
| if (condition != null) condition.accept(visitor); |
| if (update != null) update.accept(visitor); |
| body.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| if (init != null) init.accept1(visitor, arg); |
| if (condition != null) condition.accept1(visitor, arg); |
| if (update != null) update.accept1(visitor, arg); |
| body.accept1(visitor, arg); |
| } |
| |
| For _clone() => For(init, condition, update, body); |
| } |
| |
| class ForIn extends Loop { |
| // Note that [VariableDeclarationList] is a subclass of [Expression]. |
| // Therefore we can type the leftHandSide as [Expression]. |
| final Expression leftHandSide; |
| final Expression object; |
| |
| ForIn(this.leftHandSide, this.object, Statement body) : super(body); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitForIn(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitForIn(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| leftHandSide.accept(visitor); |
| object.accept(visitor); |
| body.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| leftHandSide.accept1(visitor, arg); |
| object.accept1(visitor, arg); |
| body.accept1(visitor, arg); |
| } |
| |
| ForIn _clone() => ForIn(leftHandSide, object, body); |
| } |
| |
| class While extends Loop { |
| final Node condition; |
| |
| While(this.condition, Statement body) : super(body); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitWhile(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitWhile(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| condition.accept(visitor); |
| body.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| condition.accept1(visitor, arg); |
| body.accept1(visitor, arg); |
| } |
| |
| While _clone() => While(condition, body); |
| } |
| |
| class Do extends Loop { |
| final Expression condition; |
| |
| Do(Statement body, this.condition) : super(body); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitDo(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitDo(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| body.accept(visitor); |
| condition.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| body.accept1(visitor, arg); |
| condition.accept1(visitor, arg); |
| } |
| |
| Do _clone() => Do(body, condition); |
| } |
| |
| class Continue extends Statement { |
| final String targetLabel; // Can be null. |
| |
| Continue(this.targetLabel); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitContinue(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitContinue(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) {} |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {} |
| |
| Continue _clone() => Continue(targetLabel); |
| } |
| |
| class Break extends Statement { |
| final String targetLabel; // Can be null. |
| |
| Break(this.targetLabel); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitBreak(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitBreak(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) {} |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {} |
| |
| Break _clone() => Break(targetLabel); |
| } |
| |
| class Return extends Statement { |
| final Expression value; // Can be null. |
| |
| Return([this.value = null]); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitReturn(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitReturn(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| if (value != null) value.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| if (value != null) value.accept1(visitor, arg); |
| } |
| |
| Return _clone() => Return(value); |
| } |
| |
| class Throw extends Statement { |
| final Expression expression; |
| |
| Throw(this.expression); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitThrow(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitThrow(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| expression.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| expression.accept1(visitor, arg); |
| } |
| |
| Throw _clone() => Throw(expression); |
| } |
| |
| class Try extends Statement { |
| final Block body; |
| final Catch catchPart; // Can be null if [finallyPart] is non-null. |
| final Block finallyPart; // Can be null if [catchPart] is non-null. |
| |
| Try(this.body, this.catchPart, this.finallyPart) { |
| assert(catchPart != null || finallyPart != null); |
| } |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitTry(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitTry(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| body.accept(visitor); |
| if (catchPart != null) catchPart.accept(visitor); |
| if (finallyPart != null) finallyPart.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| body.accept1(visitor, arg); |
| if (catchPart != null) catchPart.accept1(visitor, arg); |
| if (finallyPart != null) finallyPart.accept1(visitor, arg); |
| } |
| |
| Try _clone() => Try(body, catchPart, finallyPart); |
| } |
| |
| class Catch extends Node { |
| final Declaration declaration; |
| final Block body; |
| |
| Catch(this.declaration, this.body); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitCatch(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitCatch(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| declaration.accept(visitor); |
| body.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| declaration.accept1(visitor, arg); |
| body.accept1(visitor, arg); |
| } |
| |
| Catch _clone() => Catch(declaration, body); |
| } |
| |
| class Switch extends Statement { |
| final Expression key; |
| final List<SwitchClause> cases; |
| |
| Switch(this.key, this.cases); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitSwitch(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitSwitch(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| key.accept(visitor); |
| for (SwitchClause clause in cases) clause.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| key.accept1(visitor, arg); |
| for (SwitchClause clause in cases) clause.accept1(visitor, arg); |
| } |
| |
| Switch _clone() => Switch(key, cases); |
| } |
| |
| abstract class SwitchClause extends Node { |
| final Block body; |
| |
| SwitchClause(this.body); |
| } |
| |
| class Case extends SwitchClause { |
| final Expression expression; |
| |
| Case(this.expression, Block body) : super(body); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitCase(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitCase(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| expression.accept(visitor); |
| body.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| expression.accept1(visitor, arg); |
| body.accept1(visitor, arg); |
| } |
| |
| Case _clone() => Case(expression, body); |
| } |
| |
| class Default extends SwitchClause { |
| Default(Block body) : super(body); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitDefault(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitDefault(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| body.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| body.accept1(visitor, arg); |
| } |
| |
| Default _clone() => Default(body); |
| } |
| |
| class FunctionDeclaration extends Statement { |
| final Declaration name; |
| final Fun function; |
| |
| FunctionDeclaration(this.name, this.function); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitFunctionDeclaration(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitFunctionDeclaration(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| name.accept(visitor); |
| function.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| name.accept1(visitor, arg); |
| function.accept1(visitor, arg); |
| } |
| |
| FunctionDeclaration _clone() => FunctionDeclaration(name, function); |
| } |
| |
| class LabeledStatement extends Statement { |
| final String label; |
| final Statement body; |
| |
| LabeledStatement(this.label, this.body); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitLabeledStatement(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitLabeledStatement(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| body.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| body.accept1(visitor, arg); |
| } |
| |
| LabeledStatement _clone() => LabeledStatement(label, body); |
| } |
| |
| class LiteralStatement extends Statement { |
| final String code; |
| |
| LiteralStatement(this.code); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralStatement(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitLiteralStatement(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) {} |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {} |
| |
| LiteralStatement _clone() => LiteralStatement(code); |
| } |
| |
| // Not a real JavaScript node, but represents the yield statement from a dart |
| // program translated to JavaScript. |
| class DartYield extends Statement { |
| final Expression expression; |
| |
| final bool hasStar; |
| |
| DartYield(this.expression, this.hasStar); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitDartYield(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitDartYield(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| expression.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| expression.accept1(visitor, arg); |
| } |
| |
| DartYield _clone() => DartYield(expression, hasStar); |
| } |
| |
| abstract class Expression extends Node { |
| // [precedenceLevel] must not be used before printing, as deferred nodes can |
| // have precedence depending on how the deferred node is resolved. |
| int get precedenceLevel; |
| |
| Statement toStatement() => ExpressionStatement(this); |
| } |
| |
| abstract class Declaration implements VariableReference {} |
| |
| /// [Name] is an extension point to allow a JavaScript AST to contain |
| /// identifiers that are bound later. This is used in minification. |
| /// |
| /// [Name] is a [Literal] so that it can occur as a property access selector. |
| // |
| // TODO(sra): Figure out why [Name] is a Declaration and Parameter, and where |
| // that is used. How should the printer know if an occurrence of a Name is meant |
| // to be a Literal or a Declaration (which includes a VariableUse)? |
| abstract class Name extends Literal implements Declaration, Parameter { |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitName(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitName(this, arg); |
| |
| Name _clone(); |
| |
| /// Returns the text of this name. |
| /// |
| /// May throw if the text has not been decided. Typically the text is decided |
| /// in some finalization phase that happens before the AST is printed. |
| String get name; |
| |
| /// Returns a unique [key] for this name. |
| /// |
| /// The key is unrelated to the actual name and is not intended for human |
| /// consumption. As such, it might be long or cryptic. |
| String get key; |
| |
| bool get allowRename => false; |
| } |
| |
| class LiteralStringFromName extends LiteralString { |
| final Name name; |
| |
| LiteralStringFromName(this.name) : super(null) { |
| ArgumentError.checkNotNull(name, 'name'); |
| } |
| |
| @override |
| bool get isFinalized => name.isFinalized; |
| |
| @override |
| String get value => name.name; |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| name.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| name.accept1(visitor, arg); |
| } |
| } |
| |
| class LiteralExpression extends Expression { |
| final String template; |
| LiteralExpression(this.template); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralExpression(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitLiteralExpression(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) {} |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {} |
| |
| LiteralExpression _clone() => LiteralExpression(template); |
| |
| // Code that uses LiteralExpression must take care of operator precedences, |
| // and put parenthesis if needed. |
| int get precedenceLevel => PRIMARY; |
| } |
| |
| /// [VariableDeclarationList] is a subclass of [Expression] to simplify the |
| /// AST. |
| class VariableDeclarationList extends Expression { |
| final List<VariableInitialization> declarations; |
| |
| /// When pretty-printing a declaration list with multiple declarations over |
| /// several lines, the declarations are usually indented with respect to the |
| /// `var` keyword. Set [indentSplits] to `false` to suppress the indentation. |
| final bool indentSplits; |
| |
| VariableDeclarationList(this.declarations, {this.indentSplits = true}); |
| |
| T accept<T>(NodeVisitor<T> visitor) => |
| visitor.visitVariableDeclarationList(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitVariableDeclarationList(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| for (VariableInitialization declaration in declarations) { |
| declaration.accept(visitor); |
| } |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| for (VariableInitialization declaration in declarations) { |
| declaration.accept1(visitor, arg); |
| } |
| } |
| |
| VariableDeclarationList _clone() => VariableDeclarationList(declarations); |
| |
| int get precedenceLevel => EXPRESSION; |
| } |
| |
| /// Forced parenthesized expression. Pretty-printing will emit parentheses based |
| /// on need, so this node is very rarely needed. |
| class Parentheses extends Expression { |
| final Expression enclosed; |
| |
| Parentheses(this.enclosed); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitParentheses(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitParentheses(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| enclosed.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| enclosed.accept1(visitor, arg); |
| } |
| |
| Parentheses _clone() => Parentheses(enclosed); |
| |
| int get precedenceLevel => PRIMARY; |
| } |
| |
| class Assignment extends Expression { |
| final Expression leftHandSide; |
| final String op; // Null, if the assignment is not compound. |
| final Expression 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) |
| : assert(value != null); |
| |
| int get precedenceLevel => ASSIGNMENT; |
| |
| bool get isCompound => op != null; |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitAssignment(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitAssignment(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| leftHandSide.accept(visitor); |
| value.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| leftHandSide.accept1(visitor, arg); |
| value.accept1(visitor, arg); |
| } |
| |
| Assignment _clone() => Assignment.compound(leftHandSide, op, value); |
| } |
| |
| class VariableInitialization extends Expression { |
| // TODO(sra): Can [VariableInitialization] be a non-expression? |
| |
| final Declaration declaration; |
| final Expression value; // [value] may be null. |
| |
| VariableInitialization(this.declaration, this.value); |
| |
| int get precedenceLevel => ASSIGNMENT; |
| |
| T accept<T>(NodeVisitor<T> visitor) => |
| visitor.visitVariableInitialization(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitVariableInitialization(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| declaration.accept(visitor); |
| value?.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| declaration.accept1(visitor, arg); |
| value?.accept1(visitor, arg); |
| } |
| |
| VariableInitialization _clone() => VariableInitialization(declaration, value); |
| } |
| |
| class Conditional extends Expression { |
| final Expression condition; |
| final Expression then; |
| final Expression otherwise; |
| |
| Conditional(this.condition, this.then, this.otherwise); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitConditional(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitConditional(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| condition.accept(visitor); |
| then.accept(visitor); |
| otherwise.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| condition.accept1(visitor, arg); |
| then.accept1(visitor, arg); |
| otherwise.accept1(visitor, arg); |
| } |
| |
| Conditional _clone() => Conditional(condition, then, otherwise); |
| |
| int get precedenceLevel => ASSIGNMENT; |
| } |
| |
| class Call extends Expression { |
| Expression target; |
| List<Expression> arguments; |
| |
| Call(this.target, this.arguments, |
| {JavaScriptNodeSourceInformation sourceInformation}) { |
| this._sourceInformation = sourceInformation; |
| } |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitCall(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitCall(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| target.accept(visitor); |
| for (Expression arg in arguments) { |
| arg.accept(visitor); |
| } |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| target.accept1(visitor, arg); |
| for (Expression arg in arguments) { |
| arg.accept1(visitor, arg); |
| } |
| } |
| |
| Call _clone() => Call(target, arguments); |
| |
| int get precedenceLevel => CALL; |
| } |
| |
| class New extends Call { |
| New(Expression cls, List<Expression> arguments) : super(cls, arguments); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitNew(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitNew(this, arg); |
| |
| New _clone() => New(target, arguments); |
| } |
| |
| class Binary extends Expression { |
| final String op; |
| final Expression left; |
| final Expression right; |
| |
| Binary(this.op, this.left, this.right); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitBinary(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitBinary(this, arg); |
| |
| Binary _clone() => Binary(op, left, right); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| left.accept(visitor); |
| right.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| left.accept1(visitor, arg); |
| right.accept1(visitor, arg); |
| } |
| |
| bool get isCommaOperator => op == ','; |
| |
| int get precedenceLevel { |
| // TODO(floitsch): switch to constant map. |
| switch (op) { |
| case "*": |
| case "/": |
| case "%": |
| return MULTIPLICATIVE; |
| case "+": |
| case "-": |
| return ADDITIVE; |
| case "<<": |
| case ">>": |
| case ">>>": |
| return SHIFT; |
| case "<": |
| case ">": |
| case "<=": |
| case ">=": |
| case "instanceof": |
| case "in": |
| return RELATIONAL; |
| case "==": |
| case "===": |
| case "!=": |
| case "!==": |
| return EQUALITY; |
| case "&": |
| return BIT_AND; |
| case "^": |
| return BIT_XOR; |
| case "|": |
| return BIT_OR; |
| case "&&": |
| return LOGICAL_AND; |
| case "||": |
| return LOGICAL_OR; |
| case ',': |
| return EXPRESSION; |
| default: |
| throw "Internal Error: Unhandled binary operator: $op"; |
| } |
| } |
| } |
| |
| class Prefix extends Expression { |
| final String op; |
| final Expression argument; |
| |
| Prefix(this.op, this.argument); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitPrefix(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitPrefix(this, arg); |
| |
| Prefix _clone() => Prefix(op, argument); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| argument.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| argument.accept1(visitor, arg); |
| } |
| |
| int get precedenceLevel => UNARY; |
| } |
| |
| class Postfix extends Expression { |
| final String op; |
| final Expression argument; |
| |
| Postfix(this.op, this.argument); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitPostfix(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitPostfix(this, arg); |
| |
| Postfix _clone() => Postfix(op, argument); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| argument.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| argument.accept1(visitor, arg); |
| } |
| |
| int get precedenceLevel => UNARY; |
| } |
| |
| RegExp _identifierRE = RegExp(r'^[A-Za-z_$][A-Za-z_$0-9]*$'); |
| |
| abstract class VariableReference extends Expression { |
| final String name; |
| |
| VariableReference(this.name) { |
| assert(_identifierRE.hasMatch(name), "Non-identifier name '$name'"); |
| } |
| |
| T accept<T>(NodeVisitor<T> visitor); |
| |
| int get precedenceLevel => PRIMARY; |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) {} |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {} |
| } |
| |
| class VariableUse extends VariableReference { |
| VariableUse(String name) : super(name); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitVariableUse(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitVariableUse(this, arg); |
| |
| VariableUse _clone() => VariableUse(name); |
| |
| String toString() => 'VariableUse($name)'; |
| } |
| |
| class VariableDeclaration extends VariableReference implements Declaration { |
| final bool allowRename; |
| |
| VariableDeclaration(String name, {this.allowRename = true}) : super(name); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitVariableDeclaration(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitVariableDeclaration(this, arg); |
| |
| VariableDeclaration _clone() => VariableDeclaration(name); |
| } |
| |
| class Parameter extends VariableDeclaration { |
| Parameter(String name) : super(name); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitParameter(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitParameter(this, arg); |
| |
| Parameter _clone() => Parameter(name); |
| } |
| |
| class This extends Parameter { |
| This() : super("this"); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitThis(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitThis(this, arg); |
| |
| This _clone() => This(); |
| } |
| |
| class NamedFunction extends Expression { |
| final Declaration name; |
| final Fun function; |
| |
| NamedFunction(this.name, this.function); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitNamedFunction(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitNamedFunction(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| name.accept(visitor); |
| function.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| name.accept1(visitor, arg); |
| function.accept1(visitor, arg); |
| } |
| |
| NamedFunction _clone() => NamedFunction(name, function); |
| |
| int get precedenceLevel => LEFT_HAND_SIDE; |
| } |
| |
| abstract class FunctionExpression extends Expression { |
| Node body; |
| List<Parameter> params; |
| AsyncModifier asyncModifier; |
| } |
| |
| class Fun extends FunctionExpression { |
| @override |
| final Block body; |
| @override |
| final List<Parameter> params; |
| @override |
| final AsyncModifier asyncModifier; |
| |
| Fun(this.params, this.body, {this.asyncModifier = AsyncModifier.sync}); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitFun(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitFun(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| for (Parameter param in params) param.accept(visitor); |
| body.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| for (Parameter param in params) param.accept1(visitor, arg); |
| body.accept1(visitor, arg); |
| } |
| |
| Fun _clone() => Fun(params, body, asyncModifier: asyncModifier); |
| |
| int get precedenceLevel => LEFT_HAND_SIDE; |
| } |
| |
| class ArrowFunction extends FunctionExpression { |
| @override |
| final Node body; |
| @override |
| final List<Parameter> params; |
| @override |
| final AsyncModifier asyncModifier; |
| |
| /// Indicates whether it is permissible to try to emit this arrow function |
| /// in a form with an implicit 'return'. |
| final bool implicitReturnAllowed; |
| |
| ArrowFunction(this.params, this.body, |
| {this.asyncModifier = AsyncModifier.sync, |
| this.implicitReturnAllowed = true}); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitArrowFunction(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitArrowFunction(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| for (Parameter param in params) param.accept(visitor); |
| body.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| for (Parameter param in params) param.accept1(visitor, arg); |
| body.accept1(visitor, arg); |
| } |
| |
| ArrowFunction _clone() => ArrowFunction(params, body, |
| asyncModifier: asyncModifier, |
| implicitReturnAllowed: implicitReturnAllowed); |
| |
| int get precedenceLevel => ASSIGNMENT; |
| } |
| |
| class AsyncModifier { |
| final int index; |
| final bool isAsync; |
| final bool isYielding; |
| final String description; |
| |
| const AsyncModifier(this.index, this.description, |
| {this.isAsync, this.isYielding}); |
| |
| static const AsyncModifier sync = |
| AsyncModifier(0, "sync", isAsync: false, isYielding: false); |
| static const AsyncModifier async = |
| AsyncModifier(1, "async", isAsync: true, isYielding: false); |
| static const AsyncModifier asyncStar = |
| AsyncModifier(2, "async*", isAsync: true, isYielding: true); |
| static const AsyncModifier syncStar = |
| AsyncModifier(3, "sync*", isAsync: false, isYielding: true); |
| |
| static const List<AsyncModifier> values = [sync, async, asyncStar, syncStar]; |
| |
| String toString() => description; |
| } |
| |
| class PropertyAccess extends Expression { |
| final Expression receiver; |
| final Expression selector; |
| |
| PropertyAccess(this.receiver, this.selector); |
| |
| PropertyAccess.field(this.receiver, String fieldName) |
| : selector = LiteralString(fieldName); |
| |
| PropertyAccess.indexed(this.receiver, int index) |
| : selector = LiteralNumber('$index'); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitAccess(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitAccess(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| receiver.accept(visitor); |
| selector.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| receiver.accept1(visitor, arg); |
| selector.accept1(visitor, arg); |
| } |
| |
| PropertyAccess _clone() => PropertyAccess(receiver, selector); |
| |
| int get precedenceLevel => LEFT_HAND_SIDE; |
| } |
| |
| /// 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<T>(NodeVisitor<T> visitor) {} |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {} |
| |
| DeferredToken _clone() => this; |
| } |
| |
| /// Interface 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 { |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitDeferredNumber(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitDeferredNumber(this, arg); |
| |
| int get value; |
| |
| int get precedenceLevel => value.isNegative ? UNARY : PRIMARY; |
| } |
| |
| /// Interface 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 { |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitDeferredString(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitDeferredString(this, arg); |
| |
| String get value; |
| |
| int get precedenceLevel => PRIMARY; |
| } |
| |
| /// Interface 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 { |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitDeferredExpression(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitDeferredExpression(this, arg); |
| |
| Expression get value; |
| } |
| |
| abstract class Literal extends Expression { |
| void visitChildren<T>(NodeVisitor<T> visitor) {} |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {} |
| |
| int get precedenceLevel => PRIMARY; |
| } |
| |
| class LiteralBool extends Literal { |
| final bool value; |
| |
| LiteralBool(this.value); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralBool(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitLiteralBool(this, arg); |
| |
| // [visitChildren] inherited from [Literal]. |
| |
| LiteralBool _clone() => LiteralBool(value); |
| } |
| |
| class LiteralNull extends Literal { |
| LiteralNull(); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralNull(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitLiteralNull(this, arg); |
| |
| LiteralNull _clone() => LiteralNull(); |
| } |
| |
| class LiteralString extends Literal { |
| final String value; |
| |
| /// Constructs a LiteralString for a string containing the characters of |
| /// `value`. |
| /// |
| /// When printed, the string will be escaped and quoted according to the |
| /// printer's settings. |
| LiteralString(this.value); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralString(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitLiteralString(this, arg); |
| |
| LiteralString _clone() => LiteralString(value); |
| |
| @override |
| String toString() { |
| final sb = StringBuffer('$runtimeType("'); |
| String end = '"'; |
| int count = 0; |
| for (int rune in value.runes) { |
| if (++count > 20) { |
| end = '"...'; |
| break; |
| } |
| if (32 <= rune && rune < 127) { |
| sb.writeCharCode(rune); |
| } else { |
| sb.write(r'\u{'); |
| sb.write(rune.toRadixString(16)); |
| sb.write(r'}'); |
| } |
| } |
| sb.write(end); |
| sb.write(')'); |
| return sb.toString(); |
| } |
| } |
| |
| 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); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitStringConcatenation(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitStringConcatenation(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| for (Literal part in parts) part.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| for (Literal part in parts) part.accept1(visitor, arg); |
| } |
| |
| StringConcatenation _clone() => StringConcatenation(this.parts); |
| } |
| |
| class LiteralNumber extends Literal { |
| final String value; // Must be a valid JavaScript number literal. |
| |
| LiteralNumber(this.value); |
| |
| int get precedenceLevel => value.startsWith('-') ? UNARY : PRIMARY; |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralNumber(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitLiteralNumber(this, arg); |
| |
| LiteralNumber _clone() => LiteralNumber(value); |
| } |
| |
| class ArrayInitializer extends Expression { |
| final List<Expression> elements; |
| |
| ArrayInitializer(this.elements) : assert(!elements.contains(null)); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitArrayInitializer(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitArrayInitializer(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| for (Expression element in elements) element.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| for (Expression element in elements) element.accept1(visitor, arg); |
| } |
| |
| ArrayInitializer _clone() => ArrayInitializer(elements); |
| |
| int get precedenceLevel => PRIMARY; |
| } |
| |
| /// An empty place in an [ArrayInitializer]. |
| /// For example the list [1, , , 2] would contain two holes. |
| class ArrayHole extends Expression { |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitArrayHole(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitArrayHole(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) {} |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {} |
| |
| ArrayHole _clone() => ArrayHole(); |
| |
| int get precedenceLevel => PRIMARY; |
| } |
| |
| class ObjectInitializer extends Expression { |
| final List<Property> properties; |
| final bool isOneLiner; |
| |
| /// Constructs a new object-initializer containing the given [properties]. |
| /// |
| /// [isOneLiner] describes the behaviour when pretty-printing (non-minified). |
| /// If true print all properties on the same line. |
| /// If false print each property on a seperate line. |
| ObjectInitializer(this.properties, {this.isOneLiner = true}); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitObjectInitializer(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitObjectInitializer(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| for (Property init in properties) init.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| for (Property init in properties) init.accept1(visitor, arg); |
| } |
| |
| ObjectInitializer _clone() => |
| ObjectInitializer(properties, isOneLiner: isOneLiner); |
| |
| int get precedenceLevel => PRIMARY; |
| } |
| |
| class Property extends Node { |
| final Expression name; |
| final Expression value; |
| |
| Property(this.name, this.value) |
| : assert(name is Literal || name is DeferredExpression); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitProperty(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitProperty(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| name.accept(visitor); |
| value.accept(visitor); |
| } |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| name.accept1(visitor, arg); |
| value.accept1(visitor, arg); |
| } |
| |
| Property _clone() => Property(name, value); |
| } |
| |
| class MethodDefinition extends Node implements Property { |
| @override |
| final Expression name; |
| final Fun function; |
| |
| MethodDefinition(this.name, this.function); |
| |
| @override |
| Fun get value => function; |
| |
| @override |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitMethodDefinition(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitMethodDefinition(this, arg); |
| |
| @override |
| void visitChildren<T>(NodeVisitor<T> visitor) { |
| name.accept(visitor); |
| function.accept(visitor); |
| } |
| |
| @override |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) { |
| name.accept1(visitor, arg); |
| function.accept1(visitor, arg); |
| } |
| |
| @override |
| MethodDefinition _clone() => MethodDefinition(name, function); |
| } |
| |
| /// Tag class for all interpolated positions. |
| abstract class InterpolatedNode implements Node { |
| get nameOrPosition; |
| |
| bool get isNamed => nameOrPosition is String; |
| |
| bool get isPositional => nameOrPosition is int; |
| } |
| |
| class InterpolatedExpression extends Expression with InterpolatedNode { |
| final nameOrPosition; |
| |
| InterpolatedExpression(this.nameOrPosition); |
| |
| T accept<T>(NodeVisitor<T> visitor) => |
| visitor.visitInterpolatedExpression(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitInterpolatedExpression(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) {} |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {} |
| |
| InterpolatedExpression _clone() => InterpolatedExpression(nameOrPosition); |
| |
| int get precedenceLevel => PRIMARY; |
| } |
| |
| class InterpolatedLiteral extends Literal with InterpolatedNode { |
| final nameOrPosition; |
| |
| InterpolatedLiteral(this.nameOrPosition); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitInterpolatedLiteral(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitInterpolatedLiteral(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) {} |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {} |
| |
| InterpolatedLiteral _clone() => InterpolatedLiteral(nameOrPosition); |
| } |
| |
| class InterpolatedParameter extends Expression |
| with InterpolatedNode |
| implements Parameter { |
| final nameOrPosition; |
| |
| InterpolatedParameter(this.nameOrPosition); |
| |
| String get name { |
| throw "InterpolatedParameter.name must not be invoked"; |
| } |
| |
| bool get allowRename => false; |
| |
| T accept<T>(NodeVisitor<T> visitor) => |
| visitor.visitInterpolatedParameter(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitInterpolatedParameter(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) {} |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {} |
| |
| InterpolatedParameter _clone() => InterpolatedParameter(nameOrPosition); |
| |
| int get precedenceLevel => PRIMARY; |
| } |
| |
| class InterpolatedSelector extends Expression with InterpolatedNode { |
| final nameOrPosition; |
| |
| InterpolatedSelector(this.nameOrPosition); |
| |
| T accept<T>(NodeVisitor<T> visitor) => |
| visitor.visitInterpolatedSelector(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitInterpolatedSelector(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) {} |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {} |
| |
| InterpolatedSelector _clone() => InterpolatedSelector(nameOrPosition); |
| |
| int get precedenceLevel => PRIMARY; |
| } |
| |
| class InterpolatedStatement extends Statement with InterpolatedNode { |
| final nameOrPosition; |
| |
| InterpolatedStatement(this.nameOrPosition); |
| |
| T accept<T>(NodeVisitor<T> visitor) => |
| visitor.visitInterpolatedStatement(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitInterpolatedStatement(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) {} |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {} |
| |
| InterpolatedStatement _clone() => InterpolatedStatement(nameOrPosition); |
| } |
| |
| class InterpolatedDeclaration extends Expression |
| with InterpolatedNode |
| implements Declaration { |
| final nameOrPosition; |
| |
| InterpolatedDeclaration(this.nameOrPosition); |
| |
| T accept<T>(NodeVisitor<T> visitor) => |
| visitor.visitInterpolatedDeclaration(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitInterpolatedDeclaration(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) {} |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {} |
| |
| InterpolatedDeclaration _clone() { |
| return InterpolatedDeclaration(nameOrPosition); |
| } |
| |
| @override |
| String get name => throw "No name for the interpolated node"; |
| |
| @override |
| int get precedenceLevel => PRIMARY; |
| } |
| |
| /// [RegExpLiteral]s, despite being called "Literal", do not inherit from |
| /// [Literal]. Indeed, regular expressions in JavaScript have a side-effect and |
| /// are thus not in the same category as numbers or strings. |
| class RegExpLiteral extends Expression { |
| /// Contains the pattern and the flags. |
| final String pattern; |
| |
| RegExpLiteral(this.pattern); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitRegExpLiteral(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitRegExpLiteral(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) {} |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {} |
| |
| RegExpLiteral _clone() => RegExpLiteral(pattern); |
| |
| int get precedenceLevel => PRIMARY; |
| } |
| |
| /// An asynchronous await. |
| /// |
| /// Not part of JavaScript. We desugar this expression before outputting. |
| /// Should only occur in a [Fun] with `asyncModifier` async or asyncStar. |
| class Await extends Expression { |
| /// The awaited expression. |
| final Expression expression; |
| |
| Await(this.expression); |
| |
| int get precedenceLevel => UNARY; |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitAwait(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitAwait(this, arg); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) => expression.accept(visitor); |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| expression.accept1(visitor, arg); |
| |
| Await _clone() => Await(expression); |
| } |
| |
| /// A comment. |
| /// |
| /// Extends [Statement] so we can add comments before statements in |
| /// [Block] and [Program]. |
| class Comment extends Statement { |
| final String comment; |
| |
| Comment(this.comment); |
| |
| T accept<T>(NodeVisitor<T> visitor) => visitor.visitComment(this); |
| |
| R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) => |
| visitor.visitComment(this, arg); |
| |
| Comment _clone() => Comment(comment); |
| |
| void visitChildren<T>(NodeVisitor<T> visitor) {} |
| |
| void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {} |
| } |
| |
| /// Returns the value of [node] if it is a [DeferredExpression]. Otherwise |
| /// returns the [node] itself. |
| Node undefer(Node node) { |
| return node is DeferredExpression ? undefer(node.value) : node; |
| } |