OLD | NEW |
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 library analyzer.test.src.summary.resynthesize_ast_test; | 5 library analyzer.test.src.summary.resynthesize_ast_test; |
6 | 6 |
7 import 'package:analyzer/dart/ast/ast.dart'; | 7 import 'package:analyzer/dart/ast/ast.dart'; |
8 import 'package:analyzer/dart/element/element.dart'; | 8 import 'package:analyzer/dart/element/element.dart'; |
9 import 'package:analyzer/src/dart/element/element.dart'; | 9 import 'package:analyzer/src/dart/element/element.dart'; |
10 import 'package:analyzer/src/generated/engine.dart' | 10 import 'package:analyzer/src/generated/engine.dart' |
11 show AnalysisContext, AnalysisOptionsImpl; | 11 show AnalysisContext, AnalysisOptionsImpl; |
12 import 'package:analyzer/src/generated/sdk.dart'; | 12 import 'package:analyzer/src/generated/sdk.dart'; |
13 import 'package:analyzer/src/generated/source.dart'; | 13 import 'package:analyzer/src/generated/source.dart'; |
14 import 'package:analyzer/src/summary/format.dart'; | 14 import 'package:analyzer/src/summary/format.dart'; |
15 import 'package:analyzer/src/summary/idl.dart'; | 15 import 'package:analyzer/src/summary/idl.dart'; |
16 import 'package:analyzer/src/summary/link.dart'; | 16 import 'package:analyzer/src/summary/link.dart'; |
17 import 'package:analyzer/src/summary/prelink.dart'; | 17 import 'package:analyzer/src/summary/prelink.dart'; |
18 import 'package:analyzer/src/summary/resynthesize.dart'; | 18 import 'package:analyzer/src/summary/resynthesize.dart'; |
19 import 'package:analyzer/src/summary/summarize_ast.dart'; | 19 import 'package:analyzer/src/summary/summarize_ast.dart'; |
20 import 'package:analyzer/src/summary/summarize_elements.dart' | 20 import 'package:analyzer/src/summary/summarize_elements.dart' |
21 show PackageBundleAssembler; | 21 show PackageBundleAssembler; |
22 import 'package:analyzer/task/dart.dart' show PARSED_UNIT; | 22 import 'package:analyzer/task/dart.dart' show PARSED_UNIT; |
| 23 import 'package:analyzer/task/general.dart'; |
23 import 'package:unittest/unittest.dart'; | 24 import 'package:unittest/unittest.dart'; |
24 | 25 |
25 import '../../reflective_tests.dart'; | 26 import '../../reflective_tests.dart'; |
26 import '../context/abstract_context.dart'; | 27 import '../context/abstract_context.dart'; |
27 import '../task/strong/inferred_type_test.dart'; | 28 import '../task/strong/inferred_type_test.dart'; |
28 import 'resynthesize_test.dart'; | 29 import 'resynthesize_test.dart'; |
29 import 'summary_common.dart'; | 30 import 'summary_common.dart'; |
30 | 31 |
31 main() { | 32 main() { |
32 groupSep = ' | '; | 33 groupSep = ' | '; |
(...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 | 708 |
708 @override | 709 @override |
709 TestSummaryResynthesizer encodeDecodeLibrarySource(Source source) { | 710 TestSummaryResynthesizer encodeDecodeLibrarySource(Source source) { |
710 return _encodeLibrary(source); | 711 return _encodeLibrary(source); |
711 } | 712 } |
712 } | 713 } |
713 | 714 |
714 /** | 715 /** |
715 * Abstract mixin for serializing ASTs and resynthesizing elements from it. | 716 * Abstract mixin for serializing ASTs and resynthesizing elements from it. |
716 */ | 717 */ |
717 abstract class _AstResynthesizeTestMixin { | 718 abstract class _AstResynthesizeTestMixin |
| 719 implements _AstResynthesizeTestMixinInterface { |
718 final Set<Source> serializedSources = new Set<Source>(); | 720 final Set<Source> serializedSources = new Set<Source>(); |
719 final PackageBundleAssembler bundleAssembler = new PackageBundleAssembler(); | 721 final PackageBundleAssembler bundleAssembler = new PackageBundleAssembler(); |
720 final Map<String, UnlinkedUnitBuilder> uriToUnit = | 722 final Map<String, UnlinkedUnitBuilder> uriToUnit = |
721 <String, UnlinkedUnitBuilder>{}; | 723 <String, UnlinkedUnitBuilder>{}; |
722 | 724 |
723 AnalysisContext get context; | 725 AnalysisContext get context; |
724 | 726 |
725 LibraryElementImpl _encodeDecodeLibraryElement(Source source) { | 727 LibraryElementImpl _encodeDecodeLibraryElement(Source source) { |
726 SummaryResynthesizer resynthesizer = _encodeLibrary(source); | 728 SummaryResynthesizer resynthesizer = _encodeLibrary(source); |
727 return resynthesizer.getLibraryElement(source.uri.toString()); | 729 return resynthesizer.getLibraryElement(source.uri.toString()); |
728 } | 730 } |
729 | 731 |
730 TestSummaryResynthesizer _encodeLibrary(Source source) { | 732 TestSummaryResynthesizer _encodeLibrary(Source source) { |
731 _serializeLibrary(source); | 733 _serializeLibrary(source); |
732 | 734 |
733 PackageBundle bundle = | 735 PackageBundle bundle = |
734 new PackageBundle.fromBuffer(bundleAssembler.assemble().toBuffer()); | 736 new PackageBundle.fromBuffer(bundleAssembler.assemble().toBuffer()); |
735 | 737 |
736 Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{}; | 738 Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{}; |
737 for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) { | 739 for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) { |
738 String uri = bundle.unlinkedUnitUris[i]; | 740 String uri = bundle.unlinkedUnitUris[i]; |
739 unlinkedSummaries[uri] = bundle.unlinkedUnits[i]; | 741 unlinkedSummaries[uri] = bundle.unlinkedUnits[i]; |
740 } | 742 } |
741 | 743 |
742 LinkedLibrary getDependency(String absoluteUri) { | 744 LinkedLibrary getDependency(String absoluteUri) { |
743 Map<String, LinkedLibrary> sdkLibraries = | 745 Map<String, LinkedLibrary> sdkLibraries = |
744 SerializedMockSdk.instance.uriToLinkedLibrary; | 746 SerializedMockSdk.instance.uriToLinkedLibrary; |
745 LinkedLibrary linkedLibrary = sdkLibraries[absoluteUri]; | 747 LinkedLibrary linkedLibrary = sdkLibraries[absoluteUri]; |
746 if (linkedLibrary == null) { | 748 if (linkedLibrary == null && !allowMissingFiles) { |
747 fail('Linker unexpectedly requested LinkedLibrary for "$absoluteUri".' | 749 fail('Linker unexpectedly requested LinkedLibrary for "$absoluteUri".' |
748 ' Libraries available: ${sdkLibraries.keys}'); | 750 ' Libraries available: ${sdkLibraries.keys}'); |
749 } | 751 } |
750 return linkedLibrary; | 752 return linkedLibrary; |
751 } | 753 } |
752 | 754 |
753 UnlinkedUnit getUnit(String absoluteUri) { | 755 UnlinkedUnit getUnit(String absoluteUri) { |
754 UnlinkedUnit unit = uriToUnit[absoluteUri] ?? | 756 UnlinkedUnit unit = uriToUnit[absoluteUri] ?? |
755 SerializedMockSdk.instance.uriToUnlinkedUnit[absoluteUri]; | 757 SerializedMockSdk.instance.uriToUnlinkedUnit[absoluteUri]; |
756 if (unit == null) { | 758 if (unit == null && !allowMissingFiles) { |
757 fail('Linker unexpectedly requested unit for "$absoluteUri".'); | 759 fail('Linker unexpectedly requested unit for "$absoluteUri".'); |
758 } | 760 } |
759 return unit; | 761 return unit; |
760 } | 762 } |
761 | 763 |
762 Set<String> nonSdkLibraryUris = context.sources | 764 Set<String> nonSdkLibraryUris = context.sources |
763 .where((Source source) => | 765 .where((Source source) => |
764 !source.isInSystemLibrary && | 766 !source.isInSystemLibrary && |
765 context.computeKindOf(source) == SourceKind.LIBRARY) | 767 context.computeKindOf(source) == SourceKind.LIBRARY) |
766 .map((Source source) => source.uri.toString()) | 768 .map((Source source) => source.uri.toString()) |
767 .toSet(); | 769 .toSet(); |
768 | 770 |
769 Map<String, LinkedLibrary> linkedSummaries = link(nonSdkLibraryUris, | 771 Map<String, LinkedLibrary> linkedSummaries = link(nonSdkLibraryUris, |
770 getDependency, getUnit, context.analysisOptions.strongMode); | 772 getDependency, getUnit, context.analysisOptions.strongMode); |
771 | 773 |
772 return new TestSummaryResynthesizer( | 774 return new TestSummaryResynthesizer( |
773 null, | 775 null, |
774 context, | 776 context, |
775 new Map<String, UnlinkedUnit>() | 777 new Map<String, UnlinkedUnit>() |
776 ..addAll(SerializedMockSdk.instance.uriToUnlinkedUnit) | 778 ..addAll(SerializedMockSdk.instance.uriToUnlinkedUnit) |
777 ..addAll(unlinkedSummaries), | 779 ..addAll(unlinkedSummaries), |
778 new Map<String, LinkedLibrary>() | 780 new Map<String, LinkedLibrary>() |
779 ..addAll(SerializedMockSdk.instance.uriToLinkedLibrary) | 781 ..addAll(SerializedMockSdk.instance.uriToLinkedLibrary) |
780 ..addAll(linkedSummaries)); | 782 ..addAll(linkedSummaries), |
| 783 allowMissingFiles); |
781 } | 784 } |
782 | 785 |
783 UnlinkedUnit _getUnlinkedUnit(Source source) { | 786 UnlinkedUnit _getUnlinkedUnit(Source source) { |
784 String uriStr = source.uri.toString(); | 787 String uriStr = source.uri.toString(); |
785 { | 788 { |
786 UnlinkedUnit unlinkedUnitInSdk = | 789 UnlinkedUnit unlinkedUnitInSdk = |
787 SerializedMockSdk.instance.uriToUnlinkedUnit[uriStr]; | 790 SerializedMockSdk.instance.uriToUnlinkedUnit[uriStr]; |
788 if (unlinkedUnitInSdk != null) { | 791 if (unlinkedUnitInSdk != null) { |
789 return unlinkedUnitInSdk; | 792 return unlinkedUnitInSdk; |
790 } | 793 } |
791 } | 794 } |
792 return uriToUnit.putIfAbsent(uriStr, () { | 795 return uriToUnit.putIfAbsent(uriStr, () { |
| 796 int modificationTime = context.computeResult(source, MODIFICATION_TIME); |
| 797 if (modificationTime < 0) { |
| 798 // Source does not exist. |
| 799 if (!allowMissingFiles) { |
| 800 fail('Unexpectedly tried to get unlinked summary for $source'); |
| 801 } |
| 802 return null; |
| 803 } |
793 CompilationUnit unit = context.computeResult(source, PARSED_UNIT); | 804 CompilationUnit unit = context.computeResult(source, PARSED_UNIT); |
794 UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit); | 805 UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit); |
795 bundleAssembler.addUnlinkedUnit(source, unlinkedUnit); | 806 bundleAssembler.addUnlinkedUnit(source, unlinkedUnit); |
796 return unlinkedUnit; | 807 return unlinkedUnit; |
797 }); | 808 }); |
798 } | 809 } |
799 | 810 |
800 void _serializeLibrary(Source librarySource) { | 811 void _serializeLibrary(Source librarySource) { |
801 if (librarySource.isInSystemLibrary) { | 812 if (librarySource.isInSystemLibrary) { |
802 return; | 813 return; |
(...skipping 10 matching lines...) Expand all Loading... |
813 '$librarySource (${librarySource.runtimeType})'); | 824 '$librarySource (${librarySource.runtimeType})'); |
814 } | 825 } |
815 return resolvedSource; | 826 return resolvedSource; |
816 } | 827 } |
817 | 828 |
818 UnlinkedUnit getPart(String relativeUri) { | 829 UnlinkedUnit getPart(String relativeUri) { |
819 return _getUnlinkedUnit(resolveRelativeUri(relativeUri)); | 830 return _getUnlinkedUnit(resolveRelativeUri(relativeUri)); |
820 } | 831 } |
821 | 832 |
822 UnlinkedPublicNamespace getImport(String relativeUri) { | 833 UnlinkedPublicNamespace getImport(String relativeUri) { |
823 return getPart(relativeUri).publicNamespace; | 834 return getPart(relativeUri)?.publicNamespace; |
824 } | 835 } |
825 | 836 |
826 UnlinkedUnit definingUnit = _getUnlinkedUnit(librarySource); | 837 UnlinkedUnit definingUnit = _getUnlinkedUnit(librarySource); |
827 LinkedLibraryBuilder linkedLibrary = | 838 if (definingUnit != null) { |
828 prelink(definingUnit, getPart, getImport); | 839 LinkedLibraryBuilder linkedLibrary = |
829 linkedLibrary.dependencies.skip(1).forEach((LinkedDependency d) { | 840 prelink(definingUnit, getPart, getImport); |
830 _serializeLibrary(resolveRelativeUri(d.uri)); | 841 linkedLibrary.dependencies.skip(1).forEach((LinkedDependency d) { |
831 }); | 842 _serializeLibrary(resolveRelativeUri(d.uri)); |
| 843 }); |
| 844 } |
832 } | 845 } |
833 } | 846 } |
| 847 |
| 848 /** |
| 849 * Interface that [_AstResynthesizeTestMixin] requires of classes it's mixed |
| 850 * into. We can't place the getter below into [_AstResynthesizeTestMixin] |
| 851 * directly, because then it would be overriding a field at the site where the |
| 852 * mixin is instantiated. |
| 853 */ |
| 854 abstract class _AstResynthesizeTestMixinInterface { |
| 855 /** |
| 856 * A test should return `true` to indicate that a missing file at the time of |
| 857 * summary resynthesis shouldn't trigger an error. |
| 858 */ |
| 859 bool get allowMissingFiles; |
| 860 } |
OLD | NEW |