| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of js_ast; | 5 part of js_ast; |
| 6 | 6 |
| 7 class TemplateManager { | 7 class TemplateManager { |
| 8 Map<String, Template> expressionTemplates = new Map<String, Template>(); | 8 Map<String, Template> expressionTemplates = new Map<String, Template>(); |
| 9 Map<String, Template> statementTemplates = new Map<String, Template>(); | 9 Map<String, Template> statementTemplates = new Map<String, Template>(); |
| 10 | 10 |
| 11 TemplateManager(); | 11 TemplateManager(); |
| 12 | 12 |
| 13 | |
| 14 Template lookupExpressionTemplate(String source) { | 13 Template lookupExpressionTemplate(String source) { |
| 15 return expressionTemplates[source]; | 14 return expressionTemplates[source]; |
| 16 } | 15 } |
| 17 | 16 |
| 18 Template defineExpressionTemplate(String source, Node ast) { | 17 Template defineExpressionTemplate(String source, Node ast) { |
| 19 Template template = | 18 Template template = |
| 20 new Template(source, ast, isExpression: true, forceCopy: false); | 19 new Template(source, ast, isExpression: true, forceCopy: false); |
| 21 expressionTemplates[source] = template; | 20 expressionTemplates[source] = template; |
| 22 return template; | 21 return template; |
| 23 } | 22 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 48 | 47 |
| 49 Instantiator instantiator; | 48 Instantiator instantiator; |
| 50 | 49 |
| 51 int positionalArgumentCount = -1; | 50 int positionalArgumentCount = -1; |
| 52 | 51 |
| 53 // Null, unless there are named holes. | 52 // Null, unless there are named holes. |
| 54 List<String> holeNames; | 53 List<String> holeNames; |
| 55 bool get isPositional => holeNames == null; | 54 bool get isPositional => holeNames == null; |
| 56 | 55 |
| 57 Template(this.source, this.ast, | 56 Template(this.source, this.ast, |
| 58 {this.isExpression: true, this.forceCopy: false}) { | 57 {this.isExpression: true, this.forceCopy: false}) { |
| 59 _compile(); | 58 _compile(); |
| 60 } | 59 } |
| 61 | 60 |
| 62 Template.withExpressionResult(this.ast) | 61 Template.withExpressionResult(this.ast) |
| 63 : source = null, isExpression = true, forceCopy = false { | 62 : source = null, |
| 63 isExpression = true, |
| 64 forceCopy = false { |
| 64 assert(ast is Expression); | 65 assert(ast is Expression); |
| 65 assert(_checkNoPlaceholders()); | 66 assert(_checkNoPlaceholders()); |
| 66 positionalArgumentCount = 0; | 67 positionalArgumentCount = 0; |
| 67 instantiator = (arguments) => ast; | 68 instantiator = (arguments) => ast; |
| 68 } | 69 } |
| 69 | 70 |
| 70 Template.withStatementResult(this.ast) | 71 Template.withStatementResult(this.ast) |
| 71 : source = null, isExpression = false, forceCopy = false { | 72 : source = null, |
| 73 isExpression = false, |
| 74 forceCopy = false { |
| 72 assert(ast is Statement); | 75 assert(ast is Statement); |
| 73 assert(_checkNoPlaceholders()); | 76 assert(_checkNoPlaceholders()); |
| 74 positionalArgumentCount = 0; | 77 positionalArgumentCount = 0; |
| 75 instantiator = (arguments) => ast; | 78 instantiator = (arguments) => ast; |
| 76 } | 79 } |
| 77 | 80 |
| 78 bool _checkNoPlaceholders() { | 81 bool _checkNoPlaceholders() { |
| 79 InstantiatorGeneratorVisitor generator = | 82 InstantiatorGeneratorVisitor generator = |
| 80 new InstantiatorGeneratorVisitor(false); | 83 new InstantiatorGeneratorVisitor(false); |
| 81 generator.compile(ast); | 84 generator.compile(ast); |
| 82 return generator.analysis.count == 0; | 85 return generator.analysis.count == 0; |
| 83 } | 86 } |
| 84 | 87 |
| 85 void _compile() { | 88 void _compile() { |
| 86 InstantiatorGeneratorVisitor generator = | 89 InstantiatorGeneratorVisitor generator = |
| 87 new InstantiatorGeneratorVisitor(forceCopy); | 90 new InstantiatorGeneratorVisitor(forceCopy); |
| 88 instantiator = generator.compile(ast); | 91 instantiator = generator.compile(ast); |
| 89 positionalArgumentCount = generator.analysis.count; | 92 positionalArgumentCount = generator.analysis.count; |
| 90 Set<String> names = generator.analysis.holeNames; | 93 Set<String> names = generator.analysis.holeNames; |
| 91 holeNames = names.toList(growable:false); | 94 holeNames = names.toList(growable: false); |
| 92 } | 95 } |
| 93 | 96 |
| 94 /// Instantiates the template with the given [arguments]. | 97 /// Instantiates the template with the given [arguments]. |
| 95 /// | 98 /// |
| 96 /// This method fills in the holes with the given arguments. The [arguments] | 99 /// This method fills in the holes with the given arguments. The [arguments] |
| 97 /// must be either a [List] or a [Map]. | 100 /// must be either a [List] or a [Map]. |
| 98 Node instantiate(var arguments) { | 101 Node instantiate(var arguments) { |
| 99 if (arguments is List) { | 102 if (arguments is List) { |
| 100 if (arguments.length != positionalArgumentCount) { | 103 if (arguments.length != positionalArgumentCount) { |
| 101 throw 'Wrong number of template arguments, given ${arguments.length}, ' | 104 throw 'Wrong number of template arguments, given ${arguments.length}, ' |
| (...skipping 27 matching lines...) Expand all Loading... |
| 129 } | 132 } |
| 130 } | 133 } |
| 131 | 134 |
| 132 /** | 135 /** |
| 133 * An Instantiator is a Function that generates a JS AST tree or List of | 136 * An Instantiator is a Function that generates a JS AST tree or List of |
| 134 * trees. [arguments] is a List for positional templates, or Map for | 137 * trees. [arguments] is a List for positional templates, or Map for |
| 135 * named templates. | 138 * named templates. |
| 136 */ | 139 */ |
| 137 typedef Instantiator(var arguments); | 140 typedef Instantiator(var arguments); |
| 138 | 141 |
| 139 | |
| 140 /** | 142 /** |
| 141 * InstantiatorGeneratorVisitor compiles a template. This class compiles a tree | 143 * InstantiatorGeneratorVisitor compiles a template. This class compiles a tree |
| 142 * containing [InterpolatedNode]s into a function that will create a copy of the | 144 * containing [InterpolatedNode]s into a function that will create a copy of the |
| 143 * tree with the interpolated nodes substituted with provided values. | 145 * tree with the interpolated nodes substituted with provided values. |
| 144 */ | 146 */ |
| 145 class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> { | 147 class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> { |
| 146 | |
| 147 final bool forceCopy; | 148 final bool forceCopy; |
| 148 | 149 |
| 149 InterpolatedNodeAnalysis analysis = new InterpolatedNodeAnalysis(); | 150 InterpolatedNodeAnalysis analysis = new InterpolatedNodeAnalysis(); |
| 150 | 151 |
| 151 /** | 152 /** |
| 152 * The entire tree is cloned if [forceCopy] is true. | 153 * The entire tree is cloned if [forceCopy] is true. |
| 153 */ | 154 */ |
| 154 InstantiatorGeneratorVisitor(this.forceCopy); | 155 InstantiatorGeneratorVisitor(this.forceCopy); |
| 155 | 156 |
| 156 Instantiator compile(Node node) { | 157 Instantiator compile(Node node) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 | 227 |
| 227 Instantiator visitInterpolatedParameter(InterpolatedParameter node) { | 228 Instantiator visitInterpolatedParameter(InterpolatedParameter node) { |
| 228 var nameOrPosition = node.nameOrPosition; | 229 var nameOrPosition = node.nameOrPosition; |
| 229 return (arguments) { | 230 return (arguments) { |
| 230 var value = arguments[nameOrPosition]; | 231 var value = arguments[nameOrPosition]; |
| 231 | 232 |
| 232 Identifier toIdentifier(item) { | 233 Identifier toIdentifier(item) { |
| 233 if (item is Identifier) return item; | 234 if (item is Identifier) return item; |
| 234 if (item is String) return new Identifier(item); | 235 if (item is String) return new Identifier(item); |
| 235 return error('Interpolated value #$nameOrPosition is not an Identifier' | 236 return error('Interpolated value #$nameOrPosition is not an Identifier' |
| 236 ' or List of Identifiers: $value'); | 237 ' or List of Identifiers: $value'); |
| 237 } | 238 } |
| 238 if (value is Iterable) return value.map(toIdentifier); | 239 if (value is Iterable) return value.map(toIdentifier); |
| 239 return toIdentifier(value); | 240 return toIdentifier(value); |
| 240 }; | 241 }; |
| 241 } | 242 } |
| 242 | 243 |
| 243 Instantiator visitInterpolatedSelector(InterpolatedSelector node) { | 244 Instantiator visitInterpolatedSelector(InterpolatedSelector node) { |
| 244 // A selector is an expression, as in `a[selector]`. | 245 // A selector is an expression, as in `a[selector]`. |
| 245 // A String argument converted into a LiteralString, so `a.#` with argument | 246 // A String argument converted into a LiteralString, so `a.#` with argument |
| 246 // 'foo' generates `a["foo"]` which prints as `a.foo`. | 247 // 'foo' generates `a["foo"]` which prints as `a.foo`. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 }; | 288 }; |
| 288 } | 289 } |
| 289 | 290 |
| 290 Instantiator visitSplayableStatement(Node node) { | 291 Instantiator visitSplayableStatement(Node node) { |
| 291 if (node is InterpolatedStatement) { | 292 if (node is InterpolatedStatement) { |
| 292 var nameOrPosition = node.nameOrPosition; | 293 var nameOrPosition = node.nameOrPosition; |
| 293 return (arguments) { | 294 return (arguments) { |
| 294 var value = arguments[nameOrPosition]; | 295 var value = arguments[nameOrPosition]; |
| 295 Statement toStatement(item) { | 296 Statement toStatement(item) { |
| 296 if (item is Statement) return item; | 297 if (item is Statement) return item; |
| 297 if (item is Expression) return item.toStatement();; | 298 if (item is Expression) return item.toStatement(); |
| 299 ; |
| 298 return error('Interpolated value #$nameOrPosition is not ' | 300 return error('Interpolated value #$nameOrPosition is not ' |
| 299 'a Statement or List of Statements: $value'); | 301 'a Statement or List of Statements: $value'); |
| 300 } | 302 } |
| 301 if (value is Iterable) return value.map(toStatement); | 303 if (value is Iterable) return value.map(toStatement); |
| 302 return toStatement(value); | 304 return toStatement(value); |
| 303 }; | 305 }; |
| 304 } | 306 } |
| 305 return visit(node); | 307 return visit(node); |
| 306 } | 308 } |
| 307 | 309 |
| 308 Instantiator visitProgram(Program node) { | 310 Instantiator visitProgram(Program node) { |
| 309 List instantiators = node.body.map(visitSplayableStatement).toList(); | 311 List instantiators = node.body.map(visitSplayableStatement).toList(); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 Instantiator visitIfConditionalCompilation(If node) { | 368 Instantiator visitIfConditionalCompilation(If node) { |
| 367 // Special version of visitInterpolatedExpression that permits bools. | 369 // Special version of visitInterpolatedExpression that permits bools. |
| 368 compileCondition(InterpolatedExpression node) { | 370 compileCondition(InterpolatedExpression node) { |
| 369 var nameOrPosition = node.nameOrPosition; | 371 var nameOrPosition = node.nameOrPosition; |
| 370 return (arguments) { | 372 return (arguments) { |
| 371 var value = arguments[nameOrPosition]; | 373 var value = arguments[nameOrPosition]; |
| 372 if (value is bool) return value; | 374 if (value is bool) return value; |
| 373 if (value is Expression) return value; | 375 if (value is Expression) return value; |
| 374 if (value is String) return new Identifier(value); | 376 if (value is String) return new Identifier(value); |
| 375 error('Interpolated value #$nameOrPosition ' | 377 error('Interpolated value #$nameOrPosition ' |
| 376 'is not an Expression: $value'); | 378 'is not an Expression: $value'); |
| 377 }; | 379 }; |
| 378 } | 380 } |
| 379 var makeCondition = compileCondition(node.condition); | 381 var makeCondition = compileCondition(node.condition); |
| 380 Instantiator makeThen = visit(node.then); | 382 Instantiator makeThen = visit(node.then); |
| 381 Instantiator makeOtherwise = visit(node.otherwise); | 383 Instantiator makeOtherwise = visit(node.otherwise); |
| 382 return (arguments) { | 384 return (arguments) { |
| 383 var condition = makeCondition(arguments); | 385 var condition = makeCondition(arguments); |
| 384 if (condition is bool) { | 386 if (condition is bool) { |
| 385 if (condition == true) { | 387 if (condition == true) { |
| 386 return makeThen(arguments); | 388 return makeThen(arguments); |
| 387 } else { | 389 } else { |
| 388 return makeOtherwise(arguments); | 390 return makeOtherwise(arguments); |
| 389 } | 391 } |
| 390 } | 392 } |
| 391 return new If( | 393 return new If(condition, makeThen(arguments), makeOtherwise(arguments)); |
| 392 condition, | |
| 393 makeThen(arguments), | |
| 394 makeOtherwise(arguments)); | |
| 395 }; | 394 }; |
| 396 } | 395 } |
| 397 | 396 |
| 398 Instantiator visitIfNormal(If node) { | 397 Instantiator visitIfNormal(If node) { |
| 399 Instantiator makeCondition = visit(node.condition); | 398 Instantiator makeCondition = visit(node.condition); |
| 400 Instantiator makeThen = visit(node.then); | 399 Instantiator makeThen = visit(node.then); |
| 401 Instantiator makeOtherwise = visit(node.otherwise); | 400 Instantiator makeOtherwise = visit(node.otherwise); |
| 402 return (arguments) { | 401 return (arguments) { |
| 403 return new If( | 402 return new If(makeCondition(arguments), makeThen(arguments), |
| 404 makeCondition(arguments), | |
| 405 makeThen(arguments), | |
| 406 makeOtherwise(arguments)); | 403 makeOtherwise(arguments)); |
| 407 }; | 404 }; |
| 408 } | 405 } |
| 409 | 406 |
| 410 Instantiator visitFor(For node) { | 407 Instantiator visitFor(For node) { |
| 411 Instantiator makeInit = visitNullable(node.init); | 408 Instantiator makeInit = visitNullable(node.init); |
| 412 Instantiator makeCondition = visitNullable(node.condition); | 409 Instantiator makeCondition = visitNullable(node.condition); |
| 413 Instantiator makeUpdate = visitNullable(node.update); | 410 Instantiator makeUpdate = visitNullable(node.update); |
| 414 Instantiator makeBody = visit(node.body); | 411 Instantiator makeBody = visit(node.body); |
| 415 return (arguments) { | 412 return (arguments) { |
| 416 return new For( | 413 return new For(makeInit(arguments), makeCondition(arguments), |
| 417 makeInit(arguments), makeCondition(arguments), makeUpdate(arguments), | 414 makeUpdate(arguments), makeBody(arguments)); |
| 418 makeBody(arguments)); | |
| 419 }; | 415 }; |
| 420 } | 416 } |
| 421 | 417 |
| 422 Instantiator visitForIn(ForIn node) { | 418 Instantiator visitForIn(ForIn node) { |
| 423 Instantiator makeLeftHandSide = visit(node.leftHandSide); | 419 Instantiator makeLeftHandSide = visit(node.leftHandSide); |
| 424 Instantiator makeObject = visit(node.object); | 420 Instantiator makeObject = visit(node.object); |
| 425 Instantiator makeBody = visit(node.body); | 421 Instantiator makeBody = visit(node.body); |
| 426 return (arguments) { | 422 return (arguments) { |
| 427 return new ForIn( | 423 return new ForIn(makeLeftHandSide(arguments), makeObject(arguments), |
| 428 makeLeftHandSide(arguments), | |
| 429 makeObject(arguments), | |
| 430 makeBody(arguments)); | 424 makeBody(arguments)); |
| 431 }; | 425 }; |
| 432 } | 426 } |
| 433 | 427 |
| 434 Instantiator visitForOf(ForOf node) { | 428 Instantiator visitForOf(ForOf node) { |
| 435 Instantiator makeLeftHandSide = visit(node.leftHandSide); | 429 Instantiator makeLeftHandSide = visit(node.leftHandSide); |
| 436 Instantiator makeObject = visit(node.iterable); | 430 Instantiator makeObject = visit(node.iterable); |
| 437 Instantiator makeBody = visit(node.body); | 431 Instantiator makeBody = visit(node.body); |
| 438 return (arguments) { | 432 return (arguments) { |
| 439 return new ForOf( | 433 return new ForOf(makeLeftHandSide(arguments), makeObject(arguments), |
| 440 makeLeftHandSide(arguments), | |
| 441 makeObject(arguments), | |
| 442 makeBody(arguments)); | 434 makeBody(arguments)); |
| 443 }; | 435 }; |
| 444 } | 436 } |
| 445 | 437 |
| 446 TODO(String name) { | 438 TODO(String name) { |
| 447 throw new UnimplementedError('$this.$name'); | 439 throw new UnimplementedError('$this.$name'); |
| 448 } | 440 } |
| 449 | 441 |
| 450 Instantiator visitWhile(While node) { | 442 Instantiator visitWhile(While node) { |
| 451 Instantiator makeCondition = visit(node.condition); | 443 Instantiator makeCondition = visit(node.condition); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 469 Instantiator visitBreak(Break node) => | 461 Instantiator visitBreak(Break node) => |
| 470 (arguments) => new Break(node.targetLabel); | 462 (arguments) => new Break(node.targetLabel); |
| 471 | 463 |
| 472 Instantiator visitReturn(Return node) { | 464 Instantiator visitReturn(Return node) { |
| 473 Instantiator makeExpression = visitNullable(node.value); | 465 Instantiator makeExpression = visitNullable(node.value); |
| 474 return (arguments) => new Return(makeExpression(arguments)); | 466 return (arguments) => new Return(makeExpression(arguments)); |
| 475 } | 467 } |
| 476 | 468 |
| 477 Instantiator visitDartYield(DartYield node) { | 469 Instantiator visitDartYield(DartYield node) { |
| 478 Instantiator makeExpression = visit(node.expression); | 470 Instantiator makeExpression = visit(node.expression); |
| 479 return (arguments) => new DartYield(makeExpression(arguments), node.hasStar)
; | 471 return (arguments) => |
| 472 new DartYield(makeExpression(arguments), node.hasStar); |
| 480 } | 473 } |
| 481 | 474 |
| 482 Instantiator visitThrow(Throw node) { | 475 Instantiator visitThrow(Throw node) { |
| 483 Instantiator makeExpression = visit(node.expression); | 476 Instantiator makeExpression = visit(node.expression); |
| 484 return (arguments) => new Throw(makeExpression(arguments)); | 477 return (arguments) => new Throw(makeExpression(arguments)); |
| 485 } | 478 } |
| 486 | 479 |
| 487 Instantiator visitTry(Try node) { | 480 Instantiator visitTry(Try node) { |
| 488 Instantiator makeBody = visit(node.body); | 481 Instantiator makeBody = visit(node.body); |
| 489 Instantiator makeCatch = visitNullable(node.catchPart); | 482 Instantiator makeCatch = visitNullable(node.catchPart); |
| 490 Instantiator makeFinally = visitNullable(node.finallyPart); | 483 Instantiator makeFinally = visitNullable(node.finallyPart); |
| 491 return (arguments) => new Try( | 484 return (arguments) => new Try( |
| 492 makeBody(arguments), makeCatch(arguments), makeFinally(arguments)); | 485 makeBody(arguments), makeCatch(arguments), makeFinally(arguments)); |
| 493 } | 486 } |
| 494 | 487 |
| 495 Instantiator visitCatch(Catch node) { | 488 Instantiator visitCatch(Catch node) { |
| 496 Instantiator makeDeclaration = visit(node.declaration); | 489 Instantiator makeDeclaration = visit(node.declaration); |
| 497 Instantiator makeBody = visit(node.body); | 490 Instantiator makeBody = visit(node.body); |
| 498 return (arguments) => new Catch( | 491 return (arguments) => |
| 499 makeDeclaration(arguments), makeBody(arguments)); | 492 new Catch(makeDeclaration(arguments), makeBody(arguments)); |
| 500 } | 493 } |
| 501 | 494 |
| 502 Instantiator visitSwitch(Switch node) { | 495 Instantiator visitSwitch(Switch node) { |
| 503 Instantiator makeKey = visit(node.key); | 496 Instantiator makeKey = visit(node.key); |
| 504 Iterable<Instantiator> makeCases = node.cases.map(visit); | 497 Iterable<Instantiator> makeCases = node.cases.map(visit); |
| 505 return (arguments) { | 498 return (arguments) { |
| 506 return new Switch(makeKey(arguments), | 499 return new Switch( |
| 507 makeCases.map((Instantiator makeCase) => makeCase(arguments)) | 500 makeKey(arguments), |
| 508 .toList()); | 501 makeCases |
| 502 .map((Instantiator makeCase) => makeCase(arguments)) |
| 503 .toList()); |
| 509 }; | 504 }; |
| 510 } | 505 } |
| 511 | 506 |
| 512 Instantiator visitCase(Case node) { | 507 Instantiator visitCase(Case node) { |
| 513 Instantiator makeExpression = visit(node.expression); | 508 Instantiator makeExpression = visit(node.expression); |
| 514 Instantiator makeBody = visit(node.body); | 509 Instantiator makeBody = visit(node.body); |
| 515 return (arguments) { | 510 return (arguments) { |
| 516 return new Case(makeExpression(arguments), makeBody(arguments)); | 511 return new Case(makeExpression(arguments), makeBody(arguments)); |
| 517 }; | 512 }; |
| 518 } | 513 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 return new VariableDeclarationList(node.keyword, declarations); | 548 return new VariableDeclarationList(node.keyword, declarations); |
| 554 }; | 549 }; |
| 555 } | 550 } |
| 556 | 551 |
| 557 Instantiator visitAssignment(Assignment node) { | 552 Instantiator visitAssignment(Assignment node) { |
| 558 Instantiator makeLeftHandSide = visit(node.leftHandSide); | 553 Instantiator makeLeftHandSide = visit(node.leftHandSide); |
| 559 String op = node.op; | 554 String op = node.op; |
| 560 Instantiator makeValue = visitNullable(node.value); | 555 Instantiator makeValue = visitNullable(node.value); |
| 561 return (arguments) { | 556 return (arguments) { |
| 562 return new Assignment.compound( | 557 return new Assignment.compound( |
| 563 makeLeftHandSide(arguments), | 558 makeLeftHandSide(arguments), op, makeValue(arguments)); |
| 564 op, | |
| 565 makeValue(arguments)); | |
| 566 }; | 559 }; |
| 567 } | 560 } |
| 568 | 561 |
| 569 Instantiator visitVariableInitialization(VariableInitialization node) { | 562 Instantiator visitVariableInitialization(VariableInitialization node) { |
| 570 Instantiator makeDeclaration = visit(node.declaration); | 563 Instantiator makeDeclaration = visit(node.declaration); |
| 571 Instantiator makeValue = visitNullable(node.value); | 564 Instantiator makeValue = visitNullable(node.value); |
| 572 return (arguments) { | 565 return (arguments) { |
| 573 return new VariableInitialization( | 566 return new VariableInitialization( |
| 574 makeDeclaration(arguments), makeValue(arguments)); | 567 makeDeclaration(arguments), makeValue(arguments)); |
| 575 }; | 568 }; |
| 576 } | 569 } |
| 577 | 570 |
| 578 Instantiator visitConditional(Conditional cond) { | 571 Instantiator visitConditional(Conditional cond) { |
| 579 Instantiator makeCondition = visit(cond.condition); | 572 Instantiator makeCondition = visit(cond.condition); |
| 580 Instantiator makeThen = visit(cond.then); | 573 Instantiator makeThen = visit(cond.then); |
| 581 Instantiator makeOtherwise = visit(cond.otherwise); | 574 Instantiator makeOtherwise = visit(cond.otherwise); |
| 582 return (arguments) => new Conditional( | 575 return (arguments) => new Conditional(makeCondition(arguments), |
| 583 makeCondition(arguments), | 576 makeThen(arguments), makeOtherwise(arguments)); |
| 584 makeThen(arguments), | |
| 585 makeOtherwise(arguments)); | |
| 586 } | 577 } |
| 587 | 578 |
| 588 Instantiator visitNew(New node) => | 579 Instantiator visitNew(New node) => |
| 589 handleCallOrNew(node, (target, arguments) => new New(target, arguments)); | 580 handleCallOrNew(node, (target, arguments) => new New(target, arguments)); |
| 590 | 581 |
| 591 Instantiator visitCall(Call node) => | 582 Instantiator visitCall(Call node) => |
| 592 handleCallOrNew(node, (target, arguments) => new Call(target, arguments)); | 583 handleCallOrNew(node, (target, arguments) => new Call(target, arguments)); |
| 593 | 584 |
| 594 Instantiator handleCallOrNew(Call node, finish(target, arguments)) { | 585 Instantiator handleCallOrNew(Call node, finish(target, arguments)) { |
| 595 Instantiator makeTarget = visit(node.target); | 586 Instantiator makeTarget = visit(node.target); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 Instantiator visitThis(This node) => (arguments) => new This(); | 627 Instantiator visitThis(This node) => (arguments) => new This(); |
| 637 Instantiator visitSuper(Super node) => (arguments) => new Super(); | 628 Instantiator visitSuper(Super node) => (arguments) => new Super(); |
| 638 | 629 |
| 639 Instantiator visitIdentifier(Identifier node) => | 630 Instantiator visitIdentifier(Identifier node) => |
| 640 (arguments) => new Identifier(node.name); | 631 (arguments) => new Identifier(node.name); |
| 641 | 632 |
| 642 Instantiator visitSpread(Spread node) => | 633 Instantiator visitSpread(Spread node) => |
| 643 (args) => new Spread(visit(node.argument)(args)); | 634 (args) => new Spread(visit(node.argument)(args)); |
| 644 | 635 |
| 645 Instantiator visitYield(Yield node) => | 636 Instantiator visitYield(Yield node) => |
| 646 (args) => new Yield( | 637 (args) => new Yield(node.value != null ? visit(node.value)(args) : null, |
| 647 node.value != null ? visit(node.value)(args) : null, star: node.star); | 638 star: node.star); |
| 648 | 639 |
| 649 Instantiator visitRestParameter(RestParameter node) => | 640 Instantiator visitRestParameter(RestParameter node) => |
| 650 (args) => new RestParameter(visit(node.parameter)(args)); | 641 (args) => new RestParameter(visit(node.parameter)(args)); |
| 651 | 642 |
| 652 Instantiator visitAccess(PropertyAccess node) { | 643 Instantiator visitAccess(PropertyAccess node) { |
| 653 Instantiator makeReceiver = visit(node.receiver); | 644 Instantiator makeReceiver = visit(node.receiver); |
| 654 Instantiator makeSelector = visit(node.selector); | 645 Instantiator makeSelector = visit(node.selector); |
| 655 return (arguments) => | 646 return (arguments) => |
| 656 new PropertyAccess(makeReceiver(arguments), makeSelector(arguments)); | 647 new PropertyAccess(makeReceiver(arguments), makeSelector(arguments)); |
| 657 } | 648 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 699 (arguments) => new LiteralString(node.value); | 690 (arguments) => new LiteralString(node.value); |
| 700 | 691 |
| 701 Instantiator visitLiteralNumber(LiteralNumber node) => | 692 Instantiator visitLiteralNumber(LiteralNumber node) => |
| 702 (arguments) => new LiteralNumber(node.value); | 693 (arguments) => new LiteralNumber(node.value); |
| 703 | 694 |
| 704 Instantiator visitLiteralNull(LiteralNull node) => | 695 Instantiator visitLiteralNull(LiteralNull node) => |
| 705 (arguments) => new LiteralNull(); | 696 (arguments) => new LiteralNull(); |
| 706 | 697 |
| 707 Instantiator visitArrayInitializer(ArrayInitializer node) { | 698 Instantiator visitArrayInitializer(ArrayInitializer node) { |
| 708 // TODO(sra): Implement splicing? | 699 // TODO(sra): Implement splicing? |
| 709 List<Instantiator> elementMakers = node.elements | 700 List<Instantiator> elementMakers = |
| 710 .map(visit) | 701 node.elements.map(visit).toList(growable: false); |
| 711 .toList(growable: false); | |
| 712 return (arguments) { | 702 return (arguments) { |
| 713 List<Expression> elements = elementMakers | 703 List<Expression> elements = elementMakers |
| 714 .map((Instantiator instantiator) => instantiator(arguments)) | 704 .map((Instantiator instantiator) => instantiator(arguments)) |
| 715 .toList(growable: false); | 705 .toList(growable: false); |
| 716 return new ArrayInitializer(elements); | 706 return new ArrayInitializer(elements); |
| 717 }; | 707 }; |
| 718 } | 708 } |
| 719 | 709 |
| 720 Instantiator visitArrayHole(ArrayHole node) { | 710 Instantiator visitArrayHole(ArrayHole node) { |
| 721 return (arguments) => new ArrayHole(); | 711 return (arguments) => new ArrayHole(); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 768 } | 758 } |
| 769 | 759 |
| 770 Instantiator visitClassDeclaration(ClassDeclaration node) { | 760 Instantiator visitClassDeclaration(ClassDeclaration node) { |
| 771 Instantiator makeClass = visit(node.classExpr); | 761 Instantiator makeClass = visit(node.classExpr); |
| 772 return (arguments) { | 762 return (arguments) { |
| 773 return new ClassDeclaration(makeClass(arguments)); | 763 return new ClassDeclaration(makeClass(arguments)); |
| 774 }; | 764 }; |
| 775 } | 765 } |
| 776 | 766 |
| 777 Instantiator visitClassExpression(ClassExpression node) { | 767 Instantiator visitClassExpression(ClassExpression node) { |
| 778 List<Instantiator> makeMethods = node.methods.map(visitSplayableExpression) | 768 List<Instantiator> makeMethods = |
| 779 .toList(growable: true); | 769 node.methods.map(visitSplayableExpression).toList(growable: true); |
| 780 Instantiator makeName = visit(node.name); | 770 Instantiator makeName = visit(node.name); |
| 781 Instantiator makeHeritage = visit(node.heritage); | 771 Instantiator makeHeritage = visit(node.heritage); |
| 782 | 772 |
| 783 return (arguments) { | 773 return (arguments) { |
| 784 var methods = <Method>[]; | 774 var methods = <Method>[]; |
| 785 for (Instantiator instantiator in makeMethods) { | 775 for (Instantiator instantiator in makeMethods) { |
| 786 var result = instantiator(arguments); | 776 var result = instantiator(arguments); |
| 787 if (result is Iterable) { | 777 if (result is Iterable) { |
| 788 methods.addAll(result); | 778 methods.addAll(result); |
| 789 } else { | 779 } else { |
| 790 methods.add(result); | 780 methods.add(result); |
| 791 } | 781 } |
| 792 } | 782 } |
| 793 return new ClassExpression( | 783 return new ClassExpression( |
| 794 makeName(arguments), makeHeritage(arguments), methods); | 784 makeName(arguments), makeHeritage(arguments), methods); |
| 795 }; | 785 }; |
| 796 } | 786 } |
| 797 | 787 |
| 798 Instantiator visitMethod(Method node) { | 788 Instantiator visitMethod(Method node) { |
| 799 Instantiator makeName = visit(node.name); | 789 Instantiator makeName = visit(node.name); |
| 800 Instantiator makeFunction = visit(node.function); | 790 Instantiator makeFunction = visit(node.function); |
| 801 return (arguments) { | 791 return (arguments) { |
| 802 return new Method( | 792 return new Method(makeName(arguments), makeFunction(arguments), |
| 803 makeName(arguments), | |
| 804 makeFunction(arguments), | |
| 805 isGetter: node.isGetter, | 793 isGetter: node.isGetter, |
| 806 isSetter: node.isSetter, | 794 isSetter: node.isSetter, |
| 807 isStatic: node.isStatic); | 795 isStatic: node.isStatic); |
| 808 }; | 796 }; |
| 809 } | 797 } |
| 810 | 798 |
| 811 Instantiator visitComment(Comment node) => | 799 Instantiator visitComment(Comment node) => |
| 812 (arguments) => new Comment(node.comment); | 800 (arguments) => new Comment(node.comment); |
| 813 | 801 |
| 814 Instantiator visitCommentExpression(CommentExpression node) { | 802 Instantiator visitCommentExpression(CommentExpression node) { |
| 815 Instantiator makeExpr = visit(node.expression); | 803 Instantiator makeExpr = visit(node.expression); |
| 816 return (arguments) { | 804 return (arguments) { |
| 817 return new CommentExpression(node.comment, makeExpr(arguments)); | 805 return new CommentExpression(node.comment, makeExpr(arguments)); |
| 818 }; | 806 }; |
| 819 } | 807 } |
| 820 | 808 |
| 821 Instantiator visitAwait(Await node) { | 809 Instantiator visitAwait(Await node) { |
| 822 Instantiator makeExpression = visit(node.expression); | 810 Instantiator makeExpression = visit(node.expression); |
| 823 return (arguments) { | 811 return (arguments) { |
| 824 return new Await(makeExpression(arguments)); | 812 return new Await(makeExpression(arguments)); |
| 825 }; | 813 }; |
| 826 } | 814 } |
| 815 |
| 816 // Note: these are not supported yet in the interpolation grammar. |
| 817 Instantiator visitModule(Module node) => throw new UnimplementedError(); |
| 818 Instantiator visitNameSpecifier(NameSpecifier node) => |
| 819 throw new UnimplementedError(); |
| 820 |
| 821 Instantiator visitImportDeclaration(ImportDeclaration node) => |
| 822 throw new UnimplementedError(); |
| 823 |
| 824 Instantiator visitExportDeclaration(ExportDeclaration node) => |
| 825 throw new UnimplementedError(); |
| 826 |
| 827 Instantiator visitExportClause(ExportClause node) => |
| 828 throw new UnimplementedError(); |
| 827 } | 829 } |
| 828 | 830 |
| 829 /** | 831 /** |
| 830 * InterpolatedNodeAnalysis determines which AST trees contain | 832 * InterpolatedNodeAnalysis determines which AST trees contain |
| 831 * [InterpolatedNode]s, and the names of the named interpolated nodes. | 833 * [InterpolatedNode]s, and the names of the named interpolated nodes. |
| 832 */ | 834 */ |
| 833 class InterpolatedNodeAnalysis extends BaseVisitor { | 835 class InterpolatedNodeAnalysis extends BaseVisitor { |
| 834 final Set<Node> containsInterpolatedNode = new Set<Node>(); | 836 final Set<Node> containsInterpolatedNode = new Set<Node>(); |
| 835 final Set<String> holeNames = new Set<String>(); | 837 final Set<String> holeNames = new Set<String>(); |
| 836 int count = 0; | 838 int count = 0; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 850 if (count != before) containsInterpolatedNode.add(node); | 852 if (count != before) containsInterpolatedNode.add(node); |
| 851 return null; | 853 return null; |
| 852 } | 854 } |
| 853 | 855 |
| 854 visitInterpolatedNode(InterpolatedNode node) { | 856 visitInterpolatedNode(InterpolatedNode node) { |
| 855 containsInterpolatedNode.add(node); | 857 containsInterpolatedNode.add(node); |
| 856 if (node.isNamed) holeNames.add(node.nameOrPosition); | 858 if (node.isNamed) holeNames.add(node.nameOrPosition); |
| 857 ++count; | 859 ++count; |
| 858 } | 860 } |
| 859 } | 861 } |
| OLD | NEW |