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

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

Issue 1969943002: Resynthesize _DeferredClassElement lazily. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 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
OLDNEW
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 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 * creating the actual element. This allows to put these elements into 707 * creating the actual element. This allows to put these elements into
708 * namespaces without creating actual elements until they are really needed. 708 * namespaces without creating actual elements until they are really needed.
709 */ 709 */
710 class _DeferredClassElement extends ClassElementHandle { 710 class _DeferredClassElement extends ClassElementHandle {
711 final _UnitResynthesizer unitResynthesizer; 711 final _UnitResynthesizer unitResynthesizer;
712 final CompilationUnitElement unitElement; 712 final CompilationUnitElement unitElement;
713 final UnlinkedClass serializedClass; 713 final UnlinkedClass serializedClass;
714 714
715 ClassElementImpl _actualElement; 715 ClassElementImpl _actualElement;
716 716
717 /**
718 * We don't resynthesize executables of classes until they are requested.
Paul Berry 2016/05/11 22:09:37 Nit: based on the name, I made the incorrect assum
719 * TODO(scheglov) Check whether we need separate flags for separate kinds.
720 */
721 bool _hasExecutables = false;
722
717 @override 723 @override
718 final String name; 724 final String name;
719 725
720 factory _DeferredClassElement(_UnitResynthesizer unitResynthesizer, 726 factory _DeferredClassElement(_UnitResynthesizer unitResynthesizer,
721 CompilationUnitElement unitElement, UnlinkedClass serializedClass) { 727 CompilationUnitElement unitElement, UnlinkedClass serializedClass) {
722 String name = serializedClass.name; 728 String name = serializedClass.name;
723 List<String> components = 729 List<String> components =
724 unitResynthesizer.unit.location.components.toList(); 730 unitResynthesizer.unit.location.components.toList();
725 components.add(name); 731 components.add(name);
726 ElementLocationImpl location = new ElementLocationImpl.con3(components); 732 ElementLocationImpl location = new ElementLocationImpl.con3(components);
727 return new _DeferredClassElement._( 733 return new _DeferredClassElement._(
728 unitResynthesizer, unitElement, serializedClass, name, location); 734 unitResynthesizer, unitElement, serializedClass, name, location);
729 } 735 }
730 736
731 _DeferredClassElement._(this.unitResynthesizer, this.unitElement, 737 _DeferredClassElement._(this.unitResynthesizer, this.unitElement,
732 this.serializedClass, this.name, ElementLocation location) 738 this.serializedClass, this.name, ElementLocation location)
733 : super(null, location); 739 : super(null, location);
734 740
735 @override 741 @override
742 List<PropertyAccessorElement> get accessors {
743 _ensureExecutables();
744 return actualElement.accessors;
745 }
746
747 @override
736 ClassElementImpl get actualElement { 748 ClassElementImpl get actualElement {
737 if (_actualElement == null) { 749 if (_actualElement == null) {
738 _actualElement = unitResynthesizer.buildClassImpl(serializedClass); 750 _actualElement = unitResynthesizer.buildClassImpl(serializedClass, this);
739 _actualElement.enclosingElement = unitElement; 751 _actualElement.enclosingElement = unitElement;
740 } 752 }
741 return _actualElement; 753 return _actualElement;
742 } 754 }
743 755
744 @override 756 @override
757 List<ConstructorElement> get constructors {
758 _ensureExecutables();
759 return actualElement.constructors;
760 }
761
762 @override
745 AnalysisContext get context => unitElement.context; 763 AnalysisContext get context => unitElement.context;
746 764
747 @override 765 @override
748 String get displayName => name; 766 String get displayName => name;
749 767
750 @override 768 @override
751 CompilationUnitElement get enclosingElement { 769 CompilationUnitElement get enclosingElement {
752 return unitElement; 770 return unitElement;
753 } 771 }
772
773 @override
774 List<MethodElement> get methods {
775 _ensureExecutables();
776 return actualElement.methods;
777 }
778
779 @override
780 void ensureAccessorsReady() {
781 _ensureExecutables();
782 }
783
784 @override
785 void ensureActualElementComplete() {
786 _ensureExecutables();
787 }
788
789 @override
790 void ensureConstructorsReady() {
791 _ensureExecutables();
792 }
793
794 @override
795 void ensureMethodsReady() {
796 _ensureExecutables();
797 }
798
799 /**
800 * Ensure that we have [actualElement], and it has all executables.
801 */
802 void _ensureExecutables() {
803 if (!_hasExecutables) {
804 _hasExecutables = true;
805 unitResynthesizer.buildClassExecutables(actualElement, serializedClass);
806 }
807 }
754 } 808 }
755 809
756 /** 810 /**
757 * The constructor element that has been resynthesized from a summary. The 811 * The constructor element that has been resynthesized from a summary. The
758 * actual element won't be constructed until it is requested. But properties 812 * actual element won't be constructed until it is requested. But properties
759 * [displayName], [enclosingElement] and [name] can be used without creating 813 * [displayName], [enclosingElement] and [name] can be used without creating
760 * the actual element. 814 * the actual element.
761 */ 815 */
762 class _DeferredConstructorElement extends ConstructorElementHandle { 816 class _DeferredConstructorElement extends ConstructorElementHandle {
763 /** 817 /**
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
1603 } 1657 }
1604 } 1658 }
1605 1659
1606 /** 1660 /**
1607 * Resynthesize a [ClassElement] and place it in [unitHolder]. 1661 * Resynthesize a [ClassElement] and place it in [unitHolder].
1608 */ 1662 */
1609 void buildClass(UnlinkedClass serializedClass) { 1663 void buildClass(UnlinkedClass serializedClass) {
1610 ClassElement classElement; 1664 ClassElement classElement;
1611 if (libraryResynthesizer.isCoreLibrary && 1665 if (libraryResynthesizer.isCoreLibrary &&
1612 serializedClass.supertype == null) { 1666 serializedClass.supertype == null) {
1613 classElement = buildClassImpl(serializedClass); 1667 classElement = buildClassImpl(serializedClass, null);
1614 if (!serializedClass.hasNoSupertype) { 1668 if (!serializedClass.hasNoSupertype) {
1615 libraryResynthesizer.delayedObjectSubclasses.add(classElement); 1669 libraryResynthesizer.delayedObjectSubclasses.add(classElement);
1616 } 1670 }
1617 } else { 1671 } else {
1618 classElement = new _DeferredClassElement(this, unit, serializedClass); 1672 classElement = new _DeferredClassElement(this, unit, serializedClass);
1619 } 1673 }
1620 unitHolder.addType(classElement); 1674 unitHolder.addType(classElement);
1621 } 1675 }
1622 1676
1623 /** 1677 /**
1624 * Resynthesize a [ClassElementImpl]. 1678 * Fill the given [ClassElementImpl] with executable elements and fields.
1625 */ 1679 */
1626 ClassElementImpl buildClassImpl(UnlinkedClass serializedClass) { 1680 void buildClassExecutables(
1627 ClassElementImpl classElement = 1681 ClassElementImpl classElement, UnlinkedClass serializedClass) {
1628 new ClassElementImpl(serializedClass.name, serializedClass.nameOffset); 1682 currentTypeParameters.add(classElement.typeParameters);
1629 classElement.hasBeenInferred = summaryResynthesizer.strongMode;
1630 classElement.typeParameters =
1631 buildTypeParameters(serializedClass.typeParameters);
1632 classElement.abstract = serializedClass.isAbstract;
1633 classElement.mixinApplication = serializedClass.isMixinApplication;
1634 InterfaceTypeImpl correspondingType = new InterfaceTypeImpl(classElement);
1635 if (serializedClass.supertype != null) {
1636 classElement.supertype = buildType(serializedClass.supertype);
1637 } else if (!libraryResynthesizer.isCoreLibrary) {
1638 classElement.supertype = typeProvider.objectType;
1639 }
1640 classElement.interfaces =
1641 serializedClass.interfaces.map(buildType).toList();
1642 classElement.mixins = serializedClass.mixins.map(buildType).toList();
1643 ElementHolder memberHolder = new ElementHolder(); 1683 ElementHolder memberHolder = new ElementHolder();
1644 fields = <String, FieldElementImpl>{}; 1684 fields = <String, FieldElementImpl>{};
1645 for (UnlinkedVariable serializedVariable in serializedClass.fields) { 1685 for (UnlinkedVariable serializedVariable in serializedClass.fields) {
1646 buildVariable(serializedVariable, memberHolder); 1686 buildVariable(serializedVariable, memberHolder);
1647 } 1687 }
1648 bool constructorFound = false; 1688 bool constructorFound = false;
1649 constructors = <String, ConstructorElementImpl>{}; 1689 constructors = <String, ConstructorElementImpl>{};
1650 for (UnlinkedExecutable serializedExecutable 1690 for (UnlinkedExecutable serializedExecutable
1651 in serializedClass.executables) { 1691 in serializedClass.executables) {
1652 switch (serializedExecutable.kind) { 1692 switch (serializedExecutable.kind) {
1653 case UnlinkedExecutableKind.constructor: 1693 case UnlinkedExecutableKind.constructor:
1654 constructorFound = true; 1694 constructorFound = true;
1655 buildConstructor( 1695 buildConstructor(
1656 serializedExecutable, memberHolder, correspondingType); 1696 serializedExecutable, memberHolder, classElement.type);
1657 break; 1697 break;
1658 case UnlinkedExecutableKind.functionOrMethod: 1698 case UnlinkedExecutableKind.functionOrMethod:
1659 case UnlinkedExecutableKind.getter: 1699 case UnlinkedExecutableKind.getter:
1660 case UnlinkedExecutableKind.setter: 1700 case UnlinkedExecutableKind.setter:
1661 if (serializedExecutable.isStatic) { 1701 if (serializedExecutable.isStatic) {
1662 currentTypeParameters.removeLast(); 1702 currentTypeParameters.removeLast();
1663 } 1703 }
1664 buildExecutable(serializedExecutable, memberHolder); 1704 buildExecutable(serializedExecutable, memberHolder);
1665 if (serializedExecutable.isStatic) { 1705 if (serializedExecutable.isStatic) {
1666 currentTypeParameters.add(classElement.typeParameters); 1706 currentTypeParameters.add(classElement.typeParameters);
1667 } 1707 }
1668 break; 1708 break;
1669 } 1709 }
1670 } 1710 }
1671 if (!serializedClass.isMixinApplication) { 1711 if (!serializedClass.isMixinApplication) {
1672 if (!constructorFound) { 1712 if (!constructorFound) {
1673 // Synthesize implicit constructors. 1713 // Synthesize implicit constructors.
1674 ConstructorElementImpl constructor = new ConstructorElementImpl('', -1); 1714 ConstructorElementImpl constructor = new ConstructorElementImpl('', -1);
1675 constructor.synthetic = true; 1715 constructor.synthetic = true;
1676 constructor.returnType = correspondingType; 1716 constructor.returnType = classElement.type;
1677 constructor.type = new FunctionTypeImpl.elementWithNameAndArgs( 1717 constructor.type = new FunctionTypeImpl.elementWithNameAndArgs(
1678 constructor, null, getCurrentTypeArguments(), false); 1718 constructor, null, getCurrentTypeArguments(), false);
1679 memberHolder.addConstructor(constructor); 1719 memberHolder.addConstructor(constructor);
1680 } 1720 }
1681 classElement.constructors = memberHolder.constructors; 1721 classElement.constructors = memberHolder.constructors;
1682 } 1722 }
1683 classElement.accessors = memberHolder.accessors; 1723 classElement.accessors = memberHolder.accessors;
1684 classElement.fields = memberHolder.fields; 1724 classElement.fields = memberHolder.fields;
1685 classElement.methods = memberHolder.methods; 1725 classElement.methods = memberHolder.methods;
1726 resolveConstructorInitializers(classElement);
1727 currentTypeParameters.removeLast();
1728 assert(currentTypeParameters.isEmpty);
1729 }
1730
1731 /**
1732 * Resynthesize a [ClassElementImpl]. If [handle] is not `null`, then
1733 * executables are not resynthesized, and [InterfaceTypeImpl] is created
1734 * around the [handle], so that executables are resynthesized lazily.
1735 */
1736 ClassElementImpl buildClassImpl(
1737 UnlinkedClass serializedClass, ClassElementHandle handle) {
1738 ClassElementImpl classElement =
1739 new ClassElementImpl(serializedClass.name, serializedClass.nameOffset);
1740 classElement.hasBeenInferred = summaryResynthesizer.strongMode;
1741 classElement.typeParameters =
1742 buildTypeParameters(serializedClass.typeParameters);
1743 classElement.abstract = serializedClass.isAbstract;
1744 classElement.mixinApplication = serializedClass.isMixinApplication;
1745 InterfaceTypeImpl correspondingType =
1746 new InterfaceTypeImpl(handle ?? classElement);
1747 if (serializedClass.supertype != null) {
1748 classElement.supertype = buildType(serializedClass.supertype);
1749 } else if (!libraryResynthesizer.isCoreLibrary) {
1750 classElement.supertype = typeProvider.objectType;
1751 }
1752 classElement.interfaces =
1753 serializedClass.interfaces.map(buildType).toList();
1754 classElement.mixins = serializedClass.mixins.map(buildType).toList();
1686 correspondingType.typeArguments = getCurrentTypeArguments(); 1755 correspondingType.typeArguments = getCurrentTypeArguments();
1687 classElement.type = correspondingType; 1756 classElement.type = correspondingType;
1688 buildDocumentation(classElement, serializedClass.documentationComment); 1757 buildDocumentation(classElement, serializedClass.documentationComment);
1689 buildAnnotations(classElement, serializedClass.annotations); 1758 buildAnnotations(classElement, serializedClass.annotations);
1690 buildCodeRange(classElement, serializedClass.codeRange); 1759 buildCodeRange(classElement, serializedClass.codeRange);
1691 resolveConstructorInitializers(classElement);
1692 currentTypeParameters.removeLast(); 1760 currentTypeParameters.removeLast();
1693 assert(currentTypeParameters.isEmpty); 1761 assert(currentTypeParameters.isEmpty);
1762 // TODO(scheglov) Somehow Observatory shows too much time spent here
1763 // during DDC run on the large codebase. I would expect only Object here.
1764 if (handle == null) {
1765 buildClassExecutables(classElement, serializedClass);
1766 }
1694 fields = null; 1767 fields = null;
1695 constructors = null; 1768 constructors = null;
1696 return classElement; 1769 return classElement;
1697 } 1770 }
1698 1771
1699 void buildCodeRange(ElementImpl element, CodeRange codeRange) { 1772 void buildCodeRange(ElementImpl element, CodeRange codeRange) {
1700 if (codeRange != null) { 1773 if (codeRange != null) {
1701 element.setCodeRange(codeRange.offset, codeRange.length); 1774 element.setCodeRange(codeRange.offset, codeRange.length);
1702 } 1775 }
1703 } 1776 }
(...skipping 1015 matching lines...) Expand 10 before | Expand all | Expand 10 after
2719 static String _getElementIdentifier(String name, ReferenceKind kind) { 2792 static String _getElementIdentifier(String name, ReferenceKind kind) {
2720 if (kind == ReferenceKind.topLevelPropertyAccessor || 2793 if (kind == ReferenceKind.topLevelPropertyAccessor ||
2721 kind == ReferenceKind.propertyAccessor) { 2794 kind == ReferenceKind.propertyAccessor) {
2722 if (!name.endsWith('=')) { 2795 if (!name.endsWith('=')) {
2723 return name + '?'; 2796 return name + '?';
2724 } 2797 }
2725 } 2798 }
2726 return name; 2799 return name;
2727 } 2800 }
2728 } 2801 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698