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

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

Issue 1601973006: Split _LibrarySerializer into two classes. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 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
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/summary_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 serialization.elements; 5 library serialization.elements;
6 6
7 import 'package:analyzer/dart/element/element.dart'; 7 import 'package:analyzer/dart/element/element.dart';
8 import 'package:analyzer/dart/element/type.dart'; 8 import 'package:analyzer/dart/element/type.dart';
9 import 'package:analyzer/src/dart/element/element.dart'; 9 import 'package:analyzer/src/dart/element/element.dart';
10 import 'package:analyzer/src/dart/element/type.dart'; 10 import 'package:analyzer/src/dart/element/type.dart';
11 import 'package:analyzer/src/generated/ast.dart'; 11 import 'package:analyzer/src/generated/ast.dart';
12 import 'package:analyzer/src/generated/resolver.dart'; 12 import 'package:analyzer/src/generated/resolver.dart';
13 import 'package:analyzer/src/generated/utilities_dart.dart'; 13 import 'package:analyzer/src/generated/utilities_dart.dart';
14 import 'package:analyzer/src/summary/format.dart'; 14 import 'package:analyzer/src/summary/format.dart';
15 import 'package:analyzer/src/summary/name_filter.dart'; 15 import 'package:analyzer/src/summary/name_filter.dart';
16 import 'package:analyzer/src/summary/summarize_const_expr.dart'; 16 import 'package:analyzer/src/summary/summarize_const_expr.dart';
17 17
18 /** 18 /**
19 * Serialize all the elements in [lib] to a summary using [ctx] as the context 19 * Serialize all the elements in [lib] to a summary using [ctx] as the context
20 * for building the summary, and using [typeProvider] to find built-in types. 20 * for building the summary, and using [typeProvider] to find built-in types.
21 */ 21 */
22 LibrarySerializationResult serializeLibrary( 22 LibrarySerializationResult serializeLibrary(
23 LibraryElement lib, TypeProvider typeProvider) { 23 LibraryElement lib, TypeProvider typeProvider) {
24 var serializer = new _LibrarySerializer(lib, typeProvider); 24 var serializer = new _LibrarySerializer(lib, typeProvider);
25 LinkedLibraryBuilder linked = serializer.serializeLibrary(); 25 LinkedLibraryBuilder linked = serializer.serializeLibrary();
26 return new LibrarySerializationResult( 26 return new LibrarySerializationResult(
27 linked, serializer.unlinkedUnits, serializer.unitUris); 27 linked, serializer.unlinkedUnits, serializer.unitUris);
28 } 28 }
29 29
30 ReferenceKind _getReferenceKind(Element element) {
31 ReferenceKind kind;
32 if (element is PropertyAccessorElement) {
33 kind = ReferenceKind.topLevelPropertyAccessor;
34 } else if (element is FunctionTypeAliasElement) {
35 kind = ReferenceKind.typedef;
36 } else if (element is ClassElement) {
37 kind = ReferenceKind.classOrEnum;
38 } else if (element is FunctionElement) {
39 kind = ReferenceKind.topLevelFunction;
40 } else {
41 throw new Exception('Unexpected element kind: ${element.runtimeType}');
42 }
43 return kind;
44 }
45
30 /** 46 /**
31 * Data structure holding the result of serializing a [LibraryElement]. 47 * Data structure holding the result of serializing a [LibraryElement].
32 */ 48 */
33 class LibrarySerializationResult { 49 class LibrarySerializationResult {
34 /** 50 /**
35 * Linked information the given library. 51 * Linked information the given library.
36 */ 52 */
37 final LinkedLibraryBuilder linked; 53 final LinkedLibraryBuilder linked;
38 54
39 /** 55 /**
40 * Unlinked information for the compilation units constituting the library. 56 * Unlinked information for the compilation units constituting the library.
41 * The zeroth entry in the list is the defining compilation unit; the 57 * The zeroth entry in the list is the defining compilation unit; the
42 * remaining entries are the parts, in the order listed in the defining 58 * remaining entries are the parts, in the order listed in the defining
43 * compilation unit's part declarations. 59 * compilation unit's part declarations.
44 */ 60 */
45 final List<UnlinkedUnitBuilder> unlinkedUnits; 61 final List<UnlinkedUnitBuilder> unlinkedUnits;
46 62
47 /** 63 /**
48 * Absolute URI of each compilation unit appearing in the library. 64 * Absolute URI of each compilation unit appearing in the library.
49 */ 65 */
50 final List<String> unitUris; 66 final List<String> unitUris;
51 67
52 LibrarySerializationResult(this.linked, this.unlinkedUnits, this.unitUris); 68 LibrarySerializationResult(this.linked, this.unlinkedUnits, this.unitUris);
53 } 69 }
54 70
55 /** 71 /**
56 * Instances of this class keep track of intermediate state during 72 * Instances of this class keep track of intermediate state during
57 * serialization of a single constant [Expression]. 73 * serialization of a single compilation unit.
58 */ 74 */
59 class _ConstExprSerializer extends AbstractConstExprSerializer { 75 class _CompilationUnitSerializer {
60 final _LibrarySerializer serializer; 76 /**
77 * The [_LibrarySerializer] which is serializing the library of which
78 * [compilationUnit] is a part.
79 */
80 final _LibrarySerializer librarySerializer;
61 81
62 _ConstExprSerializer(this.serializer); 82 /**
83 * The [CompilationUnitElement] being serialized.
84 */
85 final CompilationUnitElement compilationUnit;
63 86
64 TypeRefBuilder serializeIdentifier(Identifier identifier) { 87 /**
65 Element element = identifier.staticElement; 88 * The ordinal index of [compilationUnit] within the library, where 0
66 assert(element != null); 89 * represents the defining compilation unit.
67 // TODO(scheglov) how to serialize element references? 90 */
68 return new TypeRefBuilder( 91 final int unitNum;
69 reference: serializer._getElementReferenceId(element));
70 }
71 92
72 @override 93 /**
73 TypeRefBuilder serializeType(TypeName typeName) { 94 * The final linked summary of the compilation unit.
74 DartType type = typeName != null ? typeName.type : DynamicTypeImpl.instance; 95 */
75 return serializer.serializeTypeRef(type, null); 96 final LinkedUnitBuilder linkedUnit = new LinkedUnitBuilder();
76 } 97
77 } 98 /**
99 * The final unlinked summary of the compilation unit.
100 */
101 final UnlinkedUnitBuilder unlinkedUnit = new UnlinkedUnitBuilder();
78 102
79 /** 103 /**
80 * Instances of this class keep track of intermediate state during 104 * Absolute URI of the compilation unit.
81 * serialization of a single library.
82 */ 105 */
83 class _LibrarySerializer { 106 String unitUri;
84 /**
85 * The library to be serialized.
86 */
87 final LibraryElement libraryElement;
88
89 /**
90 * The type provider. This is used to locate the library for `dart:core`.
91 */
92 final TypeProvider typeProvider;
93
94 /**
95 * List of objects which should be written to [LinkedLibrary.units].
96 */
97 final List<LinkedUnitBuilder> linkedUnits = <LinkedUnitBuilder>[];
98
99 /**
100 * List of unlinked units corresponding to the linked units in
101 * [linkedUnits],
102 */
103 final List<UnlinkedUnitBuilder> unlinkedUnits = <UnlinkedUnitBuilder>[];
104
105 /**
106 * List of absolute URIs of the compilation units in the library.
107 */
108 final List<String> unitUris = <String>[];
109
110 /**
111 * Map from [LibraryElement] to the index of the entry in the "dependency
112 * table" that refers to it.
113 */
114 final Map<LibraryElement, int> dependencyMap = <LibraryElement, int>{};
115
116 /**
117 * The "dependency table". This is the list of objects which should be
118 * written to [LinkedLibrary.dependencies].
119 */
120 final List<LinkedDependencyBuilder> dependencies =
121 <LinkedDependencyBuilder>[];
122
123 /**
124 * The linked portion of the "imports table". This is the list of ints
125 * which should be written to [LinkedLibrary.imports].
126 */
127 final List<int> linkedImports = <int>[];
128 107
129 /** 108 /**
130 * Map from [Element] to the index of the entry in the "references table" 109 * Map from [Element] to the index of the entry in the "references table"
131 * that refers to it. 110 * that refers to it.
132 */ 111 */
133 final Map<Element, int> referenceMap = <Element, int>{}; 112 final Map<Element, int> referenceMap = <Element, int>{};
134 113
135 /** 114 /**
136 * The unlinked portion of the "references table". This is the list of 115 * The unlinked portion of the "references table". This is the list of
137 * objects which should be written to [UnlinkedUnit.references]. 116 * objects which should be written to [UnlinkedUnit.references].
138 */ 117 */
139 List<UnlinkedReferenceBuilder> unlinkedReferences; 118 List<UnlinkedReferenceBuilder> unlinkedReferences;
140 119
141 /** 120 /**
142 * The linked portion of the "references table". This is the list of 121 * The linked portion of the "references table". This is the list of
143 * objects which should be written to [LinkedUnit.references]. 122 * objects which should be written to [LinkedUnit.references].
144 */ 123 */
145 List<LinkedReferenceBuilder> linkedReferences; 124 List<LinkedReferenceBuilder> linkedReferences;
146 125
147 //final Map<String, int> prefixIndices = <String, int>{};
148
149 /** 126 /**
150 * Index into the "references table" representing an unresolved reference, if 127 * Index into the "references table" representing an unresolved reference, if
151 * such an index exists. `null` if no such entry has been made in the 128 * such an index exists. `null` if no such entry has been made in the
152 * references table yet. 129 * references table yet.
153 */ 130 */
154 int unresolvedReferenceIndex = null; 131 int unresolvedReferenceIndex = null;
155 132
156 /** 133 _CompilationUnitSerializer(
157 * Set of libraries which have been seen so far while visiting the transitive 134 this.librarySerializer, this.compilationUnit, this.unitNum);
158 * closure of exports.
159 */
160 final Set<LibraryElement> librariesAddedToTransitiveExportClosure =
161 new Set<LibraryElement>();
162
163 /**
164 * Map from imported element to the prefix which may be used to refer to that
165 * element; elements for which no prefix is needed are absent from this map.
166 */
167 final Map<Element, PrefixElement> prefixMap = <Element, PrefixElement>{};
168
169 _LibrarySerializer(this.libraryElement, this.typeProvider) {
170 dependencies.add(new LinkedDependencyBuilder());
171 dependencyMap[libraryElement] = 0;
172 }
173
174 /**
175 * Retrieve the library element for `dart:core`.
176 */
177 LibraryElement get coreLibrary => typeProvider.objectType.element.library;
178 135
179 /** 136 /**
180 * Add all classes, enums, typedefs, executables, and top level variables 137 * Add all classes, enums, typedefs, executables, and top level variables
181 * from the given compilation unit [element] to the library summary. 138 * from the given compilation unit [element] to the compilation unit summary.
182 * [unitNum] indicates the ordinal position of this compilation unit in the 139 * [unitNum] indicates the ordinal position of this compilation unit in the
183 * library. 140 * library.
184 */ 141 */
185 void addCompilationUnitElements(CompilationUnitElement element, int unitNum) { 142 void addCompilationUnitElements() {
186 UnlinkedUnitBuilder b = new UnlinkedUnitBuilder();
187 referenceMap.clear();
188 unlinkedReferences = <UnlinkedReferenceBuilder>[ 143 unlinkedReferences = <UnlinkedReferenceBuilder>[
189 new UnlinkedReferenceBuilder() 144 new UnlinkedReferenceBuilder()
190 ]; 145 ];
191 linkedReferences = <LinkedReferenceBuilder>[ 146 linkedReferences = <LinkedReferenceBuilder>[
192 new LinkedReferenceBuilder(kind: ReferenceKind.classOrEnum) 147 new LinkedReferenceBuilder(kind: ReferenceKind.classOrEnum)
193 ]; 148 ];
194 List<UnlinkedPublicNameBuilder> names = <UnlinkedPublicNameBuilder>[]; 149 List<UnlinkedPublicNameBuilder> names = <UnlinkedPublicNameBuilder>[];
195 for (PropertyAccessorElement accessor in element.accessors) { 150 for (PropertyAccessorElement accessor in compilationUnit.accessors) {
196 if (accessor.isPublic) { 151 if (accessor.isPublic) {
197 names.add(new UnlinkedPublicNameBuilder( 152 names.add(new UnlinkedPublicNameBuilder(
198 kind: ReferenceKind.topLevelPropertyAccessor, 153 kind: ReferenceKind.topLevelPropertyAccessor,
199 name: accessor.name, 154 name: accessor.name,
200 numTypeParameters: accessor.typeParameters.length)); 155 numTypeParameters: accessor.typeParameters.length));
201 } 156 }
202 } 157 }
203 for (ClassElement cls in element.types) { 158 for (ClassElement cls in compilationUnit.types) {
204 if (cls.isPublic) { 159 if (cls.isPublic) {
205 names.add(new UnlinkedPublicNameBuilder( 160 names.add(new UnlinkedPublicNameBuilder(
206 kind: ReferenceKind.classOrEnum, 161 kind: ReferenceKind.classOrEnum,
207 name: cls.name, 162 name: cls.name,
208 numTypeParameters: cls.typeParameters.length)); 163 numTypeParameters: cls.typeParameters.length));
209 } 164 }
210 } 165 }
211 for (ClassElement enm in element.enums) { 166 for (ClassElement enm in compilationUnit.enums) {
212 if (enm.isPublic) { 167 if (enm.isPublic) {
213 names.add(new UnlinkedPublicNameBuilder( 168 names.add(new UnlinkedPublicNameBuilder(
214 kind: ReferenceKind.classOrEnum, name: enm.name)); 169 kind: ReferenceKind.classOrEnum, name: enm.name));
215 } 170 }
216 } 171 }
217 for (FunctionElement function in element.functions) { 172 for (FunctionElement function in compilationUnit.functions) {
218 if (function.isPublic) { 173 if (function.isPublic) {
219 names.add(new UnlinkedPublicNameBuilder( 174 names.add(new UnlinkedPublicNameBuilder(
220 kind: ReferenceKind.topLevelFunction, 175 kind: ReferenceKind.topLevelFunction,
221 name: function.name, 176 name: function.name,
222 numTypeParameters: function.typeParameters.length)); 177 numTypeParameters: function.typeParameters.length));
223 } 178 }
224 } 179 }
225 for (FunctionTypeAliasElement typedef in element.functionTypeAliases) { 180 for (FunctionTypeAliasElement typedef
181 in compilationUnit.functionTypeAliases) {
226 if (typedef.isPublic) { 182 if (typedef.isPublic) {
227 names.add(new UnlinkedPublicNameBuilder( 183 names.add(new UnlinkedPublicNameBuilder(
228 kind: ReferenceKind.typedef, 184 kind: ReferenceKind.typedef,
229 name: typedef.name, 185 name: typedef.name,
230 numTypeParameters: typedef.typeParameters.length)); 186 numTypeParameters: typedef.typeParameters.length));
231 } 187 }
232 } 188 }
233 if (unitNum == 0) { 189 if (unitNum == 0) {
190 LibraryElement libraryElement = librarySerializer.libraryElement;
234 if (libraryElement.name.isNotEmpty) { 191 if (libraryElement.name.isNotEmpty) {
235 b.libraryName = libraryElement.name; 192 LibraryElement libraryElement = librarySerializer.libraryElement;
236 b.libraryNameOffset = libraryElement.nameOffset; 193 unlinkedUnit.libraryName = libraryElement.name;
237 b.libraryNameLength = libraryElement.nameLength; 194 unlinkedUnit.libraryNameOffset = libraryElement.nameOffset;
238 b.libraryDocumentationComment = serializeDocumentation(libraryElement); 195 unlinkedUnit.libraryNameLength = libraryElement.nameLength;
196 unlinkedUnit.libraryDocumentationComment =
197 serializeDocumentation(libraryElement);
239 } 198 }
240 b.publicNamespace = new UnlinkedPublicNamespaceBuilder( 199 unlinkedUnit.publicNamespace = new UnlinkedPublicNamespaceBuilder(
241 exports: libraryElement.exports.map(serializeExportPublic).toList(), 200 exports: libraryElement.exports.map(serializeExportPublic).toList(),
242 parts: libraryElement.parts 201 parts: libraryElement.parts
243 .map((CompilationUnitElement e) => e.uri) 202 .map((CompilationUnitElement e) => e.uri)
244 .toList(), 203 .toList(),
245 names: names); 204 names: names);
246 b.exports = libraryElement.exports.map(serializeExportNonPublic).toList(); 205 unlinkedUnit.exports =
247 b.imports = libraryElement.imports.map(serializeImport).toList(); 206 libraryElement.exports.map(serializeExportNonPublic).toList();
248 b.parts = libraryElement.parts 207 unlinkedUnit.imports =
208 libraryElement.imports.map(serializeImport).toList();
209 unlinkedUnit.parts = libraryElement.parts
249 .map((CompilationUnitElement e) => 210 .map((CompilationUnitElement e) =>
250 new UnlinkedPartBuilder(uriOffset: e.uriOffset, uriEnd: e.uriEnd)) 211 new UnlinkedPartBuilder(uriOffset: e.uriOffset, uriEnd: e.uriEnd))
251 .toList(); 212 .toList();
252 } else { 213 } else {
253 // TODO(paulberry): we need to figure out a way to record library, part, 214 // TODO(paulberry): we need to figure out a way to record library, part,
254 // import, and export declarations that appear in non-defining 215 // import, and export declarations that appear in non-defining
255 // compilation units (even though such declarations are prohibited by the 216 // compilation units (even though such declarations are prohibited by the
256 // language), so that if the user makes code changes that cause a 217 // language), so that if the user makes code changes that cause a
257 // non-defining compilation unit to become a defining compilation unit, 218 // non-defining compilation unit to become a defining compilation unit,
258 // we can create a correct summary by simply re-linking. 219 // we can create a correct summary by simply re-linking.
259 b.publicNamespace = new UnlinkedPublicNamespaceBuilder(names: names); 220 unlinkedUnit.publicNamespace =
221 new UnlinkedPublicNamespaceBuilder(names: names);
260 } 222 }
261 b.classes = element.types.map(serializeClass).toList(); 223 unlinkedUnit.classes = compilationUnit.types.map(serializeClass).toList();
262 b.enums = element.enums.map(serializeEnum).toList(); 224 unlinkedUnit.enums = compilationUnit.enums.map(serializeEnum).toList();
263 b.typedefs = element.functionTypeAliases.map(serializeTypedef).toList(); 225 unlinkedUnit.typedefs =
226 compilationUnit.functionTypeAliases.map(serializeTypedef).toList();
264 List<UnlinkedExecutableBuilder> executables = 227 List<UnlinkedExecutableBuilder> executables =
265 element.functions.map(serializeExecutable).toList(); 228 compilationUnit.functions.map(serializeExecutable).toList();
266 for (PropertyAccessorElement accessor in element.accessors) { 229 for (PropertyAccessorElement accessor in compilationUnit.accessors) {
267 if (!accessor.isSynthetic) { 230 if (!accessor.isSynthetic) {
268 executables.add(serializeExecutable(accessor)); 231 executables.add(serializeExecutable(accessor));
269 } 232 }
270 } 233 }
271 b.executables = executables; 234 unlinkedUnit.executables = executables;
272 List<UnlinkedVariableBuilder> variables = <UnlinkedVariableBuilder>[]; 235 List<UnlinkedVariableBuilder> variables = <UnlinkedVariableBuilder>[];
273 for (PropertyAccessorElement accessor in element.accessors) { 236 for (PropertyAccessorElement accessor in compilationUnit.accessors) {
274 if (accessor.isSynthetic && accessor.isGetter) { 237 if (accessor.isSynthetic && accessor.isGetter) {
275 PropertyInducingElement variable = accessor.variable; 238 PropertyInducingElement variable = accessor.variable;
276 if (variable != null) { 239 if (variable != null) {
277 assert(!variable.isSynthetic); 240 assert(!variable.isSynthetic);
278 variables.add(serializeVariable(variable)); 241 variables.add(serializeVariable(variable));
279 } 242 }
280 } 243 }
281 } 244 }
282 b.variables = variables; 245 unlinkedUnit.variables = variables;
283 b.references = unlinkedReferences; 246 unlinkedUnit.references = unlinkedReferences;
284 unlinkedUnits.add(b); 247 linkedUnit.references = linkedReferences;
285 linkedUnits.add(new LinkedUnitBuilder(references: linkedReferences)); 248 unitUri = compilationUnit.source.uri.toString();
286 unitUris.add(element.source.uri.toString());
287 unlinkedReferences = null;
288 linkedReferences = null;
289 } 249 }
290 250
291 /** 251 /**
292 * Add [exportedLibrary] (and the transitive closure of all libraries it
293 * exports) to the dependency table ([LinkedLibrary.dependencies]).
294 */
295 void addTransitiveExportClosure(LibraryElement exportedLibrary) {
296 if (librariesAddedToTransitiveExportClosure.add(exportedLibrary)) {
297 serializeDependency(exportedLibrary);
298 for (LibraryElement transitiveExport
299 in exportedLibrary.exportedLibraries) {
300 addTransitiveExportClosure(transitiveExport);
301 }
302 }
303 }
304
305 /**
306 * Fill in [prefixMap] using information from [libraryElement.imports].
307 */
308 void computePrefixMap() {
309 for (ImportElement import in libraryElement.imports) {
310 if (import.prefix == null) {
311 continue;
312 }
313 import.importedLibrary.exportNamespace.definedNames
314 .forEach((String name, Element e) {
315 if (new NameFilter.forNamespaceCombinators(import.combinators)
316 .accepts(name)) {
317 prefixMap[e] = import.prefix;
318 }
319 });
320 }
321 }
322
323 /**
324 * Compute the appropriate De Bruijn index to represent the given type 252 * Compute the appropriate De Bruijn index to represent the given type
325 * parameter [type]. 253 * parameter [type].
326 */ 254 */
327 int findTypeParameterIndex(TypeParameterType type, Element context) { 255 int findTypeParameterIndex(TypeParameterType type, Element context) {
328 int index = 0; 256 int index = 0;
329 while (context != null) { 257 while (context != null) {
330 List<TypeParameterElement> typeParameters; 258 List<TypeParameterElement> typeParameters;
331 if (context is ClassElement) { 259 if (context is ClassElement) {
332 typeParameters = context.typeParameters; 260 typeParameters = context.typeParameters;
333 } else if (context is FunctionTypeAliasElement) { 261 } else if (context is FunctionTypeAliasElement) {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 /** 342 /**
415 * Serialize the given [expression], creating an [UnlinkedConstBuilder]. 343 * Serialize the given [expression], creating an [UnlinkedConstBuilder].
416 */ 344 */
417 UnlinkedConstBuilder serializeConstExpr(Expression expression) { 345 UnlinkedConstBuilder serializeConstExpr(Expression expression) {
418 _ConstExprSerializer serializer = new _ConstExprSerializer(this); 346 _ConstExprSerializer serializer = new _ConstExprSerializer(this);
419 serializer.serialize(expression); 347 serializer.serialize(expression);
420 return serializer.toBuilder(); 348 return serializer.toBuilder();
421 } 349 }
422 350
423 /** 351 /**
424 * Return the index of the entry in the dependency table
425 * ([LinkedLibrary.dependencies]) for the given [dependentLibrary]. A new
426 * entry is added to the table if necessary to satisfy the request.
427 */
428 int serializeDependency(LibraryElement dependentLibrary) {
429 return dependencyMap.putIfAbsent(dependentLibrary, () {
430 int index = dependencies.length;
431 List<String> parts = dependentLibrary.parts
432 .map((CompilationUnitElement e) => e.source.uri.toString())
433 .toList();
434 dependencies.add(new LinkedDependencyBuilder(
435 uri: dependentLibrary.source.uri.toString(), parts: parts));
436 return index;
437 });
438 }
439
440 /**
441 * Serialize documentation from the given [element], creating an 352 * Serialize documentation from the given [element], creating an
442 * [UnlinkedDocumentationComment]. 353 * [UnlinkedDocumentationComment].
443 * 354 *
444 * If [element] has no documentation, `null` is returned. 355 * If [element] has no documentation, `null` is returned.
445 */ 356 */
446 UnlinkedDocumentationCommentBuilder serializeDocumentation(Element element) { 357 UnlinkedDocumentationCommentBuilder serializeDocumentation(Element element) {
447 if (element.documentationComment == null) { 358 if (element.documentationComment == null) {
448 return null; 359 return null;
449 } 360 }
450 return new UnlinkedDocumentationCommentBuilder( 361 return new UnlinkedDocumentationCommentBuilder(
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 b.uriOffset = exportElement.uriOffset; 441 b.uriOffset = exportElement.uriOffset;
531 b.uriEnd = exportElement.uriEnd; 442 b.uriEnd = exportElement.uriEnd;
532 return b; 443 return b;
533 } 444 }
534 445
535 /** 446 /**
536 * Serialize the given [exportElement] into an [UnlinkedExportPublic]. 447 * Serialize the given [exportElement] into an [UnlinkedExportPublic].
537 */ 448 */
538 UnlinkedExportPublicBuilder serializeExportPublic( 449 UnlinkedExportPublicBuilder serializeExportPublic(
539 ExportElement exportElement) { 450 ExportElement exportElement) {
540 addTransitiveExportClosure(exportElement.exportedLibrary);
541 UnlinkedExportPublicBuilder b = new UnlinkedExportPublicBuilder(); 451 UnlinkedExportPublicBuilder b = new UnlinkedExportPublicBuilder();
542 b.uri = exportElement.uri; 452 b.uri = exportElement.uri;
543 b.combinators = exportElement.combinators.map(serializeCombinator).toList(); 453 b.combinators = exportElement.combinators.map(serializeCombinator).toList();
544 return b; 454 return b;
545 } 455 }
546 456
547 /** 457 /**
548 * Serialize the given [importElement] yielding an [UnlinkedImportBuilder]. 458 * Serialize the given [importElement] yielding an [UnlinkedImportBuilder].
549 * Also, add linked information about it to the [linkedImports] list. 459 * Also, add linked information about it to the [linkedImports] list.
550 */ 460 */
551 UnlinkedImportBuilder serializeImport(ImportElement importElement) { 461 UnlinkedImportBuilder serializeImport(ImportElement importElement) {
552 UnlinkedImportBuilder b = new UnlinkedImportBuilder(); 462 UnlinkedImportBuilder b = new UnlinkedImportBuilder();
553 b.isDeferred = importElement.isDeferred; 463 b.isDeferred = importElement.isDeferred;
554 b.offset = importElement.nameOffset; 464 b.offset = importElement.nameOffset;
555 b.combinators = importElement.combinators.map(serializeCombinator).toList(); 465 b.combinators = importElement.combinators.map(serializeCombinator).toList();
556 if (importElement.prefix != null) { 466 if (importElement.prefix != null) {
557 b.prefixReference = serializePrefix(importElement.prefix); 467 b.prefixReference = serializePrefix(importElement.prefix);
558 b.prefixOffset = importElement.prefix.nameOffset; 468 b.prefixOffset = importElement.prefix.nameOffset;
559 } 469 }
560 if (importElement.isSynthetic) { 470 if (importElement.isSynthetic) {
561 b.isImplicit = true; 471 b.isImplicit = true;
562 } else { 472 } else {
563 b.uri = importElement.uri; 473 b.uri = importElement.uri;
564 b.uriOffset = importElement.uriOffset; 474 b.uriOffset = importElement.uriOffset;
565 b.uriEnd = importElement.uriEnd; 475 b.uriEnd = importElement.uriEnd;
566 } 476 }
567 addTransitiveExportClosure(importElement.importedLibrary);
568 linkedImports.add(serializeDependency(importElement.importedLibrary));
569 return b; 477 return b;
570 } 478 }
571 479
572 /** 480 /**
573 * Serialize the whole library element into a [LinkedLibrary]. Should be
574 * called exactly once for each instance of [_LibrarySerializer].
575 *
576 * The unlinked compilation units are stored in [unlinkedUnits], and their
577 * absolute URIs are stored in [unitUris].
578 */
579 LinkedLibraryBuilder serializeLibrary() {
580 computePrefixMap();
581 LinkedLibraryBuilder pb = new LinkedLibraryBuilder();
582 addCompilationUnitElements(libraryElement.definingCompilationUnit, 0);
583 for (int i = 0; i < libraryElement.parts.length; i++) {
584 addCompilationUnitElements(libraryElement.parts[i], i + 1);
585 }
586 pb.units = linkedUnits;
587 pb.dependencies = dependencies;
588 pb.importDependencies = linkedImports;
589 List<String> exportedNames =
590 libraryElement.exportNamespace.definedNames.keys.toList();
591 exportedNames.sort();
592 List<LinkedExportNameBuilder> exportNames = <LinkedExportNameBuilder>[];
593 for (String name in exportedNames) {
594 if (libraryElement.publicNamespace.definedNames.containsKey(name)) {
595 continue;
596 }
597 Element element = libraryElement.exportNamespace.get(name);
598 LibraryElement dependentLibrary = element.library;
599 CompilationUnitElement unitElement =
600 element.getAncestor((Element e) => e is CompilationUnitElement);
601 int unit = dependentLibrary.units.indexOf(unitElement);
602 assert(unit != -1);
603 ReferenceKind kind = _getReferenceKind(element);
604 exportNames.add(new LinkedExportNameBuilder(
605 name: name,
606 dependency: serializeDependency(dependentLibrary),
607 unit: unit,
608 kind: kind));
609 }
610 pb.exportNames = exportNames;
611 return pb;
612 }
613
614 /**
615 * Serialize the given [parameter] into an [UnlinkedParam]. 481 * Serialize the given [parameter] into an [UnlinkedParam].
616 */ 482 */
617 UnlinkedParamBuilder serializeParam(ParameterElement parameter, 483 UnlinkedParamBuilder serializeParam(ParameterElement parameter,
618 [Element context]) { 484 [Element context]) {
619 context ??= parameter; 485 context ??= parameter;
620 UnlinkedParamBuilder b = new UnlinkedParamBuilder(); 486 UnlinkedParamBuilder b = new UnlinkedParamBuilder();
621 b.name = parameter.name; 487 b.name = parameter.name;
622 b.nameOffset = parameter.nameOffset; 488 b.nameOffset = parameter.nameOffset;
623 switch (parameter.parameterKind) { 489 switch (parameter.parameterKind) {
624 case ParameterKind.REQUIRED: 490 case ParameterKind.REQUIRED:
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 int numTypeParameters = 0; 669 int numTypeParameters = 0;
804 if (element is TypeParameterizedElement) { 670 if (element is TypeParameterizedElement) {
805 numTypeParameters = element.typeParameters.length; 671 numTypeParameters = element.typeParameters.length;
806 } 672 }
807 // Figure out a prefix that may be used to refer to the given type. 673 // Figure out a prefix that may be used to refer to the given type.
808 // TODO(paulberry): to avoid subtle relinking inconsistencies we 674 // TODO(paulberry): to avoid subtle relinking inconsistencies we
809 // should use the actual prefix from the AST (a given type may be 675 // should use the actual prefix from the AST (a given type may be
810 // reachable via multiple prefixes), but sadly, this information is 676 // reachable via multiple prefixes), but sadly, this information is
811 // not recorded in the element model. 677 // not recorded in the element model.
812 int prefixReference = 0; 678 int prefixReference = 0;
813 PrefixElement prefix = prefixMap[element]; 679 PrefixElement prefix = librarySerializer.prefixMap[element];
814 if (prefix != null) { 680 if (prefix != null) {
815 prefixReference = serializePrefix(prefix); 681 prefixReference = serializePrefix(prefix);
816 } 682 }
817 int index = unlinkedReferences.length; 683 int index = unlinkedReferences.length;
818 unlinkedReferences.add(new UnlinkedReferenceBuilder( 684 unlinkedReferences.add(new UnlinkedReferenceBuilder(
819 name: element.name, prefixReference: prefixReference)); 685 name: element.name, prefixReference: prefixReference));
820 linkedReferences.add(new LinkedReferenceBuilder( 686 linkedReferences.add(new LinkedReferenceBuilder(
821 dependency: serializeDependency(dependentLibrary), 687 dependency: librarySerializer.serializeDependency(dependentLibrary),
822 kind: _getReferenceKind(element), 688 kind: _getReferenceKind(element),
823 unit: unit, 689 unit: unit,
824 numTypeParameters: numTypeParameters)); 690 numTypeParameters: numTypeParameters));
825 return index; 691 return index;
826 }); 692 });
827 } 693 }
828
829 ReferenceKind _getReferenceKind(Element element) {
830 ReferenceKind kind;
831 if (element is PropertyAccessorElement) {
832 kind = ReferenceKind.topLevelPropertyAccessor;
833 } else if (element is FunctionTypeAliasElement) {
834 kind = ReferenceKind.typedef;
835 } else if (element is ClassElement) {
836 kind = ReferenceKind.classOrEnum;
837 } else if (element is FunctionElement) {
838 kind = ReferenceKind.topLevelFunction;
839 } else {
840 throw new Exception('Unexpected element kind: ${element.runtimeType}');
841 }
842 return kind;
843 }
844 } 694 }
695
696 /**
697 * Instances of this class keep track of intermediate state during
698 * serialization of a single constant [Expression].
699 */
700 class _ConstExprSerializer extends AbstractConstExprSerializer {
701 final _CompilationUnitSerializer serializer;
702
703 _ConstExprSerializer(this.serializer);
704
705 TypeRefBuilder serializeIdentifier(Identifier identifier) {
706 Element element = identifier.staticElement;
707 assert(element != null);
708 // TODO(scheglov) how to serialize element references?
709 return new TypeRefBuilder(
710 reference: serializer._getElementReferenceId(element));
711 }
712
713 @override
714 TypeRefBuilder serializeType(TypeName typeName) {
715 DartType type = typeName != null ? typeName.type : DynamicTypeImpl.instance;
716 return serializer.serializeTypeRef(type, null);
717 }
718 }
719
720 /**
721 * Instances of this class keep track of intermediate state during
722 * serialization of a single library.
723 */
724 class _LibrarySerializer {
725 /**
726 * The library to be serialized.
727 */
728 final LibraryElement libraryElement;
729
730 /**
731 * The type provider. This is used to locate the library for `dart:core`.
732 */
733 final TypeProvider typeProvider;
734
735 /**
736 * Map from [LibraryElement] to the index of the entry in the "dependency
737 * table" that refers to it.
738 */
739 final Map<LibraryElement, int> dependencyMap = <LibraryElement, int>{};
740
741 /**
742 * The "dependency table". This is the list of objects which should be
743 * written to [LinkedLibrary.dependencies].
744 */
745 final List<LinkedDependencyBuilder> dependencies =
746 <LinkedDependencyBuilder>[];
747
748 /**
749 * The linked portion of the "imports table". This is the list of ints
750 * which should be written to [LinkedLibrary.imports].
751 */
752 final List<int> linkedImports = <int>[];
753
754 /**
755 * Set of libraries which have been seen so far while visiting the transitive
756 * closure of exports.
757 */
758 final Set<LibraryElement> librariesAddedToTransitiveExportClosure =
759 new Set<LibraryElement>();
760
761 /**
762 * Map from imported element to the prefix which may be used to refer to that
763 * element; elements for which no prefix is needed are absent from this map.
764 */
765 final Map<Element, PrefixElement> prefixMap = <Element, PrefixElement>{};
766
767 /**
768 * List of serializers for the compilation units constituting this library.
769 */
770 final List<_CompilationUnitSerializer> compilationUnitSerializers =
771 <_CompilationUnitSerializer>[];
772
773 _LibrarySerializer(this.libraryElement, this.typeProvider) {
774 dependencies.add(new LinkedDependencyBuilder());
775 dependencyMap[libraryElement] = 0;
776 }
777
778 /**
779 * Retrieve a list of the URIs for the compilation units in the library.
780 */
781 List<String> get unitUris => compilationUnitSerializers
782 .map((_CompilationUnitSerializer s) => s.unitUri)
783 .toList();
784
785 /**
786 * Retrieve a list of the [UnlinkedUnitBuilder]s for the compilation units in
787 * the library.
788 */
789 List<UnlinkedUnitBuilder> get unlinkedUnits => compilationUnitSerializers
790 .map((_CompilationUnitSerializer s) => s.unlinkedUnit)
791 .toList();
792
793 /**
794 * Add [exportedLibrary] (and the transitive closure of all libraries it
795 * exports) to the dependency table ([LinkedLibrary.dependencies]).
796 */
797 void addTransitiveExportClosure(LibraryElement exportedLibrary) {
798 if (librariesAddedToTransitiveExportClosure.add(exportedLibrary)) {
799 serializeDependency(exportedLibrary);
800 for (LibraryElement transitiveExport
801 in exportedLibrary.exportedLibraries) {
802 addTransitiveExportClosure(transitiveExport);
803 }
804 }
805 }
806
807 /**
808 * Fill in [prefixMap] using information from [libraryElement.imports].
809 */
810 void computePrefixMap() {
811 for (ImportElement import in libraryElement.imports) {
812 if (import.prefix == null) {
813 continue;
814 }
815 import.importedLibrary.exportNamespace.definedNames
816 .forEach((String name, Element e) {
817 if (new NameFilter.forNamespaceCombinators(import.combinators)
818 .accepts(name)) {
819 prefixMap[e] = import.prefix;
820 }
821 });
822 }
823 }
824
825 /**
826 * Return the index of the entry in the dependency table
827 * ([LinkedLibrary.dependencies]) for the given [dependentLibrary]. A new
828 * entry is added to the table if necessary to satisfy the request.
829 */
830 int serializeDependency(LibraryElement dependentLibrary) {
831 return dependencyMap.putIfAbsent(dependentLibrary, () {
832 int index = dependencies.length;
833 List<String> parts = dependentLibrary.parts
834 .map((CompilationUnitElement e) => e.source.uri.toString())
835 .toList();
836 dependencies.add(new LinkedDependencyBuilder(
837 uri: dependentLibrary.source.uri.toString(), parts: parts));
838 return index;
839 });
840 }
841
842 /**
843 * Serialize the whole library element into a [LinkedLibrary]. Should be
844 * called exactly once for each instance of [_LibrarySerializer].
845 *
846 * The unlinked compilation units are stored in [unlinkedUnits], and their
847 * absolute URIs are stored in [unitUris].
848 */
849 LinkedLibraryBuilder serializeLibrary() {
850 computePrefixMap();
851 LinkedLibraryBuilder pb = new LinkedLibraryBuilder();
852 for (ExportElement exportElement in libraryElement.exports) {
853 addTransitiveExportClosure(exportElement.exportedLibrary);
854 }
855 for (ImportElement importElement in libraryElement.imports) {
856 addTransitiveExportClosure(importElement.importedLibrary);
857 linkedImports.add(serializeDependency(importElement.importedLibrary));
858 }
859 compilationUnitSerializers.add(new _CompilationUnitSerializer(
860 this, libraryElement.definingCompilationUnit, 0));
861 for (int i = 0; i < libraryElement.parts.length; i++) {
862 compilationUnitSerializers.add(
863 new _CompilationUnitSerializer(this, libraryElement.parts[i], i + 1));
864 }
865 for (_CompilationUnitSerializer compilationUnitSerializer
866 in compilationUnitSerializers) {
867 compilationUnitSerializer.addCompilationUnitElements();
868 }
869 pb.units = compilationUnitSerializers
870 .map((_CompilationUnitSerializer s) => s.linkedUnit)
871 .toList();
872 pb.dependencies = dependencies;
873 pb.importDependencies = linkedImports;
874 List<String> exportedNames =
875 libraryElement.exportNamespace.definedNames.keys.toList();
876 exportedNames.sort();
877 List<LinkedExportNameBuilder> exportNames = <LinkedExportNameBuilder>[];
878 for (String name in exportedNames) {
879 if (libraryElement.publicNamespace.definedNames.containsKey(name)) {
880 continue;
881 }
882 Element element = libraryElement.exportNamespace.get(name);
883 LibraryElement dependentLibrary = element.library;
884 CompilationUnitElement unitElement =
885 element.getAncestor((Element e) => e is CompilationUnitElement);
886 int unit = dependentLibrary.units.indexOf(unitElement);
887 assert(unit != -1);
888 ReferenceKind kind = _getReferenceKind(element);
889 exportNames.add(new LinkedExportNameBuilder(
890 name: name,
891 dependency: serializeDependency(dependentLibrary),
892 unit: unit,
893 kind: kind));
894 }
895 pb.exportNames = exportNames;
896 return pb;
897 }
898 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/summary_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698