Chromium Code Reviews| 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 |