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

Side by Side Diff: lib/src/checker/resolver.dart

Issue 1100633006: Generate static calls for Object fields and methods (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Better static dispatch check Created 5 years, 8 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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 /// Encapsulates how to invoke the analyzer resolver and overrides how it 5 /// Encapsulates how to invoke the analyzer resolver and overrides how it
6 /// computes types on expressions to use our restricted set of types. 6 /// computes types on expressions to use our restricted set of types.
7 library dev_compiler.src.checker.resolver; 7 library dev_compiler.src.checker.resolver;
8 8
9 import 'package:analyzer/analyzer.dart'; 9 import 'package:analyzer/analyzer.dart';
10 import 'package:analyzer/src/generated/ast.dart'; 10 import 'package:analyzer/src/generated/ast.dart';
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 visitor.overrideManager.currentScope = overrideScope; 562 visitor.overrideManager.currentScope = overrideScope;
563 visitor.nameScope = nameScope; 563 visitor.nameScope = nameScope;
564 } 564 }
565 } 565 }
566 566
567 /// Overrides the default [StaticTypeAnalyzer] to adjust rules that are stricter 567 /// Overrides the default [StaticTypeAnalyzer] to adjust rules that are stricter
568 /// in the restricted type system and to infer types for untyped local 568 /// in the restricted type system and to infer types for untyped local
569 /// variables. 569 /// variables.
570 class RestrictedStaticTypeAnalyzer extends StaticTypeAnalyzer { 570 class RestrictedStaticTypeAnalyzer extends StaticTypeAnalyzer {
571 final TypeProvider _typeProvider; 571 final TypeProvider _typeProvider;
572 Map<String, DartType> _objectMembers;
572 573
573 RestrictedStaticTypeAnalyzer(ResolverVisitor r) 574 RestrictedStaticTypeAnalyzer(ResolverVisitor r)
574 : _typeProvider = r.typeProvider, 575 : _typeProvider = r.typeProvider,
575 super(r); 576 super(r) {
577 _objectMembers = getObjectMemberMap(_typeProvider);
578 }
576 579
577 static constructor(ResolverVisitor r) => new RestrictedStaticTypeAnalyzer(r); 580 static constructor(ResolverVisitor r) => new RestrictedStaticTypeAnalyzer(r);
578 581
579 @override // to infer type from initializers 582 @override // to infer type from initializers
580 visitVariableDeclaration(VariableDeclaration node) { 583 visitVariableDeclaration(VariableDeclaration node) {
581 _inferType(node); 584 _inferType(node);
582 return super.visitVariableDeclaration(node); 585 return super.visitVariableDeclaration(node);
583 } 586 }
584 587
585 /// Infer the type of a variable based on the initializer's type. 588 /// Infer the type of a variable based on the initializer's type.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 var element = node.element as LocalVariableElementImpl; 644 var element = node.element as LocalVariableElementImpl;
642 var exprType = expr.staticType; 645 var exprType = expr.staticType;
643 if (exprType is InterfaceType) { 646 if (exprType is InterfaceType) {
644 var iteratedType = _findIteratedType(exprType); 647 var iteratedType = _findIteratedType(exprType);
645 if (iteratedType != null) { 648 if (iteratedType != null) {
646 element.type = iteratedType; 649 element.type = iteratedType;
647 } 650 }
648 } 651 }
649 } 652 }
650 653
651 Map<String, DartType> _objectMemberMap = null;
652
653 Map<String, DartType> _getObjectMemberMap() {
654 if (_objectMemberMap == null) {
655 _objectMemberMap = new Map<String, DartType>();
656 var objectType = _typeProvider.objectType;
657 var element = objectType.element;
658 // Only record methods (including getters) with no parameters. As paramet ers are contravariant wrt
659 // type, using Object's version may be too strict.
660 // Add instance methods.
661 element.methods
662 .where((method) => !method.isStatic && method.parameters.isEmpty)
663 .forEach((method) {
664 _objectMemberMap[method.name] = method.type;
665 });
666 // Add getters.
667 element.accessors
668 .where((member) => !member.isStatic && member.isGetter)
669 .forEach((member) {
670 _objectMemberMap[member.name] = member.type.returnType;
671 });
672 }
673 return _objectMemberMap;
674 }
675
676 List<DartType> _sealedTypes = null; 654 List<DartType> _sealedTypes = null;
677 655
678 bool _isSealed(DartType t) { 656 bool _isSealed(DartType t) {
679 if (_sealedTypes == null) { 657 if (_sealedTypes == null) {
680 // TODO(vsm): Use the analyzer's list - see dartbug.com/23125. 658 // TODO(vsm): Use the analyzer's list - see dartbug.com/23125.
681 _sealedTypes = <DartType>[ 659 _sealedTypes = <DartType>[
682 _typeProvider.nullType, 660 _typeProvider.nullType,
683 _typeProvider.numType, 661 _typeProvider.numType,
684 _typeProvider.intType, 662 _typeProvider.intType,
685 _typeProvider.doubleType, 663 _typeProvider.doubleType,
686 _typeProvider.boolType, 664 _typeProvider.boolType,
687 _typeProvider.stringType 665 _typeProvider.stringType
688 ]; 666 ];
689 } 667 }
690 return _sealedTypes.contains(t); 668 return _sealedTypes.contains(t);
691 } 669 }
692 670
693 @override // to propagate types to identifiers 671 @override // to propagate types to identifiers
694 visitMethodInvocation(MethodInvocation node) { 672 visitMethodInvocation(MethodInvocation node) {
695 // TODO(jmesserly): we rely on having a staticType propagated to the 673 // TODO(jmesserly): we rely on having a staticType propagated to the
696 // methodName identifier. This shouldn't be necessary for method calls, so 674 // methodName identifier. This shouldn't be necessary for method calls, so
697 // analyzer doesn't do it by default. Conceptually what we're doing here 675 // analyzer doesn't do it by default. Conceptually what we're doing here
698 // is asking for a tear off. We need this until we can fix #132, and rely 676 // is asking for a tear off. We need this until we can fix #132, and rely
699 // on `node.staticElement == null` instead of `rules.isDynamicCall(node)`. 677 // on `node.staticElement == null` instead of `rules.isDynamicCall(node)`.
700 visitSimpleIdentifier(node.methodName); 678 visitSimpleIdentifier(node.methodName);
701 679
702 super.visitMethodInvocation(node); 680 super.visitMethodInvocation(node);
703 681
704 // Search for Object methods. 682 // Search for Object methods.
705 var objectMap = _getObjectMemberMap();
706 var name = node.methodName.name; 683 var name = node.methodName.name;
707 if (node.staticType.isDynamic && 684 if (node.staticType.isDynamic &&
708 objectMap.containsKey(name) && 685 _objectMembers.containsKey(name) &&
709 isDynamicTarget(node.target)) { 686 isDynamicTarget(node.target)) {
710 var type = objectMap[name]; 687 var type = _objectMembers[name];
711 if (type is FunctionType && node.argumentList.arguments.isEmpty) { 688 if (type is FunctionType &&
689 type.parameters.isEmpty &&
690 node.argumentList.arguments.isEmpty) {
712 node.target.staticType = _typeProvider.objectType; 691 node.target.staticType = _typeProvider.objectType;
713 node.methodName.staticType = type; 692 node.methodName.staticType = type;
714 // Only infer the type of the overall expression if we have an exact 693 // Only infer the type of the overall expression if we have an exact
715 // type - e.g., a sealed type. Otherwise, it may be too strict. 694 // type - e.g., a sealed type. Otherwise, it may be too strict.
716 if (_isSealed(type.returnType)) { 695 if (_isSealed(type.returnType)) {
717 node.staticType = type.returnType; 696 node.staticType = type.returnType;
718 } 697 }
719 } 698 }
720 } 699 }
721 700
(...skipping 13 matching lines...) Expand all
735 var coreLib = _typeProvider.objectType.element.library; 714 var coreLib = _typeProvider.objectType.element.library;
736 var classElem = coreLib.getType(args.first.stringValue); 715 var classElem = coreLib.getType(args.first.stringValue);
737 if (classElem != null) node.staticType = classElem.type; 716 if (classElem != null) node.staticType = classElem.type;
738 } 717 }
739 } 718 }
740 } 719 }
741 720
742 void _inferObjectAccess( 721 void _inferObjectAccess(
743 Expression node, Expression target, SimpleIdentifier id) { 722 Expression node, Expression target, SimpleIdentifier id) {
744 // Search for Object accesses. 723 // Search for Object accesses.
745 var objectMap = _getObjectMemberMap();
746 var name = id.name; 724 var name = id.name;
747 if (node.staticType.isDynamic && 725 if (node.staticType.isDynamic &&
748 objectMap.containsKey(name) && 726 _objectMembers.containsKey(name) &&
749 isDynamicTarget(target)) { 727 isDynamicTarget(target)) {
750 target.staticType = _typeProvider.objectType; 728 target.staticType = _typeProvider.objectType;
751 var type = objectMap[name]; 729 var type = _objectMembers[name];
752 id.staticType = type; 730 id.staticType = type;
753 // Only infer the type of the overall expression if we have an exact 731 // Only infer the type of the overall expression if we have an exact
754 // type - e.g., a sealed type. Otherwise, it may be too strict. 732 // type - e.g., a sealed type. Otherwise, it may be too strict.
755 if (_isSealed(type)) { 733 if (_isSealed(type)) {
756 node.staticType = type; 734 node.staticType = type;
757 } 735 }
758 } 736 }
759 } 737 }
760 738
761 @override 739 @override
(...skipping 29 matching lines...) Expand all
791 } 769 }
792 } 770 }
793 771
794 // Review note: no longer need to override visitFunctionExpression, this is 772 // Review note: no longer need to override visitFunctionExpression, this is
795 // handled by the analyzer internally. 773 // handled by the analyzer internally.
796 // TODO(vsm): in visitbinaryExpression: check computeStaticReturnType result? 774 // TODO(vsm): in visitbinaryExpression: check computeStaticReturnType result?
797 // TODO(vsm): in visitFunctionDeclaration: Should we ever use the expression 775 // TODO(vsm): in visitFunctionDeclaration: Should we ever use the expression
798 // type in a (...) => expr or just the written type? 776 // type in a (...) => expr or just the written type?
799 777
800 } 778 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698