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

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

Issue 2946733003: Fix type inference of getters that "override" setters and vice versa. (Closed)
Patch Set: Address code review comments Created 3 years, 6 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 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 'src/heap.dart'; 9 import 'src/heap.dart';
10 import 'type_algebra.dart'; 10 import 'type_algebra.dart';
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 /// an abstract member declared in this class. 108 /// an abstract member declared in this class.
109 /// 109 ///
110 /// This method will not report that a member overrides itself. A given pair 110 /// This method will not report that a member overrides itself. A given pair
111 /// may be reported multiple times when there are multiple inheritance paths 111 /// may be reported multiple times when there are multiple inheritance paths
112 /// to the overridden member. 112 /// to the overridden member.
113 /// 113 ///
114 /// It is possible for two methods to override one another in both directions. 114 /// It is possible for two methods to override one another in both directions.
115 /// 115 ///
116 /// By default getters and setters are overridden separately. The [isSetter] 116 /// By default getters and setters are overridden separately. The [isSetter]
117 /// callback parameter determines which type of access is being overridden. 117 /// callback parameter determines which type of access is being overridden.
118 void forEachOverridePair(Class class_,
119 callback(Member declaredMember, Member interfaceMember, bool isSetter));
120
121 /// Invokes [callback] for every function, field, or getter declared in
122 /// [class_] that has a corresponding setter in a supertype of [class_], and
123 /// for every setter or non-final field declared in [class_] that has a
124 /// corresponding function, field, or getter in a supertype of [class_].
118 /// 125 ///
119 /// However if [crossGettersSetters] is set to `true`, getters might be 126 /// We use the term "inheritable" for members that are candidates for
120 /// reported as overriding setters, and vice versa - setter overriding 127 /// inheritance but may have been overridden. The "declared" members of a
121 /// getters. The callback should check the [Procedure.kind] property. 128 /// mixin application are those declared in the mixed-in type. The callback is
122 void forEachOverridePair(Class class_, 129 /// invoked in the following case:
123 callback(Member declaredMember, Member interfaceMember, bool isSetter), 130 ///
124 {bool crossGettersSetters: false}); 131 /// A member declared in the class overrides a member inheritable through
132 /// one of the supertypes of the class.
133 ///
134 /// This method will not report that a member overrides itself. A given pair
135 /// may be reported multiple times when there are multiple inheritance paths
136 /// to the overridden member.
137 ///
138 /// By default getters and setters are overridden separately. The [isSetter]
scheglov 2017/06/26 20:29:12 "By default getters and setters are overridden sep
Paul Berry 2017/06/27 20:53:30 Thanks! https://codereview.chromium.org/296003300
139 /// callback parameter corresponds to whether [declaredMember] is a setter.
140 void forEachCrossOverridePair(Class class_,
141 callback(Member declaredMember, Member interfaceMember, bool isSetter));
125 142
126 /// This method is invoked by the client after it changed the [classes], and 143 /// This method is invoked by the client after it changed the [classes], and
127 /// some of the information that this hierarchy might have cached, is not 144 /// some of the information that this hierarchy might have cached, is not
128 /// valid anymore. The hierarchy may perform required updates and return the 145 /// valid anymore. The hierarchy may perform required updates and return the
129 /// same instance, or return a new instance. 146 /// same instance, or return a new instance.
130 ClassHierarchy applyChanges(Iterable<Class> classes); 147 ClassHierarchy applyChanges(Iterable<Class> classes);
131 } 148 }
132 149
133 /// Implementation of [ClassHierarchy] for closed world. 150 /// Implementation of [ClassHierarchy] for closed world.
134 class ClosedWorldClassHierarchy implements ClassHierarchy { 151 class ClosedWorldClassHierarchy implements ClassHierarchy {
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 var superclass = supertype.classNode; 406 var superclass = supertype.classNode;
390 var superGetters = getInterfaceMembers(superclass); 407 var superGetters = getInterfaceMembers(superclass);
391 var superSetters = getInterfaceMembers(superclass, setters: true); 408 var superSetters = getInterfaceMembers(superclass, setters: true);
392 _reportOverrides(info.implementedGettersAndCalls, superGetters, callback); 409 _reportOverrides(info.implementedGettersAndCalls, superGetters, callback);
393 _reportOverrides(info.declaredGettersAndCalls, superGetters, callback, 410 _reportOverrides(info.declaredGettersAndCalls, superGetters, callback,
394 onlyAbstract: true); 411 onlyAbstract: true);
395 _reportOverrides(info.implementedSetters, superSetters, callback, 412 _reportOverrides(info.implementedSetters, superSetters, callback,
396 isSetter: true); 413 isSetter: true);
397 _reportOverrides(info.declaredSetters, superSetters, callback, 414 _reportOverrides(info.declaredSetters, superSetters, callback,
398 isSetter: true, onlyAbstract: true); 415 isSetter: true, onlyAbstract: true);
399 if (crossGettersSetters) {
400 _reportOverrides(info.declaredGettersAndCalls, superSetters, callback);
401 _reportOverrides(info.declaredSetters, superGetters, callback);
402 }
403 } 416 }
404 if (!class_.isAbstract) { 417 if (!class_.isAbstract) {
405 // If a non-abstract class declares an abstract method M whose 418 // If a non-abstract class declares an abstract method M whose
406 // implementation M' is inherited from the superclass, then the inherited 419 // implementation M' is inherited from the superclass, then the inherited
407 // method M' overrides the declared method M. 420 // method M' overrides the declared method M.
408 // This flies in the face of conventional override logic, but is necessary 421 // This flies in the face of conventional override logic, but is necessary
409 // because an instance of the class will contain the method M' which can 422 // because an instance of the class will contain the method M' which can
410 // be invoked through the interface of M. 423 // be invoked through the interface of M.
411 // Note that [_reportOverrides] does not report self-overrides, so in 424 // Note that [_reportOverrides] does not report self-overrides, so in
412 // most cases these calls will just scan both lists and report nothing. 425 // most cases these calls will just scan both lists and report nothing.
413 _reportOverrides(info.implementedGettersAndCalls, 426 _reportOverrides(info.implementedGettersAndCalls,
414 info.declaredGettersAndCalls, callback); 427 info.declaredGettersAndCalls, callback);
415 _reportOverrides(info.implementedSetters, info.declaredSetters, callback, 428 _reportOverrides(info.implementedSetters, info.declaredSetters, callback,
416 isSetter: true); 429 isSetter: true);
417 } 430 }
418 } 431 }
419 432
433 @override
434 void forEachCrossOverridePair(Class class_,
435 callback(Member declaredMember, Member interfaceMember, bool isSetter),
436 {bool crossGettersSetters: false}) {
437 _ClassInfo info = _infoFor[class_];
438 for (var supertype in class_.supers) {
439 var superclass = supertype.classNode;
440 var superGetters = getInterfaceMembers(superclass);
441 var superSetters = getInterfaceMembers(superclass, setters: true);
442 _reportOverrides(info.declaredGettersAndCalls, superSetters, callback);
443 _reportOverrides(info.declaredSetters, superGetters, callback,
444 isSetter: true);
445 }
446 }
447
420 static void _reportOverrides( 448 static void _reportOverrides(
421 List<Member> declaredList, 449 List<Member> declaredList,
422 List<Member> inheritedList, 450 List<Member> inheritedList,
423 callback(Member declaredMember, Member interfaceMember, bool isSetter), 451 callback(Member declaredMember, Member interfaceMember, bool isSetter),
424 {bool isSetter: false, 452 {bool isSetter: false,
425 bool onlyAbstract: false}) { 453 bool onlyAbstract: false}) {
426 int i = 0, j = 0; 454 int i = 0, j = 0;
427 while (i < declaredList.length && j < inheritedList.length) { 455 while (i < declaredList.length && j < inheritedList.length) {
428 Member declared = declaredList[i]; 456 Member declared = declaredList[i];
429 if (onlyAbstract && !declared.isAbstract) { 457 if (onlyAbstract && !declared.isAbstract) {
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after
1140 class _LubHeap extends Heap<_ClassInfo> { 1168 class _LubHeap extends Heap<_ClassInfo> {
1141 @override 1169 @override
1142 bool sortsBefore(_ClassInfo a, _ClassInfo b) => sortsBeforeStatic(a, b); 1170 bool sortsBefore(_ClassInfo a, _ClassInfo b) => sortsBeforeStatic(a, b);
1143 1171
1144 static bool sortsBeforeStatic(_ClassInfo a, _ClassInfo b) { 1172 static bool sortsBeforeStatic(_ClassInfo a, _ClassInfo b) {
1145 if (a.depth > b.depth) return true; 1173 if (a.depth > b.depth) return true;
1146 if (a.depth < b.depth) return false; 1174 if (a.depth < b.depth) return false;
1147 return a.topologicalIndex < b.topologicalIndex; 1175 return a.topologicalIndex < b.topologicalIndex;
1148 } 1176 }
1149 } 1177 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698