| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library serialization.elements; |
| 6 |
| 7 import 'package:analyzer/src/generated/element.dart'; |
| 8 import 'package:analyzer/src/generated/resolver.dart'; |
| 9 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 10 import 'package:analyzer/src/summary/builder.dart'; |
| 11 import 'package:analyzer/src/summary/format.dart'; |
| 12 |
| 13 /** |
| 14 * Serialize all the elements in [lib] to a summary using [ctx] as the context |
| 15 * for building the summary, and using [typeProvider] to find built-in types. |
| 16 * |
| 17 * Return an object which may safely be passed to [BuilderContext.getBuffer] or |
| 18 * included in an aggregate summary. |
| 19 */ |
| 20 Object serializeLibrary( |
| 21 BuilderContext ctx, LibraryElement lib, TypeProvider typeProvider) { |
| 22 return new _LibrarySerializer(ctx, lib, typeProvider).serializeLibrary(); |
| 23 } |
| 24 |
| 25 /** |
| 26 * Instances of this class keep track of intermediate state during |
| 27 * serialization of a single library.` |
| 28 */ |
| 29 class _LibrarySerializer { |
| 30 /** |
| 31 * The library to be serialized. |
| 32 */ |
| 33 final LibraryElement libraryElement; |
| 34 |
| 35 /** |
| 36 * The type provider. This is used to locate the library for `dart:core`. |
| 37 */ |
| 38 final TypeProvider typeProvider; |
| 39 |
| 40 /** |
| 41 * List of objects which should be written to [UnlinkedLibrary.classes]. |
| 42 */ |
| 43 final List<Object> classes = <Object>[]; |
| 44 |
| 45 /** |
| 46 * List of objects which should be written to [UnlinkedLibrary.enums]. |
| 47 */ |
| 48 final List<Object> enums = <Object>[]; |
| 49 |
| 50 /** |
| 51 * List of objects which should be written to [UnlinkedLibrary.executables]. |
| 52 */ |
| 53 final List<Object> executables = <Object>[]; |
| 54 |
| 55 /** |
| 56 * List of objects which should be written to [UnlinkedLibrary.typedefs]. |
| 57 */ |
| 58 final List<Object> typedefs = <Object>[]; |
| 59 |
| 60 /** |
| 61 * List of objects which should be written to [UnlinkedLibrary.units]. |
| 62 */ |
| 63 final List<Object> units = <Object>[]; |
| 64 |
| 65 /** |
| 66 * List of objects which should be written to [UnlinkedLibrary.variables]. |
| 67 */ |
| 68 final List<Object> variables = <Object>[]; |
| 69 |
| 70 /** |
| 71 * Map from [LibraryElement] to the index of the entry in the "dependency |
| 72 * table" that refers to it. |
| 73 */ |
| 74 final Map<LibraryElement, int> dependencyMap = <LibraryElement, int>{}; |
| 75 |
| 76 /** |
| 77 * The "dependency table". This is the list of objects which should be |
| 78 * written to [PrelinkedLibrary.dependencies]. |
| 79 */ |
| 80 final List<Object> dependencies = <Object>[]; |
| 81 |
| 82 /** |
| 83 * The unlinked portion of the "imports table". This is the list of objects |
| 84 * which should be written to [UnlinkedLibrary.imports]. |
| 85 */ |
| 86 final List<Object> unlinkedImports = <Object>[]; |
| 87 |
| 88 /** |
| 89 * The prelinked portion of the "imports table". This is the list of ints |
| 90 * which should be written to [PrelinkedLibrary.imports]. |
| 91 */ |
| 92 final List<Object> prelinkedImports = <int>[]; |
| 93 |
| 94 /** |
| 95 * Map from prefix [String] to the index of the entry in the "prefix" table |
| 96 * that refers to it. The empty prefix is not included in this map. |
| 97 */ |
| 98 final Map<String, int> prefixMap = <String, int>{}; |
| 99 |
| 100 /** |
| 101 * The "prefix table". This is the list of objects which should be written |
| 102 * to [UnlinkedLibrary.prefixes]. |
| 103 */ |
| 104 final List<Object> prefixes = <Object>[]; |
| 105 |
| 106 /** |
| 107 * Map from [Element] to the index of the entry in the "references table" |
| 108 * that refers to it. |
| 109 */ |
| 110 final Map<Element, int> referenceMap = <Element, int>{}; |
| 111 |
| 112 /** |
| 113 * The unlinked portion of the "references table". This is the list of |
| 114 * objects which should be written to [UnlinkedLibrary.references]. |
| 115 */ |
| 116 final List<Object> unlinkedReferences = <Object>[]; |
| 117 |
| 118 /** |
| 119 * The prelinked portion of the "references table". This is the list of |
| 120 * objects which should be written to [PrelinkedLibrary.references]. |
| 121 */ |
| 122 final List<Object> prelinkedReferences = <Object>[]; |
| 123 |
| 124 //final Map<String, int> prefixIndices = <String, int>{}; |
| 125 |
| 126 /** |
| 127 * Index into the "references table" representing `dynamic`, if such an index |
| 128 * exists. `null` if no such entry has been made in the references table |
| 129 * yet. |
| 130 */ |
| 131 int dynamicReferenceIndex = null; |
| 132 |
| 133 /** |
| 134 * Index into the "references table" representing an unresolved reference, if |
| 135 * such an index exists. `null` if no such entry has been made in the |
| 136 * references table yet. |
| 137 */ |
| 138 int unresolvedReferenceIndex = null; |
| 139 |
| 140 /** |
| 141 * Set of libraries which have been seen so far while visiting the transitive |
| 142 * closure of exports. |
| 143 */ |
| 144 final Set<LibraryElement> librariesAddedToTransitiveExportClosure = |
| 145 new Set<LibraryElement>(); |
| 146 |
| 147 /** |
| 148 * [BuilderContext] used to serialize the output summary. |
| 149 */ |
| 150 final BuilderContext ctx; |
| 151 |
| 152 _LibrarySerializer(this.ctx, this.libraryElement, this.typeProvider) { |
| 153 dependencies.add(encodePrelinkedDependency(ctx)); |
| 154 dependencyMap[libraryElement] = 0; |
| 155 prefixes.add(encodeUnlinkedPrefix(ctx)); |
| 156 } |
| 157 |
| 158 /** |
| 159 * Retrieve the library element for `dart:core`. |
| 160 */ |
| 161 LibraryElement get coreLibrary => typeProvider.objectType.element.library; |
| 162 |
| 163 /** |
| 164 * Add all classes, enums, typedefs, executables, and top level variables |
| 165 * from the given compilation unit [element] to the library summary. |
| 166 * [unitNum] indicates the ordinal position of this compilation unit in the |
| 167 * library. |
| 168 */ |
| 169 void addCompilationUnitElements(CompilationUnitElement element, int unitNum) { |
| 170 UnlinkedUnitBuilder b = new UnlinkedUnitBuilder(ctx); |
| 171 if (element.uri != null) { |
| 172 b.uri = element.uri; |
| 173 } |
| 174 units.add(b.finish()); |
| 175 for (ClassElement cls in element.types) { |
| 176 classes.add(serializeClass(cls, unitNum)); |
| 177 } |
| 178 for (ClassElement e in element.enums) { |
| 179 enums.add(serializeEnum(e, unitNum)); |
| 180 } |
| 181 for (FunctionTypeAliasElement type in element.functionTypeAliases) { |
| 182 typedefs.add(serializeTypedef(type, unitNum)); |
| 183 } |
| 184 for (FunctionElement executable in element.functions) { |
| 185 executables.add(serializeExecutable(executable, unitNum)); |
| 186 } |
| 187 for (PropertyAccessorElement accessor in element.accessors) { |
| 188 if (!accessor.isSynthetic) { |
| 189 executables.add(serializeExecutable(accessor, unitNum)); |
| 190 } else if (accessor.isGetter) { |
| 191 PropertyInducingElement variable = accessor.variable; |
| 192 if (variable != null) { |
| 193 assert(!variable.isSynthetic); |
| 194 variables.add(serializeVariable(variable, unitNum)); |
| 195 } |
| 196 } |
| 197 } |
| 198 } |
| 199 |
| 200 /** |
| 201 * Add [exportedLibrary] (and the transitive closure of all libraries it |
| 202 * exports) to the dependency table ([PrelinkedLibrary.dependencies]). |
| 203 */ |
| 204 void addTransitiveExportClosure(LibraryElement exportedLibrary) { |
| 205 if (librariesAddedToTransitiveExportClosure.add(exportedLibrary)) { |
| 206 serializeDependency(exportedLibrary); |
| 207 for (LibraryElement transitiveExport |
| 208 in exportedLibrary.exportedLibraries) { |
| 209 addTransitiveExportClosure(transitiveExport); |
| 210 } |
| 211 } |
| 212 } |
| 213 |
| 214 /** |
| 215 * Compute the appropriate De Bruijn index to represent the given type |
| 216 * parameter [type]. |
| 217 */ |
| 218 int findTypeParameterIndex(TypeParameterType type) { |
| 219 int index = 0; |
| 220 Element enclosingElement = type.element.enclosingElement; |
| 221 while (enclosingElement != null) { |
| 222 List<TypeParameterElement> typeParameters; |
| 223 if (enclosingElement is ClassElement) { |
| 224 typeParameters = enclosingElement.typeParameters; |
| 225 } else if (enclosingElement is FunctionTypeAliasElement) { |
| 226 // TODO(paulberry): test this. |
| 227 typeParameters = enclosingElement.typeParameters; |
| 228 } |
| 229 for (int i = 0; i < typeParameters.length; i++) { |
| 230 TypeParameterElement param = typeParameters[i]; |
| 231 if (param == type.element) { |
| 232 return index + typeParameters.length - i; |
| 233 } |
| 234 } |
| 235 index += typeParameters.length; |
| 236 enclosingElement = enclosingElement.enclosingElement; |
| 237 } |
| 238 throw new StateError('Unbound type parameter $type'); |
| 239 } |
| 240 |
| 241 /** |
| 242 * Serialize the given [classElement], which exists in the unit numbered |
| 243 * [unitNum], creating an [UnlinkedClass]. |
| 244 */ |
| 245 Object serializeClass(ClassElement classElement, int unitNum) { |
| 246 UnlinkedClassBuilder b = new UnlinkedClassBuilder(ctx); |
| 247 b.name = classElement.name; |
| 248 b.unit = unitNum; |
| 249 b.typeParameters = |
| 250 classElement.typeParameters.map(serializeTypeParam).toList(); |
| 251 if (classElement.supertype != null && !classElement.supertype.isObject) { |
| 252 b.supertype = serializeTypeRef(classElement.supertype); |
| 253 } |
| 254 b.mixins = classElement.mixins.map(serializeTypeRef).toList(); |
| 255 b.interfaces = classElement.interfaces.map(serializeTypeRef).toList(); |
| 256 List<Object> fields = <Object>[]; |
| 257 List<Object> executables = <Object>[]; |
| 258 for (ConstructorElement executable in classElement.constructors) { |
| 259 if (!executable.isSynthetic) { |
| 260 executables.add(serializeExecutable(executable, 0)); |
| 261 } |
| 262 } |
| 263 for (MethodElement executable in classElement.methods) { |
| 264 executables.add(serializeExecutable(executable, 0)); |
| 265 } |
| 266 for (PropertyAccessorElement accessor in classElement.accessors) { |
| 267 if (!accessor.isSynthetic) { |
| 268 executables.add(serializeExecutable(accessor, 0)); |
| 269 } else if (accessor.isGetter) { |
| 270 PropertyInducingElement field = accessor.variable; |
| 271 if (field != null && !field.isSynthetic) { |
| 272 fields.add(serializeVariable(field, 0)); |
| 273 } |
| 274 } |
| 275 } |
| 276 b.fields = fields; |
| 277 b.executables = executables; |
| 278 b.isAbstract = classElement.isAbstract; |
| 279 b.isMixinApplication = classElement.isMixinApplication; |
| 280 return b.finish(); |
| 281 } |
| 282 |
| 283 /** |
| 284 * Serialize the given [combinator] into an [UnlinkedCombinator]. |
| 285 */ |
| 286 Object serializeCombinator(NamespaceCombinator combinator) { |
| 287 UnlinkedCombinatorBuilder b = new UnlinkedCombinatorBuilder(ctx); |
| 288 if (combinator is ShowElementCombinator) { |
| 289 b.shows = combinator.shownNames.map(serializeCombinatorName).toList(); |
| 290 } else if (combinator is HideElementCombinator) { |
| 291 b.hides = combinator.hiddenNames.map(serializeCombinatorName).toList(); |
| 292 } |
| 293 return b.finish(); |
| 294 } |
| 295 |
| 296 /** |
| 297 * Serialize the given [name] into an [UnlinkedCombinatorName]. |
| 298 */ |
| 299 Object serializeCombinatorName(String name) { |
| 300 return encodeUnlinkedCombinatorName(ctx, name: name); |
| 301 } |
| 302 |
| 303 /** |
| 304 * Return the index of the entry in the dependency table |
| 305 * ([PrelinkedLibrary.dependencies]) for the given [dependentLibrary]. A new |
| 306 * entry is added to the table if necessary to satisfy the request. |
| 307 */ |
| 308 int serializeDependency(LibraryElement dependentLibrary) { |
| 309 return dependencyMap.putIfAbsent(dependentLibrary, () { |
| 310 int index = dependencies.length; |
| 311 dependencies.add(encodePrelinkedDependency(ctx, |
| 312 uri: dependentLibrary.source.uri.toString())); |
| 313 return index; |
| 314 }); |
| 315 } |
| 316 |
| 317 /** |
| 318 * Return the index of the entry in the references table |
| 319 * ([UnlinkedLibrary.references] and [PrelinkedLibrary.references]) |
| 320 * representing the pseudo-type `dynamic`. A new entry is added to the table |
| 321 * if necessary to satisfy the request. |
| 322 */ |
| 323 int serializeDynamicReference() { |
| 324 if (dynamicReferenceIndex == null) { |
| 325 assert(unlinkedReferences.length == prelinkedReferences.length); |
| 326 dynamicReferenceIndex = unlinkedReferences.length; |
| 327 unlinkedReferences.add(encodeUnlinkedReference(ctx)); |
| 328 prelinkedReferences.add(encodePrelinkedReference(ctx, |
| 329 kind: PrelinkedReferenceKind.classOrEnum)); |
| 330 } |
| 331 return dynamicReferenceIndex; |
| 332 } |
| 333 |
| 334 /** |
| 335 * Serialize the given [enumElement], which exists in the unit numbered |
| 336 * [unitNum], creating an [UnlinkedEnum]. |
| 337 */ |
| 338 Object serializeEnum(ClassElement enumElement, int unitNum) { |
| 339 UnlinkedEnumBuilder b = new UnlinkedEnumBuilder(ctx); |
| 340 b.name = enumElement.name; |
| 341 List<Object> values = <Object>[]; |
| 342 for (FieldElement field in enumElement.fields) { |
| 343 if (field.isConst && field.type.element == enumElement) { |
| 344 values.add(encodeUnlinkedEnumValue(ctx, name: field.name)); |
| 345 } |
| 346 } |
| 347 b.values = values; |
| 348 b.unit = unitNum; |
| 349 return b.finish(); |
| 350 } |
| 351 |
| 352 /** |
| 353 * Serialize the given [executableElement], which exists in the unit numbered |
| 354 * [unitNum], creating an [UnlinkedExecutable]. For elements declared inside |
| 355 * a class, [unitNum] should be zero. |
| 356 */ |
| 357 Object serializeExecutable(ExecutableElement executableElement, int unitNum) { |
| 358 if (executableElement.enclosingElement is ClassElement) { |
| 359 assert(unitNum == 0); |
| 360 } |
| 361 UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder(ctx); |
| 362 b.name = executableElement.name; |
| 363 b.unit = unitNum; |
| 364 if (!executableElement.type.returnType.isVoid) { |
| 365 b.returnType = serializeTypeRef(executableElement.type.returnType); |
| 366 } |
| 367 // TODO(paulberry): serialize type parameters. |
| 368 b.parameters = |
| 369 executableElement.type.parameters.map(serializeParam).toList(); |
| 370 if (executableElement is PropertyAccessorElement) { |
| 371 if (executableElement.isGetter) { |
| 372 b.kind = UnlinkedExecutableKind.getter; |
| 373 } else { |
| 374 b.kind = UnlinkedExecutableKind.setter; |
| 375 } |
| 376 } else if (executableElement is ConstructorElement) { |
| 377 b.kind = UnlinkedExecutableKind.constructor; |
| 378 b.isConst = executableElement.isConst; |
| 379 b.isFactory = executableElement.isFactory; |
| 380 } else { |
| 381 b.kind = UnlinkedExecutableKind.functionOrMethod; |
| 382 } |
| 383 b.isAbstract = executableElement.isAbstract; |
| 384 b.isStatic = executableElement.isStatic && |
| 385 executableElement.enclosingElement is ClassElement; |
| 386 return b.finish(); |
| 387 } |
| 388 |
| 389 /** |
| 390 * Serialize the given [exportElement] into an [UnlinkedExport]. |
| 391 */ |
| 392 Object serializeExport(ExportElement exportElement) { |
| 393 UnlinkedExportBuilder b = new UnlinkedExportBuilder(ctx); |
| 394 b.uri = exportElement.uri; |
| 395 b.combinators = exportElement.combinators.map(serializeCombinator).toList(); |
| 396 return b.finish(); |
| 397 } |
| 398 |
| 399 /** |
| 400 * Serialize the given [importElement], adding information about it to |
| 401 * the [unlinkedImports] and [prelinkedImports] lists. |
| 402 */ |
| 403 void serializeImport(ImportElement importElement) { |
| 404 assert(unlinkedImports.length == prelinkedImports.length); |
| 405 UnlinkedImportBuilder b = new UnlinkedImportBuilder(ctx); |
| 406 b.isDeferred = importElement.isDeferred; |
| 407 b.offset = importElement.nameOffset; |
| 408 b.combinators = importElement.combinators.map(serializeCombinator).toList(); |
| 409 if (importElement.prefix != null) { |
| 410 b.prefix = prefixMap.putIfAbsent(importElement.prefix.name, () { |
| 411 int index = prefixes.length; |
| 412 prefixes |
| 413 .add(encodeUnlinkedPrefix(ctx, name: importElement.prefix.name)); |
| 414 return index; |
| 415 }); |
| 416 } |
| 417 if (importElement.isSynthetic) { |
| 418 b.isImplicit = true; |
| 419 } else { |
| 420 b.uri = importElement.uri; |
| 421 } |
| 422 addTransitiveExportClosure(importElement.importedLibrary); |
| 423 unlinkedImports.add(b.finish()); |
| 424 prelinkedImports.add(serializeDependency(importElement.importedLibrary)); |
| 425 } |
| 426 |
| 427 /** |
| 428 * Serialize the whole library element into a [PrelinkedLibrary]. Should be |
| 429 * called exactly once for each instance of [_LibrarySerializer]. |
| 430 */ |
| 431 Object serializeLibrary() { |
| 432 UnlinkedLibraryBuilder ub = new UnlinkedLibraryBuilder(ctx); |
| 433 PrelinkedLibraryBuilder pb = new PrelinkedLibraryBuilder(ctx); |
| 434 if (libraryElement.name.isNotEmpty) { |
| 435 ub.name = libraryElement.name; |
| 436 } |
| 437 for (ImportElement importElement in libraryElement.imports) { |
| 438 serializeImport(importElement); |
| 439 } |
| 440 ub.exports = libraryElement.exports.map(serializeExport).toList(); |
| 441 addCompilationUnitElements(libraryElement.definingCompilationUnit, 0); |
| 442 for (int i = 0; i < libraryElement.parts.length; i++) { |
| 443 addCompilationUnitElements(libraryElement.parts[i], i + 1); |
| 444 } |
| 445 ub.classes = classes; |
| 446 ub.enums = enums; |
| 447 ub.executables = executables; |
| 448 ub.imports = unlinkedImports; |
| 449 ub.prefixes = prefixes; |
| 450 ub.references = unlinkedReferences; |
| 451 ub.typedefs = typedefs; |
| 452 ub.units = units; |
| 453 ub.variables = variables; |
| 454 pb.unlinked = ub.finish(); |
| 455 pb.dependencies = dependencies; |
| 456 pb.importDependencies = prelinkedImports; |
| 457 pb.references = prelinkedReferences; |
| 458 return pb.finish(); |
| 459 } |
| 460 |
| 461 /** |
| 462 * Serialize the given [parameter] into an [UnlinkedParam]. |
| 463 */ |
| 464 Object serializeParam(ParameterElement parameter) { |
| 465 UnlinkedParamBuilder b = new UnlinkedParamBuilder(ctx); |
| 466 b.name = parameter.name; |
| 467 switch (parameter.parameterKind) { |
| 468 case ParameterKind.REQUIRED: |
| 469 b.kind = UnlinkedParamKind.required; |
| 470 break; |
| 471 case ParameterKind.POSITIONAL: |
| 472 b.kind = UnlinkedParamKind.positional; |
| 473 break; |
| 474 case ParameterKind.NAMED: |
| 475 b.kind = UnlinkedParamKind.named; |
| 476 break; |
| 477 } |
| 478 b.isInitializingFormal = parameter.isInitializingFormal; |
| 479 DartType type = parameter.type; |
| 480 if (type is FunctionType) { |
| 481 b.isFunctionTyped = true; |
| 482 if (!type.returnType.isVoid) { |
| 483 b.type = serializeTypeRef(type.returnType); |
| 484 } |
| 485 b.parameters = type.parameters.map(serializeParam).toList(); |
| 486 } else { |
| 487 b.type = serializeTypeRef(type); |
| 488 } |
| 489 return b.finish(); |
| 490 } |
| 491 |
| 492 /** |
| 493 * Serialize the given [typedefElement], which exists in the unit numbered |
| 494 * [unitNum], creating an [UnlinkedTypedef]. |
| 495 */ |
| 496 Object serializeTypedef( |
| 497 FunctionTypeAliasElement typedefElement, int unitNum) { |
| 498 UnlinkedTypedefBuilder b = new UnlinkedTypedefBuilder(ctx); |
| 499 b.name = typedefElement.name; |
| 500 b.unit = unitNum; |
| 501 b.typeParameters = |
| 502 typedefElement.typeParameters.map(serializeTypeParam).toList(); |
| 503 if (!typedefElement.returnType.isVoid) { |
| 504 b.returnType = serializeTypeRef(typedefElement.returnType); |
| 505 } |
| 506 b.parameters = typedefElement.parameters.map(serializeParam).toList(); |
| 507 return b.finish(); |
| 508 } |
| 509 |
| 510 /** |
| 511 * Serialize the given [typeParameter] into an [UnlinkedTypeParam]. |
| 512 */ |
| 513 Object serializeTypeParam(TypeParameterElement typeParameter) { |
| 514 UnlinkedTypeParamBuilder b = new UnlinkedTypeParamBuilder(ctx); |
| 515 b.name = typeParameter.name; |
| 516 if (typeParameter.bound != null) { |
| 517 b.bound = serializeTypeRef(typeParameter.bound); |
| 518 } |
| 519 return b.finish(); |
| 520 } |
| 521 |
| 522 /** |
| 523 * Serialize the given [type] into an [UnlinkedTypeRef]. |
| 524 */ |
| 525 Object serializeTypeRef(DartType type) { |
| 526 UnlinkedTypeRefBuilder b = new UnlinkedTypeRefBuilder(ctx); |
| 527 if (type is TypeParameterType) { |
| 528 Element enclosingElement = type.element.enclosingElement; |
| 529 b.paramReference = findTypeParameterIndex(type); |
| 530 } else { |
| 531 Element element = type.element; |
| 532 CompilationUnitElement dependentCompilationUnit = |
| 533 element.getAncestor((Element e) => e is CompilationUnitElement); |
| 534 LibraryElement dependentLibrary = element.library; |
| 535 if (dependentLibrary == null) { |
| 536 assert(type.isDynamic); |
| 537 if (type is UndefinedTypeImpl) { |
| 538 b.reference = serializeUnresolvedReference(); |
| 539 } else { |
| 540 b.reference = serializeDynamicReference(); |
| 541 } |
| 542 } else { |
| 543 b.reference = referenceMap.putIfAbsent(element, () { |
| 544 assert(unlinkedReferences.length == prelinkedReferences.length); |
| 545 int index = unlinkedReferences.length; |
| 546 // TODO(paulberry): set UnlinkedReference.prefix. |
| 547 unlinkedReferences |
| 548 .add(encodeUnlinkedReference(ctx, name: element.name)); |
| 549 prelinkedReferences.add(encodePrelinkedReference(ctx, |
| 550 dependency: serializeDependency(dependentLibrary), |
| 551 kind: element is FunctionTypeAliasElement |
| 552 ? PrelinkedReferenceKind.typedef |
| 553 : PrelinkedReferenceKind.classOrEnum)); |
| 554 return index; |
| 555 }); |
| 556 } |
| 557 List<DartType> typeArguments; |
| 558 if (type is InterfaceType) { |
| 559 typeArguments = type.typeArguments; |
| 560 } else if (type is FunctionType) { |
| 561 typeArguments = type.typeArguments; |
| 562 } |
| 563 if (typeArguments != null && |
| 564 typeArguments.any((DartType argument) => !argument.isDynamic)) { |
| 565 b.typeArguments = typeArguments.map(serializeTypeRef).toList(); |
| 566 } |
| 567 } |
| 568 return b.finish(); |
| 569 } |
| 570 |
| 571 /** |
| 572 * Return the index of the entry in the references table |
| 573 * ([UnlinkedLibrary.references] and [PrelinkedLibrary.references]) used for |
| 574 * unresolved references. A new entry is added to the table if necessary to |
| 575 * satisfy the request. |
| 576 */ |
| 577 int serializeUnresolvedReference() { |
| 578 // TODO(paulberry): in order for relinking to work, we need to record the |
| 579 // name and prefix of the unresolved symbol. This is not (yet) encoded in |
| 580 // the element model. |
| 581 if (unresolvedReferenceIndex == null) { |
| 582 assert(unlinkedReferences.length == prelinkedReferences.length); |
| 583 unresolvedReferenceIndex = unlinkedReferences.length; |
| 584 unlinkedReferences.add(encodeUnlinkedReference(ctx)); |
| 585 prelinkedReferences.add(encodePrelinkedReference(ctx, |
| 586 kind: PrelinkedReferenceKind.unresolved)); |
| 587 } |
| 588 return unresolvedReferenceIndex; |
| 589 } |
| 590 |
| 591 /** |
| 592 * Serialize the given [variable], which exists in the unit numbered |
| 593 * [unitNum], creating an [UnlinkedVariable]. For variables declared inside |
| 594 * a class (i.e. fields), [unitNum] should be zero. |
| 595 */ |
| 596 Object serializeVariable(PropertyInducingElement variable, int unitNum) { |
| 597 if (variable.enclosingElement is ClassElement) { |
| 598 assert(unitNum == 0); |
| 599 } |
| 600 UnlinkedVariableBuilder b = new UnlinkedVariableBuilder(ctx); |
| 601 b.name = variable.name; |
| 602 b.unit = unitNum; |
| 603 b.type = serializeTypeRef(variable.type); |
| 604 b.isStatic = variable.isStatic && variable.enclosingElement is ClassElement; |
| 605 b.isFinal = variable.isFinal; |
| 606 b.isConst = variable.isConst; |
| 607 return b.finish(); |
| 608 } |
| 609 } |
| OLD | NEW |