Index: lib/src/js/template.dart |
diff --git a/lib/src/js/template.dart b/lib/src/js/template.dart |
deleted file mode 100644 |
index eb55252a95903d41d2029c076ae9324af6c96e29..0000000000000000000000000000000000000000 |
--- a/lib/src/js/template.dart |
+++ /dev/null |
@@ -1,923 +0,0 @@ |
-// Copyright (c) 2014, 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; |
- |
-class TemplateManager { |
- Map<String, Template> expressionTemplates = new Map<String, Template>(); |
- Map<String, Template> statementTemplates = new Map<String, Template>(); |
- |
- TemplateManager(); |
- |
- Template lookupExpressionTemplate(String source) { |
- return expressionTemplates[source]; |
- } |
- |
- Template defineExpressionTemplate(String source, Node ast) { |
- Template template = |
- new Template(source, ast, isExpression: true, forceCopy: false); |
- expressionTemplates[source] = template; |
- return template; |
- } |
- |
- Template lookupStatementTemplate(String source) { |
- return statementTemplates[source]; |
- } |
- |
- Template defineStatementTemplate(String source, Node ast) { |
- Template template = |
- new Template(source, ast, isExpression: false, forceCopy: false); |
- statementTemplates[source] = template; |
- return template; |
- } |
-} |
- |
-/** |
- * A Template is created with JavaScript AST containing placeholders (interface |
- * InterpolatedNode). The [instantiate] method creates an AST that looks like |
- * the original with the placeholders replaced by the arguments to |
- * [instantiate]. |
- */ |
-class Template { |
- final String source; |
- final bool isExpression; |
- final bool forceCopy; |
- final Node ast; |
- |
- Instantiator instantiator; |
- |
- int positionalArgumentCount = -1; |
- |
- // Null, unless there are named holes. |
- List<String> holeNames; |
- bool get isPositional => holeNames == null; |
- |
- Template(this.source, this.ast, |
- {this.isExpression: true, this.forceCopy: false}) { |
- _compile(); |
- } |
- |
- Template.withExpressionResult(this.ast) |
- : source = null, |
- isExpression = true, |
- forceCopy = false { |
- assert(ast is Expression); |
- assert(_checkNoPlaceholders()); |
- positionalArgumentCount = 0; |
- instantiator = (arguments) => ast; |
- } |
- |
- Template.withStatementResult(this.ast) |
- : source = null, |
- isExpression = false, |
- forceCopy = false { |
- assert(ast is Statement); |
- assert(_checkNoPlaceholders()); |
- positionalArgumentCount = 0; |
- instantiator = (arguments) => ast; |
- } |
- |
- bool _checkNoPlaceholders() { |
- InstantiatorGeneratorVisitor generator = |
- new InstantiatorGeneratorVisitor(false); |
- generator.compile(ast); |
- return generator.analysis.count == 0; |
- } |
- |
- void _compile() { |
- InstantiatorGeneratorVisitor generator = |
- new InstantiatorGeneratorVisitor(forceCopy); |
- instantiator = generator.compile(ast); |
- positionalArgumentCount = generator.analysis.count; |
- Set<String> names = generator.analysis.holeNames; |
- holeNames = names.toList(growable: false); |
- } |
- |
- /// Instantiates the template with the given [arguments]. |
- /// |
- /// This method fills in the holes with the given arguments. The [arguments] |
- /// must be either a [List] or a [Map]. |
- Node instantiate(var arguments) { |
- if (arguments is List) { |
- if (arguments.length != positionalArgumentCount) { |
- throw 'Wrong number of template arguments, given ${arguments.length}, ' |
- 'expected $positionalArgumentCount:\n$source'; |
- } |
- return instantiator(arguments); |
- } |
- assert(arguments is Map); |
- if (holeNames.length < arguments.length) { |
- // This search is in O(n), but we only do it in case of an error, and the |
- // number of holes should be quite limited. |
- String unusedNames = |
- arguments.keys.where((name) => !holeNames.contains(name)).join(", "); |
- throw "Template arguments has unused mappings: $unusedNames"; |
- } |
- if (!holeNames.every((String name) => arguments.containsKey(name))) { |
- String notFound = |
- holeNames.where((name) => !arguments.containsKey(name)).join(", "); |
- throw "Template arguments is missing mappings for: $notFound"; |
- } |
- return instantiator(arguments); |
- } |
- |
- /// Like [instantiate] but works with free variables. |
- Node safeCreate(Map arguments) { |
- if (holeNames.isEmpty) return ast; |
- return instantiator(new Map.fromIterable(holeNames, value: (name) { |
- var a = arguments[name]; |
- return a != null ? a : new InterpolatedExpression(name); |
- })); |
- } |
-} |
- |
-/** |
- * An Instantiator is a Function that generates a JS AST tree or List of |
- * trees. [arguments] is a List for positional templates, or Map for |
- * named templates. |
- */ |
-typedef Instantiator(var arguments); |
- |
-/** |
- * InstantiatorGeneratorVisitor compiles a template. This class compiles a tree |
- * containing [InterpolatedNode]s into a function that will create a copy of the |
- * tree with the interpolated nodes substituted with provided values. |
- */ |
-class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> { |
- final bool forceCopy; |
- |
- InterpolatedNodeAnalysis analysis = new InterpolatedNodeAnalysis(); |
- |
- /** |
- * The entire tree is cloned if [forceCopy] is true. |
- */ |
- InstantiatorGeneratorVisitor(this.forceCopy); |
- |
- Instantiator compile(Node node) { |
- analysis.visit(node); |
- Instantiator result = visit(node); |
- return result; |
- } |
- |
- static error(String message) { |
- throw message; |
- } |
- |
- static Instantiator same(Node node) => (arguments) => node; |
- static Node makeNull(arguments) => null; |
- |
- Instantiator visit(Node node) { |
- if (forceCopy || analysis.containsInterpolatedNodes(node)) { |
- return node.accept(this); |
- } |
- return same(node); |
- } |
- |
- Instantiator visitNullable(Node node) { |
- if (node == null) return makeNull; |
- return visit(node); |
- } |
- |
- Instantiator visitSplayable(Node node) { |
- // TODO(sra): Process immediate [InterpolatedNode]s, permitting splaying. |
- return visit(node); |
- } |
- |
- Instantiator visitNode(Node node) { |
- throw 'Unimplemented InstantiatorGeneratorVisitor for $node'; |
- } |
- |
- Instantiator visitInterpolatedExpression(InterpolatedExpression node) { |
- var nameOrPosition = node.nameOrPosition; |
- return (arguments) { |
- var value = arguments[nameOrPosition]; |
- if (value is Expression) return value; |
- if (value is String) return new Identifier(value); |
- error('Interpolated value #$nameOrPosition is not an Expression: $value'); |
- }; |
- } |
- |
- Instantiator visitSplayableExpression(Node node) { |
- if (node is InterpolatedExpression) { |
- var nameOrPosition = node.nameOrPosition; |
- return (arguments) { |
- var value = arguments[nameOrPosition]; |
- Expression toExpression(item) { |
- if (item is Expression) return item; |
- if (item is String) return new Identifier(item); |
- return error('Interpolated value #$nameOrPosition is not ' |
- 'an Expression or List of Expressions: $value'); |
- } |
- if (value is Iterable) return value.map(toExpression); |
- return toExpression(value); |
- }; |
- } |
- return visit(node); |
- } |
- |
- Instantiator visitInterpolatedLiteral(InterpolatedLiteral node) { |
- var nameOrPosition = node.nameOrPosition; |
- return (arguments) { |
- var value = arguments[nameOrPosition]; |
- if (value is Literal) return value; |
- error('Interpolated value #$nameOrPosition is not a Literal: $value'); |
- }; |
- } |
- |
- Instantiator visitInterpolatedParameter(InterpolatedParameter node) { |
- var nameOrPosition = node.nameOrPosition; |
- return (arguments) { |
- var value = arguments[nameOrPosition]; |
- |
- Parameter toIdentifier(item) { |
- if (item is Parameter) return item; |
- if (item is String) return new Identifier(item); |
- return error('Interpolated value #$nameOrPosition is not an Identifier' |
- ' or List of Identifiers: $value'); |
- } |
- if (value is Iterable) return value.map(toIdentifier); |
- return toIdentifier(value); |
- }; |
- } |
- |
- Instantiator visitInterpolatedSelector(InterpolatedSelector node) { |
- // A selector is an expression, as in `a[selector]`. |
- // A String argument converted into a LiteralString, so `a.#` with argument |
- // 'foo' generates `a["foo"]` which prints as `a.foo`. |
- var nameOrPosition = node.nameOrPosition; |
- return (arguments) { |
- var value = arguments[nameOrPosition]; |
- if (value is Expression) return value; |
- if (value is String) return new LiteralString('"$value"'); |
- error('Interpolated value #$nameOrPosition is not a selector: $value'); |
- }; |
- } |
- |
- Instantiator visitInterpolatedStatement(InterpolatedStatement node) { |
- var nameOrPosition = node.nameOrPosition; |
- return (arguments) { |
- var value = arguments[nameOrPosition]; |
- if (value is Node) return value.toStatement(); |
- error('Interpolated value #$nameOrPosition is not a Statement: $value'); |
- }; |
- } |
- |
- Instantiator visitInterpolatedMethod(InterpolatedMethod node) { |
- var nameOrPosition = node.nameOrPosition; |
- return (arguments) { |
- var value = arguments[nameOrPosition]; |
- Method toMethod(item) { |
- if (item is Method) return item; |
- return error('Interpolated value #$nameOrPosition is not a Method ' |
- 'or List of Methods: $value'); |
- } |
- if (value is Iterable) return value.map(toMethod); |
- return toMethod(value); |
- }; |
- } |
- |
- Instantiator visitInterpolatedIdentifier(InterpolatedIdentifier node) { |
- var nameOrPosition = node.nameOrPosition; |
- return (arguments) { |
- var item = arguments[nameOrPosition]; |
- if (item is Identifier) return item; |
- if (item is String) return new Identifier(item); |
- return error('Interpolated value #$nameOrPosition is not a ' |
- 'Identifier or String: $item'); |
- }; |
- } |
- |
- Instantiator visitSplayableStatement(Node node) { |
- if (node is InterpolatedStatement) { |
- var nameOrPosition = node.nameOrPosition; |
- return (arguments) { |
- var value = arguments[nameOrPosition]; |
- Statement toStatement(item) { |
- if (item is Statement) return item; |
- if (item is Expression) return item.toStatement(); |
- ; |
- return error('Interpolated value #$nameOrPosition is not ' |
- 'a Statement or List of Statements: $value'); |
- } |
- if (value is Iterable) return value.map(toStatement); |
- return toStatement(value); |
- }; |
- } |
- return visit(node); |
- } |
- |
- Instantiator visitProgram(Program node) { |
- List instantiators = node.body.map(visitSplayableStatement).toList(); |
- return (arguments) { |
- List<Statement> statements = <Statement>[]; |
- void add(node) { |
- if (node is EmptyStatement) return; |
- if (node is Iterable) { |
- statements.addAll(node); |
- } else { |
- statements.add(node.toStatement()); |
- } |
- } |
- for (Instantiator instantiator in instantiators) { |
- add(instantiator(arguments)); |
- } |
- return new Program(statements); |
- }; |
- } |
- |
- Instantiator visitBlock(Block node) { |
- List instantiators = node.statements.map(visitSplayableStatement).toList(); |
- return (arguments) { |
- List<Statement> statements = <Statement>[]; |
- void add(node) { |
- if (node is EmptyStatement) return; |
- if (node is Iterable) { |
- statements.addAll(node); |
- } else if (node is Block) { |
- statements.addAll(node.statements); |
- } else { |
- statements.add(node.toStatement()); |
- } |
- } |
- for (Instantiator instantiator in instantiators) { |
- add(instantiator(arguments)); |
- } |
- return new Block(statements); |
- }; |
- } |
- |
- Instantiator visitExpressionStatement(ExpressionStatement node) { |
- Instantiator buildExpression = visit(node.expression); |
- return (arguments) { |
- return buildExpression(arguments).toStatement(); |
- }; |
- } |
- |
- Instantiator visitEmptyStatement(EmptyStatement node) => |
- (arguments) => new EmptyStatement(); |
- |
- Instantiator visitIf(If node) { |
- if (node.condition is InterpolatedExpression) { |
- return visitIfConditionalCompilation(node); |
- } else { |
- return visitIfNormal(node); |
- } |
- } |
- |
- Instantiator visitIfConditionalCompilation(If node) { |
- // Special version of visitInterpolatedExpression that permits bools. |
- compileCondition(InterpolatedExpression node) { |
- var nameOrPosition = node.nameOrPosition; |
- return (arguments) { |
- var value = arguments[nameOrPosition]; |
- if (value is bool) return value; |
- if (value is Expression) return value; |
- if (value is String) return new Identifier(value); |
- error('Interpolated value #$nameOrPosition ' |
- 'is not an Expression: $value'); |
- }; |
- } |
- var makeCondition = compileCondition(node.condition); |
- Instantiator makeThen = visit(node.then); |
- Instantiator makeOtherwise = visit(node.otherwise); |
- return (arguments) { |
- var condition = makeCondition(arguments); |
- if (condition is bool) { |
- if (condition == true) { |
- return makeThen(arguments); |
- } else { |
- return makeOtherwise(arguments); |
- } |
- } |
- return new If(condition, makeThen(arguments), makeOtherwise(arguments)); |
- }; |
- } |
- |
- Instantiator visitIfNormal(If node) { |
- Instantiator makeCondition = visit(node.condition); |
- Instantiator makeThen = visit(node.then); |
- Instantiator makeOtherwise = visit(node.otherwise); |
- return (arguments) { |
- return new If(makeCondition(arguments), makeThen(arguments), |
- makeOtherwise(arguments)); |
- }; |
- } |
- |
- Instantiator visitFor(For node) { |
- Instantiator makeInit = visitNullable(node.init); |
- Instantiator makeCondition = visitNullable(node.condition); |
- Instantiator makeUpdate = visitNullable(node.update); |
- Instantiator makeBody = visit(node.body); |
- return (arguments) { |
- return new For(makeInit(arguments), makeCondition(arguments), |
- makeUpdate(arguments), makeBody(arguments)); |
- }; |
- } |
- |
- Instantiator visitForIn(ForIn node) { |
- Instantiator makeLeftHandSide = visit(node.leftHandSide); |
- Instantiator makeObject = visit(node.object); |
- Instantiator makeBody = visit(node.body); |
- return (arguments) { |
- return new ForIn(makeLeftHandSide(arguments), makeObject(arguments), |
- makeBody(arguments)); |
- }; |
- } |
- |
- Instantiator visitForOf(ForOf node) { |
- Instantiator makeLeftHandSide = visit(node.leftHandSide); |
- Instantiator makeObject = visit(node.iterable); |
- Instantiator makeBody = visit(node.body); |
- return (arguments) { |
- return new ForOf(makeLeftHandSide(arguments), makeObject(arguments), |
- makeBody(arguments)); |
- }; |
- } |
- |
- TODO(String name) { |
- throw new UnimplementedError('$this.$name'); |
- } |
- |
- Instantiator visitWhile(While node) { |
- Instantiator makeCondition = visit(node.condition); |
- Instantiator makeBody = visit(node.body); |
- return (arguments) { |
- return new While(makeCondition(arguments), makeBody(arguments)); |
- }; |
- } |
- |
- Instantiator visitDo(Do node) { |
- Instantiator makeBody = visit(node.body); |
- Instantiator makeCondition = visit(node.condition); |
- return (arguments) { |
- return new Do(makeBody(arguments), makeCondition(arguments)); |
- }; |
- } |
- |
- Instantiator visitContinue(Continue node) => |
- (arguments) => new Continue(node.targetLabel); |
- |
- Instantiator visitBreak(Break node) => |
- (arguments) => new Break(node.targetLabel); |
- |
- Instantiator visitReturn(Return node) { |
- Instantiator makeExpression = visitNullable(node.value); |
- return (arguments) => new Return(makeExpression(arguments)); |
- } |
- |
- Instantiator visitDartYield(DartYield node) { |
- Instantiator makeExpression = visit(node.expression); |
- return (arguments) => |
- new DartYield(makeExpression(arguments), node.hasStar); |
- } |
- |
- Instantiator visitThrow(Throw node) { |
- Instantiator makeExpression = visit(node.expression); |
- return (arguments) => new Throw(makeExpression(arguments)); |
- } |
- |
- Instantiator visitTry(Try node) { |
- Instantiator makeBody = visit(node.body); |
- Instantiator makeCatch = visitNullable(node.catchPart); |
- Instantiator makeFinally = visitNullable(node.finallyPart); |
- return (arguments) => new Try( |
- makeBody(arguments), makeCatch(arguments), makeFinally(arguments)); |
- } |
- |
- Instantiator visitCatch(Catch node) { |
- Instantiator makeDeclaration = visit(node.declaration); |
- Instantiator makeBody = visit(node.body); |
- return (arguments) => |
- new Catch(makeDeclaration(arguments), makeBody(arguments)); |
- } |
- |
- Instantiator visitSwitch(Switch node) { |
- Instantiator makeKey = visit(node.key); |
- Iterable<Instantiator> makeCases = node.cases.map(visit); |
- return (arguments) { |
- return new Switch( |
- makeKey(arguments), |
- makeCases |
- .map((Instantiator makeCase) => makeCase(arguments)) |
- .toList()); |
- }; |
- } |
- |
- Instantiator visitCase(Case node) { |
- Instantiator makeExpression = visit(node.expression); |
- Instantiator makeBody = visit(node.body); |
- return (arguments) { |
- return new Case(makeExpression(arguments), makeBody(arguments)); |
- }; |
- } |
- |
- Instantiator visitDefault(Default node) { |
- Instantiator makeBody = visit(node.body); |
- return (arguments) { |
- return new Default(makeBody(arguments)); |
- }; |
- } |
- |
- Instantiator visitFunctionDeclaration(FunctionDeclaration node) { |
- Instantiator makeName = visit(node.name); |
- Instantiator makeFunction = visit(node.function); |
- return (arguments) => |
- new FunctionDeclaration(makeName(arguments), makeFunction(arguments)); |
- } |
- |
- Instantiator visitLabeledStatement(LabeledStatement node) { |
- Instantiator makeBody = visit(node.body); |
- return (arguments) => new LabeledStatement(node.label, makeBody(arguments)); |
- } |
- |
- Instantiator visitLiteralStatement(LiteralStatement node) => |
- TODO('visitLiteralStatement'); |
- Instantiator visitLiteralExpression(LiteralExpression node) => |
- TODO('visitLiteralExpression'); |
- |
- Instantiator visitVariableDeclarationList(VariableDeclarationList node) { |
- List<Instantiator> declarationMakers = |
- node.declarations.map(visit).toList(); |
- return (arguments) { |
- List<VariableInitialization> declarations = <VariableInitialization>[]; |
- for (Instantiator instantiator in declarationMakers) { |
- var result = instantiator(arguments); |
- declarations.add(result); |
- } |
- return new VariableDeclarationList(node.keyword, declarations); |
- }; |
- } |
- |
- Instantiator visitAssignment(Assignment node) { |
- Instantiator makeLeftHandSide = visit(node.leftHandSide); |
- String op = node.op; |
- Instantiator makeValue = visitNullable(node.value); |
- return (arguments) { |
- return new Assignment.compound( |
- makeLeftHandSide(arguments), op, makeValue(arguments)); |
- }; |
- } |
- |
- Instantiator visitVariableInitialization(VariableInitialization node) { |
- Instantiator makeDeclaration = visit(node.declaration); |
- Instantiator makeValue = visitNullable(node.value); |
- return (arguments) { |
- return new VariableInitialization( |
- makeDeclaration(arguments), makeValue(arguments)); |
- }; |
- } |
- |
- Instantiator visitConditional(Conditional cond) { |
- Instantiator makeCondition = visit(cond.condition); |
- Instantiator makeThen = visit(cond.then); |
- Instantiator makeOtherwise = visit(cond.otherwise); |
- return (arguments) => new Conditional(makeCondition(arguments), |
- makeThen(arguments), makeOtherwise(arguments)); |
- } |
- |
- Instantiator visitNew(New node) => |
- handleCallOrNew(node, (target, arguments) => new New(target, arguments)); |
- |
- Instantiator visitCall(Call node) => |
- handleCallOrNew(node, (target, arguments) => new Call(target, arguments)); |
- |
- Instantiator handleCallOrNew(Call node, finish(target, arguments)) { |
- Instantiator makeTarget = visit(node.target); |
- Iterable<Instantiator> argumentMakers = |
- node.arguments.map(visitSplayableExpression).toList(); |
- |
- // TODO(sra): Avoid copying call arguments if no interpolation or forced |
- // copying. |
- return (arguments) { |
- Node target = makeTarget(arguments); |
- List<Expression> callArguments = <Expression>[]; |
- for (Instantiator instantiator in argumentMakers) { |
- var result = instantiator(arguments); |
- if (result is Iterable) { |
- callArguments.addAll(result); |
- } else { |
- callArguments.add(result); |
- } |
- } |
- return finish(target, callArguments.toList(growable: false)); |
- }; |
- } |
- |
- Instantiator visitBinary(Binary node) { |
- Instantiator makeLeft = visit(node.left); |
- Instantiator makeRight = visit(node.right); |
- String op = node.op; |
- return (arguments) => |
- new Binary(op, makeLeft(arguments), makeRight(arguments)); |
- } |
- |
- Instantiator visitPrefix(Prefix node) { |
- Instantiator makeOperand = visit(node.argument); |
- String op = node.op; |
- return (arguments) => new Prefix(op, makeOperand(arguments)); |
- } |
- |
- Instantiator visitPostfix(Postfix node) { |
- Instantiator makeOperand = visit(node.argument); |
- String op = node.op; |
- return (arguments) => new Postfix(op, makeOperand(arguments)); |
- } |
- |
- Instantiator visitThis(This node) => (arguments) => new This(); |
- Instantiator visitSuper(Super node) => (arguments) => new Super(); |
- |
- Instantiator visitIdentifier(Identifier node) => |
- (arguments) => new Identifier(node.name); |
- |
- Instantiator visitSpread(Spread node) => |
- (args) => new Spread(visit(node.argument)(args)); |
- |
- Instantiator visitYield(Yield node) => |
- (args) => new Yield(node.value != null ? visit(node.value)(args) : null, |
- star: node.star); |
- |
- Instantiator visitRestParameter(RestParameter node) => |
- (args) => new RestParameter(visit(node.parameter)(args)); |
- |
- Instantiator visitAccess(PropertyAccess node) { |
- Instantiator makeReceiver = visit(node.receiver); |
- Instantiator makeSelector = visit(node.selector); |
- return (arguments) => |
- new PropertyAccess(makeReceiver(arguments), makeSelector(arguments)); |
- } |
- |
- Instantiator visitNamedFunction(NamedFunction node) { |
- Instantiator makeDeclaration = visit(node.name); |
- Instantiator makeFunction = visit(node.function); |
- return (arguments) => |
- new NamedFunction(makeDeclaration(arguments), makeFunction(arguments)); |
- } |
- |
- Instantiator visitFunctionExpression(FunctionExpression node) { |
- List<Instantiator> paramMakers = node.params.map(visitSplayable).toList(); |
- Instantiator makeBody = visit(node.body); |
- // TODO(sra): Avoid copying params if no interpolation or forced copying. |
- return (arguments) { |
- List<Parameter> params = <Parameter>[]; |
- for (Instantiator instantiator in paramMakers) { |
- var result = instantiator(arguments); |
- if (result is Iterable) { |
- params.addAll(result); |
- } else { |
- params.add(result); |
- } |
- } |
- var body = makeBody(arguments); |
- if (node is ArrowFun) { |
- return new ArrowFun(params, body); |
- } else if (node is Fun) { |
- return new Fun(params, body); |
- } else { |
- throw "Unknown FunctionExpression type ${node.runtimeType}: $node"; |
- } |
- }; |
- } |
- |
- Instantiator visitFun(Fun node) => visitFunctionExpression(node); |
- |
- Instantiator visitArrowFun(ArrowFun node) => visitFunctionExpression(node); |
- |
- Instantiator visitLiteralBool(LiteralBool node) => |
- (arguments) => new LiteralBool(node.value); |
- |
- Instantiator visitLiteralString(LiteralString node) => |
- (arguments) => new LiteralString(node.value); |
- |
- Instantiator visitLiteralNumber(LiteralNumber node) => |
- (arguments) => new LiteralNumber(node.value); |
- |
- Instantiator visitLiteralNull(LiteralNull node) => |
- (arguments) => new LiteralNull(); |
- |
- Instantiator visitArrayInitializer(ArrayInitializer node) { |
- // TODO(sra): Implement splicing? |
- List<Instantiator> elementMakers = |
- node.elements.map(visit).toList(growable: false); |
- return (arguments) { |
- List<Expression> elements = elementMakers |
- .map((Instantiator instantiator) => instantiator(arguments)) |
- .toList(growable: false); |
- return new ArrayInitializer(elements); |
- }; |
- } |
- |
- Instantiator visitArrayHole(ArrayHole node) { |
- return (arguments) => new ArrayHole(); |
- } |
- |
- Instantiator visitObjectInitializer(ObjectInitializer node) { |
- List<Instantiator> propertyMakers = |
- node.properties.map(visitSplayable).toList(); |
- return (arguments) { |
- List<Property> properties = <Property>[]; |
- for (Instantiator instantiator in propertyMakers) { |
- var result = instantiator(arguments); |
- if (result is Iterable) { |
- properties.addAll(result); |
- } else { |
- properties.add(result); |
- } |
- } |
- return new ObjectInitializer(properties); |
- }; |
- } |
- |
- Instantiator visitProperty(Property node) { |
- Instantiator makeName = visit(node.name); |
- Instantiator makeValue = visit(node.value); |
- return (arguments) { |
- return new Property(makeName(arguments), makeValue(arguments)); |
- }; |
- } |
- |
- Instantiator visitRegExpLiteral(RegExpLiteral node) => |
- (arguments) => new RegExpLiteral(node.pattern); |
- |
- Instantiator visitTemplateString(TemplateString node) { |
- Iterable makeElements = |
- node.elements.map((e) => e is String ? e : visit(e)); |
- return (arguments) { |
- return new TemplateString(makeElements |
- .map((m) => m is String ? m : m(arguments)) |
- .toList(growable: false)); |
- }; |
- } |
- |
- Instantiator visitTaggedTemplate(TaggedTemplate node) { |
- Instantiator makeTag = visit(node.tag); |
- Instantiator makeTemplate = visit(node.template); |
- return (arguments) { |
- return new TaggedTemplate(makeTag(arguments), makeTemplate(arguments)); |
- }; |
- } |
- |
- Instantiator visitClassDeclaration(ClassDeclaration node) { |
- Instantiator makeClass = visit(node.classExpr); |
- return (arguments) { |
- return new ClassDeclaration(makeClass(arguments)); |
- }; |
- } |
- |
- Instantiator visitClassExpression(ClassExpression node) { |
- List<Instantiator> makeMethods = |
- node.methods.map(visitSplayableExpression).toList(growable: true); |
- Instantiator makeName = visit(node.name); |
- Instantiator makeHeritage = visit(node.heritage); |
- |
- return (arguments) { |
- var methods = <Method>[]; |
- for (Instantiator instantiator in makeMethods) { |
- var result = instantiator(arguments); |
- if (result is Iterable) { |
- methods.addAll(result); |
- } else { |
- methods.add(result); |
- } |
- } |
- return new ClassExpression( |
- makeName(arguments), makeHeritage(arguments), methods); |
- }; |
- } |
- |
- Instantiator visitMethod(Method node) { |
- Instantiator makeName = visit(node.name); |
- Instantiator makeFunction = visit(node.function); |
- return (arguments) { |
- return new Method(makeName(arguments), makeFunction(arguments), |
- isGetter: node.isGetter, |
- isSetter: node.isSetter, |
- isStatic: node.isStatic); |
- }; |
- } |
- |
- Instantiator visitComment(Comment node) => |
- (arguments) => new Comment(node.comment); |
- |
- Instantiator visitCommentExpression(CommentExpression node) { |
- Instantiator makeExpr = visit(node.expression); |
- return (arguments) { |
- return new CommentExpression(node.comment, makeExpr(arguments)); |
- }; |
- } |
- |
- Instantiator visitAwait(Await node) { |
- Instantiator makeExpression = visit(node.expression); |
- return (arguments) { |
- return new Await(makeExpression(arguments)); |
- }; |
- } |
- |
- // Note: these are not supported yet in the interpolation grammar. |
- Instantiator visitModule(Module node) => throw new UnimplementedError(); |
- Instantiator visitNameSpecifier(NameSpecifier node) => |
- throw new UnimplementedError(); |
- |
- Instantiator visitImportDeclaration(ImportDeclaration node) => |
- throw new UnimplementedError(); |
- |
- Instantiator visitExportDeclaration(ExportDeclaration node) => |
- throw new UnimplementedError(); |
- |
- Instantiator visitExportClause(ExportClause node) => |
- throw new UnimplementedError(); |
- |
- Instantiator visitAnyTypeRef(AnyTypeRef node) => |
- throw new UnimplementedError(); |
- |
- Instantiator visitUnknownTypeRef(UnknownTypeRef node) => |
- throw new UnimplementedError(); |
- |
- Instantiator visitArrayTypeRef(ArrayTypeRef node) => |
- throw new UnimplementedError(); |
- |
- Instantiator visitFunctionTypeRef(FunctionTypeRef node) => |
- throw new UnimplementedError(); |
- |
- Instantiator visitGenericTypeRef(GenericTypeRef node) => |
- throw new UnimplementedError(); |
- |
- Instantiator visitQualifiedTypeRef(QualifiedTypeRef node) => |
- throw new UnimplementedError(); |
- |
- Instantiator visitOptionalTypeRef(OptionalTypeRef node) => |
- throw new UnimplementedError(); |
- |
- Instantiator visitRecordTypeRef(RecordTypeRef node) => |
- throw new UnimplementedError(); |
- |
- Instantiator visitUnionTypeRef(UnionTypeRef node) => |
- throw new UnimplementedError(); |
- |
- @override |
- Instantiator visitDestructuredVariable(DestructuredVariable node) { |
- Instantiator makeName = visit(node.name); |
- Instantiator makeStructure = visit(node.structure); |
- Instantiator makeDefaultValue = visit(node.defaultValue); |
- return (arguments) { |
- return new DestructuredVariable( |
- name: makeName(arguments), |
- structure: makeStructure(arguments), |
- defaultValue: makeDefaultValue(arguments)); |
- }; |
- } |
- |
- @override |
- Instantiator visitArrayBindingPattern(ArrayBindingPattern node) { |
- List<Instantiator> makeVars = node.variables.map(this.visit).toList(); |
- return (arguments) { |
- return new ArrayBindingPattern( |
- makeVars.map((m) => m(arguments)).toList()); |
- }; |
- } |
- |
- @override |
- Instantiator visitObjectBindingPattern(ObjectBindingPattern node) { |
- List<Instantiator> makeVars = node.variables.map(this.visit).toList(); |
- return (arguments) { |
- return new ObjectBindingPattern( |
- makeVars.map((m) => m(arguments)).toList()); |
- }; |
- } |
- |
- @override |
- Instantiator visitSimpleBindingPattern(SimpleBindingPattern node) => |
- (arguments) => new SimpleBindingPattern(new Identifier(node.name.name)); |
-} |
- |
-/** |
- * InterpolatedNodeAnalysis determines which AST trees contain |
- * [InterpolatedNode]s, and the names of the named interpolated nodes. |
- */ |
-class InterpolatedNodeAnalysis extends BaseVisitor { |
- final Set<Node> containsInterpolatedNode = new Set<Node>(); |
- final Set<String> holeNames = new Set<String>(); |
- int count = 0; |
- |
- InterpolatedNodeAnalysis(); |
- |
- bool containsInterpolatedNodes(Node node) => |
- containsInterpolatedNode.contains(node); |
- |
- void visit(Node node) { |
- node.accept(this); |
- } |
- |
- void visitNode(Node node) { |
- int before = count; |
- node.visitChildren(this); |
- if (count != before) containsInterpolatedNode.add(node); |
- return null; |
- } |
- |
- visitInterpolatedNode(InterpolatedNode node) { |
- containsInterpolatedNode.add(node); |
- if (node.isNamed) holeNames.add(node.nameOrPosition); |
- ++count; |
- } |
-} |