| OLD | NEW |
| 1 // Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Fletch 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.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
| 4 | 4 |
| 5 library fletchc.closure_environment; | 5 library fletchc.closure_environment; |
| 6 | 6 |
| 7 import 'package:compiler/src/util/util.dart' show | |
| 8 SpannableAssertionFailure; | |
| 9 | |
| 10 import 'package:compiler/src/resolution/semantic_visitor.dart'; | 7 import 'package:compiler/src/resolution/semantic_visitor.dart'; |
| 11 | 8 |
| 12 import 'package:compiler/src/resolution/operators.dart' show | 9 import 'package:compiler/src/resolution/operators.dart' show |
| 13 AssignmentOperator, | 10 AssignmentOperator, |
| 14 BinaryOperator, | 11 BinaryOperator, |
| 15 IncDecOperator, | 12 IncDecOperator, |
| 16 UnaryOperator; | 13 UnaryOperator; |
| 17 | 14 |
| 18 import 'package:compiler/src/elements/elements.dart'; | 15 import 'package:compiler/src/elements/elements.dart'; |
| 19 import 'package:compiler/src/resolution/resolution.dart'; | 16 import 'package:compiler/src/resolution/tree_elements.dart'; |
| 17 import 'package:compiler/src/resolution/send_resolver.dart'; |
| 20 import 'package:compiler/src/tree/tree.dart'; | 18 import 'package:compiler/src/tree/tree.dart'; |
| 21 import 'package:compiler/src/universe/universe.dart'; | 19 import 'package:compiler/src/universe/selector.dart'; |
| 22 import 'package:compiler/src/util/util.dart' show Spannable; | 20 import 'package:compiler/src/universe/call_structure.dart'; |
| 21 import 'package:compiler/src/diagnostics/spannable.dart' show |
| 22 Spannable, |
| 23 SpannableAssertionFailure; |
| 23 import 'package:compiler/src/dart_types.dart'; | 24 import 'package:compiler/src/dart_types.dart'; |
| 24 | 25 |
| 25 enum CaptureMode { | 26 enum CaptureMode { |
| 26 /** | 27 /** |
| 27 * If a local is marked [ByValue], the local is read in closures. | 28 * If a local is marked [ByValue], the local is read in closures. |
| 28 */ | 29 */ |
| 29 ByValue, | 30 ByValue, |
| 30 | 31 |
| 31 /** | 32 /** |
| 32 * If a local is marked [ByReference], a write to the local can be observed | 33 * If a local is marked [ByReference], a write to the local can be observed |
| (...skipping 28 matching lines...) Expand all Loading... |
| 61 final Map<FunctionElement, ClosureInfo> closures = | 62 final Map<FunctionElement, ClosureInfo> closures = |
| 62 <FunctionElement, ClosureInfo>{}; | 63 <FunctionElement, ClosureInfo>{}; |
| 63 | 64 |
| 64 bool shouldBeBoxed(element) => captured[element] == CaptureMode.ByReference; | 65 bool shouldBeBoxed(element) => captured[element] == CaptureMode.ByReference; |
| 65 } | 66 } |
| 66 | 67 |
| 67 class ClosureVisitor | 68 class ClosureVisitor |
| 68 extends SemanticVisitor | 69 extends SemanticVisitor |
| 69 with TraversalSendMixin, | 70 with TraversalSendMixin, |
| 70 SemanticSendResolvedMixin, | 71 SemanticSendResolvedMixin, |
| 71 SendResolverMixin, | |
| 72 BaseImplementationOfLocalsMixin, | 72 BaseImplementationOfLocalsMixin, |
| 73 VariableBulkMixin, | 73 VariableBulkMixin, |
| 74 ParameterBulkMixin, | 74 ParameterBulkMixin, |
| 75 FunctionBulkMixin, | 75 FunctionBulkMixin, |
| 76 ConstructorBulkMixin, | 76 ConstructorBulkMixin, |
| 77 InitializerBulkMixin | 77 InitializerBulkMixin |
| 78 implements SemanticSendVisitor, SemanticDeclarationVisitor { | 78 implements SemanticSendVisitor, SemanticDeclarationVisitor { |
| 79 final ClosureEnvironment closureEnvironment = new ClosureEnvironment(); | 79 final ClosureEnvironment closureEnvironment = new ClosureEnvironment(); |
| 80 | 80 |
| 81 /** | 81 /** |
| (...skipping 11 matching lines...) Expand all Loading... |
| 93 ClosureVisitor(this.element, TreeElements elements) | 93 ClosureVisitor(this.element, TreeElements elements) |
| 94 : super(elements); | 94 : super(elements); |
| 95 | 95 |
| 96 SemanticSendVisitor get sendVisitor => this; | 96 SemanticSendVisitor get sendVisitor => this; |
| 97 SemanticDeclarationVisitor get declVisitor => this; | 97 SemanticDeclarationVisitor get declVisitor => this; |
| 98 | 98 |
| 99 ClosureEnvironment compute() { | 99 ClosureEnvironment compute() { |
| 100 assert(element.memberContext == element); | 100 assert(element.memberContext == element); |
| 101 assert(currentElement == null); | 101 assert(currentElement == null); |
| 102 currentElement = element; | 102 currentElement = element; |
| 103 if (element.node != null) element.node.accept(this); | 103 if (element.node != null) element.resolvedAst.node.accept(this); |
| 104 assert(currentElement == element); | 104 assert(currentElement == element); |
| 105 return closureEnvironment; | 105 return closureEnvironment; |
| 106 } | 106 } |
| 107 | 107 |
| 108 void visitNode(Node node) { | 108 void visitNode(Node node) { |
| 109 node.visitChildren(this); | 109 node.visitChildren(this); |
| 110 } | 110 } |
| 111 | 111 |
| 112 void visitVariableDefinitions(VariableDefinitions node) { | 112 void visitVariableDefinitions(VariableDefinitions node) { |
| 113 for (Node definition in node.definitions) { | 113 for (Node definition in node.definitions) { |
| 114 VariableElement element = elements[definition]; | 114 VariableElement element = elements[definition]; |
| 115 Expression initializer = element.initializer; | 115 Expression initializer = element.initializer; |
| 116 if (initializer != null) initializer.accept(this); | 116 if (initializer != null) initializer.accept(this); |
| 117 } | 117 } |
| 118 } | 118 } |
| 119 | 119 |
| 120 void visitFunctionExpression(FunctionExpression node) { | 120 void visitFunctionExpression(FunctionExpression node) { |
| 121 ExecutableElement oldElement = currentElement; | 121 ExecutableElement oldElement = currentElement; |
| 122 currentElement = elements[node]; | 122 currentElement = elements.getFunctionDefinition(node); |
| 123 if (currentElement != element) { | 123 if (currentElement != element) { |
| 124 ClosureInfo info = new ClosureInfo(); | 124 ClosureInfo info = new ClosureInfo(); |
| 125 closureEnvironment.closures[currentElement] = info; | 125 closureEnvironment.closures[currentElement] = info; |
| 126 } | 126 } |
| 127 if (currentElement.isConstructor) { | 127 if (currentElement.isConstructor) { |
| 128 inInitializers = true; | 128 inInitializers = true; |
| 129 visitInitializers(node, null); | 129 visitInitializers(node, null); |
| 130 inInitializers = false; | 130 inInitializers = false; |
| 131 } | 131 } |
| 132 node.body.accept(this); | 132 node.body.accept(this); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 void handleLocalInvoke( | 220 void handleLocalInvoke( |
| 221 Send node, | 221 Send node, |
| 222 LocalElement element, | 222 LocalElement element, |
| 223 NodeList arguments, | 223 NodeList arguments, |
| 224 CallStructure callStructure, | 224 CallStructure callStructure, |
| 225 _) { | 225 _) { |
| 226 markUsed(element, CaptureMode.ByValue); | 226 markUsed(element, CaptureMode.ByValue); |
| 227 arguments.accept(this); | 227 arguments.accept(this); |
| 228 } | 228 } |
| 229 | 229 |
| 230 void visitThisPropertySet(Send node, Selector selector, Node rhs, _) { | 230 void visitThisPropertySet(Send node, Name name, Node rhs, _) { |
| 231 markThisUsed(); | 231 markThisUsed(); |
| 232 super.visitThisPropertySet(node, selector, rhs, null); | 232 super.visitThisPropertySet(node, name, rhs, null); |
| 233 } | 233 } |
| 234 | 234 |
| 235 void visitLocalVariablePrefix( | 235 void visitLocalVariablePrefix( |
| 236 SendSet node, | 236 SendSet node, |
| 237 LocalVariableElement element, | 237 LocalVariableElement element, |
| 238 IncDecOperator operator, | 238 IncDecOperator operator, |
| 239 _) { | 239 _) { |
| 240 markUsed(element, CaptureMode.ByReference); | 240 markUsed(element, CaptureMode.ByReference); |
| 241 } | 241 } |
| 242 | 242 |
| 243 void visitLocalVariablePostfix( | 243 void visitLocalVariablePostfix( |
| 244 SendSet node, | 244 SendSet node, |
| 245 LocalVariableElement element, | 245 LocalVariableElement element, |
| 246 IncDecOperator operator, | 246 IncDecOperator operator, |
| 247 _) { | 247 _) { |
| 248 markUsed(element, CaptureMode.ByReference); | 248 markUsed(element, CaptureMode.ByReference); |
| 249 } | 249 } |
| 250 | 250 |
| 251 void visitThisPropertyInvoke( | 251 void visitThisPropertyInvoke( |
| 252 Send node, | 252 Send node, |
| 253 NodeList arguments, | 253 NodeList arguments, |
| 254 Selector selector, | 254 Selector selector, |
| 255 _) { | 255 _) { |
| 256 markThisUsed(); | 256 markThisUsed(); |
| 257 arguments.accept(this); | 257 arguments.accept(this); |
| 258 } | 258 } |
| 259 | 259 |
| 260 void visitThisPropertyGet( | 260 void visitThisPropertyGet( |
| 261 Send node, | 261 Send node, |
| 262 Selector selector, | 262 Name name, |
| 263 _) { | 263 _) { |
| 264 markThisUsed(); | 264 markThisUsed(); |
| 265 } | 265 } |
| 266 | 266 |
| 267 void visitThisGet(Node node, _) { | 267 void visitThisGet(Node node, _) { |
| 268 markThisUsed(); | 268 markThisUsed(); |
| 269 } | 269 } |
| 270 | 270 |
| 271 void visitIs(Send node, Node expression, DartType type, _) { | 271 void visitIs(Send node, Node expression, DartType type, _) { |
| 272 // TODO(ajohnsen): Type is used ByValue. | 272 // TODO(ajohnsen): Type is used ByValue. |
| 273 expression.accept(this); | 273 expression.accept(this); |
| 274 } | 274 } |
| 275 | 275 |
| 276 void visitIsNot(Send node, Node expression, DartType type, _) { | 276 void visitIsNot(Send node, Node expression, DartType type, _) { |
| 277 // TODO(ajohnsen): Type is used ByValue. | 277 // TODO(ajohnsen): Type is used ByValue. |
| 278 expression.accept(this); | 278 expression.accept(this); |
| 279 } | 279 } |
| 280 | 280 |
| 281 void visitAs(Send node, Node expression, DartType type, _) { | 281 void visitAs(Send node, Node expression, DartType type, _) { |
| 282 // TODO(ajohnsen): Type is used ByValue. | 282 // TODO(ajohnsen): Type is used ByValue. |
| 283 expression.accept(this); | 283 expression.accept(this); |
| 284 } | 284 } |
| 285 | 285 |
| 286 void visitAssert(Send node, Node expression, _) { | 286 void visitAssert(Assert node) { |
| 287 // TODO(ajohnsen): Only visit in checked mode. | 287 // TODO(ajohnsen): Only visit in checked mode. |
| 288 expression.accept(this); | 288 node.condition.accept(this); |
| 289 node.message?.accept(this); |
| 289 } | 290 } |
| 290 | 291 |
| 291 void visitLocalVariableCompound( | 292 void visitLocalVariableCompound( |
| 292 Send node, | 293 Send node, |
| 293 LocalVariableElement variable, | 294 LocalVariableElement variable, |
| 294 AssignmentOperator operator, | 295 AssignmentOperator operator, |
| 295 Node rhs, | 296 Node rhs, |
| 296 _) { | 297 _) { |
| 297 markUsed(variable, CaptureMode.ByReference); | 298 markUsed(variable, CaptureMode.ByReference); |
| 298 super.visitLocalVariableCompound(node, variable, operator, rhs, null); | 299 super.visitLocalVariableCompound(node, variable, operator, rhs, null); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 FunctionElement function, | 461 FunctionElement function, |
| 461 Node index, | 462 Node index, |
| 462 Node rhs, | 463 Node rhs, |
| 463 _) { | 464 _) { |
| 464 markThisUsed(); | 465 markThisUsed(); |
| 465 super.visitSuperIndexSet(node, function, index, rhs, null); | 466 super.visitSuperIndexSet(node, function, index, rhs, null); |
| 466 } | 467 } |
| 467 | 468 |
| 468 void visitThisPropertyCompound( | 469 void visitThisPropertyCompound( |
| 469 Send node, | 470 Send node, |
| 471 Name name, |
| 470 AssignmentOperator operator, | 472 AssignmentOperator operator, |
| 471 Node rhs, | 473 Node rhs, |
| 472 Selector getterSelector, | |
| 473 Selector setterSelector, | |
| 474 _) { | 474 _) { |
| 475 markThisUsed(); | 475 markThisUsed(); |
| 476 super.visitThisPropertyCompound( | 476 super.visitThisPropertyCompound( |
| 477 node, operator, rhs, getterSelector, setterSelector, null); | 477 node, name, operator, rhs, null); |
| 478 } | 478 } |
| 479 | 479 |
| 480 void visitParameterCompound( | 480 void visitParameterCompound( |
| 481 Send node, | 481 Send node, |
| 482 ParameterElement parameter, | 482 ParameterElement parameter, |
| 483 AssignmentOperator operator, | 483 AssignmentOperator operator, |
| 484 Node rhs, | 484 Node rhs, |
| 485 _) { | 485 _) { |
| 486 markUsed(parameter, CaptureMode.ByReference); | 486 markUsed(parameter, CaptureMode.ByReference); |
| 487 super.visitParameterCompound(node, parameter, operator, rhs, null); | 487 super.visitParameterCompound(node, parameter, operator, rhs, null); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 Send node, | 562 Send node, |
| 563 ParameterElement parameter, | 563 ParameterElement parameter, |
| 564 IncDecOperator operator, | 564 IncDecOperator operator, |
| 565 _) { | 565 _) { |
| 566 markUsed(parameter, CaptureMode.ByReference); | 566 markUsed(parameter, CaptureMode.ByReference); |
| 567 super.visitParameterPrefix(node, parameter, operator, null); | 567 super.visitParameterPrefix(node, parameter, operator, null); |
| 568 } | 568 } |
| 569 | 569 |
| 570 void visitThisPropertyPrefix( | 570 void visitThisPropertyPrefix( |
| 571 Send node, | 571 Send node, |
| 572 Name name, |
| 572 IncDecOperator operator, | 573 IncDecOperator operator, |
| 573 Selector getterSelector, | |
| 574 Selector setterSelector, | |
| 575 _) { | 574 _) { |
| 576 markThisUsed(); | 575 markThisUsed(); |
| 577 super.visitThisPropertyPrefix( | 576 super.visitThisPropertyPrefix( |
| 578 node, operator, getterSelector, setterSelector, null); | 577 node, name, operator, null); |
| 579 } | 578 } |
| 580 | 579 |
| 581 void visitSuperFieldPrefix( | 580 void visitSuperFieldPrefix( |
| 582 Send node, | 581 Send node, |
| 583 FieldElement field, | 582 FieldElement field, |
| 584 IncDecOperator operator, | 583 IncDecOperator operator, |
| 585 _) { | 584 _) { |
| 586 markThisUsed(); | 585 markThisUsed(); |
| 587 super.visitSuperFieldPrefix(node, field, operator, null); | 586 super.visitSuperFieldPrefix(node, field, operator, null); |
| 588 } | 587 } |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 651 Send node, | 650 Send node, |
| 652 ParameterElement parameter, | 651 ParameterElement parameter, |
| 653 IncDecOperator operator, | 652 IncDecOperator operator, |
| 654 _) { | 653 _) { |
| 655 markUsed(parameter, CaptureMode.ByReference); | 654 markUsed(parameter, CaptureMode.ByReference); |
| 656 super.visitParameterPostfix(node, parameter, operator, null); | 655 super.visitParameterPostfix(node, parameter, operator, null); |
| 657 } | 656 } |
| 658 | 657 |
| 659 void visitThisPropertyPostfix( | 658 void visitThisPropertyPostfix( |
| 660 Send node, | 659 Send node, |
| 660 Name name, |
| 661 IncDecOperator operator, | 661 IncDecOperator operator, |
| 662 Selector getterSelector, | |
| 663 Selector setterSelector, | |
| 664 _) { | 662 _) { |
| 665 markThisUsed(); | 663 markThisUsed(); |
| 666 super.visitThisPropertyPostfix( | 664 super.visitThisPropertyPostfix( |
| 667 node, operator, getterSelector, setterSelector, null); | 665 node, name, operator, null); |
| 668 } | 666 } |
| 669 | 667 |
| 670 void visitSuperFieldPostfix( | 668 void visitSuperFieldPostfix( |
| 671 Send node, | 669 Send node, |
| 672 FieldElement field, | 670 FieldElement field, |
| 673 IncDecOperator operator, | 671 IncDecOperator operator, |
| 674 _) { | 672 _) { |
| 675 markThisUsed(); | 673 markThisUsed(); |
| 676 super.visitSuperFieldPostfix(node, field, operator, null); | 674 super.visitSuperFieldPostfix(node, field, operator, null); |
| 677 } | 675 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 FunctionElement indexFunction, | 739 FunctionElement indexFunction, |
| 742 FunctionElement indexSetFunction, | 740 FunctionElement indexSetFunction, |
| 743 Node index, | 741 Node index, |
| 744 IncDecOperator operator, | 742 IncDecOperator operator, |
| 745 _) { | 743 _) { |
| 746 markThisUsed(); | 744 markThisUsed(); |
| 747 super.visitSuperIndexPrefix( | 745 super.visitSuperIndexPrefix( |
| 748 node, indexFunction, indexSetFunction, index, operator, null); | 746 node, indexFunction, indexSetFunction, index, operator, null); |
| 749 } | 747 } |
| 750 | 748 |
| 749 @override |
| 750 void visitTypeAnnotation(TypeAnnotation node) { |
| 751 // This is to avoid the inherited implementation that visits children and |
| 752 // throws when encountering anything unresolved. |
| 753 } |
| 754 |
| 751 void handleImmutableLocalSet( | 755 void handleImmutableLocalSet( |
| 752 SendSet node, | 756 SendSet node, |
| 753 LocalElement element, | 757 LocalElement element, |
| 754 Node rhs, | 758 Node rhs, |
| 755 _) { | 759 _) { |
| 756 apply(rhs); | 760 apply(rhs); |
| 757 } | 761 } |
| 758 | 762 |
| 759 void bulkHandleNode(Node node, String message, _) { | 763 void bulkHandleNode(Node node, String message, _) { |
| 760 } | 764 } |
| 761 | 765 |
| 762 void applyInitializers(FunctionExpression initializers, _) { | 766 void applyInitializers(FunctionExpression initializers, _) { |
| 763 } | 767 } |
| 764 | 768 |
| 765 void applyParameters(NodeList parameters, _) { | 769 void applyParameters(NodeList parameters, _) { |
| 766 } | 770 } |
| 767 } | 771 } |
| OLD | NEW |