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