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

Side by Side Diff: pkg/kernel/lib/src/incremental_class_hierarchy.dart

Issue 2921083002: Implement getClassicLeastUpperBound() in IncrementalClassHierarchy. (Closed)
Patch Set: 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
« no previous file with comments | « no previous file | pkg/kernel/test/class_hierarchy_test.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) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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.incremental_class_hierarchy; 4 library kernel.incremental_class_hierarchy;
5 5
6 import 'dart:collection'; 6 import 'dart:collection';
7 import 'dart:math'; 7 import 'dart:math';
8 8
9 import 'package:kernel/ast.dart'; 9 import 'package:kernel/ast.dart';
10 import 'package:kernel/class_hierarchy.dart'; 10 import 'package:kernel/class_hierarchy.dart';
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 } 44 }
45 45
46 @override 46 @override
47 int getClassDepth(Class node) { 47 int getClassDepth(Class node) {
48 return _getInfo(node).depth; 48 return _getInfo(node).depth;
49 } 49 }
50 50
51 @override 51 @override
52 InterfaceType getClassicLeastUpperBound( 52 InterfaceType getClassicLeastUpperBound(
53 InterfaceType type1, InterfaceType type2) { 53 InterfaceType type1, InterfaceType type2) {
54 // TODO(scheglov): implement getClassicLeastUpperBound 54 // The algorithm is: first we compute a list of superclasses for both types,
55 throw new UnimplementedError(); 55 // ordered from greatest to least depth, and ordered by topological sort
56 // index within each depth. Due to the sort order, we can find the
57 // intersection of these lists by a simple walk.
58 //
59 // Then, for each class in the intersection, determine the exact type that
60 // is implemented by type1 and type2. If the types match, that type is a
61 // candidate (it's a member of S_n). As soon as we find a candidate which
62 // is unique for its depth, we return it.
63 //
64 // As an optimization, if the class for I is a subtype of the class for J,
65 // then we know that the list of superclasses of J is a subset of the list
66 // of superclasses for I; therefore it is sufficient to compute just the
67 // list of superclasses for J. To avoid complicating the code below (which
68 // intersects the two lists), we set both lists equal to the list of
69 // superclasses for J. And vice versa with the role of I and J swapped.
70
71 // Compute the list of superclasses for both types, with the above
72 // optimization.
73 _ClassInfo info1 = _getInfo(type1.classNode);
74 _ClassInfo info2 = _getInfo(type2.classNode);
75 List<_ClassInfo> classes1;
76 List<_ClassInfo> classes2;
77 if (identical(info1, info2) || info1.isSubtypeOf(info2)) {
78 classes1 = classes2 = _getRankedSuperclassList(info2);
79 } else if (info2.isSubtypeOf(info1)) {
80 classes1 = classes2 = _getRankedSuperclassList(info1);
81 } else {
82 classes1 = _getRankedSuperclassList(info1);
83 classes2 = _getRankedSuperclassList(info2);
84 }
85
86 // Walk the lists finding their intersection, looking for a depth that has a
87 // single candidate.
88 int i1 = 0;
89 int i2 = 0;
90 InterfaceType candidate = null;
91 int currentDepth = -1;
92 int numCandidatesAtThisDepth = 0;
93 while (true) {
94 _ClassInfo next = classes1[i1];
95 _ClassInfo next2 = classes2[i2];
96 if (!identical(next, next2)) {
97 if (_LubHeap.sortsBeforeStatic(next, next2)) {
98 ++i1;
99 } else {
100 ++i2;
101 }
102 continue;
103 }
104 ++i2;
105 ++i1;
106 if (next.depth != currentDepth) {
107 if (numCandidatesAtThisDepth == 1) return candidate;
108 currentDepth = next.depth;
109 numCandidatesAtThisDepth = 0;
110 candidate = null;
111 } else if (numCandidatesAtThisDepth > 1) {
112 continue;
113 }
114
115 // For each class in the intersection, find the exact type that is
116 // implemented by type1 and type2. If they match, it's a candidate.
117 //
118 // Two additional optimizations:
119 //
120 // - If this class lacks type parameters, we know there is a match without
121 // needing to substitute.
122 //
123 // - If the depth is 0, we have reached Object, so we can return it
124 // immediately. Since all interface types are subtypes of Object, this
125 // ensures the loop terminates.
126 if (next.node.typeParameters.isEmpty) {
127 candidate = next.node.rawType;
128 if (currentDepth == 0) return candidate;
129 ++numCandidatesAtThisDepth;
130 } else {
131 var superType1 = identical(info1, next)
132 ? type1
133 : Substitution.fromInterfaceType(type1).substituteType(
134 info1.genericSuperTypes[next.node].asInterfaceType);
135 var superType2 = identical(info2, next)
136 ? type2
137 : Substitution.fromInterfaceType(type2).substituteType(
138 info2.genericSuperTypes[next.node].asInterfaceType);
139 if (superType1 == superType2) {
140 candidate = superType1;
141 ++numCandidatesAtThisDepth;
142 }
143 }
144 }
56 } 145 }
57 146
58 @override 147 @override
59 int getClassIndex(Class node) { 148 int getClassIndex(Class node) {
60 return _getInfo(node).id; 149 return _getInfo(node).id;
61 } 150 }
62 151
63 @override 152 @override
64 Member getDispatchTarget(Class class_, Name name, {bool setter: false}) { 153 Member getDispatchTarget(Class class_, Name name, {bool setter: false}) {
65 // TODO(scheglov): implement getDispatchTarget 154 // TODO(scheglov): implement getDispatchTarget
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 class _LubHeap extends Heap<_ClassInfo> { 353 class _LubHeap extends Heap<_ClassInfo> {
265 @override 354 @override
266 bool sortsBefore(_ClassInfo a, _ClassInfo b) => sortsBeforeStatic(a, b); 355 bool sortsBefore(_ClassInfo a, _ClassInfo b) => sortsBeforeStatic(a, b);
267 356
268 static bool sortsBeforeStatic(_ClassInfo a, _ClassInfo b) { 357 static bool sortsBeforeStatic(_ClassInfo a, _ClassInfo b) {
269 if (a.depth > b.depth) return true; 358 if (a.depth > b.depth) return true;
270 if (a.depth < b.depth) return false; 359 if (a.depth < b.depth) return false;
271 return a.id < b.id; 360 return a.id < b.id;
272 } 361 }
273 } 362 }
OLDNEW
« no previous file with comments | « no previous file | pkg/kernel/test/class_hierarchy_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698