OLD | NEW |
---|---|
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 8750 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8761 super.visitYieldStatement(node); | 8761 super.visitYieldStatement(node); |
8762 DartType type = e?.staticType; | 8762 DartType type = e?.staticType; |
8763 if (type != null && isGenerator) { | 8763 if (type != null && isGenerator) { |
8764 // If this just a yield, then we just pass on the element type | 8764 // If this just a yield, then we just pass on the element type |
8765 if (node.star != null) { | 8765 if (node.star != null) { |
8766 // If this is a yield*, then we unwrap the element return type | 8766 // If this is a yield*, then we unwrap the element return type |
8767 // If it's synchronous, we expect Iterable<T>, otherwise Stream<T> | 8767 // If it's synchronous, we expect Iterable<T>, otherwise Stream<T> |
8768 InterfaceType wrapperType = _enclosingFunction.isSynchronous | 8768 InterfaceType wrapperType = _enclosingFunction.isSynchronous |
8769 ? typeProvider.iterableType | 8769 ? typeProvider.iterableType |
8770 : typeProvider.streamType; | 8770 : typeProvider.streamType; |
8771 List<DartType> candidates = | 8771 type = typeSystem.mostSpecificTypeArgument(type, wrapperType); |
8772 _findImplementedTypeArgument(type, wrapperType); | |
8773 type = InterfaceTypeImpl.findMostSpecificType(candidates, typeSystem); | |
8774 } | 8772 } |
8775 if (type != null) { | 8773 if (type != null) { |
8776 inferenceContext.addReturnOrYieldType(type); | 8774 inferenceContext.addReturnOrYieldType(type); |
8777 } | 8775 } |
8778 } | 8776 } |
8779 return null; | 8777 return null; |
8780 } | 8778 } |
8781 | 8779 |
8782 /** | 8780 /** |
8783 * Checks each promoted variable in the current scope for compliance with the following | 8781 * Checks each promoted variable in the current scope for compliance with the following |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8835 // Match the types to instantiate the type arguments if possible | 8833 // Match the types to instantiate the type arguments if possible |
8836 List<DartType> typeArgs = | 8834 List<DartType> typeArgs = |
8837 inferenceContext.matchTypes(rawType, declaredType); | 8835 inferenceContext.matchTypes(rawType, declaredType); |
8838 return (typeArgs?.length == 1) ? typeArgs[0] : null; | 8836 return (typeArgs?.length == 1) ? typeArgs[0] : null; |
8839 } | 8837 } |
8840 // Must be asynchronous to reach here, so strip off any layers of Future | 8838 // Must be asynchronous to reach here, so strip off any layers of Future |
8841 return declaredType.flattenFutures(typeSystem); | 8839 return declaredType.flattenFutures(typeSystem); |
8842 } | 8840 } |
8843 | 8841 |
8844 /** | 8842 /** |
8845 * Starting from t1, search its class hierarchy for types of the form | |
8846 * `t2<R>`, and return a list of the resulting R's. | |
8847 * | |
8848 * For example, given t1 = `List<int>` and t2 = `Iterable<T>`, this will | |
8849 * return [int]. | |
8850 */ | |
8851 // TODO(jmesserly): this is very similar to code used for flattening futures. | |
8852 // The only difference is, because of a lack of TypeProvider, the other method | |
8853 // has to match the Future type by its name and library. Here was are passed | |
8854 // in the correct type. | |
8855 List<DartType> _findImplementedTypeArgument(DartType t1, InterfaceType t2) { | |
Jennifer Messerly
2016/03/08 19:14:11
oh awesome! I was wondering when reading error ver
| |
8856 List<DartType> result = <DartType>[]; | |
8857 HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>(); | |
8858 void recurse(InterfaceTypeImpl type) { | |
8859 if (type.element == t2.element && type.typeArguments.isNotEmpty) { | |
8860 result.add(type.typeArguments[0]); | |
8861 } | |
8862 if (visitedClasses.add(type.element)) { | |
8863 if (type.superclass != null) { | |
8864 recurse(type.superclass); | |
8865 } | |
8866 type.mixins.forEach(recurse); | |
8867 type.interfaces.forEach(recurse); | |
8868 visitedClasses.remove(type.element); | |
8869 } | |
8870 } | |
8871 if (t1 is InterfaceType) { | |
8872 recurse(t1); | |
8873 } | |
8874 return result; | |
8875 } | |
8876 | |
8877 /** | |
8878 * The given expression is the expression used to compute the iterator for a | 8843 * The given expression is the expression used to compute the iterator for a |
8879 * for-each statement. Attempt to compute the type of objects that will be | 8844 * for-each statement. Attempt to compute the type of objects that will be |
8880 * assigned to the loop variable and return that type. Return `null` if the | 8845 * assigned to the loop variable and return that type. Return `null` if the |
8881 * type could not be determined. The [iteratorExpression] is the expression | 8846 * type could not be determined. The [iteratorExpression] is the expression |
8882 * that will return the Iterable being iterated over. | 8847 * that will return the Iterable being iterated over. |
8883 */ | 8848 */ |
8884 DartType _getIteratorElementType(Expression iteratorExpression) { | 8849 DartType _getIteratorElementType(Expression iteratorExpression) { |
8885 DartType expressionType = iteratorExpression.bestType; | 8850 DartType expressionType = iteratorExpression.bestType; |
8886 if (expressionType is InterfaceType) { | 8851 if (expressionType is InterfaceType) { |
8887 InterfaceType interfaceType = expressionType; | 8852 InterfaceType interfaceType = expressionType; |
(...skipping 4088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12976 nonFields.add(node); | 12941 nonFields.add(node); |
12977 return null; | 12942 return null; |
12978 } | 12943 } |
12979 | 12944 |
12980 @override | 12945 @override |
12981 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); | 12946 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); |
12982 | 12947 |
12983 @override | 12948 @override |
12984 Object visitWithClause(WithClause node) => null; | 12949 Object visitWithClause(WithClause node) => null; |
12985 } | 12950 } |
OLD | NEW |