| Index: lib/src/js/nodes.dart
|
| diff --git a/lib/src/js/nodes.dart b/lib/src/js/nodes.dart
|
| deleted file mode 100644
|
| index cd0e807a9542a3cf4c5cb13da93722b2f49473a4..0000000000000000000000000000000000000000
|
| --- a/lib/src/js/nodes.dart
|
| +++ /dev/null
|
| @@ -1,1838 +0,0 @@
|
| -// 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> implements TypeRefVisitor<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 visitForOf(ForOf 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 visitSpread(Spread node);
|
| - T visitYield(Yield node);
|
| -
|
| - T visitIdentifier(Identifier node);
|
| - T visitThis(This node);
|
| - T visitSuper(Super node);
|
| - T visitAccess(PropertyAccess node);
|
| - T visitRestParameter(RestParameter node);
|
| -
|
| - T visitNamedFunction(NamedFunction node);
|
| - T visitFun(Fun node);
|
| - T visitArrowFun(ArrowFun node);
|
| -
|
| - T visitLiteralBool(LiteralBool node);
|
| - T visitLiteralString(LiteralString node);
|
| - T visitLiteralNumber(LiteralNumber node);
|
| - T visitLiteralNull(LiteralNull node);
|
| -
|
| - T visitArrayInitializer(ArrayInitializer node);
|
| - T visitArrayHole(ArrayHole node);
|
| - T visitObjectInitializer(ObjectInitializer node);
|
| - T visitProperty(Property node);
|
| - T visitRegExpLiteral(RegExpLiteral node);
|
| - T visitTemplateString(TemplateString node);
|
| - T visitTaggedTemplate(TaggedTemplate node);
|
| -
|
| - T visitAwait(Await node);
|
| -
|
| - T visitClassDeclaration(ClassDeclaration node);
|
| - T visitClassExpression(ClassExpression node);
|
| - T visitMethod(Method node);
|
| -
|
| - T visitImportDeclaration(ImportDeclaration node);
|
| - T visitExportDeclaration(ExportDeclaration node);
|
| - T visitExportClause(ExportClause node);
|
| - T visitNameSpecifier(NameSpecifier node);
|
| - T visitModule(Module node);
|
| -
|
| - T visitComment(Comment node);
|
| - T visitCommentExpression(CommentExpression node);
|
| -
|
| - T visitInterpolatedExpression(InterpolatedExpression node);
|
| - T visitInterpolatedLiteral(InterpolatedLiteral node);
|
| - T visitInterpolatedParameter(InterpolatedParameter node);
|
| - T visitInterpolatedSelector(InterpolatedSelector node);
|
| - T visitInterpolatedStatement(InterpolatedStatement node);
|
| - T visitInterpolatedMethod(InterpolatedMethod node);
|
| - T visitInterpolatedIdentifier(InterpolatedIdentifier node);
|
| -
|
| - T visitArrayBindingPattern(ArrayBindingPattern node);
|
| - T visitObjectBindingPattern(ObjectBindingPattern node);
|
| - T visitDestructuredVariable(DestructuredVariable node);
|
| - T visitSimpleBindingPattern(SimpleBindingPattern node);
|
| -}
|
| -
|
| -abstract class TypeRefVisitor<T> {
|
| - T visitQualifiedTypeRef(QualifiedTypeRef node);
|
| - T visitGenericTypeRef(GenericTypeRef node);
|
| - T visitUnionTypeRef(UnionTypeRef node);
|
| - T visitRecordTypeRef(RecordTypeRef node);
|
| - T visitOptionalTypeRef(OptionalTypeRef node);
|
| - T visitFunctionTypeRef(FunctionTypeRef node);
|
| - T visitAnyTypeRef(AnyTypeRef node);
|
| - T visitUnknownTypeRef(UnknownTypeRef node);
|
| - T visitArrayTypeRef(ArrayTypeRef node);
|
| -}
|
| -
|
| -class BaseVisitor<T> implements NodeVisitor<T> {
|
| - T visitNode(Node node) {
|
| - node.visitChildren(this);
|
| - return null;
|
| - }
|
| -
|
| - T visitProgram(Program node) => visitNode(node);
|
| -
|
| - T visitStatement(Statement node) => visitModuleItem(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 visitForOf(ForOf 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 visitLiteralExpression(LiteralExpression node) => visitExpression(node);
|
| - T visitVariableDeclarationList(VariableDeclarationList node)
|
| - => visitExpression(node);
|
| - T visitAssignment(Assignment node) => visitExpression(node);
|
| - T visitVariableInitialization(VariableInitialization node) {
|
| - if (node.value != null) {
|
| - return visitAssignment(node);
|
| - } else {
|
| - return 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 visitSpread(Spread node) => visitPrefix(node);
|
| - T visitYield(Yield node) => visitExpression(node);
|
| - T visitAccess(PropertyAccess node) => visitExpression(node);
|
| -
|
| - T visitIdentifier(Identifier node) => visitExpression(node);
|
| - T visitThis(This node) => visitExpression(node);
|
| - T visitSuper(Super node) => visitExpression(node);
|
| -
|
| - T visitRestParameter(RestParameter node) => visitNode(node);
|
| -
|
| - T visitNamedFunction(NamedFunction node) => visitExpression(node);
|
| - T visitFunctionExpression(FunctionExpression node) => visitExpression(node);
|
| - T visitFun(Fun node) => visitFunctionExpression(node);
|
| - T visitArrowFun(ArrowFun node) => visitFunctionExpression(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 visitArrayInitializer(ArrayInitializer node) => visitExpression(node);
|
| - T visitArrayHole(ArrayHole node) => visitExpression(node);
|
| - T visitObjectInitializer(ObjectInitializer node) => visitExpression(node);
|
| - T visitProperty(Property node) => visitNode(node);
|
| - T visitRegExpLiteral(RegExpLiteral node) => visitExpression(node);
|
| - T visitTemplateString(TemplateString node) => visitExpression(node);
|
| - T visitTaggedTemplate(TaggedTemplate node) => visitExpression(node);
|
| -
|
| - T visitClassDeclaration(ClassDeclaration node) => visitStatement(node);
|
| - T visitClassExpression(ClassExpression node) => visitExpression(node);
|
| - T visitMethod(Method node) => visitProperty(node);
|
| -
|
| - T visitModuleItem(ModuleItem node) => visitNode(node);
|
| - T visitImportDeclaration(ImportDeclaration node) => visitModuleItem(node);
|
| - T visitExportDeclaration(ExportDeclaration node) => visitModuleItem(node);
|
| - T visitExportClause(ExportClause node) => visitNode(node);
|
| - T visitNameSpecifier(NameSpecifier node) => visitNode(node);
|
| - T visitModule(Module node) => visitNode(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 visitInterpolatedMethod(InterpolatedMethod node)
|
| - => visitInterpolatedNode(node);
|
| - T visitInterpolatedIdentifier(InterpolatedIdentifier node)
|
| - => visitInterpolatedNode(node);
|
| -
|
| - // Ignore comments by default.
|
| - T visitComment(Comment node) => null;
|
| - T visitCommentExpression(CommentExpression node) => null;
|
| -
|
| - T visitAwait(Await node) => visitExpression(node);
|
| - T visitDartYield(DartYield node) => visitStatement(node);
|
| -
|
| - T visitBindingPattern(BindingPattern node) => visitNode(node);
|
| - T visitArrayBindingPattern(ArrayBindingPattern node)
|
| - => visitBindingPattern(node);
|
| - T visitObjectBindingPattern(ObjectBindingPattern node)
|
| - => visitBindingPattern(node);
|
| - T visitDestructuredVariable(DestructuredVariable node) => visitNode(node);
|
| - T visitSimpleBindingPattern(SimpleBindingPattern node) => visitNode(node);
|
| -
|
| - T visitTypeRef(TypeRef node) => visitNode(node);
|
| - T visitQualifiedTypeRef(QualifiedTypeRef node) => visitTypeRef(node);
|
| - T visitGenericTypeRef(GenericTypeRef node) => visitTypeRef(node);
|
| - T visitOptionalTypeRef(OptionalTypeRef node) => visitTypeRef(node);
|
| - T visitRecordTypeRef(RecordTypeRef node) => visitTypeRef(node);
|
| - T visitUnionTypeRef(UnionTypeRef node) => visitTypeRef(node);
|
| - T visitFunctionTypeRef(FunctionTypeRef node) => visitTypeRef(node);
|
| - T visitAnyTypeRef(AnyTypeRef node) => visitTypeRef(node);
|
| - T visitUnknownTypeRef(UnknownTypeRef node) => visitTypeRef(node);
|
| - T visitArrayTypeRef(ArrayTypeRef node) => visitTypeRef(node);
|
| -}
|
| -
|
| -abstract class Node {
|
| - /// Sets the source location of this node. For performance reasons, we allow
|
| - /// setting this after construction.
|
| - Object sourceInformation;
|
| -
|
| - ClosureAnnotation _closureAnnotation;
|
| - /// Closure annotation of this node.
|
| - ClosureAnnotation get closureAnnotation => _closureAnnotation;
|
| -
|
| - accept(NodeVisitor visitor);
|
| - void visitChildren(NodeVisitor visitor);
|
| -
|
| - // 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();
|
| -
|
| - withClosureAnnotation(ClosureAnnotation closureAnnotation) {
|
| - if (this.closureAnnotation == closureAnnotation) return this;
|
| -
|
| - return _clone()
|
| - ..sourceInformation = sourceInformation
|
| - .._closureAnnotation = closureAnnotation;
|
| - }
|
| - // Returns a node equivalent to [this], but with new source position and end
|
| - // source position.
|
| - Node withSourceInformation(sourceInformation) {
|
| - if (sourceInformation == this.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 new UnsupportedError('toStatement');
|
| - }
|
| - Statement toReturn() {
|
| - throw new UnsupportedError('toReturn');
|
| - }
|
| -
|
| - // For debugging
|
| - String toString() {
|
| - var context = new SimpleJavaScriptPrintingContext();
|
| - var opts = new JavaScriptPrintingOptions(allowKeywordsInProperties: true);
|
| - context.buffer.write('js_ast `');
|
| - accept(new Printer(opts, context));
|
| - context.buffer.write('`');
|
| - return context.getText();
|
| - }
|
| -}
|
| -
|
| -class Program extends Node {
|
| - /// Script tag hash-bang, e.g. `#!/usr/bin/env node`
|
| - final String scriptTag;
|
| -
|
| - /// Top-level statements in the program.
|
| - final List<ModuleItem> body;
|
| -
|
| - Program(this.body, {this.scriptTag});
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitProgram(this);
|
| - void visitChildren(NodeVisitor visitor) {
|
| - for (ModuleItem statement in body) statement.accept(visitor);
|
| - }
|
| - Program _clone() => new Program(body);
|
| -}
|
| -
|
| -abstract class Statement extends ModuleItem {
|
| - Statement toStatement() => this;
|
| - Statement toReturn() => new Block([this, new Return()]);
|
| -}
|
| -
|
| -class Block extends Statement {
|
| - final List<Statement> statements;
|
| -
|
| - /// True to preserve this [Block] for scoping reasons.
|
| - final bool isScope;
|
| -
|
| - Block(this.statements, {this.isScope: false}) {
|
| - assert(!statements.any((s) => s is! Statement));
|
| - }
|
| - Block.empty() : statements = <Statement>[], isScope = false;
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitBlock(this);
|
| - void visitChildren(NodeVisitor visitor) {
|
| - for (Statement statement in statements) statement.accept(visitor);
|
| - }
|
| - Block _clone() => new Block(statements);
|
| -}
|
| -
|
| -class ExpressionStatement extends Statement {
|
| - final Expression expression;
|
| - ExpressionStatement(this.expression);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitExpressionStatement(this);
|
| - void visitChildren(NodeVisitor visitor) { expression.accept(visitor); }
|
| - ExpressionStatement _clone() => new ExpressionStatement(expression);
|
| -}
|
| -
|
| -class EmptyStatement extends Statement {
|
| - EmptyStatement();
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitEmptyStatement(this);
|
| - void visitChildren(NodeVisitor visitor) {}
|
| - EmptyStatement _clone() => new EmptyStatement();
|
| -}
|
| -
|
| -class If extends Statement {
|
| - final Expression condition;
|
| - final Node then;
|
| - final Node otherwise;
|
| -
|
| - If(this.condition, this.then, this.otherwise);
|
| - If.noElse(this.condition, this.then) : this.otherwise = null;
|
| -
|
| - bool get hasElse => otherwise != null;
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitIf(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - condition.accept(visitor);
|
| - then.accept(visitor);
|
| - if (otherwise != null) otherwise.accept(visitor);
|
| - }
|
| -
|
| - If _clone() => new 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);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitFor(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - if (init != null) init.accept(visitor);
|
| - if (condition != null) condition.accept(visitor);
|
| - if (update != null) update.accept(visitor);
|
| - body.accept(visitor);
|
| - }
|
| -
|
| - For _clone() => new 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);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitForIn(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - leftHandSide.accept(visitor);
|
| - object.accept(visitor);
|
| - body.accept(visitor);
|
| - }
|
| -
|
| - ForIn _clone() => new ForIn(leftHandSide, object, body);
|
| -}
|
| -
|
| -class ForOf extends Loop {
|
| - // Note that [VariableDeclarationList] is a subclass of [Expression].
|
| - // Therefore we can type the leftHandSide as [Expression].
|
| - final Expression leftHandSide;
|
| - final Expression iterable;
|
| -
|
| - ForOf(this.leftHandSide, this.iterable, Statement body) : super(body);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitForOf(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - leftHandSide.accept(visitor);
|
| - iterable.accept(visitor);
|
| - body.accept(visitor);
|
| - }
|
| -
|
| - ForIn _clone() => new ForIn(leftHandSide, iterable, body);
|
| -}
|
| -
|
| -class While extends Loop {
|
| - final Node condition;
|
| -
|
| - While(this.condition, Statement body) : super(body);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitWhile(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - condition.accept(visitor);
|
| - body.accept(visitor);
|
| - }
|
| -
|
| - While _clone() => new While(condition, body);
|
| -}
|
| -
|
| -class Do extends Loop {
|
| - final Expression condition;
|
| -
|
| - Do(Statement body, this.condition) : super(body);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitDo(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - body.accept(visitor);
|
| - condition.accept(visitor);
|
| - }
|
| -
|
| - Do _clone() => new Do(body, condition);
|
| -}
|
| -
|
| -class Continue extends Statement {
|
| - final String targetLabel; // Can be null.
|
| -
|
| - Continue(this.targetLabel);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitContinue(this);
|
| - void visitChildren(NodeVisitor visitor) {}
|
| -
|
| - Continue _clone() => new Continue(targetLabel);
|
| -}
|
| -
|
| -class Break extends Statement {
|
| - final String targetLabel; // Can be null.
|
| -
|
| - Break(this.targetLabel);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitBreak(this);
|
| - void visitChildren(NodeVisitor visitor) {}
|
| -
|
| - Break _clone() => new Break(targetLabel);
|
| -}
|
| -
|
| -class Return extends Statement {
|
| - final Expression value; // Can be null.
|
| -
|
| - Return([this.value = null]);
|
| -
|
| - Statement toReturn() => this;
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitReturn(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - if (value != null) value.accept(visitor);
|
| - }
|
| -
|
| - Return _clone() => new Return(value);
|
| -
|
| - static bool foundIn(Node node) {
|
| - _returnFinder.found = false;
|
| - node.accept(_returnFinder);
|
| - return _returnFinder.found;
|
| - }
|
| -}
|
| -
|
| -final _returnFinder = new _ReturnFinder();
|
| -class _ReturnFinder extends BaseVisitor {
|
| - bool found = false;
|
| - visitReturn(Return node) {
|
| - found = true;
|
| - }
|
| - visitNode(Node node) {
|
| - if (!found) super.visitNode(node);
|
| - }
|
| -}
|
| -
|
| -
|
| -class Throw extends Statement {
|
| - final Expression expression;
|
| -
|
| - Throw(this.expression);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitThrow(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - expression.accept(visitor);
|
| - }
|
| -
|
| - Throw _clone() => new 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);
|
| - }
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitTry(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - body.accept(visitor);
|
| - if (catchPart != null) catchPart.accept(visitor);
|
| - if (finallyPart != null) finallyPart.accept(visitor);
|
| - }
|
| -
|
| - Try _clone() => new Try(body, catchPart, finallyPart);
|
| -}
|
| -
|
| -class Catch extends Node {
|
| - final Identifier declaration;
|
| - final Block body;
|
| -
|
| - Catch(this.declaration, this.body);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitCatch(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - declaration.accept(visitor);
|
| - body.accept(visitor);
|
| - }
|
| -
|
| - Catch _clone() => new Catch(declaration, body);
|
| -}
|
| -
|
| -class Switch extends Statement {
|
| - final Expression key;
|
| - final List<SwitchClause> cases;
|
| -
|
| - Switch(this.key, this.cases);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitSwitch(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - key.accept(visitor);
|
| - for (SwitchClause clause in cases) clause.accept(visitor);
|
| - }
|
| -
|
| - Switch _clone() => new 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);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitCase(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - expression.accept(visitor);
|
| - body.accept(visitor);
|
| - }
|
| -
|
| - Case _clone() => new Case(expression, body);
|
| -}
|
| -
|
| -class Default extends SwitchClause {
|
| - Default(Block body) : super(body);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitDefault(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - body.accept(visitor);
|
| - }
|
| -
|
| - Default _clone() => new Default(body);
|
| -}
|
| -
|
| -class FunctionDeclaration extends Statement {
|
| - final Identifier name;
|
| - final Fun function;
|
| -
|
| - FunctionDeclaration(this.name, this.function);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitFunctionDeclaration(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - name.accept(visitor);
|
| - function.accept(visitor);
|
| - }
|
| -
|
| - FunctionDeclaration _clone() => new FunctionDeclaration(name, function);
|
| -}
|
| -
|
| -class LabeledStatement extends Statement {
|
| - final String label;
|
| - final Statement body;
|
| -
|
| - LabeledStatement(this.label, this.body);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitLabeledStatement(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - body.accept(visitor);
|
| - }
|
| -
|
| - LabeledStatement _clone() => new LabeledStatement(label, body);
|
| -}
|
| -
|
| -class LiteralStatement extends Statement {
|
| - final String code;
|
| -
|
| - LiteralStatement(this.code);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitLiteralStatement(this);
|
| - void visitChildren(NodeVisitor visitor) { }
|
| -
|
| - LiteralStatement _clone() => new 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);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitDartYield(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - expression.accept(visitor);
|
| - }
|
| -
|
| - DartYield _clone() => new DartYield(expression, hasStar);
|
| -}
|
| -
|
| -abstract class Expression extends Node {
|
| - Expression();
|
| -
|
| - factory Expression.binary(List<Expression> exprs, String op) {
|
| - Expression comma = null;
|
| - for (var node in exprs) {
|
| - comma = (comma == null) ? node : new Binary(op, comma, node);
|
| - }
|
| - return comma;
|
| - }
|
| -
|
| - int get precedenceLevel;
|
| -
|
| - Statement toStatement() => new ExpressionStatement(toVoidExpression());
|
| - Statement toReturn() => new Return(this);
|
| - Statement toYieldStatement({bool star: false}) =>
|
| - new ExpressionStatement(new Yield(this, star: star));
|
| -
|
| - Expression toVoidExpression() => this;
|
| - Expression toAssignExpression(Expression left) => new Assignment(left, this);
|
| - Statement toVariableDeclaration(Identifier name) =>
|
| - new VariableDeclarationList('let',
|
| - [new VariableInitialization(name, this)]).toStatement();
|
| -}
|
| -
|
| -class LiteralExpression extends Expression {
|
| - final String template;
|
| - final List<Expression> inputs;
|
| -
|
| - LiteralExpression(this.template) : inputs = const [];
|
| - LiteralExpression.withData(this.template, this.inputs);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitLiteralExpression(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - if (inputs != null) {
|
| - for (Expression expr in inputs) expr.accept(visitor);
|
| - }
|
| - }
|
| -
|
| - LiteralExpression _clone() =>
|
| - new LiteralExpression.withData(template, inputs);
|
| -
|
| - // Code that uses JS 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 {
|
| - /** The `var` or `let` keyword used for this variable declaration list. */
|
| - final String keyword;
|
| - final List<VariableInitialization> declarations;
|
| -
|
| - VariableDeclarationList(this.keyword, this.declarations);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitVariableDeclarationList(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - for (VariableInitialization declaration in declarations) {
|
| - declaration.accept(visitor);
|
| - }
|
| - }
|
| -
|
| - VariableDeclarationList _clone() =>
|
| - new VariableDeclarationList(keyword, declarations);
|
| -
|
| - int get precedenceLevel => EXPRESSION;
|
| -}
|
| -
|
| -class Assignment extends Expression {
|
| - final Expression leftHandSide;
|
| - 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.compound(this.leftHandSide, this.op, this.value);
|
| -
|
| - int get precedenceLevel => ASSIGNMENT;
|
| -
|
| - bool get isCompound => op != null;
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitAssignment(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - leftHandSide.accept(visitor);
|
| - if (value != null) value.accept(visitor);
|
| - }
|
| -
|
| - Assignment _clone() =>
|
| - new Assignment.compound(leftHandSide, op, value);
|
| -}
|
| -
|
| -class VariableInitialization extends Assignment {
|
| - /** [value] may be null. */
|
| - VariableInitialization(VariableBinding declaration, Expression value)
|
| - : super(declaration, value);
|
| -
|
| - VariableBinding get declaration => leftHandSide;
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitVariableInitialization(this);
|
| -
|
| - VariableInitialization _clone() =>
|
| - new VariableInitialization(declaration, value);
|
| -}
|
| -
|
| -abstract class VariableBinding extends Expression {
|
| -}
|
| -
|
| -class DestructuredVariable extends Expression implements Parameter {
|
| - /// [LiteralString] or [Identifier].
|
| - final Expression name;
|
| - final BindingPattern structure;
|
| - final Expression defaultValue;
|
| - final TypeRef type;
|
| - DestructuredVariable({this.name, this.structure, this.defaultValue, this.type}) {
|
| - assert(name != null || structure != null);
|
| - }
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitDestructuredVariable(this);
|
| - void visitChildren(NodeVisitor visitor) {
|
| - name?.accept(visitor);
|
| - structure?.accept(visitor);
|
| - defaultValue?.accept(visitor);
|
| - }
|
| -
|
| - /// Avoid parenthesis when pretty-printing.
|
| - @override int get precedenceLevel => PRIMARY;
|
| - @override Node _clone() =>
|
| - new DestructuredVariable(
|
| - name: name, structure: structure, defaultValue: defaultValue);
|
| -}
|
| -
|
| -abstract class BindingPattern extends Expression implements VariableBinding {
|
| - final List<DestructuredVariable> variables;
|
| - BindingPattern(this.variables);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - for (DestructuredVariable v in variables) v.accept(visitor);
|
| - }
|
| -}
|
| -
|
| -class SimpleBindingPattern extends BindingPattern {
|
| - final Identifier name;
|
| - SimpleBindingPattern(Identifier name)
|
| - : super([new DestructuredVariable(name: name)]), this.name = name;
|
| - accept(NodeVisitor visitor) => visitor.visitSimpleBindingPattern(this);
|
| -
|
| - /// Avoid parenthesis when pretty-printing.
|
| - @override int get precedenceLevel => PRIMARY;
|
| - @override Node _clone() => new SimpleBindingPattern(name);
|
| -}
|
| -
|
| -class ObjectBindingPattern extends BindingPattern {
|
| - ObjectBindingPattern(List<DestructuredVariable> variables)
|
| - : super(variables);
|
| - accept(NodeVisitor visitor) => visitor.visitObjectBindingPattern(this);
|
| -
|
| - /// Avoid parenthesis when pretty-printing.
|
| - @override int get precedenceLevel => PRIMARY;
|
| - @override Node _clone() => new ObjectBindingPattern(variables);
|
| -}
|
| -
|
| -class ArrayBindingPattern extends BindingPattern {
|
| - ArrayBindingPattern(List<DestructuredVariable> variables)
|
| - : super(variables);
|
| - accept(NodeVisitor visitor) => visitor.visitArrayBindingPattern(this);
|
| -
|
| - /// Avoid parenthesis when pretty-printing.
|
| - @override int get precedenceLevel => PRIMARY;
|
| - @override Node _clone() => new ObjectBindingPattern(variables);
|
| -}
|
| -
|
| -class Conditional extends Expression {
|
| - final Expression condition;
|
| - final Expression then;
|
| - final Expression otherwise;
|
| -
|
| - Conditional(this.condition, this.then, this.otherwise);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitConditional(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - condition.accept(visitor);
|
| - then.accept(visitor);
|
| - otherwise.accept(visitor);
|
| - }
|
| -
|
| - Conditional _clone() => new Conditional(condition, then, otherwise);
|
| -
|
| - int get precedenceLevel => ASSIGNMENT;
|
| -}
|
| -
|
| -class Call extends Expression {
|
| - Expression target;
|
| - List<Expression> arguments;
|
| -
|
| - Call(this.target, this.arguments);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitCall(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - target.accept(visitor);
|
| - for (Expression arg in arguments) arg.accept(visitor);
|
| - }
|
| -
|
| - Call _clone() => new Call(target, arguments);
|
| -
|
| - int get precedenceLevel => CALL;
|
| -}
|
| -
|
| -class New extends Call {
|
| - New(Expression cls, List<Expression> arguments) : super(cls, arguments);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitNew(this);
|
| -
|
| - New _clone() => new New(target, arguments);
|
| -
|
| - int get precedenceLevel => ACCESS;
|
| -}
|
| -
|
| -class Binary extends Expression {
|
| - final String op;
|
| - final Expression left;
|
| - final Expression right;
|
| -
|
| - Binary(this.op, this.left, this.right);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitBinary(this);
|
| -
|
| - Binary _clone() => new Binary(op, left, right);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - left.accept(visitor);
|
| - right.accept(visitor);
|
| - }
|
| -
|
| - bool get isCommaOperator => op == ',';
|
| -
|
| - Expression toVoidExpression() {
|
| - if (!isCommaOperator) return super.toVoidExpression();
|
| - var l = left.toVoidExpression();
|
| - var r = right.toVoidExpression();
|
| - if (l == left && r == right) return this;
|
| - return new Binary(',', l, r);
|
| - }
|
| -
|
| - Statement toStatement() {
|
| - if (!isCommaOperator) return super.toStatement();
|
| - return new Block([left.toStatement(), right.toStatement()]);
|
| - }
|
| -
|
| - Statement toReturn() {
|
| - if (!isCommaOperator) return super.toReturn();
|
| - return new Block([left.toStatement(), right.toReturn()]);
|
| - }
|
| -
|
| - Statement toYieldStatement({bool star: false}) {
|
| - if (!isCommaOperator) return super.toYieldStatement(star: star);
|
| - return new Block([left.toStatement(), right.toYieldStatement(star: star)]);
|
| - }
|
| -
|
| - List<Expression> commaToExpressionList() {
|
| - if (!isCommaOperator) throw new StateError('not a comma expression');
|
| - var exprs = [];
|
| - _flattenComma(exprs, left);
|
| - _flattenComma(exprs, right);
|
| - return exprs;
|
| - }
|
| -
|
| - static void _flattenComma(List<Expression> exprs, Expression node) {
|
| - if (node is Binary && node.isCommaOperator) {
|
| - _flattenComma(exprs, node.left);
|
| - _flattenComma(exprs, node.right);
|
| - } else {
|
| - exprs.add(node);
|
| - }
|
| - }
|
| -
|
| - 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);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitPrefix(this);
|
| -
|
| - Prefix _clone() => new Prefix(op, argument);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - argument.accept(visitor);
|
| - }
|
| -
|
| - int get precedenceLevel => UNARY;
|
| -}
|
| -
|
| -// SpreadElement isn't really a prefix expression, as it can only appear in
|
| -// certain places such as ArgumentList and BindingPattern, but we pretend
|
| -// it is for simplicity's sake.
|
| -class Spread extends Prefix {
|
| - Spread(Expression operand) : super('...', operand);
|
| - int get precedenceLevel => SPREAD;
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitSpread(this);
|
| - Spread _clone() => new Spread(argument);
|
| -}
|
| -
|
| -class Postfix extends Expression {
|
| - final String op;
|
| - final Expression argument;
|
| -
|
| - Postfix(this.op, this.argument);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitPostfix(this);
|
| -
|
| - Postfix _clone() => new Postfix(op, argument);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - argument.accept(visitor);
|
| - }
|
| -
|
| - int get precedenceLevel => UNARY;
|
| -}
|
| -
|
| -abstract class Parameter implements Expression, VariableBinding {
|
| - TypeRef get type;
|
| -}
|
| -
|
| -class Identifier extends Expression implements Parameter, VariableBinding {
|
| - final String name;
|
| - final bool allowRename;
|
| - final TypeRef type;
|
| -
|
| - Identifier(this.name, {this.allowRename: true, this.type}) {
|
| - if (!_identifierRE.hasMatch(name)) {
|
| - throw new ArgumentError.value(name, "name", "not a valid identifier");
|
| - }
|
| - }
|
| - static RegExp _identifierRE = new RegExp(r'^[A-Za-z_$][A-Za-z_$0-9]*$');
|
| -
|
| - Identifier _clone() =>
|
| - new Identifier(name, allowRename: allowRename);
|
| - accept(NodeVisitor visitor) => visitor.visitIdentifier(this);
|
| - int get precedenceLevel => PRIMARY;
|
| - void visitChildren(NodeVisitor visitor) {}
|
| -}
|
| -
|
| -// This is an expression for convenience in the AST.
|
| -class RestParameter extends Expression implements Parameter {
|
| - final Identifier parameter;
|
| - TypeRef get type => null;
|
| -
|
| - RestParameter(this.parameter);
|
| -
|
| - RestParameter _clone() => new RestParameter(parameter);
|
| - accept(NodeVisitor visitor) => visitor.visitRestParameter(this);
|
| - void visitChildren(NodeVisitor visitor) {
|
| - parameter.accept(visitor);
|
| - }
|
| - int get precedenceLevel => PRIMARY;
|
| -}
|
| -
|
| -class This extends Expression {
|
| - accept(NodeVisitor visitor) => visitor.visitThis(this);
|
| - This _clone() => new This();
|
| - int get precedenceLevel => PRIMARY;
|
| - void visitChildren(NodeVisitor visitor) {}
|
| -
|
| - static bool foundIn(Node node) {
|
| - _thisFinder.found = false;
|
| - node.accept(_thisFinder);
|
| - return _thisFinder.found;
|
| - }
|
| -}
|
| -
|
| -final _thisFinder = new _ThisFinder();
|
| -class _ThisFinder extends BaseVisitor {
|
| - bool found = false;
|
| - visitThis(This node) {
|
| - found = true;
|
| - }
|
| - visitNode(Node node) {
|
| - if (!found) super.visitNode(node);
|
| - }
|
| -}
|
| -
|
| -
|
| -// `super` is more restricted in the ES6 spec, but for simplicity we accept
|
| -// it anywhere that `this` is accepted.
|
| -class Super extends Expression {
|
| - accept(NodeVisitor visitor) => visitor.visitSuper(this);
|
| - Super _clone() => new Super();
|
| - int get precedenceLevel => PRIMARY;
|
| - void visitChildren(NodeVisitor visitor) {}
|
| -}
|
| -
|
| -class NamedFunction extends Expression {
|
| - final Identifier name;
|
| - final Fun function;
|
| -
|
| - NamedFunction(this.name, this.function);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitNamedFunction(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - name.accept(visitor);
|
| - function.accept(visitor);
|
| - }
|
| - NamedFunction _clone() => new NamedFunction(name, function);
|
| -
|
| - int get precedenceLevel => PRIMARY_LOW_PRECEDENCE;
|
| -}
|
| -
|
| -abstract class FunctionExpression extends Expression {
|
| - List<Parameter> get params;
|
| -
|
| - get body; // Expression or block
|
| - /// Type parameters passed to this generic function, if any. `null` otherwise.
|
| - // TODO(ochafik): Support type bounds.
|
| - List<Identifier> get typeParams;
|
| - /// Return type of this function, if any. `null` otherwise.
|
| - TypeRef get returnType;
|
| -}
|
| -
|
| -class Fun extends FunctionExpression {
|
| - final List<Parameter> params;
|
| - final Block body;
|
| - @override final List<Identifier> typeParams;
|
| - @override final TypeRef returnType;
|
| - /** Whether this is a JS generator (`function*`) that may contain `yield`. */
|
| - final bool isGenerator;
|
| -
|
| - final AsyncModifier asyncModifier;
|
| -
|
| - Fun(this.params, this.body, {this.isGenerator: false,
|
| - this.asyncModifier: const AsyncModifier.sync(),
|
| - this.typeParams, this.returnType});
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitFun(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - for (Parameter param in params) param.accept(visitor);
|
| - body.accept(visitor);
|
| - }
|
| -
|
| - Fun _clone() => new Fun(params, body,
|
| - isGenerator: isGenerator, asyncModifier: asyncModifier);
|
| -
|
| - int get precedenceLevel => PRIMARY_LOW_PRECEDENCE;
|
| -}
|
| -
|
| -class ArrowFun extends FunctionExpression {
|
| - final List<Parameter> params;
|
| - final body; // Expression or Block
|
| - @override final List<Identifier> typeParams;
|
| - @override final TypeRef returnType;
|
| -
|
| - ArrowFun(this.params, this.body, {this.typeParams, this.returnType});
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitArrowFun(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - for (Parameter param in params) param.accept(visitor);
|
| - body.accept(visitor);
|
| - }
|
| -
|
| - int get precedenceLevel => PRIMARY_LOW_PRECEDENCE;
|
| -
|
| - ArrowFun _clone() => new ArrowFun(params, body);
|
| -}
|
| -
|
| -/**
|
| - * The Dart sync, sync*, async, and async* modifier.
|
| - * See [DartYield].
|
| - *
|
| - * This is not used for JS functions.
|
| - */
|
| -class AsyncModifier {
|
| - final bool isAsync;
|
| - final bool isYielding;
|
| - final String description;
|
| -
|
| - const AsyncModifier.sync()
|
| - : isAsync = false,
|
| - isYielding = false,
|
| - description = "sync";
|
| - const AsyncModifier.async()
|
| - : isAsync = true,
|
| - isYielding = false,
|
| - description = "async";
|
| - const AsyncModifier.asyncStar()
|
| - : isAsync = true,
|
| - isYielding = true,
|
| - description = "async*";
|
| - const AsyncModifier.syncStar()
|
| - : isAsync = false,
|
| - isYielding = true,
|
| - description = "sync*";
|
| - toString() => description;
|
| -}
|
| -
|
| -class PropertyAccess extends Expression {
|
| - final Expression receiver;
|
| - final Expression selector;
|
| -
|
| - PropertyAccess(this.receiver, this.selector);
|
| - PropertyAccess.field(this.receiver, String fieldName)
|
| - : selector = new LiteralString('"$fieldName"');
|
| - PropertyAccess.indexed(this.receiver, int index)
|
| - : selector = new LiteralNumber('$index');
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitAccess(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - receiver.accept(visitor);
|
| - selector.accept(visitor);
|
| - }
|
| -
|
| - PropertyAccess _clone() => new PropertyAccess(receiver, selector);
|
| -
|
| - int get precedenceLevel => ACCESS;
|
| -}
|
| -
|
| -abstract class Literal extends Expression {
|
| - void visitChildren(NodeVisitor visitor) {}
|
| -
|
| - int get precedenceLevel => PRIMARY;
|
| -}
|
| -
|
| -class LiteralBool extends Literal {
|
| - final bool value;
|
| -
|
| - LiteralBool(this.value);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitLiteralBool(this);
|
| - // [visitChildren] inherited from [Literal].
|
| - LiteralBool _clone() => new LiteralBool(value);
|
| -}
|
| -
|
| -class LiteralNull extends Literal {
|
| - LiteralNull();
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitLiteralNull(this);
|
| - LiteralNull _clone() => new LiteralNull();
|
| -}
|
| -
|
| -class LiteralString extends Literal {
|
| - final String value;
|
| -
|
| - /**
|
| - * 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
|
| - * as a JS value.
|
| - *
|
| - * TODO(sra): Introduce variants for known valid strings that don't allocate a
|
| - * new string just to add quotes.
|
| - */
|
| - LiteralString(this.value);
|
| -
|
| - /// Gets the value inside the string without the beginning and end quotes.
|
| - String get valueWithoutQuotes => value.substring(1, value.length - 1);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitLiteralString(this);
|
| - LiteralString _clone() => new LiteralString(value);
|
| -}
|
| -
|
| -class LiteralNumber extends Literal {
|
| - final String value; // Must be a valid JavaScript number literal.
|
| -
|
| - LiteralNumber(this.value);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitLiteralNumber(this);
|
| - LiteralNumber _clone() => new LiteralNumber(value);
|
| -
|
| - /**
|
| - * Use a different precedence level depending on whether the value contains a
|
| - * dot to ensure we generate `(1).toString()` and `1.0.toString()`.
|
| - */
|
| - int get precedenceLevel => value.contains('.') ? PRIMARY : UNARY;
|
| -}
|
| -
|
| -class ArrayInitializer extends Expression {
|
| - final List<Expression> elements;
|
| - final bool multiline;
|
| -
|
| - ArrayInitializer(this.elements, {this.multiline: false});
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitArrayInitializer(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - for (Expression element in elements) element.accept(visitor);
|
| - }
|
| -
|
| - ArrayInitializer _clone() => new 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 {
|
| - accept(NodeVisitor visitor) => visitor.visitArrayHole(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {}
|
| -
|
| - ArrayHole _clone() => new ArrayHole();
|
| -
|
| - int get precedenceLevel => PRIMARY;
|
| -}
|
| -
|
| -class ObjectInitializer extends Expression {
|
| - final List<Property> properties;
|
| - final bool _multiline;
|
| -
|
| - /**
|
| - * Constructs a new object-initializer containing the given [properties].
|
| - */
|
| - ObjectInitializer(this.properties, {multiline: false})
|
| - : _multiline = multiline;
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitObjectInitializer(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - for (Property init in properties) init.accept(visitor);
|
| - }
|
| -
|
| - ObjectInitializer _clone() => new ObjectInitializer(properties);
|
| -
|
| - int get precedenceLevel => PRIMARY;
|
| - /**
|
| - * If set to true, forces a vertical layout when using the [Printer].
|
| - * Otherwise, layout will be vertical if and only if any [properties]
|
| - * are [FunctionExpression]s.
|
| - */
|
| - bool get multiline {
|
| - return _multiline || properties.any((p) => p.value is FunctionExpression);
|
| - }
|
| -}
|
| -
|
| -class Property extends Node {
|
| - final Expression name;
|
| - final Expression value;
|
| -
|
| - Property(this.name, this.value);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitProperty(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - name.accept(visitor);
|
| - value.accept(visitor);
|
| - }
|
| -
|
| - Property _clone() => new Property(name, value);
|
| -}
|
| -
|
| -// TODO(jmesserly): parser does not support this yet.
|
| -class TemplateString extends Expression {
|
| - /**
|
| - * The parts of this template string: a sequence of [String]s and
|
| - * [Expression]s. Strings and expressions will alternate, for example:
|
| - *
|
| - * `foo${1 + 2} bar ${'hi'}`
|
| - *
|
| - * would be represented by:
|
| - *
|
| - * ['foo', new JS.Binary('+', js.number(1), js.number(2)),
|
| - * ' bar ', new JS.LiteralString("'hi'")]
|
| - */
|
| - final List elements;
|
| - TemplateString(this.elements);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitTemplateString(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - for (var element in elements) {
|
| - if (element is Expression) element.accept(visitor);
|
| - }
|
| - }
|
| -
|
| - TemplateString _clone() => new TemplateString(elements);
|
| -
|
| - int get precedenceLevel => PRIMARY;
|
| -}
|
| -
|
| -// TODO(jmesserly): parser does not support this yet.
|
| -class TaggedTemplate extends Expression {
|
| - final Expression tag;
|
| - final TemplateString template;
|
| -
|
| - TaggedTemplate(this.tag, this.template);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitTaggedTemplate(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - tag.accept(visitor);
|
| - template.accept(visitor);
|
| - }
|
| -
|
| - TaggedTemplate _clone() => new TaggedTemplate(tag, template);
|
| -
|
| - int get precedenceLevel => CALL;
|
| -}
|
| -
|
| -// TODO(jmesserly): parser does not support this yet.
|
| -class Yield extends Expression {
|
| - final Expression value; // Can be null.
|
| -
|
| - /**
|
| - * Whether this yield expression is a `yield*` that iterates each item in
|
| - * [value].
|
| - */
|
| - final bool star;
|
| -
|
| - Yield(this.value, {this.star: false});
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitYield(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - if (value != null) value.accept(visitor);
|
| - }
|
| -
|
| - Yield _clone() => new Yield(value);
|
| -
|
| - int get precedenceLevel => YIELD;
|
| -}
|
| -
|
| -class ClassDeclaration extends Statement {
|
| - final ClassExpression classExpr;
|
| -
|
| - ClassDeclaration(this.classExpr);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitClassDeclaration(this);
|
| - visitChildren(NodeVisitor visitor) => classExpr.accept(visitor);
|
| - ClassDeclaration _clone() => new ClassDeclaration(classExpr);
|
| -}
|
| -
|
| -class ClassExpression extends Expression {
|
| - final Identifier name;
|
| - final Expression heritage; // Can be null.
|
| - final List<Method> methods;
|
| - /// Type parameters of this class, if any. `null` otherwise.
|
| - // TODO(ochafik): Support type bounds.
|
| - final List<Identifier> typeParams;
|
| - /// Field declarations of this class (TypeScript / ES6_TYPED).
|
| - final List<VariableDeclarationList> fields;
|
| -
|
| - ClassExpression(this.name, this.heritage, this.methods,
|
| - {this.typeParams, this.fields});
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitClassExpression(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - name.accept(visitor);
|
| - if (heritage != null) heritage.accept(visitor);
|
| - for (Method element in methods) element.accept(visitor);
|
| - if (fields != null) {
|
| - for (var field in fields) {
|
| - field.accept(visitor);
|
| - }
|
| - }
|
| - if (typeParams != null) {
|
| - for (var typeParam in typeParams) {
|
| - typeParam.accept(visitor);
|
| - }
|
| - }
|
| - }
|
| -
|
| - ClassExpression _clone() => new ClassExpression(
|
| - name, heritage, methods, typeParams: typeParams, fields: fields);
|
| -
|
| - int get precedenceLevel => PRIMARY_LOW_PRECEDENCE;
|
| -}
|
| -
|
| -class Method extends Property {
|
| - final bool isGetter;
|
| - final bool isSetter;
|
| - final bool isStatic;
|
| -
|
| - Method(Expression name, Fun function,
|
| - {this.isGetter: false, this.isSetter: false, this.isStatic: false})
|
| - : super(name, function) {
|
| - assert(!isGetter || function.params.length == 0);
|
| - assert(!isSetter || function.params.length == 1);
|
| - assert(!isGetter && !isSetter || !function.isGenerator);
|
| - }
|
| -
|
| - Fun get function => super.value;
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitMethod(this);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {
|
| - name.accept(visitor);
|
| - function.accept(visitor);
|
| - }
|
| -
|
| - Method _clone() => new Method(name, function,
|
| - isGetter: isGetter, isSetter: isSetter, isStatic: isStatic);
|
| -}
|
| -
|
| -/// 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);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitInterpolatedExpression(this);
|
| - void visitChildren(NodeVisitor visitor) {}
|
| - InterpolatedExpression _clone() =>
|
| - new InterpolatedExpression(nameOrPosition);
|
| -
|
| - int get precedenceLevel => PRIMARY;
|
| -}
|
| -
|
| -class InterpolatedLiteral extends Literal with InterpolatedNode {
|
| - final nameOrPosition;
|
| -
|
| - InterpolatedLiteral(this.nameOrPosition);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitInterpolatedLiteral(this);
|
| - void visitChildren(NodeVisitor visitor) {}
|
| - InterpolatedLiteral _clone() => new InterpolatedLiteral(nameOrPosition);
|
| -}
|
| -
|
| -class InterpolatedParameter extends Expression with InterpolatedNode
|
| - implements Identifier {
|
| - final nameOrPosition;
|
| - TypeRef get type => null;
|
| -
|
| - String get name { throw "InterpolatedParameter.name must not be invoked"; }
|
| - bool get allowRename => false;
|
| -
|
| - InterpolatedParameter(this.nameOrPosition);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitInterpolatedParameter(this);
|
| - void visitChildren(NodeVisitor visitor) {}
|
| - InterpolatedParameter _clone() => new InterpolatedParameter(nameOrPosition);
|
| -
|
| - int get precedenceLevel => PRIMARY;
|
| -}
|
| -
|
| -class InterpolatedSelector extends Expression with InterpolatedNode {
|
| - final nameOrPosition;
|
| -
|
| - InterpolatedSelector(this.nameOrPosition);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitInterpolatedSelector(this);
|
| - void visitChildren(NodeVisitor visitor) {}
|
| - InterpolatedSelector _clone() => new InterpolatedSelector(nameOrPosition);
|
| -
|
| - int get precedenceLevel => PRIMARY;
|
| -}
|
| -
|
| -class InterpolatedStatement extends Statement with InterpolatedNode {
|
| - final nameOrPosition;
|
| -
|
| - InterpolatedStatement(this.nameOrPosition);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitInterpolatedStatement(this);
|
| - void visitChildren(NodeVisitor visitor) {}
|
| - InterpolatedStatement _clone() => new InterpolatedStatement(nameOrPosition);
|
| -}
|
| -
|
| -// TODO(jmesserly): generalize this to InterpolatedProperty?
|
| -class InterpolatedMethod extends Expression with InterpolatedNode
|
| - implements Method {
|
| - final nameOrPosition;
|
| -
|
| - InterpolatedMethod(this.nameOrPosition);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitInterpolatedMethod(this);
|
| - void visitChildren(NodeVisitor visitor) {}
|
| - InterpolatedMethod _clone() => new InterpolatedMethod(nameOrPosition);
|
| -
|
| - int get precedenceLevel => PRIMARY;
|
| - Expression get name => _unsupported;
|
| - Expression get value => _unsupported;
|
| - bool get isGetter => _unsupported;
|
| - bool get isSetter => _unsupported;
|
| - bool get isStatic => _unsupported;
|
| - Fun get function => _unsupported;
|
| - get _unsupported => throw '$runtimeType does not support this member.';
|
| -}
|
| -
|
| -class InterpolatedIdentifier extends Expression with InterpolatedNode
|
| - implements Identifier {
|
| - final nameOrPosition;
|
| - TypeRef get type => null;
|
| -
|
| - InterpolatedIdentifier(this.nameOrPosition);
|
| -
|
| - accept(NodeVisitor visitor) =>
|
| - visitor.visitInterpolatedIdentifier(this);
|
| - void visitChildren(NodeVisitor visitor) {}
|
| - InterpolatedIdentifier _clone() => new InterpolatedIdentifier(nameOrPosition);
|
| -
|
| - int get precedenceLevel => PRIMARY;
|
| - String get name => throw '$runtimeType does not support this member.';
|
| - bool get allowRename => false;
|
| -}
|
| -
|
| -/**
|
| - * [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);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitRegExpLiteral(this);
|
| - void visitChildren(NodeVisitor visitor) {}
|
| - RegExpLiteral _clone() => new 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;
|
| - accept(NodeVisitor visitor) => visitor.visitAwait(this);
|
| - void visitChildren(NodeVisitor visitor) => expression.accept(visitor);
|
| - Await _clone() => new 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);
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitComment(this);
|
| - Comment _clone() => new Comment(comment);
|
| -
|
| - void visitChildren(NodeVisitor visitor) {}
|
| -}
|
| -
|
| -/**
|
| - * A comment for expressions.
|
| - *
|
| - * Extends [Expression] so we can add comments before expressions.
|
| - * Has the highest possible precedence, so we don't add parentheses around it.
|
| - */
|
| -class CommentExpression extends Expression {
|
| - final String comment;
|
| - final Expression expression;
|
| -
|
| - CommentExpression(this.comment, this.expression);
|
| -
|
| - int get precedenceLevel => PRIMARY;
|
| - accept(NodeVisitor visitor) => visitor.visitCommentExpression(this);
|
| - CommentExpression _clone() => new CommentExpression(comment, expression);
|
| -
|
| - void visitChildren(NodeVisitor visitor) => expression.accept(visitor);
|
| -}
|
| -
|
| -/**
|
| - * Represents allowed module items:
|
| - * [Statement], [ImportDeclaration], and [ExportDeclaration].
|
| - */
|
| -abstract class ModuleItem extends Node {}
|
| -
|
| -class ImportDeclaration extends ModuleItem {
|
| - final Identifier defaultBinding; // Can be null.
|
| -
|
| - // Can be null, a single specifier of `* as name`, or a list.
|
| - final List<NameSpecifier> namedImports;
|
| -
|
| - final LiteralString from;
|
| -
|
| - ImportDeclaration({this.defaultBinding, this.namedImports, this.from});
|
| -
|
| - /** The `import "name.js"` form of import */
|
| - ImportDeclaration.all(LiteralString module) : this(from: module);
|
| -
|
| - /** If this import has `* as name` returns the name, otherwise null. */
|
| - String get importStarAs {
|
| - if (namedImports != null && namedImports.length == 1 &&
|
| - namedImports[0].name == '*') {
|
| - return namedImports[0].asName;
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitImportDeclaration(this);
|
| - void visitChildren(NodeVisitor visitor) {
|
| - if (namedImports != null) {
|
| - for (NameSpecifier name in namedImports) name.accept(visitor);
|
| - }
|
| - from.accept(visitor);
|
| - }
|
| - ImportDeclaration _clone() => new ImportDeclaration(
|
| - defaultBinding: defaultBinding, namedImports: namedImports, from: from);
|
| -}
|
| -
|
| -class ExportDeclaration extends ModuleItem {
|
| - /**
|
| - * Exports a name from this module.
|
| - *
|
| - * This can be a [ClassDeclaration] or [FunctionDeclaration].
|
| - * If [isDefault] is true, it can also be an [Expression].
|
| - * Otherwise it can be a [VariableDeclarationList] or an [ExportClause].
|
| - */
|
| - final Node exported;
|
| -
|
| - /** True if this is an `export default`. */
|
| - final bool isDefault;
|
| -
|
| - ExportDeclaration(this.exported, {this.isDefault: false}) {
|
| - assert(exported is ClassDeclaration ||
|
| - exported is FunctionDeclaration ||
|
| - isDefault
|
| - ? exported is Expression
|
| - : exported is VariableDeclarationList ||
|
| - exported is ExportClause);
|
| - }
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitExportDeclaration(this);
|
| - visitChildren(NodeVisitor visitor) => exported.accept(visitor);
|
| - ExportDeclaration _clone() =>
|
| - new ExportDeclaration(exported, isDefault: isDefault);
|
| -}
|
| -
|
| -class ExportClause extends Node {
|
| - final List<NameSpecifier> exports;
|
| - final LiteralString from; // Can be null.
|
| -
|
| - ExportClause(this.exports, {this.from});
|
| -
|
| - /** The `export * from 'name.js'` form. */
|
| - ExportClause.star(LiteralString from)
|
| - : this([new NameSpecifier('*')], from: from);
|
| -
|
| - /** True if this is an `export *`. */
|
| - bool get exportStar => exports.length == 1 && exports[0].name == '*';
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitExportClause(this);
|
| - void visitChildren(NodeVisitor visitor) {
|
| - for (NameSpecifier name in exports) name.accept(visitor);
|
| - if (from != null) from.accept(visitor);
|
| - }
|
| - ExportClause _clone() => new ExportClause(exports, from: from);
|
| -}
|
| -
|
| -/** An import or export specifier. */
|
| -class NameSpecifier extends Node {
|
| - // TODO(jmesserly): should we wrap this in a node of some sort?
|
| - final String name;
|
| - final String asName; // Can be null.
|
| -
|
| - NameSpecifier(this.name, {this.asName});
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitNameSpecifier(this);
|
| - void visitChildren(NodeVisitor visitor) {}
|
| - NameSpecifier _clone() => new NameSpecifier(name, asName: asName);
|
| -}
|
| -
|
| -// TODO(jmesserly): should this be related to [Program]?
|
| -class Module extends Node {
|
| - /// The module's name
|
| - // TODO(jmesserly): this is not declared in ES6, but is known by the loader.
|
| - // We use this because some ES5 desugarings require it.
|
| - final String name;
|
| -
|
| - final List<ModuleItem> body;
|
| - Module(this.body, {this.name});
|
| -
|
| - accept(NodeVisitor visitor) => visitor.visitModule(this);
|
| - void visitChildren(NodeVisitor visitor) {
|
| - for (ModuleItem item in body) item.accept(visitor);
|
| - }
|
| - Module _clone() => new Module(body);
|
| -}
|
|
|