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

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

Issue 2916383003: Implement getInterfaceMember() for IncrementalClassHierarchy. (Closed)
Patch Set: tweak 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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 208
209 @override 209 @override
210 Member getDispatchTarget(Class node, Name name, {bool setter: false}) { 210 Member getDispatchTarget(Class node, Name name, {bool setter: false}) {
211 _ClassInfo info = _getInfo(node); 211 _ClassInfo info = _getInfo(node);
212 List<Member> targets = 212 List<Member> targets =
213 setter ? info.implementedSetters : info.implementedGettersAndCalls; 213 setter ? info.implementedSetters : info.implementedGettersAndCalls;
214 return _findMemberByName(targets, name); 214 return _findMemberByName(targets, name);
215 } 215 }
216 216
217 @override 217 @override
218 Member getInterfaceMember(Class class_, Name name, {bool setter: false}) { 218 Member getInterfaceMember(Class node, Name name, {bool setter: false}) {
219 // TODO(scheglov): implement getInterfaceMember 219 _ClassInfo info = _getInfo(node);
220 throw new UnimplementedError(); 220 List<Member> members =
221 setter ? info.interfaceSetters : info.interfaceGettersAndCalls;
222 return _findMemberByName(members, name);
221 } 223 }
222 224
223 @override 225 @override
224 List<Class> getRankedSuperclasses(Class node) { 226 List<Class> getRankedSuperclasses(Class node) {
225 var info = _getInfo(node); 227 var info = _getInfo(node);
226 return _getRankedSuperclassList(info).map((info) => info.node).toList(); 228 return _getRankedSuperclassList(info).map((info) => info.node).toList();
227 } 229 }
228 230
229 @override 231 @override
230 InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass) { 232 InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass) {
231 Supertype castedType = getClassAsInstanceOf(type.classNode, superclass); 233 Supertype castedType = getClassAsInstanceOf(type.classNode, superclass);
232 if (castedType == null) return null; 234 if (castedType == null) return null;
233 return Substitution 235 return Substitution
234 .fromInterfaceType(type) 236 .fromInterfaceType(type)
235 .substituteType(castedType.asInterfaceType); 237 .substituteType(castedType.asInterfaceType);
236 } 238 }
237 239
238 @override 240 @override
239 bool hasProperSubtypes(Class class_) { 241 bool hasProperSubtypes(Class class_) {
240 // TODO(scheglov): implement hasProperSubtypes 242 // TODO(scheglov): implement hasProperSubtypes
241 throw new UnimplementedError(); 243 throw new UnimplementedError();
242 } 244 }
243 245
244 /// Fill the given [info] with declared methods and setters. 246 /// Fill the given [info] with declared instance methods and setters.
245 void _buildDeclaredMembers(_ClassInfo info) { 247 void _buildDeclaredMembers(_ClassInfo info) {
246 Class node = info.node; 248 Class node = info.node;
247 if (node.mixedInType != null) { 249 if (node.mixedInType != null) {
248 _ClassInfo mixedInfo = _getInfo(node.mixedInType.classNode); 250 _ClassInfo mixedInfo = _getInfo(node.mixedInType.classNode);
249 info.declaredGettersAndCalls = mixedInfo.declaredGettersAndCalls; 251 info.declaredGettersAndCalls = mixedInfo.declaredGettersAndCalls;
250 info.declaredSetters = mixedInfo.declaredSetters; 252 info.declaredSetters = mixedInfo.declaredSetters;
251 } else { 253 } else {
252 var members = info.declaredGettersAndCalls = <Member>[]; 254 var members = info.declaredGettersAndCalls = <Member>[];
253 var setters = info.declaredSetters = <Member>[]; 255 var setters = info.declaredSetters = <Member>[];
254 for (Procedure procedure in node.procedures) { 256 for (Procedure procedure in node.procedures) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 inheritedSetters = superInfo.implementedSetters; 288 inheritedSetters = superInfo.implementedSetters;
287 } 289 }
288 info.implementedGettersAndCalls = _inheritMembers( 290 info.implementedGettersAndCalls = _inheritMembers(
289 info.declaredGettersAndCalls, inheritedMembers, 291 info.declaredGettersAndCalls, inheritedMembers,
290 skipAbstractMembers: true); 292 skipAbstractMembers: true);
291 info.implementedSetters = _inheritMembers( 293 info.implementedSetters = _inheritMembers(
292 info.declaredSetters, inheritedSetters, 294 info.declaredSetters, inheritedSetters,
293 skipAbstractMembers: true); 295 skipAbstractMembers: true);
294 } 296 }
295 297
298 /// Build interface methods or setters for the class described by [info].
299 void _buildInterfaceMembers(_ClassInfo info) {
300 List<Member> declaredGetters = info.declaredGettersAndCalls;
301 List<Member> declaredSetters = info.declaredSetters;
302 List<Member> allInheritedGetters = <Member>[];
303 List<Member> allInheritedSetters = <Member>[];
304
305 void inheritFrom(Supertype type) {
306 if (type == null) return;
307 var info = _getInfo(type.classNode);
308 // TODO(scheglov): Can we optimize this with yield?
309
310 var inheritedGetters = _getUnshadowedInheritedMembers(
311 declaredGetters, info.interfaceGettersAndCalls);
312 allInheritedGetters = _merge(allInheritedGetters, inheritedGetters);
313
314 var inheritedSetters = _getUnshadowedInheritedMembers(
315 declaredSetters, info.interfaceSetters);
316 allInheritedSetters = _merge(allInheritedSetters, inheritedSetters);
317 }
318
319 Class node = info.node;
320 inheritFrom(node.supertype);
321 inheritFrom(node.mixedInType);
322 node.implementedTypes.forEach(inheritFrom);
323
324 info.interfaceGettersAndCalls =
325 _inheritMembers(declaredGetters, allInheritedGetters);
326 info.interfaceSetters =
327 _inheritMembers(declaredSetters, allInheritedSetters);
328 }
329
296 /// Return the [_ClassInfo] for the [node]. 330 /// Return the [_ClassInfo] for the [node].
297 _ClassInfo _getInfo(Class node) { 331 _ClassInfo _getInfo(Class node) {
298 var info = _info[node]; 332 var info = _info[node];
299 if (info == null) { 333 if (info == null) {
300 info = new _ClassInfo(_nextId++, node); 334 info = new _ClassInfo(_nextId++, node);
301 _info[node] = info; 335 _info[node] = info;
302 336
303 void addSupertypeIdentifiers(_ClassInfo superInfo) { 337 void addSupertypeIdentifiers(_ClassInfo superInfo) {
304 info.supertypeIdSet.add(superInfo.id); 338 info.supertypeIdSet.add(superInfo.id);
305 info.supertypeIdSet.addAll(superInfo.supertypeIdSet); 339 info.supertypeIdSet.addAll(superInfo.supertypeIdSet);
(...skipping 15 matching lines...) Expand all
321 for (var implementedType in node.implementedTypes) { 355 for (var implementedType in node.implementedTypes) {
322 var implementedInfo = _getInfo(implementedType.classNode); 356 var implementedInfo = _getInfo(implementedType.classNode);
323 superDepth = max(superDepth, implementedInfo.depth); 357 superDepth = max(superDepth, implementedInfo.depth);
324 addSupertypeIdentifiers(implementedInfo); 358 addSupertypeIdentifiers(implementedInfo);
325 _recordSuperTypes(info, implementedType, implementedInfo); 359 _recordSuperTypes(info, implementedType, implementedInfo);
326 } 360 }
327 info.depth = superDepth + 1; 361 info.depth = superDepth + 1;
328 362
329 _buildDeclaredMembers(info); 363 _buildDeclaredMembers(info);
330 _buildImplementedMembers(info); 364 _buildImplementedMembers(info);
365 _buildInterfaceMembers(info);
331 } 366 }
332 return info; 367 return info;
333 } 368 }
334 369
335 List<_ClassInfo> _getRankedSuperclassList(_ClassInfo info) { 370 List<_ClassInfo> _getRankedSuperclassList(_ClassInfo info) {
336 if (info.rankedSuperclassList != null) { 371 if (info.rankedSuperclassList != null) {
337 return info.rankedSuperclassList; 372 return info.rankedSuperclassList;
338 } 373 }
339 374
340 var heap = new _LubHeap()..add(info); 375 var heap = new _LubHeap()..add(info);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 var substitution = Substitution.fromPairs( 426 var substitution = Substitution.fromPairs(
392 superclass.typeParameters, supertype.typeArguments); 427 superclass.typeParameters, supertype.typeArguments);
393 subInfo.genericSuperTypes ??= <Class, Supertype>{}; 428 subInfo.genericSuperTypes ??= <Class, Supertype>{};
394 superInfo.genericSuperTypes?.forEach((Class key, Supertype type) { 429 superInfo.genericSuperTypes?.forEach((Class key, Supertype type) {
395 subInfo.genericSuperTypes[key] = substitution.substituteSupertype(type); 430 subInfo.genericSuperTypes[key] = substitution.substituteSupertype(type);
396 }); 431 });
397 subInfo.genericSuperTypes[superclass] = supertype; 432 subInfo.genericSuperTypes[superclass] = supertype;
398 } 433 }
399 } 434 }
400 435
436 /// Returns the subset of members in [inherited] for which a member with the
437 /// same name does not occur in [declared].
438 ///
439 /// The input lists must be sorted, and the returned list is sorted.
440 static List<Member> _getUnshadowedInheritedMembers(
441 List<Member> declared, List<Member> inherited) {
442 List<Member> result = <Member>[]..length = inherited.length;
Paul Berry 2017/06/03 13:27:34 Creating the list and then setting its length as t
scheglov 2017/06/04 00:47:47 Done.
443 int storeIndex = 0;
444 int i = 0, j = 0;
445 while (i < declared.length && j < inherited.length) {
446 Member declaredMember = declared[i];
447 Member inheritedMember = inherited[j];
448 int comparison = _compareMembers(declaredMember, inheritedMember);
449 if (comparison < 0) {
450 ++i;
451 } else if (comparison > 0) {
452 result[storeIndex++] = inheritedMember;
453 ++j;
454 } else {
455 // Move past the shadowed member, but retain the declared member, as
456 // it may shadow multiple members.
457 ++j;
458 }
459 }
460 // If the list of declared members is exhausted, copy over the remains of
461 // the inherited members.
462 while (j < inherited.length) {
463 result[storeIndex++] = inherited[j++];
464 }
465 result.length = storeIndex;
466 return result;
467 }
468
401 /// Computes the list of implemented members, based on the declared instance 469 /// Computes the list of implemented members, based on the declared instance
402 /// members and inherited instance members. 470 /// members and inherited instance members.
403 /// 471 ///
404 /// Both lists must be sorted by name beforehand. 472 /// Both lists must be sorted by name beforehand.
405 static List<Member> _inheritMembers( 473 static List<Member> _inheritMembers(
406 List<Member> declared, List<Member> inherited, 474 List<Member> declared, List<Member> inherited,
407 {bool skipAbstractMembers: false}) { 475 {bool skipAbstractMembers: false}) {
408 List<Member> result = <Member>[]..length = 476 List<Member> result = <Member>[]..length =
409 declared.length + inherited.length; 477 declared.length + inherited.length;
410 // Since both lists are sorted, we can fuse them like in merge sort. 478 // Since both lists are sorted, we can fuse them like in merge sort.
(...skipping 30 matching lines...) Expand all
441 result[storeIndex++] = declaredMember; 509 result[storeIndex++] = declaredMember;
442 } 510 }
443 while (j < inherited.length) { 511 while (j < inherited.length) {
444 Member inheritedMember = inherited[j++]; 512 Member inheritedMember = inherited[j++];
445 if (skipAbstractMembers && inheritedMember.isAbstract) continue; 513 if (skipAbstractMembers && inheritedMember.isAbstract) continue;
446 result[storeIndex++] = inheritedMember; 514 result[storeIndex++] = inheritedMember;
447 } 515 }
448 result.length = storeIndex; 516 result.length = storeIndex;
449 return result; 517 return result;
450 } 518 }
519
520 /// Merges two sorted lists.
521 ///
522 /// If a given member occurs in both lists, the merge will attempt to exclude
523 /// the duplicate member, but is not strictly guaranteed to do so.
524 static List<Member> _merge(List<Member> first, List<Member> second) {
525 if (first.isEmpty) return second;
526 if (second.isEmpty) return first;
527 List<Member> result = <Member>[]..length = first.length + second.length;
528 int storeIndex = 0;
529 int i = 0, j = 0;
530 while (i < first.length && j < second.length) {
531 Member firstMember = first[i];
532 Member secondMember = second[j];
533 int compare = _compareMembers(firstMember, secondMember);
534 if (compare <= 0) {
535 result[storeIndex++] = firstMember;
536 ++i;
537 // If the same member occurs in both lists, skip the duplicate.
538 if (identical(firstMember, secondMember)) {
539 ++j;
540 }
541 } else {
542 result[storeIndex++] = secondMember;
543 ++j;
544 }
545 }
546 while (i < first.length) {
547 result[storeIndex++] = first[i++];
548 }
549 while (j < second.length) {
550 result[storeIndex++] = second[j++];
551 }
552 result.length = storeIndex;
553 return result;
554 }
451 } 555 }
452 556
453 /// Information about a [Class]. 557 /// Information about a [Class].
454 class _ClassInfo { 558 class _ClassInfo {
455 /// The unique identifier of the [_ClassInfo]. 559 /// The unique identifier of the [_ClassInfo].
456 final int id; 560 final int id;
457 561
458 /// The [Class] node described by this [_ClassInfo]. 562 /// The [Class] node described by this [_ClassInfo].
459 final Class node; 563 final Class node;
460 564
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 List<Member> declaredSetters; 612 List<Member> declaredSetters;
509 613
510 /// Instance fields, getters, methods, and operators implemented by this class 614 /// Instance fields, getters, methods, and operators implemented by this class
511 /// (declared or inherited). 615 /// (declared or inherited).
512 List<Member> implementedGettersAndCalls; 616 List<Member> implementedGettersAndCalls;
513 617
514 /// Non-final instance fields and setters implemented by this class 618 /// Non-final instance fields and setters implemented by this class
515 /// (declared or inherited). 619 /// (declared or inherited).
516 List<Member> implementedSetters; 620 List<Member> implementedSetters;
517 621
622 /// Instance fields, getters, methods, and operators declared in this class,
623 /// or its supertype, or interfaces, sorted according to [_compareMembers],
624 /// or `null` if it has not been computed yet.
625 List<Member> interfaceGettersAndCalls;
626
627 /// Non-final instance fields and setters declared in this class, or its
628 /// supertype, or interfaces, sorted according to [_compareMembers], or
629 /// `null` if it has not been computed yet.
630 List<Member> interfaceSetters;
631
518 _ClassInfo(this.id, this.node); 632 _ClassInfo(this.id, this.node);
519 633
520 /// Return `true` if the [superInfo] corresponds to a supertype of this class. 634 /// Return `true` if the [superInfo] corresponds to a supertype of this class.
521 bool isSubtypeOf(_ClassInfo superInfo) { 635 bool isSubtypeOf(_ClassInfo superInfo) {
522 return supertypeIdSet.contains(superInfo.id); 636 return supertypeIdSet.contains(superInfo.id);
523 } 637 }
524 638
525 @override 639 @override
526 String toString() => node.toString(); 640 String toString() => node.toString();
527 } 641 }
528 642
529 /// Heap for use in computing least upper bounds. 643 /// Heap for use in computing least upper bounds.
530 /// 644 ///
531 /// The heap is sorted such that classes that are deepest in the hierarchy 645 /// The heap is sorted such that classes that are deepest in the hierarchy
532 /// are removed first; in the case of ties, classes with lower unique 646 /// are removed first; in the case of ties, classes with lower unique
533 /// identifiers removed first. 647 /// identifiers removed first.
534 class _LubHeap extends Heap<_ClassInfo> { 648 class _LubHeap extends Heap<_ClassInfo> {
535 @override 649 @override
536 bool sortsBefore(_ClassInfo a, _ClassInfo b) => sortsBeforeStatic(a, b); 650 bool sortsBefore(_ClassInfo a, _ClassInfo b) => sortsBeforeStatic(a, b);
537 651
538 static bool sortsBeforeStatic(_ClassInfo a, _ClassInfo b) { 652 static bool sortsBeforeStatic(_ClassInfo a, _ClassInfo b) {
539 if (a.depth > b.depth) return true; 653 if (a.depth > b.depth) return true;
540 if (a.depth < b.depth) return false; 654 if (a.depth < b.depth) return false;
541 return a.id < b.id; 655 return a.id < b.id;
542 } 656 }
543 } 657 }
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