| 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 20 matching lines...) Expand all Loading... |
| 31 /// Maps variables to their name. | 31 /// Maps variables to their name. |
| 32 final Map<tree.Variable, String> variableNames; | 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 /// Variables that are used as catch handler parameters. |
| 42 final Set<tree.Variable> handlerVariables = new Set<tree.Variable>(); |
| 43 |
| 41 /// Variable names that have already been used. Used to avoid name clashes. | 44 /// Variable names that have already been used. Used to avoid name clashes. |
| 42 final Set<String> usedVariableNames; | 45 final Set<String> usedVariableNames; |
| 43 | 46 |
| 44 /// Statements emitted by the most recent call to [visitStatement]. | 47 /// Statements emitted by the most recent call to [visitStatement]. |
| 45 List<T> _statementBuffer = <T>[]; | 48 List<T> _statementBuffer = <T>[]; |
| 46 | 49 |
| 47 /// The element currently being emitted. | 50 /// The element currently being emitted. |
| 48 ExecutableElement currentElement; | 51 ExecutableElement currentElement; |
| 49 | 52 |
| 50 /// Bookkeeping object needed to synthesize a variable declaration. | 53 /// Bookkeeping object needed to synthesize a variable declaration. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 76 variableNames = <tree.Variable, String>{}; | 79 variableNames = <tree.Variable, String>{}; |
| 77 | 80 |
| 78 BuilderContext.initializer(BuilderContext<T> parent) | 81 BuilderContext.initializer(BuilderContext<T> parent) |
| 79 : this._parent = parent, | 82 : this._parent = parent, |
| 80 usedVariableNames = parent.usedVariableNames, | 83 usedVariableNames = parent.usedVariableNames, |
| 81 inInitializer = true, | 84 inInitializer = true, |
| 82 variableNames = | 85 variableNames = |
| 83 new Map<tree.Variable, String>.from(parent.variableNames); | 86 new Map<tree.Variable, String>.from(parent.variableNames); |
| 84 | 87 |
| 85 // TODO(johnniwinther): Fully encapsulate handling of parameter, variable | 88 // TODO(johnniwinther): Fully encapsulate handling of parameter, variable |
| 86 // and local funciton declarations. | 89 // and local function declarations. |
| 87 void addDeclaration(tree.Variable variable, [Expression initializer]) { | 90 void addDeclaration(tree.Variable variable, [Expression initializer]) { |
| 88 assert(!declaredVariables.contains(variable)); | 91 assert(!declaredVariables.contains(variable)); |
| 89 String name = getVariableName(variable); | 92 String name = getVariableName(variable); |
| 90 VariableDeclaration decl = new VariableDeclaration(name, initializer); | 93 VariableDeclaration decl = new VariableDeclaration(name, initializer); |
| 91 decl.element = variable.element; | 94 decl.element = variable.element; |
| 92 declaredVariables.add(variable); | 95 declaredVariables.add(variable); |
| 93 variables.add(decl); | 96 variables.add(decl); |
| 94 } | 97 } |
| 95 | 98 |
| 96 /// Generates a name for the given variable and synthesizes an element for it, | 99 /// Generates a name for the given variable and synthesizes an element for it, |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 body = new EmptyStatement(); | 356 body = new EmptyStatement(); |
| 354 } else { | 357 } else { |
| 355 context.firstStatement = definition.body; | 358 context.firstStatement = definition.body; |
| 356 visitStatement(definition.body, context); | 359 visitStatement(definition.body, context); |
| 357 context.removeTrailingReturn(_recognizeTrailingReturn); | 360 context.removeTrailingReturn(_recognizeTrailingReturn); |
| 358 | 361 |
| 359 // Some of the variable declarations have already been added | 362 // Some of the variable declarations have already been added |
| 360 // if their first assignment could be pulled into the initializer. | 363 // if their first assignment could be pulled into the initializer. |
| 361 // Add the remaining variable declarations now. | 364 // Add the remaining variable declarations now. |
| 362 for (tree.Variable variable in context.variableNames.keys) { | 365 for (tree.Variable variable in context.variableNames.keys) { |
| 363 if (!context.declaredVariables.contains(variable)) { | 366 if (!context.declaredVariables.contains(variable) && |
| 367 !context.handlerVariables.contains(variable)) { |
| 364 context.addDeclaration(variable); | 368 context.addDeclaration(variable); |
| 365 } | 369 } |
| 366 } | 370 } |
| 367 | 371 |
| 368 // Add constant declarations. | 372 // Add constant declarations. |
| 369 List<VariableDeclaration> constants = <VariableDeclaration>[]; | 373 List<VariableDeclaration> constants = <VariableDeclaration>[]; |
| 370 for (ConstDeclaration constDecl in definition.localConstants) { | 374 for (ConstDeclaration constDecl in definition.localConstants) { |
| 371 if (!context.constantNames.containsKey(constDecl.element)) { | 375 if (!context.constantNames.containsKey(constDecl.element)) { |
| 372 continue; // Discard unused constants declarations. | 376 continue; // Discard unused constants declarations. |
| 373 } | 377 } |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 622 BuilderContext<Statement> context) { | 626 BuilderContext<Statement> context) { |
| 623 Expression condition = visitExpression(stmt.condition, context); | 627 Expression condition = visitExpression(stmt.condition, context); |
| 624 Block body = visitInSubContext(stmt.body, context, fallthrough: stmt); | 628 Block body = visitInSubContext(stmt.body, context, fallthrough: stmt); |
| 625 Statement statement = new While(condition, body); | 629 Statement statement = new While(condition, body); |
| 626 addLabeledStatement(stmt.label, statement, context); | 630 addLabeledStatement(stmt.label, statement, context); |
| 627 | 631 |
| 628 visitStatement(stmt.next, context); | 632 visitStatement(stmt.next, context); |
| 629 } | 633 } |
| 630 | 634 |
| 631 @override | 635 @override |
| 636 void visitTryStatement(tree.TryStatement stmt, |
| 637 BuilderContext<Statement> context) { |
| 638 Block tryBody = visitInSubContext(stmt.tryBody, context); |
| 639 Block catchBody = visitInSubContext(stmt.catchBody, context); |
| 640 CatchBlock catchBlock; |
| 641 tree.Variable exceptionVariable = stmt.catchParameters[0]; |
| 642 context.handlerVariables.add(exceptionVariable); |
| 643 VariableDeclaration exceptionParameter = |
| 644 new VariableDeclaration(context.getVariableName(exceptionVariable)); |
| 645 exceptionParameter.element = exceptionVariable.element; |
| 646 if (stmt.catchParameters.length == 2) { |
| 647 tree.Variable stackTraceVariable = stmt.catchParameters[1]; |
| 648 context.handlerVariables.add(stackTraceVariable); |
| 649 VariableDeclaration stackTraceParameter = |
| 650 new VariableDeclaration(context.getVariableName(stackTraceVariable)); |
| 651 stackTraceParameter.element = stackTraceVariable.element; |
| 652 catchBlock = new CatchBlock(catchBody, |
| 653 exceptionVar: exceptionParameter, |
| 654 stackVar: stackTraceParameter); |
| 655 } else { |
| 656 assert(stmt.catchParameters.length == 1); |
| 657 catchBlock = new CatchBlock(catchBody, |
| 658 exceptionVar: exceptionParameter); |
| 659 } |
| 660 context.addStatement(new Try(tryBody, <CatchBlock>[catchBlock], null)); |
| 661 } |
| 662 |
| 663 @override |
| 632 Expression visitConstant(tree.Constant exp, | 664 Expression visitConstant(tree.Constant exp, |
| 633 BuilderContext<Statement> context) { | 665 BuilderContext<Statement> context) { |
| 634 return ConstantEmitter.createExpression(exp.expression, context); | 666 return ConstantEmitter.createExpression(exp.expression, context); |
| 635 } | 667 } |
| 636 | 668 |
| 637 @override | 669 @override |
| 638 Expression visitThis(tree.This exp, | 670 Expression visitThis(tree.This exp, |
| 639 BuilderContext<Statement> context) { | 671 BuilderContext<Statement> context) { |
| 640 return new This(); | 672 return new This(); |
| 641 } | 673 } |
| (...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1258 : super(name, ElementKind.VARIABLE, enclosingElement, variables, null); | 1290 : super(name, ElementKind.VARIABLE, enclosingElement, variables, null); |
| 1259 | 1291 |
| 1260 ExecutableElement get executableContext => enclosingElement; | 1292 ExecutableElement get executableContext => enclosingElement; |
| 1261 | 1293 |
| 1262 ExecutableElement get memberContext => executableContext.memberContext; | 1294 ExecutableElement get memberContext => executableContext.memberContext; |
| 1263 | 1295 |
| 1264 bool get isLocal => true; | 1296 bool get isLocal => true; |
| 1265 | 1297 |
| 1266 LibraryElement get implementationLibrary => enclosingElement.library; | 1298 LibraryElement get implementationLibrary => enclosingElement.library; |
| 1267 } | 1299 } |
| OLD | NEW |