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 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |