Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(522)

Side by Side Diff: pkg/kernel/lib/ast.dart

Issue 2665723002: Implement canonical name scheme in kernel. (Closed)
Patch Set: Address comments Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698