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.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; | |
|
Jennifer Messerly
2016/01/13 22:32:46
This stores the element's type in the methodName n
| |
| 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 * For variables it is their type taking into account any type promotion. |
| 1346 // If we do return `dynamic` we need to be careful that this doesn't | 1360 * For getters it is the type that they return. |
| 1347 // adversely affect propagatedType code path. But it shouldn't because | 1361 */ |
| 1348 // we'll discard `dynamic` anyway (see _propagatedInvokeTypeIfBetter). | 1362 DartType _getInvokeType(Element element) { |
| 1349 return null; | |
| 1350 } | |
| 1351 | |
| 1352 DartType invokeType; | 1363 DartType invokeType; |
| 1353 if (element is PropertyAccessorElement) { | 1364 if (element is PropertyAccessorElement) { |
| 1354 invokeType = element.returnType; | 1365 invokeType = element.returnType; |
| 1355 } else if (element is ExecutableElement) { | 1366 } else if (element is ExecutableElement) { |
| 1356 invokeType = element.type; | 1367 invokeType = element.type; |
| 1357 } else if (element is VariableElement) { | 1368 } else if (element is VariableElement) { |
| 1358 invokeType = _promoteManager.getStaticType(element); | 1369 invokeType = _promoteManager.getStaticType(element); |
| 1359 } | 1370 } |
| 1360 | 1371 return invokeType ?? DynamicTypeImpl.instance; |
| 1361 return _resolveGenericMethod( | |
| 1362 invokeType, node.typeArguments, node.methodName); | |
| 1363 } | 1372 } |
| 1364 | 1373 |
| 1365 /** | 1374 /** |
| 1366 * If the given [element] is a setter, return the getter associated with it. | 1375 * If the given [element] is a setter, return the getter associated with it. |
| 1367 * Otherwise, return the element unchanged. | 1376 * Otherwise, return the element unchanged. |
| 1368 */ | 1377 */ |
| 1369 Element _convertSetterToGetter(Element element) { | 1378 Element _convertSetterToGetter(Element element) { |
| 1370 // TODO(brianwilkerson) Determine whether and why the element could ever be | 1379 // TODO(brianwilkerson) Determine whether and why the element could ever be |
| 1371 // a setter. | 1380 // a setter. |
| 1372 if (element is PropertyAccessorElement) { | 1381 if (element is PropertyAccessorElement) { |
| (...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2078 } | 2087 } |
| 2079 if (element != null && element.isAccessibleIn(_definingLibrary)) { | 2088 if (element != null && element.isAccessibleIn(_definingLibrary)) { |
| 2080 return element; | 2089 return element; |
| 2081 } | 2090 } |
| 2082 return null; | 2091 return null; |
| 2083 } | 2092 } |
| 2084 | 2093 |
| 2085 /** | 2094 /** |
| 2086 * Check for a generic method & apply type arguments if any were passed. | 2095 * Check for a generic method & apply type arguments if any were passed. |
| 2087 */ | 2096 */ |
| 2088 DartType _resolveGenericMethod( | 2097 DartType _instantiateGenericMethod( |
| 2089 DartType invokeType, TypeArgumentList typeArguments, AstNode node) { | 2098 DartType invokeType, TypeArgumentList typeArguments, AstNode node) { |
| 2090 // TODO(jmesserly): support generic "call" methods on InterfaceType. | 2099 // TODO(jmesserly): support generic "call" methods on InterfaceType. |
| 2091 if (invokeType is FunctionType) { | 2100 if (invokeType is FunctionType) { |
| 2092 FunctionType type = invokeType; | 2101 FunctionType type = invokeType; |
| 2093 List<TypeParameterElement> parameters = type.typeFormals; | 2102 List<TypeParameterElement> parameters = type.typeFormals; |
| 2094 | 2103 |
| 2095 NodeList<TypeName> arguments = typeArguments?.arguments; | 2104 NodeList<TypeName> arguments = typeArguments?.arguments; |
| 2096 if (arguments != null && arguments.length != parameters.length) { | 2105 if (arguments != null && arguments.length != parameters.length) { |
| 2097 // Wrong number of type arguments. Ignore them | 2106 // Wrong number of type arguments. Ignore them |
| 2098 arguments = null; | 2107 arguments = null; |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2609 | 2618 |
| 2610 @override | 2619 @override |
| 2611 Element get staticElement => null; | 2620 Element get staticElement => null; |
| 2612 | 2621 |
| 2613 @override | 2622 @override |
| 2614 accept(AstVisitor visitor) => null; | 2623 accept(AstVisitor visitor) => null; |
| 2615 | 2624 |
| 2616 @override | 2625 @override |
| 2617 void visitChildren(AstVisitor visitor) {} | 2626 void visitChildren(AstVisitor visitor) {} |
| 2618 } | 2627 } |
| OLD | NEW |