Chromium Code Reviews| 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/analyzer.dart'; | 9 import 'package:analyzer/analyzer.dart'; |
| 10 import 'package:analyzer/src/generated/element.dart'; | 10 import 'package:analyzer/src/generated/element.dart'; |
| 11 import 'package:analyzer/src/generated/element_handle.dart'; | 11 import 'package:analyzer/src/generated/element_handle.dart'; |
| 12 import 'package:analyzer/src/generated/engine.dart'; | 12 import 'package:analyzer/src/generated/engine.dart'; |
| 13 import 'package:analyzer/src/generated/resolver.dart'; | 13 import 'package:analyzer/src/generated/resolver.dart'; |
| 14 import 'package:analyzer/src/generated/source_io.dart'; | 14 import 'package:analyzer/src/generated/source_io.dart'; |
| 15 import 'package:analyzer/src/summary/format.dart'; | 15 import 'package:analyzer/src/summary/format.dart'; |
| 16 | 16 |
| 17 /** | 17 /** |
| 18 * Callback used by [SummaryResynthesizer] to obtain the prelinked summary for | 18 * Callback used by [SummaryResynthesizer] to obtain the prelinked summary for |
| 19 * a given URI. | 19 * a given URI. |
| 20 */ | 20 */ |
| 21 typedef PrelinkedLibrary GetPrelinkedSummaryCallback(String uri); | 21 typedef PrelinkedLibrary GetPrelinkedSummaryCallback(String uri); |
| 22 | 22 |
| 23 /** | 23 /** |
| 24 * Callback used by [SummaryResynthesizer] to obtain the unlinked summary for a | 24 * Callback used by [SummaryResynthesizer] to obtain the unlinked summary for a |
| 25 * given URI. | 25 * given URI. |
| 26 */ | 26 */ |
| 27 typedef UnlinkedUnit GetUnlinkedSummaryCallback(String uri); | 27 typedef UnlinkedUnit GetUnlinkedSummaryCallback(String uri); |
| 28 | 28 |
| 29 /** | 29 /** |
| 30 * Callback used by [SummaryResynthesizer] to check whether it can access | |
| 31 * summaries of the library with the given [uri]. | |
| 32 */ | |
| 33 typedef bool HasLibrarySummaryCallback(String uri); | |
| 34 | |
| 35 /** | |
| 30 * Implementation of [ElementResynthesizer] used when resynthesizing an element | 36 * Implementation of [ElementResynthesizer] used when resynthesizing an element |
| 31 * model from summaries. | 37 * model from summaries. |
| 32 */ | 38 */ |
| 33 class SummaryResynthesizer extends ElementResynthesizer { | 39 class SummaryResynthesizer extends ElementResynthesizer { |
| 34 /** | 40 /** |
| 41 * The parent [SummaryResynthesizer] which is asked to resynthesis elements | |
| 42 * before this resynthesizer attempts to do this. Can be `null`. | |
| 43 */ | |
| 44 final SummaryResynthesizer parent; | |
| 45 | |
| 46 /** | |
| 47 * Callback used to check whether summaries for a given URI can be accessed. | |
| 48 */ | |
| 49 final HasLibrarySummaryCallback hasLibrarySummary; | |
| 50 | |
| 51 /** | |
| 35 * Callback used to obtain the prelinked summary for a given URI. | 52 * Callback used to obtain the prelinked summary for a given URI. |
| 36 */ | 53 */ |
| 37 final GetPrelinkedSummaryCallback getPrelinkedSummary; | 54 final GetPrelinkedSummaryCallback getPrelinkedSummary; |
| 38 | 55 |
| 39 /** | 56 /** |
| 40 * Callback used to obtain the unlinked summary for a given URI. | 57 * Callback used to obtain the unlinked summary for a given URI. |
| 41 */ | 58 */ |
| 42 final GetUnlinkedSummaryCallback getUnlinkedSummary; | 59 final GetUnlinkedSummaryCallback getUnlinkedSummary; |
| 43 | 60 |
| 44 /** | 61 /** |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 65 final Map<String, Map<String, Map<String, Element>>> _resynthesizedElements = | 82 final Map<String, Map<String, Map<String, Element>>> _resynthesizedElements = |
| 66 <String, Map<String, Map<String, Element>>>{}; | 83 <String, Map<String, Map<String, Element>>>{}; |
| 67 | 84 |
| 68 /** | 85 /** |
| 69 * Map of libraries which have been resynthesized from summaries. The map | 86 * Map of libraries which have been resynthesized from summaries. The map |
| 70 * key is the library URI. | 87 * key is the library URI. |
| 71 */ | 88 */ |
| 72 final Map<String, LibraryElement> _resynthesizedLibraries = | 89 final Map<String, LibraryElement> _resynthesizedLibraries = |
| 73 <String, LibraryElement>{}; | 90 <String, LibraryElement>{}; |
| 74 | 91 |
| 75 SummaryResynthesizer(AnalysisContext context, this.typeProvider, | 92 SummaryResynthesizer( |
| 76 this.getPrelinkedSummary, this.getUnlinkedSummary, this.sourceFactory) | 93 this.parent, |
| 94 AnalysisContext context, | |
| 95 this.typeProvider, | |
| 96 this.hasLibrarySummary, | |
| 97 this.getPrelinkedSummary, | |
| 98 this.getUnlinkedSummary, | |
| 99 this.sourceFactory) | |
| 77 : super(context); | 100 : super(context); |
| 78 | 101 |
| 79 /** | 102 /** |
| 80 * Number of libraries that have been resynthesized so far. | 103 * Number of libraries that have been resynthesized so far. |
| 81 */ | 104 */ |
| 82 int get resynthesisCount => _resynthesizedLibraries.length; | 105 int get resynthesisCount => _resynthesizedLibraries.length; |
| 83 | 106 |
| 84 @override | 107 @override |
| 85 Element getElement(ElementLocation location) { | 108 Element getElement(ElementLocation location) { |
| 86 if (location.components.length == 1) { | 109 List<String> components = location.components; |
| 87 return getLibraryElement(location.components[0]); | 110 // Ask the parent resynthesizer. |
| 88 } else if (location.components.length == 3) { | 111 if (parent != null && components.length >= 1) { |
| 89 String uri = location.components[0]; | 112 String libraryUri = components[0]; |
|
Paul Berry
2016/01/14 18:54:39
Personally I would move this up to line 110, and d
scheglov
2016/01/14 22:43:08
Done.
| |
| 113 if (parent.hasLibrarySummary(libraryUri)) { | |
| 114 return parent.getElement(location); | |
| 115 } | |
| 116 } | |
| 117 // Resynthesize locally. | |
| 118 if (components.length == 1) { | |
| 119 String libraryUri = components[0]; | |
| 120 return getLibraryElement(libraryUri); | |
| 121 } else if (components.length == 3) { | |
| 122 String libraryUri = components[0]; | |
| 90 Map<String, Map<String, Element>> libraryMap = | 123 Map<String, Map<String, Element>> libraryMap = |
| 91 _resynthesizedElements[uri]; | 124 _resynthesizedElements[libraryUri]; |
| 92 if (libraryMap == null) { | 125 if (libraryMap == null) { |
| 93 getLibraryElement(uri); | 126 getLibraryElement(libraryUri); |
| 94 libraryMap = _resynthesizedElements[uri]; | 127 libraryMap = _resynthesizedElements[libraryUri]; |
| 95 assert(libraryMap != null); | 128 assert(libraryMap != null); |
| 96 } | 129 } |
| 97 Map<String, Element> compilationUnitElements = | 130 Map<String, Element> compilationUnitElements = libraryMap[components[1]]; |
| 98 libraryMap[location.components[1]]; | |
| 99 if (compilationUnitElements != null) { | 131 if (compilationUnitElements != null) { |
| 100 Element element = compilationUnitElements[location.components[2]]; | 132 Element element = compilationUnitElements[components[2]]; |
| 101 if (element != null) { | 133 if (element != null) { |
| 102 return element; | 134 return element; |
| 103 } | 135 } |
| 104 } | 136 } |
| 105 throw new Exception('Element not found in summary: $location'); | 137 throw new Exception('Element not found in summary: $location'); |
| 106 } else { | 138 } else { |
| 107 throw new UnimplementedError(location.toString()); | 139 throw new UnimplementedError(location.toString()); |
| 108 } | 140 } |
| 109 } | 141 } |
| 110 | 142 |
| 111 /** | 143 /** |
| 112 * Get the [LibraryElement] for the given [uri], resynthesizing it if it | 144 * Get the [LibraryElement] for the given [uri], resynthesizing it if it |
| 113 * hasn't been resynthesized already. | 145 * hasn't been resynthesized already. |
| 114 */ | 146 */ |
| 115 LibraryElement getLibraryElement(String uri) { | 147 LibraryElement getLibraryElement(String uri) { |
| 148 if (parent != null && parent.hasLibrarySummary(uri)) { | |
| 149 return parent.getLibraryElement(uri); | |
| 150 } | |
| 116 return _resynthesizedLibraries.putIfAbsent(uri, () { | 151 return _resynthesizedLibraries.putIfAbsent(uri, () { |
| 117 PrelinkedLibrary serializedLibrary = getPrelinkedSummary(uri); | 152 PrelinkedLibrary serializedLibrary = getPrelinkedSummary(uri); |
| 118 List<UnlinkedUnit> serializedUnits = <UnlinkedUnit>[ | 153 List<UnlinkedUnit> serializedUnits = <UnlinkedUnit>[ |
| 119 getUnlinkedSummary(uri) | 154 getUnlinkedSummary(uri) |
| 120 ]; | 155 ]; |
| 121 Source librarySource = _getSource(uri); | 156 Source librarySource = _getSource(uri); |
| 122 for (String part in serializedUnits[0].publicNamespace.parts) { | 157 for (String part in serializedUnits[0].publicNamespace.parts) { |
| 123 Source partSource = sourceFactory.resolveUri(librarySource, part); | 158 Source partSource = sourceFactory.resolveUri(librarySource, part); |
| 124 String partAbsUri = partSource.uri.toString(); | 159 String partAbsUri = partSource.uri.toString(); |
| 125 serializedUnits.add(getUnlinkedSummary(partAbsUri)); | 160 serializedUnits.add(getUnlinkedSummary(partAbsUri)); |
| (...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 838 /** | 873 /** |
| 839 * Build a [DartType] object based on an [UnlinkedTypeRef]. This [DartType] | 874 * Build a [DartType] object based on an [UnlinkedTypeRef]. This [DartType] |
| 840 * may refer to elements in other libraries than the library being | 875 * may refer to elements in other libraries than the library being |
| 841 * deserialized, so handles are used to avoid having to deserialize other | 876 * deserialized, so handles are used to avoid having to deserialize other |
| 842 * libraries in the process. | 877 * libraries in the process. |
| 843 */ | 878 */ |
| 844 DartType buildType(UnlinkedTypeRef type) { | 879 DartType buildType(UnlinkedTypeRef type) { |
| 845 if (type.paramReference != 0) { | 880 if (type.paramReference != 0) { |
| 846 // TODO(paulberry): make this work for generic methods. | 881 // TODO(paulberry): make this work for generic methods. |
| 847 return currentTypeParameters[ | 882 return currentTypeParameters[ |
| 848 currentTypeParameters.length - type.paramReference].type; | 883 currentTypeParameters.length - type.paramReference] |
| 884 .type; | |
| 849 } else { | 885 } else { |
| 850 // TODO(paulberry): handle references to things other than classes (note: | 886 // TODO(paulberry): handle references to things other than classes (note: |
| 851 // this should only occur in the case of erroneous code). | 887 // this should only occur in the case of erroneous code). |
| 852 // TODO(paulberry): test reference to something inside a part. | 888 // TODO(paulberry): test reference to something inside a part. |
| 853 // TODO(paulberry): test reference to something inside a part of the | 889 // TODO(paulberry): test reference to something inside a part of the |
| 854 // current lib. | 890 // current lib. |
| 855 UnlinkedReference reference = unlinkedUnit.references[type.reference]; | 891 UnlinkedReference reference = unlinkedUnit.references[type.reference]; |
| 856 PrelinkedReference referenceResolution = | 892 PrelinkedReference referenceResolution = |
| 857 prelinkedUnit.references[type.reference]; | 893 prelinkedUnit.references[type.reference]; |
| 858 ElementLocationImpl location; | 894 ElementLocationImpl location; |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1076 } | 1112 } |
| 1077 for (PropertyAccessorElementImpl accessor in unit.accessors) { | 1113 for (PropertyAccessorElementImpl accessor in unit.accessors) { |
| 1078 elementMap[accessor.identifier] = accessor; | 1114 elementMap[accessor.identifier] = accessor; |
| 1079 } | 1115 } |
| 1080 resummarizedElements[absoluteUri] = elementMap; | 1116 resummarizedElements[absoluteUri] = elementMap; |
| 1081 unitHolder = null; | 1117 unitHolder = null; |
| 1082 prelinkedUnit = null; | 1118 prelinkedUnit = null; |
| 1083 unlinkedUnit = null; | 1119 unlinkedUnit = null; |
| 1084 } | 1120 } |
| 1085 } | 1121 } |
| OLD | NEW |