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/src/generated/element.dart'; | 7 import 'package:analyzer/src/generated/element.dart'; |
8 import 'package:analyzer/src/generated/resolver.dart'; | 8 import 'package:analyzer/src/generated/resolver.dart'; |
9 import 'package:analyzer/src/generated/utilities_dart.dart'; | 9 import 'package:analyzer/src/generated/utilities_dart.dart'; |
10 import 'package:analyzer/src/summary/builder.dart'; | 10 import 'package:analyzer/src/summary/builder.dart'; |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 in exportedLibrary.exportedLibraries) { | 209 in exportedLibrary.exportedLibraries) { |
210 addTransitiveExportClosure(transitiveExport); | 210 addTransitiveExportClosure(transitiveExport); |
211 } | 211 } |
212 } | 212 } |
213 } | 213 } |
214 | 214 |
215 /** | 215 /** |
216 * Compute the appropriate De Bruijn index to represent the given type | 216 * Compute the appropriate De Bruijn index to represent the given type |
217 * parameter [type]. | 217 * parameter [type]. |
218 */ | 218 */ |
219 int findTypeParameterIndex(TypeParameterType type) { | 219 int findTypeParameterIndex(TypeParameterType type, Element context) { |
220 int index = 0; | 220 int index = 0; |
221 Element enclosingElement = type.element.enclosingElement; | 221 while (context != null) { |
222 while (enclosingElement != null) { | |
223 List<TypeParameterElement> typeParameters; | 222 List<TypeParameterElement> typeParameters; |
224 if (enclosingElement is ClassElement) { | 223 if (context is ClassElement) { |
225 typeParameters = enclosingElement.typeParameters; | 224 typeParameters = context.typeParameters; |
226 } else if (enclosingElement is FunctionTypeAliasElement) { | 225 } else if (context is FunctionTypeAliasElement) { |
227 // TODO(paulberry): test this. | 226 typeParameters = context.typeParameters; |
228 typeParameters = enclosingElement.typeParameters; | 227 } else if (context is ExecutableElement) { |
| 228 typeParameters = context.typeParameters; |
229 } | 229 } |
230 for (int i = 0; i < typeParameters.length; i++) { | 230 if (typeParameters != null) { |
231 TypeParameterElement param = typeParameters[i]; | 231 for (int i = 0; i < typeParameters.length; i++) { |
232 if (param == type.element) { | 232 TypeParameterElement param = typeParameters[i]; |
233 return index + typeParameters.length - i; | 233 if (param == type.element) { |
| 234 return index + typeParameters.length - i; |
| 235 } |
234 } | 236 } |
| 237 index += typeParameters.length; |
235 } | 238 } |
236 index += typeParameters.length; | 239 context = context.enclosingElement; |
237 enclosingElement = enclosingElement.enclosingElement; | |
238 } | 240 } |
239 throw new StateError('Unbound type parameter $type'); | 241 throw new StateError('Unbound type parameter $type'); |
240 } | 242 } |
241 | 243 |
242 /** | 244 /** |
243 * Serialize the given [classElement], which exists in the unit numbered | 245 * Serialize the given [classElement], which exists in the unit numbered |
244 * [unitNum], creating an [UnlinkedClass]. | 246 * [unitNum], creating an [UnlinkedClass]. |
245 */ | 247 */ |
246 UnlinkedClassBuilder serializeClass(ClassElement classElement, int unitNum) { | 248 UnlinkedClassBuilder serializeClass(ClassElement classElement, int unitNum) { |
247 UnlinkedClassBuilder b = new UnlinkedClassBuilder(ctx); | 249 UnlinkedClassBuilder b = new UnlinkedClassBuilder(ctx); |
248 b.name = classElement.name; | 250 b.name = classElement.name; |
249 b.unit = unitNum; | 251 b.unit = unitNum; |
250 b.typeParameters = | 252 b.typeParameters = |
251 classElement.typeParameters.map(serializeTypeParam).toList(); | 253 classElement.typeParameters.map(serializeTypeParam).toList(); |
252 if (classElement.supertype != null && !classElement.supertype.isObject) { | 254 if (classElement.supertype != null && !classElement.supertype.isObject) { |
253 b.supertype = serializeTypeRef(classElement.supertype); | 255 b.supertype = serializeTypeRef(classElement.supertype, classElement); |
254 } | 256 } |
255 b.mixins = classElement.mixins.map(serializeTypeRef).toList(); | 257 b.mixins = classElement.mixins |
256 b.interfaces = classElement.interfaces.map(serializeTypeRef).toList(); | 258 .map((InterfaceType t) => serializeTypeRef(t, classElement)) |
| 259 .toList(); |
| 260 b.interfaces = classElement.interfaces |
| 261 .map((InterfaceType t) => serializeTypeRef(t, classElement)) |
| 262 .toList(); |
257 List<UnlinkedVariableBuilder> fields = <UnlinkedVariableBuilder>[]; | 263 List<UnlinkedVariableBuilder> fields = <UnlinkedVariableBuilder>[]; |
258 List<UnlinkedExecutableBuilder> executables = <UnlinkedExecutableBuilder>[]; | 264 List<UnlinkedExecutableBuilder> executables = <UnlinkedExecutableBuilder>[]; |
259 for (ConstructorElement executable in classElement.constructors) { | 265 for (ConstructorElement executable in classElement.constructors) { |
260 if (!executable.isSynthetic) { | 266 if (!executable.isSynthetic) { |
261 executables.add(serializeExecutable(executable, 0)); | 267 executables.add(serializeExecutable(executable, 0)); |
262 } | 268 } |
263 } | 269 } |
264 for (MethodElement executable in classElement.methods) { | 270 for (MethodElement executable in classElement.methods) { |
265 executables.add(serializeExecutable(executable, 0)); | 271 executables.add(serializeExecutable(executable, 0)); |
266 } | 272 } |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 */ | 364 */ |
359 UnlinkedExecutableBuilder serializeExecutable( | 365 UnlinkedExecutableBuilder serializeExecutable( |
360 ExecutableElement executableElement, int unitNum) { | 366 ExecutableElement executableElement, int unitNum) { |
361 if (executableElement.enclosingElement is ClassElement) { | 367 if (executableElement.enclosingElement is ClassElement) { |
362 assert(unitNum == 0); | 368 assert(unitNum == 0); |
363 } | 369 } |
364 UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder(ctx); | 370 UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder(ctx); |
365 b.name = executableElement.name; | 371 b.name = executableElement.name; |
366 b.unit = unitNum; | 372 b.unit = unitNum; |
367 if (!executableElement.type.returnType.isVoid) { | 373 if (!executableElement.type.returnType.isVoid) { |
368 b.returnType = serializeTypeRef(executableElement.type.returnType); | 374 b.returnType = serializeTypeRef( |
| 375 executableElement.type.returnType, executableElement); |
369 } | 376 } |
370 // TODO(paulberry): serialize type parameters. | 377 b.typeParameters = |
| 378 executableElement.typeParameters.map(serializeTypeParam).toList(); |
371 b.parameters = | 379 b.parameters = |
372 executableElement.type.parameters.map(serializeParam).toList(); | 380 executableElement.type.parameters.map(serializeParam).toList(); |
373 if (executableElement is PropertyAccessorElement) { | 381 if (executableElement is PropertyAccessorElement) { |
374 if (executableElement.isGetter) { | 382 if (executableElement.isGetter) { |
375 b.kind = UnlinkedExecutableKind.getter; | 383 b.kind = UnlinkedExecutableKind.getter; |
376 } else { | 384 } else { |
377 b.kind = UnlinkedExecutableKind.setter; | 385 b.kind = UnlinkedExecutableKind.setter; |
378 } | 386 } |
379 } else if (executableElement is ConstructorElement) { | 387 } else if (executableElement is ConstructorElement) { |
380 b.kind = UnlinkedExecutableKind.constructor; | 388 b.kind = UnlinkedExecutableKind.constructor; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 break; | 484 break; |
477 case ParameterKind.NAMED: | 485 case ParameterKind.NAMED: |
478 b.kind = UnlinkedParamKind.named; | 486 b.kind = UnlinkedParamKind.named; |
479 break; | 487 break; |
480 } | 488 } |
481 b.isInitializingFormal = parameter.isInitializingFormal; | 489 b.isInitializingFormal = parameter.isInitializingFormal; |
482 DartType type = parameter.type; | 490 DartType type = parameter.type; |
483 if (type is FunctionType) { | 491 if (type is FunctionType) { |
484 b.isFunctionTyped = true; | 492 b.isFunctionTyped = true; |
485 if (!type.returnType.isVoid) { | 493 if (!type.returnType.isVoid) { |
486 b.type = serializeTypeRef(type.returnType); | 494 b.type = serializeTypeRef(type.returnType, parameter); |
487 } | 495 } |
488 b.parameters = type.parameters.map(serializeParam).toList(); | 496 b.parameters = type.parameters.map(serializeParam).toList(); |
489 } else { | 497 } else { |
490 b.type = serializeTypeRef(type); | 498 b.type = serializeTypeRef(type, parameter); |
491 } | 499 } |
492 return b; | 500 return b; |
493 } | 501 } |
494 | 502 |
495 /** | 503 /** |
496 * Serialize the given [typedefElement], which exists in the unit numbered | 504 * Serialize the given [typedefElement], which exists in the unit numbered |
497 * [unitNum], creating an [UnlinkedTypedef]. | 505 * [unitNum], creating an [UnlinkedTypedef]. |
498 */ | 506 */ |
499 UnlinkedTypedefBuilder serializeTypedef( | 507 UnlinkedTypedefBuilder serializeTypedef( |
500 FunctionTypeAliasElement typedefElement, int unitNum) { | 508 FunctionTypeAliasElement typedefElement, int unitNum) { |
501 UnlinkedTypedefBuilder b = new UnlinkedTypedefBuilder(ctx); | 509 UnlinkedTypedefBuilder b = new UnlinkedTypedefBuilder(ctx); |
502 b.name = typedefElement.name; | 510 b.name = typedefElement.name; |
503 b.unit = unitNum; | 511 b.unit = unitNum; |
504 b.typeParameters = | 512 b.typeParameters = |
505 typedefElement.typeParameters.map(serializeTypeParam).toList(); | 513 typedefElement.typeParameters.map(serializeTypeParam).toList(); |
506 if (!typedefElement.returnType.isVoid) { | 514 if (!typedefElement.returnType.isVoid) { |
507 b.returnType = serializeTypeRef(typedefElement.returnType); | 515 b.returnType = |
| 516 serializeTypeRef(typedefElement.returnType, typedefElement); |
508 } | 517 } |
509 b.parameters = typedefElement.parameters.map(serializeParam).toList(); | 518 b.parameters = typedefElement.parameters.map(serializeParam).toList(); |
510 return b; | 519 return b; |
511 } | 520 } |
512 | 521 |
513 /** | 522 /** |
514 * Serialize the given [typeParameter] into an [UnlinkedTypeParam]. | 523 * Serialize the given [typeParameter] into an [UnlinkedTypeParam]. |
515 */ | 524 */ |
516 UnlinkedTypeParamBuilder serializeTypeParam( | 525 UnlinkedTypeParamBuilder serializeTypeParam( |
517 TypeParameterElement typeParameter) { | 526 TypeParameterElement typeParameter) { |
518 UnlinkedTypeParamBuilder b = new UnlinkedTypeParamBuilder(ctx); | 527 UnlinkedTypeParamBuilder b = new UnlinkedTypeParamBuilder(ctx); |
519 b.name = typeParameter.name; | 528 b.name = typeParameter.name; |
520 if (typeParameter.bound != null) { | 529 if (typeParameter.bound != null) { |
521 b.bound = serializeTypeRef(typeParameter.bound); | 530 b.bound = serializeTypeRef(typeParameter.bound, typeParameter); |
522 } | 531 } |
523 return b; | 532 return b; |
524 } | 533 } |
525 | 534 |
526 /** | 535 /** |
527 * Serialize the given [type] into an [UnlinkedTypeRef]. | 536 * Serialize the given [type] into an [UnlinkedTypeRef]. |
528 */ | 537 */ |
529 UnlinkedTypeRefBuilder serializeTypeRef(DartType type) { | 538 UnlinkedTypeRefBuilder serializeTypeRef(DartType type, Element context) { |
530 UnlinkedTypeRefBuilder b = new UnlinkedTypeRefBuilder(ctx); | 539 UnlinkedTypeRefBuilder b = new UnlinkedTypeRefBuilder(ctx); |
531 if (type is TypeParameterType) { | 540 if (type is TypeParameterType) { |
532 Element enclosingElement = type.element.enclosingElement; | 541 Element enclosingElement = type.element.enclosingElement; |
533 b.paramReference = findTypeParameterIndex(type); | 542 b.paramReference = findTypeParameterIndex(type, context); |
534 } else { | 543 } else { |
535 Element element = type.element; | 544 Element element = type.element; |
536 CompilationUnitElement dependentCompilationUnit = | 545 CompilationUnitElement dependentCompilationUnit = |
537 element.getAncestor((Element e) => e is CompilationUnitElement); | 546 element.getAncestor((Element e) => e is CompilationUnitElement); |
538 LibraryElement dependentLibrary = element.library; | 547 LibraryElement dependentLibrary = element.library; |
539 if (dependentLibrary == null) { | 548 if (dependentLibrary == null) { |
540 assert(type.isDynamic); | 549 assert(type.isDynamic); |
541 if (type is UndefinedTypeImpl) { | 550 if (type is UndefinedTypeImpl) { |
542 b.reference = serializeUnresolvedReference(); | 551 b.reference = serializeUnresolvedReference(); |
543 } else { | 552 } else { |
(...skipping 15 matching lines...) Expand all Loading... |
559 }); | 568 }); |
560 } | 569 } |
561 List<DartType> typeArguments; | 570 List<DartType> typeArguments; |
562 if (type is InterfaceType) { | 571 if (type is InterfaceType) { |
563 typeArguments = type.typeArguments; | 572 typeArguments = type.typeArguments; |
564 } else if (type is FunctionType) { | 573 } else if (type is FunctionType) { |
565 typeArguments = type.typeArguments; | 574 typeArguments = type.typeArguments; |
566 } | 575 } |
567 if (typeArguments != null && | 576 if (typeArguments != null && |
568 typeArguments.any((DartType argument) => !argument.isDynamic)) { | 577 typeArguments.any((DartType argument) => !argument.isDynamic)) { |
569 b.typeArguments = typeArguments.map(serializeTypeRef).toList(); | 578 b.typeArguments = typeArguments |
| 579 .map((DartType t) => serializeTypeRef(t, context)) |
| 580 .toList(); |
570 } | 581 } |
571 } | 582 } |
572 return b; | 583 return b; |
573 } | 584 } |
574 | 585 |
575 /** | 586 /** |
576 * Return the index of the entry in the references table | 587 * Return the index of the entry in the references table |
577 * ([UnlinkedLibrary.references] and [PrelinkedLibrary.references]) used for | 588 * ([UnlinkedLibrary.references] and [PrelinkedLibrary.references]) used for |
578 * unresolved references. A new entry is added to the table if necessary to | 589 * unresolved references. A new entry is added to the table if necessary to |
579 * satisfy the request. | 590 * satisfy the request. |
(...skipping 18 matching lines...) Expand all Loading... |
598 * a class (i.e. fields), [unitNum] should be zero. | 609 * a class (i.e. fields), [unitNum] should be zero. |
599 */ | 610 */ |
600 UnlinkedVariableBuilder serializeVariable( | 611 UnlinkedVariableBuilder serializeVariable( |
601 PropertyInducingElement variable, int unitNum) { | 612 PropertyInducingElement variable, int unitNum) { |
602 if (variable.enclosingElement is ClassElement) { | 613 if (variable.enclosingElement is ClassElement) { |
603 assert(unitNum == 0); | 614 assert(unitNum == 0); |
604 } | 615 } |
605 UnlinkedVariableBuilder b = new UnlinkedVariableBuilder(ctx); | 616 UnlinkedVariableBuilder b = new UnlinkedVariableBuilder(ctx); |
606 b.name = variable.name; | 617 b.name = variable.name; |
607 b.unit = unitNum; | 618 b.unit = unitNum; |
608 b.type = serializeTypeRef(variable.type); | 619 b.type = serializeTypeRef(variable.type, variable); |
609 b.isStatic = variable.isStatic && variable.enclosingElement is ClassElement; | 620 b.isStatic = variable.isStatic && variable.enclosingElement is ClassElement; |
610 b.isFinal = variable.isFinal; | 621 b.isFinal = variable.isFinal; |
611 b.isConst = variable.isConst; | 622 b.isConst = variable.isConst; |
612 return b; | 623 return b; |
613 } | 624 } |
614 } | 625 } |
OLD | NEW |