| 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/element/element.dart'; | 9 import 'package:analyzer/dart/element/element.dart'; |
| 10 import 'package:analyzer/dart/element/type.dart'; | 10 import 'package:analyzer/dart/element/type.dart'; |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 | 420 |
| 421 @override | 421 @override |
| 422 Object visitFunctionDeclaration(FunctionDeclaration node) { | 422 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 423 setMetadata(node.element, node); | 423 setMetadata(node.element, node); |
| 424 return null; | 424 return null; |
| 425 } | 425 } |
| 426 | 426 |
| 427 @override | 427 @override |
| 428 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | 428 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
| 429 Expression function = node.function; | 429 Expression function = node.function; |
| 430 DartType staticInvokeType = | 430 DartType staticInvokeType = _instantiateGenericMethod( |
| 431 _resolveGenericMethod(function.staticType, node.typeArguments, node); | 431 function.staticType, node.typeArguments, node); |
| 432 DartType propagatedInvokeType = _resolveGenericMethod( | 432 DartType propagatedInvokeType = _instantiateGenericMethod( |
| 433 function.propagatedType, node.typeArguments, node); | 433 function.propagatedType, node.typeArguments, node); |
| 434 | 434 |
| 435 node.staticInvokeType = staticInvokeType; | 435 node.staticInvokeType = staticInvokeType; |
| 436 node.propagatedInvokeType = | 436 node.propagatedInvokeType = |
| 437 _propagatedInvokeTypeIfBetter(propagatedInvokeType, staticInvokeType); | 437 _propagatedInvokeTypeIfBetter(propagatedInvokeType, staticInvokeType); |
| 438 | 438 |
| 439 List<ParameterElement> parameters = | 439 List<ParameterElement> parameters = |
| 440 _computeCorrespondingParameters(node.argumentList, staticInvokeType); | 440 _computeCorrespondingParameters(node.argumentList, staticInvokeType); |
| 441 if (parameters != null) { | 441 if (parameters != null) { |
| 442 node.argumentList.correspondingStaticParameters = parameters; | 442 node.argumentList.correspondingStaticParameters = parameters; |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 if (propagatedType is InterfaceType) { | 645 if (propagatedType is InterfaceType) { |
| 646 propagatedElement = _resolveInvokedElementWithTarget( | 646 propagatedElement = _resolveInvokedElementWithTarget( |
| 647 target, propagatedType, methodName, isConditional); | 647 target, propagatedType, methodName, isConditional); |
| 648 } | 648 } |
| 649 } | 649 } |
| 650 } | 650 } |
| 651 | 651 |
| 652 staticElement = _convertSetterToGetter(staticElement); | 652 staticElement = _convertSetterToGetter(staticElement); |
| 653 propagatedElement = _convertSetterToGetter(propagatedElement); | 653 propagatedElement = _convertSetterToGetter(propagatedElement); |
| 654 | 654 |
| 655 DartType staticInvokeType = _computeMethodInvokeType(node, staticElement); | 655 // |
| 656 DartType propagatedInvokeType = | 656 // Given the elements, determine the type of the function we are invoking |
| 657 _computeMethodInvokeType(node, propagatedElement); | 657 // |
| 658 DartType staticInvokeType = _getInvokeType(staticElement); |
| 659 methodName.staticType = staticInvokeType; |
| 660 |
| 661 DartType propagatedInvokeType = _getInvokeType(propagatedElement); |
| 662 methodName.propagatedType = |
| 663 _propagatedInvokeTypeIfBetter(propagatedInvokeType, staticInvokeType); |
| 664 |
| 665 // |
| 666 // Instantiate generic function or method if needed. |
| 667 // |
| 668 staticInvokeType = _instantiateGenericMethod( |
| 669 staticInvokeType, node.typeArguments, node.methodName); |
| 670 propagatedInvokeType = _instantiateGenericMethod( |
| 671 propagatedInvokeType, node.typeArguments, node.methodName); |
| 658 | 672 |
| 659 // | 673 // |
| 660 // Record the results. | 674 // Record the results. |
| 661 // | 675 // |
| 662 methodName.staticElement = staticElement; | 676 methodName.staticElement = staticElement; |
| 663 methodName.propagatedElement = propagatedElement; | 677 methodName.propagatedElement = propagatedElement; |
| 664 | 678 |
| 665 node.staticInvokeType = staticInvokeType; | 679 node.staticInvokeType = staticInvokeType; |
| 666 // | 680 // |
| 667 // Store the propagated invoke type if it's more specific than the static | 681 // Store the propagated invoke type if it's more specific than the static |
| (...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1331 if (callMethod != null) { | 1345 if (callMethod != null) { |
| 1332 return _resolveArgumentsToFunction(false, argumentList, callMethod); | 1346 return _resolveArgumentsToFunction(false, argumentList, callMethod); |
| 1333 } | 1347 } |
| 1334 } else if (type is FunctionType) { | 1348 } else if (type is FunctionType) { |
| 1335 return _resolveArgumentsToParameters( | 1349 return _resolveArgumentsToParameters( |
| 1336 false, argumentList, type.parameters); | 1350 false, argumentList, type.parameters); |
| 1337 } | 1351 } |
| 1338 return null; | 1352 return null; |
| 1339 } | 1353 } |
| 1340 | 1354 |
| 1341 DartType _computeMethodInvokeType(MethodInvocation node, Element element) { | 1355 /** |
| 1342 if (element == null) { | 1356 * Given an element, computes the type of the invocation. |
| 1343 // TODO(jmesserly): should we return `dynamic` in this case? | 1357 * |
| 1344 // Otherwise we have to guard against `null` every time we use | 1358 * For executable elements (like methods, functions) this is just their type. |
| 1345 // `staticInvokeType`. | 1359 * |
| 1346 // If we do return `dynamic` we need to be careful that this doesn't | 1360 * For variables it is their type taking into account any type promotion. |
| 1347 // adversely affect propagatedType code path. But it shouldn't because | 1361 * |
| 1348 // we'll discard `dynamic` anyway (see _propagatedInvokeTypeIfBetter). | 1362 * For calls to getters in Dart, we invoke the function that is returned by |
| 1349 return null; | 1363 * the getter, so the invoke type is the getter's returnType. |
| 1350 } | 1364 */ |
| 1351 | 1365 DartType _getInvokeType(Element element) { |
| 1352 DartType invokeType; | 1366 DartType invokeType; |
| 1353 if (element is PropertyAccessorElement) { | 1367 if (element is PropertyAccessorElement) { |
| 1354 invokeType = element.returnType; | 1368 invokeType = element.returnType; |
| 1355 } else if (element is ExecutableElement) { | 1369 } else if (element is ExecutableElement) { |
| 1356 invokeType = element.type; | 1370 invokeType = element.type; |
| 1357 } else if (element is VariableElement) { | 1371 } else if (element is VariableElement) { |
| 1358 invokeType = _promoteManager.getStaticType(element); | 1372 invokeType = _promoteManager.getStaticType(element); |
| 1359 } | 1373 } |
| 1360 | 1374 return invokeType ?? DynamicTypeImpl.instance; |
| 1361 return _resolveGenericMethod( | |
| 1362 invokeType, node.typeArguments, node.methodName); | |
| 1363 } | 1375 } |
| 1364 | 1376 |
| 1365 /** | 1377 /** |
| 1366 * If the given [element] is a setter, return the getter associated with it. | 1378 * If the given [element] is a setter, return the getter associated with it. |
| 1367 * Otherwise, return the element unchanged. | 1379 * Otherwise, return the element unchanged. |
| 1368 */ | 1380 */ |
| 1369 Element _convertSetterToGetter(Element element) { | 1381 Element _convertSetterToGetter(Element element) { |
| 1370 // TODO(brianwilkerson) Determine whether and why the element could ever be | 1382 // TODO(brianwilkerson) Determine whether and why the element could ever be |
| 1371 // a setter. | 1383 // a setter. |
| 1372 if (element is PropertyAccessorElement) { | 1384 if (element is PropertyAccessorElement) { |
| (...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2078 } | 2090 } |
| 2079 if (element != null && element.isAccessibleIn(_definingLibrary)) { | 2091 if (element != null && element.isAccessibleIn(_definingLibrary)) { |
| 2080 return element; | 2092 return element; |
| 2081 } | 2093 } |
| 2082 return null; | 2094 return null; |
| 2083 } | 2095 } |
| 2084 | 2096 |
| 2085 /** | 2097 /** |
| 2086 * Check for a generic method & apply type arguments if any were passed. | 2098 * Check for a generic method & apply type arguments if any were passed. |
| 2087 */ | 2099 */ |
| 2088 DartType _resolveGenericMethod( | 2100 DartType _instantiateGenericMethod( |
| 2089 DartType invokeType, TypeArgumentList typeArguments, AstNode node) { | 2101 DartType invokeType, TypeArgumentList typeArguments, AstNode node) { |
| 2090 // TODO(jmesserly): support generic "call" methods on InterfaceType. | 2102 // TODO(jmesserly): support generic "call" methods on InterfaceType. |
| 2091 if (invokeType is FunctionType) { | 2103 if (invokeType is FunctionType) { |
| 2092 FunctionType type = invokeType; | 2104 FunctionType type = invokeType; |
| 2093 List<TypeParameterElement> parameters = type.typeFormals; | 2105 List<TypeParameterElement> parameters = type.typeFormals; |
| 2094 | 2106 |
| 2095 NodeList<TypeName> arguments = typeArguments?.arguments; | 2107 NodeList<TypeName> arguments = typeArguments?.arguments; |
| 2096 if (arguments != null && arguments.length != parameters.length) { | 2108 if (arguments != null && arguments.length != parameters.length) { |
| 2097 // Wrong number of type arguments. Ignore them | 2109 // Wrong number of type arguments. Ignore them |
| 2098 arguments = null; | 2110 arguments = null; |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2609 | 2621 |
| 2610 @override | 2622 @override |
| 2611 Element get staticElement => null; | 2623 Element get staticElement => null; |
| 2612 | 2624 |
| 2613 @override | 2625 @override |
| 2614 accept(AstVisitor visitor) => null; | 2626 accept(AstVisitor visitor) => null; |
| 2615 | 2627 |
| 2616 @override | 2628 @override |
| 2617 void visitChildren(AstVisitor visitor) {} | 2629 void visitChildren(AstVisitor visitor) {} |
| 2618 } | 2630 } |
| OLD | NEW |