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

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

Issue 1771153002: Type check for-in statements. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Update to latest on master. Created 4 years, 9 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
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 70aa151cd7bd61ecdba7c55b6ccd368b9666745c..7d0c52be00f21130eeef324d522e9d8db516a6a7 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -689,6 +689,12 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
@override
+ Object visitForEachStatement(ForEachStatement node) {
+ _checkForInIterable(node);
+ return super.visitForEachStatement(node);
+ }
+
+ @override
Object visitFunctionDeclaration(FunctionDeclaration node) {
ExecutableElement outerFunction = _enclosingFunction;
try {
@@ -5663,16 +5669,65 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
/**
+ * Check for a type mis-match between the iterable expression and the
+ * assigned variable in a for-in statement.
+ */
+ void _checkForInIterable(ForEachStatement node) {
+ // Ignore malformed for statements.
+ if (node.identifier == null && node.loopVariable == null) {
+ return;
+ }
+
+ DartType iterableType = getStaticType(node.iterable);
+ if (iterableType.isDynamic) {
+ return;
+ }
+
+ // The type of the loop variable.
+ SimpleIdentifier variable = node.identifier != null
Jennifer Messerly 2016/03/08 19:14:11 probably not worth it, but this could be: nod
+ ? node.identifier
+ : node.loopVariable.identifier;
+ DartType variableType = getStaticType(variable);
+
+ DartType loopType = node.awaitKeyword != null
+ ? _typeProvider.streamType
+ : _typeProvider.iterableType;
+
+ // Use an explicit string instead of [loopType] to remove the "<E>".
+ String loopTypeName = node.awaitKeyword != null
Jennifer Messerly 2016/03/08 19:14:11 do you need this? Isn't this just: `loopType.name`
+ ? "Stream"
+ : "Iterable";
+
+ // The object being iterated has to implement Iterable<T> for some T that
+ // is assignable to the variable's type.
+ // TODO(rnystrom): Move this into mostSpecificTypeArgument()?
Jennifer Messerly 2016/03/08 19:14:11 yeah, I think that makes sense.
+ iterableType = iterableType.resolveToBound(_typeProvider.objectType);
+ DartType bestIterableType = _typeSystem.mostSpecificTypeArgument(
+ iterableType, loopType);
+ if (bestIterableType == null) {
+ _errorReporter.reportTypeErrorForNode(
+ StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE,
+ node,
+ [iterableType, loopTypeName]);
+ } else if (!_typeSystem.isAssignableTo(bestIterableType, variableType)) {
+ _errorReporter.reportTypeErrorForNode(
+ StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE,
+ node,
+ [iterableType, loopTypeName, variableType]);
+ }
+ }
+
+ /**
* Check for a type mis-match between the yielded type and the declared
* return type of a generator function.
*
* This method should only be called in generator functions.
*/
- bool _checkForYieldOfInvalidType(
+ void _checkForYieldOfInvalidType(
Brian Wilkerson 2016/03/08 01:12:12 fyi: I don't know that it matters, but the origina
Bob Nystrom 2016/03/08 19:00:50 I'm not sure about the other methods, but this one
Expression yieldExpression, bool isYieldEach) {
assert(_inGenerator);
if (_enclosingFunction == null) {
- return false;
+ return;
}
DartType declaredReturnType = _enclosingFunction.returnType;
DartType staticYieldedType = getStaticType(yieldExpression);
@@ -5691,7 +5746,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
StaticTypeWarningCode.YIELD_OF_INVALID_TYPE,
yieldExpression,
[impliedReturnType, declaredReturnType]);
- return true;
+ return;
}
if (isYieldEach) {
// Since the declared return type might have been "dynamic", we need to
@@ -5708,10 +5763,9 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
StaticTypeWarningCode.YIELD_OF_INVALID_TYPE,
yieldExpression,
[impliedReturnType, requiredReturnType]);
- return true;
+ return;
}
}
- return false;
}
/**

Powered by Google App Engine
This is Rietveld 408576698