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

Side by Side Diff: pkg/analyzer/lib/src/summary/link.dart

Issue 1902103002: Clean up handling of declared/inferred types in ExecutableElementForLink (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 months 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
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/resynthesize_ast_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/resynthesize_ast_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698