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. | |
ahe
2017/02/02 16:24:01
Add TODO?
asgerf
2017/02/03 10:31:16
I don't think it actually helps to spray non-actio
| |
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 |