Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 /// ----------------------------------------------------------------------- | 5 /// ----------------------------------------------------------------------- |
| 6 /// ERROR HANDLING | 6 /// ERROR HANDLING |
| 7 /// ----------------------------------------------------------------------- | 7 /// ----------------------------------------------------------------------- |
| 8 /// | 8 /// |
| 9 /// As a rule of thumb, errors that can be detected statically are handled by | 9 /// As a rule of thumb, errors that can be detected statically are handled by |
| 10 /// the frontend, typically by translating the erroneous code into a 'throw' or | 10 /// the frontend, typically by translating the erroneous code into a 'throw' or |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 49 /// has to update parent pointers manually. | 49 /// has to update parent pointers manually. |
| 50 /// | 50 /// |
| 51 library kernel.ast; | 51 library kernel.ast; |
| 52 | 52 |
| 53 import 'visitor.dart'; | 53 import 'visitor.dart'; |
| 54 export 'visitor.dart'; | 54 export 'visitor.dart'; |
| 55 | 55 |
| 56 import 'type_propagation/type_propagation.dart'; | 56 import 'type_propagation/type_propagation.dart'; |
| 57 export 'type_propagation/type_propagation.dart'; | 57 export 'type_propagation/type_propagation.dart'; |
| 58 | 58 |
| 59 import 'canonical_name.dart' show CanonicalName; | |
| 60 export 'canonical_name.dart' show CanonicalName; | |
| 61 | |
| 59 import 'transformations/flags.dart'; | 62 import 'transformations/flags.dart'; |
| 60 import 'text/ast_to_text.dart'; | 63 import 'text/ast_to_text.dart'; |
| 61 import 'type_algebra.dart'; | 64 import 'type_algebra.dart'; |
| 62 import 'type_environment.dart'; | 65 import 'type_environment.dart'; |
| 63 | 66 |
| 64 /// Any type of node in the IR. | 67 /// Any type of node in the IR. |
| 65 abstract class Node { | 68 abstract class Node { |
| 66 const Node(); | 69 const Node(); |
| 67 | 70 |
| 68 accept(Visitor v); | 71 accept(Visitor v); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 parent = null; | 129 parent = null; |
| 127 } | 130 } |
| 128 | 131 |
| 129 /// Removes this node from the [List] it is currently stored in, or assigns | 132 /// Removes this node from the [List] it is currently stored in, or assigns |
| 130 /// `null` to the field on the parent currently pointing to the node. | 133 /// `null` to the field on the parent currently pointing to the node. |
| 131 /// | 134 /// |
| 132 /// Has no effect if the node is orphaned or if the parent pointer is stale. | 135 /// Has no effect if the node is orphaned or if the parent pointer is stale. |
| 133 void remove() { | 136 void remove() { |
| 134 parent?.replaceChild(this, null); | 137 parent?.replaceChild(this, null); |
| 135 parent = null; | 138 parent = null; |
| 136 } | 139 } |
|
kustermann
2017/02/01 13:00:54
Do the replaceWith/replaceChild/remove/parent= met
asgerf
2017/02/02 12:30:27
No.
| |
| 137 | 140 |
| 138 Program get enclosingProgram => parent?.enclosingProgram; | 141 Program get enclosingProgram => parent?.enclosingProgram; |
| 139 | 142 |
| 140 /// Returns the best known source location of the given AST node, or `null` if | 143 /// Returns the best known source location of the given AST node, or `null` if |
| 141 /// the node is orphaned. | 144 /// the node is orphaned. |
| 142 /// | 145 /// |
| 143 /// This getter is intended for diagnostics and debugging, and should be | 146 /// This getter is intended for diagnostics and debugging, and should be |
| 144 /// avoided in production code. | 147 /// avoided in production code. |
| 145 Location get location { | 148 Location get location { |
| 146 if (fileOffset == noOffset) return parent?.location; | 149 if (fileOffset == noOffset) return parent?.location; |
| 147 return _getLocationInEnclosingFile(fileOffset); | 150 return _getLocationInEnclosingFile(fileOffset); |
| 148 } | 151 } |
| 149 | 152 |
| 150 Location _getLocationInEnclosingFile(int offset) { | 153 Location _getLocationInEnclosingFile(int offset) { |
| 151 return parent?._getLocationInEnclosingFile(offset); | 154 return parent?._getLocationInEnclosingFile(offset); |
| 152 } | 155 } |
| 153 } | 156 } |
| 154 | 157 |
| 158 /// An AST node that has an associated [CanonicalName], allowing it to be | |
| 159 /// referenced by name. Libraries, classes, and members are linked nodes. | |
| 160 /// | |
| 161 /// When created, a linked node has no associated canonical name, and must be | |
| 162 /// linked to such a name before it can be referenced. A canonical name is | |
| 163 /// typically assigned by either: | |
| 164 /// - Adding it to the a class or library using `addMember` or `addClass`. | |
| 165 /// - Explicitly assigning a name using [CanonicalName.linkTo]. | |
| 166 abstract class LinkedNode extends TreeNode { | |
| 167 CanonicalName canonicalName; | |
| 168 } | |
| 169 | |
| 155 // ------------------------------------------------------------------------ | 170 // ------------------------------------------------------------------------ |
| 156 // LIBRARIES and CLASSES | 171 // LIBRARIES and CLASSES |
| 157 // ------------------------------------------------------------------------ | 172 // ------------------------------------------------------------------------ |
| 158 | 173 |
| 159 class Library extends TreeNode implements Comparable<Library> { | 174 class Library extends LinkedNode implements Comparable<Library> { |
| 160 /// An import path to this library. | 175 /// An import path to this library. |
| 161 /// | 176 /// |
| 162 /// The [Uri] should have the `dart`, `package`, `app`, or `file` scheme. | 177 /// The [Uri] should have the `dart`, `package`, `app`, or `file` scheme. |
| 163 /// | 178 /// |
| 164 /// If the URI has the `app` scheme, it is relative to the application root. | 179 /// If the URI has the `app` scheme, it is relative to the application root. |
| 165 Uri importUri; | 180 Uri importUri; |
| 166 | 181 |
| 167 /// The uri of the source file this library was loaded from. | 182 /// The uri of the source file this library was loaded from. |
| 168 String fileUri; | 183 String fileUri; |
| 169 | 184 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 198 } | 213 } |
| 199 | 214 |
| 200 /// Returns the top-level fields and procedures defined in this library. | 215 /// Returns the top-level fields and procedures defined in this library. |
| 201 /// | 216 /// |
| 202 /// This getter is for convenience, not efficiency. Consider manually | 217 /// This getter is for convenience, not efficiency. Consider manually |
| 203 /// iterating the members to speed up code in production. | 218 /// iterating the members to speed up code in production. |
| 204 Iterable<Member> get members => | 219 Iterable<Member> get members => |
| 205 <Iterable<Member>>[fields, procedures].expand((x) => x); | 220 <Iterable<Member>>[fields, procedures].expand((x) => x); |
| 206 | 221 |
| 207 void addMember(Member member) { | 222 void addMember(Member member) { |
| 223 if (member.canonicalName == null) { | |
| 224 getCanonicalNameOfLibrary(this).getChildFromMember(member).linkTo(member); | |
|
ahe
2017/01/30 17:16:16
Would it make sense to move this to "set parent"?
asgerf
2017/02/02 12:30:27
I don't see why. Set parent is the low-level acces
| |
| 225 } | |
| 208 member.parent = this; | 226 member.parent = this; |
| 209 if (member is Procedure) { | 227 if (member is Procedure) { |
| 210 procedures.add(member); | 228 procedures.add(member); |
| 211 } else if (member is Field) { | 229 } else if (member is Field) { |
| 212 fields.add(member); | 230 fields.add(member); |
| 213 } else { | 231 } else { |
| 214 throw new ArgumentError(member); | 232 throw new ArgumentError(member); |
| 215 } | 233 } |
| 216 } | 234 } |
| 217 | 235 |
| 218 void addClass(Class class_) { | 236 void addClass(Class class_) { |
| 237 if (class_.canonicalName == null) { | |
| 238 getCanonicalNameOfLibrary(this).getChild(class_.name).linkTo(class_); | |
| 239 } | |
| 219 class_.parent = this; | 240 class_.parent = this; |
| 220 classes.add(class_); | 241 classes.add(class_); |
| 221 } | 242 } |
| 222 | 243 |
| 223 accept(TreeVisitor v) => v.visitLibrary(this); | 244 accept(TreeVisitor v) => v.visitLibrary(this); |
| 224 | 245 |
| 225 visitChildren(Visitor v) { | 246 visitChildren(Visitor v) { |
| 226 visitList(classes, v); | 247 visitList(classes, v); |
| 227 visitList(procedures, v); | 248 visitList(procedures, v); |
| 228 visitList(fields, v); | 249 visitList(fields, v); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 282 /// not necessarily at [Body] level. | 303 /// not necessarily at [Body] level. |
| 283 Body, | 304 Body, |
| 284 } | 305 } |
| 285 | 306 |
| 286 /// Declaration of a regular class or a mixin application. | 307 /// Declaration of a regular class or a mixin application. |
| 287 /// | 308 /// |
| 288 /// Mixin applications may not contain fields or procedures, as they implicitly | 309 /// Mixin applications may not contain fields or procedures, as they implicitly |
| 289 /// use those from its mixed-in type. However, the IR does not enforce this | 310 /// use those from its mixed-in type. However, the IR does not enforce this |
| 290 /// rule directly, as doing so can obstruct transformations. It is possible to | 311 /// rule directly, as doing so can obstruct transformations. It is possible to |
| 291 /// transform a mixin application to become a regular class, and vice versa. | 312 /// transform a mixin application to become a regular class, and vice versa. |
| 292 class Class extends TreeNode { | 313 class Class extends LinkedNode { |
| 293 /// The degree to which the contents of the class have been loaded. | 314 /// The degree to which the contents of the class have been loaded. |
| 294 ClassLevel level = ClassLevel.Body; | 315 ClassLevel level = ClassLevel.Body; |
| 295 | 316 |
| 296 /// List of metadata annotations on the class. | 317 /// List of metadata annotations on the class. |
| 297 /// | 318 /// |
| 298 /// This defaults to an immutable empty list. Use [addAnnotation] to add | 319 /// This defaults to an immutable empty list. Use [addAnnotation] to add |
| 299 /// annotations if needed. | 320 /// annotations if needed. |
| 300 List<Expression> annotations = const <Expression>[]; | 321 List<Expression> annotations = const <Expression>[]; |
| 301 | 322 |
| 302 /// Name of the class. | 323 /// Name of the class. |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 390 ].expand((x) => x); | 411 ].expand((x) => x); |
| 391 | 412 |
| 392 /// The library containing this class. | 413 /// The library containing this class. |
| 393 Library get enclosingLibrary => parent; | 414 Library get enclosingLibrary => parent; |
| 394 | 415 |
| 395 /// Adds a member to this class. | 416 /// Adds a member to this class. |
| 396 /// | 417 /// |
| 397 /// Throws an error if attempting to add a field or procedure to a mixin | 418 /// Throws an error if attempting to add a field or procedure to a mixin |
| 398 /// application. | 419 /// application. |
| 399 void addMember(Member member) { | 420 void addMember(Member member) { |
| 421 if (member.canonicalName == null) { | |
| 422 getCanonicalNameOfClass(this).getChildFromMember(member).linkTo(member); | |
| 423 } | |
|
kustermann
2017/02/01 13:00:54
Should we do some verification in the else branch,
asgerf
2017/02/02 12:30:27
The assertion is equivalent to always doing linkTo
| |
| 400 member.parent = this; | 424 member.parent = this; |
| 401 if (member is Constructor) { | 425 if (member is Constructor) { |
| 402 constructors.add(member); | 426 constructors.add(member); |
| 403 } else if (member is Procedure) { | 427 } else if (member is Procedure) { |
| 404 procedures.add(member); | 428 procedures.add(member); |
| 405 } else if (member is Field) { | 429 } else if (member is Field) { |
| 406 fields.add(member); | 430 fields.add(member); |
| 407 } else { | 431 } else { |
| 408 throw new ArgumentError(member); | 432 throw new ArgumentError(member); |
| 409 } | 433 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 483 | 507 |
| 484 Location _getLocationInEnclosingFile(int offset) { | 508 Location _getLocationInEnclosingFile(int offset) { |
| 485 return enclosingProgram.getLocation(fileUri, offset); | 509 return enclosingProgram.getLocation(fileUri, offset); |
| 486 } | 510 } |
| 487 } | 511 } |
| 488 | 512 |
| 489 // ------------------------------------------------------------------------ | 513 // ------------------------------------------------------------------------ |
| 490 // MEMBERS | 514 // MEMBERS |
| 491 // ------------------------------------------------------------------------ | 515 // ------------------------------------------------------------------------ |
| 492 | 516 |
| 493 /// A indirect reference to a member, which can be updated to point at another | 517 abstract class Member extends LinkedNode { |
| 494 /// member at a later time. | |
| 495 class _MemberAccessor { | |
| 496 Member target; | |
| 497 _MemberAccessor(this.target); | |
| 498 } | |
| 499 | |
| 500 abstract class Member extends TreeNode { | |
| 501 /// End offset in the source file it comes from. Valid values are from 0 and | 518 /// End offset in the source file it comes from. Valid values are from 0 and |
| 502 /// up, or -1 ([TreeNode.noOffset]) if the file end offset is not available | 519 /// up, or -1 ([TreeNode.noOffset]) if the file end offset is not available |
| 503 /// (this is the default if none is specifically set). | 520 /// (this is the default if none is specifically set). |
| 504 int fileEndOffset = TreeNode.noOffset; | 521 int fileEndOffset = TreeNode.noOffset; |
| 505 | 522 |
| 506 /// List of metadata annotations on the member. | 523 /// List of metadata annotations on the member. |
| 507 /// | 524 /// |
| 508 /// This defaults to an immutable empty list. Use [addAnnotation] to add | 525 /// This defaults to an immutable empty list. Use [addAnnotation] to add |
| 509 /// annotations if needed. | 526 /// annotations if needed. |
| 510 List<Expression> annotations = const <Expression>[]; | 527 List<Expression> annotations = const <Expression>[]; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 578 annotations.add(node); | 595 annotations.add(node); |
| 579 node.parent = this; | 596 node.parent = this; |
| 580 } | 597 } |
| 581 | 598 |
| 582 DartType get getterType; | 599 DartType get getterType; |
| 583 DartType get setterType; | 600 DartType get setterType; |
| 584 | 601 |
| 585 bool get containsSuperCalls { | 602 bool get containsSuperCalls { |
| 586 return transformerFlags & TransformerFlag.superCalls != 0; | 603 return transformerFlags & TransformerFlag.superCalls != 0; |
| 587 } | 604 } |
| 588 | |
| 589 _MemberAccessor get _getterInterface; | |
| 590 _MemberAccessor get _setterInterface; | |
| 591 } | 605 } |
| 592 | 606 |
| 593 /// A field declaration. | 607 /// A field declaration. |
| 594 /// | 608 /// |
| 595 /// The implied getter and setter for the field are not represented explicitly, | 609 /// The implied getter and setter for the field are not represented explicitly, |
| 596 /// but can be made explicit if needed. | 610 /// but can be made explicit if needed. |
| 597 class Field extends Member { | 611 class Field extends Member { |
| 598 _MemberAccessor _getterInterface, _setterInterface; | |
| 599 | |
| 600 DartType type; // Not null. Defaults to DynamicType. | 612 DartType type; // Not null. Defaults to DynamicType. |
| 601 InferredValue inferredValue; // May be null. | 613 InferredValue inferredValue; // May be null. |
| 602 int flags = 0; | 614 int flags = 0; |
| 603 Expression initializer; // May be null. | 615 Expression initializer; // May be null. |
| 604 | 616 |
| 605 /// The uri of the source file this field was loaded from. | 617 /// The uri of the source file this field was loaded from. |
| 606 String fileUri; | 618 String fileUri; |
| 607 | 619 |
| 608 Field(Name name, | 620 Field(Name name, |
| 609 {this.type: const DynamicType(), | 621 {this.type: const DynamicType(), |
| 610 this.inferredValue, | 622 this.inferredValue, |
| 611 this.initializer, | 623 this.initializer, |
| 612 bool isFinal: false, | 624 bool isFinal: false, |
| 613 bool isConst: false, | 625 bool isConst: false, |
| 614 bool isStatic: false, | 626 bool isStatic: false, |
| 615 bool hasImplicitGetter, | 627 bool hasImplicitGetter, |
| 616 bool hasImplicitSetter, | 628 bool hasImplicitSetter, |
| 617 int transformerFlags: 0, | 629 int transformerFlags: 0, |
| 618 this.fileUri}) | 630 this.fileUri}) |
| 619 : super(name) { | 631 : super(name) { |
| 620 _getterInterface = new _MemberAccessor(this); | |
| 621 _setterInterface = new _MemberAccessor(this); | |
| 622 assert(type != null); | 632 assert(type != null); |
| 623 initializer?.parent = this; | 633 initializer?.parent = this; |
| 624 this.isFinal = isFinal; | 634 this.isFinal = isFinal; |
| 625 this.isConst = isConst; | 635 this.isConst = isConst; |
| 626 this.isStatic = isStatic; | 636 this.isStatic = isStatic; |
| 627 this.hasImplicitGetter = hasImplicitGetter ?? !isStatic; | 637 this.hasImplicitGetter = hasImplicitGetter ?? !isStatic; |
| 628 this.hasImplicitSetter = hasImplicitSetter ?? (!isStatic && !isFinal); | 638 this.hasImplicitSetter = hasImplicitSetter ?? (!isStatic && !isFinal); |
| 629 this.transformerFlags = transformerFlags; | 639 this.transformerFlags = transformerFlags; |
| 630 } | 640 } |
| 631 | 641 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 711 transformList(annotations, v, this); | 721 transformList(annotations, v, this); |
| 712 if (initializer != null) { | 722 if (initializer != null) { |
| 713 initializer = initializer.accept(v); | 723 initializer = initializer.accept(v); |
| 714 initializer?.parent = this; | 724 initializer?.parent = this; |
| 715 } | 725 } |
| 716 } | 726 } |
| 717 | 727 |
| 718 DartType get getterType => type; | 728 DartType get getterType => type; |
| 719 DartType get setterType => isMutable ? type : const BottomType(); | 729 DartType get setterType => isMutable ? type : const BottomType(); |
| 720 | 730 |
| 721 /// Makes all [PropertyGet]s that have this field as its interface target | |
| 722 /// use [getter] as its interface target instead. | |
| 723 /// | |
| 724 /// That can be used to introduce an explicit getter for a field instead of | |
| 725 /// its implicit getter. | |
| 726 /// | |
| 727 /// This method only updates the stored interface target -- the caller must | |
| 728 /// ensure that [getter] actually becomes the target for dispatches that | |
| 729 /// would previously hit the implicit field getter. | |
| 730 /// | |
| 731 /// [DirectPropertyGet]s are not affected, and will continue to access the | |
| 732 /// field directly. [PropertyGet] nodes created after the call will not be | |
| 733 /// affected until the method is called again. | |
| 734 /// | |
| 735 /// Existing [ClassHierarchy] instances are not affected by this call. | |
| 736 void replaceGetterInterfaceWith(Procedure getter) { | |
| 737 _getterInterface.target = getter; | |
| 738 _getterInterface = new _MemberAccessor(this); | |
| 739 } | |
| 740 | |
| 741 /// Makes all [PropertySet]s that have this field as its interface target | |
| 742 /// use [setter] as its interface target instead. | |
| 743 /// | |
| 744 /// That can be used to introduce an explicit setter for a field instead of | |
| 745 /// its implicit setter. | |
| 746 /// | |
| 747 /// This method only updates the stored interface target -- the caller must | |
| 748 /// ensure that [setter] actually becomes the target for dispatches that | |
| 749 /// would previously hit the implicit field setter. | |
| 750 /// | |
| 751 /// [DirectPropertySet] and [FieldInitializer]s are not affected, and will | |
| 752 /// continue to access the field directly. [PropertySet] nodes created after | |
| 753 /// the call will not be affected until the method is called again. | |
| 754 /// | |
| 755 /// Existing [ClassHierarchy] instances are not affected by this call. | |
| 756 void replaceSetterInterfaceWith(Procedure setter) { | |
| 757 _setterInterface.target = setter; | |
| 758 _setterInterface = new _MemberAccessor(this); | |
| 759 } | |
| 760 | |
| 761 Location _getLocationInEnclosingFile(int offset) { | 731 Location _getLocationInEnclosingFile(int offset) { |
| 762 return enclosingProgram.getLocation(fileUri, offset); | 732 return enclosingProgram.getLocation(fileUri, offset); |
| 763 } | 733 } |
| 764 } | 734 } |
| 765 | 735 |
| 766 /// A generative constructor, possibly redirecting. | 736 /// A generative constructor, possibly redirecting. |
| 767 /// | 737 /// |
| 768 /// Note that factory constructors are treated as [Procedure]s. | 738 /// Note that factory constructors are treated as [Procedure]s. |
| 769 /// | 739 /// |
| 770 /// Constructors do not take type parameters. Type arguments from a constructor | 740 /// Constructors do not take type parameters. Type arguments from a constructor |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 825 transformList(annotations, v, this); | 795 transformList(annotations, v, this); |
| 826 if (function != null) { | 796 if (function != null) { |
| 827 function = function.accept(v); | 797 function = function.accept(v); |
| 828 function?.parent = this; | 798 function?.parent = this; |
| 829 } | 799 } |
| 830 transformList(initializers, v, this); | 800 transformList(initializers, v, this); |
| 831 } | 801 } |
| 832 | 802 |
| 833 DartType get getterType => const BottomType(); | 803 DartType get getterType => const BottomType(); |
| 834 DartType get setterType => const BottomType(); | 804 DartType get setterType => const BottomType(); |
| 835 | |
| 836 _MemberAccessor get _getterInterface { | |
| 837 throw 'Constructors cannot be used as getters'; | |
| 838 } | |
| 839 | |
| 840 _MemberAccessor get _setterInterface { | |
| 841 throw 'Constructors cannot be used as setters'; | |
| 842 } | |
| 843 } | 805 } |
| 844 | 806 |
| 845 /// A method, getter, setter, index-getter, index-setter, operator overloader, | 807 /// A method, getter, setter, index-getter, index-setter, operator overloader, |
| 846 /// or factory. | 808 /// or factory. |
| 847 /// | 809 /// |
| 848 /// Procedures can have the static, abstract, and/or external modifier, although | 810 /// Procedures can have the static, abstract, and/or external modifier, although |
| 849 /// only the static and external modifiers may be used together. | 811 /// only the static and external modifiers may be used together. |
| 850 /// | 812 /// |
| 851 /// For non-static procedures the name is required for dynamic dispatch. | 813 /// For non-static procedures the name is required for dynamic dispatch. |
| 852 /// For external procedures the name is required for identifying the external | 814 /// For external procedures the name is required for identifying the external |
| 853 /// implementation. | 815 /// implementation. |
| 854 /// | 816 /// |
| 855 /// For methods, getters, and setters the name is just as it was declared. | 817 /// For methods, getters, and setters the name is just as it was declared. |
| 856 /// For setters this does not include a trailing `=`. | 818 /// For setters this does not include a trailing `=`. |
| 857 /// For index-getters/setters, this is `[]` and `[]=`. | 819 /// For index-getters/setters, this is `[]` and `[]=`. |
| 858 /// For operators, this is the token for the operator, e.g. `+` or `==`, | 820 /// For operators, this is the token for the operator, e.g. `+` or `==`, |
| 859 /// except for the unary minus operator, whose name is `unary-`. | 821 /// except for the unary minus operator, whose name is `unary-`. |
| 860 class Procedure extends Member { | 822 class Procedure extends Member { |
| 861 _MemberAccessor _reference; | |
| 862 ProcedureKind kind; | 823 ProcedureKind kind; |
| 863 int flags = 0; | 824 int flags = 0; |
| 864 FunctionNode function; // Body is null if and only if abstract or external. | 825 FunctionNode function; // Body is null if and only if abstract or external. |
| 865 | 826 |
| 866 /// The uri of the source file this procedure was loaded from. | 827 /// The uri of the source file this procedure was loaded from. |
| 867 String fileUri; | 828 String fileUri; |
| 868 | 829 |
| 869 Procedure(Name name, this.kind, this.function, | 830 Procedure(Name name, this.kind, this.function, |
| 870 {bool isAbstract: false, | 831 {bool isAbstract: false, |
| 871 bool isStatic: false, | 832 bool isStatic: false, |
| 872 bool isExternal: false, | 833 bool isExternal: false, |
| 873 bool isConst: false, | 834 bool isConst: false, |
| 874 int transformerFlags: 0, | 835 int transformerFlags: 0, |
| 875 this.fileUri}) | 836 this.fileUri}) |
| 876 : super(name) { | 837 : super(name) { |
| 877 _reference = new _MemberAccessor(this); | |
| 878 function?.parent = this; | 838 function?.parent = this; |
| 879 this.isAbstract = isAbstract; | 839 this.isAbstract = isAbstract; |
| 880 this.isStatic = isStatic; | 840 this.isStatic = isStatic; |
| 881 this.isExternal = isExternal; | 841 this.isExternal = isExternal; |
| 882 this.isConst = isConst; | 842 this.isConst = isConst; |
| 883 this.transformerFlags = transformerFlags; | 843 this.transformerFlags = transformerFlags; |
| 884 } | 844 } |
| 885 | 845 |
| 886 static const int FlagStatic = 1 << 0; // Must match serialized bit positions. | 846 static const int FlagStatic = 1 << 0; // Must match serialized bit positions. |
| 887 static const int FlagAbstract = 1 << 1; | 847 static const int FlagAbstract = 1 << 1; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 940 DartType get getterType { | 900 DartType get getterType { |
| 941 return isGetter ? function.returnType : function.functionType; | 901 return isGetter ? function.returnType : function.functionType; |
| 942 } | 902 } |
| 943 | 903 |
| 944 DartType get setterType { | 904 DartType get setterType { |
| 945 return isSetter | 905 return isSetter |
| 946 ? function.positionalParameters[0].type | 906 ? function.positionalParameters[0].type |
| 947 : const BottomType(); | 907 : const BottomType(); |
| 948 } | 908 } |
| 949 | 909 |
| 950 _MemberAccessor get _getterInterface => _reference; | |
| 951 _MemberAccessor get _setterInterface => _reference; | |
| 952 | |
| 953 Location _getLocationInEnclosingFile(int offset) { | 910 Location _getLocationInEnclosingFile(int offset) { |
| 954 return enclosingProgram.getLocation(fileUri, offset); | 911 return enclosingProgram.getLocation(fileUri, offset); |
| 955 } | 912 } |
| 956 } | 913 } |
| 957 | 914 |
| 958 enum ProcedureKind { | 915 enum ProcedureKind { |
| 959 Method, | 916 Method, |
| 960 Getter, | 917 Getter, |
| 961 Setter, | 918 Setter, |
| 962 Operator, | 919 Operator, |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 988 /// A field assignment `field = value` occurring in the initializer list of | 945 /// A field assignment `field = value` occurring in the initializer list of |
| 989 /// a constructor. | 946 /// a constructor. |
| 990 /// | 947 /// |
| 991 /// This node has nothing to do with declaration-site field initializers; those | 948 /// This node has nothing to do with declaration-site field initializers; those |
| 992 /// are [Expression]s stored in [Field.initializer]. | 949 /// are [Expression]s stored in [Field.initializer]. |
| 993 // | 950 // |
| 994 // TODO: The frontend should check that all final fields are initialized | 951 // TODO: The frontend should check that all final fields are initialized |
| 995 // exactly once, and that no fields are assigned twice in the initializer list. | 952 // exactly once, and that no fields are assigned twice in the initializer list. |
| 996 class FieldInitializer extends Initializer { | 953 class FieldInitializer extends Initializer { |
| 997 /// Reference to the field being initialized. Not null. | 954 /// Reference to the field being initialized. Not null. |
| 998 Field field; | 955 CanonicalName fieldName; |
| 999 Expression value; | 956 Expression value; |
| 1000 | 957 |
| 1001 FieldInitializer(this.field, this.value) { | 958 FieldInitializer(Field field, Expression value) |
| 959 : this.byName(getCanonicalNameOfMember(field), value); | |
| 960 | |
| 961 FieldInitializer.byName(this.fieldName, this.value) { | |
| 1002 value?.parent = this; | 962 value?.parent = this; |
| 1003 } | 963 } |
| 1004 | 964 |
| 965 Field get field => fieldName?.definition as Field; | |
|
kustermann
2017/02/01 13:00:54
Could you use fieldName?.asField here?
Or is this
asgerf
2017/02/02 12:30:27
Yep, it was supposed to say fieldName?.asField.
| |
| 966 | |
| 967 void set field(Field field) { | |
| 968 fieldName = getCanonicalNameOfMember(field); | |
| 969 } | |
| 970 | |
| 1005 accept(InitializerVisitor v) => v.visitFieldInitializer(this); | 971 accept(InitializerVisitor v) => v.visitFieldInitializer(this); |
| 1006 | 972 |
| 1007 visitChildren(Visitor v) { | 973 visitChildren(Visitor v) { |
| 1008 field?.acceptReference(v); | 974 field?.acceptReference(v); |
| 1009 value?.accept(v); | 975 value?.accept(v); |
| 1010 } | 976 } |
| 1011 | 977 |
| 1012 transformChildren(Transformer v) { | 978 transformChildren(Transformer v) { |
| 1013 if (value != null) { | 979 if (value != null) { |
| 1014 value = value.accept(v); | 980 value = value.accept(v); |
| 1015 value?.parent = this; | 981 value?.parent = this; |
| 1016 } | 982 } |
| 1017 } | 983 } |
| 1018 } | 984 } |
| 1019 | 985 |
| 1020 /// A super call `super(x,y)` occurring in the initializer list of a | 986 /// A super call `super(x,y)` occurring in the initializer list of a |
| 1021 /// constructor. | 987 /// constructor. |
| 1022 /// | 988 /// |
| 1023 /// There are no type arguments on this call. | 989 /// There are no type arguments on this call. |
| 1024 // | 990 // |
| 1025 // TODO: The frontend should check that there is no more than one super call. | 991 // TODO: The frontend should check that there is no more than one super call. |
| 1026 // | 992 // |
| 1027 // DESIGN TODO: Consider if the frontend should insert type arguments derived | 993 // DESIGN TODO: Consider if the frontend should insert type arguments derived |
| 1028 // from the extends clause. | 994 // from the extends clause. |
| 1029 class SuperInitializer extends Initializer { | 995 class SuperInitializer extends Initializer { |
| 1030 /// Reference to the constructor being invoked in the super class. Not null. | 996 /// Reference to the constructor being invoked in the super class. Not null. |
| 1031 Constructor target; | 997 CanonicalName targetName; |
| 1032 Arguments arguments; | 998 Arguments arguments; |
| 1033 | 999 |
| 1034 SuperInitializer(this.target, this.arguments) { | 1000 SuperInitializer(Constructor target, Arguments arguments) |
| 1001 : this.byName(getCanonicalNameOfMember(target), arguments); | |
| 1002 | |
| 1003 SuperInitializer.byName(this.targetName, this.arguments) { | |
| 1035 arguments?.parent = this; | 1004 arguments?.parent = this; |
| 1036 } | 1005 } |
| 1037 | 1006 |
| 1007 Constructor get target => targetName?.definition as Constructor; | |
|
kustermann
2017/02/01 13:00:54
ditto
asgerf
2017/02/02 12:30:27
Done.
| |
| 1008 | |
| 1009 void set target(Constructor target) { | |
| 1010 targetName = getCanonicalNameOfMember(target); | |
| 1011 } | |
| 1012 | |
| 1038 accept(InitializerVisitor v) => v.visitSuperInitializer(this); | 1013 accept(InitializerVisitor v) => v.visitSuperInitializer(this); |
| 1039 | 1014 |
| 1040 visitChildren(Visitor v) { | 1015 visitChildren(Visitor v) { |
| 1041 target?.acceptReference(v); | 1016 target?.acceptReference(v); |
| 1042 arguments?.accept(v); | 1017 arguments?.accept(v); |
| 1043 } | 1018 } |
| 1044 | 1019 |
| 1045 transformChildren(Transformer v) { | 1020 transformChildren(Transformer v) { |
| 1046 if (arguments != null) { | 1021 if (arguments != null) { |
| 1047 arguments = arguments.accept(v); | 1022 arguments = arguments.accept(v); |
| 1048 arguments?.parent = this; | 1023 arguments?.parent = this; |
| 1049 } | 1024 } |
| 1050 } | 1025 } |
| 1051 } | 1026 } |
| 1052 | 1027 |
| 1053 /// A redirecting call `this(x,y)` occurring in the initializer list of | 1028 /// A redirecting call `this(x,y)` occurring in the initializer list of |
| 1054 /// a constructor. | 1029 /// a constructor. |
| 1055 // | 1030 // |
| 1056 // TODO: The frontend should check that this is the only initializer and if the | 1031 // TODO: The frontend should check that this is the only initializer and if the |
| 1057 // constructor has a body or if there is a cycle in the initializer calls. | 1032 // constructor has a body or if there is a cycle in the initializer calls. |
| 1058 class RedirectingInitializer extends Initializer { | 1033 class RedirectingInitializer extends Initializer { |
| 1059 /// Reference to the constructor being invoked in the same class. Not null. | 1034 /// Reference to the constructor being invoked in the same class. Not null. |
| 1060 Constructor target; | 1035 CanonicalName targetName; |
| 1061 Arguments arguments; | 1036 Arguments arguments; |
| 1062 | 1037 |
| 1063 RedirectingInitializer(this.target, this.arguments) { | 1038 RedirectingInitializer(Constructor target, Arguments arguments) |
| 1039 : this.byName(getCanonicalNameOfMember(target), arguments); | |
| 1040 | |
| 1041 RedirectingInitializer.byName(this.targetName, this.arguments) { | |
| 1064 arguments?.parent = this; | 1042 arguments?.parent = this; |
| 1065 } | 1043 } |
| 1066 | 1044 |
| 1045 Constructor get target => targetName?.definition as Constructor; | |
|
kustermann
2017/02/01 13:00:54
ditto
asgerf
2017/02/02 12:30:27
Done.
| |
| 1046 | |
| 1047 void set target(Constructor target) { | |
| 1048 targetName = getCanonicalNameOfMember(target); | |
| 1049 } | |
| 1050 | |
| 1067 accept(InitializerVisitor v) => v.visitRedirectingInitializer(this); | 1051 accept(InitializerVisitor v) => v.visitRedirectingInitializer(this); |
| 1068 | 1052 |
| 1069 visitChildren(Visitor v) { | 1053 visitChildren(Visitor v) { |
| 1070 target?.acceptReference(v); | 1054 target?.acceptReference(v); |
| 1071 arguments?.accept(v); | 1055 arguments?.accept(v); |
| 1072 } | 1056 } |
| 1073 | 1057 |
| 1074 transformChildren(Transformer v) { | 1058 transformChildren(Transformer v) { |
| 1075 if (arguments != null) { | 1059 if (arguments != null) { |
| 1076 arguments = arguments.accept(v); | 1060 arguments = arguments.accept(v); |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1349 } | 1333 } |
| 1350 } | 1334 } |
| 1351 | 1335 |
| 1352 /// Expression of form `x.field`. | 1336 /// Expression of form `x.field`. |
| 1353 /// | 1337 /// |
| 1354 /// This may invoke a getter, read a field, or tear off a method. | 1338 /// This may invoke a getter, read a field, or tear off a method. |
| 1355 class PropertyGet extends Expression { | 1339 class PropertyGet extends Expression { |
| 1356 Expression receiver; | 1340 Expression receiver; |
| 1357 Name name; | 1341 Name name; |
| 1358 | 1342 |
| 1359 _MemberAccessor _interfaceTargetReference; | 1343 CanonicalName interfaceTargetName; |
| 1360 | 1344 |
| 1361 PropertyGet(this.receiver, this.name, [Member interfaceTarget]) { | 1345 PropertyGet(Expression receiver, Name name, [Member interfaceTarget]) |
| 1346 : this.byName(receiver, name, getCanonicalNameOfMember(interfaceTarget)); | |
| 1347 | |
| 1348 PropertyGet.byName(this.receiver, this.name, this.interfaceTargetName) { | |
| 1362 receiver?.parent = this; | 1349 receiver?.parent = this; |
| 1363 this.interfaceTarget = interfaceTarget; | |
| 1364 } | 1350 } |
| 1365 | 1351 |
| 1366 Member get interfaceTarget => _interfaceTargetReference?.target; | 1352 Member get interfaceTarget => interfaceTargetName?.asMember; |
| 1367 | 1353 |
| 1368 void set interfaceTarget(Member newTarget) { | 1354 void set interfaceTarget(Member member) { |
| 1369 _interfaceTargetReference = newTarget?._getterInterface; | 1355 interfaceTargetName = getCanonicalNameOfMember(member); |
| 1370 } | 1356 } |
| 1371 | 1357 |
| 1372 DartType getStaticType(TypeEnvironment types) { | 1358 DartType getStaticType(TypeEnvironment types) { |
| 1373 var interfaceTarget = this.interfaceTarget; | 1359 var interfaceTarget = this.interfaceTarget; |
| 1374 if (interfaceTarget != null) { | 1360 if (interfaceTarget != null) { |
| 1375 Class superclass = interfaceTarget.enclosingClass; | 1361 Class superclass = interfaceTarget.enclosingClass; |
| 1376 var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types); | 1362 var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types); |
| 1377 return Substitution | 1363 return Substitution |
| 1378 .fromInterfaceType(receiverType) | 1364 .fromInterfaceType(receiverType) |
| 1379 .substituteType(interfaceTarget.getterType); | 1365 .substituteType(interfaceTarget.getterType); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1406 /// Expression of form `x.field = value`. | 1392 /// Expression of form `x.field = value`. |
| 1407 /// | 1393 /// |
| 1408 /// This may invoke a setter or assign a field. | 1394 /// This may invoke a setter or assign a field. |
| 1409 /// | 1395 /// |
| 1410 /// Evaluates to the value of [value]. | 1396 /// Evaluates to the value of [value]. |
| 1411 class PropertySet extends Expression { | 1397 class PropertySet extends Expression { |
| 1412 Expression receiver; | 1398 Expression receiver; |
| 1413 Name name; | 1399 Name name; |
| 1414 Expression value; | 1400 Expression value; |
| 1415 | 1401 |
| 1416 _MemberAccessor _interfaceTargetReference; | 1402 CanonicalName interfaceTargetName; |
| 1417 | 1403 |
| 1418 PropertySet(this.receiver, this.name, this.value, [Member interfaceTarget]) { | 1404 PropertySet(Expression receiver, Name name, Expression value, |
| 1405 [Member interfaceTarget]) | |
| 1406 : this.byName( | |
| 1407 receiver, name, value, getCanonicalNameOfMember(interfaceTarget)); | |
| 1408 | |
| 1409 PropertySet.byName( | |
| 1410 this.receiver, this.name, this.value, this.interfaceTargetName) { | |
| 1419 receiver?.parent = this; | 1411 receiver?.parent = this; |
| 1420 value?.parent = this; | 1412 value?.parent = this; |
| 1421 this.interfaceTarget = interfaceTarget; | |
| 1422 } | 1413 } |
| 1423 | 1414 |
| 1424 Member get interfaceTarget => _interfaceTargetReference?.target; | 1415 Member get interfaceTarget => interfaceTargetName?.asMember; |
| 1425 | 1416 |
| 1426 void set interfaceTarget(Member newTarget) { | 1417 void set interfaceTarget(Member member) { |
| 1427 _interfaceTargetReference = newTarget?._setterInterface; | 1418 interfaceTargetName = getCanonicalNameOfMember(member); |
| 1428 } | 1419 } |
| 1429 | 1420 |
| 1430 DartType getStaticType(TypeEnvironment types) => value.getStaticType(types); | 1421 DartType getStaticType(TypeEnvironment types) => value.getStaticType(types); |
| 1431 | 1422 |
| 1432 accept(ExpressionVisitor v) => v.visitPropertySet(this); | 1423 accept(ExpressionVisitor v) => v.visitPropertySet(this); |
| 1433 | 1424 |
| 1434 visitChildren(Visitor v) { | 1425 visitChildren(Visitor v) { |
| 1435 receiver?.accept(v); | 1426 receiver?.accept(v); |
| 1436 name?.accept(v); | 1427 name?.accept(v); |
| 1437 value?.accept(v); | 1428 value?.accept(v); |
| 1438 } | 1429 } |
| 1439 | 1430 |
| 1440 transformChildren(Transformer v) { | 1431 transformChildren(Transformer v) { |
| 1441 if (receiver != null) { | 1432 if (receiver != null) { |
| 1442 receiver = receiver.accept(v); | 1433 receiver = receiver.accept(v); |
| 1443 receiver?.parent = this; | 1434 receiver?.parent = this; |
| 1444 } | 1435 } |
| 1445 if (value != null) { | 1436 if (value != null) { |
| 1446 value = value.accept(v); | 1437 value = value.accept(v); |
| 1447 value?.parent = this; | 1438 value?.parent = this; |
| 1448 } | 1439 } |
| 1449 } | 1440 } |
| 1450 } | 1441 } |
| 1451 | 1442 |
| 1452 /// Directly read a field, call a getter, or tear off a method. | 1443 /// Directly read a field, call a getter, or tear off a method. |
| 1453 class DirectPropertyGet extends Expression { | 1444 class DirectPropertyGet extends Expression { |
| 1454 Expression receiver; | 1445 Expression receiver; |
| 1455 Member target; | 1446 CanonicalName targetName; |
| 1456 | 1447 |
| 1457 DirectPropertyGet(this.receiver, this.target) { | 1448 DirectPropertyGet(Expression receiver, Member target) |
| 1449 : this.byName(receiver, getCanonicalNameOfMember(target)); | |
| 1450 | |
| 1451 DirectPropertyGet.byName(this.receiver, this.targetName) { | |
| 1458 receiver?.parent = this; | 1452 receiver?.parent = this; |
| 1459 } | 1453 } |
| 1460 | 1454 |
| 1455 Member get target => targetName?.asMember; | |
| 1456 | |
| 1457 void set target(Member target) { | |
| 1458 targetName = getCanonicalNameOfMember(target); | |
| 1459 } | |
| 1460 | |
| 1461 visitChildren(Visitor v) { | 1461 visitChildren(Visitor v) { |
| 1462 receiver?.accept(v); | 1462 receiver?.accept(v); |
| 1463 target?.acceptReference(v); | 1463 target?.acceptReference(v); |
| 1464 } | 1464 } |
| 1465 | 1465 |
| 1466 transformChildren(Transformer v) { | 1466 transformChildren(Transformer v) { |
| 1467 if (receiver != null) { | 1467 if (receiver != null) { |
| 1468 receiver = receiver.accept(v); | 1468 receiver = receiver.accept(v); |
| 1469 receiver?.parent = this; | 1469 receiver?.parent = this; |
| 1470 } | 1470 } |
| 1471 } | 1471 } |
| 1472 | 1472 |
| 1473 accept(ExpressionVisitor v) => v.visitDirectPropertyGet(this); | 1473 accept(ExpressionVisitor v) => v.visitDirectPropertyGet(this); |
| 1474 | 1474 |
| 1475 DartType getStaticType(TypeEnvironment types) { | 1475 DartType getStaticType(TypeEnvironment types) { |
| 1476 Class superclass = target.enclosingClass; | 1476 Class superclass = target.enclosingClass; |
| 1477 var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types); | 1477 var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types); |
| 1478 return Substitution | 1478 return Substitution |
| 1479 .fromInterfaceType(receiverType) | 1479 .fromInterfaceType(receiverType) |
| 1480 .substituteType(target.getterType); | 1480 .substituteType(target.getterType); |
| 1481 } | 1481 } |
| 1482 } | 1482 } |
| 1483 | 1483 |
| 1484 /// Directly assign a field, or call a setter. | 1484 /// Directly assign a field, or call a setter. |
| 1485 /// | 1485 /// |
| 1486 /// Evaluates to the value of [value]. | 1486 /// Evaluates to the value of [value]. |
| 1487 class DirectPropertySet extends Expression { | 1487 class DirectPropertySet extends Expression { |
| 1488 Expression receiver; | 1488 Expression receiver; |
| 1489 Member target; | 1489 CanonicalName targetName; |
| 1490 Expression value; | 1490 Expression value; |
| 1491 | 1491 |
| 1492 DirectPropertySet(this.receiver, this.target, this.value) { | 1492 DirectPropertySet(Expression receiver, Member target, Expression value) |
| 1493 : this.byName(receiver, getCanonicalNameOfMember(target), value); | |
| 1494 | |
| 1495 DirectPropertySet.byName(this.receiver, this.targetName, this.value) { | |
| 1493 receiver?.parent = this; | 1496 receiver?.parent = this; |
| 1494 value?.parent = this; | 1497 value?.parent = this; |
| 1495 } | 1498 } |
| 1496 | 1499 |
| 1500 Member get target => targetName?.asMember; | |
| 1501 | |
| 1502 void set target(Member target) { | |
| 1503 targetName = getCanonicalNameOfMember(target); | |
| 1504 } | |
| 1505 | |
| 1497 visitChildren(Visitor v) { | 1506 visitChildren(Visitor v) { |
| 1498 receiver?.accept(v); | 1507 receiver?.accept(v); |
| 1499 target?.acceptReference(v); | 1508 target?.acceptReference(v); |
| 1500 value?.accept(v); | 1509 value?.accept(v); |
| 1501 } | 1510 } |
| 1502 | 1511 |
| 1503 transformChildren(Transformer v) { | 1512 transformChildren(Transformer v) { |
| 1504 if (receiver != null) { | 1513 if (receiver != null) { |
| 1505 receiver = receiver.accept(v); | 1514 receiver = receiver.accept(v); |
| 1506 receiver?.parent = this; | 1515 receiver?.parent = this; |
| 1507 } | 1516 } |
| 1508 if (value != null) { | 1517 if (value != null) { |
| 1509 value = value.accept(v); | 1518 value = value.accept(v); |
| 1510 value?.parent = this; | 1519 value?.parent = this; |
| 1511 } | 1520 } |
| 1512 } | 1521 } |
| 1513 | 1522 |
| 1514 accept(ExpressionVisitor v) => v.visitDirectPropertySet(this); | 1523 accept(ExpressionVisitor v) => v.visitDirectPropertySet(this); |
| 1515 | 1524 |
| 1516 DartType getStaticType(TypeEnvironment types) => value.getStaticType(types); | 1525 DartType getStaticType(TypeEnvironment types) => value.getStaticType(types); |
| 1517 } | 1526 } |
| 1518 | 1527 |
| 1519 /// Directly call an instance method, bypassing ordinary dispatch. | 1528 /// Directly call an instance method, bypassing ordinary dispatch. |
| 1520 class DirectMethodInvocation extends Expression { | 1529 class DirectMethodInvocation extends Expression { |
| 1521 Expression receiver; | 1530 Expression receiver; |
| 1522 Procedure target; | 1531 CanonicalName targetName; |
| 1523 Arguments arguments; | 1532 Arguments arguments; |
| 1524 | 1533 |
| 1525 DirectMethodInvocation(this.receiver, this.target, this.arguments) { | 1534 DirectMethodInvocation( |
| 1535 Expression receiver, Procedure target, Arguments arguments) | |
| 1536 : this.byName(receiver, getCanonicalNameOfMember(target), arguments); | |
| 1537 | |
| 1538 DirectMethodInvocation.byName( | |
| 1539 this.receiver, this.targetName, this.arguments) { | |
| 1526 receiver?.parent = this; | 1540 receiver?.parent = this; |
| 1527 arguments?.parent = this; | 1541 arguments?.parent = this; |
| 1528 } | 1542 } |
| 1529 | 1543 |
| 1544 Procedure get target => targetName?.asProcedure; | |
| 1545 | |
| 1546 void set target(Procedure target) { | |
| 1547 targetName = getCanonicalNameOfMember(target); | |
| 1548 } | |
| 1549 | |
| 1530 visitChildren(Visitor v) { | 1550 visitChildren(Visitor v) { |
| 1531 receiver?.accept(v); | 1551 receiver?.accept(v); |
| 1532 target?.acceptReference(v); | 1552 target?.acceptReference(v); |
| 1533 arguments?.accept(v); | 1553 arguments?.accept(v); |
| 1534 } | 1554 } |
| 1535 | 1555 |
| 1536 transformChildren(Transformer v) { | 1556 transformChildren(Transformer v) { |
| 1537 if (receiver != null) { | 1557 if (receiver != null) { |
| 1538 receiver = receiver.accept(v); | 1558 receiver = receiver.accept(v); |
| 1539 receiver?.parent = this; | 1559 receiver?.parent = this; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1560 .fromPairs(target.function.typeParameters, arguments.types) | 1580 .fromPairs(target.function.typeParameters, arguments.types) |
| 1561 .substituteType(returnType); | 1581 .substituteType(returnType); |
| 1562 } | 1582 } |
| 1563 } | 1583 } |
| 1564 | 1584 |
| 1565 /// Expression of form `super.field`. | 1585 /// Expression of form `super.field`. |
| 1566 /// | 1586 /// |
| 1567 /// This may invoke a getter, read a field, or tear off a method. | 1587 /// This may invoke a getter, read a field, or tear off a method. |
| 1568 class SuperPropertyGet extends Expression { | 1588 class SuperPropertyGet extends Expression { |
| 1569 Name name; | 1589 Name name; |
| 1570 _MemberAccessor _interfaceTargetReference; | 1590 CanonicalName interfaceTargetName; |
| 1571 | 1591 |
| 1572 SuperPropertyGet(this.name, [Member interfaceTarget]) { | 1592 SuperPropertyGet(Name name, [Member interfaceTarget]) |
| 1573 _interfaceTargetReference = interfaceTarget?._getterInterface; | 1593 : this.byName(name, getCanonicalNameOfMember(interfaceTarget)); |
| 1574 } | |
| 1575 | 1594 |
| 1576 Member get interfaceTarget => _interfaceTargetReference?.target; | 1595 SuperPropertyGet.byName(this.name, this.interfaceTargetName); |
| 1577 | 1596 |
| 1578 void set interfaceTarget(Member newTarget) { | 1597 Member get interfaceTarget => interfaceTargetName?.asMember; |
| 1579 _interfaceTargetReference = newTarget?._getterInterface; | 1598 |
| 1599 void set interfaceTarget(Member member) { | |
| 1600 interfaceTargetName = getCanonicalNameOfMember(member); | |
| 1580 } | 1601 } |
| 1581 | 1602 |
| 1582 DartType getStaticType(TypeEnvironment types) { | 1603 DartType getStaticType(TypeEnvironment types) { |
| 1583 Class declaringClass = interfaceTarget.enclosingClass; | 1604 Class declaringClass = interfaceTarget.enclosingClass; |
| 1584 if (declaringClass.typeParameters.isEmpty) { | 1605 if (declaringClass.typeParameters.isEmpty) { |
| 1585 return interfaceTarget.getterType; | 1606 return interfaceTarget.getterType; |
| 1586 } | 1607 } |
| 1587 var receiver = | 1608 var receiver = |
| 1588 types.hierarchy.getTypeAsInstanceOf(types.thisType, declaringClass); | 1609 types.hierarchy.getTypeAsInstanceOf(types.thisType, declaringClass); |
| 1589 return Substitution | 1610 return Substitution |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1601 } | 1622 } |
| 1602 | 1623 |
| 1603 /// Expression of form `super.field = value`. | 1624 /// Expression of form `super.field = value`. |
| 1604 /// | 1625 /// |
| 1605 /// This may invoke a setter or assign a field. | 1626 /// This may invoke a setter or assign a field. |
| 1606 /// | 1627 /// |
| 1607 /// Evaluates to the value of [value]. | 1628 /// Evaluates to the value of [value]. |
| 1608 class SuperPropertySet extends Expression { | 1629 class SuperPropertySet extends Expression { |
| 1609 Name name; | 1630 Name name; |
| 1610 Expression value; | 1631 Expression value; |
| 1611 _MemberAccessor _interfaceTargetReference; | 1632 CanonicalName interfaceTargetName; |
| 1612 | 1633 |
| 1613 SuperPropertySet(this.name, this.value, [Member interfaceTarget]) { | 1634 SuperPropertySet(Name name, Expression value, Member interfaceTarget) |
| 1635 : this.byName(name, value, getCanonicalNameOfMember(interfaceTarget)); | |
| 1636 | |
| 1637 SuperPropertySet.byName(this.name, this.value, this.interfaceTargetName) { | |
| 1614 value?.parent = this; | 1638 value?.parent = this; |
| 1615 _interfaceTargetReference = interfaceTarget?._setterInterface; | |
| 1616 } | 1639 } |
| 1617 | 1640 |
| 1618 Member get interfaceTarget => _interfaceTargetReference?.target; | 1641 Member get interfaceTarget => interfaceTargetName?.asMember; |
| 1619 | 1642 |
| 1620 void set interfaceTarget(Member newTarget) { | 1643 void set interfaceTarget(Member member) { |
| 1621 _interfaceTargetReference = newTarget?._setterInterface; | 1644 interfaceTargetName = getCanonicalNameOfMember(member); |
| 1622 } | 1645 } |
| 1623 | 1646 |
| 1624 DartType getStaticType(TypeEnvironment types) => value.getStaticType(types); | 1647 DartType getStaticType(TypeEnvironment types) => value.getStaticType(types); |
| 1625 | 1648 |
| 1626 accept(ExpressionVisitor v) => v.visitSuperPropertySet(this); | 1649 accept(ExpressionVisitor v) => v.visitSuperPropertySet(this); |
| 1627 | 1650 |
| 1628 visitChildren(Visitor v) { | 1651 visitChildren(Visitor v) { |
| 1629 name?.accept(v); | 1652 name?.accept(v); |
| 1630 value?.accept(v); | 1653 value?.accept(v); |
| 1631 } | 1654 } |
| 1632 | 1655 |
| 1633 transformChildren(Transformer v) { | 1656 transformChildren(Transformer v) { |
| 1634 if (value != null) { | 1657 if (value != null) { |
| 1635 value = value.accept(v); | 1658 value = value.accept(v); |
| 1636 value?.parent = this; | 1659 value?.parent = this; |
| 1637 } | 1660 } |
| 1638 } | 1661 } |
| 1639 } | 1662 } |
| 1640 | 1663 |
| 1641 /// Read a static field, call a static getter, or tear off a static method. | 1664 /// Read a static field, call a static getter, or tear off a static method. |
| 1642 class StaticGet extends Expression { | 1665 class StaticGet extends Expression { |
| 1643 /// A static field, getter, or method (for tear-off). | 1666 /// A static field, getter, or method (for tear-off). |
| 1644 Member target; | 1667 CanonicalName targetName; |
| 1645 | 1668 |
| 1646 StaticGet(this.target); | 1669 StaticGet(Member target) : this.byName(getCanonicalNameOfMember(target)); |
| 1670 | |
| 1671 StaticGet.byName(this.targetName); | |
| 1672 | |
| 1673 Member get target => targetName?.asMember; | |
| 1674 | |
| 1675 void set target(Member target) { | |
| 1676 targetName = getCanonicalNameOfMember(target); | |
| 1677 } | |
| 1647 | 1678 |
| 1648 DartType getStaticType(TypeEnvironment types) => target.getterType; | 1679 DartType getStaticType(TypeEnvironment types) => target.getterType; |
| 1649 | 1680 |
| 1650 accept(ExpressionVisitor v) => v.visitStaticGet(this); | 1681 accept(ExpressionVisitor v) => v.visitStaticGet(this); |
| 1651 | 1682 |
| 1652 visitChildren(Visitor v) { | 1683 visitChildren(Visitor v) { |
| 1653 target?.acceptReference(v); | 1684 target?.acceptReference(v); |
| 1654 } | 1685 } |
| 1655 | 1686 |
| 1656 transformChildren(Transformer v) {} | 1687 transformChildren(Transformer v) {} |
| 1657 } | 1688 } |
| 1658 | 1689 |
| 1659 /// Assign a static field or call a static setter. | 1690 /// Assign a static field or call a static setter. |
| 1660 /// | 1691 /// |
| 1661 /// Evaluates to the value of [value]. | 1692 /// Evaluates to the value of [value]. |
| 1662 class StaticSet extends Expression { | 1693 class StaticSet extends Expression { |
| 1663 /// A mutable static field or a static setter. | 1694 /// A mutable static field or a static setter. |
| 1664 Member target; | 1695 CanonicalName targetName; |
| 1665 Expression value; | 1696 Expression value; |
| 1666 | 1697 |
| 1667 StaticSet(this.target, this.value) { | 1698 StaticSet(Member target, Expression value) |
| 1699 : this.byName(getCanonicalNameOfMember(target), value); | |
| 1700 | |
| 1701 StaticSet.byName(this.targetName, this.value) { | |
| 1668 value?.parent = this; | 1702 value?.parent = this; |
| 1669 } | 1703 } |
| 1670 | 1704 |
| 1705 Member get target => targetName?.asMember; | |
| 1706 | |
| 1707 void set target(Member target) { | |
| 1708 targetName = getCanonicalNameOfMember(target); | |
| 1709 } | |
| 1710 | |
| 1671 DartType getStaticType(TypeEnvironment types) => value.getStaticType(types); | 1711 DartType getStaticType(TypeEnvironment types) => value.getStaticType(types); |
| 1672 | 1712 |
| 1673 accept(ExpressionVisitor v) => v.visitStaticSet(this); | 1713 accept(ExpressionVisitor v) => v.visitStaticSet(this); |
| 1674 | 1714 |
| 1675 visitChildren(Visitor v) { | 1715 visitChildren(Visitor v) { |
| 1676 target?.acceptReference(v); | 1716 target?.acceptReference(v); |
| 1677 value?.accept(v); | 1717 value?.accept(v); |
| 1678 } | 1718 } |
| 1679 | 1719 |
| 1680 transformChildren(Transformer v) { | 1720 transformChildren(Transformer v) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1754 /// May be `null` if the target is a synthetic static member without a name. | 1794 /// May be `null` if the target is a synthetic static member without a name. |
| 1755 Name get name; | 1795 Name get name; |
| 1756 } | 1796 } |
| 1757 | 1797 |
| 1758 /// Expression of form `x.foo(y)`. | 1798 /// Expression of form `x.foo(y)`. |
| 1759 class MethodInvocation extends InvocationExpression { | 1799 class MethodInvocation extends InvocationExpression { |
| 1760 Expression receiver; | 1800 Expression receiver; |
| 1761 Name name; | 1801 Name name; |
| 1762 Arguments arguments; | 1802 Arguments arguments; |
| 1763 | 1803 |
| 1764 Procedure interfaceTarget; | 1804 CanonicalName interfaceTargetName; |
| 1765 | 1805 |
| 1766 MethodInvocation(this.receiver, this.name, this.arguments, | 1806 MethodInvocation(Expression receiver, Name name, Arguments arguments, |
| 1767 [this.interfaceTarget]) { | 1807 [Procedure interfaceTarget]) |
| 1808 : this.byName(receiver, name, arguments, | |
| 1809 getCanonicalNameOfMember(interfaceTarget)); | |
| 1810 | |
| 1811 MethodInvocation.byName( | |
| 1812 this.receiver, this.name, this.arguments, this.interfaceTargetName) { | |
| 1768 receiver?.parent = this; | 1813 receiver?.parent = this; |
| 1769 arguments?.parent = this; | 1814 arguments?.parent = this; |
| 1770 } | 1815 } |
| 1771 | 1816 |
| 1817 Procedure get interfaceTarget => interfaceTargetName?.asProcedure; | |
| 1818 | |
| 1819 void set interfaceTarget(Member target) { | |
| 1820 interfaceTargetName = getCanonicalNameOfMember(target); | |
| 1821 } | |
| 1822 | |
| 1772 DartType getStaticType(TypeEnvironment types) { | 1823 DartType getStaticType(TypeEnvironment types) { |
| 1773 if (interfaceTarget != null) { | 1824 if (interfaceTarget != null) { |
| 1774 if (types.isOverloadedArithmeticOperator(interfaceTarget)) { | 1825 if (types.isOverloadedArithmeticOperator(interfaceTarget)) { |
| 1775 return types.getTypeOfOverloadedArithmetic( | 1826 return types.getTypeOfOverloadedArithmetic( |
| 1776 receiver.getStaticType(types), | 1827 receiver.getStaticType(types), |
| 1777 arguments.positional[0].getStaticType(types)); | 1828 arguments.positional[0].getStaticType(types)); |
| 1778 } | 1829 } |
| 1779 Class superclass = interfaceTarget.enclosingClass; | 1830 Class superclass = interfaceTarget.enclosingClass; |
| 1780 var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types); | 1831 var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types); |
| 1781 var returnType = Substitution | 1832 var returnType = Substitution |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1823 } | 1874 } |
| 1824 } | 1875 } |
| 1825 | 1876 |
| 1826 /// Expression of form `super.foo(x)`. | 1877 /// Expression of form `super.foo(x)`. |
| 1827 /// | 1878 /// |
| 1828 /// The provided arguments might not match the parameters of the target. | 1879 /// The provided arguments might not match the parameters of the target. |
| 1829 class SuperMethodInvocation extends InvocationExpression { | 1880 class SuperMethodInvocation extends InvocationExpression { |
| 1830 Name name; | 1881 Name name; |
| 1831 Arguments arguments; | 1882 Arguments arguments; |
| 1832 | 1883 |
| 1833 Member interfaceTarget; | 1884 CanonicalName interfaceTargetName; |
| 1834 | 1885 |
| 1835 SuperMethodInvocation(this.name, this.arguments, this.interfaceTarget) { | 1886 SuperMethodInvocation(Name name, Arguments arguments, |
| 1887 [Procedure interfaceTarget]) | |
| 1888 : this.byName(name, arguments, getCanonicalNameOfMember(interfaceTarget)); | |
| 1889 | |
| 1890 SuperMethodInvocation.byName( | |
| 1891 this.name, this.arguments, this.interfaceTargetName) { | |
| 1836 arguments?.parent = this; | 1892 arguments?.parent = this; |
| 1837 } | 1893 } |
| 1838 | 1894 |
| 1895 Procedure get interfaceTarget => interfaceTargetName?.asProcedure; | |
| 1896 | |
| 1897 void set interfaceTarget(Procedure target) { | |
| 1898 interfaceTargetName = getCanonicalNameOfMember(target); | |
| 1899 } | |
| 1900 | |
| 1839 DartType getStaticType(TypeEnvironment types) { | 1901 DartType getStaticType(TypeEnvironment types) { |
| 1840 if (interfaceTarget == null) return const DynamicType(); | 1902 if (interfaceTarget == null) return const DynamicType(); |
| 1841 Class superclass = interfaceTarget.enclosingClass; | 1903 Class superclass = interfaceTarget.enclosingClass; |
| 1842 var receiverType = | 1904 var receiverType = |
| 1843 types.hierarchy.getTypeAsInstanceOf(types.thisType, superclass); | 1905 types.hierarchy.getTypeAsInstanceOf(types.thisType, superclass); |
| 1844 var returnType = Substitution | 1906 var returnType = Substitution |
| 1845 .fromInterfaceType(receiverType) | 1907 .fromInterfaceType(receiverType) |
| 1846 .substituteType(interfaceTarget.function.returnType); | 1908 .substituteType(interfaceTarget.function.returnType); |
| 1847 return Substitution | 1909 return Substitution |
| 1848 .fromPairs(interfaceTarget.function.typeParameters, arguments.types) | 1910 .fromPairs(interfaceTarget.function.typeParameters, arguments.types) |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1862 arguments?.parent = this; | 1924 arguments?.parent = this; |
| 1863 } | 1925 } |
| 1864 } | 1926 } |
| 1865 } | 1927 } |
| 1866 | 1928 |
| 1867 /// Expression of form `foo(x)`, or `const foo(x)` if the target is an | 1929 /// Expression of form `foo(x)`, or `const foo(x)` if the target is an |
| 1868 /// external constant factory. | 1930 /// external constant factory. |
| 1869 /// | 1931 /// |
| 1870 /// The provided arguments might not match the parameters of the target. | 1932 /// The provided arguments might not match the parameters of the target. |
| 1871 class StaticInvocation extends InvocationExpression { | 1933 class StaticInvocation extends InvocationExpression { |
| 1872 Procedure target; | 1934 CanonicalName targetName; |
| 1873 Arguments arguments; | 1935 Arguments arguments; |
| 1874 | 1936 |
| 1875 /// True if this is a constant call to an external constant factory. | 1937 /// True if this is a constant call to an external constant factory. |
| 1876 bool isConst; | 1938 bool isConst; |
| 1877 | 1939 |
| 1878 Name get name => target?.name; | 1940 Name get name => target?.name; |
| 1879 | 1941 |
| 1880 StaticInvocation(this.target, this.arguments, {this.isConst: false}) { | 1942 StaticInvocation(Procedure target, Arguments arguments, {bool isConst: false}) |
| 1943 : this.byName(getCanonicalNameOfMember(target), arguments, | |
| 1944 isConst: isConst); | |
| 1945 | |
| 1946 StaticInvocation.byName(this.targetName, this.arguments, | |
| 1947 {this.isConst: false}) { | |
| 1881 arguments?.parent = this; | 1948 arguments?.parent = this; |
| 1882 } | 1949 } |
| 1883 | 1950 |
| 1951 Procedure get target => targetName?.asProcedure; | |
| 1952 | |
| 1953 void set target(Procedure target) { | |
| 1954 targetName = getCanonicalNameOfMember(target); | |
| 1955 } | |
| 1956 | |
| 1884 DartType getStaticType(TypeEnvironment types) { | 1957 DartType getStaticType(TypeEnvironment types) { |
| 1885 return Substitution | 1958 return Substitution |
| 1886 .fromPairs(target.function.typeParameters, arguments.types) | 1959 .fromPairs(target.function.typeParameters, arguments.types) |
| 1887 .substituteType(target.function.returnType); | 1960 .substituteType(target.function.returnType); |
| 1888 } | 1961 } |
| 1889 | 1962 |
| 1890 accept(ExpressionVisitor v) => v.visitStaticInvocation(this); | 1963 accept(ExpressionVisitor v) => v.visitStaticInvocation(this); |
| 1891 | 1964 |
| 1892 visitChildren(Visitor v) { | 1965 visitChildren(Visitor v) { |
| 1893 target?.acceptReference(v); | 1966 target?.acceptReference(v); |
| 1894 arguments?.accept(v); | 1967 arguments?.accept(v); |
| 1895 } | 1968 } |
| 1896 | 1969 |
| 1897 transformChildren(Transformer v) { | 1970 transformChildren(Transformer v) { |
| 1898 if (arguments != null) { | 1971 if (arguments != null) { |
| 1899 arguments = arguments.accept(v); | 1972 arguments = arguments.accept(v); |
| 1900 arguments?.parent = this; | 1973 arguments?.parent = this; |
| 1901 } | 1974 } |
| 1902 } | 1975 } |
| 1903 } | 1976 } |
| 1904 | 1977 |
| 1905 /// Expression of form `new Foo(x)` or `const Foo(x)`. | 1978 /// Expression of form `new Foo(x)` or `const Foo(x)`. |
| 1906 /// | 1979 /// |
| 1907 /// The provided arguments might not match the parameters of the target. | 1980 /// The provided arguments might not match the parameters of the target. |
| 1908 // | 1981 // |
| 1909 // DESIGN TODO: Should we pass type arguments in a separate field | 1982 // DESIGN TODO: Should we pass type arguments in a separate field |
| 1910 // `classTypeArguments`? They are quite different from type arguments to | 1983 // `classTypeArguments`? They are quite different from type arguments to |
| 1911 // generic functions. | 1984 // generic functions. |
| 1912 class ConstructorInvocation extends InvocationExpression { | 1985 class ConstructorInvocation extends InvocationExpression { |
| 1913 Constructor target; | 1986 CanonicalName targetName; |
| 1914 Arguments arguments; | 1987 Arguments arguments; |
| 1915 bool isConst; | 1988 bool isConst; |
| 1916 | 1989 |
| 1917 Name get name => target?.name; | 1990 Name get name => target?.name; |
| 1918 | 1991 |
| 1919 ConstructorInvocation(this.target, this.arguments, {this.isConst: false}) { | 1992 ConstructorInvocation(Constructor target, Arguments arguments, |
| 1993 {bool isConst: false}) | |
| 1994 : this.byName(getCanonicalNameOfMember(target), arguments, | |
| 1995 isConst: isConst); | |
| 1996 | |
| 1997 ConstructorInvocation.byName(this.targetName, this.arguments, | |
| 1998 {this.isConst: false}) { | |
| 1920 arguments?.parent = this; | 1999 arguments?.parent = this; |
| 1921 } | 2000 } |
| 1922 | 2001 |
| 2002 Constructor get target => targetName?.asConstructor; | |
| 2003 | |
| 2004 void set target(Constructor target) { | |
| 2005 targetName = getCanonicalNameOfMember(target); | |
| 2006 } | |
| 2007 | |
| 1923 DartType getStaticType(TypeEnvironment types) { | 2008 DartType getStaticType(TypeEnvironment types) { |
| 1924 return arguments.types.isEmpty | 2009 return arguments.types.isEmpty |
| 1925 ? target.enclosingClass.rawType | 2010 ? target.enclosingClass.rawType |
| 1926 : new InterfaceType(target.enclosingClass, arguments.types); | 2011 : new InterfaceType(target.enclosingClass, arguments.types); |
| 1927 } | 2012 } |
| 1928 | 2013 |
| 1929 accept(ExpressionVisitor v) => v.visitConstructorInvocation(this); | 2014 accept(ExpressionVisitor v) => v.visitConstructorInvocation(this); |
| 1930 | 2015 |
| 1931 visitChildren(Visitor v) { | 2016 visitChildren(Visitor v) { |
| 1932 target?.acceptReference(v); | 2017 target?.acceptReference(v); |
| (...skipping 1181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3114 /// statically resolved references are represented in nameless form. | 3199 /// statically resolved references are represented in nameless form. |
| 3115 /// | 3200 /// |
| 3116 /// [Name]s are immutable and compare based on structural equality, and they | 3201 /// [Name]s are immutable and compare based on structural equality, and they |
| 3117 /// are not AST nodes. | 3202 /// are not AST nodes. |
| 3118 /// | 3203 /// |
| 3119 /// The [toString] method returns a human-readable string that includes the | 3204 /// The [toString] method returns a human-readable string that includes the |
| 3120 /// library name for private names; uniqueness is not guaranteed. | 3205 /// library name for private names; uniqueness is not guaranteed. |
| 3121 abstract class Name implements Node { | 3206 abstract class Name implements Node { |
| 3122 final int hashCode; | 3207 final int hashCode; |
| 3123 final String name; | 3208 final String name; |
| 3209 CanonicalName get libraryName; | |
| 3124 Library get library; | 3210 Library get library; |
| 3125 bool get isPrivate; | 3211 bool get isPrivate; |
| 3126 | 3212 |
| 3127 Name._internal(this.hashCode, this.name); | 3213 Name._internal(this.hashCode, this.name); |
| 3128 | 3214 |
| 3129 factory Name(String name, [Library library]) { | 3215 factory Name(String name, [Library library]) => |
| 3216 new Name.byReference(name, library?.canonicalName); | |
| 3217 | |
| 3218 factory Name.byReference(String name, CanonicalName library) { | |
|
kustermann
2017/02/01 13:00:54
library -> libraryName
asgerf
2017/02/02 12:30:27
Done.
| |
| 3130 /// Use separate subclasses for the public and private case to save memory | 3219 /// Use separate subclasses for the public and private case to save memory |
| 3131 /// for public names. | 3220 /// for public names. |
| 3132 if (name.startsWith('_')) { | 3221 if (name.startsWith('_')) { |
| 3133 assert(library != null); | 3222 assert(library != null); |
| 3134 return new _PrivateName(name, library); | 3223 return new _PrivateName(name, library); |
| 3135 } else { | 3224 } else { |
| 3136 return new _PublicName(name); | 3225 return new _PublicName(name); |
| 3137 } | 3226 } |
| 3138 } | 3227 } |
| 3139 | 3228 |
| 3140 bool operator ==(other) { | 3229 bool operator ==(other) { |
| 3141 return other is Name && name == other.name && library == other.library; | 3230 return other is Name && name == other.name && library == other.library; |
| 3142 } | 3231 } |
| 3143 | 3232 |
| 3144 accept(Visitor v) => v.visitName(this); | 3233 accept(Visitor v) => v.visitName(this); |
| 3145 | 3234 |
| 3146 visitChildren(Visitor v) { | 3235 visitChildren(Visitor v) { |
| 3147 // DESIGN TODO: Should we visit the library as a library reference? | 3236 // DESIGN TODO: Should we visit the library as a library reference? |
| 3148 } | 3237 } |
| 3149 } | 3238 } |
| 3150 | 3239 |
| 3151 class _PrivateName extends Name { | 3240 class _PrivateName extends Name { |
| 3152 final Library library; | 3241 final CanonicalName libraryName; |
| 3153 bool get isPrivate => true; | 3242 bool get isPrivate => true; |
| 3154 | 3243 |
| 3155 _PrivateName(String name, Library library) | 3244 _PrivateName(String name, CanonicalName libraryName) |
| 3156 : this.library = library, | 3245 : this.libraryName = libraryName, |
| 3157 super._internal(_computeHashCode(name, library), name); | 3246 super._internal(_computeHashCode(name, libraryName), name); |
| 3158 | 3247 |
| 3159 String toString() => library != null ? '$library::$name' : name; | 3248 String toString() => library != null ? '$library::$name' : name; |
| 3160 | 3249 |
| 3161 static int _computeHashCode(String name, Library library) { | 3250 Library get library => libraryName.asLibrary; |
| 3162 return 131 * name.hashCode + 17 * library.hashCode; | 3251 |
| 3252 static int _computeHashCode(String name, CanonicalName libraryName) { | |
| 3253 return 131 * name.hashCode + 17 * libraryName.hashCode; | |
| 3163 } | 3254 } |
| 3164 } | 3255 } |
| 3165 | 3256 |
| 3166 class _PublicName extends Name { | 3257 class _PublicName extends Name { |
| 3258 CanonicalName get libraryName => null; | |
| 3167 Library get library => null; | 3259 Library get library => null; |
| 3168 bool get isPrivate => false; | 3260 bool get isPrivate => false; |
| 3169 | 3261 |
| 3170 _PublicName(String name) : super._internal(name.hashCode, name); | 3262 _PublicName(String name) : super._internal(name.hashCode, name); |
| 3171 | 3263 |
| 3172 String toString() => name; | 3264 String toString() => name; |
| 3173 } | 3265 } |
| 3174 | 3266 |
| 3175 // ------------------------------------------------------------------------ | 3267 // ------------------------------------------------------------------------ |
| 3176 // TYPES | 3268 // TYPES |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3236 | 3328 |
| 3237 const BottomType(); | 3329 const BottomType(); |
| 3238 | 3330 |
| 3239 accept(DartTypeVisitor v) => v.visitBottomType(this); | 3331 accept(DartTypeVisitor v) => v.visitBottomType(this); |
| 3240 visitChildren(Visitor v) {} | 3332 visitChildren(Visitor v) {} |
| 3241 | 3333 |
| 3242 bool operator ==(Object other) => other is BottomType; | 3334 bool operator ==(Object other) => other is BottomType; |
| 3243 } | 3335 } |
| 3244 | 3336 |
| 3245 class InterfaceType extends DartType { | 3337 class InterfaceType extends DartType { |
| 3246 final Class classNode; | 3338 final CanonicalName className; |
| 3247 final List<DartType> typeArguments; | 3339 final List<DartType> typeArguments; |
| 3248 | 3340 |
| 3249 /// The [typeArguments] list must not be modified after this call. If the | 3341 /// The [typeArguments] list must not be modified after this call. If the |
| 3250 /// list is omitted, 'dynamic' type arguments are filled in. | 3342 /// list is omitted, 'dynamic' type arguments are filled in. |
| 3251 InterfaceType(Class classNode, [List<DartType> typeArguments]) | 3343 InterfaceType(Class classNode, [List<DartType> typeArguments]) |
| 3252 : this.classNode = classNode, | 3344 : this.byName(getCanonicalNameOfClass(classNode), |
| 3253 this.typeArguments = typeArguments ?? _defaultTypeArguments(classNode); | 3345 typeArguments ?? _defaultTypeArguments(classNode)); |
| 3346 | |
| 3347 InterfaceType.byName(this.className, this.typeArguments); | |
| 3348 | |
| 3349 Class get classNode => className.asClass; | |
| 3254 | 3350 |
| 3255 static List<DartType> _defaultTypeArguments(Class classNode) { | 3351 static List<DartType> _defaultTypeArguments(Class classNode) { |
| 3256 if (classNode.typeParameters.length == 0) { | 3352 if (classNode.typeParameters.length == 0) { |
| 3257 // Avoid allocating a list in this very common case. | 3353 // Avoid allocating a list in this very common case. |
| 3258 return const <DartType>[]; | 3354 return const <DartType>[]; |
| 3259 } else { | 3355 } else { |
| 3260 return new List<DartType>.filled( | 3356 return new List<DartType>.filled( |
| 3261 classNode.typeParameters.length, const DynamicType()); | 3357 classNode.typeParameters.length, const DynamicType()); |
| 3262 } | 3358 } |
| 3263 } | 3359 } |
| 3264 | 3360 |
| 3265 accept(DartTypeVisitor v) => v.visitInterfaceType(this); | 3361 accept(DartTypeVisitor v) => v.visitInterfaceType(this); |
| 3266 | 3362 |
| 3267 visitChildren(Visitor v) { | 3363 visitChildren(Visitor v) { |
| 3268 classNode.acceptReference(v); | 3364 classNode.acceptReference(v); |
| 3269 visitList(typeArguments, v); | 3365 visitList(typeArguments, v); |
| 3270 } | 3366 } |
| 3271 | 3367 |
| 3272 bool operator ==(Object other) { | 3368 bool operator ==(Object other) { |
| 3273 if (identical(this, other)) return true; | 3369 if (identical(this, other)) return true; |
| 3274 if (other is InterfaceType) { | 3370 if (other is InterfaceType) { |
| 3275 if (classNode != other.classNode) return false; | 3371 if (className != other.className) return false; |
| 3276 if (typeArguments.length != other.typeArguments.length) return false; | 3372 if (typeArguments.length != other.typeArguments.length) return false; |
| 3277 for (int i = 0; i < typeArguments.length; ++i) { | 3373 for (int i = 0; i < typeArguments.length; ++i) { |
| 3278 if (typeArguments[i] != other.typeArguments[i]) return false; | 3374 if (typeArguments[i] != other.typeArguments[i]) return false; |
| 3279 } | 3375 } |
| 3280 return true; | 3376 return true; |
| 3281 } else { | 3377 } else { |
| 3282 return false; | 3378 return false; |
| 3283 } | 3379 } |
| 3284 } | 3380 } |
| 3285 | 3381 |
| 3286 int get hashCode { | 3382 int get hashCode { |
| 3287 int hash = 0x3fffffff & classNode.hashCode; | 3383 int hash = 0x3fffffff & className.hashCode; |
| 3288 for (int i = 0; i < typeArguments.length; ++i) { | 3384 for (int i = 0; i < typeArguments.length; ++i) { |
| 3289 hash = 0x3fffffff & (hash * 31 + (hash ^ typeArguments[i].hashCode)); | 3385 hash = 0x3fffffff & (hash * 31 + (hash ^ typeArguments[i].hashCode)); |
| 3290 } | 3386 } |
| 3291 return hash; | 3387 return hash; |
| 3292 } | 3388 } |
| 3293 } | 3389 } |
| 3294 | 3390 |
| 3295 /// A possibly generic function type. | 3391 /// A possibly generic function type. |
| 3296 class FunctionType extends DartType { | 3392 class FunctionType extends DartType { |
| 3297 final List<TypeParameter> typeParameters; | 3393 final List<TypeParameter> typeParameters; |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3465 transformChildren(Transformer v) { | 3561 transformChildren(Transformer v) { |
| 3466 bound = v.visitDartType(bound); | 3562 bound = v.visitDartType(bound); |
| 3467 } | 3563 } |
| 3468 | 3564 |
| 3469 /// Returns a possibly synthesized name for this type parameter, consistent | 3565 /// Returns a possibly synthesized name for this type parameter, consistent |
| 3470 /// with the names used across all [toString] calls. | 3566 /// with the names used across all [toString] calls. |
| 3471 String toString() => debugQualifiedTypeParameterName(this); | 3567 String toString() => debugQualifiedTypeParameterName(this); |
| 3472 } | 3568 } |
| 3473 | 3569 |
| 3474 class Supertype extends Node { | 3570 class Supertype extends Node { |
| 3475 final Class classNode; | 3571 final CanonicalName className; |
| 3476 final List<DartType> typeArguments; | 3572 final List<DartType> typeArguments; |
| 3477 | 3573 |
| 3478 Supertype(this.classNode, this.typeArguments); | 3574 Supertype(Class classNode, List<DartType> typeArguments) |
| 3575 : this.byName(getCanonicalNameOfClass(classNode), typeArguments); | |
| 3576 | |
| 3577 Supertype.byName(this.className, this.typeArguments); | |
| 3578 | |
| 3579 Class get classNode => className.asClass; | |
| 3479 | 3580 |
| 3480 accept(Visitor v) => v.visitSupertype(this); | 3581 accept(Visitor v) => v.visitSupertype(this); |
| 3481 | 3582 |
| 3482 visitChildren(Visitor v) { | 3583 visitChildren(Visitor v) { |
| 3483 classNode.acceptReference(v); | 3584 classNode.acceptReference(v); |
| 3484 visitList(typeArguments, v); | 3585 visitList(typeArguments, v); |
| 3485 } | 3586 } |
| 3486 | 3587 |
| 3487 InterfaceType get asInterfaceType { | 3588 InterfaceType get asInterfaceType { |
| 3488 return new InterfaceType(classNode, typeArguments); | 3589 return new InterfaceType(classNode, typeArguments); |
| 3489 } | 3590 } |
| 3490 | 3591 |
| 3491 bool operator ==(Object other) { | 3592 bool operator ==(Object other) { |
| 3492 if (identical(this, other)) return true; | 3593 if (identical(this, other)) return true; |
| 3493 if (other is Supertype) { | 3594 if (other is Supertype) { |
| 3494 if (classNode != other.classNode) return false; | 3595 if (className != other.className) return false; |
| 3495 if (typeArguments.length != other.typeArguments.length) return false; | 3596 if (typeArguments.length != other.typeArguments.length) return false; |
| 3496 for (int i = 0; i < typeArguments.length; ++i) { | 3597 for (int i = 0; i < typeArguments.length; ++i) { |
| 3497 if (typeArguments[i] != other.typeArguments[i]) return false; | 3598 if (typeArguments[i] != other.typeArguments[i]) return false; |
| 3498 } | 3599 } |
| 3499 return true; | 3600 return true; |
| 3500 } else { | 3601 } else { |
| 3501 return false; | 3602 return false; |
| 3502 } | 3603 } |
| 3503 } | 3604 } |
| 3504 | 3605 |
| 3505 int get hashCode { | 3606 int get hashCode { |
| 3506 int hash = 0x3fffffff & classNode.hashCode; | 3607 int hash = 0x3fffffff & className.hashCode; |
| 3507 for (int i = 0; i < typeArguments.length; ++i) { | 3608 for (int i = 0; i < typeArguments.length; ++i) { |
| 3508 hash = 0x3fffffff & (hash * 31 + (hash ^ typeArguments[i].hashCode)); | 3609 hash = 0x3fffffff & (hash * 31 + (hash ^ typeArguments[i].hashCode)); |
| 3509 } | 3610 } |
| 3510 return hash; | 3611 return hash; |
| 3511 } | 3612 } |
| 3512 } | 3613 } |
| 3513 | 3614 |
| 3514 // ------------------------------------------------------------------------ | 3615 // ------------------------------------------------------------------------ |
| 3515 // PROGRAM | 3616 // PROGRAM |
| 3516 // ------------------------------------------------------------------------ | 3617 // ------------------------------------------------------------------------ |
| 3517 | 3618 |
| 3518 /// A way to bundle up all the libraries in a program. | 3619 /// A way to bundle up all the libraries in a program. |
| 3519 class Program extends TreeNode { | 3620 class Program extends TreeNode { |
| 3621 final CanonicalName root = new CanonicalName.root(); | |
| 3622 | |
| 3520 final List<Library> libraries; | 3623 final List<Library> libraries; |
| 3521 | 3624 |
| 3522 /// Map from a source file uri to a line-starts table and source code. | 3625 /// Map from a source file uri to a line-starts table and source code. |
| 3523 /// Given a source file uri and a offset in that file one can translate | 3626 /// Given a source file uri and a offset in that file one can translate |
| 3524 /// it to a line:column position in that file. | 3627 /// it to a line:column position in that file. |
| 3525 final Map<String, Source> uriToSource; | 3628 final Map<String, Source> uriToSource; |
| 3526 | 3629 |
| 3527 /// Reference to the main method in one of the libraries. | 3630 /// Reference to the main method in one of the libraries. |
| 3528 Procedure mainMethod; | 3631 CanonicalName mainMethodName; |
| 3529 | 3632 |
| 3530 Program([List<Library> libraries, Map<String, Source> uriToSource]) | 3633 Program([List<Library> libraries, Map<String, Source> uriToSource]) |
| 3531 : libraries = libraries ?? <Library>[], | 3634 : libraries = libraries ?? <Library>[], |
| 3532 uriToSource = uriToSource ?? <String, Source>{} { | 3635 uriToSource = uriToSource ?? <String, Source>{} { |
| 3533 setParents(libraries, this); | 3636 setParents(this.libraries, this); |
| 3637 } | |
| 3638 | |
| 3639 Procedure get mainMethod => mainMethodName?.asProcedure; | |
| 3640 | |
| 3641 void set mainMethod(Procedure main) { | |
| 3642 mainMethodName = getCanonicalNameOfMember(main); | |
| 3534 } | 3643 } |
| 3535 | 3644 |
| 3536 accept(TreeVisitor v) => v.visitProgram(this); | 3645 accept(TreeVisitor v) => v.visitProgram(this); |
| 3537 | 3646 |
| 3538 visitChildren(Visitor v) { | 3647 visitChildren(Visitor v) { |
| 3539 visitList(libraries, v); | 3648 visitList(libraries, v); |
| 3540 mainMethod?.acceptReference(v); | 3649 mainMethod?.acceptReference(v); |
| 3541 } | 3650 } |
| 3542 | 3651 |
| 3543 transformChildren(Transformer v) { | 3652 transformChildren(Transformer v) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 3558 } else { | 3667 } else { |
| 3559 high = mid - 1; | 3668 high = mid - 1; |
| 3560 } | 3669 } |
| 3561 } | 3670 } |
| 3562 int lineIndex = low; | 3671 int lineIndex = low; |
| 3563 int lineStart = lines[lineIndex]; | 3672 int lineStart = lines[lineIndex]; |
| 3564 int lineNumber = 1 + lineIndex; | 3673 int lineNumber = 1 + lineIndex; |
| 3565 int columnNumber = 1 + offset - lineStart; | 3674 int columnNumber = 1 + offset - lineStart; |
| 3566 return new Location(file, lineNumber, columnNumber); | 3675 return new Location(file, lineNumber, columnNumber); |
| 3567 } | 3676 } |
| 3677 | |
| 3678 Library getLibraryReference(Uri uri) { | |
| 3679 assert(uri.hasScheme); | |
| 3680 var canonicalName = root.getChildFromUri(uri); | |
| 3681 Library library; | |
| 3682 if (canonicalName.definition == null) { | |
| 3683 library = new Library(uri, isExternal: true); | |
| 3684 canonicalName.linkTo(library); | |
| 3685 libraries.add(library..parent = this); | |
| 3686 } else { | |
| 3687 library = canonicalName.definition; | |
| 3688 } | |
| 3689 return library; | |
| 3690 } | |
| 3568 } | 3691 } |
| 3569 | 3692 |
| 3570 /// A tuple with file, line, and column number, for displaying human-readable | 3693 /// A tuple with file, line, and column number, for displaying human-readable |
| 3571 /// locations. | 3694 /// locations. |
| 3572 class Location { | 3695 class Location { |
| 3573 final String file; | 3696 final String file; |
| 3574 final int line; // 1-based. | 3697 final int line; // 1-based. |
| 3575 final int column; // 1-based. | 3698 final int column; // 1-based. |
| 3576 | 3699 |
| 3577 Location(this.file, this.line, this.column); | 3700 Location(this.file, this.line, this.column); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3666 } | 3789 } |
| 3667 } | 3790 } |
| 3668 } | 3791 } |
| 3669 | 3792 |
| 3670 class Source { | 3793 class Source { |
| 3671 final List<int> lineStarts; | 3794 final List<int> lineStarts; |
| 3672 final String source; | 3795 final String source; |
| 3673 | 3796 |
| 3674 Source(this.lineStarts, this.source); | 3797 Source(this.lineStarts, this.source); |
| 3675 } | 3798 } |
| 3799 | |
| 3800 /// Returns the canonical name of [member], or throws an exception if the | |
| 3801 /// member has not been assigned a canonical name yet. | |
| 3802 /// | |
| 3803 /// Returns `null` if the member is `null`. | |
| 3804 CanonicalName getCanonicalNameOfMember(Member member) { | |
| 3805 if (member == null) { | |
| 3806 return null; | |
| 3807 } | |
| 3808 var name = member.canonicalName; | |
| 3809 if (name == null) { | |
| 3810 throw '$member has no canonical name. ' | |
| 3811 'It must be added to a class or library before it can be referenced.'; | |
| 3812 } | |
| 3813 return name; | |
| 3814 } | |
| 3815 | |
| 3816 /// Returns the canonical name of [class_], or throws an exception if the | |
| 3817 /// class has not been assigned a canonical name yet. | |
| 3818 /// | |
| 3819 /// Returns `null` if the class is `null`. | |
| 3820 CanonicalName getCanonicalNameOfClass(Class class_) { | |
| 3821 if (class_ == null) { | |
| 3822 return null; | |
| 3823 } | |
| 3824 var name = class_.canonicalName; | |
| 3825 if (name == null) { | |
| 3826 throw '$class_ has no canonical name. ' | |
| 3827 'It must be added to a library before it can be referenced.'; | |
| 3828 } | |
| 3829 return name; | |
| 3830 } | |
| 3831 | |
| 3832 CanonicalName getCanonicalNameOfLibrary(Library library) { | |
|
kustermann
2017/02/01 13:00:54
for consistency you can add the comment here as we
asgerf
2017/02/02 12:30:27
Done.
| |
| 3833 if (library == null) { | |
| 3834 return null; | |
| 3835 } | |
| 3836 var name = library.canonicalName; | |
| 3837 if (name == null) { | |
| 3838 throw '$library has no canonical name. ' | |
| 3839 'It must be added to a program before it can be referenced.'; | |
| 3840 } | |
| 3841 return name; | |
| 3842 } | |
| OLD | NEW |