| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 summary_resynthesizer; | 5 library summary_resynthesizer; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/token.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
| (...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET)); | 541 TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET)); |
| 542 } | 542 } |
| 543 } | 543 } |
| 544 | 544 |
| 545 /** | 545 /** |
| 546 * Convert the next reference to the [DartType] and return the AST | 546 * Convert the next reference to the [DartType] and return the AST |
| 547 * corresponding to this type. | 547 * corresponding to this type. |
| 548 */ | 548 */ |
| 549 TypeName _newTypeName() { | 549 TypeName _newTypeName() { |
| 550 EntityRef typeRef = uc.references[refPtr++]; | 550 EntityRef typeRef = uc.references[refPtr++]; |
| 551 DartType type = resynthesizer.buildType(typeRef); | 551 DartType type = resynthesizer.buildType( |
| 552 typeRef, resynthesizer._currentTypeParameterizedElement); |
| 552 return _buildTypeAst(type); | 553 return _buildTypeAst(type); |
| 553 } | 554 } |
| 554 | 555 |
| 555 Expression _pop() => stack.removeLast(); | 556 Expression _pop() => stack.removeLast(); |
| 556 | 557 |
| 557 void _push(Expression expr) { | 558 void _push(Expression expr) { |
| 558 stack.add(expr); | 559 stack.add(expr); |
| 559 } | 560 } |
| 560 | 561 |
| 561 void _pushBinary(TokenType operator) { | 562 void _pushBinary(TokenType operator) { |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 694 List<Expression> _removeTopItems(int count) { | 695 List<Expression> _removeTopItems(int count) { |
| 695 int start = stack.length - count; | 696 int start = stack.length - count; |
| 696 int end = stack.length; | 697 int end = stack.length; |
| 697 List<Expression> items = stack.getRange(start, end).toList(); | 698 List<Expression> items = stack.getRange(start, end).toList(); |
| 698 stack.removeRange(start, end); | 699 stack.removeRange(start, end); |
| 699 return items; | 700 return items; |
| 700 } | 701 } |
| 701 } | 702 } |
| 702 | 703 |
| 703 /** | 704 /** |
| 705 * Temporary [TypeParameterizedElementMixin] implementation. |
| 706 * |
| 707 * TODO(scheglov) remove after moving resynthesize logic to Impl. |
| 708 */ |
| 709 class _CurrentTypeParameterizedElement |
| 710 implements TypeParameterizedElementMixin { |
| 711 final _UnitResynthesizer unitResynthesizer; |
| 712 |
| 713 _CurrentTypeParameterizedElement(this.unitResynthesizer); |
| 714 |
| 715 @override |
| 716 TypeParameterType getTypeParameterType(int index) { |
| 717 return unitResynthesizer.getTypeParameterFromScope(index); |
| 718 } |
| 719 |
| 720 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
| 721 } |
| 722 |
| 723 /** |
| 704 * A class element that has been resynthesized from a summary. The actual | 724 * A class element that has been resynthesized from a summary. The actual |
| 705 * element won't be constructed until it is requested. But properties | 725 * element won't be constructed until it is requested. But properties |
| 706 * [context], [displayName], [enclosingElement] and [name] can be used without | 726 * [context], [displayName], [enclosingElement] and [name] can be used without |
| 707 * creating the actual element. This allows to put these elements into | 727 * creating the actual element. This allows to put these elements into |
| 708 * namespaces without creating actual elements until they are really needed. | 728 * namespaces without creating actual elements until they are really needed. |
| 709 */ | 729 */ |
| 710 class _DeferredClassElement extends ClassElementHandle { | 730 class _DeferredClassElement extends ClassElementHandle { |
| 711 final _UnitResynthesizer unitResynthesizer; | 731 final _UnitResynthesizer unitResynthesizer; |
| 712 final CompilationUnitElement unitElement; | 732 final CompilationUnitElement unitElement; |
| 713 final UnlinkedClass serializedClass; | 733 final UnlinkedClass serializedClass; |
| (...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1524 if (numTypeArguments != 0) { | 1544 if (numTypeArguments != 0) { |
| 1525 typeArguments = <DartType>[]; | 1545 typeArguments = <DartType>[]; |
| 1526 for (int i = 0; i < numTypeArguments; i++) { | 1546 for (int i = 0; i < numTypeArguments; i++) { |
| 1527 typeArguments.add(getTypeArgument(i)); | 1547 typeArguments.add(getTypeArgument(i)); |
| 1528 } | 1548 } |
| 1529 } | 1549 } |
| 1530 return typeArguments; | 1550 return typeArguments; |
| 1531 } | 1551 } |
| 1532 } | 1552 } |
| 1533 | 1553 |
| 1554 class _ResynthesizerContext implements ResynthesizerContext { |
| 1555 final _UnitResynthesizer _unitResynthesizer; |
| 1556 |
| 1557 _ResynthesizerContext(this._unitResynthesizer); |
| 1558 |
| 1559 @override |
| 1560 DartType resolveTypeRef( |
| 1561 EntityRef type, TypeParameterizedElementMixin typeParameterContext, |
| 1562 {bool defaultVoid: false, bool instantiateToBoundsAllowed: true}) { |
| 1563 return _unitResynthesizer.buildType(type, typeParameterContext, |
| 1564 defaultVoid: defaultVoid, |
| 1565 instantiateToBoundsAllowed: instantiateToBoundsAllowed); |
| 1566 } |
| 1567 } |
| 1568 |
| 1534 /** | 1569 /** |
| 1535 * An instance of [_UnitResynthesizer] is responsible for resynthesizing the | 1570 * An instance of [_UnitResynthesizer] is responsible for resynthesizing the |
| 1536 * elements in a single unit from that unit's summary. | 1571 * elements in a single unit from that unit's summary. |
| 1537 */ | 1572 */ |
| 1538 class _UnitResynthesizer { | 1573 class _UnitResynthesizer { |
| 1539 /** | 1574 /** |
| 1540 * The [_LibraryResynthesizer] which is being used to obtain summaries. | 1575 * The [_LibraryResynthesizer] which is being used to obtain summaries. |
| 1541 */ | 1576 */ |
| 1542 final _LibraryResynthesizer libraryResynthesizer; | 1577 final _LibraryResynthesizer libraryResynthesizer; |
| 1543 | 1578 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1618 int numLinkedReferences; | 1653 int numLinkedReferences; |
| 1619 int numUnlinkedReferences; | 1654 int numUnlinkedReferences; |
| 1620 | 1655 |
| 1621 /** | 1656 /** |
| 1622 * List of [_ReferenceInfo] objects describing the references in the current | 1657 * List of [_ReferenceInfo] objects describing the references in the current |
| 1623 * compilation unit. This list is works as a lazily filled cache, use | 1658 * compilation unit. This list is works as a lazily filled cache, use |
| 1624 * [getReferenceInfo] to get the [_ReferenceInfo] for an index. | 1659 * [getReferenceInfo] to get the [_ReferenceInfo] for an index. |
| 1625 */ | 1660 */ |
| 1626 List<_ReferenceInfo> referenceInfos; | 1661 List<_ReferenceInfo> referenceInfos; |
| 1627 | 1662 |
| 1663 /** |
| 1664 * The [ResynthesizerContext] for this resynthesize session. |
| 1665 */ |
| 1666 ResynthesizerContext _resynthesizerContext; |
| 1667 |
| 1668 /** |
| 1669 * TODO(scheglov) clean up after moving resynthesize logic to Impl. |
| 1670 */ |
| 1671 TypeParameterizedElementMixin _currentTypeParameterizedElement; |
| 1672 |
| 1628 _UnitResynthesizer(this.libraryResynthesizer, this.unlinkedUnit, | 1673 _UnitResynthesizer(this.libraryResynthesizer, this.unlinkedUnit, |
| 1629 this.linkedUnit, this.unit) { | 1674 this.linkedUnit, this.unit) { |
| 1630 for (EntityRef t in linkedUnit.types) { | 1675 for (EntityRef t in linkedUnit.types) { |
| 1631 linkedTypeMap[t.slot] = t; | 1676 linkedTypeMap[t.slot] = t; |
| 1632 } | 1677 } |
| 1633 constCycles = linkedUnit.constCycles.toSet(); | 1678 constCycles = linkedUnit.constCycles.toSet(); |
| 1634 numLinkedReferences = linkedUnit.references.length; | 1679 numLinkedReferences = linkedUnit.references.length; |
| 1635 numUnlinkedReferences = unlinkedUnit.references.length; | 1680 numUnlinkedReferences = unlinkedUnit.references.length; |
| 1636 referenceInfos = new List<_ReferenceInfo>(numLinkedReferences); | 1681 referenceInfos = new List<_ReferenceInfo>(numLinkedReferences); |
| 1682 _resynthesizerContext = new _ResynthesizerContext(this); |
| 1683 _currentTypeParameterizedElement = |
| 1684 new _CurrentTypeParameterizedElement(this); |
| 1637 } | 1685 } |
| 1638 | 1686 |
| 1639 SummaryResynthesizer get summaryResynthesizer => | 1687 SummaryResynthesizer get summaryResynthesizer => |
| 1640 libraryResynthesizer.summaryResynthesizer; | 1688 libraryResynthesizer.summaryResynthesizer; |
| 1641 | 1689 |
| 1642 TypeProvider get typeProvider => summaryResynthesizer.typeProvider; | 1690 TypeProvider get typeProvider => summaryResynthesizer.typeProvider; |
| 1643 | 1691 |
| 1644 /** | 1692 /** |
| 1645 * Build the annotations for the given [element]. | 1693 * Build the annotations for the given [element]. |
| 1646 */ | 1694 */ |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1746 assert(currentTypeParameters.isEmpty); | 1794 assert(currentTypeParameters.isEmpty); |
| 1747 } | 1795 } |
| 1748 | 1796 |
| 1749 /** | 1797 /** |
| 1750 * Resynthesize a [ClassElementImpl]. If [handle] is not `null`, then | 1798 * Resynthesize a [ClassElementImpl]. If [handle] is not `null`, then |
| 1751 * executables are not resynthesized, and [InterfaceTypeImpl] is created | 1799 * executables are not resynthesized, and [InterfaceTypeImpl] is created |
| 1752 * around the [handle], so that executables are resynthesized lazily. | 1800 * around the [handle], so that executables are resynthesized lazily. |
| 1753 */ | 1801 */ |
| 1754 ClassElementImpl buildClassImpl( | 1802 ClassElementImpl buildClassImpl( |
| 1755 UnlinkedClass serializedClass, ClassElementHandle handle) { | 1803 UnlinkedClass serializedClass, ClassElementHandle handle) { |
| 1756 ClassElementImpl classElement = | 1804 ClassElementImpl classElement = new ClassElementImpl.forSerialized( |
| 1757 new ClassElementImpl.forSerialized(serializedClass); | 1805 _resynthesizerContext, serializedClass); |
| 1758 classElement.hasBeenInferred = summaryResynthesizer.strongMode; | 1806 classElement.hasBeenInferred = summaryResynthesizer.strongMode; |
| 1759 classElement.typeParameters = | |
| 1760 buildTypeParameters(serializedClass.typeParameters); | |
| 1761 classElement.mixinApplication = serializedClass.isMixinApplication; | 1807 classElement.mixinApplication = serializedClass.isMixinApplication; |
| 1762 InterfaceTypeImpl correspondingType = | 1808 InterfaceTypeImpl correspondingType = |
| 1763 new InterfaceTypeImpl(handle ?? classElement); | 1809 new InterfaceTypeImpl(handle ?? classElement); |
| 1764 if (serializedClass.supertype != null) { | 1810 if (serializedClass.supertype != null) { |
| 1765 classElement.supertype = buildType(serializedClass.supertype); | 1811 classElement.supertype = |
| 1812 buildType(serializedClass.supertype, classElement); |
| 1766 } else if (!libraryResynthesizer.isCoreLibrary) { | 1813 } else if (!libraryResynthesizer.isCoreLibrary) { |
| 1767 classElement.supertype = typeProvider.objectType; | 1814 classElement.supertype = typeProvider.objectType; |
| 1768 } | 1815 } |
| 1769 classElement.interfaces = | 1816 classElement.interfaces = serializedClass.interfaces |
| 1770 serializedClass.interfaces.map(buildType).toList(); | 1817 .map((EntityRef t) => buildType(t, classElement)) |
| 1771 classElement.mixins = serializedClass.mixins.map(buildType).toList(); | 1818 .toList(); |
| 1772 correspondingType.typeArguments = getCurrentTypeArguments(); | 1819 classElement.mixins = serializedClass.mixins |
| 1820 .map((EntityRef t) => buildType(t, classElement)) |
| 1821 .toList(); |
| 1822 // TODO(scheglov) move to ClassElementImpl |
| 1823 correspondingType.typeArguments = classElement.typeParameterTypes; |
| 1773 classElement.type = correspondingType; | 1824 classElement.type = correspondingType; |
| 1774 buildAnnotations(classElement, serializedClass.annotations); | 1825 buildAnnotations(classElement, serializedClass.annotations); |
| 1775 currentTypeParameters.removeLast(); | |
| 1776 assert(currentTypeParameters.isEmpty); | 1826 assert(currentTypeParameters.isEmpty); |
| 1777 // TODO(scheglov) Somehow Observatory shows too much time spent here | 1827 // TODO(scheglov) Somehow Observatory shows too much time spent here |
| 1778 // during DDC run on the large codebase. I would expect only Object here. | 1828 // during DDC run on the large codebase. I would expect only Object here. |
| 1779 if (handle == null) { | 1829 if (handle == null) { |
| 1780 buildClassExecutables(classElement, serializedClass); | 1830 buildClassExecutables(classElement, serializedClass); |
| 1781 } | 1831 } |
| 1782 fields = null; | 1832 fields = null; |
| 1783 constructors = null; | 1833 constructors = null; |
| 1784 return classElement; | 1834 return classElement; |
| 1785 } | 1835 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1812 } | 1862 } |
| 1813 | 1863 |
| 1814 /** | 1864 /** |
| 1815 * Resynthesize a [ConstructorElement] and place it in the given [holder]. | 1865 * Resynthesize a [ConstructorElement] and place it in the given [holder]. |
| 1816 * [classType] is the type of the class for which this element is a | 1866 * [classType] is the type of the class for which this element is a |
| 1817 * constructor. | 1867 * constructor. |
| 1818 */ | 1868 */ |
| 1819 void buildConstructor(UnlinkedExecutable serializedExecutable, | 1869 void buildConstructor(UnlinkedExecutable serializedExecutable, |
| 1820 ElementHolder holder, InterfaceType classType) { | 1870 ElementHolder holder, InterfaceType classType) { |
| 1821 assert(serializedExecutable.kind == UnlinkedExecutableKind.constructor); | 1871 assert(serializedExecutable.kind == UnlinkedExecutableKind.constructor); |
| 1822 currentConstructor = | 1872 currentConstructor = new ConstructorElementImpl.forSerialized( |
| 1823 new ConstructorElementImpl.forSerialized(serializedExecutable); | 1873 _resynthesizerContext, serializedExecutable); |
| 1824 currentConstructor.isCycleFree = serializedExecutable.isConst && | 1874 currentConstructor.isCycleFree = serializedExecutable.isConst && |
| 1825 !constCycles.contains(serializedExecutable.constCycleSlot); | 1875 !constCycles.contains(serializedExecutable.constCycleSlot); |
| 1826 if (serializedExecutable.name.isEmpty) { | 1876 if (serializedExecutable.name.isEmpty) { |
| 1827 currentConstructor.nameEnd = | 1877 currentConstructor.nameEnd = |
| 1828 serializedExecutable.nameOffset + classType.name.length; | 1878 serializedExecutable.nameOffset + classType.name.length; |
| 1829 } else { | 1879 } else { |
| 1830 currentConstructor.nameEnd = serializedExecutable.nameEnd; | 1880 currentConstructor.nameEnd = serializedExecutable.nameEnd; |
| 1831 currentConstructor.periodOffset = serializedExecutable.periodOffset; | 1881 currentConstructor.periodOffset = serializedExecutable.periodOffset; |
| 1832 } | 1882 } |
| 1833 constructors[serializedExecutable.name] = currentConstructor; | 1883 constructors[serializedExecutable.name] = currentConstructor; |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1984 UnlinkedExecutableKind kind = serializedExecutable.kind; | 2034 UnlinkedExecutableKind kind = serializedExecutable.kind; |
| 1985 String name = serializedExecutable.name; | 2035 String name = serializedExecutable.name; |
| 1986 if (kind == UnlinkedExecutableKind.setter) { | 2036 if (kind == UnlinkedExecutableKind.setter) { |
| 1987 assert(name.endsWith('=')); | 2037 assert(name.endsWith('=')); |
| 1988 name = name.substring(0, name.length - 1); | 2038 name = name.substring(0, name.length - 1); |
| 1989 } | 2039 } |
| 1990 switch (kind) { | 2040 switch (kind) { |
| 1991 case UnlinkedExecutableKind.functionOrMethod: | 2041 case UnlinkedExecutableKind.functionOrMethod: |
| 1992 if (isTopLevel) { | 2042 if (isTopLevel) { |
| 1993 FunctionElementImpl executableElement = | 2043 FunctionElementImpl executableElement = |
| 1994 new FunctionElementImpl.forSerialized(serializedExecutable); | 2044 new FunctionElementImpl.forSerialized( |
| 2045 _resynthesizerContext, serializedExecutable); |
| 1995 buildExecutableCommonParts(executableElement, serializedExecutable); | 2046 buildExecutableCommonParts(executableElement, serializedExecutable); |
| 1996 holder.addFunction(executableElement); | 2047 holder.addFunction(executableElement); |
| 1997 } else { | 2048 } else { |
| 1998 MethodElementImpl executableElement = | 2049 MethodElementImpl executableElement = |
| 1999 new MethodElementImpl.forSerialized(serializedExecutable); | 2050 new MethodElementImpl.forSerialized( |
| 2051 _resynthesizerContext, serializedExecutable); |
| 2000 buildExecutableCommonParts(executableElement, serializedExecutable); | 2052 buildExecutableCommonParts(executableElement, serializedExecutable); |
| 2001 holder.addMethod(executableElement); | 2053 holder.addMethod(executableElement); |
| 2002 } | 2054 } |
| 2003 break; | 2055 break; |
| 2004 case UnlinkedExecutableKind.getter: | 2056 case UnlinkedExecutableKind.getter: |
| 2005 case UnlinkedExecutableKind.setter: | 2057 case UnlinkedExecutableKind.setter: |
| 2006 PropertyAccessorElementImpl executableElement = | 2058 PropertyAccessorElementImpl executableElement = |
| 2007 new PropertyAccessorElementImpl.forSerialized(serializedExecutable); | 2059 new PropertyAccessorElementImpl.forSerialized( |
| 2060 _resynthesizerContext, serializedExecutable); |
| 2008 buildExecutableCommonParts(executableElement, serializedExecutable); | 2061 buildExecutableCommonParts(executableElement, serializedExecutable); |
| 2009 DartType type; | 2062 DartType type; |
| 2010 if (kind == UnlinkedExecutableKind.getter) { | 2063 if (kind == UnlinkedExecutableKind.getter) { |
| 2011 type = executableElement.returnType; | 2064 type = executableElement.returnType; |
| 2012 } else { | 2065 } else { |
| 2013 type = executableElement.parameters[0].type; | 2066 type = executableElement.parameters[0].type; |
| 2014 } | 2067 } |
| 2015 holder.addAccessor(executableElement); | 2068 holder.addAccessor(executableElement); |
| 2016 PropertyInducingElementImpl implicitVariable; | 2069 PropertyInducingElementImpl implicitVariable; |
| 2017 if (isTopLevel) { | 2070 if (isTopLevel) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2045 executableElement.typeParameters = | 2098 executableElement.typeParameters = |
| 2046 buildTypeParameters(serializedExecutable.typeParameters); | 2099 buildTypeParameters(serializedExecutable.typeParameters); |
| 2047 executableElement.parameters = | 2100 executableElement.parameters = |
| 2048 serializedExecutable.parameters.map(buildParameter).toList(); | 2101 serializedExecutable.parameters.map(buildParameter).toList(); |
| 2049 if (serializedExecutable.kind == UnlinkedExecutableKind.constructor) { | 2102 if (serializedExecutable.kind == UnlinkedExecutableKind.constructor) { |
| 2050 // Caller handles setting the return type. | 2103 // Caller handles setting the return type. |
| 2051 assert(serializedExecutable.returnType == null); | 2104 assert(serializedExecutable.returnType == null); |
| 2052 } else { | 2105 } else { |
| 2053 bool isSetter = | 2106 bool isSetter = |
| 2054 serializedExecutable.kind == UnlinkedExecutableKind.setter; | 2107 serializedExecutable.kind == UnlinkedExecutableKind.setter; |
| 2055 executableElement.returnType = | 2108 executableElement.returnType = buildLinkedType( |
| 2056 buildLinkedType(serializedExecutable.inferredReturnTypeSlot) ?? | 2109 serializedExecutable.inferredReturnTypeSlot, |
| 2057 buildType(serializedExecutable.returnType, | 2110 _currentTypeParameterizedElement) ?? |
| 2058 defaultVoid: isSetter && summaryResynthesizer.strongMode); | 2111 buildType( |
| 2112 serializedExecutable.returnType, _currentTypeParameterizedElement, |
| 2113 defaultVoid: isSetter && summaryResynthesizer.strongMode); |
| 2059 executableElement.hasImplicitReturnType = | 2114 executableElement.hasImplicitReturnType = |
| 2060 serializedExecutable.returnType == null; | 2115 serializedExecutable.returnType == null; |
| 2061 } | 2116 } |
| 2062 executableElement.type = new FunctionTypeImpl.elementWithNameAndArgs( | 2117 executableElement.type = new FunctionTypeImpl.elementWithNameAndArgs( |
| 2063 executableElement, null, getCurrentTypeArguments(skipLevels: 1), false); | 2118 executableElement, null, getCurrentTypeArguments(skipLevels: 1), false); |
| 2064 buildAnnotations(executableElement, serializedExecutable.annotations); | 2119 buildAnnotations(executableElement, serializedExecutable.annotations); |
| 2065 executableElement.functions = | 2120 executableElement.functions = |
| 2066 serializedExecutable.localFunctions.map(buildLocalFunction).toList(); | 2121 serializedExecutable.localFunctions.map(buildLocalFunction).toList(); |
| 2067 executableElement.labels = | 2122 executableElement.labels = |
| 2068 serializedExecutable.localLabels.map(buildLocalLabel).toList(); | 2123 serializedExecutable.localLabels.map(buildLocalLabel).toList(); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2148 // TODO(paulberry): what if the getter and setter have a type mismatch? | 2203 // TODO(paulberry): what if the getter and setter have a type mismatch? |
| 2149 variable.final2 = false; | 2204 variable.final2 = false; |
| 2150 return variable; | 2205 return variable; |
| 2151 } | 2206 } |
| 2152 } | 2207 } |
| 2153 | 2208 |
| 2154 /** | 2209 /** |
| 2155 * Build the appropriate [DartType] object corresponding to a slot id in the | 2210 * Build the appropriate [DartType] object corresponding to a slot id in the |
| 2156 * [LinkedUnit.types] table. | 2211 * [LinkedUnit.types] table. |
| 2157 */ | 2212 */ |
| 2158 DartType buildLinkedType(int slot) { | 2213 DartType buildLinkedType( |
| 2214 int slot, TypeParameterizedElementMixin typeParameterContext) { |
| 2159 if (slot == 0) { | 2215 if (slot == 0) { |
| 2160 // A slot id of 0 means there is no [DartType] object to build. | 2216 // A slot id of 0 means there is no [DartType] object to build. |
| 2161 return null; | 2217 return null; |
| 2162 } | 2218 } |
| 2163 EntityRef type = linkedTypeMap[slot]; | 2219 EntityRef type = linkedTypeMap[slot]; |
| 2164 if (type == null) { | 2220 if (type == null) { |
| 2165 // A missing entry in [LinkedUnit.types] means there is no [DartType] | 2221 // A missing entry in [LinkedUnit.types] means there is no [DartType] |
| 2166 // stored in this slot. | 2222 // stored in this slot. |
| 2167 return null; | 2223 return null; |
| 2168 } | 2224 } |
| 2169 return buildType(type); | 2225 return buildType(type, typeParameterContext); |
| 2170 } | 2226 } |
| 2171 | 2227 |
| 2172 /** | 2228 /** |
| 2173 * Resynthesize a local [FunctionElement]. | 2229 * Resynthesize a local [FunctionElement]. |
| 2174 */ | 2230 */ |
| 2175 FunctionElementImpl buildLocalFunction( | 2231 FunctionElementImpl buildLocalFunction( |
| 2176 UnlinkedExecutable serializedExecutable) { | 2232 UnlinkedExecutable serializedExecutable) { |
| 2177 FunctionElementImpl element = | 2233 FunctionElementImpl element = new FunctionElementImpl.forSerialized( |
| 2178 new FunctionElementImpl.forSerialized(serializedExecutable); | 2234 _resynthesizerContext, serializedExecutable); |
| 2179 if (serializedExecutable.visibleOffset != 0) { | 2235 if (serializedExecutable.visibleOffset != 0) { |
| 2180 element.setVisibleRange(serializedExecutable.visibleOffset, | 2236 element.setVisibleRange(serializedExecutable.visibleOffset, |
| 2181 serializedExecutable.visibleLength); | 2237 serializedExecutable.visibleLength); |
| 2182 } | 2238 } |
| 2183 buildExecutableCommonParts(element, serializedExecutable); | 2239 buildExecutableCommonParts(element, serializedExecutable); |
| 2184 return element; | 2240 return element; |
| 2185 } | 2241 } |
| 2186 | 2242 |
| 2187 /** | 2243 /** |
| 2188 * Resynthesize a [LabelElement]. | 2244 * Resynthesize a [LabelElement]. |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2272 List<ParameterElement> subParameters = serializedParameter.parameters | 2328 List<ParameterElement> subParameters = serializedParameter.parameters |
| 2273 .map((UnlinkedParam p) => buildParameter(p, synthetic: synthetic)) | 2329 .map((UnlinkedParam p) => buildParameter(p, synthetic: synthetic)) |
| 2274 .toList(); | 2330 .toList(); |
| 2275 if (synthetic) { | 2331 if (synthetic) { |
| 2276 parameterTypeElement.parameters = subParameters; | 2332 parameterTypeElement.parameters = subParameters; |
| 2277 } else { | 2333 } else { |
| 2278 parameterElement.parameters = subParameters; | 2334 parameterElement.parameters = subParameters; |
| 2279 parameterTypeElement.shareParameters(subParameters); | 2335 parameterTypeElement.shareParameters(subParameters); |
| 2280 parameterTypeElement.enclosingElement = parameterElement; | 2336 parameterTypeElement.enclosingElement = parameterElement; |
| 2281 } | 2337 } |
| 2282 parameterTypeElement.returnType = buildType(serializedParameter.type); | 2338 parameterTypeElement.returnType = |
| 2339 buildType(serializedParameter.type, _currentTypeParameterizedElement); |
| 2283 parameterElement.type = new FunctionTypeImpl.elementWithNameAndArgs( | 2340 parameterElement.type = new FunctionTypeImpl.elementWithNameAndArgs( |
| 2284 parameterTypeElement, null, getCurrentTypeArguments(), false); | 2341 parameterTypeElement, null, getCurrentTypeArguments(), false); |
| 2285 parameterTypeElement.type = parameterElement.type; | 2342 parameterTypeElement.type = parameterElement.type; |
| 2286 } else { | 2343 } else { |
| 2287 if (serializedParameter.isInitializingFormal && | 2344 if (serializedParameter.isInitializingFormal && |
| 2288 serializedParameter.type == null) { | 2345 serializedParameter.type == null) { |
| 2289 // The type is inherited from the matching field. | 2346 // The type is inherited from the matching field. |
| 2290 parameterElement.type = | 2347 parameterElement.type = |
| 2291 fields[serializedParameter.name]?.type ?? DynamicTypeImpl.instance; | 2348 fields[serializedParameter.name]?.type ?? DynamicTypeImpl.instance; |
| 2292 } else { | 2349 } else { |
| 2293 parameterElement.type = | 2350 parameterElement.type = buildLinkedType( |
| 2294 buildLinkedType(serializedParameter.inferredTypeSlot) ?? | 2351 serializedParameter.inferredTypeSlot, |
| 2295 buildType(serializedParameter.type); | 2352 _currentTypeParameterizedElement) ?? |
| 2353 buildType( |
| 2354 serializedParameter.type, _currentTypeParameterizedElement); |
| 2296 } | 2355 } |
| 2297 parameterElement.hasImplicitType = serializedParameter.type == null; | 2356 parameterElement.hasImplicitType = serializedParameter.type == null; |
| 2298 } | 2357 } |
| 2299 buildVariableInitializer(parameterElement, serializedParameter.initializer); | 2358 buildVariableInitializer(parameterElement, serializedParameter.initializer); |
| 2300 switch (serializedParameter.kind) { | 2359 switch (serializedParameter.kind) { |
| 2301 case UnlinkedParamKind.named: | 2360 case UnlinkedParamKind.named: |
| 2302 parameterElement.parameterKind = ParameterKind.NAMED; | 2361 parameterElement.parameterKind = ParameterKind.NAMED; |
| 2303 break; | 2362 break; |
| 2304 case UnlinkedParamKind.positional: | 2363 case UnlinkedParamKind.positional: |
| 2305 parameterElement.parameterKind = ParameterKind.POSITIONAL; | 2364 parameterElement.parameterKind = ParameterKind.POSITIONAL; |
| 2306 break; | 2365 break; |
| 2307 case UnlinkedParamKind.required: | 2366 case UnlinkedParamKind.required: |
| 2308 parameterElement.parameterKind = ParameterKind.REQUIRED; | 2367 parameterElement.parameterKind = ParameterKind.REQUIRED; |
| 2309 break; | 2368 break; |
| 2310 } | 2369 } |
| 2311 if (serializedParameter.visibleOffset != 0) { | 2370 if (serializedParameter.visibleOffset != 0) { |
| 2312 parameterElement.setVisibleRange( | 2371 parameterElement.setVisibleRange( |
| 2313 serializedParameter.visibleOffset, serializedParameter.visibleLength); | 2372 serializedParameter.visibleOffset, serializedParameter.visibleLength); |
| 2314 } | 2373 } |
| 2315 return parameterElement; | 2374 return parameterElement; |
| 2316 } | 2375 } |
| 2317 | 2376 |
| 2318 /** | 2377 /** |
| 2319 * Handle the parts that are common to top level variables and fields. | 2378 * Handle the parts that are common to top level variables and fields. |
| 2320 */ | 2379 */ |
| 2321 void buildPropertyIntroducingElementCommonParts( | 2380 void buildPropertyIntroducingElementCommonParts( |
| 2322 PropertyInducingElementImpl element, | 2381 PropertyInducingElementImpl element, |
| 2323 UnlinkedVariable serializedVariable) { | 2382 UnlinkedVariable serializedVariable) { |
| 2324 buildVariableCommonParts(element, serializedVariable); | 2383 buildVariableCommonParts(element, serializedVariable); |
| 2325 element.propagatedType = | 2384 element.propagatedType = buildLinkedType( |
| 2326 buildLinkedType(serializedVariable.propagatedTypeSlot); | 2385 serializedVariable.propagatedTypeSlot, |
| 2386 _currentTypeParameterizedElement); |
| 2327 } | 2387 } |
| 2328 | 2388 |
| 2329 /** | 2389 /** |
| 2330 * Build a [DartType] object based on a [EntityRef]. This [DartType] | 2390 * Build a [DartType] object based on a [EntityRef]. This [DartType] |
| 2331 * may refer to elements in other libraries than the library being | 2391 * may refer to elements in other libraries than the library being |
| 2332 * deserialized, so handles are used to avoid having to deserialize other | 2392 * deserialized, so handles are used to avoid having to deserialize other |
| 2333 * libraries in the process. | 2393 * libraries in the process. |
| 2334 */ | 2394 */ |
| 2335 DartType buildType(EntityRef type, | 2395 DartType buildType( |
| 2396 EntityRef type, TypeParameterizedElementMixin typeParameterContext, |
| 2336 {bool defaultVoid: false, bool instantiateToBoundsAllowed: true}) { | 2397 {bool defaultVoid: false, bool instantiateToBoundsAllowed: true}) { |
| 2337 if (type == null) { | 2398 if (type == null) { |
| 2338 if (defaultVoid) { | 2399 if (defaultVoid) { |
| 2339 return VoidTypeImpl.instance; | 2400 return VoidTypeImpl.instance; |
| 2340 } else { | 2401 } else { |
| 2341 return DynamicTypeImpl.instance; | 2402 return DynamicTypeImpl.instance; |
| 2342 } | 2403 } |
| 2343 } | 2404 } |
| 2344 if (type.paramReference != 0) { | 2405 if (type.paramReference != 0) { |
| 2345 return getTypeParameterFromScope(type.paramReference); | 2406 return typeParameterContext.getTypeParameterType(type.paramReference); |
| 2346 } else if (type.syntheticReturnType != null) { | 2407 } else if (type.syntheticReturnType != null) { |
| 2347 FunctionElementImpl element = new FunctionElementImpl('', -1); | 2408 FunctionElementImpl element = new FunctionElementImpl('', -1); |
| 2348 element.synthetic = true; | 2409 element.synthetic = true; |
| 2349 element.parameters = type.syntheticParams | 2410 element.parameters = type.syntheticParams |
| 2350 .map((UnlinkedParam param) => buildParameter(param, synthetic: true)) | 2411 .map((UnlinkedParam param) => buildParameter(param, synthetic: true)) |
| 2351 .toList(); | 2412 .toList(); |
| 2352 element.returnType = buildType(type.syntheticReturnType); | 2413 element.returnType = |
| 2414 buildType(type.syntheticReturnType, typeParameterContext); |
| 2353 FunctionTypeImpl result = new FunctionTypeImpl.elementWithNameAndArgs( | 2415 FunctionTypeImpl result = new FunctionTypeImpl.elementWithNameAndArgs( |
| 2354 element, null, null, false); | 2416 element, null, null, false); |
| 2355 element.type = result; | 2417 element.type = result; |
| 2356 return result; | 2418 return result; |
| 2357 } else { | 2419 } else { |
| 2358 DartType getTypeArgument(int i) { | 2420 DartType getTypeArgument(int i) { |
| 2359 if (i < type.typeArguments.length) { | 2421 if (i < type.typeArguments.length) { |
| 2360 return buildType(type.typeArguments[i]); | 2422 return buildType(type.typeArguments[i], typeParameterContext); |
| 2361 } else { | 2423 } else { |
| 2362 return DynamicTypeImpl.instance; | 2424 return DynamicTypeImpl.instance; |
| 2363 } | 2425 } |
| 2364 } | 2426 } |
| 2365 _ReferenceInfo referenceInfo = getReferenceInfo(type.reference); | 2427 _ReferenceInfo referenceInfo = getReferenceInfo(type.reference); |
| 2366 return referenceInfo.buildType( | 2428 return referenceInfo.buildType( |
| 2367 instantiateToBoundsAllowed, | 2429 instantiateToBoundsAllowed, |
| 2368 type.typeArguments.length, | 2430 type.typeArguments.length, |
| 2369 getTypeArgument, | 2431 getTypeArgument, |
| 2370 type.implicitFunctionTypeIndices); | 2432 type.implicitFunctionTypeIndices); |
| 2371 } | 2433 } |
| 2372 } | 2434 } |
| 2373 | 2435 |
| 2374 /** | 2436 /** |
| 2375 * Resynthesize a [FunctionTypeAliasElement] and place it in the | 2437 * Resynthesize a [FunctionTypeAliasElement] and place it in the |
| 2376 * [unitHolder]. | 2438 * [unitHolder]. |
| 2377 */ | 2439 */ |
| 2378 void buildTypedef(UnlinkedTypedef serializedTypedef) { | 2440 void buildTypedef(UnlinkedTypedef serializedTypedef) { |
| 2379 FunctionTypeAliasElementImpl functionTypeAliasElement = | 2441 FunctionTypeAliasElementImpl functionTypeAliasElement = |
| 2380 new FunctionTypeAliasElementImpl.forSerialized(serializedTypedef); | 2442 new FunctionTypeAliasElementImpl.forSerialized( |
| 2443 _resynthesizerContext, serializedTypedef); |
| 2381 functionTypeAliasElement.typeParameters = | 2444 functionTypeAliasElement.typeParameters = |
| 2382 buildTypeParameters(serializedTypedef.typeParameters); | 2445 buildTypeParameters(serializedTypedef.typeParameters); |
| 2383 functionTypeAliasElement.parameters = | 2446 functionTypeAliasElement.parameters = |
| 2384 serializedTypedef.parameters.map(buildParameter).toList(); | 2447 serializedTypedef.parameters.map(buildParameter).toList(); |
| 2385 functionTypeAliasElement.returnType = | 2448 functionTypeAliasElement.returnType = buildType( |
| 2386 buildType(serializedTypedef.returnType); | 2449 serializedTypedef.returnType, _currentTypeParameterizedElement); |
| 2387 functionTypeAliasElement.type = | 2450 functionTypeAliasElement.type = |
| 2388 new FunctionTypeImpl.forTypedef(functionTypeAliasElement); | 2451 new FunctionTypeImpl.forTypedef(functionTypeAliasElement); |
| 2389 buildAnnotations(functionTypeAliasElement, serializedTypedef.annotations); | 2452 buildAnnotations(functionTypeAliasElement, serializedTypedef.annotations); |
| 2390 unitHolder.addTypeAlias(functionTypeAliasElement); | 2453 unitHolder.addTypeAlias(functionTypeAliasElement); |
| 2391 currentTypeParameters.removeLast(); | 2454 currentTypeParameters.removeLast(); |
| 2392 assert(currentTypeParameters.isEmpty); | 2455 assert(currentTypeParameters.isEmpty); |
| 2393 } | 2456 } |
| 2394 | 2457 |
| 2395 /** | 2458 /** |
| 2396 * Resynthesize a [TypeParameterElement], handling all parts of its except | 2459 * Resynthesize a [TypeParameterElement], handling all parts of its except |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2468 buildImplicitAccessors(element, holder); | 2531 buildImplicitAccessors(element, holder); |
| 2469 fields[element.name] = element; | 2532 fields[element.name] = element; |
| 2470 } | 2533 } |
| 2471 } | 2534 } |
| 2472 | 2535 |
| 2473 /** | 2536 /** |
| 2474 * Handle the parts that are common to variables. | 2537 * Handle the parts that are common to variables. |
| 2475 */ | 2538 */ |
| 2476 void buildVariableCommonParts( | 2539 void buildVariableCommonParts( |
| 2477 VariableElementImpl element, UnlinkedVariable serializedVariable) { | 2540 VariableElementImpl element, UnlinkedVariable serializedVariable) { |
| 2478 element.type = buildLinkedType(serializedVariable.inferredTypeSlot) ?? | 2541 element.type = buildLinkedType(serializedVariable.inferredTypeSlot, |
| 2479 buildType(serializedVariable.type); | 2542 _currentTypeParameterizedElement) ?? |
| 2543 buildType(serializedVariable.type, _currentTypeParameterizedElement); |
| 2480 element.const3 = serializedVariable.isConst; | 2544 element.const3 = serializedVariable.isConst; |
| 2481 element.final2 = serializedVariable.isFinal; | 2545 element.final2 = serializedVariable.isFinal; |
| 2482 element.hasImplicitType = serializedVariable.type == null; | 2546 element.hasImplicitType = serializedVariable.type == null; |
| 2483 buildVariableInitializer(element, serializedVariable.initializer); | 2547 buildVariableInitializer(element, serializedVariable.initializer); |
| 2484 buildDocumentation(element, serializedVariable.documentationComment); | 2548 buildDocumentation(element, serializedVariable.documentationComment); |
| 2485 buildAnnotations(element, serializedVariable.annotations); | 2549 buildAnnotations(element, serializedVariable.annotations); |
| 2486 buildCodeRange(element, serializedVariable.codeRange); | 2550 buildCodeRange(element, serializedVariable.codeRange); |
| 2487 } | 2551 } |
| 2488 | 2552 |
| 2489 /** | 2553 /** |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2500 initializerElement.synthetic = true; | 2564 initializerElement.synthetic = true; |
| 2501 variable.initializer = initializerElement; | 2565 variable.initializer = initializerElement; |
| 2502 } | 2566 } |
| 2503 | 2567 |
| 2504 /** | 2568 /** |
| 2505 * Finish creating a [TypeParameterElement] by deserializing its bound. | 2569 * Finish creating a [TypeParameterElement] by deserializing its bound. |
| 2506 */ | 2570 */ |
| 2507 void finishTypeParameter(UnlinkedTypeParam serializedTypeParameter, | 2571 void finishTypeParameter(UnlinkedTypeParam serializedTypeParameter, |
| 2508 TypeParameterElementImpl typeParameterElement) { | 2572 TypeParameterElementImpl typeParameterElement) { |
| 2509 if (serializedTypeParameter.bound != null) { | 2573 if (serializedTypeParameter.bound != null) { |
| 2510 typeParameterElement.bound = buildType(serializedTypeParameter.bound, | 2574 typeParameterElement.bound = buildType( |
| 2575 serializedTypeParameter.bound, _currentTypeParameterizedElement, |
| 2511 instantiateToBoundsAllowed: false); | 2576 instantiateToBoundsAllowed: false); |
| 2512 } | 2577 } |
| 2513 } | 2578 } |
| 2514 | 2579 |
| 2515 /** | 2580 /** |
| 2516 * Return a list of type arguments corresponding to [currentTypeParameters], | 2581 * Return a list of type arguments corresponding to [currentTypeParameters], |
| 2517 * skipping the innermost [skipLevels] nesting levels. | 2582 * skipping the innermost [skipLevels] nesting levels. |
| 2518 * | 2583 * |
| 2519 * Type parameters are listed in nesting order from innermost to outermost, | 2584 * Type parameters are listed in nesting order from innermost to outermost, |
| 2520 * and then in declaration order. So for instance if we are resynthesizing a | 2585 * and then in declaration order. So for instance if we are resynthesizing a |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2739 } | 2804 } |
| 2740 | 2805 |
| 2741 /** | 2806 /** |
| 2742 * Return the defining type for a [ConstructorElement] by applying | 2807 * Return the defining type for a [ConstructorElement] by applying |
| 2743 * [typeArgumentRefs] to the given linked [info]. | 2808 * [typeArgumentRefs] to the given linked [info]. |
| 2744 */ | 2809 */ |
| 2745 InterfaceType _createConstructorDefiningType( | 2810 InterfaceType _createConstructorDefiningType( |
| 2746 _ReferenceInfo info, List<EntityRef> typeArgumentRefs) { | 2811 _ReferenceInfo info, List<EntityRef> typeArgumentRefs) { |
| 2747 bool isClass = info.element is ClassElement; | 2812 bool isClass = info.element is ClassElement; |
| 2748 _ReferenceInfo classInfo = isClass ? info : info.enclosing; | 2813 _ReferenceInfo classInfo = isClass ? info : info.enclosing; |
| 2749 List<DartType> typeArguments = typeArgumentRefs.map(buildType).toList(); | 2814 List<DartType> typeArguments = typeArgumentRefs |
| 2815 .map((t) => buildType(t, _currentTypeParameterizedElement)) |
| 2816 .toList(); |
| 2750 return classInfo.buildType(true, typeArguments.length, (i) { | 2817 return classInfo.buildType(true, typeArguments.length, (i) { |
| 2751 if (i < typeArguments.length) { | 2818 if (i < typeArguments.length) { |
| 2752 return typeArguments[i]; | 2819 return typeArguments[i]; |
| 2753 } else { | 2820 } else { |
| 2754 return DynamicTypeImpl.instance; | 2821 return DynamicTypeImpl.instance; |
| 2755 } | 2822 } |
| 2756 }, const <int>[]); | 2823 }, const <int>[]); |
| 2757 } | 2824 } |
| 2758 | 2825 |
| 2759 /** | 2826 /** |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2783 static String _getElementIdentifier(String name, ReferenceKind kind) { | 2850 static String _getElementIdentifier(String name, ReferenceKind kind) { |
| 2784 if (kind == ReferenceKind.topLevelPropertyAccessor || | 2851 if (kind == ReferenceKind.topLevelPropertyAccessor || |
| 2785 kind == ReferenceKind.propertyAccessor) { | 2852 kind == ReferenceKind.propertyAccessor) { |
| 2786 if (!name.endsWith('=')) { | 2853 if (!name.endsWith('=')) { |
| 2787 return name + '?'; | 2854 return name + '?'; |
| 2788 } | 2855 } |
| 2789 } | 2856 } |
| 2790 return name; | 2857 return name; |
| 2791 } | 2858 } |
| 2792 } | 2859 } |
| OLD | NEW |