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.element_resolver; | 5 library analyzer.src.generated.element_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 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
636 // does not apply to conditional method invocation (i.e. 'C?.m(...)'). | 636 // does not apply to conditional method invocation (i.e. 'C?.m(...)'). |
637 // | 637 // |
638 bool isConditional = node.operator.type == TokenType.QUESTION_PERIOD; | 638 bool isConditional = node.operator.type == TokenType.QUESTION_PERIOD; |
639 ClassElement typeReference = getTypeReference(target); | 639 ClassElement typeReference = getTypeReference(target); |
640 if (typeReference != null) { | 640 if (typeReference != null) { |
641 if (node.isCascaded) { | 641 if (node.isCascaded) { |
642 typeReference = _typeType.element; | 642 typeReference = _typeType.element; |
643 } | 643 } |
644 staticElement = _resolveElement(typeReference, methodName); | 644 staticElement = _resolveElement(typeReference, methodName); |
645 } else { | 645 } else { |
646 DartType staticType = _getStaticType(target); | 646 DartType staticType = _resolver.strongMode |
647 ? _getStaticTypeOrFunctionType(target) | |
648 : _getStaticType(target); | |
647 DartType propagatedType = _getPropagatedType(target); | 649 DartType propagatedType = _getPropagatedType(target); |
648 staticElement = _resolveInvokedElementWithTarget( | 650 staticElement = _resolveInvokedElementWithTarget( |
649 target, staticType, methodName, isConditional); | 651 target, staticType, methodName, isConditional); |
650 // If we have propagated type information use it (since it should | 652 // If we have propagated type information use it (since it should |
651 // not be redundant with the staticType). Otherwise, don't produce | 653 // not be redundant with the staticType). Otherwise, don't produce |
652 // a propagatedElement which duplicates the staticElement. | 654 // a propagatedElement which duplicates the staticElement. |
653 if (propagatedType is InterfaceType) { | 655 if (propagatedType is InterfaceType) { |
654 propagatedElement = _resolveInvokedElementWithTarget( | 656 propagatedElement = _resolveInvokedElementWithTarget( |
655 target, propagatedType, methodName, isConditional); | 657 target, propagatedType, methodName, isConditional); |
656 } | 658 } |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
810 } else if (identical( | 812 } else if (identical( |
811 errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD)) { | 813 errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD)) { |
812 // Generate the type name. | 814 // Generate the type name. |
813 // The error code will never be generated via type propagation | 815 // The error code will never be generated via type propagation |
814 DartType getSuperType(DartType type) { | 816 DartType getSuperType(DartType type) { |
815 if (type is InterfaceType && !type.isObject) { | 817 if (type is InterfaceType && !type.isObject) { |
816 return type.superclass; | 818 return type.superclass; |
817 } | 819 } |
818 return type; | 820 return type; |
819 } | 821 } |
822 | |
820 DartType targetType = getSuperType(_getStaticType(target)); | 823 DartType targetType = getSuperType(_getStaticType(target)); |
821 String targetTypeName = targetType?.name; | 824 String targetTypeName = targetType?.name; |
822 _resolver.errorReporter.reportErrorForNode( | 825 _resolver.errorReporter.reportErrorForNode( |
823 StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, | 826 StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, |
824 methodName, | 827 methodName, |
825 [methodName.name, targetTypeName]); | 828 [methodName.name, targetTypeName]); |
826 } | 829 } |
827 return null; | 830 return null; |
828 } | 831 } |
829 | 832 |
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1509 propagatedType = _resolver.typeProvider.functionType; | 1512 propagatedType = _resolver.typeProvider.functionType; |
1510 } | 1513 } |
1511 return propagatedType; | 1514 return propagatedType; |
1512 } | 1515 } |
1513 | 1516 |
1514 /** | 1517 /** |
1515 * Return the static type of the given [expression] that is to be used for | 1518 * Return the static type of the given [expression] that is to be used for |
1516 * type analysis. | 1519 * type analysis. |
1517 */ | 1520 */ |
1518 DartType _getStaticType(Expression expression) { | 1521 DartType _getStaticType(Expression expression) { |
1519 if (expression is NullLiteral) { | 1522 DartType staticType = _getStaticTypeOrFunctionType(expression); |
1520 return _resolver.typeProvider.bottomType; | |
1521 } | |
1522 DartType staticType = _resolveTypeParameter(expression.staticType); | |
1523 if (staticType is FunctionType) { | 1523 if (staticType is FunctionType) { |
1524 // | 1524 // |
1525 // All function types are subtypes of 'Function', which is itself a | 1525 // All function types are subtypes of 'Function', which is itself a |
1526 // subclass of 'Object'. | 1526 // subclass of 'Object'. |
1527 // | 1527 // |
1528 staticType = _resolver.typeProvider.functionType; | 1528 staticType = _resolver.typeProvider.functionType; |
Jennifer Messerly
2016/08/09 17:14:21
... wow
Leaf
2016/08/10 07:38:14
Wat? Am I crazy, or does this mean that everythin
Jennifer Messerly
2016/08/10 15:27:45
yeah it's *super* scary. I looked a bit yesterday.
| |
1529 } | 1529 } |
1530 return staticType; | 1530 return staticType; |
1531 } | 1531 } |
1532 | 1532 |
1533 DartType _getStaticTypeOrFunctionType(Expression expression) { | |
1534 if (expression is NullLiteral) { | |
1535 return _resolver.typeProvider.bottomType; | |
1536 } | |
1537 return _resolveTypeParameter(expression.staticType); | |
1538 } | |
1539 | |
1533 /** | 1540 /** |
1534 * Check for a generic method & apply type arguments if any were passed. | 1541 * Check for a generic method & apply type arguments if any were passed. |
1535 */ | 1542 */ |
1536 DartType _instantiateGenericMethod( | 1543 DartType _instantiateGenericMethod( |
1537 DartType invokeType, TypeArgumentList typeArguments, AstNode node) { | 1544 DartType invokeType, TypeArgumentList typeArguments, AstNode node) { |
1538 // TODO(jmesserly): support generic "call" methods on InterfaceType. | 1545 // TODO(jmesserly): support generic "call" methods on InterfaceType. |
1539 if (invokeType is FunctionType) { | 1546 if (invokeType is FunctionType) { |
1540 List<TypeParameterElement> parameters = invokeType.typeFormals; | 1547 List<TypeParameterElement> parameters = invokeType.typeFormals; |
1541 | 1548 |
1542 NodeList<TypeName> arguments = typeArguments?.arguments; | 1549 NodeList<TypeName> arguments = typeArguments?.arguments; |
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2189 // If there's no method, then it's possible that 'm' is a getter that | 2196 // If there's no method, then it's possible that 'm' is a getter that |
2190 // returns a function. | 2197 // returns a function. |
2191 // | 2198 // |
2192 // TODO (collinsn): need to add union type support here too, in the | 2199 // TODO (collinsn): need to add union type support here too, in the |
2193 // style of [lookUpMethod]. | 2200 // style of [lookUpMethod]. |
2194 element = _lookUpGetter(target, targetType, methodName.name); | 2201 element = _lookUpGetter(target, targetType, methodName.name); |
2195 } | 2202 } |
2196 return element; | 2203 return element; |
2197 } else if (target is SimpleIdentifier) { | 2204 } else if (target is SimpleIdentifier) { |
2198 Element targetElement = target.staticElement; | 2205 Element targetElement = target.staticElement; |
2206 if (targetType is FunctionType && | |
2207 methodName.name == FunctionElement.CALL_METHOD_NAME) { | |
2208 return targetElement; | |
2209 } | |
2199 if (targetElement is PrefixElement) { | 2210 if (targetElement is PrefixElement) { |
2200 if (isConditional) { | 2211 if (isConditional) { |
2201 _resolver.errorReporter.reportErrorForNode( | 2212 _resolver.errorReporter.reportErrorForNode( |
2202 CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, | 2213 CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, |
2203 target, | 2214 target, |
2204 [target.name]); | 2215 [target.name]); |
2205 } | 2216 } |
2206 // | 2217 // |
2207 // Look to see whether the name of the method is really part of a | 2218 // Look to see whether the name of the method is really part of a |
2208 // prefixed identifier for an imported top-level function or top-level | 2219 // prefixed identifier for an imported top-level function or top-level |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2592 | 2603 |
2593 @override | 2604 @override |
2594 Element get staticElement => null; | 2605 Element get staticElement => null; |
2595 | 2606 |
2596 @override | 2607 @override |
2597 dynamic/*=E*/ accept/*<E>*/(AstVisitor/*<E>*/ visitor) => null; | 2608 dynamic/*=E*/ accept/*<E>*/(AstVisitor/*<E>*/ visitor) => null; |
2598 | 2609 |
2599 @override | 2610 @override |
2600 void visitChildren(AstVisitor visitor) {} | 2611 void visitChildren(AstVisitor visitor) {} |
2601 } | 2612 } |
OLD | NEW |