Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(634)

Side by Side Diff: pkg/analyzer/lib/src/generated/element_resolver.dart

Issue 1405143006: improve static type analysis for `await for` (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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.element_resolver; 5 library engine.resolver.element_resolver;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import 'ast.dart'; 9 import 'ast.dart';
10 import 'element.dart'; 10 import 'element.dart';
(...skipping 1555 matching lines...) Expand 10 before | Expand all | Expand 10 after
1566 /** 1566 /**
1567 * Look up the getter with the given [getterName] in the given [type]. Return 1567 * Look up the getter with the given [getterName] in the given [type]. Return
1568 * the element representing the getter that was found, or `null` if there is 1568 * the element representing the getter that was found, or `null` if there is
1569 * no getter with the given name. The [target] is the target of the 1569 * no getter with the given name. The [target] is the target of the
1570 * invocation, or `null` if there is no target. 1570 * invocation, or `null` if there is no target.
1571 */ 1571 */
1572 PropertyAccessorElement _lookUpGetter( 1572 PropertyAccessorElement _lookUpGetter(
1573 Expression target, DartType type, String getterName) { 1573 Expression target, DartType type, String getterName) {
1574 type = _resolveTypeParameter(type); 1574 type = _resolveTypeParameter(type);
1575 if (type is InterfaceType) { 1575 if (type is InterfaceType) {
1576 InterfaceType interfaceType = type; 1576 return type.lookUpInheritedGetter(getterName,
1577 PropertyAccessorElement accessor; 1577 library: _definingLibrary, thisType: target is! SuperExpression);
1578 if (target is SuperExpression) {
1579 accessor = interfaceType.lookUpGetterInSuperclass(
1580 getterName, _definingLibrary);
1581 } else {
1582 accessor = interfaceType.lookUpGetter(getterName, _definingLibrary);
1583 }
1584 if (accessor != null) {
1585 return accessor;
1586 }
1587 return _lookUpGetterInInterfaces(
1588 interfaceType, false, getterName, new HashSet<ClassElement>());
1589 } 1578 }
1590 return null; 1579 return null;
1591 } 1580 }
1592 1581
1593 /** 1582 /**
1594 * Look up the getter with the given [getterName] in the interfaces
1595 * implemented by the given [targetType], either directly or indirectly.
1596 * Return the element representing the getter that was found, or `null` if
1597 * there is no getter with the given name. The flag [includeTargetType] should
1598 * be `true` if the search should include the target type. The
1599 * [visitedInterfaces] is a set containing all of the interfaces that have
1600 * been examined, used to prevent infinite recursion and to optimize the
1601 * search.
1602 */
1603 PropertyAccessorElement _lookUpGetterInInterfaces(
1604 InterfaceType targetType,
1605 bool includeTargetType,
1606 String getterName,
1607 HashSet<ClassElement> visitedInterfaces) {
1608 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
1609 // specification (titled "Inheritance and Overriding" under "Interfaces")
1610 // describes a much more complex scheme for finding the inherited member.
1611 // We need to follow that scheme. The code below should cover the 80% case.
1612 ClassElement targetClass = targetType.element;
1613 if (visitedInterfaces.contains(targetClass)) {
1614 return null;
1615 }
1616 visitedInterfaces.add(targetClass);
1617 if (includeTargetType) {
1618 PropertyAccessorElement getter = targetType.getGetter(getterName);
1619 if (getter != null && getter.isAccessibleIn(_definingLibrary)) {
1620 return getter;
1621 }
1622 }
1623 for (InterfaceType interfaceType in targetType.interfaces) {
1624 PropertyAccessorElement getter = _lookUpGetterInInterfaces(
1625 interfaceType, true, getterName, visitedInterfaces);
1626 if (getter != null) {
1627 return getter;
1628 }
1629 }
1630 for (InterfaceType mixinType in targetType.mixins.reversed) {
1631 PropertyAccessorElement getter = _lookUpGetterInInterfaces(
1632 mixinType, true, getterName, visitedInterfaces);
1633 if (getter != null) {
1634 return getter;
1635 }
1636 }
1637 InterfaceType superclass = targetType.superclass;
1638 if (superclass == null) {
1639 return null;
1640 }
1641 return _lookUpGetterInInterfaces(
1642 superclass, true, getterName, visitedInterfaces);
1643 }
1644
1645 /**
1646 * Look up the method or getter with the given [memberName] in the given 1583 * Look up the method or getter with the given [memberName] in the given
1647 * [type]. Return the element representing the method or getter that was 1584 * [type]. Return the element representing the method or getter that was
1648 * found, or `null` if there is no method or getter with the given name. 1585 * found, or `null` if there is no method or getter with the given name.
1649 */ 1586 */
1650 ExecutableElement _lookupGetterOrMethod(DartType type, String memberName) { 1587 ExecutableElement _lookupGetterOrMethod(DartType type, String memberName) {
1651 type = _resolveTypeParameter(type); 1588 type = _resolveTypeParameter(type);
1652 if (type is InterfaceType) { 1589 if (type is InterfaceType) {
1653 InterfaceType interfaceType = type; 1590 return type.lookUpInheritedGetterOrMethod(memberName,
1654 ExecutableElement member = 1591 library: _definingLibrary);
1655 interfaceType.lookUpMethod(memberName, _definingLibrary);
1656 if (member != null) {
1657 return member;
1658 }
1659 member = interfaceType.lookUpGetter(memberName, _definingLibrary);
1660 if (member != null) {
1661 return member;
1662 }
1663 return _lookUpGetterOrMethodInInterfaces(
1664 interfaceType, false, memberName, new HashSet<ClassElement>());
1665 } 1592 }
1666 return null; 1593 return null;
1667 } 1594 }
1668 1595
1669 /** 1596 /**
1670 * Look up the method or getter with the given [memberName] in the interfaces
1671 * implemented by the given [targetType], either directly or indirectly.
1672 * Return the element representing the method or getter that was found, or
1673 * `null` if there is no method or getter with the given name. The flag
1674 * [includeTargetType] should be `true` if the search should include the
1675 * target type. The [visitedInterfaces] is a set containing all of the
1676 * interfaces that have been examined, used to prevent infinite recursion and
1677 * to optimize the search.
1678 */
1679 ExecutableElement _lookUpGetterOrMethodInInterfaces(
1680 InterfaceType targetType,
1681 bool includeTargetType,
1682 String memberName,
1683 HashSet<ClassElement> visitedInterfaces) {
1684 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
1685 // specification (titled "Inheritance and Overriding" under "Interfaces")
1686 // describes a much more complex scheme for finding the inherited member.
1687 // We need to follow that scheme. The code below should cover the 80% case.
1688 ClassElement targetClass = targetType.element;
1689 if (visitedInterfaces.contains(targetClass)) {
1690 return null;
1691 }
1692 visitedInterfaces.add(targetClass);
1693 if (includeTargetType) {
1694 ExecutableElement member = targetType.getMethod(memberName);
1695 if (member != null) {
1696 return member;
1697 }
1698 member = targetType.getGetter(memberName);
1699 if (member != null) {
1700 return member;
1701 }
1702 }
1703 for (InterfaceType interfaceType in targetType.interfaces) {
1704 ExecutableElement member = _lookUpGetterOrMethodInInterfaces(
1705 interfaceType, true, memberName, visitedInterfaces);
1706 if (member != null) {
1707 return member;
1708 }
1709 }
1710 for (InterfaceType mixinType in targetType.mixins.reversed) {
1711 ExecutableElement member = _lookUpGetterOrMethodInInterfaces(
1712 mixinType, true, memberName, visitedInterfaces);
1713 if (member != null) {
1714 return member;
1715 }
1716 }
1717 InterfaceType superclass = targetType.superclass;
1718 if (superclass == null) {
1719 return null;
1720 }
1721 return _lookUpGetterOrMethodInInterfaces(
1722 superclass, true, memberName, visitedInterfaces);
1723 }
1724
1725 /**
1726 * Look up the method with the given [methodName] in the given [type]. Return 1597 * Look up the method with the given [methodName] in the given [type]. Return
1727 * the element representing the method that was found, or `null` if there is 1598 * the element representing the method that was found, or `null` if there is
1728 * no method with the given name. The [target] is the target of the 1599 * no method with the given name. The [target] is the target of the
1729 * invocation, or `null` if there is no target. 1600 * invocation, or `null` if there is no target.
1730 */ 1601 */
1731 MethodElement _lookUpMethod( 1602 MethodElement _lookUpMethod(
1732 Expression target, DartType type, String methodName) { 1603 Expression target, DartType type, String methodName) {
1733 type = _resolveTypeParameter(type); 1604 type = _resolveTypeParameter(type);
1734 if (type is InterfaceType) { 1605 if (type is InterfaceType) {
1735 InterfaceType interfaceType = type; 1606 return type.lookUpInheritedMethod(methodName,
1736 MethodElement method; 1607 library: _definingLibrary, thisType: target is! SuperExpression);
1737 if (target is SuperExpression) {
1738 method = interfaceType.lookUpMethodInSuperclass(
1739 methodName, _definingLibrary);
1740 } else {
1741 method = interfaceType.lookUpMethod(methodName, _definingLibrary);
1742 }
1743 if (method != null) {
1744 return method;
1745 }
1746 return _lookUpMethodInInterfaces(
1747 interfaceType, false, methodName, new HashSet<ClassElement>());
1748 } 1608 }
1749 return null; 1609 return null;
1750 } 1610 }
1751 1611
1752 /** 1612 /**
1753 * Look up the method with the given [methodName] in the interfaces
1754 * implemented by the given [targetType], either directly or indirectly.
1755 * Return the element representing the method that was found, or `null` if
1756 * there is no method with the given name. The flag [includeTargetType] should
1757 * be `true` if the search should include the target type. The
1758 * [visitedInterfaces] is a set containing all of the interfaces that have
1759 * been examined, used to prevent infinite recursion and to optimize the
1760 * search.
1761 */
1762 MethodElement _lookUpMethodInInterfaces(
1763 InterfaceType targetType,
1764 bool includeTargetType,
1765 String methodName,
1766 HashSet<ClassElement> visitedInterfaces) {
1767 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
1768 // specification (titled "Inheritance and Overriding" under "Interfaces")
1769 // describes a much more complex scheme for finding the inherited member.
1770 // We need to follow that scheme. The code below should cover the 80% case.
1771 ClassElement targetClass = targetType.element;
1772 if (visitedInterfaces.contains(targetClass)) {
1773 return null;
1774 }
1775 visitedInterfaces.add(targetClass);
1776 if (includeTargetType) {
1777 MethodElement method = targetType.getMethod(methodName);
1778 if (method != null && method.isAccessibleIn(_definingLibrary)) {
1779 return method;
1780 }
1781 }
1782 for (InterfaceType interfaceType in targetType.interfaces) {
1783 MethodElement method = _lookUpMethodInInterfaces(
1784 interfaceType, true, methodName, visitedInterfaces);
1785 if (method != null) {
1786 return method;
1787 }
1788 }
1789 for (InterfaceType mixinType in targetType.mixins.reversed) {
1790 MethodElement method = _lookUpMethodInInterfaces(
1791 mixinType, true, methodName, visitedInterfaces);
1792 if (method != null) {
1793 return method;
1794 }
1795 }
1796 InterfaceType superclass = targetType.superclass;
1797 if (superclass == null) {
1798 return null;
1799 }
1800 return _lookUpMethodInInterfaces(
1801 superclass, true, methodName, visitedInterfaces);
1802 }
1803
1804 /**
1805 * Look up the setter with the given [setterName] in the given [type]. Return 1613 * Look up the setter with the given [setterName] in the given [type]. Return
1806 * the element representing the setter that was found, or `null` if there is 1614 * the element representing the setter that was found, or `null` if there is
1807 * no setter with the given name. The [target] is the target of the 1615 * no setter with the given name. The [target] is the target of the
1808 * invocation, or `null` if there is no target. 1616 * invocation, or `null` if there is no target.
1809 */ 1617 */
1810 PropertyAccessorElement _lookUpSetter( 1618 PropertyAccessorElement _lookUpSetter(
1811 Expression target, DartType type, String setterName) { 1619 Expression target, DartType type, String setterName) {
1812 type = _resolveTypeParameter(type); 1620 type = _resolveTypeParameter(type);
1813 if (type is InterfaceType) { 1621 if (type is InterfaceType) {
1814 InterfaceType interfaceType = type; 1622 return type.lookUpInheritedSetter(setterName,
1815 PropertyAccessorElement accessor; 1623 library: _definingLibrary, thisType: target is! SuperExpression);
1816 if (target is SuperExpression) {
1817 accessor = interfaceType.lookUpSetterInSuperclass(
1818 setterName, _definingLibrary);
1819 } else {
1820 accessor = interfaceType.lookUpSetter(setterName, _definingLibrary);
1821 }
1822 if (accessor != null) {
1823 return accessor;
1824 }
1825 return _lookUpSetterInInterfaces(
1826 interfaceType, false, setterName, new HashSet<ClassElement>());
1827 } 1624 }
1828 return null; 1625 return null;
1829 } 1626 }
1830 1627
1831 /** 1628 /**
1832 * Look up the setter with the given [setterName] in the interfaces
1833 * implemented by the given [targetType], either directly or indirectly.
1834 * Return the element representing the setter that was found, or `null` if
1835 * there is no setter with the given name. The [targetType] is the type in
1836 * which the setter might be defined. The flag [includeTargetType] should be
1837 * `true` if the search should include the target type. The
1838 * [visitedInterfaces] is a set containing all of the interfaces that have
1839 * been examined, used to prevent infinite recursion and to optimize the
1840 * search.
1841 */
1842 PropertyAccessorElement _lookUpSetterInInterfaces(
1843 InterfaceType targetType,
1844 bool includeTargetType,
1845 String setterName,
1846 HashSet<ClassElement> visitedInterfaces) {
1847 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
1848 // specification (titled "Inheritance and Overriding" under "Interfaces")
1849 // describes a much more complex scheme for finding the inherited member.
1850 // We need to follow that scheme. The code below should cover the 80% case.
1851 ClassElement targetClass = targetType.element;
1852 if (visitedInterfaces.contains(targetClass)) {
1853 return null;
1854 }
1855 visitedInterfaces.add(targetClass);
1856 if (includeTargetType) {
1857 PropertyAccessorElement setter = targetType.getSetter(setterName);
1858 if (setter != null && setter.isAccessibleIn(_definingLibrary)) {
1859 return setter;
1860 }
1861 }
1862 for (InterfaceType interfaceType in targetType.interfaces) {
1863 PropertyAccessorElement setter = _lookUpSetterInInterfaces(
1864 interfaceType, true, setterName, visitedInterfaces);
1865 if (setter != null) {
1866 return setter;
1867 }
1868 }
1869 for (InterfaceType mixinType in targetType.mixins.reversed) {
1870 PropertyAccessorElement setter = _lookUpSetterInInterfaces(
1871 mixinType, true, setterName, visitedInterfaces);
1872 if (setter != null) {
1873 return setter;
1874 }
1875 }
1876 InterfaceType superclass = targetType.superclass;
1877 if (superclass == null) {
1878 return null;
1879 }
1880 return _lookUpSetterInInterfaces(
1881 superclass, true, setterName, visitedInterfaces);
1882 }
1883
1884 /**
1885 * Given some class [element], this method uses [_subtypeManager] to find the 1629 * Given some class [element], this method uses [_subtypeManager] to find the
1886 * set of all subtypes; the subtypes are then searched for a member (method, 1630 * set of all subtypes; the subtypes are then searched for a member (method,
1887 * getter, or setter), that has the given [memberName]. The flag [asMethod] 1631 * getter, or setter), that has the given [memberName]. The flag [asMethod]
1888 * should be `true` if the methods should be searched for in the subtypes. The 1632 * should be `true` if the methods should be searched for in the subtypes. The
1889 * flag [asAccessor] should be `true` if the accessors (getters and setters) 1633 * flag [asAccessor] should be `true` if the accessors (getters and setters)
1890 * should be searched for in the subtypes. 1634 * should be searched for in the subtypes.
1891 */ 1635 */
1892 bool _memberFoundInSubclass( 1636 bool _memberFoundInSubclass(
1893 Element element, String memberName, bool asMethod, bool asAccessor) { 1637 Element element, String memberName, bool asMethod, bool asAccessor) {
1894 if (element is ClassElement) { 1638 if (element is ClassElement) {
(...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after
2823 2567
2824 @override 2568 @override
2825 Element get staticElement => null; 2569 Element get staticElement => null;
2826 2570
2827 @override 2571 @override
2828 accept(AstVisitor visitor) => null; 2572 accept(AstVisitor visitor) => null;
2829 2573
2830 @override 2574 @override
2831 void visitChildren(AstVisitor visitor) {} 2575 void visitChildren(AstVisitor visitor) {}
2832 } 2576 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/element.dart ('k') | pkg/analyzer/lib/src/generated/resolver.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698