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

Unified Diff: pkg/analyzer/lib/src/generated/error_verifier.dart

Issue 1924113002: fix #26334, allow supertypes for async function returns in strong mode (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/static_type_warning_code_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/generated/error_verifier.dart
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index c99057ad123a0ffe0645274036a38d55461dfbe9..65ec775016ad3039d90ad93506c837f21d3e21ac 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -3440,39 +3440,55 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
if (_enclosingFunction.isAsynchronous) {
if (_enclosingFunction.isGenerator) {
- if (_options.strongMode) {
- if (_enclosingFunction.returnType.element !=
- _typeProvider.streamType.element) {
- _errorReporter.reportErrorForNode(
- StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE,
- returnType);
- }
- } else if (!_typeSystem.isAssignableTo(
- _enclosingFunction.returnType, _typeProvider.streamDynamicType)) {
- _errorReporter.reportErrorForNode(
- StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE,
- returnType);
- }
+ _checkForIllegalReturnTypeCode(
+ returnType,
+ _typeProvider.streamDynamicType,
+ StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE);
} else {
- if (_options.strongMode) {
- if (_enclosingFunction.returnType.element !=
- _typeProvider.futureType.element) {
- _errorReporter.reportErrorForNode(
- StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE, returnType);
- }
- } else if (!_typeSystem.isAssignableTo(
- _enclosingFunction.returnType, _typeProvider.futureDynamicType)) {
- _errorReporter.reportErrorForNode(
- StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE, returnType);
- }
+ _checkForIllegalReturnTypeCode(
+ returnType,
+ _typeProvider.futureDynamicType,
+ StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE);
}
} else if (_enclosingFunction.isGenerator) {
- if (!_typeSystem.isAssignableTo(
- _enclosingFunction.returnType, _typeProvider.iterableDynamicType)) {
- _errorReporter.reportErrorForNode(
- StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE,
- returnType);
- }
+ _checkForIllegalReturnTypeCode(
+ returnType,
+ _typeProvider.iterableDynamicType,
+ StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE);
+ }
+ }
+
+ /**
+ * If the current function is async, async*, or sync*, verify that its
+ * declared return type is assignable to Future, Stream, or Iterable,
+ * respectively. This is called by [_checkForIllegalReturnType] to check if
+ * the declared [returnTypeName] is assignable to the required [expectedType]
+ * and if not report [errorCode].
+ */
+ void _checkForIllegalReturnTypeCode(TypeName returnTypeName,
+ DartType expectedType, StaticTypeWarningCode errorCode) {
+ DartType returnType = _enclosingFunction.returnType;
+ if (_options.strongMode) {
+ // When checking an async/sync*/async* method, we know the exact type
+ // that will be returned (e.g. Future, Iterable, or Stream).
+ //
+ // For example, an `async` function body will return a `Future<T>` for
+ // some T (possibly `dynamic`).
+ //
+ // We allow the declared return type to be a supertype of that
+ // (e.g. `dynamic`, `Object`), or Future<S> for some S.
+ // (We assume the T <: S relation is checked elsewhere.)
+ //
+ // We do not allow user-defined subtypes of Future, because an `async`
+ // method will never return those.
+ //
+ // Similar logic applies for sync* and async*.
+ if (!_typeSystem.isSubtypeOf(expectedType, returnType) &&
+ returnType.element != expectedType.element) {
Leaf 2016/04/28 01:01:50 This is a little tricky. It might be clearer just
Jennifer Messerly 2016/04/28 01:25:04 DOH. Yes, Future<bottom> is what I should've done.
+ _errorReporter.reportErrorForNode(errorCode, returnTypeName);
+ }
+ } else if (!_typeSystem.isAssignableTo(returnType, expectedType)) {
+ _errorReporter.reportErrorForNode(errorCode, returnTypeName);
}
}
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/static_type_warning_code_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698