Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 inferrer_visitor; | 5 library inferrer_visitor; |
| 6 | 6 |
| 7 import 'dart:collection' show | 7 import 'dart:collection' show |
| 8 IterableMixin; | 8 IterableMixin; |
| 9 | 9 |
| 10 import '../compiler.dart' show | 10 import '../compiler.dart' show |
| 11 Compiler; | 11 Compiler; |
| 12 import '../constants/constant_system.dart'; | 12 import '../constants/constant_system.dart'; |
| 13 import '../constants/expressions.dart'; | 13 import '../constants/expressions.dart'; |
| 14 import '../dart_types.dart'; | 14 import '../dart_types.dart'; |
| 15 import '../diagnostics/spannable.dart' show | 15 import '../diagnostics/spannable.dart' show |
| 16 Spannable; | 16 Spannable; |
| 17 import '../elements/elements.dart'; | 17 import '../elements/elements.dart'; |
| 18 import '../resolution/operators.dart'; | 18 import '../resolution/operators.dart'; |
| 19 import '../resolved_visitor.dart'; | 19 import '../resolution/semantic_visitor.dart'; |
| 20 import '../resolution/send_resolver.dart' show | |
| 21 SendResolverMixin; | |
| 22 import '../resolution/tree_elements.dart' show | |
| 23 TreeElements; | |
| 20 import '../tree/tree.dart'; | 24 import '../tree/tree.dart'; |
| 21 import '../types/types.dart' show | 25 import '../types/types.dart' show |
| 22 TypeMask; | 26 TypeMask; |
| 23 import '../types/constants.dart' show | 27 import '../types/constants.dart' show |
| 24 computeTypeMask; | 28 computeTypeMask; |
| 25 import '../universe/universe.dart'; | 29 import '../universe/universe.dart'; |
| 26 import '../util/util.dart'; | 30 import '../util/util.dart'; |
| 27 import '../world.dart' show | 31 import '../world.dart' show |
| 28 ClassWorld; | 32 ClassWorld; |
| 29 | 33 |
| (...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 676 locals[variable] = newType; | 680 locals[variable] = newType; |
| 677 } | 681 } |
| 678 }); | 682 }); |
| 679 } | 683 } |
| 680 | 684 |
| 681 void updateField(Element element, T type) { | 685 void updateField(Element element, T type) { |
| 682 fieldScope.updateField(element, type); | 686 fieldScope.updateField(element, type); |
| 683 } | 687 } |
| 684 } | 688 } |
| 685 | 689 |
| 686 abstract class InferrerVisitor | 690 abstract class InferrerVisitor<T, E extends MinimalInferrerEngine<T>> |
| 687 <T, E extends MinimalInferrerEngine<T>> extends NewResolvedVisitor<T> { | 691 extends Visitor<T> |
| 692 with SendResolverMixin, | |
| 693 SemanticSendResolvedMixin<T, dynamic>, | |
| 694 CompoundBulkMixin<T, dynamic>, | |
| 695 PrefixBulkMixin<T, dynamic>, | |
| 696 PostfixBulkMixin<T, dynamic>, | |
| 697 ErrorBulkMixin<T, dynamic>, | |
| 698 NewBulkMixin<T, dynamic>, | |
| 699 SetBulkMixin<T, dynamic> | |
| 700 implements SemanticSendVisitor<T, dynamic> { | |
| 688 final Compiler compiler; | 701 final Compiler compiler; |
| 689 final AstElement analyzedElement; | 702 final AstElement analyzedElement; |
| 690 final TypeSystem<T> types; | 703 final TypeSystem<T> types; |
| 691 final E inferrer; | 704 final E inferrer; |
| 692 final Map<JumpTarget, List<LocalsHandler<T>>> breaksFor = | 705 final Map<JumpTarget, List<LocalsHandler<T>>> breaksFor = |
| 693 new Map<JumpTarget, List<LocalsHandler<T>>>(); | 706 new Map<JumpTarget, List<LocalsHandler<T>>>(); |
| 694 final Map<JumpTarget, List<LocalsHandler>> continuesFor = | 707 final Map<JumpTarget, List<LocalsHandler>> continuesFor = |
| 695 new Map<JumpTarget, List<LocalsHandler<T>>>(); | 708 new Map<JumpTarget, List<LocalsHandler<T>>>(); |
| 696 LocalsHandler<T> locals; | 709 LocalsHandler<T> locals; |
| 697 final List<T> cascadeReceiverStack = new List<T>(); | 710 final List<T> cascadeReceiverStack = new List<T>(); |
| 711 final TreeElements elements; | |
| 698 | 712 |
| 699 bool accumulateIsChecks = false; | 713 bool accumulateIsChecks = false; |
| 700 bool conditionIsSimple = false; | 714 bool conditionIsSimple = false; |
| 701 List<Send> isChecks; | 715 List<Send> isChecks; |
| 702 int loopLevel = 0; | 716 int loopLevel = 0; |
| 703 | 717 |
| 704 bool get inLoop => loopLevel > 0; | 718 bool get inLoop => loopLevel > 0; |
| 705 bool get isThisExposed { | 719 bool get isThisExposed { |
| 706 return analyzedElement.isGenerativeConstructor | 720 return analyzedElement.isGenerativeConstructor |
| 707 ? locals.fieldScope.isThisExposed | 721 ? locals.fieldScope.isThisExposed |
| 708 : true; | 722 : true; |
| 709 } | 723 } |
| 710 void set isThisExposed(value) { | 724 void set isThisExposed(value) { |
| 711 if (analyzedElement.isGenerativeConstructor) { | 725 if (analyzedElement.isGenerativeConstructor) { |
| 712 locals.fieldScope.isThisExposed = value; | 726 locals.fieldScope.isThisExposed = value; |
| 713 } | 727 } |
| 714 } | 728 } |
| 715 | 729 |
| 716 InferrerVisitor(AstElement analyzedElement, | 730 InferrerVisitor(AstElement analyzedElement, |
| 717 this.inferrer, | 731 this.inferrer, |
| 718 this.types, | 732 this.types, |
| 719 this.compiler, | 733 this.compiler, |
| 720 [LocalsHandler<T> handler]) | 734 [LocalsHandler<T> handler]) |
| 721 : this.analyzedElement = analyzedElement, | 735 : this.analyzedElement = analyzedElement, |
| 722 this.locals = handler, | 736 this.locals = handler, |
| 723 super(analyzedElement.resolvedAst.elements) { | 737 this.elements = analyzedElement.resolvedAst.elements { |
| 724 if (handler != null) return; | 738 if (handler != null) return; |
| 725 Node node = analyzedElement.node; | 739 Node node = analyzedElement.node; |
| 726 FieldInitializationScope<T> fieldScope = | 740 FieldInitializationScope<T> fieldScope = |
| 727 analyzedElement.isGenerativeConstructor | 741 analyzedElement.isGenerativeConstructor |
| 728 ? new FieldInitializationScope<T>(types) | 742 ? new FieldInitializationScope<T>(types) |
| 729 : null; | 743 : null; |
| 730 locals = new LocalsHandler<T>(inferrer, types, compiler, node, fieldScope); | 744 locals = new LocalsHandler<T>(inferrer, types, compiler, node, fieldScope); |
| 731 } | 745 } |
| 732 | 746 |
| 747 @override | |
| 748 SemanticSendVisitor get sendVisitor => this; | |
| 749 | |
| 750 @override | |
| 751 T apply(Node node, _) => visit(node); | |
| 752 | |
| 733 T handleSendSet(SendSet node); | 753 T handleSendSet(SendSet node); |
| 734 | 754 |
| 735 T handleDynamicInvoke(Send node); | 755 T handleDynamicInvoke(Send node); |
| 736 | 756 |
| 737 T visitAsyncForIn(AsyncForIn node); | 757 T visitAsyncForIn(AsyncForIn node); |
| 738 | 758 |
| 739 T visitSyncForIn(SyncForIn node); | 759 T visitSyncForIn(SyncForIn node); |
| 740 | 760 |
| 741 T visitReturn(Return node); | 761 T visitReturn(Return node); |
| 742 | 762 |
| 743 T visitFunctionExpression(FunctionExpression node); | 763 T visitFunctionExpression(FunctionExpression node); |
| 744 | 764 |
| 745 @override | 765 @override |
| 766 T bulkHandleSet(SendSet node, _) { | |
| 767 return handleSendSet(node); | |
| 768 } | |
| 769 | |
| 770 @override | |
| 771 T bulkHandleCompound(SendSet node, _) { | |
| 772 return handleSendSet(node); | |
| 773 } | |
| 774 | |
| 775 @override | |
| 776 T bulkHandlePrefix(SendSet node, _) { | |
| 777 return handleSendSet(node); | |
| 778 } | |
| 779 | |
| 780 @override | |
| 781 T bulkHandlePostfix(SendSet node, _) { | |
| 782 return handleSendSet(node); | |
| 783 } | |
| 784 | |
| 785 @override | |
| 746 T visitAssert(Send node, Node expression, _) { | 786 T visitAssert(Send node, Node expression, _) { |
| 747 if (!compiler.enableUserAssertions) { | 787 if (!compiler.enableUserAssertions) { |
| 748 return types.nullType; | 788 return types.nullType; |
| 749 } | 789 } |
| 750 return handleAssert(node, expression); | 790 return handleAssert(node, expression); |
| 751 } | 791 } |
| 752 | 792 |
| 753 /// Handle an enabled assertion of [expression]. | 793 /// Handle an enabled assertion of [expression]. |
| 754 T handleAssert(Send node, Node expression); | 794 T handleAssert(Send node, Node expression); |
| 755 | 795 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 814 return types.nullType; | 854 return types.nullType; |
| 815 } | 855 } |
| 816 | 856 |
| 817 T visitLiteralSymbol(LiteralSymbol node) { | 857 T visitLiteralSymbol(LiteralSymbol node) { |
| 818 // TODO(kasperl): We should be able to tell that the type of a literal | 858 // TODO(kasperl): We should be able to tell that the type of a literal |
| 819 // symbol is always a non-null exact symbol implementation -- not just | 859 // symbol is always a non-null exact symbol implementation -- not just |
| 820 // any non-null subtype of the symbol interface. | 860 // any non-null subtype of the symbol interface. |
| 821 return types.nonNullSubtype(compiler.symbolClass); | 861 return types.nonNullSubtype(compiler.symbolClass); |
| 822 } | 862 } |
| 823 | 863 |
| 824 T visitTypePrefixSend(Send node) { | |
| 825 // TODO(johnniwinther): Remove the need for handling this node. | |
| 826 return types.dynamicType; | |
| 827 } | |
| 828 | |
| 829 @override | 864 @override |
| 830 void previsitDeferredAccess(Send node, PrefixElement prefix, _) { | 865 void previsitDeferredAccess(Send node, PrefixElement prefix, _) { |
| 831 // Deferred access does not affect inference. | 866 // Deferred access does not affect inference. |
| 832 } | 867 } |
| 833 | 868 |
| 834 T handleTypeLiteralGet() { | 869 T handleTypeLiteralGet() { |
| 835 return types.typeType; | 870 return types.typeType; |
| 836 } | 871 } |
| 837 | 872 |
| 838 T handleTypeLiteralInvoke(NodeList arguments) { | 873 T handleTypeLiteralInvoke(NodeList arguments) { |
| 839 return types.dynamicType; | 874 return types.dynamicType; |
| 840 } | 875 } |
| 841 | 876 |
| 877 | |
| 878 @override | |
| 879 T bulkHandleNode(Node node, String message, _) { | |
| 880 return internalError(node, message.replaceAll('#', '$node')); | |
| 881 } | |
| 882 | |
| 883 @override | |
|
Johnni Winther
2015/08/21 10:55:12
These are not used, yet.
| |
| 884 T visitConstantGet( | |
| 885 Send node, | |
| 886 ConstantExpression constant, | |
| 887 _) { | |
| 888 return bulkHandleNode(node, "Constant read `#` unhandled.", _); | |
| 889 } | |
| 890 | |
| 891 @override | |
| 892 T visitConstantInvoke( | |
| 893 Send node, | |
| 894 ConstantExpression constant, | |
| 895 NodeList arguments, | |
| 896 CallStructure callStructure, | |
| 897 _) { | |
| 898 return bulkHandleNode(node, "Constant invoke `#` unhandled.", _); | |
| 899 } | |
| 900 | |
| 842 T visitClassTypeLiteralGet( | 901 T visitClassTypeLiteralGet( |
| 843 Send node, | 902 Send node, |
| 844 ConstantExpression constant, | 903 ConstantExpression constant, |
| 845 _) { | 904 _) { |
| 846 return handleTypeLiteralGet(); | 905 return handleTypeLiteralGet(); |
| 847 } | 906 } |
| 848 | 907 |
| 849 T visitClassTypeLiteralInvoke( | 908 T visitClassTypeLiteralInvoke( |
| 850 Send node, | 909 Send node, |
| 851 ConstantExpression constant, | 910 ConstantExpression constant, |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 921 } | 980 } |
| 922 } | 981 } |
| 923 | 982 |
| 924 T _superType; | 983 T _superType; |
| 925 T get superType { | 984 T get superType { |
| 926 if (_superType != null) return _superType; | 985 if (_superType != null) return _superType; |
| 927 return _superType = types.nonNullExact( | 986 return _superType = types.nonNullExact( |
| 928 outermostElement.enclosingClass.superclass); | 987 outermostElement.enclosingClass.superclass); |
| 929 } | 988 } |
| 930 | 989 |
| 990 @override | |
| 991 T visitThisGet(Identifier node, _) { | |
| 992 return thisType; | |
| 993 } | |
| 994 | |
| 931 T visitIdentifier(Identifier node) { | 995 T visitIdentifier(Identifier node) { |
| 932 if (node.isThis()) { | 996 if (node.isThis()) { |
| 933 return thisType; | 997 return thisType; |
| 934 } else if (node.isSuper()) { | 998 } else if (node.isSuper()) { |
| 935 return superType; | 999 return superType; |
| 936 } else { | 1000 } else { |
| 937 Element element = elements[node]; | 1001 Element element = elements[node]; |
| 938 if (Elements.isLocal(element)) { | 1002 if (Elements.isLocal(element)) { |
| 939 LocalElement local = element; | 1003 LocalElement local = element; |
| 940 return locals.use(local); | 1004 return locals.use(local); |
| (...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1458 return type; | 1522 return type; |
| 1459 } | 1523 } |
| 1460 | 1524 |
| 1461 T visitCascade(Cascade node) { | 1525 T visitCascade(Cascade node) { |
| 1462 // Ignore the result of the cascade send and return the type of the cascade | 1526 // Ignore the result of the cascade send and return the type of the cascade |
| 1463 // receiver. | 1527 // receiver. |
| 1464 visit(node.expression); | 1528 visit(node.expression); |
| 1465 return cascadeReceiverStack.removeLast(); | 1529 return cascadeReceiverStack.removeLast(); |
| 1466 } | 1530 } |
| 1467 } | 1531 } |
| OLD | NEW |