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

Side by Side Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 1405143006: improve static type analysis for `await for` (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 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 unified diff | Download patch
OLDNEW
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 engine.resolver; 5 library engine.resolver;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import 'package:analyzer/src/generated/scanner.dart'; 9 import 'package:analyzer/src/generated/scanner.dart';
10 10
(...skipping 5834 matching lines...) Expand 10 before | Expand all | Expand 10 after
5845 */ 5845 */
5846 ExecutableElement lookupMember(ClassElement classElt, String memberName) { 5846 ExecutableElement lookupMember(ClassElement classElt, String memberName) {
5847 ExecutableElement element = _lookupMemberInClass(classElt, memberName); 5847 ExecutableElement element = _lookupMemberInClass(classElt, memberName);
5848 if (element != null) { 5848 if (element != null) {
5849 return element; 5849 return element;
5850 } 5850 }
5851 return lookupInheritance(classElt, memberName); 5851 return lookupInheritance(classElt, memberName);
5852 } 5852 }
5853 5853
5854 /** 5854 /**
5855 * Given some [InterfaceType] and some member name, this returns the
5856 * [FunctionType] of the [ExecutableElement] that the
5857 * class either declares itself, or inherits, that has the member name, if no member is inherited
5858 * `null` is returned. The returned [FunctionType] has all type
5859 * parameters substituted with corresponding type arguments from the given [In terfaceType].
5860 *
5861 * @param interfaceType the interface type to query
5862 * @param memberName the name of the executable element to find and return
5863 * @return the member's function type, or `null` if no such member exists
5864 */
5865 FunctionType lookupMemberType(
5866 InterfaceType interfaceType, String memberName) {
5867 ExecutableElement iteratorMember =
5868 lookupMember(interfaceType.element, memberName);
5869 if (iteratorMember == null) {
5870 return null;
5871 }
5872 return substituteTypeArgumentsInMemberFromInheritance(
5873 iteratorMember.type, memberName, interfaceType);
5874 }
5875
5876 /**
5877 * Determine the set of methods which is overridden by the given class member. If no member is 5855 * Determine the set of methods which is overridden by the given class member. If no member is
5878 * inherited, an empty list is returned. If one of the inherited members is a 5856 * inherited, an empty list is returned. If one of the inherited members is a
5879 * [MultiplyInheritedExecutableElement], then it is expanded into its constitu ent inherited 5857 * [MultiplyInheritedExecutableElement], then it is expanded into its constitu ent inherited
5880 * elements. 5858 * elements.
5881 * 5859 *
5882 * @param classElt the class to query 5860 * @param classElt the class to query
5883 * @param memberName the name of the class member to query 5861 * @param memberName the name of the class member to query
5884 * @return a list of overridden methods 5862 * @return a list of overridden methods
5885 */ 5863 */
5886 List<ExecutableElement> lookupOverrides( 5864 List<ExecutableElement> lookupOverrides(
(...skipping 18 matching lines...) Expand all
5905 } else { 5883 } else {
5906 result.add(overriddenElement); 5884 result.add(overriddenElement);
5907 } 5885 }
5908 } 5886 }
5909 } 5887 }
5910 } 5888 }
5911 return result; 5889 return result;
5912 } 5890 }
5913 5891
5914 /** 5892 /**
5915 * This method takes some inherited [FunctionType], and resolves all the param eterized types
5916 * in the function type, dependent on the class in which it is being overridde n.
5917 *
5918 * @param baseFunctionType the function type that is being overridden
5919 * @param memberName the name of the member, this is used to lookup the inheri tance path of the
5920 * override
5921 * @param definingType the type that is overriding the member
5922 * @return the passed function type with any parameterized types substituted
5923 */
5924 FunctionType substituteTypeArgumentsInMemberFromInheritance(
5925 FunctionType baseFunctionType,
5926 String memberName,
5927 InterfaceType definingType) {
5928 // if the baseFunctionType is null, or does not have any parameters,
5929 // return it.
5930 if (baseFunctionType == null ||
5931 baseFunctionType.typeArguments.length == 0) {
5932 return baseFunctionType;
5933 }
5934 // First, generate the path from the defining type to the overridden member
5935 Queue<InterfaceType> inheritancePath = new Queue<InterfaceType>();
5936 _computeInheritancePath(inheritancePath, definingType, memberName);
5937 if (inheritancePath == null || inheritancePath.isEmpty) {
5938 // TODO(jwren) log analysis engine error
5939 return baseFunctionType;
5940 }
5941 FunctionType functionTypeToReturn = baseFunctionType;
5942 // loop backward through the list substituting as we go:
5943 while (!inheritancePath.isEmpty) {
5944 InterfaceType lastType = inheritancePath.removeLast();
5945 List<DartType> parameterTypes = lastType.element.type.typeArguments;
5946 List<DartType> argumentTypes = lastType.typeArguments;
5947 functionTypeToReturn =
5948 functionTypeToReturn.substitute2(argumentTypes, parameterTypes);
5949 }
5950 return functionTypeToReturn;
5951 }
5952
5953 /**
5954 * Compute and return a mapping between the set of all string names of the mem bers inherited from 5893 * Compute and return a mapping between the set of all string names of the mem bers inherited from
5955 * the passed [ClassElement] superclass hierarchy, and the associated 5894 * the passed [ClassElement] superclass hierarchy, and the associated
5956 * [ExecutableElement]. 5895 * [ExecutableElement].
5957 * 5896 *
5958 * @param classElt the class element to query 5897 * @param classElt the class element to query
5959 * @param visitedClasses a set of visited classes passed back into this method when it calls 5898 * @param visitedClasses a set of visited classes passed back into this method when it calls
5960 * itself recursively 5899 * itself recursively
5961 * @return a mapping between the set of all string names of the members inheri ted from the passed 5900 * @return a mapping between the set of all string names of the members inheri ted from the passed
5962 * [ClassElement] superclass hierarchy, and the associated [Executable Element] 5901 * [ClassElement] superclass hierarchy, and the associated [Executable Element]
5963 */ 5902 */
(...skipping 5621 matching lines...) Expand 10 before | Expand all | Expand 10 after
11585 * The given expression is the expression used to compute the iterator for a 11524 * The given expression is the expression used to compute the iterator for a
11586 * for-each statement. Attempt to compute the type of objects that will be 11525 * for-each statement. Attempt to compute the type of objects that will be
11587 * assigned to the loop variable and return that type. Return `null` if the 11526 * assigned to the loop variable and return that type. Return `null` if the
11588 * type could not be determined. The [iteratorExpression] is the expression 11527 * type could not be determined. The [iteratorExpression] is the expression
11589 * that will return the Iterable being iterated over. 11528 * that will return the Iterable being iterated over.
11590 */ 11529 */
11591 DartType _getIteratorElementType(Expression iteratorExpression) { 11530 DartType _getIteratorElementType(Expression iteratorExpression) {
11592 DartType expressionType = iteratorExpression.bestType; 11531 DartType expressionType = iteratorExpression.bestType;
11593 if (expressionType is InterfaceType) { 11532 if (expressionType is InterfaceType) {
11594 InterfaceType interfaceType = expressionType; 11533 InterfaceType interfaceType = expressionType;
11595 FunctionType iteratorFunction = 11534 PropertyAccessorElement iteratorFunction =
11596 _inheritanceManager.lookupMemberType(interfaceType, "iterator"); 11535 interfaceType.lookUpInheritedGetter("iterator");
11597 if (iteratorFunction == null) { 11536 if (iteratorFunction == null) {
11598 // TODO(brianwilkerson) Should we report this error? 11537 // TODO(brianwilkerson) Should we report this error?
11599 return null; 11538 return null;
11600 } 11539 }
11601 DartType iteratorType = iteratorFunction.returnType; 11540 DartType iteratorType = iteratorFunction.returnType;
11602 if (iteratorType is InterfaceType) { 11541 if (iteratorType is InterfaceType) {
11603 InterfaceType iteratorInterfaceType = iteratorType; 11542 InterfaceType iteratorInterfaceType = iteratorType;
11604 FunctionType currentFunction = _inheritanceManager.lookupMemberType( 11543 PropertyAccessorElement currentFunction =
11605 iteratorInterfaceType, "current"); 11544 iteratorInterfaceType.lookUpInheritedGetter("current");
11606 if (currentFunction == null) { 11545 if (currentFunction == null) {
11607 // TODO(brianwilkerson) Should we report this error? 11546 // TODO(brianwilkerson) Should we report this error?
11608 return null; 11547 return null;
11609 } 11548 }
11610 return currentFunction.returnType; 11549 return currentFunction.returnType;
11611 } 11550 }
11612 } 11551 }
11613 return null; 11552 return null;
11614 } 11553 }
11615 11554
11616 /** 11555 /**
11617 * The given expression is the expression used to compute the stream for an 11556 * The given expression is the expression used to compute the stream for an
11618 * asyncronous for-each statement. Attempt to compute the type of objects that 11557 * asynchronous for-each statement. Attempt to compute the type of objects
11619 * will be assigned to the loop variable and return that type. Return `null` 11558 * that will be assigned to the loop variable and return that type.
11620 * if the type could not be determined. The [streamExpression] is the 11559 * Return `null` if the type could not be determined. The [streamExpression]
11621 * expression that will return the stream being iterated over. 11560 * is the expression that will return the stream being iterated over.
11622 */ 11561 */
11623 DartType _getStreamElementType(Expression streamExpression) { 11562 DartType _getStreamElementType(Expression streamExpression) {
11624 DartType streamType = streamExpression.bestType; 11563 DartType streamType = streamExpression.bestType;
11625 if (streamType is InterfaceType) { 11564 if (streamType is InterfaceType) {
11626 FunctionType listenFunction = 11565 MethodElement listenFunction = streamType.lookUpInheritedMethod("listen");
11627 _inheritanceManager.lookupMemberType(streamType, "listen");
11628 if (listenFunction == null) { 11566 if (listenFunction == null) {
11629 return null; 11567 return null;
11630 } 11568 }
11631 List<ParameterElement> listenParameters = listenFunction.parameters; 11569 List<ParameterElement> listenParameters = listenFunction.parameters;
11632 if (listenParameters == null || listenParameters.length < 1) { 11570 if (listenParameters == null || listenParameters.length < 1) {
11633 return null; 11571 return null;
11634 } 11572 }
11635 DartType onDataType = listenParameters[0].type; 11573 DartType onDataType = listenParameters[0].type;
11636 if (onDataType is FunctionType) { 11574 if (onDataType is FunctionType) {
11637 List<ParameterElement> onDataParameters = onDataType.parameters; 11575 List<ParameterElement> onDataParameters = onDataType.parameters;
11638 if (onDataParameters == null || onDataParameters.length < 1) { 11576 if (onDataParameters == null || onDataParameters.isEmpty) {
11639 return null; 11577 return null;
11640 } 11578 }
11641 DartType eventType = onDataParameters[0].type; 11579 return onDataParameters[0].type;
11642 // TODO(paulberry): checking that typeParameters.isNotEmpty is a
11643 // band-aid fix for dartbug.com/24191. Figure out what the correct
11644 // logic should be.
11645 if (streamType.typeParameters.isNotEmpty &&
11646 eventType.element == streamType.typeParameters[0]) {
11647 return streamType.typeArguments[0];
11648 }
11649 } 11580 }
11650 } 11581 }
11651 return null; 11582 return null;
11652 } 11583 }
11653 11584
11654 /** 11585 /**
11655 * If given "mayBeClosure" is [FunctionExpression] without explicit parameters types and its 11586 * If given "mayBeClosure" is [FunctionExpression] without explicit parameters types and its
11656 * required type is [FunctionType], then infer parameters types from [Function Type]. 11587 * required type is [FunctionType], then infer parameters types from [Function Type].
11657 */ 11588 */
11658 void _inferFunctionExpressionParametersTypes( 11589 void _inferFunctionExpressionParametersTypes(
(...skipping 1215 matching lines...) Expand 10 before | Expand all | Expand 10 after
12874 return false; 12805 return false;
12875 } 12806 }
12876 12807
12877 @override 12808 @override
12878 bool isSubtypeOf(DartType leftType, DartType rightType) { 12809 bool isSubtypeOf(DartType leftType, DartType rightType) {
12879 return _isSubtypeOf(leftType, rightType, null); 12810 return _isSubtypeOf(leftType, rightType, null);
12880 } 12811 }
12881 12812
12882 FunctionType _getCallMethodType(DartType t) { 12813 FunctionType _getCallMethodType(DartType t) {
12883 if (t is InterfaceType) { 12814 if (t is InterfaceType) {
12884 ClassElement element = t.element; 12815 MethodElement callMethod = t.lookUpInheritedMethod("call");
12885 InheritanceManager manager = new InheritanceManager(element.library); 12816 return callMethod != null ? callMethod.type : null;
Paul Berry 2015/10/29 16:29:59 Nit: these two lines could be collapsed to: retur
Jennifer Messerly 2015/10/29 16:36:40 not sure if I can use null aware ops yet
Paul Berry 2015/10/29 16:43:10 There was a brief period where we couldn't use the
Jennifer Messerly 2015/10/29 17:24:33 Ah thank you! BTW, I didn't intend to reply to yo
12886 FunctionType callType = manager.lookupMemberType(t, "call");
12887 return callType;
12888 } 12817 }
12889 return null; 12818 return null;
12890 } 12819 }
12891 12820
12892 // Given a type t, if t is an interface type with a call method 12821 // Given a type t, if t is an interface type with a call method
12893 // defined, return the function type for the call method, otherwise 12822 // defined, return the function type for the call method, otherwise
12894 // return null. 12823 // return null.
12895 _GuardedSubtypeChecker<DartType> _guard( 12824 _GuardedSubtypeChecker<DartType> _guard(
12896 _GuardedSubtypeChecker<DartType> check) { 12825 _GuardedSubtypeChecker<DartType> check) {
12897 return (DartType t1, DartType t2, Set<Element> visited) { 12826 return (DartType t1, DartType t2, Set<Element> visited) {
(...skipping 3166 matching lines...) Expand 10 before | Expand all | Expand 10 after
16064 nonFields.add(node); 15993 nonFields.add(node);
16065 return null; 15994 return null;
16066 } 15995 }
16067 15996
16068 @override 15997 @override
16069 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); 15998 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this);
16070 15999
16071 @override 16000 @override
16072 Object visitWithClause(WithClause node) => null; 16001 Object visitWithClause(WithClause node) => null;
16073 } 16002 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698