| 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 |