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 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
743 List<Expression> _removeTopItems(int count) { | 743 List<Expression> _removeTopItems(int count) { |
744 int start = stack.length - count; | 744 int start = stack.length - count; |
745 int end = stack.length; | 745 int end = stack.length; |
746 List<Expression> items = stack.getRange(start, end).toList(); | 746 List<Expression> items = stack.getRange(start, end).toList(); |
747 stack.removeRange(start, end); | 747 stack.removeRange(start, end); |
748 return items; | 748 return items; |
749 } | 749 } |
750 } | 750 } |
751 | 751 |
752 /** | 752 /** |
753 * A class element that has been resynthesized from a summary. The actual | |
754 * element won't be constructed until it is requested. But properties | |
755 * [context], [displayName], [enclosingElement] and [name] can be used without | |
756 * creating the actual element. This allows to put these elements into | |
757 * namespaces without creating actual elements until they are really needed. | |
758 */ | |
759 class _DeferredClassElement extends ClassElementHandle { | |
760 final _UnitResynthesizer unitResynthesizer; | |
761 final CompilationUnitElement unitElement; | |
762 final UnlinkedClass serializedClass; | |
763 | |
764 ClassElementImpl _actualElement; | |
765 | |
766 /** | |
767 * We don't resynthesize executables of classes until they are requested. | |
768 * TODO(scheglov) Check whether we need separate flags for separate kinds. | |
769 */ | |
770 bool _executablesResynthesized = false; | |
771 | |
772 @override | |
773 final String name; | |
774 | |
775 factory _DeferredClassElement(_UnitResynthesizer unitResynthesizer, | |
776 CompilationUnitElement unitElement, UnlinkedClass serializedClass) { | |
777 String name = serializedClass.name; | |
778 List<String> components = | |
779 unitResynthesizer.unit.location.components.toList(); | |
780 components.add(name); | |
781 ElementLocationImpl location = new ElementLocationImpl.con3(components); | |
782 return new _DeferredClassElement._( | |
783 unitResynthesizer, unitElement, serializedClass, name, location); | |
784 } | |
785 | |
786 _DeferredClassElement._(this.unitResynthesizer, this.unitElement, | |
787 this.serializedClass, this.name, ElementLocation location) | |
788 : super(null, location); | |
789 | |
790 @override | |
791 List<PropertyAccessorElement> get accessors { | |
792 _ensureExecutables(); | |
793 return actualElement.accessors; | |
794 } | |
795 | |
796 @override | |
797 ClassElementImpl get actualElement { | |
798 if (_actualElement == null) { | |
799 _actualElement = unitResynthesizer.buildClassImpl(serializedClass, this); | |
800 _actualElement.enclosingElement = unitElement; | |
801 } | |
802 return _actualElement; | |
803 } | |
804 | |
805 @override | |
806 List<ConstructorElement> get constructors { | |
807 _ensureExecutables(); | |
808 return actualElement.constructors; | |
809 } | |
810 | |
811 @override | |
812 AnalysisContext get context => unitElement.context; | |
813 | |
814 @override | |
815 String get displayName => name; | |
816 | |
817 @override | |
818 CompilationUnitElement get enclosingElement { | |
819 return unitElement; | |
820 } | |
821 | |
822 @override | |
823 List<FieldElement> get fields { | |
824 _ensureExecutables(); | |
825 return actualElement.fields; | |
826 } | |
827 | |
828 @override | |
829 List<MethodElement> get methods { | |
830 _ensureExecutables(); | |
831 return actualElement.methods; | |
832 } | |
833 | |
834 @override | |
835 void ensureAccessorsReady() { | |
836 _ensureExecutables(); | |
837 } | |
838 | |
839 @override | |
840 void ensureActualElementComplete() { | |
841 _ensureExecutables(); | |
842 } | |
843 | |
844 @override | |
845 void ensureConstructorsReady() { | |
846 _ensureExecutables(); | |
847 } | |
848 | |
849 @override | |
850 void ensureMethodsReady() { | |
851 _ensureExecutables(); | |
852 } | |
853 | |
854 /** | |
855 * Ensure that we have [actualElement], and it has all executables. | |
856 */ | |
857 void _ensureExecutables() { | |
858 // TODO(scheglov) remove and clean up Handle | |
859 } | |
860 } | |
861 | |
862 /** | |
863 * Local function element representing the initializer for a variable that has | 753 * Local function element representing the initializer for a variable that has |
864 * been resynthesized from a summary. The actual element won't be constructed | 754 * been resynthesized from a summary. The actual element won't be constructed |
865 * until it is requested. But properties [context] and [enclosingElement] can | 755 * until it is requested. But properties [context] and [enclosingElement] can |
866 * be used without creating the actual element. | 756 * be used without creating the actual element. |
867 */ | 757 */ |
868 class _DeferredInitializerElement extends FunctionElementHandle { | 758 class _DeferredInitializerElement extends FunctionElementHandle { |
869 /** | 759 /** |
870 * The variable element containing this element. | 760 * The variable element containing this element. |
871 */ | 761 */ |
872 @override | 762 @override |
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1627 element.metadata = serializedAnnotations | 1517 element.metadata = serializedAnnotations |
1628 .map((a) => buildAnnotation(element, a)) | 1518 .map((a) => buildAnnotation(element, a)) |
1629 .toList(); | 1519 .toList(); |
1630 } | 1520 } |
1631 } | 1521 } |
1632 | 1522 |
1633 /** | 1523 /** |
1634 * Resynthesize a [ClassElement] and place it in [unitHolder]. | 1524 * Resynthesize a [ClassElement] and place it in [unitHolder]. |
1635 */ | 1525 */ |
1636 void buildClass(UnlinkedClass serializedClass) { | 1526 void buildClass(UnlinkedClass serializedClass) { |
1637 ClassElement classElement; | 1527 ClassElementImpl classElement = |
1638 if (libraryResynthesizer.isCoreLibrary && | 1528 new ClassElementImpl.forSerialized(serializedClass, unit); |
1639 serializedClass.supertype == null) { | 1529 classElement.hasBeenInferred = summaryResynthesizer.strongMode; |
1640 classElement = buildClassImpl(serializedClass, null); | 1530 InterfaceTypeImpl correspondingType = new InterfaceTypeImpl(classElement); |
1641 } else { | 1531 // TODO(scheglov) move to ClassElementImpl |
1642 classElement = new _DeferredClassElement(this, unit, serializedClass); | 1532 correspondingType.typeArguments = classElement.typeParameterTypes; |
1643 } | 1533 classElement.type = correspondingType; |
1644 unitHolder.addType(classElement); | 1534 unitHolder.addType(classElement); |
1645 } | 1535 } |
1646 | 1536 |
1647 /** | 1537 /** |
1648 * Resynthesize a [ClassElementImpl]. If [handle] is not `null`, then | |
1649 * executables are not resynthesized, and [InterfaceTypeImpl] is created | |
1650 * around the [handle], so that executables are resynthesized lazily. | |
1651 */ | |
1652 ClassElementImpl buildClassImpl( | |
1653 UnlinkedClass serializedClass, ClassElementHandle handle) { | |
1654 ClassElementImpl classElement = | |
1655 new ClassElementImpl.forSerialized(serializedClass, unit); | |
1656 classElement.hasBeenInferred = summaryResynthesizer.strongMode; | |
1657 InterfaceTypeImpl correspondingType = | |
1658 new InterfaceTypeImpl(handle ?? classElement); | |
1659 // TODO(scheglov) move to ClassElementImpl | |
1660 correspondingType.typeArguments = classElement.typeParameterTypes; | |
1661 classElement.type = correspondingType; | |
1662 return classElement; | |
1663 } | |
1664 | |
1665 /** | |
1666 * Build the documentation for the given [element]. Does nothing if | 1538 * Build the documentation for the given [element]. Does nothing if |
1667 * [serializedDocumentationComment] is `null`. | 1539 * [serializedDocumentationComment] is `null`. |
1668 */ | 1540 */ |
1669 void buildDocumentation(ElementImpl element, | 1541 void buildDocumentation(ElementImpl element, |
1670 UnlinkedDocumentationComment serializedDocumentationComment) { | 1542 UnlinkedDocumentationComment serializedDocumentationComment) { |
1671 if (serializedDocumentationComment != null) { | 1543 if (serializedDocumentationComment != null) { |
1672 element.documentationComment = serializedDocumentationComment.text; | 1544 element.documentationComment = serializedDocumentationComment.text; |
1673 element.setDocRange(serializedDocumentationComment.offset, | 1545 element.setDocRange(serializedDocumentationComment.offset, |
1674 serializedDocumentationComment.length); | 1546 serializedDocumentationComment.length); |
1675 } | 1547 } |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2106 static String _getElementIdentifier(String name, ReferenceKind kind) { | 1978 static String _getElementIdentifier(String name, ReferenceKind kind) { |
2107 if (kind == ReferenceKind.topLevelPropertyAccessor || | 1979 if (kind == ReferenceKind.topLevelPropertyAccessor || |
2108 kind == ReferenceKind.propertyAccessor) { | 1980 kind == ReferenceKind.propertyAccessor) { |
2109 if (!name.endsWith('=')) { | 1981 if (!name.endsWith('=')) { |
2110 return name + '?'; | 1982 return name + '?'; |
2111 } | 1983 } |
2112 } | 1984 } |
2113 return name; | 1985 return name; |
2114 } | 1986 } |
2115 } | 1987 } |
OLD | NEW |