| 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 | 
|---|