Chromium Code Reviews| 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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 86 // and local funciton declarations. | 86 // and local funciton declarations. |
| 87 void addDeclaration(tree.Variable variable, [Expression initializer]) { | 87 void addDeclaration(tree.Variable variable, [Expression initializer]) { |
| 88 assert(!declaredVariables.contains(variable)); | 88 assert(!declaredVariables.contains(variable)); |
| 89 String name = getVariableName(variable); | 89 String name = getVariableName(variable); |
| 90 VariableDeclaration decl = new VariableDeclaration(name, initializer); | 90 VariableDeclaration decl = new VariableDeclaration(name, initializer); |
| 91 decl.element = variable.element; | 91 decl.element = variable.element; |
| 92 declaredVariables.add(variable); | 92 declaredVariables.add(variable); |
| 93 variables.add(decl); | 93 variables.add(decl); |
| 94 } | 94 } |
| 95 | 95 |
| 96 /// Creates an [Identifier] referring to the given variable. | |
| 97 Expression makeVariableAccess(tree.Variable variable) { | |
| 98 return new Identifier(getVariableName(variable)) | |
| 99 ..element = variable.element; | |
| 100 } | |
| 101 | |
| 96 /// Generates a name for the given variable and synthesizes an element for it, | 102 /// Generates a name for the given variable and synthesizes an element for it, |
| 97 /// if necessary. | 103 /// if necessary. |
| 98 String getVariableName(tree.Variable variable) { | 104 String getVariableName(tree.Variable variable) { |
| 99 // If the variable belongs to an enclosing function, ask the parent emitter | 105 // If the variable belongs to an enclosing function, ask the parent emitter |
| 100 // for the variable name. | 106 // for the variable name. |
| 101 if (!inInitializer && variable.host != currentElement) { | 107 if (!inInitializer && variable.host != currentElement) { |
| 102 return _parent.getVariableName(variable); | 108 return _parent.getVariableName(variable); |
| 103 } | 109 } |
| 104 | 110 |
| 105 // Get the name if we already have one. | 111 // Get the name if we already have one. |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 529 // Try to pull into initializer. | 535 // Try to pull into initializer. |
| 530 if (context.firstStatement == stmt && isFirstOccurrence && isDeclaredHere) { | 536 if (context.firstStatement == stmt && isFirstOccurrence && isDeclaredHere) { |
| 531 if (isNullLiteral(definition)) definition = null; | 537 if (isNullLiteral(definition)) definition = null; |
| 532 context.addDeclaration(stmt.variable, definition); | 538 context.addDeclaration(stmt.variable, definition); |
| 533 context.firstStatement = stmt.next; | 539 context.firstStatement = stmt.next; |
| 534 visitStatement(stmt.next, context); | 540 visitStatement(stmt.next, context); |
| 535 return; | 541 return; |
| 536 } | 542 } |
| 537 | 543 |
| 538 // Emit a variable declaration if we are required to do so. | 544 // Emit a variable declaration if we are required to do so. |
| 539 // This is to ensure that a fresh closure variable is created. | 545 // For captured variables, this ensures that a fresh variable is created. |
| 540 if (stmt.isDeclaration) { | 546 if (stmt.isDeclaration) { |
| 541 assert(isFirstOccurrence); | 547 assert(isFirstOccurrence); |
| 542 assert(isDeclaredHere); | 548 assert(isDeclaredHere); |
| 543 if (isNullLiteral(definition)) definition = null; | 549 if (isNullLiteral(definition)) definition = null; |
| 544 VariableDeclaration decl = new VariableDeclaration(name, definition) | 550 VariableDeclaration decl = new VariableDeclaration(name, definition) |
| 545 ..element = stmt.variable.element; | 551 ..element = stmt.variable.element; |
| 546 context.declaredVariables.add(stmt.variable); | 552 context.declaredVariables.add(stmt.variable); |
| 547 context.addStatement(new VariableDeclarations([decl])); | 553 context.addStatement(new VariableDeclarations([decl])); |
| 548 visitStatement(stmt.next, context); | 554 visitStatement(stmt.next, context); |
| 549 return; | 555 return; |
| 550 } | 556 } |
| 551 | 557 |
| 552 context.addStatement(new ExpressionStatement(makeAssignment( | 558 context.addStatement(new ExpressionStatement(makeAssignment( |
| 553 visitVariable(stmt.variable, context), | 559 context.makeVariableAccess(stmt.variable), |
| 554 definition))); | 560 definition))); |
| 555 visitStatement(stmt.next, context); | 561 visitStatement(stmt.next, context); |
| 556 } | 562 } |
| 557 | 563 |
| 558 @override | 564 @override |
| 559 void visitReturn(tree.Return stmt, | 565 void visitReturn(tree.Return stmt, |
| 560 BuilderContext<Statement> context) { | 566 BuilderContext<Statement> context) { |
| 561 if (context.currentElement.isGenerativeConstructor && | 567 if (context.currentElement.isGenerativeConstructor && |
| 562 !context.inInitializer) { | 568 !context.inInitializer) { |
| 563 assert(() { | 569 assert(() { |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 824 visitExpression(exp.right, context)); | 830 visitExpression(exp.right, context)); |
| 825 } | 831 } |
| 826 | 832 |
| 827 @override | 833 @override |
| 828 Expression visitNot(tree.Not exp, | 834 Expression visitNot(tree.Not exp, |
| 829 BuilderContext<Statement> context) { | 835 BuilderContext<Statement> context) { |
| 830 return new UnaryOperator('!', visitExpression(exp.operand, context)); | 836 return new UnaryOperator('!', visitExpression(exp.operand, context)); |
| 831 } | 837 } |
| 832 | 838 |
| 833 @override | 839 @override |
| 834 Expression visitVariable(tree.Variable exp, | 840 Expression visitVariableUse(tree.VariableUse exp, |
| 835 BuilderContext<Statement> context) { | 841 BuilderContext<Statement> context) { |
| 836 return new Identifier(context.getVariableName(exp)) | 842 return context.makeVariableAccess(exp.variable); |
| 837 ..element = exp.element; | |
| 838 } | 843 } |
| 839 | 844 |
| 840 FunctionExpression makeSubFunction(tree.FunctionDefinition function, | 845 FunctionExpression makeSubFunction(tree.FunctionDefinition function, |
| 841 BuilderContext<Statement> context) { | 846 BuilderContext<Statement> context) { |
| 842 return emit(function, new BuilderContext<Statement>.inner(context)); | 847 return emit(function, new BuilderContext<Statement>.inner(context)); |
| 843 } | 848 } |
| 844 | 849 |
| 845 @override | 850 @override |
| 846 Expression visitFunctionExpression(tree.FunctionExpression exp, | 851 Expression visitFunctionExpression(tree.FunctionExpression exp, |
| 847 BuilderContext<Statement> context) { | 852 BuilderContext<Statement> context) { |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1226 visitStatement(definition.body); | 1231 visitStatement(definition.body); |
| 1227 environment = oldEnvironment; | 1232 environment = oldEnvironment; |
| 1228 shadowedParameters = oldShadow; | 1233 shadowedParameters = oldShadow; |
| 1229 | 1234 |
| 1230 for (int i=0; i<definition.parameters.length; i++) { | 1235 for (int i=0; i<definition.parameters.length; i++) { |
| 1231 tree.Variable param = definition.parameters[i]; | 1236 tree.Variable param = definition.parameters[i]; |
| 1232 if (hasShadowedUse.remove(param)) { | 1237 if (hasShadowedUse.remove(param)) { |
| 1233 tree.Variable newParam = new tree.Variable(definition.element, | 1238 tree.Variable newParam = new tree.Variable(definition.element, |
| 1234 param.element); | 1239 param.element); |
| 1235 definition.parameters[i] = newParam; | 1240 definition.parameters[i] = newParam; |
| 1236 definition.body = new tree.Assign(param, newParam, definition.body); | 1241 definition.body = new tree.Assign(param, new tree.VariableUse(newParam), |
| 1242 definition.body); | |
| 1237 newParam.writeCount = 1; // Being a parameter counts as a write. | 1243 newParam.writeCount = 1; // Being a parameter counts as a write. |
| 1244 param.writeCount--; // Not a parameter anymore. | |
| 1238 } | 1245 } |
| 1239 } | 1246 } |
| 1240 } | 1247 } |
| 1241 | 1248 |
| 1242 visitVariable(tree.Variable variable) { | 1249 @override |
| 1250 invalidateMovingAssignment(tree.Variable variable) { | |
|
Kevin Millikin (Google)
2015/02/27 12:17:18
This seems like a rename refactoring that went wro
asgerf
2015/02/27 12:20:53
Ah, thanks.
| |
| 1243 if (shadowedParameters.contains(variable)) { | 1251 if (shadowedParameters.contains(variable)) { |
| 1244 hasShadowedUse.add(variable); | 1252 hasShadowedUse.add(variable); |
| 1245 } | 1253 } |
| 1246 } | 1254 } |
| 1247 | 1255 |
| 1248 } | 1256 } |
| 1249 | 1257 |
| 1250 // TODO(johnniwinther): Remove this when the dart `backend_ast` does not need | 1258 // TODO(johnniwinther): Remove this when the dart `backend_ast` does not need |
| 1251 // [Element] for entities. | 1259 // [Element] for entities. |
| 1252 class _SyntheticLocalVariableElement extends modelx.VariableElementX | 1260 class _SyntheticLocalVariableElement extends modelx.VariableElementX |
| 1253 implements LocalVariableElement { | 1261 implements LocalVariableElement { |
| 1254 | 1262 |
| 1255 _SyntheticLocalVariableElement(String name, | 1263 _SyntheticLocalVariableElement(String name, |
| 1256 ExecutableElement enclosingElement, | 1264 ExecutableElement enclosingElement, |
| 1257 modelx.VariableList variables) | 1265 modelx.VariableList variables) |
| 1258 : super(name, ElementKind.VARIABLE, enclosingElement, variables, null); | 1266 : super(name, ElementKind.VARIABLE, enclosingElement, variables, null); |
| 1259 | 1267 |
| 1260 ExecutableElement get executableContext => enclosingElement; | 1268 ExecutableElement get executableContext => enclosingElement; |
| 1261 | 1269 |
| 1262 ExecutableElement get memberContext => executableContext.memberContext; | 1270 ExecutableElement get memberContext => executableContext.memberContext; |
| 1263 | 1271 |
| 1264 bool get isLocal => true; | 1272 bool get isLocal => true; |
| 1265 | 1273 |
| 1266 LibraryElement get implementationLibrary => enclosingElement.library; | 1274 LibraryElement get implementationLibrary => enclosingElement.library; |
| 1267 } | 1275 } |
| OLD | NEW |