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

Side by Side Diff: lib/class_hierarchy.dart

Issue 2439043002: Introduce Substitution class and Supertype class. (Closed)
Patch Set: Created 4 years, 1 month 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
« no previous file with comments | « lib/binary/ast_to_binary.dart ('k') | lib/text/ast_to_text.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 library kernel.class_hierarchy; 4 library kernel.class_hierarchy;
5 5
6 import 'ast.dart'; 6 import 'ast.dart';
7 import 'dart:math'; 7 import 'dart:math';
8 import 'dart:typed_data'; 8 import 'dart:typed_data';
9 import 'type_algebra.dart'; 9 import 'type_algebra.dart';
10 10
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 return _infoFor[class_].directMixers.isNotEmpty; 57 return _infoFor[class_].directMixers.isNotEmpty;
58 } 58 }
59 59
60 /// True if the given class is used in an `implements` clause. 60 /// True if the given class is used in an `implements` clause.
61 bool isUsedAsSuperInterface(Class class_) { 61 bool isUsedAsSuperInterface(Class class_) {
62 return _infoFor[class_].directImplementers.isNotEmpty; 62 return _infoFor[class_].directImplementers.isNotEmpty;
63 } 63 }
64 64
65 /// Returns the instantiation of [superclass] that is implemented by [class_], 65 /// Returns the instantiation of [superclass] that is implemented by [class_],
66 /// or `null` if [class_] does not implement [superclass] at all. 66 /// or `null` if [class_] does not implement [superclass] at all.
67 InterfaceType getClassAsInstanceOf(Class class_, Class superclass) { 67 Supertype getClassAsInstanceOf(Class class_, Class superclass) {
68 if (identical(class_, superclass)) return class_.thisType; 68 if (identical(class_, superclass)) return class_.asThisSupertype;
69 _ClassInfo info = _infoFor[class_]; 69 _ClassInfo info = _infoFor[class_];
70 _ClassInfo superInfo = _infoFor[superclass]; 70 _ClassInfo superInfo = _infoFor[superclass];
71 if (!info.isSubtypeOf(superInfo)) return null; 71 if (!info.isSubtypeOf(superInfo)) return null;
72 if (superclass.typeParameters.isEmpty) return superclass.rawType; 72 if (superclass.typeParameters.isEmpty) return superclass.asRawSupertype;
73 return info.genericSuperTypes[superclass]; 73 return info.genericSuperTypes[superclass];
74 } 74 }
75 75
76 /// Returns the instantiation of [superclass] that is implemented by [type], 76 /// Returns the instantiation of [superclass] that is implemented by [type],
77 /// or `null` if [type] does not implement [superclass] at all. 77 /// or `null` if [type] does not implement [superclass] at all.
78 InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass) { 78 InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass) {
79 InterfaceType castedType = getClassAsInstanceOf(type.classNode, superclass); 79 Supertype castedType = getClassAsInstanceOf(type.classNode, superclass);
80 if (castedType == null) return null; 80 if (castedType == null) return null;
81 return substituteThisType(castedType, type); 81 return Substitution
82 .fromInterfaceType(type)
83 .substituteType(castedType.asInterfaceType);
82 } 84 }
83 85
84 /// Returns the instance member that would respond to a dynamic dispatch of 86 /// Returns the instance member that would respond to a dynamic dispatch of
85 /// [name] to an instance of [class_], or `null` if no such member exists. 87 /// [name] to an instance of [class_], or `null` if no such member exists.
86 /// 88 ///
87 /// If [setter] is `false`, the name is dispatched as a getter or call, 89 /// If [setter] is `false`, the name is dispatched as a getter or call,
88 /// and will return a field, getter, method, or operator (or null). 90 /// and will return a field, getter, method, or operator (or null).
89 /// 91 ///
90 /// If [setter] is `true`, the name is dispatched as a setter, roughly 92 /// If [setter] is `true`, the name is dispatched as a setter, roughly
91 /// corresponding to `name=` in the Dart specification, but note that the 93 /// corresponding to `name=` in the Dart specification, but note that the
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 } 350 }
349 351
350 List<Member> _buildInterfaceMembers(Class classNode, _ClassInfo info, 352 List<Member> _buildInterfaceMembers(Class classNode, _ClassInfo info,
351 {bool setters}) { 353 {bool setters}) {
352 List<Member> members = 354 List<Member> members =
353 setters ? info.interfaceSetters : info.interfaceGettersAndCalls; 355 setters ? info.interfaceSetters : info.interfaceGettersAndCalls;
354 if (members != null) return members; 356 if (members != null) return members;
355 List<Member> allInheritedMembers = <Member>[]; 357 List<Member> allInheritedMembers = <Member>[];
356 List<Member> declared = 358 List<Member> declared =
357 setters ? info.declaredSetters : info.declaredGettersAndCalls; 359 setters ? info.declaredSetters : info.declaredGettersAndCalls;
358 void inheritFrom(InterfaceType type) { 360 void inheritFrom(Supertype type) {
359 if (type == null) return; 361 if (type == null) return;
360 List<Member> inherited = _buildInterfaceMembers( 362 List<Member> inherited = _buildInterfaceMembers(
361 type.classNode, _infoFor[type.classNode], 363 type.classNode, _infoFor[type.classNode],
362 setters: setters); 364 setters: setters);
363 inherited = _getUnshadowedInheritedMembers(declared, inherited); 365 inherited = _getUnshadowedInheritedMembers(declared, inherited);
364 allInheritedMembers = _merge(allInheritedMembers, inherited); 366 allInheritedMembers = _merge(allInheritedMembers, inherited);
365 } 367 }
366 inheritFrom(classNode.supertype); 368 inheritFrom(classNode.supertype);
367 inheritFrom(classNode.mixedInType); 369 inheritFrom(classNode.mixedInType);
368 classNode.implementedTypes.forEach(inheritFrom); 370 classNode.implementedTypes.forEach(inheritFrom);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 while (i < first.length) { 486 while (i < first.length) {
485 result[storeIndex++] = first[i++]; 487 result[storeIndex++] = first[i++];
486 } 488 }
487 while (j < second.length) { 489 while (j < second.length) {
488 result[storeIndex++] = second[j++]; 490 result[storeIndex++] = second[j++];
489 } 491 }
490 result.length = storeIndex; 492 result.length = storeIndex;
491 return result; 493 return result;
492 } 494 }
493 495
494 void _recordSuperTypes(_ClassInfo subInfo, InterfaceType supertype) { 496 void _recordSuperTypes(_ClassInfo subInfo, Supertype supertype) {
495 _ClassInfo superInfo = _infoFor[supertype.classNode]; 497 _ClassInfo superInfo = _infoFor[supertype.classNode];
496 if (supertype.typeArguments.isEmpty) { 498 if (supertype.typeArguments.isEmpty) {
497 if (superInfo.genericSuperTypes == null) return; 499 if (superInfo.genericSuperTypes == null) return;
498 // Since the immediate super type is not generic, all entries in its 500 // Since the immediate super type is not generic, all entries in its
499 // super type map are also valid entries for this class. 501 // super type map are also valid entries for this class.
500 if (subInfo.genericSuperTypes == null && 502 if (subInfo.genericSuperTypes == null &&
501 superInfo.ownsGenericSuperTypeMap) { 503 superInfo.ownsGenericSuperTypeMap) {
502 // Instead of copying the map, take ownership of the map object. 504 // Instead of copying the map, take ownership of the map object.
503 // This may result in more entries being added to the map later. Those 505 // This may result in more entries being added to the map later. Those
504 // are not valid for the super type, but it works out because all 506 // are not valid for the super type, but it works out because all
505 // lookups in the map are guarded by a subtype check, so the super type 507 // lookups in the map are guarded by a subtype check, so the super type
506 // will not be bothered by the extra entries. 508 // will not be bothered by the extra entries.
507 subInfo.genericSuperTypes = superInfo.genericSuperTypes; 509 subInfo.genericSuperTypes = superInfo.genericSuperTypes;
508 superInfo.ownsGenericSuperTypeMap = false; 510 superInfo.ownsGenericSuperTypeMap = false;
509 } else { 511 } else {
510 // Copy over the super type entries. 512 // Copy over the super type entries.
511 subInfo.genericSuperTypes ??= <Class, InterfaceType>{}; 513 subInfo.genericSuperTypes ??= <Class, Supertype>{};
512 subInfo.genericSuperTypes.addAll(superInfo.genericSuperTypes); 514 subInfo.genericSuperTypes.addAll(superInfo.genericSuperTypes);
513 } 515 }
514 } else { 516 } else {
515 // Copy over all transitive generic super types, and substitute the 517 // Copy over all transitive generic super types, and substitute the
516 // free variables with those provided in [supertype]. 518 // free variables with those provided in [supertype].
517 Class superclass = supertype.classNode; 519 Class superclass = supertype.classNode;
518 var substitution = new Map<TypeParameter, DartType>.fromIterables( 520 var substitution = Substitution.fromPairs(
519 superclass.typeParameters, supertype.typeArguments); 521 superclass.typeParameters, supertype.typeArguments);
520 subInfo.genericSuperTypes ??= <Class, InterfaceType>{}; 522 subInfo.genericSuperTypes ??= <Class, Supertype>{};
521 superInfo.genericSuperTypes?.forEach((Class key, InterfaceType type) { 523 superInfo.genericSuperTypes?.forEach((Class key, Supertype type) {
522 subInfo.genericSuperTypes[key] = substitute(type, substitution); 524 subInfo.genericSuperTypes[key] = substitution.substituteSupertype(type);
523 }); 525 });
524 subInfo.genericSuperTypes[superclass] = supertype; 526 subInfo.genericSuperTypes[superclass] = supertype;
525 } 527 }
526 } 528 }
527 529
528 /// Downwards traversal of the class hierarchy that orders classes so local 530 /// Downwards traversal of the class hierarchy that orders classes so local
529 /// hierarchies have contiguous indices. 531 /// hierarchies have contiguous indices.
530 int _topDownSortIndex = 0; 532 int _topDownSortIndex = 0;
531 void _topDownSortVisit(_ClassInfo info) { 533 void _topDownSortVisit(_ClassInfo info) {
532 if (info.topDownIndex != -1) return; 534 if (info.topDownIndex != -1) return;
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 /// For example: 815 /// For example:
814 /// 816 ///
815 /// class Q<T> 817 /// class Q<T>
816 /// class A<T> 818 /// class A<T>
817 /// 819 ///
818 /// class B extends A<String> 820 /// class B extends A<String>
819 /// class C extends B implements Q<int> 821 /// class C extends B implements Q<int>
820 /// 822 ///
821 /// In this case, a single map object `{A: A<String>, Q: Q<int>}` may be 823 /// In this case, a single map object `{A: A<String>, Q: Q<int>}` may be
822 /// shared by the classes `B` and `C`. 824 /// shared by the classes `B` and `C`.
823 Map<Class, InterfaceType> genericSuperTypes; 825 Map<Class, Supertype> genericSuperTypes;
824 826
825 /// If true, this is the current "owner" of [genericSuperTypes], meaning 827 /// If true, this is the current "owner" of [genericSuperTypes], meaning
826 /// we may add additional entries to the map or transfer ownership to another 828 /// we may add additional entries to the map or transfer ownership to another
827 /// class. 829 /// class.
828 bool ownsGenericSuperTypeMap = true; 830 bool ownsGenericSuperTypeMap = true;
829 831
830 /// Instance fields, getters, methods, and operators declared in this class 832 /// Instance fields, getters, methods, and operators declared in this class
831 /// or its mixed-in class, sorted according to [_compareMembers]. 833 /// or its mixed-in class, sorted according to [_compareMembers].
832 List<Member> declaredGettersAndCalls; 834 List<Member> declaredGettersAndCalls;
833 835
834 /// Non-final instance fields and setters declared in this class or its 836 /// Non-final instance fields and setters declared in this class or its
835 /// mixed-in class, sorted according to [_compareMembers]. 837 /// mixed-in class, sorted according to [_compareMembers].
836 List<Member> declaredSetters; 838 List<Member> declaredSetters;
837 839
838 /// Instance fields, getters, methods, and operators implemented by this class 840 /// Instance fields, getters, methods, and operators implemented by this class
839 /// (declared or inherited). 841 /// (declared or inherited).
840 List<Member> implementedGettersAndCalls; 842 List<Member> implementedGettersAndCalls;
841 843
842 /// Non-final instance fields and setters implemented by this class 844 /// Non-final instance fields and setters implemented by this class
843 /// (declared or inherited). 845 /// (declared or inherited).
844 List<Member> implementedSetters; 846 List<Member> implementedSetters;
845 847
846 List<Member> interfaceGettersAndCalls; 848 List<Member> interfaceGettersAndCalls;
847 List<Member> interfaceSetters; 849 List<Member> interfaceSetters;
848 850
849 _ClassInfo(this.classNode); 851 _ClassInfo(this.classNode);
850 } 852 }
OLDNEW
« no previous file with comments | « lib/binary/ast_to_binary.dart ('k') | lib/text/ast_to_text.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698