| 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'; |
| 10 import 'package:analyzer/dart/ast/visitor.dart'; |
| 9 import 'package:analyzer/dart/element/element.dart'; | 11 import 'package:analyzer/dart/element/element.dart'; |
| 10 import 'package:analyzer/dart/element/type.dart'; | 12 import 'package:analyzer/dart/element/type.dart'; |
| 13 import 'package:analyzer/src/dart/ast/ast.dart' |
| 14 show ChildEntities, IdentifierImpl; |
| 11 import 'package:analyzer/src/dart/element/element.dart'; | 15 import 'package:analyzer/src/dart/element/element.dart'; |
| 12 import 'package:analyzer/src/dart/element/type.dart'; | 16 import 'package:analyzer/src/dart/element/type.dart'; |
| 13 import 'package:analyzer/src/generated/ast.dart'; | |
| 14 import 'package:analyzer/src/generated/engine.dart'; | 17 import 'package:analyzer/src/generated/engine.dart'; |
| 15 import 'package:analyzer/src/generated/error.dart'; | 18 import 'package:analyzer/src/generated/error.dart'; |
| 16 import 'package:analyzer/src/generated/resolver.dart'; | 19 import 'package:analyzer/src/generated/resolver.dart'; |
| 17 import 'package:analyzer/src/generated/scanner.dart' as sc; | 20 import 'package:analyzer/src/generated/scanner.dart' as sc; |
| 18 | 21 |
| 19 /** | 22 /** |
| 20 * An object used by instances of [ResolverVisitor] to resolve references within | 23 * An object used by instances of [ResolverVisitor] to resolve references within |
| 21 * the AST structure to the elements being referenced. The requirements for the | 24 * the AST structure to the elements being referenced. The requirements for the |
| 22 * element resolver are: | 25 * element resolver are: |
| 23 * | 26 * |
| (...skipping 1365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1389 } else { | 1392 } else { |
| 1390 invokeType = type.instantiate(arguments.map((n) => n.type).toList()); | 1393 invokeType = type.instantiate(arguments.map((n) => n.type).toList()); |
| 1391 } | 1394 } |
| 1392 } | 1395 } |
| 1393 } | 1396 } |
| 1394 | 1397 |
| 1395 return invokeType; | 1398 return invokeType; |
| 1396 } | 1399 } |
| 1397 | 1400 |
| 1398 /** | 1401 /** |
| 1399 * Given an element, computes the type of the invocation. | |
| 1400 * | |
| 1401 * For executable elements (like methods, functions) this is just their type. | |
| 1402 * | |
| 1403 * For variables it is their type taking into account any type promotion. | |
| 1404 * | |
| 1405 * For calls to getters in Dart, we invoke the function that is returned by | |
| 1406 * the getter, so the invoke type is the getter's returnType. | |
| 1407 */ | |
| 1408 DartType _getInvokeType(Element element) { | |
| 1409 DartType invokeType; | |
| 1410 if (element is PropertyAccessorElement) { | |
| 1411 invokeType = element.returnType; | |
| 1412 } else if (element is ExecutableElement) { | |
| 1413 invokeType = element.type; | |
| 1414 } else if (element is VariableElement) { | |
| 1415 invokeType = _promoteManager.getStaticType(element); | |
| 1416 } | |
| 1417 return invokeType ?? DynamicTypeImpl.instance; | |
| 1418 } | |
| 1419 | |
| 1420 /** | |
| 1421 * If the given [element] is a setter, return the getter associated with it. | 1402 * If the given [element] is a setter, return the getter associated with it. |
| 1422 * Otherwise, return the element unchanged. | 1403 * Otherwise, return the element unchanged. |
| 1423 */ | 1404 */ |
| 1424 Element _convertSetterToGetter(Element element) { | 1405 Element _convertSetterToGetter(Element element) { |
| 1425 // TODO(brianwilkerson) Determine whether and why the element could ever be | 1406 // TODO(brianwilkerson) Determine whether and why the element could ever be |
| 1426 // a setter. | 1407 // a setter. |
| 1427 if (element is PropertyAccessorElement) { | 1408 if (element is PropertyAccessorElement) { |
| 1428 return element.variable.getter; | 1409 return element.variable.getter; |
| 1429 } | 1410 } |
| 1430 return element; | 1411 return element; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1487 */ | 1468 */ |
| 1488 LibraryElement _getImportedLibrary(Expression expression) { | 1469 LibraryElement _getImportedLibrary(Expression expression) { |
| 1489 PrefixElement prefixElement = | 1470 PrefixElement prefixElement = |
| 1490 (expression as SimpleIdentifier).staticElement as PrefixElement; | 1471 (expression as SimpleIdentifier).staticElement as PrefixElement; |
| 1491 List<ImportElement> imports = | 1472 List<ImportElement> imports = |
| 1492 prefixElement.enclosingElement.getImportsWithPrefix(prefixElement); | 1473 prefixElement.enclosingElement.getImportsWithPrefix(prefixElement); |
| 1493 return imports[0].importedLibrary; | 1474 return imports[0].importedLibrary; |
| 1494 } | 1475 } |
| 1495 | 1476 |
| 1496 /** | 1477 /** |
| 1478 * Given an element, computes the type of the invocation. |
| 1479 * |
| 1480 * For executable elements (like methods, functions) this is just their type. |
| 1481 * |
| 1482 * For variables it is their type taking into account any type promotion. |
| 1483 * |
| 1484 * For calls to getters in Dart, we invoke the function that is returned by |
| 1485 * the getter, so the invoke type is the getter's returnType. |
| 1486 */ |
| 1487 DartType _getInvokeType(Element element) { |
| 1488 DartType invokeType; |
| 1489 if (element is PropertyAccessorElement) { |
| 1490 invokeType = element.returnType; |
| 1491 } else if (element is ExecutableElement) { |
| 1492 invokeType = element.type; |
| 1493 } else if (element is VariableElement) { |
| 1494 invokeType = _promoteManager.getStaticType(element); |
| 1495 } |
| 1496 return invokeType ?? DynamicTypeImpl.instance; |
| 1497 } |
| 1498 |
| 1499 /** |
| 1497 * Return the name of the method invoked by the given postfix [expression]. | 1500 * Return the name of the method invoked by the given postfix [expression]. |
| 1498 */ | 1501 */ |
| 1499 String _getPostfixOperator(PostfixExpression expression) => | 1502 String _getPostfixOperator(PostfixExpression expression) => |
| 1500 (expression.operator.type == sc.TokenType.PLUS_PLUS) | 1503 (expression.operator.type == sc.TokenType.PLUS_PLUS) |
| 1501 ? sc.TokenType.PLUS.lexeme | 1504 ? sc.TokenType.PLUS.lexeme |
| 1502 : sc.TokenType.MINUS.lexeme; | 1505 : sc.TokenType.MINUS.lexeme; |
| 1503 | 1506 |
| 1504 /** | 1507 /** |
| 1505 * Return the name of the method invoked by the given postfix [expression]. | 1508 * Return the name of the method invoked by the given postfix [expression]. |
| 1506 */ | 1509 */ |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1547 // | 1550 // |
| 1548 // All function types are subtypes of 'Function', which is itself a | 1551 // All function types are subtypes of 'Function', which is itself a |
| 1549 // subclass of 'Object'. | 1552 // subclass of 'Object'. |
| 1550 // | 1553 // |
| 1551 staticType = _resolver.typeProvider.functionType; | 1554 staticType = _resolver.typeProvider.functionType; |
| 1552 } | 1555 } |
| 1553 return staticType; | 1556 return staticType; |
| 1554 } | 1557 } |
| 1555 | 1558 |
| 1556 /** | 1559 /** |
| 1560 * Check for a generic method & apply type arguments if any were passed. |
| 1561 */ |
| 1562 DartType _instantiateGenericMethod( |
| 1563 DartType invokeType, TypeArgumentList typeArguments, AstNode node) { |
| 1564 // TODO(jmesserly): support generic "call" methods on InterfaceType. |
| 1565 if (invokeType is FunctionType) { |
| 1566 FunctionType type = invokeType; |
| 1567 List<TypeParameterElement> parameters = type.typeFormals; |
| 1568 |
| 1569 NodeList<TypeName> arguments = typeArguments?.arguments; |
| 1570 if (arguments != null && arguments.length != parameters.length) { |
| 1571 // Wrong number of type arguments. Ignore them |
| 1572 arguments = null; |
| 1573 _resolver.reportErrorForNode( |
| 1574 StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, |
| 1575 node, |
| 1576 [type, parameters.length, arguments?.length ?? 0]); |
| 1577 } |
| 1578 if (parameters.isNotEmpty) { |
| 1579 if (arguments == null) { |
| 1580 invokeType = _resolver.typeSystem.instantiateToBounds(type); |
| 1581 } else { |
| 1582 invokeType = type.instantiate(arguments.map((n) => n.type).toList()); |
| 1583 } |
| 1584 } |
| 1585 } |
| 1586 return invokeType; |
| 1587 } |
| 1588 |
| 1589 /** |
| 1557 * Return `true` if the given [expression] is a prefix for a deferred import. | 1590 * Return `true` if the given [expression] is a prefix for a deferred import. |
| 1558 */ | 1591 */ |
| 1559 bool _isDeferredPrefix(Expression expression) { | 1592 bool _isDeferredPrefix(Expression expression) { |
| 1560 if (expression is! SimpleIdentifier) { | 1593 if (expression is! SimpleIdentifier) { |
| 1561 return false; | 1594 return false; |
| 1562 } | 1595 } |
| 1563 Element element = (expression as SimpleIdentifier).staticElement; | 1596 Element element = (expression as SimpleIdentifier).staticElement; |
| 1564 if (element is! PrefixElement) { | 1597 if (element is! PrefixElement) { |
| 1565 return false; | 1598 return false; |
| 1566 } | 1599 } |
| (...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2131 if (element == null) { | 2164 if (element == null) { |
| 2132 element = classElement.getMethod(name); | 2165 element = classElement.getMethod(name); |
| 2133 } | 2166 } |
| 2134 if (element != null && element.isAccessibleIn(_definingLibrary)) { | 2167 if (element != null && element.isAccessibleIn(_definingLibrary)) { |
| 2135 return element; | 2168 return element; |
| 2136 } | 2169 } |
| 2137 return null; | 2170 return null; |
| 2138 } | 2171 } |
| 2139 | 2172 |
| 2140 /** | 2173 /** |
| 2141 * Check for a generic method & apply type arguments if any were passed. | |
| 2142 */ | |
| 2143 DartType _instantiateGenericMethod( | |
| 2144 DartType invokeType, TypeArgumentList typeArguments, AstNode node) { | |
| 2145 // TODO(jmesserly): support generic "call" methods on InterfaceType. | |
| 2146 if (invokeType is FunctionType) { | |
| 2147 FunctionType type = invokeType; | |
| 2148 List<TypeParameterElement> parameters = type.typeFormals; | |
| 2149 | |
| 2150 NodeList<TypeName> arguments = typeArguments?.arguments; | |
| 2151 if (arguments != null && arguments.length != parameters.length) { | |
| 2152 // Wrong number of type arguments. Ignore them | |
| 2153 arguments = null; | |
| 2154 _resolver.reportErrorForNode( | |
| 2155 StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, | |
| 2156 node, | |
| 2157 [type, parameters.length, arguments?.length ?? 0]); | |
| 2158 } | |
| 2159 if (parameters.isNotEmpty) { | |
| 2160 if (arguments == null) { | |
| 2161 invokeType = _resolver.typeSystem.instantiateToBounds(type); | |
| 2162 } else { | |
| 2163 invokeType = type.instantiate(arguments.map((n) => n.type).toList()); | |
| 2164 } | |
| 2165 } | |
| 2166 } | |
| 2167 return invokeType; | |
| 2168 } | |
| 2169 | |
| 2170 /** | |
| 2171 * Given an invocation of the form 'm(a1, ..., an)', resolve 'm' to the | 2174 * Given an invocation of the form 'm(a1, ..., an)', resolve 'm' to the |
| 2172 * element being invoked. If the returned element is a method, then the method | 2175 * element being invoked. If the returned element is a method, then the method |
| 2173 * will be invoked. If the returned element is a getter, the getter will be | 2176 * will be invoked. If the returned element is a getter, the getter will be |
| 2174 * invoked without arguments and the result of that invocation will then be | 2177 * invoked without arguments and the result of that invocation will then be |
| 2175 * invoked with the arguments. The [methodName] is the name of the method | 2178 * invoked with the arguments. The [methodName] is the name of the method |
| 2176 * being invoked ('m'). | 2179 * being invoked ('m'). |
| 2177 */ | 2180 */ |
| 2178 Element _resolveInvokedElement(SimpleIdentifier methodName) { | 2181 Element _resolveInvokedElement(SimpleIdentifier methodName) { |
| 2179 // | 2182 // |
| 2180 // Look first in the lexical scope. | 2183 // Look first in the lexical scope. |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2664 | 2667 |
| 2665 @override | 2668 @override |
| 2666 Element get staticElement => null; | 2669 Element get staticElement => null; |
| 2667 | 2670 |
| 2668 @override | 2671 @override |
| 2669 accept(AstVisitor visitor) => null; | 2672 accept(AstVisitor visitor) => null; |
| 2670 | 2673 |
| 2671 @override | 2674 @override |
| 2672 void visitChildren(AstVisitor visitor) {} | 2675 void visitChildren(AstVisitor visitor) {} |
| 2673 } | 2676 } |
| OLD | NEW |