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/token.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
(...skipping 5740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5751 } | 5751 } |
5752 | 5752 |
5753 /** | 5753 /** |
5754 * Prepares this [ResolverVisitor] to using it for incremental resolution. | 5754 * Prepares this [ResolverVisitor] to using it for incremental resolution. |
5755 */ | 5755 */ |
5756 void initForIncrementalResolution() { | 5756 void initForIncrementalResolution() { |
5757 _overrideManager.enterScope(); | 5757 _overrideManager.enterScope(); |
5758 } | 5758 } |
5759 | 5759 |
5760 /** | 5760 /** |
| 5761 * Returns true if this method is `Future.then`. |
| 5762 * |
| 5763 * If so we will apply special typing rules in strong mode, to handle the |
| 5764 * implicit union of `S | Future<S>` |
| 5765 */ |
| 5766 bool isFutureThen(Element element) { |
| 5767 return element is MethodElement && |
| 5768 element.name == 'then' && |
| 5769 element.enclosingElement.type.isDartAsyncFuture; |
| 5770 } |
| 5771 |
| 5772 /** |
5761 * Given a downward inference type [fnType], and the declared | 5773 * Given a downward inference type [fnType], and the declared |
5762 * [typeParameterList] for a function expression, determines if we can enable | 5774 * [typeParameterList] for a function expression, determines if we can enable |
5763 * downward inference and if so, returns the function type to use for | 5775 * downward inference and if so, returns the function type to use for |
5764 * inference. | 5776 * inference. |
5765 * | 5777 * |
5766 * This will return null if inference is not possible. This happens when | 5778 * This will return null if inference is not possible. This happens when |
5767 * there is no way we can find a subtype of the function type, given the | 5779 * there is no way we can find a subtype of the function type, given the |
5768 * provided type parameter list. | 5780 * provided type parameter list. |
5769 */ | 5781 */ |
5770 FunctionType matchFunctionTypeParameters( | 5782 FunctionType matchFunctionTypeParameters( |
(...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6576 _overrideManager.enterScope(); | 6588 _overrideManager.enterScope(); |
6577 try { | 6589 try { |
6578 DartType functionType = InferenceContext.getType(node); | 6590 DartType functionType = InferenceContext.getType(node); |
6579 if (functionType is FunctionType) { | 6591 if (functionType is FunctionType) { |
6580 functionType = | 6592 functionType = |
6581 matchFunctionTypeParameters(node.typeParameters, functionType); | 6593 matchFunctionTypeParameters(node.typeParameters, functionType); |
6582 if (functionType is FunctionType) { | 6594 if (functionType is FunctionType) { |
6583 _inferFormalParameterList(node.parameters, functionType); | 6595 _inferFormalParameterList(node.parameters, functionType); |
6584 | 6596 |
6585 DartType returnType; | 6597 DartType returnType; |
6586 if (_isFutureThenLambda(node)) { | 6598 if (isFutureThen(node.staticParameterElement?.enclosingElement)) { |
6587 var futureThenType = | 6599 var futureThenType = |
6588 InferenceContext.getContext(node.parent) as FunctionType; | 6600 InferenceContext.getContext(node.parent) as FunctionType; |
6589 | 6601 |
6590 // Pretend the return type of Future<T>.then<S> first parameter is | 6602 // Pretend the return type of Future<T>.then<S> first parameter is |
6591 // | 6603 // |
6592 // T -> (S | Future<S>) | 6604 // T -> (S | Future<S>) |
6593 // | 6605 // |
6594 // We can't represent this in Dart so we populate it here during | 6606 // We can't represent this in Dart so we populate it here during |
6595 // inference. | 6607 // inference. |
6596 returnType = FutureUnionType.from( | 6608 returnType = FutureUnionType.from( |
(...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7387 // | 7399 // |
7388 // Unsound to assume that [x = "hello";] never executed after the | 7400 // Unsound to assume that [x = "hello";] never executed after the |
7389 // if-statement. Of course, a dead-code analysis could point out that | 7401 // if-statement. Of course, a dead-code analysis could point out that |
7390 // [return] here is dead. | 7402 // [return] here is dead. |
7391 return _isAbruptTerminationStatement(statements[size - 1]); | 7403 return _isAbruptTerminationStatement(statements[size - 1]); |
7392 } | 7404 } |
7393 return false; | 7405 return false; |
7394 } | 7406 } |
7395 | 7407 |
7396 /** | 7408 /** |
7397 * Returns true if this expression is being passed to `Future.then`. | |
7398 * | |
7399 * If so we will apply special typing rules in strong mode, to handle the | |
7400 * implicit union of `S | Future<S>` | |
7401 */ | |
7402 bool _isFutureThenLambda(FunctionExpression node) { | |
7403 Element element = node.staticParameterElement?.enclosingElement; | |
7404 return element is MethodElement && | |
7405 element.name == 'then' && | |
7406 element.enclosingElement.type.isDartAsyncFuture; | |
7407 } | |
7408 | |
7409 /** | |
7410 * Return `true` if the given variable is accessed within a closure in the giv
en | 7409 * Return `true` if the given variable is accessed within a closure in the giv
en |
7411 * [AstNode] and also mutated somewhere in variable scope. This information is
only | 7410 * [AstNode] and also mutated somewhere in variable scope. This information is
only |
7412 * available for local variables (including parameters). | 7411 * available for local variables (including parameters). |
7413 * | 7412 * |
7414 * @param variable the variable to check | 7413 * @param variable the variable to check |
7415 * @param target the [AstNode] to check within | 7414 * @param target the [AstNode] to check within |
7416 * @return `true` if this variable is potentially mutated somewhere in the giv
en ASTNode | 7415 * @return `true` if this variable is potentially mutated somewhere in the giv
en ASTNode |
7417 */ | 7416 */ |
7418 bool _isVariableAccessedInClosure(Element variable, AstNode target) { | 7417 bool _isVariableAccessedInClosure(Element variable, AstNode target) { |
7419 _ResolverVisitor_isVariableAccessedInClosure visitor = | 7418 _ResolverVisitor_isVariableAccessedInClosure visitor = |
(...skipping 3685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11105 return null; | 11104 return null; |
11106 } | 11105 } |
11107 if (identical(node.staticElement, variable)) { | 11106 if (identical(node.staticElement, variable)) { |
11108 if (node.inSetterContext()) { | 11107 if (node.inSetterContext()) { |
11109 result = true; | 11108 result = true; |
11110 } | 11109 } |
11111 } | 11110 } |
11112 return null; | 11111 return null; |
11113 } | 11112 } |
11114 } | 11113 } |
OLD | NEW |