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

Side by Side Diff: pkg/compiler/lib/src/inferrer/type_graph_nodes.dart

Issue 2971693002: Split MemberTypeInformation by member kind (Closed)
Patch Set: Updated cf. comments. Created 3 years, 5 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/compiler/lib/src/inferrer/type_system.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 library compiler.src.inferrer.type_graph_nodes; 5 library compiler.src.inferrer.type_graph_nodes;
6 6
7 import 'dart:collection' show IterableBase; 7 import 'dart:collection' show IterableBase;
8 8
9 import '../common.dart'; 9 import '../common.dart';
10 import '../common/names.dart' show Identifiers; 10 import '../common/names.dart' show Identifiers;
11 import '../compiler.dart' show Compiler; 11 import '../compiler.dart' show Compiler;
12 import '../constants/values.dart'; 12 import '../constants/values.dart';
13 import '../elements/elements.dart'; 13 import '../elements/elements.dart';
14 import '../elements/entities.dart'; 14 import '../elements/entities.dart';
15 import '../elements/resolution_types.dart' 15 import '../elements/resolution_types.dart'
16 show 16 show ResolutionDartType, ResolutionInterfaceType;
17 ResolutionDartType, 17 import '../elements/types.dart';
18 ResolutionFunctionType,
19 ResolutionInterfaceType,
20 ResolutionTypeKind;
21 import '../tree/tree.dart' as ast show Node, Send; 18 import '../tree/tree.dart' as ast show Node, Send;
22 import '../types/masks.dart' 19 import '../types/masks.dart'
23 show 20 show
24 CommonMasks, 21 CommonMasks,
25 ContainerTypeMask, 22 ContainerTypeMask,
26 DictionaryTypeMask, 23 DictionaryTypeMask,
27 MapTypeMask, 24 MapTypeMask,
28 TypeMask, 25 TypeMask,
29 ValueTypeMask; 26 ValueTypeMask;
30 import '../universe/selector.dart' show Selector; 27 import '../universe/selector.dart' show Selector;
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 * A node representing members in the broadest sense: 360 * A node representing members in the broadest sense:
364 * 361 *
365 * - Functions 362 * - Functions
366 * - Constructors 363 * - Constructors
367 * - Fields (also synthetic ones due to closures) 364 * - Fields (also synthetic ones due to closures)
368 * - Local functions (closures) 365 * - Local functions (closures)
369 * 366 *
370 * These should never be created directly but instead are constructed by 367 * These should never be created directly but instead are constructed by
371 * the [ElementTypeInformation] factory. 368 * the [ElementTypeInformation] factory.
372 */ 369 */
373 class MemberTypeInformation extends ElementTypeInformation 370 abstract class MemberTypeInformation extends ElementTypeInformation
374 with ApplyableTypeInformation { 371 with ApplyableTypeInformation {
375 MemberElement get _member => super._element; 372 MemberElement get _member => super._element;
376 373
377 /** 374 /**
378 * If [element] is a function, [closurizedCount] is the number of 375 * If [element] is a function, [closurizedCount] is the number of
379 * times it is closurized. The value gets updated while inferring. 376 * times it is closurized. The value gets updated while inferring.
380 */ 377 */
381 int closurizedCount = 0; 378 int closurizedCount = 0;
382 379
383 // Strict `bool` value is computed in cleanup(). Also used as a flag to see if 380 // Strict `bool` value is computed in cleanup(). Also used as a flag to see if
384 // cleanup has been called. 381 // cleanup has been called.
385 bool _isCalledOnce = null; 382 bool _isCalledOnce = null;
386 383
387 /** 384 /**
388 * This map contains the callers of [element]. It stores all unique call sites 385 * This map contains the callers of [element]. It stores all unique call sites
389 * to enable counting the global number of call sites of [element]. 386 * to enable counting the global number of call sites of [element].
390 * 387 *
391 * A call site is either an AST [ast.Node], an [Element] (see uses of 388 * A call site is either an AST [ast.Node], an [Element] (see uses of
392 * [synthesizeForwardingCall] in [SimpleTypeInferrerVisitor]). 389 * [synthesizeForwardingCall] in [SimpleTypeInferrerVisitor]).
393 * 390 *
394 * The global information is summarized in [cleanup], after which [_callers] 391 * The global information is summarized in [cleanup], after which [_callers]
395 * is set to `null`. 392 * is set to `null`.
396 */ 393 */
397 Map<MemberElement, Setlet<Spannable>> _callers; 394 Map<MemberElement, Setlet<Spannable>> _callers;
398 395
399 MemberTypeInformation(MemberElement element) : super._internal(null, element); 396 MemberTypeInformation._internal(MemberElement element)
397 : super._internal(null, element);
400 398
401 MemberElement get member => _element; 399 MemberElement get member => _element;
402 400
403 String get debugName => '$member'; 401 String get debugName => '$member';
404 402
405 void addCall(MemberElement caller, Spannable node) { 403 void addCall(MemberElement caller, Spannable node) {
406 assert(node is ast.Node || node is Element); 404 assert(node is ast.Node || node is Element);
407 _callers ??= <MemberElement, Setlet<Spannable>>{}; 405 _callers ??= <MemberElement, Setlet<Spannable>>{};
408 _callers.putIfAbsent(caller, () => new Setlet()).add(node); 406 _callers.putIfAbsent(caller, () => new Setlet()).add(node);
409 } 407 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 } 446 }
449 447
450 bool get isClosurized => closurizedCount > 0; 448 bool get isClosurized => closurizedCount > 0;
451 449
452 // Closurized methods never become stable to ensure that the information in 450 // Closurized methods never become stable to ensure that the information in
453 // [users] is accurate. The inference stops tracking users for stable types. 451 // [users] is accurate. The inference stops tracking users for stable types.
454 // Note that we only override the getter, the setter will still modify the 452 // Note that we only override the getter, the setter will still modify the
455 // state of the [isStable] field inherited from [TypeInformation]. 453 // state of the [isStable] field inherited from [TypeInformation].
456 bool get isStable => super.isStable && !isClosurized; 454 bool get isStable => super.isStable && !isClosurized;
457 455
458 TypeMask handleSpecialCases(InferrerEngine inferrer) { 456 TypeMask handleSpecialCases(InferrerEngine inferrer);
459 if (_member.isField &&
460 (!inferrer.backend.canFieldBeUsedForGlobalOptimizations(
461 _member, inferrer.closedWorld) ||
462 inferrer.assumeDynamic(_member))) {
463 // Do not infer types for fields that have a corresponding annotation or
464 // are assigned by synthesized calls
465 457
466 giveUp(inferrer); 458 TypeMask _handleFunctionCase(
467 return safeType(inferrer); 459 FunctionEntity function, InferrerEngine inferrer) {
468 } 460 if (inferrer.closedWorld.nativeData.isNativeMember(function)) {
469 if (inferrer.closedWorld.nativeData.isNativeMember(_member)) {
470 // Use the type annotation as the type for native elements. We 461 // Use the type annotation as the type for native elements. We
471 // also give up on inferring to make sure this element never 462 // also give up on inferring to make sure this element never
472 // goes in the work queue. 463 // goes in the work queue.
473 giveUp(inferrer); 464 giveUp(inferrer);
474 if (_member.isField) { 465 return inferrer
475 FieldElement field = _member; 466 .typeOfNativeBehavior(
476 return inferrer 467 inferrer.closedWorld.nativeData.getNativeMethodBehavior(function))
477 .typeOfNativeBehavior(inferrer.closedWorld.nativeData 468 .type;
478 .getNativeFieldLoadBehavior(field))
479 .type;
480 } else {
481 assert(_member.isFunction ||
482 _member.isGetter ||
483 _member.isSetter ||
484 _member.isConstructor);
485 MethodElement methodElement = _member;
486 var elementType = methodElement.type;
487 if (elementType.kind != ResolutionTypeKind.FUNCTION) {
488 return safeType(inferrer);
489 } else {
490 return inferrer
491 .typeOfNativeBehavior(inferrer.closedWorld.nativeData
492 .getNativeMethodBehavior(methodElement))
493 .type;
494 }
495 }
496 }
497
498 CommonMasks commonMasks = inferrer.commonMasks;
499 if (_member.isConstructor) {
500 ConstructorElement constructor = _member;
501 if (constructor.isIntFromEnvironmentConstructor) {
502 giveUp(inferrer);
503 return commonMasks.intType.nullable();
504 } else if (constructor.isBoolFromEnvironmentConstructor) {
505 giveUp(inferrer);
506 return commonMasks.boolType.nullable();
507 } else if (constructor.isStringFromEnvironmentConstructor) {
508 giveUp(inferrer);
509 return commonMasks.stringType.nullable();
510 }
511 } 469 }
512 return null; 470 return null;
513 } 471 }
514 472
515 TypeMask potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) { 473 TypeMask potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) {
516 Compiler compiler = inferrer.compiler; 474 Compiler compiler = inferrer.compiler;
517 if (!compiler.options.trustTypeAnnotations && 475 if (!compiler.options.trustTypeAnnotations &&
518 !compiler.options.enableTypeAssertions && 476 !compiler.options.enableTypeAssertions &&
519 !inferrer.trustTypeAnnotations(_member)) { 477 !inferrer.trustTypeAnnotations(_member)) {
520 return mask; 478 return mask;
521 } 479 }
522 if (_member.isGenerativeConstructor || _member.isSetter) { 480 return _potentiallyNarrowType(mask, inferrer);
523 return mask; 481 }
524 }
525 if (_member.isField) {
526 return _narrowType(inferrer.closedWorld, mask, _member.type);
527 }
528 assert(
529 _member.isFunction || _member.isGetter || _member.isFactoryConstructor);
530 482
531 ResolutionFunctionType type = _member.type; 483 TypeMask _potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer);
532 return _narrowType(inferrer.closedWorld, mask, type.returnType);
533 }
534 484
535 TypeMask computeType(InferrerEngine inferrer) { 485 TypeMask computeType(InferrerEngine inferrer) {
536 TypeMask special = handleSpecialCases(inferrer); 486 TypeMask special = handleSpecialCases(inferrer);
537 if (special != null) return potentiallyNarrowType(special, inferrer); 487 if (special != null) return potentiallyNarrowType(special, inferrer);
538 return potentiallyNarrowType( 488 return potentiallyNarrowType(
539 inferrer.types.computeTypeMask(assignments), inferrer); 489 inferrer.types.computeTypeMask(assignments), inferrer);
540 } 490 }
541 491
542 TypeMask safeType(InferrerEngine inferrer) { 492 TypeMask safeType(InferrerEngine inferrer) {
543 return potentiallyNarrowType(super.safeType(inferrer), inferrer); 493 return potentiallyNarrowType(super.safeType(inferrer), inferrer);
544 } 494 }
545 495
546 String toString() => 'MemberElement $_member $type'; 496 String toString() => 'MemberElement $_member $type';
547 497
548 accept(TypeInformationVisitor visitor) { 498 accept(TypeInformationVisitor visitor) {
549 return visitor.visitMemberTypeInformation(this); 499 return visitor.visitMemberTypeInformation(this);
550 } 500 }
551 501
552 bool hasStableType(InferrerEngine inferrer) {
553 // The number of assignments of non-final fields is
554 // not stable. Therefore such a field cannot be stable.
555 if (_member.isField && !(_member.isConst || _member.isFinal)) {
556 return false;
557 }
558
559 if (_member.isFunction) return false;
560
561 return super.hasStableType(inferrer);
562 }
563
564 void cleanup() { 502 void cleanup() {
565 // This node is on multiple lists so cleanup() can be called twice. 503 // This node is on multiple lists so cleanup() can be called twice.
566 if (_isCalledOnce != null) return; 504 if (_isCalledOnce != null) return;
567 _isCalledOnce = _computeIsCalledOnce(); 505 _isCalledOnce = _computeIsCalledOnce();
568 _callers = null; 506 _callers = null;
569 super.cleanup(); 507 super.cleanup();
570 } 508 }
571 509
572 @override 510 @override
573 String getInferredSignature(TypeSystem types) { 511 String getInferredSignature(TypeSystem types) {
574 return types.getInferredSignatureOfMethod(_member); 512 return types.getInferredSignatureOfMethod(_member);
575 } 513 }
576 } 514 }
577 515
516 class FieldTypeInformation extends MemberTypeInformation {
517 FieldElement get _field => _member;
518
519 FieldTypeInformation(FieldElement element) : super._internal(element);
520
521 TypeMask handleSpecialCases(InferrerEngine inferrer) {
522 if (!inferrer.backend.canFieldBeUsedForGlobalOptimizations(
523 _field, inferrer.closedWorld) ||
524 inferrer.assumeDynamic(_field)) {
525 // Do not infer types for fields that have a corresponding annotation or
526 // are assigned by synthesized calls
527
528 giveUp(inferrer);
529 return safeType(inferrer);
530 }
531 if (inferrer.closedWorld.nativeData.isNativeMember(_field)) {
532 // Use the type annotation as the type for native elements. We
533 // also give up on inferring to make sure this element never
534 // goes in the work queue.
535 giveUp(inferrer);
536 return inferrer
537 .typeOfNativeBehavior(inferrer.closedWorld.nativeData
538 .getNativeFieldLoadBehavior(_field))
539 .type;
540 }
541 return null;
542 }
543
544 TypeMask _potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) {
545 return _narrowType(inferrer.closedWorld, mask, _field.type);
546 }
547
548 bool hasStableType(InferrerEngine inferrer) {
549 // The number of assignments of non-final fields is
550 // not stable. Therefore such a field cannot be stable.
551 if (!(_field.isConst || _field.isFinal)) {
552 return false;
553 }
554 return super.hasStableType(inferrer);
555 }
556 }
557
558 class GetterTypeInformation extends MemberTypeInformation {
559 GetterElement get _getter => _member;
560
561 GetterTypeInformation(GetterElement element) : super._internal(element);
562
563 TypeMask handleSpecialCases(InferrerEngine inferrer) {
564 return _handleFunctionCase(_getter, inferrer);
565 }
566
567 TypeMask _potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) {
568 FunctionType type = _getter.type;
569 return _narrowType(inferrer.closedWorld, mask, type.returnType);
570 }
571 }
572
573 class SetterTypeInformation extends MemberTypeInformation {
574 SetterElement get _setter => _member;
575
576 SetterTypeInformation(SetterElement element) : super._internal(element);
577
578 TypeMask handleSpecialCases(InferrerEngine inferrer) {
579 return _handleFunctionCase(_setter, inferrer);
580 }
581
582 TypeMask _potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) {
583 return mask;
584 }
585 }
586
587 class MethodTypeInformation extends MemberTypeInformation {
588 MethodElement get _method => _member;
589
590 MethodTypeInformation(MethodElement element) : super._internal(element);
591
592 TypeMask handleSpecialCases(InferrerEngine inferrer) {
593 return _handleFunctionCase(_method, inferrer);
594 }
595
596 TypeMask _potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) {
597 FunctionType type = _method.type;
598 return _narrowType(inferrer.closedWorld, mask, type.returnType);
599 }
600
601 bool hasStableType(InferrerEngine inferrer) => false;
602 }
603
604 class FactoryConstructorTypeInformation extends MemberTypeInformation {
605 ConstructorElement get _constructor => _member;
606
607 FactoryConstructorTypeInformation(ConstructorElement element)
608 : super._internal(element);
609
610 TypeMask handleSpecialCases(InferrerEngine inferrer) {
611 CommonMasks commonMasks = inferrer.commonMasks;
612 if (_constructor.isIntFromEnvironmentConstructor) {
613 giveUp(inferrer);
614 return commonMasks.intType.nullable();
615 } else if (_constructor.isBoolFromEnvironmentConstructor) {
616 giveUp(inferrer);
617 return commonMasks.boolType.nullable();
618 } else if (_constructor.isStringFromEnvironmentConstructor) {
619 giveUp(inferrer);
620 return commonMasks.stringType.nullable();
621 }
622 return _handleFunctionCase(_constructor, inferrer);
623 }
624
625 TypeMask _potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) {
626 FunctionType type = _constructor.type;
627 return _narrowType(inferrer.closedWorld, mask, type.returnType);
628 }
629
630 bool hasStableType(InferrerEngine inferrer) {
631 return super.hasStableType(inferrer);
632 }
633 }
634
635 class GenerativeConstructorTypeInformation extends MemberTypeInformation {
636 ConstructorElement get _constructor => _member;
637
638 GenerativeConstructorTypeInformation(ConstructorElement element)
639 : super._internal(element);
640
641 TypeMask handleSpecialCases(InferrerEngine inferrer) {
642 return _handleFunctionCase(_constructor, inferrer);
643 }
644
645 TypeMask _potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) {
646 return mask;
647 }
648
649 bool hasStableType(InferrerEngine inferrer) {
650 return super.hasStableType(inferrer);
651 }
652 }
653
578 /** 654 /**
579 * A node representing parameters: 655 * A node representing parameters:
580 * 656 *
581 * - Parameters 657 * - Parameters
582 * - Initializing formals 658 * - Initializing formals
583 * 659 *
584 * These should never be created directly but instead are constructed by 660 * These should never be created directly but instead are constructed by
585 * the [ElementTypeInformation] factory. 661 * the [ElementTypeInformation] factory.
586 */ 662 */
587 class ParameterTypeInformation extends ElementTypeInformation { 663 class ParameterTypeInformation extends ElementTypeInformation {
588 ParameterElement get _parameter => super._element; 664 ParameterElement get _parameter => super._element;
589 final MethodElement _method; 665 final MethodElement _method;
590 bool _isInstanceMemberParameter; 666 bool _isInstanceMemberParameter;
591 bool _isClosureParameter; 667 bool _isClosureParameter;
592 bool _isTearOffClosureParameter = false; 668 bool _isTearOffClosureParameter = false;
593 669
594 ParameterTypeInformation.localFunction(MemberTypeInformation context, 670 ParameterTypeInformation.localFunction(
595 ParameterElement parameter, this._method) 671 MemberTypeInformation context, ParameterElement parameter, this._method)
596 : _isInstanceMemberParameter = false, 672 : _isInstanceMemberParameter = false,
597 _isClosureParameter = true, 673 _isClosureParameter = true,
598 super._internal(context, parameter); 674 super._internal(context, parameter);
599 675
600 ParameterTypeInformation.static( 676 ParameterTypeInformation.static(
601 MemberTypeInformation context, ParameterElement parameter, this._method) 677 MemberTypeInformation context, ParameterElement parameter, this._method)
602 : _isInstanceMemberParameter = false, 678 : _isInstanceMemberParameter = false,
603 _isClosureParameter = false, 679 _isClosureParameter = false,
604 super._internal(context, parameter); 680 super._internal(context, parameter);
605 681
(...skipping 1195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1801 // TODO(ngeoffray): Narrow to bound. 1877 // TODO(ngeoffray): Narrow to bound.
1802 return type; 1878 return type;
1803 } else { 1879 } else {
1804 ResolutionInterfaceType interfaceType = annotation; 1880 ResolutionInterfaceType interfaceType = annotation;
1805 otherType = new TypeMask.nonNullSubtype(interfaceType.element, closedWorld); 1881 otherType = new TypeMask.nonNullSubtype(interfaceType.element, closedWorld);
1806 } 1882 }
1807 if (isNullable) otherType = otherType.nullable(); 1883 if (isNullable) otherType = otherType.nullable();
1808 if (type == null) return otherType; 1884 if (type == null) return otherType;
1809 return type.intersection(otherType, closedWorld); 1885 return type.intersection(otherType, closedWorld);
1810 } 1886 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/inferrer/type_system.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698