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 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/type.dart'; | 9 import 'package:analyzer/src/dart/element/type.dart'; |
10 import 'package:analyzer/src/generated/resolver.dart'; | 10 import 'package:analyzer/src/generated/resolver.dart'; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 final List<PrelinkedDependencyBuilder> dependencies = | 54 final List<PrelinkedDependencyBuilder> dependencies = |
55 <PrelinkedDependencyBuilder>[]; | 55 <PrelinkedDependencyBuilder>[]; |
56 | 56 |
57 /** | 57 /** |
58 * The prelinked portion of the "imports table". This is the list of ints | 58 * The prelinked portion of the "imports table". This is the list of ints |
59 * which should be written to [PrelinkedLibrary.imports]. | 59 * which should be written to [PrelinkedLibrary.imports]. |
60 */ | 60 */ |
61 final List<int> prelinkedImports = <int>[]; | 61 final List<int> prelinkedImports = <int>[]; |
62 | 62 |
63 /** | 63 /** |
64 * Map from prefix [String] to the index of the entry in the "prefix" table | |
65 * that refers to it. The empty prefix is not included in this map. | |
66 */ | |
67 final Map<String, int> prefixMap = <String, int>{}; | |
68 | |
69 /** | |
70 * The "prefix table". This is the list of objects which should be written | |
71 * to [UnlinkedLibrary.prefixes]. | |
72 */ | |
73 final List<UnlinkedPrefixBuilder> prefixes = <UnlinkedPrefixBuilder>[]; | |
74 | |
75 /** | |
76 * Map from [Element] to the index of the entry in the "references table" | 64 * Map from [Element] to the index of the entry in the "references table" |
77 * that refers to it. | 65 * that refers to it. |
78 */ | 66 */ |
79 final Map<Element, int> referenceMap = <Element, int>{}; | 67 final Map<Element, int> referenceMap = <Element, int>{}; |
80 | 68 |
81 /** | 69 /** |
82 * The unlinked portion of the "references table". This is the list of | 70 * The unlinked portion of the "references table". This is the list of |
83 * objects which should be written to [UnlinkedUnit.references]. | 71 * objects which should be written to [UnlinkedUnit.references]. |
84 */ | 72 */ |
85 List<UnlinkedReferenceBuilder> unlinkedReferences; | 73 List<UnlinkedReferenceBuilder> unlinkedReferences; |
(...skipping 21 matching lines...) Expand all Loading... |
107 new Set<LibraryElement>(); | 95 new Set<LibraryElement>(); |
108 | 96 |
109 /** | 97 /** |
110 * [BuilderContext] used to serialize the output summary. | 98 * [BuilderContext] used to serialize the output summary. |
111 */ | 99 */ |
112 final BuilderContext ctx; | 100 final BuilderContext ctx; |
113 | 101 |
114 _LibrarySerializer(this.ctx, this.libraryElement, this.typeProvider) { | 102 _LibrarySerializer(this.ctx, this.libraryElement, this.typeProvider) { |
115 dependencies.add(encodePrelinkedDependency(ctx)); | 103 dependencies.add(encodePrelinkedDependency(ctx)); |
116 dependencyMap[libraryElement] = 0; | 104 dependencyMap[libraryElement] = 0; |
117 prefixes.add(encodeUnlinkedPrefix(ctx)); | |
118 } | 105 } |
119 | 106 |
120 /** | 107 /** |
121 * Retrieve the library element for `dart:core`. | 108 * Retrieve the library element for `dart:core`. |
122 */ | 109 */ |
123 LibraryElement get coreLibrary => typeProvider.objectType.element.library; | 110 LibraryElement get coreLibrary => typeProvider.objectType.element.library; |
124 | 111 |
125 /** | 112 /** |
126 * Add all classes, enums, typedefs, executables, and top level variables | 113 * Add all classes, enums, typedefs, executables, and top level variables |
127 * from the given compilation unit [element] to the library summary. | 114 * from the given compilation unit [element] to the library summary. |
128 * [unitNum] indicates the ordinal position of this compilation unit in the | 115 * [unitNum] indicates the ordinal position of this compilation unit in the |
129 * library. | 116 * library. |
130 */ | 117 */ |
131 void addCompilationUnitElements(CompilationUnitElement element, int unitNum) { | 118 void addCompilationUnitElements(CompilationUnitElement element, int unitNum) { |
132 UnlinkedUnitBuilder b = new UnlinkedUnitBuilder(ctx); | 119 UnlinkedUnitBuilder b = new UnlinkedUnitBuilder(ctx); |
| 120 unlinkedReferences = <UnlinkedReferenceBuilder>[ |
| 121 encodeUnlinkedReference(ctx) |
| 122 ]; |
| 123 prelinkedReferences = <PrelinkedReferenceBuilder>[ |
| 124 encodePrelinkedReference(ctx, kind: PrelinkedReferenceKind.classOrEnum) |
| 125 ]; |
133 if (unitNum == 0) { | 126 if (unitNum == 0) { |
134 // TODO(paulberry): we need to figure out a way to record library, part, | 127 // TODO(paulberry): we need to figure out a way to record library, part, |
135 // import, and export declarations that appear in non-defining | 128 // import, and export declarations that appear in non-defining |
136 // compilation units (even though such declarations are prohibited by the | 129 // compilation units (even though such declarations are prohibited by the |
137 // language), so that if the user makes code changes that cause a | 130 // language), so that if the user makes code changes that cause a |
138 // non-defining compilation unit to become a defining compilation unit, | 131 // non-defining compilation unit to become a defining compilation unit, |
139 // we can create a correct summary by simply re-linking. | 132 // we can create a correct summary by simply re-linking. |
140 if (libraryElement.name.isNotEmpty) { | 133 if (libraryElement.name.isNotEmpty) { |
141 b.libraryName = libraryElement.name; | 134 b.libraryName = libraryElement.name; |
142 } | 135 } |
143 b.exports = libraryElement.exports.map(serializeExport).toList(); | 136 b.exports = libraryElement.exports.map(serializeExport).toList(); |
144 b.imports = libraryElement.imports.map(serializeImport).toList(); | 137 b.imports = libraryElement.imports.map(serializeImport).toList(); |
145 b.parts = libraryElement.parts | 138 b.parts = libraryElement.parts |
146 .map( | 139 .map( |
147 (CompilationUnitElement e) => encodeUnlinkedPart(ctx, uri: e.uri)) | 140 (CompilationUnitElement e) => encodeUnlinkedPart(ctx, uri: e.uri)) |
148 .toList(); | 141 .toList(); |
149 } | 142 } |
150 unlinkedReferences = <UnlinkedReferenceBuilder>[ | |
151 encodeUnlinkedReference(ctx) | |
152 ]; | |
153 prelinkedReferences = <PrelinkedReferenceBuilder>[ | |
154 encodePrelinkedReference(ctx, kind: PrelinkedReferenceKind.classOrEnum) | |
155 ]; | |
156 b.classes = element.types.map(serializeClass).toList(); | 143 b.classes = element.types.map(serializeClass).toList(); |
157 b.enums = element.enums.map(serializeEnum).toList(); | 144 b.enums = element.enums.map(serializeEnum).toList(); |
158 b.typedefs = element.functionTypeAliases.map(serializeTypedef).toList(); | 145 b.typedefs = element.functionTypeAliases.map(serializeTypedef).toList(); |
159 List<UnlinkedExecutableBuilder> executables = | 146 List<UnlinkedExecutableBuilder> executables = |
160 element.functions.map(serializeExecutable).toList(); | 147 element.functions.map(serializeExecutable).toList(); |
161 for (PropertyAccessorElement accessor in element.accessors) { | 148 for (PropertyAccessorElement accessor in element.accessors) { |
162 if (!accessor.isSynthetic) { | 149 if (!accessor.isSynthetic) { |
163 executables.add(serializeExecutable(accessor)); | 150 executables.add(serializeExecutable(accessor)); |
164 } | 151 } |
165 } | 152 } |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 /** | 362 /** |
376 * Serialize the given [importElement] yielding an [UnlinkedImportBuilder]. | 363 * Serialize the given [importElement] yielding an [UnlinkedImportBuilder]. |
377 * Also, add pre-linked information about it to the [prelinkedImports] list. | 364 * Also, add pre-linked information about it to the [prelinkedImports] list. |
378 */ | 365 */ |
379 UnlinkedImportBuilder serializeImport(ImportElement importElement) { | 366 UnlinkedImportBuilder serializeImport(ImportElement importElement) { |
380 UnlinkedImportBuilder b = new UnlinkedImportBuilder(ctx); | 367 UnlinkedImportBuilder b = new UnlinkedImportBuilder(ctx); |
381 b.isDeferred = importElement.isDeferred; | 368 b.isDeferred = importElement.isDeferred; |
382 b.offset = importElement.nameOffset; | 369 b.offset = importElement.nameOffset; |
383 b.combinators = importElement.combinators.map(serializeCombinator).toList(); | 370 b.combinators = importElement.combinators.map(serializeCombinator).toList(); |
384 if (importElement.prefix != null) { | 371 if (importElement.prefix != null) { |
385 b.prefix = prefixMap.putIfAbsent(importElement.prefix.name, () { | 372 b.prefixReference = serializePrefix(importElement.prefix); |
386 int index = prefixes.length; | |
387 prefixes | |
388 .add(encodeUnlinkedPrefix(ctx, name: importElement.prefix.name)); | |
389 return index; | |
390 }); | |
391 } | 373 } |
392 if (importElement.isSynthetic) { | 374 if (importElement.isSynthetic) { |
393 b.isImplicit = true; | 375 b.isImplicit = true; |
394 } else { | 376 } else { |
395 b.uri = importElement.uri; | 377 b.uri = importElement.uri; |
396 } | 378 } |
397 addTransitiveExportClosure(importElement.importedLibrary); | 379 addTransitiveExportClosure(importElement.importedLibrary); |
398 prelinkedImports.add(serializeDependency(importElement.importedLibrary)); | 380 prelinkedImports.add(serializeDependency(importElement.importedLibrary)); |
399 return b; | 381 return b; |
400 } | 382 } |
401 | 383 |
402 /** | 384 /** |
403 * Serialize the whole library element into a [PrelinkedLibrary]. Should be | 385 * Serialize the whole library element into a [PrelinkedLibrary]. Should be |
404 * called exactly once for each instance of [_LibrarySerializer]. | 386 * called exactly once for each instance of [_LibrarySerializer]. |
405 */ | 387 */ |
406 PrelinkedLibraryBuilder serializeLibrary() { | 388 PrelinkedLibraryBuilder serializeLibrary() { |
407 UnlinkedLibraryBuilder ub = new UnlinkedLibraryBuilder(ctx); | |
408 PrelinkedLibraryBuilder pb = new PrelinkedLibraryBuilder(ctx); | 389 PrelinkedLibraryBuilder pb = new PrelinkedLibraryBuilder(ctx); |
409 addCompilationUnitElements(libraryElement.definingCompilationUnit, 0); | 390 addCompilationUnitElements(libraryElement.definingCompilationUnit, 0); |
410 for (int i = 0; i < libraryElement.parts.length; i++) { | 391 for (int i = 0; i < libraryElement.parts.length; i++) { |
411 addCompilationUnitElements(libraryElement.parts[i], i + 1); | 392 addCompilationUnitElements(libraryElement.parts[i], i + 1); |
412 } | 393 } |
413 ub.prefixes = prefixes; | |
414 pb.units = units; | 394 pb.units = units; |
415 pb.unlinked = ub; | |
416 pb.dependencies = dependencies; | 395 pb.dependencies = dependencies; |
417 pb.importDependencies = prelinkedImports; | 396 pb.importDependencies = prelinkedImports; |
418 return pb; | 397 return pb; |
419 } | 398 } |
420 | 399 |
421 /** | 400 /** |
422 * Serialize the given [parameter] into an [UnlinkedParam]. | 401 * Serialize the given [parameter] into an [UnlinkedParam]. |
423 */ | 402 */ |
424 UnlinkedParamBuilder serializeParam(ParameterElement parameter) { | 403 UnlinkedParamBuilder serializeParam(ParameterElement parameter) { |
425 UnlinkedParamBuilder b = new UnlinkedParamBuilder(ctx); | 404 UnlinkedParamBuilder b = new UnlinkedParamBuilder(ctx); |
(...skipping 18 matching lines...) Expand all Loading... |
444 } | 423 } |
445 b.parameters = type.parameters.map(serializeParam).toList(); | 424 b.parameters = type.parameters.map(serializeParam).toList(); |
446 } else { | 425 } else { |
447 b.type = serializeTypeRef(type, parameter); | 426 b.type = serializeTypeRef(type, parameter); |
448 b.hasImplicitType = parameter.hasImplicitType; | 427 b.hasImplicitType = parameter.hasImplicitType; |
449 } | 428 } |
450 return b; | 429 return b; |
451 } | 430 } |
452 | 431 |
453 /** | 432 /** |
| 433 * Serialize the given [prefix] into an index into the references table. |
| 434 */ |
| 435 int serializePrefix(PrefixElement element) { |
| 436 return referenceMap.putIfAbsent(element, () { |
| 437 assert(unlinkedReferences.length == prelinkedReferences.length); |
| 438 int index = unlinkedReferences.length; |
| 439 unlinkedReferences.add(encodeUnlinkedReference(ctx, name: element.name)); |
| 440 prelinkedReferences.add( |
| 441 encodePrelinkedReference(ctx, kind: PrelinkedReferenceKind.prefix)); |
| 442 return index; |
| 443 }); |
| 444 } |
| 445 |
| 446 /** |
454 * Serialize the given [typedefElement], creating an [UnlinkedTypedef]. | 447 * Serialize the given [typedefElement], creating an [UnlinkedTypedef]. |
455 */ | 448 */ |
456 UnlinkedTypedefBuilder serializeTypedef( | 449 UnlinkedTypedefBuilder serializeTypedef( |
457 FunctionTypeAliasElement typedefElement) { | 450 FunctionTypeAliasElement typedefElement) { |
458 UnlinkedTypedefBuilder b = new UnlinkedTypedefBuilder(ctx); | 451 UnlinkedTypedefBuilder b = new UnlinkedTypedefBuilder(ctx); |
459 b.name = typedefElement.name; | 452 b.name = typedefElement.name; |
460 b.typeParameters = | 453 b.typeParameters = |
461 typedefElement.typeParameters.map(serializeTypeParam).toList(); | 454 typedefElement.typeParameters.map(serializeTypeParam).toList(); |
462 if (!typedefElement.returnType.isVoid) { | 455 if (!typedefElement.returnType.isVoid) { |
463 b.returnType = | 456 b.returnType = |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 UnlinkedVariableBuilder b = new UnlinkedVariableBuilder(ctx); | 553 UnlinkedVariableBuilder b = new UnlinkedVariableBuilder(ctx); |
561 b.name = variable.name; | 554 b.name = variable.name; |
562 b.type = serializeTypeRef(variable.type, variable); | 555 b.type = serializeTypeRef(variable.type, variable); |
563 b.isStatic = variable.isStatic && variable.enclosingElement is ClassElement; | 556 b.isStatic = variable.isStatic && variable.enclosingElement is ClassElement; |
564 b.isFinal = variable.isFinal; | 557 b.isFinal = variable.isFinal; |
565 b.isConst = variable.isConst; | 558 b.isConst = variable.isConst; |
566 b.hasImplicitType = variable.hasImplicitType; | 559 b.hasImplicitType = variable.hasImplicitType; |
567 return b; | 560 return b; |
568 } | 561 } |
569 } | 562 } |
OLD | NEW |