OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 engine.resolver; | 5 library engine.resolver; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
| 9 import '../task/strong/info.dart' show InferredType, StaticInfo; |
| 10 import '../task/strong/rules.dart' show TypeRules; |
9 import 'ast.dart'; | 11 import 'ast.dart'; |
10 import 'constant.dart'; | 12 import 'constant.dart'; |
11 import 'element.dart'; | 13 import 'element.dart'; |
12 import 'element_resolver.dart'; | 14 import 'element_resolver.dart'; |
13 import 'engine.dart'; | 15 import 'engine.dart'; |
14 import 'error.dart'; | 16 import 'error.dart'; |
15 import 'error_verifier.dart'; | 17 import 'error_verifier.dart'; |
16 import 'html.dart' as ht; | 18 import 'html.dart' as ht; |
17 import 'java_core.dart'; | 19 import 'java_core.dart'; |
18 import 'java_engine.dart'; | 20 import 'java_engine.dart'; |
(...skipping 5729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5748 List<ImportDirective> importList = _libraryMap[libraryElement]; | 5750 List<ImportDirective> importList = _libraryMap[libraryElement]; |
5749 if (importList == null) { | 5751 if (importList == null) { |
5750 importList = new List<ImportDirective>(); | 5752 importList = new List<ImportDirective>(); |
5751 _libraryMap[libraryElement] = importList; | 5753 _libraryMap[libraryElement] = importList; |
5752 } | 5754 } |
5753 importList.add(importDirective); | 5755 importList.add(importDirective); |
5754 } | 5756 } |
5755 } | 5757 } |
5756 | 5758 |
5757 /** | 5759 /** |
| 5760 * Maintains and manages contextual type information used for |
| 5761 * inferring types. |
| 5762 */ |
| 5763 class InferenceContext { |
| 5764 // TODO(leafp): Consider replacing these node properties with a |
| 5765 // hash table help in an instance of this class. |
| 5766 static const String _typeProperty = |
| 5767 'analyzer.src.generated.InferenceContext.contextType'; |
| 5768 |
| 5769 /** |
| 5770 * The error listener on which to record inference information. |
| 5771 */ |
| 5772 final AnalysisErrorListener _errorListener; |
| 5773 |
| 5774 /** |
| 5775 * Type provider, needed for type matching. |
| 5776 */ |
| 5777 final TypeProvider _typeProvider; |
| 5778 |
| 5779 /** |
| 5780 * The type system in use. |
| 5781 */ |
| 5782 final TypeSystem _typeSystem; |
| 5783 |
| 5784 /** |
| 5785 * The DDC type rules, used to create the inference info nodes. |
| 5786 */ |
| 5787 final TypeRules _rules; |
| 5788 |
| 5789 /** |
| 5790 * A stack of return types for all of the enclosing |
| 5791 * functions and methods. |
| 5792 */ |
| 5793 List<DartType> _returnStack = <DartType>[]; |
| 5794 |
| 5795 InferenceContext._( |
| 5796 this._errorListener, TypeProvider typeProvider, this._typeSystem) |
| 5797 : _typeProvider = typeProvider, |
| 5798 _rules = new TypeRules(typeProvider); |
| 5799 |
| 5800 /** |
| 5801 * Get the return type of the current enclosing function, if any. |
| 5802 */ |
| 5803 DartType get returnContext => |
| 5804 (_returnStack.isNotEmpty) ? _returnStack.last : null; |
| 5805 |
| 5806 /** |
| 5807 * Match type [t1] against type [t2] as follows. |
| 5808 * If `t1 = I<dynamic, ..., dynamic>`, then look for a supertype |
| 5809 * of t1 of the form `K<S0, ..., Sm>` where `t2 = K<S0', ..., Sm'>` |
| 5810 * If the supertype exists, use the constraints `S0 <: S0', ... Sm <: Sm'` |
| 5811 * to derive a concrete instantation for I of the form `<T0, ..., Tn>`, |
| 5812 * such that `I<T0, .., Tn> <: t2` |
| 5813 */ |
| 5814 List<DartType> matchTypes(DartType t1, DartType t2) => |
| 5815 (t1 is InterfaceType && t2 is InterfaceType) ? _matchTypes(t1, t2) : null; |
| 5816 |
| 5817 /** |
| 5818 * Pop a return type off of the return stack. |
| 5819 */ |
| 5820 void popReturnContext() { |
| 5821 assert(_returnStack.isNotEmpty); |
| 5822 if (_returnStack.isNotEmpty) { |
| 5823 _returnStack.removeLast(); |
| 5824 } |
| 5825 } |
| 5826 |
| 5827 /** |
| 5828 * Push a [returnType] onto the return stack. |
| 5829 */ |
| 5830 void pushReturnContext(DartType returnType) { |
| 5831 _returnStack.add(returnType); |
| 5832 } |
| 5833 |
| 5834 /** |
| 5835 * Place an info node into the error stream indicating that a |
| 5836 * [type] has been inferred as the type of [node]. |
| 5837 */ |
| 5838 void recordInference(Expression node, DartType type) { |
| 5839 StaticInfo info = InferredType.create(_rules, node, type); |
| 5840 if (info == null) { |
| 5841 return; |
| 5842 } |
| 5843 AnalysisError error = info.toAnalysisError(); |
| 5844 _errorListener.onError(error); |
| 5845 } |
| 5846 |
| 5847 List<DartType> _matchTypes(InterfaceType t1, InterfaceType t2) { |
| 5848 if (t1 == t2) { |
| 5849 return t2.typeArguments; |
| 5850 } |
| 5851 List<DartType> tArgs1 = t1.typeArguments; |
| 5852 List<DartType> tArgs2 = t2.typeArguments; |
| 5853 // If t1 isn't a raw type, bail out |
| 5854 if (tArgs1 != null && tArgs1.any((t) => !t.isDynamic)) { |
| 5855 return null; |
| 5856 } |
| 5857 |
| 5858 // This is our inferred type argument list. We start at all dynamic, |
| 5859 // and fill in with inferred types when we reach a match. |
| 5860 List<DartType> actuals = |
| 5861 new List<DartType>.filled(tArgs1.length, _typeProvider.dynamicType); |
| 5862 |
| 5863 // When we find the supertype of t1 with the same |
| 5864 // classname as t2 (see below), we have the following: |
| 5865 // If t1 is an instantiation of a class T1<X0, ..., Xn> |
| 5866 // and t2 is an instantiation of a class T2<Y0, ...., Ym> |
| 5867 // of the form t2 = T2<S0, ..., Sm> |
| 5868 // then we want to choose instantiations for the Xi |
| 5869 // T0, ..., Tn such that T1<T0, ..., Tn> <: t2 . |
| 5870 // To find this, we simply instantate T1 with |
| 5871 // X0, ..., Xn, and then find its superclass |
| 5872 // T2<T0', ..., Tn'>. We then solve the constraint |
| 5873 // set T0' <: S0, ..., Tn' <: Sn for the Xi. |
| 5874 // Currently, we only handle constraints where |
| 5875 // the Ti' is one of the Xi'. If there are multiple |
| 5876 // constraints on some Xi, we choose the lower of the |
| 5877 // two (if it exists). |
| 5878 bool permute(List<DartType> permutedArgs) { |
| 5879 if (permutedArgs == null) { |
| 5880 return false; |
| 5881 } |
| 5882 List<TypeParameterElement> ps = t1.typeParameters; |
| 5883 List<DartType> ts = ps.map((p) => p.type).toList(); |
| 5884 for (int i = 0; i < permutedArgs.length; i++) { |
| 5885 DartType tVar = permutedArgs[i]; |
| 5886 DartType tActual = tArgs2[i]; |
| 5887 int index = ts.indexOf(tVar); |
| 5888 if (index >= 0 && _typeSystem.isSubtypeOf(tActual, actuals[index])) { |
| 5889 actuals[index] = tActual; |
| 5890 } |
| 5891 } |
| 5892 return actuals.any((x) => !x.isDynamic); |
| 5893 } |
| 5894 |
| 5895 // Look for the first supertype of t1 with the same class name as t2. |
| 5896 bool match(InterfaceType t1, Set<Element> visited) { |
| 5897 if (t1.element == t2.element) { |
| 5898 return permute(t1.typeArguments); |
| 5899 } |
| 5900 |
| 5901 if (t1 == _typeProvider.objectType) { |
| 5902 return false; |
| 5903 } |
| 5904 |
| 5905 Element element = t1.element; |
| 5906 if (visited == null) { |
| 5907 visited = new HashSet<Element>(); |
| 5908 } |
| 5909 if (element == null || !visited.add(element)) { |
| 5910 return false; |
| 5911 } |
| 5912 try { |
| 5913 if (match(t1.superclass, visited)) { |
| 5914 return true; |
| 5915 } |
| 5916 |
| 5917 for (final parent in t1.mixins) { |
| 5918 if (match(parent, visited)) { |
| 5919 return true; |
| 5920 } |
| 5921 } |
| 5922 |
| 5923 for (final parent in t1.interfaces) { |
| 5924 if (match(parent, visited)) { |
| 5925 return true; |
| 5926 } |
| 5927 } |
| 5928 } finally { |
| 5929 visited.remove(element); |
| 5930 } |
| 5931 return false; |
| 5932 } |
| 5933 |
| 5934 // We have that t1 = T1<dynamic, ..., dynamic>. |
| 5935 // To match t1 against t2, we use the uninstantiated version |
| 5936 // of t1, essentially treating it as an instantiation with |
| 5937 // fresh variables, and solve for the variables. |
| 5938 // t1.element.type will be of the form T1<X0, ..., Xn> |
| 5939 if (!match(t1.element.type, null)) { |
| 5940 return null; |
| 5941 } |
| 5942 DartType newT1 = t1.element.type.substitute4(actuals); |
| 5943 // If we found a solution, return it. |
| 5944 if (_typeSystem.isSubtypeOf(newT1, t2)) { |
| 5945 return actuals; |
| 5946 } |
| 5947 return null; |
| 5948 } |
| 5949 |
| 5950 /** |
| 5951 * Clear the type information assocated with [node]. |
| 5952 */ |
| 5953 static void clearType(AstNode node) { |
| 5954 node?.setProperty(_typeProperty, null); |
| 5955 } |
| 5956 |
| 5957 /** |
| 5958 * Look for contextual type information attached to [node]. Returns |
| 5959 * the type if found, otherwise null. |
| 5960 */ |
| 5961 static DartType getType(AstNode node) => node?.getProperty(_typeProperty); |
| 5962 |
| 5963 /** |
| 5964 * Attach contextual type information [type] to [node] for use during |
| 5965 * inference. |
| 5966 */ |
| 5967 static void setType(AstNode node, DartType type) { |
| 5968 node?.setProperty(_typeProperty, type); |
| 5969 } |
| 5970 |
| 5971 /** |
| 5972 * Attach contextual type information [type] to [node] for use during |
| 5973 * inference. |
| 5974 */ |
| 5975 static void setTypeFromNode(AstNode innerNode, AstNode outerNode) { |
| 5976 setType(innerNode, getType(outerNode)); |
| 5977 } |
| 5978 } |
| 5979 |
| 5980 /** |
5758 * Instances of the class `InheritanceManager` manage the knowledge of where cla
ss members | 5981 * Instances of the class `InheritanceManager` manage the knowledge of where cla
ss members |
5759 * (methods, getters & setters) are inherited from. | 5982 * (methods, getters & setters) are inherited from. |
5760 */ | 5983 */ |
5761 class InheritanceManager { | 5984 class InheritanceManager { |
5762 /** | 5985 /** |
5763 * The [LibraryElement] that is managed by this manager. | 5986 * The [LibraryElement] that is managed by this manager. |
5764 */ | 5987 */ |
5765 LibraryElement _library; | 5988 LibraryElement _library; |
5766 | 5989 |
5767 /** | 5990 /** |
(...skipping 4610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10378 * The object used to resolve the element associated with the current node. | 10601 * The object used to resolve the element associated with the current node. |
10379 */ | 10602 */ |
10380 ElementResolver elementResolver; | 10603 ElementResolver elementResolver; |
10381 | 10604 |
10382 /** | 10605 /** |
10383 * The object used to compute the type associated with the current node. | 10606 * The object used to compute the type associated with the current node. |
10384 */ | 10607 */ |
10385 StaticTypeAnalyzer typeAnalyzer; | 10608 StaticTypeAnalyzer typeAnalyzer; |
10386 | 10609 |
10387 /* | 10610 /* |
10388 * The type system in use during resolution. | 10611 * The type system in use during resolution. |
10389 */ | 10612 */ |
10390 TypeSystem typeSystem; | 10613 TypeSystem typeSystem; |
10391 | 10614 |
10392 /** | 10615 /** |
10393 * The class element representing the class containing the current node, | 10616 * The class element representing the class containing the current node, |
10394 * or `null` if the current node is not contained in a class. | 10617 * or `null` if the current node is not contained in a class. |
10395 */ | 10618 */ |
10396 ClassElement enclosingClass = null; | 10619 ClassElement enclosingClass = null; |
10397 | 10620 |
10398 /** | 10621 /** |
10399 * The class declaration representing the class containing the current node, o
r `null` if | 10622 * The class declaration representing the class containing the current node, o
r `null` if |
(...skipping 12 matching lines...) Expand all Loading... |
10412 * current node is not contained in a function. | 10635 * current node is not contained in a function. |
10413 */ | 10636 */ |
10414 ExecutableElement _enclosingFunction = null; | 10637 ExecutableElement _enclosingFunction = null; |
10415 | 10638 |
10416 /** | 10639 /** |
10417 * The [Comment] before a [FunctionDeclaration] or a [MethodDeclaration] that | 10640 * The [Comment] before a [FunctionDeclaration] or a [MethodDeclaration] that |
10418 * cannot be resolved where we visited it, because it should be resolved in th
e scope of the body. | 10641 * cannot be resolved where we visited it, because it should be resolved in th
e scope of the body. |
10419 */ | 10642 */ |
10420 Comment _commentBeforeFunction = null; | 10643 Comment _commentBeforeFunction = null; |
10421 | 10644 |
| 10645 InferenceContext inferenceContext = null; |
| 10646 |
10422 /** | 10647 /** |
10423 * The object keeping track of which elements have had their types overridden. | 10648 * The object keeping track of which elements have had their types overridden. |
10424 */ | 10649 */ |
10425 TypeOverrideManager _overrideManager = new TypeOverrideManager(); | 10650 TypeOverrideManager _overrideManager = new TypeOverrideManager(); |
10426 | 10651 |
10427 /** | 10652 /** |
10428 * The object keeping track of which elements have had their types promoted. | 10653 * The object keeping track of which elements have had their types promoted. |
10429 */ | 10654 */ |
10430 TypePromotionManager _promoteManager = new TypePromotionManager(); | 10655 TypePromotionManager _promoteManager = new TypePromotionManager(); |
10431 | 10656 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10463 StaticTypeAnalyzerFactory typeAnalyzerFactory}) | 10688 StaticTypeAnalyzerFactory typeAnalyzerFactory}) |
10464 : super(definingLibrary, source, typeProvider, errorListener, | 10689 : super(definingLibrary, source, typeProvider, errorListener, |
10465 nameScope: nameScope) { | 10690 nameScope: nameScope) { |
10466 if (inheritanceManager == null) { | 10691 if (inheritanceManager == null) { |
10467 this._inheritanceManager = new InheritanceManager(definingLibrary); | 10692 this._inheritanceManager = new InheritanceManager(definingLibrary); |
10468 } else { | 10693 } else { |
10469 this._inheritanceManager = inheritanceManager; | 10694 this._inheritanceManager = inheritanceManager; |
10470 } | 10695 } |
10471 this.elementResolver = new ElementResolver(this); | 10696 this.elementResolver = new ElementResolver(this); |
10472 this.typeSystem = definingLibrary.context.typeSystem; | 10697 this.typeSystem = definingLibrary.context.typeSystem; |
| 10698 this.inferenceContext = |
| 10699 new InferenceContext._(errorListener, typeProvider, typeSystem); |
10473 if (typeAnalyzerFactory == null) { | 10700 if (typeAnalyzerFactory == null) { |
10474 this.typeAnalyzer = new StaticTypeAnalyzer(this); | 10701 this.typeAnalyzer = new StaticTypeAnalyzer(this); |
10475 } else { | 10702 } else { |
10476 this.typeAnalyzer = typeAnalyzerFactory(this); | 10703 this.typeAnalyzer = typeAnalyzerFactory(this); |
10477 } | 10704 } |
10478 } | 10705 } |
10479 | 10706 |
10480 /** | 10707 /** |
10481 * Initialize a newly created visitor to resolve the nodes in a compilation un
it. | 10708 * Initialize a newly created visitor to resolve the nodes in a compilation un
it. |
10482 * | 10709 * |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10735 expression.propagatedType = type; | 10962 expression.propagatedType = type; |
10736 } | 10963 } |
10737 | 10964 |
10738 @override | 10965 @override |
10739 Object visitAnnotation(Annotation node) { | 10966 Object visitAnnotation(Annotation node) { |
10740 AstNode parent = node.parent; | 10967 AstNode parent = node.parent; |
10741 if (identical(parent, _enclosingClassDeclaration) || | 10968 if (identical(parent, _enclosingClassDeclaration) || |
10742 identical(parent, _enclosingFunctionTypeAlias)) { | 10969 identical(parent, _enclosingFunctionTypeAlias)) { |
10743 return null; | 10970 return null; |
10744 } | 10971 } |
10745 return super.visitAnnotation(node); | 10972 safelyVisit(node.name); |
| 10973 safelyVisit(node.constructorName); |
| 10974 Element element = node.element; |
| 10975 if (element is ExecutableElement) { |
| 10976 InferenceContext.setType(node.arguments, element.type); |
| 10977 } |
| 10978 safelyVisit(node.arguments); |
| 10979 node.accept(elementResolver); |
| 10980 node.accept(typeAnalyzer); |
| 10981 return null; |
| 10982 } |
| 10983 |
| 10984 @override |
| 10985 Object visitArgumentList(ArgumentList node) { |
| 10986 DartType callerType = InferenceContext.getType(node); |
| 10987 if (callerType is FunctionType) { |
| 10988 Map<String, DartType> namedParameterTypes = |
| 10989 callerType.namedParameterTypes; |
| 10990 List<DartType> normalParameterTypes = callerType.normalParameterTypes; |
| 10991 List<DartType> optionalParameterTypes = callerType.optionalParameterTypes; |
| 10992 int normalCount = normalParameterTypes.length; |
| 10993 int optionalCount = optionalParameterTypes.length; |
| 10994 |
| 10995 NodeList<Expression> arguments = node.arguments; |
| 10996 Iterable<Expression> positional = |
| 10997 arguments.takeWhile((l) => l is! NamedExpression); |
| 10998 Iterable<Expression> required = positional.take(normalCount); |
| 10999 Iterable<Expression> optional = |
| 11000 positional.skip(normalCount).take(optionalCount); |
| 11001 Iterable<Expression> named = |
| 11002 arguments.skipWhile((l) => l is! NamedExpression); |
| 11003 |
| 11004 //TODO(leafp): Consider using the parameter elements here instead. |
| 11005 //TODO(leafp): Make sure that the parameter elements are getting |
| 11006 // setup correctly with inference. |
| 11007 int index = 0; |
| 11008 for (Expression argument in required) { |
| 11009 InferenceContext.setType(argument, normalParameterTypes[index++]); |
| 11010 } |
| 11011 index = 0; |
| 11012 for (Expression argument in optional) { |
| 11013 InferenceContext.setType(argument, optionalParameterTypes[index++]); |
| 11014 } |
| 11015 |
| 11016 for (Expression argument in named) { |
| 11017 if (argument is NamedExpression) { |
| 11018 DartType type = namedParameterTypes[argument.name.label.name]; |
| 11019 if (type != null) { |
| 11020 InferenceContext.setType(argument, type); |
| 11021 } |
| 11022 } |
| 11023 } |
| 11024 } |
| 11025 return super.visitArgumentList(node); |
10746 } | 11026 } |
10747 | 11027 |
10748 @override | 11028 @override |
10749 Object visitAsExpression(AsExpression node) { | 11029 Object visitAsExpression(AsExpression node) { |
| 11030 InferenceContext.setType(node.expression, node.type.type); |
10750 super.visitAsExpression(node); | 11031 super.visitAsExpression(node); |
10751 // Since an as-statement doesn't actually change the type, we don't | 11032 // Since an as-statement doesn't actually change the type, we don't |
10752 // let it affect the propagated type when it would result in a loss | 11033 // let it affect the propagated type when it would result in a loss |
10753 // of precision. | 11034 // of precision. |
10754 overrideExpression(node.expression, node.type.type, false, false); | 11035 overrideExpression(node.expression, node.type.type, false, false); |
10755 return null; | 11036 return null; |
10756 } | 11037 } |
10757 | 11038 |
10758 @override | 11039 @override |
10759 Object visitAssertStatement(AssertStatement node) { | 11040 Object visitAssertStatement(AssertStatement node) { |
10760 super.visitAssertStatement(node); | 11041 super.visitAssertStatement(node); |
10761 _propagateTrueState(node.condition); | 11042 _propagateTrueState(node.condition); |
10762 return null; | 11043 return null; |
10763 } | 11044 } |
10764 | 11045 |
10765 @override | 11046 @override |
| 11047 Object visitAssignmentExpression(AssignmentExpression node) { |
| 11048 safelyVisit(node.leftHandSide); |
| 11049 sc.TokenType operator = node.operator.type; |
| 11050 if (operator == sc.TokenType.EQ || |
| 11051 operator == sc.TokenType.QUESTION_QUESTION_EQ) { |
| 11052 InferenceContext.setType( |
| 11053 node.rightHandSide, node.leftHandSide.staticType); |
| 11054 } |
| 11055 safelyVisit(node.rightHandSide); |
| 11056 node.accept(elementResolver); |
| 11057 node.accept(typeAnalyzer); |
| 11058 return null; |
| 11059 } |
| 11060 |
| 11061 @override |
| 11062 Object visitAwaitExpression(AwaitExpression node) { |
| 11063 //TODO(leafp): Handle the implicit union type here |
| 11064 DartType contextType = InferenceContext.getType(node); |
| 11065 if (contextType != null) { |
| 11066 InterfaceType futureT = |
| 11067 typeProvider.futureType.substitute4([contextType]); |
| 11068 InferenceContext.setType(node.expression, futureT); |
| 11069 } |
| 11070 return super.visitAwaitExpression(node); |
| 11071 } |
| 11072 |
| 11073 @override |
10766 Object visitBinaryExpression(BinaryExpression node) { | 11074 Object visitBinaryExpression(BinaryExpression node) { |
10767 sc.TokenType operatorType = node.operator.type; | 11075 sc.TokenType operatorType = node.operator.type; |
10768 Expression leftOperand = node.leftOperand; | 11076 Expression leftOperand = node.leftOperand; |
10769 Expression rightOperand = node.rightOperand; | 11077 Expression rightOperand = node.rightOperand; |
10770 if (operatorType == sc.TokenType.AMPERSAND_AMPERSAND) { | 11078 if (operatorType == sc.TokenType.AMPERSAND_AMPERSAND) { |
10771 safelyVisit(leftOperand); | 11079 safelyVisit(leftOperand); |
10772 if (rightOperand != null) { | 11080 if (rightOperand != null) { |
10773 _overrideManager.enterScope(); | 11081 _overrideManager.enterScope(); |
10774 try { | 11082 try { |
10775 _promoteManager.enterScope(); | 11083 _promoteManager.enterScope(); |
(...skipping 19 matching lines...) Expand all Loading... |
10795 if (rightOperand != null) { | 11103 if (rightOperand != null) { |
10796 _overrideManager.enterScope(); | 11104 _overrideManager.enterScope(); |
10797 try { | 11105 try { |
10798 _propagateFalseState(leftOperand); | 11106 _propagateFalseState(leftOperand); |
10799 rightOperand.accept(this); | 11107 rightOperand.accept(this); |
10800 } finally { | 11108 } finally { |
10801 _overrideManager.exitScope(); | 11109 _overrideManager.exitScope(); |
10802 } | 11110 } |
10803 } | 11111 } |
10804 } else { | 11112 } else { |
| 11113 // TODO(leafp): Do downwards inference using the declared type |
| 11114 // of the binary operator. |
10805 safelyVisit(leftOperand); | 11115 safelyVisit(leftOperand); |
10806 safelyVisit(rightOperand); | 11116 safelyVisit(rightOperand); |
10807 } | 11117 } |
10808 node.accept(elementResolver); | 11118 node.accept(elementResolver); |
10809 node.accept(typeAnalyzer); | 11119 node.accept(typeAnalyzer); |
10810 return null; | 11120 return null; |
10811 } | 11121 } |
10812 | 11122 |
10813 @override | 11123 @override |
10814 Object visitBlockFunctionBody(BlockFunctionBody node) { | 11124 Object visitBlockFunctionBody(BlockFunctionBody node) { |
10815 safelyVisit(_commentBeforeFunction); | 11125 safelyVisit(_commentBeforeFunction); |
10816 _overrideManager.enterScope(); | 11126 _overrideManager.enterScope(); |
10817 try { | 11127 try { |
| 11128 inferenceContext.pushReturnContext(InferenceContext.getType(node)); |
10818 super.visitBlockFunctionBody(node); | 11129 super.visitBlockFunctionBody(node); |
10819 } finally { | 11130 } finally { |
10820 _overrideManager.exitScope(); | 11131 _overrideManager.exitScope(); |
| 11132 inferenceContext.popReturnContext(); |
10821 } | 11133 } |
10822 return null; | 11134 return null; |
10823 } | 11135 } |
10824 | 11136 |
10825 @override | 11137 @override |
10826 Object visitBreakStatement(BreakStatement node) { | 11138 Object visitBreakStatement(BreakStatement node) { |
10827 // | 11139 // |
10828 // We do not visit the label because it needs to be visited in the context | 11140 // We do not visit the label because it needs to be visited in the context |
10829 // of the statement. | 11141 // of the statement. |
10830 // | 11142 // |
10831 node.accept(elementResolver); | 11143 node.accept(elementResolver); |
10832 node.accept(typeAnalyzer); | 11144 node.accept(typeAnalyzer); |
10833 return null; | 11145 return null; |
10834 } | 11146 } |
10835 | 11147 |
10836 @override | 11148 @override |
| 11149 Object visitCascadeExpression(CascadeExpression node) { |
| 11150 InferenceContext.setTypeFromNode(node.target, node); |
| 11151 return super.visitCascadeExpression(node); |
| 11152 } |
| 11153 |
| 11154 @override |
10837 Object visitClassDeclaration(ClassDeclaration node) { | 11155 Object visitClassDeclaration(ClassDeclaration node) { |
10838 // | 11156 // |
10839 // Resolve the metadata in the library scope. | 11157 // Resolve the metadata in the library scope. |
10840 // | 11158 // |
10841 if (node.metadata != null) { | 11159 if (node.metadata != null) { |
10842 node.metadata.accept(this); | 11160 node.metadata.accept(this); |
10843 } | 11161 } |
10844 _enclosingClassDeclaration = node; | 11162 _enclosingClassDeclaration = node; |
10845 // | 11163 // |
10846 // Continue the class resolution. | 11164 // Continue the class resolution. |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10959 try { | 11277 try { |
10960 _promoteManager.enterScope(); | 11278 _promoteManager.enterScope(); |
10961 try { | 11279 try { |
10962 _propagateTrueState(condition); | 11280 _propagateTrueState(condition); |
10963 // Type promotion. | 11281 // Type promotion. |
10964 _promoteTypes(condition); | 11282 _promoteTypes(condition); |
10965 _clearTypePromotionsIfPotentiallyMutatedIn(thenExpression); | 11283 _clearTypePromotionsIfPotentiallyMutatedIn(thenExpression); |
10966 _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated( | 11284 _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated( |
10967 thenExpression); | 11285 thenExpression); |
10968 // Visit "then" expression. | 11286 // Visit "then" expression. |
| 11287 InferenceContext.setTypeFromNode(thenExpression, node); |
10969 thenExpression.accept(this); | 11288 thenExpression.accept(this); |
10970 } finally { | 11289 } finally { |
10971 _promoteManager.exitScope(); | 11290 _promoteManager.exitScope(); |
10972 } | 11291 } |
10973 } finally { | 11292 } finally { |
10974 _overrideManager.exitScope(); | 11293 _overrideManager.exitScope(); |
10975 } | 11294 } |
10976 } | 11295 } |
10977 Expression elseExpression = node.elseExpression; | 11296 Expression elseExpression = node.elseExpression; |
10978 if (elseExpression != null) { | 11297 if (elseExpression != null) { |
10979 _overrideManager.enterScope(); | 11298 _overrideManager.enterScope(); |
10980 try { | 11299 try { |
10981 _propagateFalseState(condition); | 11300 _propagateFalseState(condition); |
| 11301 InferenceContext.setTypeFromNode(elseExpression, node); |
10982 elseExpression.accept(this); | 11302 elseExpression.accept(this); |
10983 } finally { | 11303 } finally { |
10984 _overrideManager.exitScope(); | 11304 _overrideManager.exitScope(); |
10985 } | 11305 } |
10986 } | 11306 } |
10987 node.accept(elementResolver); | 11307 node.accept(elementResolver); |
10988 node.accept(typeAnalyzer); | 11308 node.accept(typeAnalyzer); |
10989 bool thenIsAbrupt = _isAbruptTerminationExpression(thenExpression); | 11309 bool thenIsAbrupt = _isAbruptTerminationExpression(thenExpression); |
10990 bool elseIsAbrupt = _isAbruptTerminationExpression(elseExpression); | 11310 bool elseIsAbrupt = _isAbruptTerminationExpression(elseExpression); |
10991 if (elseIsAbrupt && !thenIsAbrupt) { | 11311 if (elseIsAbrupt && !thenIsAbrupt) { |
10992 _propagateTrueState(condition); | 11312 _propagateTrueState(condition); |
10993 _propagateState(thenExpression); | 11313 _propagateState(thenExpression); |
10994 } else if (thenIsAbrupt && !elseIsAbrupt) { | 11314 } else if (thenIsAbrupt && !elseIsAbrupt) { |
10995 _propagateFalseState(condition); | 11315 _propagateFalseState(condition); |
10996 _propagateState(elseExpression); | 11316 _propagateState(elseExpression); |
10997 } | 11317 } |
10998 return null; | 11318 return null; |
10999 } | 11319 } |
11000 | 11320 |
11001 @override | 11321 @override |
11002 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 11322 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
11003 ExecutableElement outerFunction = _enclosingFunction; | 11323 ExecutableElement outerFunction = _enclosingFunction; |
11004 try { | 11324 try { |
11005 _enclosingFunction = node.element; | 11325 _enclosingFunction = node.element; |
| 11326 FunctionType type = _enclosingFunction.type; |
| 11327 InferenceContext.setType(node.body, type.returnType); |
11006 super.visitConstructorDeclaration(node); | 11328 super.visitConstructorDeclaration(node); |
11007 } finally { | 11329 } finally { |
11008 _enclosingFunction = outerFunction; | 11330 _enclosingFunction = outerFunction; |
11009 } | 11331 } |
11010 ConstructorElementImpl constructor = node.element; | 11332 ConstructorElementImpl constructor = node.element; |
11011 constructor.constantInitializers = | 11333 constructor.constantInitializers = |
11012 new ConstantAstCloner().cloneNodeList(node.initializers); | 11334 new ConstantAstCloner().cloneNodeList(node.initializers); |
11013 return null; | 11335 return null; |
11014 } | 11336 } |
11015 | 11337 |
11016 @override | 11338 @override |
11017 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { | 11339 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { |
11018 // | 11340 // |
11019 // We visit the expression, but do not visit the field name because it needs | 11341 // We visit the expression, but do not visit the field name because it needs |
11020 // to be visited in the context of the constructor field initializer node. | 11342 // to be visited in the context of the constructor field initializer node. |
11021 // | 11343 // |
| 11344 FieldElement fieldElement = enclosingClass.getField(node.fieldName.name); |
| 11345 InferenceContext.setType(node.expression, fieldElement?.type); |
11022 safelyVisit(node.expression); | 11346 safelyVisit(node.expression); |
11023 node.accept(elementResolver); | 11347 node.accept(elementResolver); |
11024 node.accept(typeAnalyzer); | 11348 node.accept(typeAnalyzer); |
11025 return null; | 11349 return null; |
11026 } | 11350 } |
11027 | 11351 |
11028 @override | 11352 @override |
11029 Object visitConstructorName(ConstructorName node) { | 11353 Object visitConstructorName(ConstructorName node) { |
11030 // | 11354 // |
11031 // We do not visit either the type name, because it won't be visited anyway, | 11355 // We do not visit either the type name, because it won't be visited anyway, |
(...skipping 11 matching lines...) Expand all Loading... |
11043 // We do not visit the label because it needs to be visited in the context | 11367 // We do not visit the label because it needs to be visited in the context |
11044 // of the statement. | 11368 // of the statement. |
11045 // | 11369 // |
11046 node.accept(elementResolver); | 11370 node.accept(elementResolver); |
11047 node.accept(typeAnalyzer); | 11371 node.accept(typeAnalyzer); |
11048 return null; | 11372 return null; |
11049 } | 11373 } |
11050 | 11374 |
11051 @override | 11375 @override |
11052 Object visitDefaultFormalParameter(DefaultFormalParameter node) { | 11376 Object visitDefaultFormalParameter(DefaultFormalParameter node) { |
| 11377 InferenceContext.setType(node.defaultValue, node.parameter.element?.type); |
11053 super.visitDefaultFormalParameter(node); | 11378 super.visitDefaultFormalParameter(node); |
11054 ParameterElement element = node.element; | 11379 ParameterElement element = node.element; |
11055 if (element.initializer != null && node.defaultValue != null) { | 11380 if (element.initializer != null && node.defaultValue != null) { |
11056 (element.initializer as FunctionElementImpl).returnType = | 11381 (element.initializer as FunctionElementImpl).returnType = |
11057 node.defaultValue.staticType; | 11382 node.defaultValue.staticType; |
11058 } | 11383 } |
11059 FormalParameterList parent = node.parent; | 11384 FormalParameterList parent = node.parent; |
11060 AstNode grandparent = parent.parent; | 11385 AstNode grandparent = parent.parent; |
11061 if (grandparent is ConstructorDeclaration && | 11386 if (grandparent is ConstructorDeclaration && |
11062 grandparent.constKeyword != null) { | 11387 grandparent.constKeyword != null) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11121 } | 11446 } |
11122 | 11447 |
11123 @override | 11448 @override |
11124 Object visitExpressionFunctionBody(ExpressionFunctionBody node) { | 11449 Object visitExpressionFunctionBody(ExpressionFunctionBody node) { |
11125 safelyVisit(_commentBeforeFunction); | 11450 safelyVisit(_commentBeforeFunction); |
11126 if (resolveOnlyCommentInFunctionBody) { | 11451 if (resolveOnlyCommentInFunctionBody) { |
11127 return null; | 11452 return null; |
11128 } | 11453 } |
11129 _overrideManager.enterScope(); | 11454 _overrideManager.enterScope(); |
11130 try { | 11455 try { |
| 11456 InferenceContext.setTypeFromNode(node.expression, node); |
11131 super.visitExpressionFunctionBody(node); | 11457 super.visitExpressionFunctionBody(node); |
11132 } finally { | 11458 } finally { |
11133 _overrideManager.exitScope(); | 11459 _overrideManager.exitScope(); |
11134 } | 11460 } |
11135 return null; | 11461 return null; |
11136 } | 11462 } |
11137 | 11463 |
11138 @override | 11464 @override |
11139 Object visitFieldDeclaration(FieldDeclaration node) { | 11465 Object visitFieldDeclaration(FieldDeclaration node) { |
11140 _overrideManager.enterScope(); | 11466 _overrideManager.enterScope(); |
(...skipping 19 matching lines...) Expand all Loading... |
11160 return null; | 11486 return null; |
11161 } | 11487 } |
11162 | 11488 |
11163 @override | 11489 @override |
11164 void visitForEachStatementInScope(ForEachStatement node) { | 11490 void visitForEachStatementInScope(ForEachStatement node) { |
11165 // | 11491 // |
11166 // We visit the iterator before the loop variable because the loop variable | 11492 // We visit the iterator before the loop variable because the loop variable |
11167 // cannot be in scope while visiting the iterator. | 11493 // cannot be in scope while visiting the iterator. |
11168 // | 11494 // |
11169 Expression iterable = node.iterable; | 11495 Expression iterable = node.iterable; |
11170 safelyVisit(iterable); | |
11171 DeclaredIdentifier loopVariable = node.loopVariable; | 11496 DeclaredIdentifier loopVariable = node.loopVariable; |
11172 SimpleIdentifier identifier = node.identifier; | 11497 SimpleIdentifier identifier = node.identifier; |
| 11498 if (loopVariable?.type?.type != null) { |
| 11499 InterfaceType targetType = (node.awaitKeyword == null) |
| 11500 ? typeProvider.iterableType |
| 11501 : typeProvider.streamType; |
| 11502 InferenceContext.setType( |
| 11503 iterable, targetType.substitute4([loopVariable.type.type])); |
| 11504 } |
| 11505 safelyVisit(iterable); |
11173 safelyVisit(loopVariable); | 11506 safelyVisit(loopVariable); |
11174 safelyVisit(identifier); | 11507 safelyVisit(identifier); |
11175 Statement body = node.body; | 11508 Statement body = node.body; |
11176 if (body != null) { | 11509 if (body != null) { |
11177 _overrideManager.enterScope(); | 11510 _overrideManager.enterScope(); |
11178 try { | 11511 try { |
11179 if (loopVariable != null && iterable != null) { | 11512 if (loopVariable != null && iterable != null) { |
11180 LocalVariableElement loopElement = loopVariable.element; | 11513 LocalVariableElement loopElement = loopVariable.element; |
11181 if (loopElement != null) { | 11514 if (loopElement != null) { |
11182 DartType propagatedType = null; | 11515 DartType propagatedType = null; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11235 // TODO(brianwilkerson) If the loop can only be exited because the condition | 11568 // TODO(brianwilkerson) If the loop can only be exited because the condition |
11236 // is false, then propagateFalseState(condition); | 11569 // is false, then propagateFalseState(condition); |
11237 } | 11570 } |
11238 | 11571 |
11239 @override | 11572 @override |
11240 Object visitFunctionDeclaration(FunctionDeclaration node) { | 11573 Object visitFunctionDeclaration(FunctionDeclaration node) { |
11241 ExecutableElement outerFunction = _enclosingFunction; | 11574 ExecutableElement outerFunction = _enclosingFunction; |
11242 try { | 11575 try { |
11243 SimpleIdentifier functionName = node.name; | 11576 SimpleIdentifier functionName = node.name; |
11244 _enclosingFunction = functionName.staticElement as ExecutableElement; | 11577 _enclosingFunction = functionName.staticElement as ExecutableElement; |
| 11578 InferenceContext.setType( |
| 11579 node.functionExpression, _enclosingFunction.type); |
11245 super.visitFunctionDeclaration(node); | 11580 super.visitFunctionDeclaration(node); |
11246 } finally { | 11581 } finally { |
11247 _enclosingFunction = outerFunction; | 11582 _enclosingFunction = outerFunction; |
11248 } | 11583 } |
11249 return null; | 11584 return null; |
11250 } | 11585 } |
11251 | 11586 |
11252 @override | 11587 @override |
11253 Object visitFunctionExpression(FunctionExpression node) { | 11588 Object visitFunctionExpression(FunctionExpression node) { |
11254 ExecutableElement outerFunction = _enclosingFunction; | 11589 ExecutableElement outerFunction = _enclosingFunction; |
11255 try { | 11590 try { |
11256 _enclosingFunction = node.element; | 11591 _enclosingFunction = node.element; |
11257 _overrideManager.enterScope(); | 11592 _overrideManager.enterScope(); |
11258 try { | 11593 try { |
| 11594 DartType functionType = InferenceContext.getType(node); |
| 11595 if (functionType is FunctionType) { |
| 11596 _inferFormalParameterList(node.parameters, functionType); |
| 11597 InferenceContext.setType(node.body, functionType.returnType); |
| 11598 } |
11259 super.visitFunctionExpression(node); | 11599 super.visitFunctionExpression(node); |
11260 } finally { | 11600 } finally { |
11261 _overrideManager.exitScope(); | 11601 _overrideManager.exitScope(); |
11262 } | 11602 } |
11263 } finally { | 11603 } finally { |
11264 _enclosingFunction = outerFunction; | 11604 _enclosingFunction = outerFunction; |
11265 } | 11605 } |
11266 return null; | 11606 return null; |
11267 } | 11607 } |
11268 | 11608 |
11269 @override | 11609 @override |
11270 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | 11610 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
11271 safelyVisit(node.function); | 11611 safelyVisit(node.function); |
11272 node.accept(elementResolver); | 11612 node.accept(elementResolver); |
11273 _inferFunctionExpressionsParametersTypes(node.argumentList); | 11613 _inferFunctionExpressionsParametersTypes(node.argumentList); |
| 11614 InferenceContext.setType(node.argumentList, node.function.staticType); |
11274 safelyVisit(node.argumentList); | 11615 safelyVisit(node.argumentList); |
11275 node.accept(typeAnalyzer); | 11616 node.accept(typeAnalyzer); |
11276 return null; | 11617 return null; |
11277 } | 11618 } |
11278 | 11619 |
11279 @override | 11620 @override |
11280 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 11621 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
11281 // Resolve the metadata in the library scope. | 11622 // Resolve the metadata in the library scope. |
11282 if (node.metadata != null) { | 11623 if (node.metadata != null) { |
11283 node.metadata.accept(this); | 11624 node.metadata.accept(this); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11351 List<Map<VariableElement, DartType>> perBranchOverrides = | 11692 List<Map<VariableElement, DartType>> perBranchOverrides = |
11352 new List<Map<VariableElement, DartType>>(); | 11693 new List<Map<VariableElement, DartType>>(); |
11353 perBranchOverrides.add(thenOverrides); | 11694 perBranchOverrides.add(thenOverrides); |
11354 perBranchOverrides.add(elseOverrides); | 11695 perBranchOverrides.add(elseOverrides); |
11355 _overrideManager.mergeOverrides(perBranchOverrides); | 11696 _overrideManager.mergeOverrides(perBranchOverrides); |
11356 } | 11697 } |
11357 return null; | 11698 return null; |
11358 } | 11699 } |
11359 | 11700 |
11360 @override | 11701 @override |
| 11702 Object visitInstanceCreationExpression(InstanceCreationExpression node) { |
| 11703 DartType contextType = InferenceContext.getType(node); |
| 11704 if (contextType is InterfaceType && |
| 11705 contextType.typeArguments != null && |
| 11706 contextType.typeArguments.length > 0) { |
| 11707 TypeName classTypeName = node.constructorName.type; |
| 11708 if (classTypeName.typeArguments == null) { |
| 11709 List<DartType> targs = |
| 11710 inferenceContext.matchTypes(classTypeName.type, contextType); |
| 11711 if (targs != null && targs.any((t) => !t.isDynamic)) { |
| 11712 ClassElement classElement = classTypeName.type.element; |
| 11713 InterfaceType rawType = classElement.type; |
| 11714 InterfaceType fullType = |
| 11715 rawType.substitute2(targs, rawType.typeArguments); |
| 11716 // The element resolver uses the type on the constructor name, so |
| 11717 // infer it first |
| 11718 typeAnalyzer.inferConstructorName(node.constructorName, fullType); |
| 11719 safelyVisit(node.constructorName); |
| 11720 ConstructorElement invokedConstructor = |
| 11721 node.constructorName.staticElement; |
| 11722 FunctionType rawConstructorType = invokedConstructor.type; |
| 11723 FunctionType constructorType = rawConstructorType.substitute2( |
| 11724 targs, rawConstructorType.typeArguments); |
| 11725 InferenceContext.setType(node.argumentList, constructorType); |
| 11726 safelyVisit(node.argumentList); |
| 11727 InferenceContext.setType(node, fullType); |
| 11728 node.accept(elementResolver); |
| 11729 node.accept(typeAnalyzer); |
| 11730 return null; |
| 11731 } |
| 11732 } else { |
| 11733 InferenceContext.clearType(node); |
| 11734 } |
| 11735 } |
| 11736 super.visitInstanceCreationExpression(node); |
| 11737 return null; |
| 11738 } |
| 11739 |
| 11740 @override |
11361 Object visitLabel(Label node) => null; | 11741 Object visitLabel(Label node) => null; |
11362 | 11742 |
11363 @override | 11743 @override |
11364 Object visitLibraryIdentifier(LibraryIdentifier node) => null; | 11744 Object visitLibraryIdentifier(LibraryIdentifier node) => null; |
11365 | 11745 |
11366 @override | 11746 @override |
| 11747 Object visitListLiteral(ListLiteral node) { |
| 11748 DartType contextType = InferenceContext.getType(node); |
| 11749 if (node.typeArguments == null && contextType is InterfaceType) { |
| 11750 InterfaceType listD = |
| 11751 typeProvider.listType.substitute4([typeProvider.dynamicType]); |
| 11752 List<DartType> targs = inferenceContext.matchTypes(listD, contextType); |
| 11753 if (targs != null && |
| 11754 targs.length == 1 && |
| 11755 targs.any((t) => !t.isDynamic)) { |
| 11756 DartType eType = targs[0]; |
| 11757 InterfaceType listT = typeProvider.listType.substitute4([eType]); |
| 11758 for (Expression child in node.elements) { |
| 11759 InferenceContext.setType(child, eType); |
| 11760 } |
| 11761 InferenceContext.setType(node, listT); |
| 11762 } else { |
| 11763 InferenceContext.clearType(node); |
| 11764 } |
| 11765 } |
| 11766 super.visitListLiteral(node); |
| 11767 return null; |
| 11768 } |
| 11769 |
| 11770 @override |
| 11771 Object visitMapLiteral(MapLiteral node) { |
| 11772 DartType contextType = InferenceContext.getType(node); |
| 11773 if (node.typeArguments == null && contextType is InterfaceType) { |
| 11774 InterfaceType mapD = typeProvider.mapType |
| 11775 .substitute4([typeProvider.dynamicType, typeProvider.dynamicType]); |
| 11776 List<DartType> targs = inferenceContext.matchTypes(mapD, contextType); |
| 11777 if (targs != null && |
| 11778 targs.length == 2 && |
| 11779 targs.any((t) => !t.isDynamic)) { |
| 11780 DartType kType = targs[0]; |
| 11781 DartType vType = targs[1]; |
| 11782 InterfaceType mapT = typeProvider.mapType.substitute4([kType, vType]); |
| 11783 for (MapLiteralEntry entry in node.entries) { |
| 11784 InferenceContext.setType(entry.key, kType); |
| 11785 InferenceContext.setType(entry.value, vType); |
| 11786 } |
| 11787 InferenceContext.setType(node, mapT); |
| 11788 } else { |
| 11789 InferenceContext.clearType(node); |
| 11790 } |
| 11791 } |
| 11792 super.visitMapLiteral(node); |
| 11793 return null; |
| 11794 } |
| 11795 |
| 11796 @override |
11367 Object visitMethodDeclaration(MethodDeclaration node) { | 11797 Object visitMethodDeclaration(MethodDeclaration node) { |
11368 ExecutableElement outerFunction = _enclosingFunction; | 11798 ExecutableElement outerFunction = _enclosingFunction; |
11369 try { | 11799 try { |
11370 _enclosingFunction = node.element; | 11800 _enclosingFunction = node.element; |
| 11801 InferenceContext.setType(node.body, node.element.type?.returnType); |
11371 super.visitMethodDeclaration(node); | 11802 super.visitMethodDeclaration(node); |
11372 } finally { | 11803 } finally { |
11373 _enclosingFunction = outerFunction; | 11804 _enclosingFunction = outerFunction; |
11374 } | 11805 } |
11375 return null; | 11806 return null; |
11376 } | 11807 } |
11377 | 11808 |
11378 @override | 11809 @override |
11379 Object visitMethodInvocation(MethodInvocation node) { | 11810 Object visitMethodInvocation(MethodInvocation node) { |
11380 // | 11811 // |
11381 // We visit the target and argument list, but do not visit the method name | 11812 // We visit the target and argument list, but do not visit the method name |
11382 // because it needs to be visited in the context of the invocation. | 11813 // because it needs to be visited in the context of the invocation. |
11383 // | 11814 // |
11384 safelyVisit(node.target); | 11815 safelyVisit(node.target); |
11385 node.accept(elementResolver); | 11816 node.accept(elementResolver); |
11386 _inferFunctionExpressionsParametersTypes(node.argumentList); | 11817 _inferFunctionExpressionsParametersTypes(node.argumentList); |
| 11818 Element methodElement = node.methodName.staticElement; |
| 11819 if (methodElement is ExecutableElement) { |
| 11820 InferenceContext.setType(node.argumentList, methodElement.type); |
| 11821 } |
11387 safelyVisit(node.argumentList); | 11822 safelyVisit(node.argumentList); |
11388 node.accept(typeAnalyzer); | 11823 node.accept(typeAnalyzer); |
11389 return null; | 11824 return null; |
11390 } | 11825 } |
11391 | 11826 |
11392 @override | 11827 @override |
| 11828 Object visitNamedExpression(NamedExpression node) { |
| 11829 InferenceContext.setType(node.expression, InferenceContext.getType(node)); |
| 11830 return super.visitNamedExpression(node); |
| 11831 } |
| 11832 |
| 11833 @override |
11393 Object visitNode(AstNode node) { | 11834 Object visitNode(AstNode node) { |
11394 node.visitChildren(this); | 11835 node.visitChildren(this); |
11395 node.accept(elementResolver); | 11836 node.accept(elementResolver); |
11396 node.accept(typeAnalyzer); | 11837 node.accept(typeAnalyzer); |
11397 return null; | 11838 return null; |
11398 } | 11839 } |
11399 | 11840 |
11400 @override | 11841 @override |
| 11842 Object visitParenthesizedExpression(ParenthesizedExpression node) { |
| 11843 InferenceContext.setType(node.expression, InferenceContext.getType(node)); |
| 11844 return super.visitParenthesizedExpression(node); |
| 11845 } |
| 11846 |
| 11847 @override |
11401 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | 11848 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
11402 // | 11849 // |
11403 // We visit the prefix, but do not visit the identifier because it needs to | 11850 // We visit the prefix, but do not visit the identifier because it needs to |
11404 // be visited in the context of the prefix. | 11851 // be visited in the context of the prefix. |
11405 // | 11852 // |
11406 safelyVisit(node.prefix); | 11853 safelyVisit(node.prefix); |
11407 node.accept(elementResolver); | 11854 node.accept(elementResolver); |
11408 node.accept(typeAnalyzer); | 11855 node.accept(typeAnalyzer); |
11409 return null; | 11856 return null; |
11410 } | 11857 } |
(...skipping 11 matching lines...) Expand all Loading... |
11422 } | 11869 } |
11423 | 11870 |
11424 @override | 11871 @override |
11425 Object visitRedirectingConstructorInvocation( | 11872 Object visitRedirectingConstructorInvocation( |
11426 RedirectingConstructorInvocation node) { | 11873 RedirectingConstructorInvocation node) { |
11427 // | 11874 // |
11428 // We visit the argument list, but do not visit the optional identifier | 11875 // We visit the argument list, but do not visit the optional identifier |
11429 // because it needs to be visited in the context of the constructor | 11876 // because it needs to be visited in the context of the constructor |
11430 // invocation. | 11877 // invocation. |
11431 // | 11878 // |
| 11879 InferenceContext.setType(node.argumentList, node.staticElement?.type); |
11432 safelyVisit(node.argumentList); | 11880 safelyVisit(node.argumentList); |
11433 node.accept(elementResolver); | 11881 node.accept(elementResolver); |
11434 node.accept(typeAnalyzer); | 11882 node.accept(typeAnalyzer); |
11435 return null; | 11883 return null; |
11436 } | 11884 } |
11437 | 11885 |
11438 @override | 11886 @override |
| 11887 Object visitReturnStatement(ReturnStatement node) { |
| 11888 InferenceContext.setType(node.expression, inferenceContext.returnContext); |
| 11889 return super.visitReturnStatement(node); |
| 11890 } |
| 11891 |
| 11892 @override |
11439 Object visitShowCombinator(ShowCombinator node) => null; | 11893 Object visitShowCombinator(ShowCombinator node) => null; |
11440 | 11894 |
11441 @override | 11895 @override |
11442 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { | 11896 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { |
11443 // | 11897 // |
11444 // We visit the argument list, but do not visit the optional identifier | 11898 // We visit the argument list, but do not visit the optional identifier |
11445 // because it needs to be visited in the context of the constructor | 11899 // because it needs to be visited in the context of the constructor |
11446 // invocation. | 11900 // invocation. |
11447 // | 11901 // |
| 11902 InferenceContext.setType(node.argumentList, node.staticElement?.type); |
11448 safelyVisit(node.argumentList); | 11903 safelyVisit(node.argumentList); |
11449 node.accept(elementResolver); | 11904 node.accept(elementResolver); |
11450 node.accept(typeAnalyzer); | 11905 node.accept(typeAnalyzer); |
11451 return null; | 11906 return null; |
11452 } | 11907 } |
11453 | 11908 |
11454 @override | 11909 @override |
11455 Object visitSwitchCase(SwitchCase node) { | 11910 Object visitSwitchCase(SwitchCase node) { |
11456 _overrideManager.enterScope(); | 11911 _overrideManager.enterScope(); |
11457 try { | 11912 try { |
(...skipping 27 matching lines...) Expand all Loading... |
11485 _overrideManager.applyOverrides(overrides); | 11940 _overrideManager.applyOverrides(overrides); |
11486 } | 11941 } |
11487 return null; | 11942 return null; |
11488 } | 11943 } |
11489 | 11944 |
11490 @override | 11945 @override |
11491 Object visitTypeName(TypeName node) => null; | 11946 Object visitTypeName(TypeName node) => null; |
11492 | 11947 |
11493 @override | 11948 @override |
11494 Object visitVariableDeclaration(VariableDeclaration node) { | 11949 Object visitVariableDeclaration(VariableDeclaration node) { |
| 11950 InferenceContext.setType(node.initializer, InferenceContext.getType(node)); |
11495 super.visitVariableDeclaration(node); | 11951 super.visitVariableDeclaration(node); |
11496 VariableElement element = node.element; | 11952 VariableElement element = node.element; |
11497 if (element.initializer != null && node.initializer != null) { | 11953 if (element.initializer != null && node.initializer != null) { |
11498 (element.initializer as FunctionElementImpl).returnType = | 11954 (element.initializer as FunctionElementImpl).returnType = |
11499 node.initializer.staticType; | 11955 node.initializer.staticType; |
11500 } | 11956 } |
11501 // Note: in addition to cloning the initializers for const variables, we | 11957 // Note: in addition to cloning the initializers for const variables, we |
11502 // have to clone the initializers for non-static final fields (because if | 11958 // have to clone the initializers for non-static final fields (because if |
11503 // they occur in a class with a const constructor, they will be needed to | 11959 // they occur in a class with a const constructor, they will be needed to |
11504 // evaluate the const constructor). | 11960 // evaluate the const constructor). |
11505 if ((element.isConst || | 11961 if ((element.isConst || |
11506 (element is FieldElement && | 11962 (element is FieldElement && |
11507 element.isFinal && | 11963 element.isFinal && |
11508 !element.isStatic)) && | 11964 !element.isStatic)) && |
11509 node.initializer != null) { | 11965 node.initializer != null) { |
11510 (element as ConstVariableElement).constantInitializer = | 11966 (element as ConstVariableElement).constantInitializer = |
11511 new ConstantAstCloner().cloneNode(node.initializer); | 11967 new ConstantAstCloner().cloneNode(node.initializer); |
11512 } | 11968 } |
11513 return null; | 11969 return null; |
11514 } | 11970 } |
11515 | 11971 |
| 11972 @override visitVariableDeclarationList(VariableDeclarationList node) { |
| 11973 for (VariableDeclaration decl in node.variables) { |
| 11974 InferenceContext.setType(decl, node.type?.type); |
| 11975 } |
| 11976 super.visitVariableDeclarationList(node); |
| 11977 } |
| 11978 |
11516 @override | 11979 @override |
11517 Object visitWhileStatement(WhileStatement node) { | 11980 Object visitWhileStatement(WhileStatement node) { |
11518 // Note: since we don't call the base class, we have to maintain | 11981 // Note: since we don't call the base class, we have to maintain |
11519 // _implicitLabelScope ourselves. | 11982 // _implicitLabelScope ourselves. |
11520 ImplicitLabelScope outerImplicitScope = _implicitLabelScope; | 11983 ImplicitLabelScope outerImplicitScope = _implicitLabelScope; |
11521 try { | 11984 try { |
11522 _implicitLabelScope = _implicitLabelScope.nest(node); | 11985 _implicitLabelScope = _implicitLabelScope.nest(node); |
11523 Expression condition = node.condition; | 11986 Expression condition = node.condition; |
11524 safelyVisit(condition); | 11987 safelyVisit(condition); |
11525 Statement body = node.body; | 11988 Statement body = node.body; |
11526 if (body != null) { | 11989 if (body != null) { |
11527 _overrideManager.enterScope(); | 11990 _overrideManager.enterScope(); |
11528 try { | 11991 try { |
11529 _propagateTrueState(condition); | 11992 _propagateTrueState(condition); |
11530 visitStatementInScope(body); | 11993 visitStatementInScope(body); |
11531 } finally { | 11994 } finally { |
11532 _overrideManager.exitScope(); | 11995 _overrideManager.exitScope(); |
11533 } | 11996 } |
11534 } | 11997 } |
11535 } finally { | 11998 } finally { |
11536 _implicitLabelScope = outerImplicitScope; | 11999 _implicitLabelScope = outerImplicitScope; |
11537 } | 12000 } |
11538 // TODO(brianwilkerson) If the loop can only be exited because the condition | 12001 // TODO(brianwilkerson) If the loop can only be exited because the condition |
11539 // is false, then propagateFalseState(condition); | 12002 // is false, then propagateFalseState(condition); |
11540 node.accept(elementResolver); | 12003 node.accept(elementResolver); |
11541 node.accept(typeAnalyzer); | 12004 node.accept(typeAnalyzer); |
11542 return null; | 12005 return null; |
11543 } | 12006 } |
11544 | 12007 |
| 12008 @override |
| 12009 Object visitYieldStatement(YieldStatement node) { |
| 12010 DartType returnType = inferenceContext.returnContext; |
| 12011 if (returnType != null && _enclosingFunction != null) { |
| 12012 // If we're not in a generator ([a]sync*, then we shouldn't have a yield. |
| 12013 // so don't infer |
| 12014 if (_enclosingFunction.isGenerator) { |
| 12015 // If this is a yield*, then we just propagate the return type downwards |
| 12016 DartType type = returnType; |
| 12017 // If this just a yield, then we need to get the element type |
| 12018 if (node.star == null) { |
| 12019 // If it's synchronous, we expect Iterable<T>, otherwise Stream<T> |
| 12020 InterfaceType wrapperD = _enclosingFunction.isSynchronous |
| 12021 ? typeProvider.iterableDynamicType |
| 12022 : typeProvider.streamDynamicType; |
| 12023 // Match the types to instantiate the type arguments if possible |
| 12024 List<DartType> targs = |
| 12025 inferenceContext.matchTypes(wrapperD, returnType); |
| 12026 type = (targs?.length == 1) ? targs[0] : null; |
| 12027 } |
| 12028 InferenceContext.setType(node.expression, type); |
| 12029 } |
| 12030 } |
| 12031 return super.visitYieldStatement(node); |
| 12032 } |
| 12033 |
11545 /** | 12034 /** |
11546 * Checks each promoted variable in the current scope for compliance with the
following | 12035 * Checks each promoted variable in the current scope for compliance with the
following |
11547 * specification statement: | 12036 * specification statement: |
11548 * | 12037 * |
11549 * If the variable <i>v</i> is accessed by a closure in <i>s<sub>1</sub></i> t
hen the variable | 12038 * If the variable <i>v</i> is accessed by a closure in <i>s<sub>1</sub></i> t
hen the variable |
11550 * <i>v</i> is not potentially mutated anywhere in the scope of <i>v</i>. | 12039 * <i>v</i> is not potentially mutated anywhere in the scope of <i>v</i>. |
11551 */ | 12040 */ |
11552 void _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated( | 12041 void _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated( |
11553 AstNode target) { | 12042 AstNode target) { |
11554 for (Element element in _promoteManager.promotedElements) { | 12043 for (Element element in _promoteManager.promotedElements) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11629 List<ParameterElement> onDataParameters = onDataType.parameters; | 12118 List<ParameterElement> onDataParameters = onDataType.parameters; |
11630 if (onDataParameters == null || onDataParameters.isEmpty) { | 12119 if (onDataParameters == null || onDataParameters.isEmpty) { |
11631 return null; | 12120 return null; |
11632 } | 12121 } |
11633 return onDataParameters[0].type; | 12122 return onDataParameters[0].type; |
11634 } | 12123 } |
11635 } | 12124 } |
11636 return null; | 12125 return null; |
11637 } | 12126 } |
11638 | 12127 |
| 12128 void _inferFormalParameterList(FormalParameterList node, DartType type) { |
| 12129 if (typeAnalyzer.inferFormalParameterList(node, type)) { |
| 12130 // TODO(leafp): This gets dropped on the floor if we're in the field |
| 12131 // inference task. We should probably keep these infos. |
| 12132 inferenceContext.recordInference(node.parent, type); |
| 12133 } |
| 12134 } |
| 12135 |
11639 /** | 12136 /** |
11640 * If given "mayBeClosure" is [FunctionExpression] without explicit parameters
types and its | 12137 * If given "mayBeClosure" is [FunctionExpression] without explicit parameters
types and its |
11641 * required type is [FunctionType], then infer parameters types from [Function
Type]. | 12138 * required type is [FunctionType], then infer parameters types from [Function
Type]. |
11642 */ | 12139 */ |
11643 void _inferFunctionExpressionParametersTypes( | 12140 void _inferFunctionExpressionParametersTypes( |
11644 Expression mayBeClosure, DartType mayByFunctionType) { | 12141 Expression mayBeClosure, DartType mayByFunctionType) { |
11645 // prepare closure | 12142 // prepare closure |
11646 if (mayBeClosure is! FunctionExpression) { | 12143 if (mayBeClosure is! FunctionExpression) { |
11647 return; | 12144 return; |
11648 } | 12145 } |
(...skipping 3913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15562 nonFields.add(node); | 16059 nonFields.add(node); |
15563 return null; | 16060 return null; |
15564 } | 16061 } |
15565 | 16062 |
15566 @override | 16063 @override |
15567 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); | 16064 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); |
15568 | 16065 |
15569 @override | 16066 @override |
15570 Object visitWithClause(WithClause node) => null; | 16067 Object visitWithClause(WithClause node) => null; |
15571 } | 16068 } |
OLD | NEW |