| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 /** | 5 /** |
| 6 * This library is capable of producing linked summaries from unlinked | 6 * This library is capable of producing linked summaries from unlinked |
| 7 * ones (or prelinked ones). It functions by building a miniature | 7 * ones (or prelinked ones). It functions by building a miniature |
| 8 * element model to represent the contents of the summaries, and then | 8 * element model to represent the contents of the summaries, and then |
| 9 * scanning the element model to gather linked information and adding | 9 * scanning the element model to gather linked information and adding |
| 10 * it to the summary data structures. | 10 * it to the summary data structures. |
| (...skipping 1597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1608 final ClassElementForLink_Class enclosingClass; | 1608 final ClassElementForLink_Class enclosingClass; |
| 1609 | 1609 |
| 1610 /** | 1610 /** |
| 1611 * Return the compilation unit in which this executable appears. | 1611 * Return the compilation unit in which this executable appears. |
| 1612 */ | 1612 */ |
| 1613 final CompilationUnitElementForLink enclosingUnit; | 1613 final CompilationUnitElementForLink enclosingUnit; |
| 1614 | 1614 |
| 1615 ExecutableElementForLink( | 1615 ExecutableElementForLink( |
| 1616 this.enclosingUnit, this.enclosingClass, this._unlinkedExecutable); | 1616 this.enclosingUnit, this.enclosingClass, this._unlinkedExecutable); |
| 1617 | 1617 |
| 1618 /** |
| 1619 * If the executable element had an explicitly declared return type, return |
| 1620 * it. Otherwise return `null`. |
| 1621 */ |
| 1622 DartType get declaredReturnType { |
| 1623 if (_unlinkedExecutable.returnType == null) { |
| 1624 return null; |
| 1625 } else { |
| 1626 return _declaredReturnType ??= |
| 1627 enclosingUnit._resolveTypeRef(_unlinkedExecutable.returnType, this); |
| 1628 } |
| 1629 } |
| 1630 |
| 1618 @override | 1631 @override |
| 1619 String get displayName { | 1632 String get displayName { |
| 1620 if (_displayName == null) { | 1633 if (_displayName == null) { |
| 1621 _displayName = _unlinkedExecutable.name; | 1634 _displayName = _unlinkedExecutable.name; |
| 1622 if (_unlinkedExecutable.kind == UnlinkedExecutableKind.setter) { | 1635 if (_unlinkedExecutable.kind == UnlinkedExecutableKind.setter) { |
| 1623 _displayName = _displayName.substring(0, _displayName.length - 1); | 1636 _displayName = _displayName.substring(0, _displayName.length - 1); |
| 1624 } | 1637 } |
| 1625 } | 1638 } |
| 1626 return _displayName; | 1639 return _displayName; |
| 1627 } | 1640 } |
| 1628 | 1641 |
| 1629 @override | 1642 @override |
| 1630 Element get enclosingElement => enclosingClass ?? enclosingUnit; | 1643 Element get enclosingElement => enclosingClass ?? enclosingUnit; |
| 1631 | 1644 |
| 1632 @override | 1645 @override |
| 1633 TypeParameterizedElementForLink get enclosingTypeParameterContext => | 1646 TypeParameterizedElementForLink get enclosingTypeParameterContext => |
| 1634 enclosingClass; | 1647 enclosingClass; |
| 1635 | 1648 |
| 1636 @override | 1649 @override |
| 1637 bool get hasImplicitReturnType => _unlinkedExecutable.returnType == null; | 1650 bool get hasImplicitReturnType => _unlinkedExecutable.returnType == null; |
| 1638 | 1651 |
| 1652 /** |
| 1653 * Return the inferred return type of the executable element. Should only be |
| 1654 * called if no return type was explicitly declared. |
| 1655 */ |
| 1656 DartType get inferredReturnType { |
| 1657 // We should only try to infer a return type when none is explicitly |
| 1658 // declared. |
| 1659 assert(_unlinkedExecutable.returnType == null); |
| 1660 if (Linker._initializerTypeInferenceCycle != null && |
| 1661 Linker._initializerTypeInferenceCycle == |
| 1662 enclosingUnit.library.libraryCycleForLink) { |
| 1663 // We are currently computing the type of an initializer expression in the |
| 1664 // current library cycle, so type inference results should be ignored. |
| 1665 return _computeDefaultReturnType(); |
| 1666 } |
| 1667 if (_inferredReturnType == null) { |
| 1668 if (_unlinkedExecutable.kind == UnlinkedExecutableKind.constructor) { |
| 1669 // TODO(paulberry): implement. |
| 1670 throw new UnimplementedError(); |
| 1671 } else if (enclosingUnit.isInBuildUnit) { |
| 1672 _inferredReturnType = _computeDefaultReturnType(); |
| 1673 } else { |
| 1674 _inferredReturnType = enclosingUnit.getLinkedType( |
| 1675 _unlinkedExecutable.inferredReturnTypeSlot, this); |
| 1676 } |
| 1677 } |
| 1678 return _inferredReturnType; |
| 1679 } |
| 1680 |
| 1639 @override | 1681 @override |
| 1640 bool get isStatic => _unlinkedExecutable.isStatic; | 1682 bool get isStatic => _unlinkedExecutable.isStatic; |
| 1641 | 1683 |
| 1642 @override | 1684 @override |
| 1643 bool get isSynthetic => false; | 1685 bool get isSynthetic => false; |
| 1644 | 1686 |
| 1645 @override | 1687 @override |
| 1646 LibraryElementForLink get library => enclosingElement.library; | 1688 LibraryElementForLink get library => enclosingElement.library; |
| 1647 | 1689 |
| 1648 @override | 1690 @override |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1664 for (int i = 0; i < numParameters; i++) { | 1706 for (int i = 0; i < numParameters; i++) { |
| 1665 UnlinkedParam unlinkedParam = _unlinkedExecutable.parameters[i]; | 1707 UnlinkedParam unlinkedParam = _unlinkedExecutable.parameters[i]; |
| 1666 _parameters[i] = new ParameterElementForLink( | 1708 _parameters[i] = new ParameterElementForLink( |
| 1667 this, unlinkedParam, this, enclosingUnit, i); | 1709 this, unlinkedParam, this, enclosingUnit, i); |
| 1668 } | 1710 } |
| 1669 } | 1711 } |
| 1670 return _parameters; | 1712 return _parameters; |
| 1671 } | 1713 } |
| 1672 | 1714 |
| 1673 @override | 1715 @override |
| 1674 DartType get returnType { | 1716 DartType get returnType => declaredReturnType ?? inferredReturnType; |
| 1675 if (_inferredReturnType != null) { | |
| 1676 return _inferredReturnType; | |
| 1677 } else if (_declaredReturnType == null) { | |
| 1678 if (_unlinkedExecutable.returnType == null) { | |
| 1679 if (_unlinkedExecutable.kind == UnlinkedExecutableKind.constructor) { | |
| 1680 // TODO(paulberry): implement. | |
| 1681 throw new UnimplementedError(); | |
| 1682 } else if (!enclosingUnit.isInBuildUnit) { | |
| 1683 _inferredReturnType = enclosingUnit.getLinkedType( | |
| 1684 _unlinkedExecutable.inferredReturnTypeSlot, this); | |
| 1685 return _inferredReturnType; | |
| 1686 } else if (_unlinkedExecutable.kind == UnlinkedExecutableKind.setter && | |
| 1687 library._linker.strongMode) { | |
| 1688 // In strong mode, setters without an explicit return type are | |
| 1689 // considered to return `void`. | |
| 1690 _declaredReturnType = VoidTypeImpl.instance; | |
| 1691 } else { | |
| 1692 _declaredReturnType = DynamicTypeImpl.instance; | |
| 1693 } | |
| 1694 } else { | |
| 1695 _declaredReturnType = | |
| 1696 enclosingUnit._resolveTypeRef(_unlinkedExecutable.returnType, this); | |
| 1697 } | |
| 1698 } | |
| 1699 return _declaredReturnType; | |
| 1700 } | |
| 1701 | 1717 |
| 1702 @override | 1718 @override |
| 1703 void set returnType(DartType inferredType) { | 1719 void set returnType(DartType inferredType) { |
| 1704 assert(_inferredReturnType == null); | 1720 assert(_inferredReturnType == null); |
| 1705 _inferredReturnType = inferredType; | 1721 _inferredReturnType = inferredType; |
| 1706 } | 1722 } |
| 1707 | 1723 |
| 1708 @override | 1724 @override |
| 1709 FunctionTypeImpl get type => _type ??= new FunctionTypeImpl(this); | 1725 FunctionTypeImpl get type => _type ??= new FunctionTypeImpl(this); |
| 1710 | 1726 |
| 1711 @override | 1727 @override |
| 1712 List<UnlinkedTypeParam> get _unlinkedTypeParams => | 1728 List<UnlinkedTypeParam> get _unlinkedTypeParams => |
| 1713 _unlinkedExecutable.typeParameters; | 1729 _unlinkedExecutable.typeParameters; |
| 1714 | 1730 |
| 1715 @override | 1731 @override |
| 1716 bool isAccessibleIn(LibraryElement library) => | 1732 bool isAccessibleIn(LibraryElement library) => |
| 1717 !Identifier.isPrivateName(name) || identical(this.library, library); | 1733 !Identifier.isPrivateName(name) || identical(this.library, library); |
| 1718 | 1734 |
| 1719 /** | 1735 /** |
| 1720 * Store the results of type inference for this method in [compilationUnit]. | 1736 * Store the results of type inference for this method in [compilationUnit]. |
| 1721 */ | 1737 */ |
| 1722 void link(CompilationUnitElementInBuildUnit compilationUnit) { | 1738 void link(CompilationUnitElementInBuildUnit compilationUnit) { |
| 1723 compilationUnit._storeLinkedType( | 1739 if (_unlinkedExecutable.returnType == null) { |
| 1724 _unlinkedExecutable.inferredReturnTypeSlot, returnType, this); | 1740 compilationUnit._storeLinkedType( |
| 1741 _unlinkedExecutable.inferredReturnTypeSlot, inferredReturnType, this); |
| 1742 } |
| 1725 for (ParameterElementForLink parameterElement in parameters) { | 1743 for (ParameterElementForLink parameterElement in parameters) { |
| 1726 parameterElement.link(compilationUnit); | 1744 parameterElement.link(compilationUnit); |
| 1727 } | 1745 } |
| 1728 } | 1746 } |
| 1747 |
| 1748 /** |
| 1749 * Compute the default return type for this type of executable element (if no |
| 1750 * return type is declared and strong mode type inference cannot infer a |
| 1751 * better return type). |
| 1752 */ |
| 1753 DartType _computeDefaultReturnType() { |
| 1754 if (_unlinkedExecutable.kind == UnlinkedExecutableKind.setter && |
| 1755 library._linker.strongMode) { |
| 1756 // In strong mode, setters without an explicit return type are |
| 1757 // considered to return `void`. |
| 1758 return VoidTypeImpl.instance; |
| 1759 } else { |
| 1760 return DynamicTypeImpl.instance; |
| 1761 } |
| 1762 } |
| 1729 } | 1763 } |
| 1730 | 1764 |
| 1731 class ExprTypeComputer { | 1765 class ExprTypeComputer { |
| 1732 VariableElementForLink variable; | 1766 VariableElementForLink variable; |
| 1733 CompilationUnitElementForLink unit; | 1767 CompilationUnitElementForLink unit; |
| 1734 LibraryElementForLink library; | 1768 LibraryElementForLink library; |
| 1735 Linker linker; | 1769 Linker linker; |
| 1736 TypeProvider typeProvider; | 1770 TypeProvider typeProvider; |
| 1737 UnlinkedConst unlinkedConst; | 1771 UnlinkedConst unlinkedConst; |
| 1738 | 1772 |
| (...skipping 1243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2982 return dependencies; | 3016 return dependencies; |
| 2983 } | 3017 } |
| 2984 } | 3018 } |
| 2985 | 3019 |
| 2986 /** | 3020 /** |
| 2987 * Instances of [Linker] contain the necessary information to link | 3021 * Instances of [Linker] contain the necessary information to link |
| 2988 * together a single build unit. | 3022 * together a single build unit. |
| 2989 */ | 3023 */ |
| 2990 class Linker { | 3024 class Linker { |
| 2991 /** | 3025 /** |
| 3026 * During linking, if type inference is currently being performed on the |
| 3027 * initializer of a static or instance variable, the library cycle in |
| 3028 * which inference is being performed. Otherwise, `null`. |
| 3029 * |
| 3030 * This allows us to suppress instance member type inference results from a |
| 3031 * library cycle while doing inference on the right hand sides of static and |
| 3032 * instance variables in that same cycle. |
| 3033 */ |
| 3034 static LibraryCycleForLink _initializerTypeInferenceCycle; |
| 3035 |
| 3036 /** |
| 2992 * Callback to ask the client for a [LinkedLibrary] for a | 3037 * Callback to ask the client for a [LinkedLibrary] for a |
| 2993 * dependency. | 3038 * dependency. |
| 2994 */ | 3039 */ |
| 2995 final GetDependencyCallback getDependency; | 3040 final GetDependencyCallback getDependency; |
| 2996 | 3041 |
| 2997 /** | 3042 /** |
| 2998 * Callback to ask the client for an [UnlinkedUnit]. | 3043 * Callback to ask the client for an [UnlinkedUnit]. |
| 2999 */ | 3044 */ |
| 3000 final GetUnitCallback getUnit; | 3045 final GetUnitCallback getUnit; |
| 3001 | 3046 |
| (...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3741 */ | 3786 */ |
| 3742 DartType _inferredType; | 3787 DartType _inferredType; |
| 3743 | 3788 |
| 3744 TypeInferenceNode(this.variableElement); | 3789 TypeInferenceNode(this.variableElement); |
| 3745 | 3790 |
| 3746 /** | 3791 /** |
| 3747 * Infer a type for this node if necessary, and return it. | 3792 * Infer a type for this node if necessary, and return it. |
| 3748 */ | 3793 */ |
| 3749 DartType get inferredType { | 3794 DartType get inferredType { |
| 3750 if (_inferredType == null) { | 3795 if (_inferredType == null) { |
| 3796 Linker._initializerTypeInferenceCycle = |
| 3797 variableElement.compilationUnit.library.libraryCycleForLink; |
| 3751 new TypeInferenceDependencyWalker().walk(this); | 3798 new TypeInferenceDependencyWalker().walk(this); |
| 3752 assert(_inferredType != null); | 3799 assert(_inferredType != null); |
| 3800 Linker._initializerTypeInferenceCycle = null; |
| 3753 } | 3801 } |
| 3754 return _inferredType; | 3802 return _inferredType; |
| 3755 } | 3803 } |
| 3756 | 3804 |
| 3757 @override | 3805 @override |
| 3758 bool get isEvaluated => _inferredType != null; | 3806 bool get isEvaluated => _inferredType != null; |
| 3759 | 3807 |
| 3760 /** | 3808 /** |
| 3761 * Collect the type inference dependencies in [unlinkedConst] (which should be | 3809 * Collect the type inference dependencies in [unlinkedConst] (which should be |
| 3762 * interpreted relative to [compilationUnit]) and store them in | 3810 * interpreted relative to [compilationUnit]) and store them in |
| (...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4277 if (type is InterfaceType) { | 4325 if (type is InterfaceType) { |
| 4278 Element result = type.lookUpGetter(name, compilationUnit.library); | 4326 Element result = type.lookUpGetter(name, compilationUnit.library); |
| 4279 result ??= type.lookUpMethod(name, compilationUnit.library); | 4327 result ??= type.lookUpMethod(name, compilationUnit.library); |
| 4280 return result; | 4328 return result; |
| 4281 } | 4329 } |
| 4282 } | 4330 } |
| 4283 // TODO(scheglov): implement for propagated types | 4331 // TODO(scheglov): implement for propagated types |
| 4284 return null; | 4332 return null; |
| 4285 } | 4333 } |
| 4286 } | 4334 } |
| OLD | NEW |