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

Unified Diff: lib/type_checker.dart

Issue 2473523004: Fix expected return type in async functions (Closed)
Patch Set: Also handle yield* Created 4 years, 1 month 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 | lib/type_environment.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/type_checker.dart
diff --git a/lib/type_checker.dart b/lib/type_checker.dart
index ab47f6e328aead936a0dcab8cba10bcd766081cd..be49ca0c285c5a8943374170ef6a0d54fc76bf8d 100644
--- a/lib/type_checker.dart
+++ b/lib/type_checker.dart
@@ -158,12 +158,14 @@ class TypeCheckingVisitor
}
visitProcedure(Procedure node) {
- environment.returnType = node.function.returnType;
+ environment.returnType = _getInternalReturnType(node.function);
environment.yieldType = _getYieldType(node.function);
handleFunctionNode(node.function);
}
void handleFunctionNode(FunctionNode node) {
+ var oldAsyncMarker = environment.currentAsyncMarker;
+ environment.currentAsyncMarker = node.asyncMarker;
node.positionalParameters
.skip(node.requiredParameterCount)
.forEach(handleOptionalParameter);
@@ -171,12 +173,13 @@ class TypeCheckingVisitor
if (node.body != null) {
visitStatement(node.body);
}
+ environment.currentAsyncMarker = oldAsyncMarker;
}
void handleNestedFunctionNode(FunctionNode node) {
var oldReturn = environment.returnType;
var oldYield = environment.yieldType;
- environment.returnType = node.returnType;
+ environment.returnType = _getInternalReturnType(node);
environment.yieldType = _getYieldType(node);
handleFunctionNode(node);
environment.returnType = oldReturn;
@@ -275,6 +278,29 @@ class TypeCheckingVisitor
return substitution.substituteType(function.returnType);
}
+ DartType _getInternalReturnType(FunctionNode function) {
+ switch (function.asyncMarker) {
+ case AsyncMarker.Sync:
+ return function.returnType;
+
+ case AsyncMarker.Async:
+ Class container = coreTypes.futureClass;
+ DartType returnType = function.returnType;
+ if (returnType is InterfaceType && returnType.classNode == container) {
+ return returnType.typeArguments.single;
+ }
+ return const DynamicType();
+
+ case AsyncMarker.SyncStar:
+ case AsyncMarker.AsyncStar:
+ case AsyncMarker.SyncYielding:
+ return null;
+
+ default:
+ throw 'Unexpected async marker: ${function.asyncMarker}';
+ }
+ }
+
DartType _getYieldType(FunctionNode function) {
switch (function.asyncMarker) {
case AsyncMarker.Sync:
@@ -736,7 +762,11 @@ class TypeCheckingVisitor
if (environment.returnType == null) {
fail(node, 'Return of a value from void method');
} else {
- checkAssignableExpression(node.expression, environment.returnType);
+ var type = visitExpression(node.expression);
+ if (environment.currentAsyncMarker == AsyncMarker.Async) {
+ type = environment.unfutureType(type);
+ }
+ checkAssignable(node.expression, type, environment.returnType);
}
}
}
@@ -779,7 +809,23 @@ class TypeCheckingVisitor
@override
visitYieldStatement(YieldStatement node) {
- checkAssignableExpression(node.expression, environment.yieldType);
+ if (node.isYieldStar) {
+ Class container = environment.currentAsyncMarker == AsyncMarker.AsyncStar
+ ? coreTypes.streamClass
+ : coreTypes.iterableClass;
+ var type = visitExpression(node.expression);
+ var asContainer = type is InterfaceType
+ ? hierarchy.getTypeAsInstanceOf(type, container)
+ : null;
+ if (asContainer != null) {
+ checkAssignable(node.expression, asContainer.typeArguments[0],
+ environment.yieldType);
+ } else {
+ fail(node.expression, '$type is not an instance of $container');
+ }
+ } else {
+ checkAssignableExpression(node.expression, environment.yieldType);
+ }
}
@override
« no previous file with comments | « no previous file | lib/type_environment.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698