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

Side by Side Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 2260313002: Extend Future.then inference to subclasses (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: rebase Created 4 years, 4 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
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/generated/static_type_analyzer.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 5748 matching lines...) Expand 10 before | Expand all | Expand 10 after
5759 } 5759 }
5760 5760
5761 /** 5761 /**
5762 * Prepares this [ResolverVisitor] to using it for incremental resolution. 5762 * Prepares this [ResolverVisitor] to using it for incremental resolution.
5763 */ 5763 */
5764 void initForIncrementalResolution() { 5764 void initForIncrementalResolution() {
5765 _overrideManager.enterScope(); 5765 _overrideManager.enterScope();
5766 } 5766 }
5767 5767
5768 /** 5768 /**
5769 * Returns true if this method is `Future.then`. 5769 * Returns true if this method is `Future.then` or an override thereof.
5770 * 5770 *
5771 * If so we will apply special typing rules in strong mode, to handle the 5771 * If so we will apply special typing rules in strong mode, to handle the
5772 * implicit union of `S | Future<S>` 5772 * implicit union of `S | Future<S>`
5773 */ 5773 */
5774 bool isFutureThen(Element element) { 5774 bool isFutureThen(Element element) {
5775 return element is MethodElement && 5775 // If we are a method named then
5776 element.name == 'then' && 5776 if (element is MethodElement && element.name == 'then') {
5777 element.enclosingElement.type.isDartAsyncFuture; 5777 DartType type = element.enclosingElement.type;
5778 // On Future or a subtype, then we're good.
5779 return (type.isDartAsyncFuture || isSubtypeOfFuture(type));
5780 }
5781 return false;
5778 } 5782 }
5779 5783
5780 /** 5784 /**
5785 * Returns true if this type is any subtype of the built in Future type.
5786 */
5787 bool isSubtypeOfFuture(DartType type) =>
5788 typeSystem.isSubtypeOf(type, typeProvider.futureDynamicType);
5789
5790 /**
5781 * Given a downward inference type [fnType], and the declared 5791 * Given a downward inference type [fnType], and the declared
5782 * [typeParameterList] for a function expression, determines if we can enable 5792 * [typeParameterList] for a function expression, determines if we can enable
5783 * downward inference and if so, returns the function type to use for 5793 * downward inference and if so, returns the function type to use for
5784 * inference. 5794 * inference.
5785 * 5795 *
5786 * This will return null if inference is not possible. This happens when 5796 * This will return null if inference is not possible. This happens when
5787 * there is no way we can find a subtype of the function type, given the 5797 * there is no way we can find a subtype of the function type, given the
5788 * provided type parameter list. 5798 * provided type parameter list.
5789 */ 5799 */
5790 FunctionType matchFunctionTypeParameters( 5800 FunctionType matchFunctionTypeParameters(
(...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after
6726 perBranchOverrides.add(thenOverrides); 6736 perBranchOverrides.add(thenOverrides);
6727 perBranchOverrides.add(elseOverrides); 6737 perBranchOverrides.add(elseOverrides);
6728 _overrideManager.mergeOverrides(perBranchOverrides); 6738 _overrideManager.mergeOverrides(perBranchOverrides);
6729 } 6739 }
6730 return null; 6740 return null;
6731 } 6741 }
6732 6742
6733 @override 6743 @override
6734 Object visitInstanceCreationExpression(InstanceCreationExpression node) { 6744 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
6735 TypeName classTypeName = node.constructorName.type; 6745 TypeName classTypeName = node.constructorName.type;
6746 // TODO(leafp): Currently, we may re-infer types here, since we
6747 // sometimes resolve multiple times. We should really check that we
6748 // have not already inferred something. However, the obvious ways to
6749 // check this don't work, since we may have been instantiated
6750 // to bounds in an earlier phase, and we *do* want to do inference
6751 // in that case.
6736 if (classTypeName.typeArguments == null) { 6752 if (classTypeName.typeArguments == null) {
6737 // Given a union of context types ` T0 | T1 | ... | Tn`, find the first 6753 // Given a union of context types ` T0 | T1 | ... | Tn`, find the first
6738 // valid instantiation `new C<Ti>`, if it exists. 6754 // valid instantiation `new C<Ti>`, if it exists.
6739 // TODO(jmesserly): if we support union types for real, `new C<Ti | Tj>` 6755 // TODO(jmesserly): if we support union types for real, `new C<Ti | Tj>`
6740 // will become a valid possibility. Right now the only allowed union is 6756 // will become a valid possibility. Right now the only allowed union is
6741 // `T | Future<T>` so we can take a simple approach. 6757 // `T | Future<T>` so we can take a simple approach.
6742 for (var contextType in InferenceContext.getTypes(node)) { 6758 for (var contextType in InferenceContext.getTypes(node)) {
6743 if (contextType is InterfaceType && 6759 if (contextType is InterfaceType &&
6744 contextType.typeArguments != null && 6760 contextType.typeArguments != null &&
6745 contextType.typeArguments.isNotEmpty) { 6761 contextType.typeArguments.isNotEmpty) {
(...skipping 4407 matching lines...) Expand 10 before | Expand all | Expand 10 after
11153 return null; 11169 return null;
11154 } 11170 }
11155 if (identical(node.staticElement, variable)) { 11171 if (identical(node.staticElement, variable)) {
11156 if (node.inSetterContext()) { 11172 if (node.inSetterContext()) {
11157 result = true; 11173 result = true;
11158 } 11174 }
11159 } 11175 }
11160 return null; 11176 return null;
11161 } 11177 }
11162 } 11178 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/generated/static_type_analyzer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698