| 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 library backend_ast_emitter; | 5 library backend_ast_emitter; |
| 6 | 6 |
| 7 import '../tree_ir/tree_ir_nodes.dart' as tree; | 7 import '../tree_ir/tree_ir_nodes.dart' as tree; |
| 8 import 'backend_ast_nodes.dart'; | 8 import 'backend_ast_nodes.dart'; |
| 9 import '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
| 10 import '../constants/values.dart'; | 10 import '../constants/values.dart'; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 // TODO(johnniwinther): Split into function/block state. | 22 // TODO(johnniwinther): Split into function/block state. |
| 23 class BuilderContext<T> { | 23 class BuilderContext<T> { |
| 24 /// Builder context for the enclosing function, or null if the current | 24 /// Builder context for the enclosing function, or null if the current |
| 25 /// function is not a local function. | 25 /// function is not a local function. |
| 26 BuilderContext<T> _parent; | 26 BuilderContext<T> _parent; |
| 27 | 27 |
| 28 /// Variables to be hoisted at the top of the current function. | 28 /// Variables to be hoisted at the top of the current function. |
| 29 final List<VariableDeclaration> variables = <VariableDeclaration>[]; | 29 final List<VariableDeclaration> variables = <VariableDeclaration>[]; |
| 30 | 30 |
| 31 /// Maps variables to their name. | 31 /// Maps variables to their name. |
| 32 final Map<tree.Variable, String> variableNames = <tree.Variable, String>{}; | 32 final Map<tree.Variable, String> variableNames; |
| 33 | 33 |
| 34 /// Maps local constants to their name. | 34 /// Maps local constants to their name. |
| 35 final Map<VariableElement, String> constantNames = | 35 final Map<VariableElement, String> constantNames = |
| 36 <VariableElement, String>{}; | 36 <VariableElement, String>{}; |
| 37 | 37 |
| 38 /// Variables that have had their declaration created. | 38 /// Variables that have had their declaration created. |
| 39 final Set<tree.Variable> declaredVariables = new Set<tree.Variable>(); | 39 final Set<tree.Variable> declaredVariables = new Set<tree.Variable>(); |
| 40 | 40 |
| 41 /// Variable names that have already been used. Used to avoid name clashes. | 41 /// Variable names that have already been used. Used to avoid name clashes. |
| 42 final Set<String> usedVariableNames; | 42 final Set<String> usedVariableNames; |
| 43 | 43 |
| 44 /// Statements emitted by the most recent call to [visitStatement]. | 44 /// Statements emitted by the most recent call to [visitStatement]. |
| 45 List<T> _statementBuffer = <T>[]; | 45 List<T> _statementBuffer = <T>[]; |
| 46 | 46 |
| 47 /// The element currently being emitted. | 47 /// The element currently being emitted. |
| 48 ExecutableElement currentElement; | 48 ExecutableElement currentElement; |
| 49 | 49 |
| 50 /// Bookkeeping object needed to synthesize a variable declaration. | 50 /// Bookkeeping object needed to synthesize a variable declaration. |
| 51 final modelx.VariableList variableList | 51 final modelx.VariableList variableList |
| 52 = new modelx.VariableList(tree.Modifiers.EMPTY); | 52 = new modelx.VariableList(tree.Modifiers.EMPTY); |
| 53 | 53 |
| 54 /// Input to [visitStatement]. Denotes the statement that will execute next | 54 /// Input to [visitStatement]. Denotes the statement that will execute next |
| 55 /// if the statements produced by [visitStatement] complete normally. | 55 /// if the statements produced by [visitStatement] complete normally. |
| 56 /// Set to null if control will fall over the end of the method. | 56 /// Set to null if control will fall over the end of the method. |
| 57 tree.Statement fallthrough = null; | 57 tree.Statement fallthrough = null; |
| 58 | 58 |
| 59 /// Labels that could not be eliminated using fallthrough. | 59 /// Labels that could not be eliminated using fallthrough. |
| 60 final Set<tree.Label> _usedLabels = new Set<tree.Label>(); | 60 final Set<tree.Label> _usedLabels = new Set<tree.Label>(); |
| 61 | 61 |
| 62 final bool inInitializer; |
| 63 |
| 62 /// The first dart_tree statement that is not converted to a variable | 64 /// The first dart_tree statement that is not converted to a variable |
| 63 /// initializer. | 65 /// initializer. |
| 64 tree.Statement firstStatement; | 66 tree.Statement firstStatement; |
| 65 | 67 |
| 66 BuilderContext() : usedVariableNames = new Set<String>(); | 68 BuilderContext() : usedVariableNames = new Set<String>(), |
| 69 inInitializer = false, |
| 70 variableNames = <tree.Variable, String>{}; |
| 67 | 71 |
| 68 BuilderContext.inner(BuilderContext<T> parent) | 72 BuilderContext.inner(BuilderContext<T> parent) |
| 69 : this._parent = parent, | 73 : this._parent = parent, |
| 70 usedVariableNames = parent.usedVariableNames; | 74 usedVariableNames = parent.usedVariableNames, |
| 75 inInitializer = false, |
| 76 variableNames = <tree.Variable, String>{}; |
| 77 |
| 78 BuilderContext.initializer(BuilderContext<T> parent) |
| 79 : this._parent = parent, |
| 80 usedVariableNames = parent.usedVariableNames, |
| 81 inInitializer = true, |
| 82 variableNames = |
| 83 new Map<tree.Variable, String>.from(parent.variableNames); |
| 71 | 84 |
| 72 // TODO(johnniwinther): Fully encapsulate handling of parameter, variable | 85 // TODO(johnniwinther): Fully encapsulate handling of parameter, variable |
| 73 // and local funciton declarations. | 86 // and local funciton declarations. |
| 74 void addDeclaration(tree.Variable variable, [Expression initializer]) { | 87 void addDeclaration(tree.Variable variable, [Expression initializer]) { |
| 75 assert(!declaredVariables.contains(variable)); | 88 assert(!declaredVariables.contains(variable)); |
| 76 String name = getVariableName(variable); | 89 String name = getVariableName(variable); |
| 77 VariableDeclaration decl = new VariableDeclaration(name, initializer); | 90 VariableDeclaration decl = new VariableDeclaration(name, initializer); |
| 78 decl.element = variable.element; | 91 decl.element = variable.element; |
| 79 declaredVariables.add(variable); | 92 declaredVariables.add(variable); |
| 80 variables.add(decl); | 93 variables.add(decl); |
| 81 } | 94 } |
| 82 | 95 |
| 83 /// Generates a name for the given variable and synthesizes an element for it, | 96 /// Generates a name for the given variable and synthesizes an element for it, |
| 84 /// if necessary. | 97 /// if necessary. |
| 85 String getVariableName(tree.Variable variable) { | 98 String getVariableName(tree.Variable variable) { |
| 86 // If the variable belongs to an enclosing function, ask the parent emitter | 99 // If the variable belongs to an enclosing function, ask the parent emitter |
| 87 // for the variable name. | 100 // for the variable name. |
| 88 if (variable.host != currentElement) { | 101 if (!inInitializer && variable.host != currentElement) { |
| 89 return _parent.getVariableName(variable); | 102 return _parent.getVariableName(variable); |
| 90 } | 103 } |
| 91 | 104 |
| 92 // Get the name if we already have one. | 105 // Get the name if we already have one. |
| 93 String name = variableNames[variable]; | 106 String name = variableNames[variable]; |
| 94 if (name != null) { | 107 if (name != null) { |
| 95 return name; | 108 return name; |
| 96 } | 109 } |
| 97 | 110 |
| 98 // Synthesize a variable name that isn't used elsewhere. | 111 // Synthesize a variable name that isn't used elsewhere. |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 /// Translates the dart_tree IR to Dart backend AST. | 198 /// Translates the dart_tree IR to Dart backend AST. |
| 186 /// An instance of this class should only be used once; a fresh emitter | 199 /// An instance of this class should only be used once; a fresh emitter |
| 187 /// must be created for each function to be emitted. | 200 /// must be created for each function to be emitted. |
| 188 class ASTEmitter | 201 class ASTEmitter |
| 189 extends tree.Visitor1<dynamic, Expression, BuilderContext<Statement>> { | 202 extends tree.Visitor1<dynamic, Expression, BuilderContext<Statement>> { |
| 190 | 203 |
| 191 ExecutableDefinition emit(tree.ExecutableDefinition definition, | 204 ExecutableDefinition emit(tree.ExecutableDefinition definition, |
| 192 BuilderContext<Statement> context) { | 205 BuilderContext<Statement> context) { |
| 193 if (definition is tree.FieldDefinition) { | 206 if (definition is tree.FieldDefinition) { |
| 194 return emitField(definition, context); | 207 return emitField(definition, context); |
| 208 } else if (definition is tree.ConstructorDefinition) { |
| 209 return emitConstructor(definition, context); |
| 195 } | 210 } |
| 196 assert(definition is tree.FunctionDefinition); | 211 assert(definition is tree.FunctionDefinition); |
| 197 return emitFunction(definition, context); | 212 return emitFunction(definition, context); |
| 198 } | 213 } |
| 199 | 214 |
| 200 FieldDefinition emitField(tree.FieldDefinition definition, | 215 FieldDefinition emitField(tree.FieldDefinition definition, |
| 201 BuilderContext<Statement> context) { | 216 BuilderContext<Statement> context) { |
| 202 context.currentElement = definition.element; | 217 context.currentElement = definition.element; |
| 203 Expression initializer; | 218 Expression initializer; |
| 204 if (definition.hasInitializer) { | 219 if (definition.hasInitializer) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 232 return onlyStatement.expression; | 247 return onlyStatement.expression; |
| 233 } | 248 } |
| 234 } | 249 } |
| 235 Statement body = new Block(bodyParts); | 250 Statement body = new Block(bodyParts); |
| 236 FunctionExpression function = | 251 FunctionExpression function = |
| 237 new FunctionExpression(new Parameters([]), body); | 252 new FunctionExpression(new Parameters([]), body); |
| 238 function.element = null; | 253 function.element = null; |
| 239 return new CallFunction(function, []); | 254 return new CallFunction(function, []); |
| 240 } | 255 } |
| 241 | 256 |
| 257 bool _recognizeTrailingReturn(Statement statement) { |
| 258 if (statement is Return) { |
| 259 Expression expr = statement.expression; |
| 260 if (expr == null || expr is Literal && expr.value.isNull) { |
| 261 return true; |
| 262 } |
| 263 } |
| 264 return false; |
| 265 } |
| 266 |
| 267 FunctionExpression emitConstructor(tree.ConstructorDefinition definition, |
| 268 BuilderContext<Statement> context) { |
| 269 context.currentElement = definition.element; |
| 270 |
| 271 Parameters parameters = emitRootParameters(definition, context); |
| 272 |
| 273 // Declare parameters. |
| 274 for (tree.Variable param in definition.parameters) { |
| 275 context.variableNames[param] = param.element.name; |
| 276 context.usedVariableNames.add(param.element.name); |
| 277 context.declaredVariables.add(param); |
| 278 } |
| 279 |
| 280 List<Expression> initializers; |
| 281 Statement body; |
| 282 |
| 283 if (!definition.isAbstract) { |
| 284 initializers = |
| 285 definition.initializers.map((tree.Initializer initializer) { |
| 286 return visitExpression(initializer, context); |
| 287 }).toList(); |
| 288 |
| 289 context.firstStatement = definition.body; |
| 290 visitStatement(definition.body, context); |
| 291 context.removeTrailingReturn(_recognizeTrailingReturn); |
| 292 |
| 293 // Some of the variable declarations have already been added |
| 294 // if their first assignment could be pulled into the initializer. |
| 295 // Add the remaining variable declarations now. |
| 296 for (tree.Variable variable in context.variableNames.keys) { |
| 297 if (!context.declaredVariables.contains(variable)) { |
| 298 context.addDeclaration(variable); |
| 299 } |
| 300 } |
| 301 |
| 302 // Add constant declarations. |
| 303 List<VariableDeclaration> constants = <VariableDeclaration>[]; |
| 304 for (ConstDeclaration constDecl in definition.localConstants) { |
| 305 if (!context.constantNames.containsKey(constDecl.element)) { |
| 306 continue; // Discard unused constants declarations. |
| 307 } |
| 308 String name = context.getConstantName(constDecl.element); |
| 309 Expression value = |
| 310 ConstantEmitter.createExpression(constDecl.expression, context); |
| 311 VariableDeclaration decl = new VariableDeclaration(name, value); |
| 312 decl.element = constDecl.element; |
| 313 constants.add(decl); |
| 314 } |
| 315 |
| 316 List<Statement> bodyParts = []; |
| 317 if (constants.length > 0) { |
| 318 bodyParts.add(new VariableDeclarations(constants, isConst: true)); |
| 319 } |
| 320 if (context.variables.length > 0) { |
| 321 bodyParts.add(new VariableDeclarations(context.variables)); |
| 322 } |
| 323 bodyParts.addAll(context.statements); |
| 324 |
| 325 body = new Block(bodyParts); |
| 326 |
| 327 } |
| 328 FunctionType functionType = context.currentElement.type; |
| 329 |
| 330 return new ConstructorDefinition( |
| 331 parameters, |
| 332 body, |
| 333 initializers, |
| 334 context.currentElement.name, definition.element.isConst) |
| 335 ..element = context.currentElement; |
| 336 } |
| 337 |
| 242 FunctionExpression emitFunction(tree.FunctionDefinition definition, | 338 FunctionExpression emitFunction(tree.FunctionDefinition definition, |
| 243 BuilderContext<Statement> context) { | 339 BuilderContext<Statement> context) { |
| 244 context.currentElement = definition.element; | 340 context.currentElement = definition.element; |
| 245 | 341 |
| 246 Parameters parameters = emitRootParameters(definition, context); | 342 Parameters parameters = emitRootParameters(definition, context); |
| 247 | 343 |
| 248 // Declare parameters. | 344 // Declare parameters. |
| 249 for (tree.Variable param in definition.parameters) { | 345 for (tree.Variable param in definition.parameters) { |
| 250 context.variableNames[param] = param.element.name; | 346 context.variableNames[param] = param.element.name; |
| 251 context.usedVariableNames.add(param.element.name); | 347 context.usedVariableNames.add(param.element.name); |
| 252 context.declaredVariables.add(param); | 348 context.declaredVariables.add(param); |
| 253 } | 349 } |
| 254 | 350 |
| 255 Statement body; | 351 Statement body; |
| 256 if (definition.isAbstract) { | 352 if (definition.isAbstract) { |
| 257 body = new EmptyStatement(); | 353 body = new EmptyStatement(); |
| 258 } else { | 354 } else { |
| 259 context.firstStatement = definition.body; | 355 context.firstStatement = definition.body; |
| 260 visitStatement(definition.body, context); | 356 visitStatement(definition.body, context); |
| 261 context.removeTrailingReturn((Statement statement) { | 357 context.removeTrailingReturn(_recognizeTrailingReturn); |
| 262 if (statement is Return) { | |
| 263 Expression expr = statement.expression; | |
| 264 if (expr is Literal && expr.value.isNull) { | |
| 265 return true; | |
| 266 } | |
| 267 } | |
| 268 return false; | |
| 269 }); | |
| 270 | 358 |
| 271 // Some of the variable declarations have already been added | 359 // Some of the variable declarations have already been added |
| 272 // if their first assignment could be pulled into the initializer. | 360 // if their first assignment could be pulled into the initializer. |
| 273 // Add the remaining variable declarations now. | 361 // Add the remaining variable declarations now. |
| 274 for (tree.Variable variable in context.variableNames.keys) { | 362 for (tree.Variable variable in context.variableNames.keys) { |
| 275 if (!context.declaredVariables.contains(variable)) { | 363 if (!context.declaredVariables.contains(variable)) { |
| 276 context.addDeclaration(variable); | 364 context.addDeclaration(variable); |
| 277 } | 365 } |
| 278 } | 366 } |
| 279 | 367 |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 | 551 |
| 464 context.addStatement(new ExpressionStatement(makeAssignment( | 552 context.addStatement(new ExpressionStatement(makeAssignment( |
| 465 visitVariable(stmt.variable, context), | 553 visitVariable(stmt.variable, context), |
| 466 definition))); | 554 definition))); |
| 467 visitStatement(stmt.next, context); | 555 visitStatement(stmt.next, context); |
| 468 } | 556 } |
| 469 | 557 |
| 470 @override | 558 @override |
| 471 void visitReturn(tree.Return stmt, | 559 void visitReturn(tree.Return stmt, |
| 472 BuilderContext<Statement> context) { | 560 BuilderContext<Statement> context) { |
| 473 Expression inner = visitExpression(stmt.value, context); | 561 if (context.currentElement.isGenerativeConstructor && |
| 474 context.addStatement(new Return(inner)); | 562 !context.inInitializer) { |
| 563 assert(() { |
| 564 tree.Expression value = stmt.value; |
| 565 return value is tree.Constant && value.value.isNull; |
| 566 }); |
| 567 context.addStatement(new Return(null)); |
| 568 } else { |
| 569 Expression inner = visitExpression(stmt.value, context); |
| 570 context.addStatement(new Return(inner)); |
| 571 } |
| 475 } | 572 } |
| 476 | 573 |
| 477 @override | 574 @override |
| 478 void visitBreak(tree.Break stmt, | 575 void visitBreak(tree.Break stmt, |
| 479 BuilderContext<Statement> context) { | 576 BuilderContext<Statement> context) { |
| 480 tree.Statement fall = context.fallthrough; | 577 tree.Statement fall = context.fallthrough; |
| 481 if (stmt.target.binding.next == fall) { | 578 if (stmt.target.binding.next == fall) { |
| 482 // Fall through to break target | 579 // Fall through to break target |
| 483 } else if (fall is tree.Break && fall.target == stmt.target) { | 580 } else if (fall is tree.Break && fall.target == stmt.target) { |
| 484 // Fall through to equivalent break | 581 // Fall through to equivalent break |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 } | 677 } |
| 581 | 678 |
| 582 @override | 679 @override |
| 583 Expression visitTypeOperator(tree.TypeOperator exp, | 680 Expression visitTypeOperator(tree.TypeOperator exp, |
| 584 BuilderContext<Statement> context) { | 681 BuilderContext<Statement> context) { |
| 585 return new TypeOperator(visitExpression(exp.receiver, context), | 682 return new TypeOperator(visitExpression(exp.receiver, context), |
| 586 exp.operator, | 683 exp.operator, |
| 587 TypeGenerator.createType(exp.type)); | 684 TypeGenerator.createType(exp.type)); |
| 588 } | 685 } |
| 589 | 686 |
| 590 List<Argument> emitArguments(tree.Invoke exp, | 687 List<Argument> emitArguments(List<Expression> arguments, |
| 591 BuilderContext<Statement> context) { | 688 Selector selector) { |
| 592 List<tree.Expression> args = exp.arguments; | 689 int positionalArgumentCount = selector.positionalArgumentCount; |
| 593 int positionalArgumentCount = exp.selector.positionalArgumentCount; | |
| 594 List<Argument> result = new List<Argument>.generate(positionalArgumentCount, | 690 List<Argument> result = new List<Argument>.generate(positionalArgumentCount, |
| 595 (i) => visitExpression(exp.arguments[i], context)); | 691 (i) => arguments[i]); |
| 596 for (int i = 0; i < exp.selector.namedArgumentCount; ++i) { | 692 for (int i = 0; i < selector.namedArgumentCount; ++i) { |
| 597 result.add(new NamedArgument(exp.selector.namedArguments[i], | 693 result.add(new NamedArgument(selector.namedArguments[i], |
| 598 visitExpression( | 694 arguments[positionalArgumentCount + i])); |
| 599 exp.arguments[positionalArgumentCount + i], context))); | |
| 600 } | 695 } |
| 601 return result; | 696 return result; |
| 602 } | 697 } |
| 603 | 698 |
| 699 List<Expression> visitArgumentList(List<tree.Expression> arguments, |
| 700 BuilderContext context) { |
| 701 return arguments |
| 702 .map((tree.Expression argument) => visitExpression(argument, context)) |
| 703 .toList(); |
| 704 } |
| 705 |
| 604 @override | 706 @override |
| 605 Expression visitInvokeStatic(tree.InvokeStatic exp, | 707 Expression visitInvokeStatic(tree.InvokeStatic exp, |
| 606 BuilderContext<Statement> context) { | 708 BuilderContext<Statement> context) { |
| 607 switch (exp.selector.kind) { | 709 switch (exp.selector.kind) { |
| 608 case SelectorKind.GETTER: | 710 case SelectorKind.GETTER: |
| 609 return new Identifier(exp.target.name)..element = exp.target; | 711 return new Identifier(exp.target.name)..element = exp.target; |
| 610 | 712 |
| 611 case SelectorKind.SETTER: | 713 case SelectorKind.SETTER: |
| 612 return new Assignment( | 714 return new Assignment( |
| 613 new Identifier(exp.target.name)..element = exp.target, | 715 new Identifier(exp.target.name)..element = exp.target, |
| 614 '=', | 716 '=', |
| 615 visitExpression(exp.arguments[0], context)); | 717 visitExpression(exp.arguments[0], context)); |
| 616 | 718 |
| 617 case SelectorKind.CALL: | 719 case SelectorKind.CALL: |
| 618 return new CallStatic( | 720 return new CallStatic( |
| 619 null, exp.target.name, emitArguments(exp, context)) | 721 null, exp.target.name, |
| 620 ..element = exp.target; | 722 emitArguments(visitArgumentList(exp.arguments, context), |
| 723 exp.selector)) |
| 724 ..element = exp.target; |
| 621 | 725 |
| 622 default: | 726 default: |
| 623 throw "Unexpected selector kind: ${exp.selector.kind}"; | 727 throw "Unexpected selector kind: ${exp.selector.kind}"; |
| 624 } | 728 } |
| 625 } | 729 } |
| 626 | 730 |
| 627 Expression emitMethodCall(tree.Invoke exp, Receiver receiver, | 731 Expression emitMethodCall(tree.Invoke exp, Receiver receiver, |
| 628 BuilderContext<Statement> context) { | 732 BuilderContext<Statement> context) { |
| 629 List<Argument> args = emitArguments(exp, context); | 733 List<Argument> args = |
| 734 emitArguments(visitArgumentList(exp.arguments, context), exp.selector); |
| 630 switch (exp.selector.kind) { | 735 switch (exp.selector.kind) { |
| 631 case SelectorKind.CALL: | 736 case SelectorKind.CALL: |
| 632 if (exp.selector.name == "call") { | 737 if (exp.selector.name == "call") { |
| 633 return new CallFunction(receiver, args); | 738 return new CallFunction(receiver, args); |
| 634 } | 739 } |
| 635 return new CallMethod(receiver, exp.selector.name, args); | 740 return new CallMethod(receiver, exp.selector.name, args); |
| 636 | 741 |
| 637 case SelectorKind.OPERATOR: | 742 case SelectorKind.OPERATOR: |
| 638 if (args.length == 0) { | 743 if (args.length == 0) { |
| 639 String name = exp.selector.name; | 744 String name = exp.selector.name; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 | 778 |
| 674 @override | 779 @override |
| 675 Expression visitInvokeSuperMethod(tree.InvokeSuperMethod exp, | 780 Expression visitInvokeSuperMethod(tree.InvokeSuperMethod exp, |
| 676 BuilderContext<Statement> context) { | 781 BuilderContext<Statement> context) { |
| 677 return emitMethodCall(exp, new SuperReceiver(), context); | 782 return emitMethodCall(exp, new SuperReceiver(), context); |
| 678 } | 783 } |
| 679 | 784 |
| 680 @override | 785 @override |
| 681 Expression visitInvokeConstructor(tree.InvokeConstructor exp, | 786 Expression visitInvokeConstructor(tree.InvokeConstructor exp, |
| 682 BuilderContext<Statement> context) { | 787 BuilderContext<Statement> context) { |
| 683 List args = emitArguments(exp, context); | 788 List<Argument> args = |
| 789 emitArguments(visitArgumentList(exp.arguments, context), exp.selector); |
| 684 FunctionElement constructor = exp.target; | 790 FunctionElement constructor = exp.target; |
| 685 String name = constructor.name.isEmpty ? null : constructor.name; | 791 String name = constructor.name.isEmpty ? null : constructor.name; |
| 686 return new CallNew(TypeGenerator.createType(exp.type), | 792 return new CallNew(TypeGenerator.createType(exp.type), |
| 687 args, | 793 args, |
| 688 constructorName: name, | 794 constructorName: name, |
| 689 isConst: exp.constant != null) | 795 isConst: exp.constant != null) |
| 690 ..constructor = constructor | 796 ..constructor = constructor |
| 691 ..dartType = exp.type; | 797 ..dartType = exp.type; |
| 692 } | 798 } |
| 693 | 799 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 743 BuilderContext<Statement> context) { | 849 BuilderContext<Statement> context) { |
| 744 assert(context.variableNames[node.variable] == null); | 850 assert(context.variableNames[node.variable] == null); |
| 745 String name = context.getVariableName(node.variable); | 851 String name = context.getVariableName(node.variable); |
| 746 FunctionExpression inner = makeSubFunction(node.definition, context); | 852 FunctionExpression inner = makeSubFunction(node.definition, context); |
| 747 inner.name = name; | 853 inner.name = name; |
| 748 FunctionDeclaration decl = new FunctionDeclaration(inner); | 854 FunctionDeclaration decl = new FunctionDeclaration(inner); |
| 749 context.declaredVariables.add(node.variable); | 855 context.declaredVariables.add(node.variable); |
| 750 context.addStatement(decl); | 856 context.addStatement(decl); |
| 751 visitStatement(node.next, context); | 857 visitStatement(node.next, context); |
| 752 } | 858 } |
| 859 |
| 860 List<Statement> buildInInitializerContext(tree.Statement root, |
| 861 BuilderContext context) { |
| 862 BuilderContext inner = new BuilderContext<Statement>.initializer(context); |
| 863 inner.currentElement = context.currentElement; |
| 864 visitStatement(root, inner); |
| 865 List<Statement> bodyParts; |
| 866 for (tree.Variable variable in inner.variableNames.keys) { |
| 867 if (!context.declaredVariables.contains(variable)) { |
| 868 inner.addDeclaration(variable); |
| 869 } |
| 870 } |
| 871 if (inner.variables.length > 0) { |
| 872 bodyParts = new List<Statement>(); |
| 873 bodyParts.add(new VariableDeclarations(inner.variables)); |
| 874 bodyParts.addAll(inner.statements); |
| 875 } else { |
| 876 bodyParts = inner.statements; |
| 877 } |
| 878 return bodyParts; |
| 879 } |
| 880 |
| 881 @override |
| 882 Expression visitFieldInitializer(tree.FieldInitializer node, |
| 883 BuilderContext<Statement> context) { |
| 884 return new FieldInitializer(node.element, |
| 885 ensureExpression(buildInInitializerContext(node.body, context))); |
| 886 } |
| 887 |
| 888 @override |
| 889 Expression visitSuperInitializer(tree.SuperInitializer node, |
| 890 BuilderContext<Statement> context) { |
| 891 List<Argument> arguments = node.arguments.map((tree.Statement argument) { |
| 892 return ensureExpression(buildInInitializerContext(argument, context)); |
| 893 }).toList(); |
| 894 return new SuperInitializer(node.target, |
| 895 emitArguments(arguments, node.selector)); |
| 896 } |
| 753 } | 897 } |
| 754 | 898 |
| 755 class TypeGenerator { | 899 class TypeGenerator { |
| 756 | 900 |
| 757 /// TODO(johnniwinther): Remove this when issue 21283 has been resolved. | 901 /// TODO(johnniwinther): Remove this when issue 21283 has been resolved. |
| 758 static int pseudoNameCounter = 0; | 902 static int pseudoNameCounter = 0; |
| 759 | 903 |
| 760 static Parameter emitParameter(DartType type, | 904 static Parameter emitParameter(DartType type, |
| 761 BuilderContext<Statement> context, | 905 BuilderContext<Statement> context, |
| 762 {String name, | 906 {String name, |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1092 : super(name, ElementKind.VARIABLE, enclosingElement, variables, null); | 1236 : super(name, ElementKind.VARIABLE, enclosingElement, variables, null); |
| 1093 | 1237 |
| 1094 ExecutableElement get executableContext => enclosingElement; | 1238 ExecutableElement get executableContext => enclosingElement; |
| 1095 | 1239 |
| 1096 ExecutableElement get memberContext => executableContext.memberContext; | 1240 ExecutableElement get memberContext => executableContext.memberContext; |
| 1097 | 1241 |
| 1098 bool get isLocal => true; | 1242 bool get isLocal => true; |
| 1099 | 1243 |
| 1100 LibraryElement get implementationLibrary => enclosingElement.library; | 1244 LibraryElement get implementationLibrary => enclosingElement.library; |
| 1101 } | 1245 } |
| OLD | NEW |