Chromium Code Reviews| Index: pkg/analyzer/lib/src/generated/static_type_analyzer.dart |
| diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart |
| index 720f8bbd4f0e314e7688cc267ac2ef22bfab6c7f..aec5135cbe16d4116806679f7dcc8f7f915295f6 100644 |
| --- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart |
| +++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart |
| @@ -1212,6 +1212,56 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
| return null; |
| } |
| + // TODO(vsm): Use leafp's matchType here? |
| + DartType _findIteratedType(InterfaceType type) { |
| + if (type.element == _typeProvider.iterableType.element) { |
| + var typeArguments = type.typeArguments; |
|
Brian Wilkerson
2015/08/28 20:59:33
nit: in the 'analyzer' package, we always provide
Leaf
2015/09/01 21:21:02
Done. What tool do you use? I poked around Intel
|
| + assert(typeArguments.length == 1); |
| + return typeArguments[0]; |
| + } |
| + |
| + if (type == _typeProvider.objectType) return null; |
| + |
| + var result = _findIteratedType(type.superclass); |
| + if (result != null) return result; |
| + |
| + for (final parent in type.interfaces) { |
| + result = _findIteratedType(parent); |
| + if (result != null) return result; |
| + } |
| + |
| + for (final parent in type.mixins) { |
| + result = _findIteratedType(parent); |
| + if (result != null) return result; |
| + } |
| + |
| + return null; |
| + } |
| + |
| + _inferDeclaredIdentifierType(DeclaredIdentifier node) { |
| + if (node.type == null) { |
| + var parent = node.parent as ForEachStatement; |
|
Paul Berry
2015/08/28 20:51:10
Isn't this going to blow up when visiting declared
Leaf
2015/09/01 21:21:02
As far as I can tell, the only place that the anal
Brian Wilkerson
2015/09/01 21:37:29
True, but we might re-use the class if the syntax
|
| + var expr = parent.iterable; |
| + var element = node.element as LocalVariableElementImpl; |
| + var exprType = expr.staticType; |
| + if (exprType is InterfaceType) { |
| + var iteratedType = _findIteratedType(exprType); |
|
Paul Berry
2015/08/28 20:51:10
We need to also check whether this is an "await fo
Brian Wilkerson
2015/08/28 20:59:33
This doesn't support the 'await for' case (see Res
Leaf
2015/09/01 21:21:01
Done.
|
| + if (iteratedType != null) { |
| + element.type = iteratedType; |
| + node.identifier.staticType = iteratedType; |
| + } |
| + } |
| + } |
| + } |
| + |
| + @override |
| + visitDeclaredIdentifier(DeclaredIdentifier node) { |
| + super.visitDeclaredIdentifier(node); |
| + if (_resolver.definingLibrary.context.analysisOptions.strongMode) { |
| + _inferDeclaredIdentifierType(node); |
| + } |
| + } |
| + |
| /** |
| * Set the static (propagated) type of [node] to be the least upper bound |
| * of the static (propagated) types of subexpressions [expr1] and [expr2]. |