| 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 |