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 analyzer.src.generated.resolver; | 5 library analyzer.src.generated.resolver; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; | 10 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; |
(...skipping 5152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5163 } | 5163 } |
5164 | 5164 |
5165 /** | 5165 /** |
5166 * Prepares this [ResolverVisitor] to using it for incremental resolution. | 5166 * Prepares this [ResolverVisitor] to using it for incremental resolution. |
5167 */ | 5167 */ |
5168 void initForIncrementalResolution() { | 5168 void initForIncrementalResolution() { |
5169 _overrideManager.enterScope(); | 5169 _overrideManager.enterScope(); |
5170 } | 5170 } |
5171 | 5171 |
5172 /** | 5172 /** |
5173 * Returns true if this method is `Future.then` or an override thereof. | |
5174 * | |
5175 * If so we will apply special typing rules in strong mode, to handle the | |
5176 * implicit union of `S | Future<S>` | |
5177 */ | |
5178 // TODO(leafp): Eliminate this when code is switched to using FutureOr | |
5179 bool isFutureThen(Element element) { | |
5180 // If we are a method named then | |
5181 if (element is MethodElement && element.name == 'then') { | |
5182 DartType type = element.enclosingElement.type; | |
5183 // On Future or a subtype, then we're good. | |
5184 return (type.isDartAsyncFuture || isSubtypeOfFuture(type)); | |
5185 } | |
5186 return false; | |
5187 } | |
5188 | |
5189 /** | |
5190 * Returns true if this type is any subtype of the built in Future type. | |
5191 */ | |
5192 // TODO(leafp): Eliminate this when code is switched to using FutureOr | |
5193 bool isSubtypeOfFuture(DartType type) => | |
5194 typeSystem.isSubtypeOf(type, typeProvider.futureDynamicType); | |
5195 | |
5196 /** | |
5197 * Given a downward inference type [fnType], and the declared | 5173 * Given a downward inference type [fnType], and the declared |
5198 * [typeParameterList] for a function expression, determines if we can enable | 5174 * [typeParameterList] for a function expression, determines if we can enable |
5199 * downward inference and if so, returns the function type to use for | 5175 * downward inference and if so, returns the function type to use for |
5200 * inference. | 5176 * inference. |
5201 * | 5177 * |
5202 * This will return null if inference is not possible. This happens when | 5178 * This will return null if inference is not possible. This happens when |
5203 * there is no way we can find a subtype of the function type, given the | 5179 * there is no way we can find a subtype of the function type, given the |
5204 * provided type parameter list. | 5180 * provided type parameter list. |
5205 */ | 5181 */ |
5206 FunctionType matchFunctionTypeParameters( | 5182 FunctionType matchFunctionTypeParameters( |
(...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6024 _enclosingFunction = node.element; | 6000 _enclosingFunction = node.element; |
6025 _overrideManager.enterScope(); | 6001 _overrideManager.enterScope(); |
6026 try { | 6002 try { |
6027 DartType functionType = InferenceContext.getContext(node); | 6003 DartType functionType = InferenceContext.getContext(node); |
6028 var ts = typeSystem; | 6004 var ts = typeSystem; |
6029 if (functionType is FunctionType && ts is StrongTypeSystemImpl) { | 6005 if (functionType is FunctionType && ts is StrongTypeSystemImpl) { |
6030 functionType = | 6006 functionType = |
6031 matchFunctionTypeParameters(node.typeParameters, functionType); | 6007 matchFunctionTypeParameters(node.typeParameters, functionType); |
6032 if (functionType is FunctionType) { | 6008 if (functionType is FunctionType) { |
6033 _inferFormalParameterList(node.parameters, functionType); | 6009 _inferFormalParameterList(node.parameters, functionType); |
6034 DartType returnType; | 6010 InferenceContext.setType( |
6035 ParameterElement parameterElement = | 6011 node.body, _computeReturnOrYieldType(functionType.returnType)); |
6036 resolutionMap.staticParameterElementForExpression(node); | |
6037 if (isFutureThen(parameterElement?.enclosingElement)) { | |
6038 var futureThenType = | |
6039 InferenceContext.getContext(node.parent) as FunctionType; | |
6040 | |
6041 // TODO(leafp): Get rid of this once code has been updated to use | |
6042 // FutureOr | |
6043 // Introduce FutureOr<T> for backwards compatibility if it was | |
6044 // missing in old code. | |
6045 if (futureThenType.parameters.isNotEmpty) { | |
6046 if (!futureThenType.parameters[0].type.isDartAsyncFutureOr) { | |
6047 var typeParamS = futureThenType.returnType.flattenFutures(ts); | |
6048 returnType = _createFutureOr(typeParamS); | |
6049 } | |
6050 } | |
6051 } | |
6052 returnType ??= _computeReturnOrYieldType(functionType.returnType); | |
6053 InferenceContext.setType(node.body, returnType); | |
6054 } | 6012 } |
6055 } | 6013 } |
6056 super.visitFunctionExpression(node); | 6014 super.visitFunctionExpression(node); |
6057 } finally { | 6015 } finally { |
6058 _overrideManager.exitScope(); | 6016 _overrideManager.exitScope(); |
6059 } | 6017 } |
6060 } finally { | 6018 } finally { |
6061 _currentFunctionBody = outerFunctionBody; | 6019 _currentFunctionBody = outerFunctionBody; |
6062 _enclosingFunction = outerFunction; | 6020 _enclosingFunction = outerFunction; |
6063 } | 6021 } |
(...skipping 4874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10938 return null; | 10896 return null; |
10939 } | 10897 } |
10940 if (identical(node.staticElement, variable)) { | 10898 if (identical(node.staticElement, variable)) { |
10941 if (node.inSetterContext()) { | 10899 if (node.inSetterContext()) { |
10942 result = true; | 10900 result = true; |
10943 } | 10901 } |
10944 } | 10902 } |
10945 return null; | 10903 return null; |
10946 } | 10904 } |
10947 } | 10905 } |
OLD | NEW |