| 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/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'; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 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) { | 30 ReferenceKind _getReferenceKind(Element element) { |
| 31 ReferenceKind kind; | 31 ReferenceKind kind; |
| 32 if (element is PropertyAccessorElement) { | 32 if (element is PropertyAccessorElement) { |
| 33 kind = ReferenceKind.topLevelPropertyAccessor; | 33 kind = ReferenceKind.topLevelPropertyAccessor; |
| 34 } else if (element is FunctionTypeAliasElement) { | 34 } else if (element is FunctionTypeAliasElement) { |
| 35 kind = ReferenceKind.typedef; | 35 kind = ReferenceKind.typedef; |
| 36 } else if (element is ClassElement || element is DynamicElementImpl) { | 36 } else if (element == null || |
| 37 element is ClassElement || |
| 38 element is DynamicElementImpl) { |
| 37 kind = ReferenceKind.classOrEnum; | 39 kind = ReferenceKind.classOrEnum; |
| 38 } else if (element is FunctionElement) { | 40 } else if (element is FunctionElement) { |
| 39 kind = ReferenceKind.topLevelFunction; | 41 kind = ReferenceKind.topLevelFunction; |
| 40 } else { | 42 } else { |
| 41 throw new Exception('Unexpected element kind: ${element.runtimeType}'); | 43 throw new Exception('Unexpected element kind: ${element.runtimeType}'); |
| 42 } | 44 } |
| 43 return kind; | 45 return kind; |
| 44 } | 46 } |
| 45 | 47 |
| 46 /** | 48 /** |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 b.name = executableElement.name; | 441 b.name = executableElement.name; |
| 440 b.nameOffset = executableElement.nameOffset; | 442 b.nameOffset = executableElement.nameOffset; |
| 441 if (executableElement is! ConstructorElement) { | 443 if (executableElement is! ConstructorElement) { |
| 442 if (executableElement.hasImplicitReturnType) { | 444 if (executableElement.hasImplicitReturnType) { |
| 443 // In strong mode, the variable's static type may have been overwritten | 445 // In strong mode, the variable's static type may have been overwritten |
| 444 // by an inferred type. In this part of the summary we want to store | 446 // by an inferred type. In this part of the summary we want to store |
| 445 // the weak mode static type (which is `dynamic`), since the strong | 447 // the weak mode static type (which is `dynamic`), since the strong |
| 446 // mode static type is fully linked information. | 448 // mode static type is fully linked information. |
| 447 b.returnType = serializeTypeRef( | 449 b.returnType = serializeTypeRef( |
| 448 librarySerializer.typeProvider.dynamicType, executableElement); | 450 librarySerializer.typeProvider.dynamicType, executableElement); |
| 449 } else if (!executableElement.type.returnType.isVoid) { | 451 } else { |
| 450 b.returnType = serializeTypeRef( | 452 b.returnType = serializeTypeRef( |
| 451 executableElement.type.returnType, executableElement); | 453 executableElement.type.returnType, executableElement); |
| 452 } | 454 } |
| 453 } | 455 } |
| 454 b.typeParameters = | 456 b.typeParameters = |
| 455 executableElement.typeParameters.map(serializeTypeParam).toList(); | 457 executableElement.typeParameters.map(serializeTypeParam).toList(); |
| 456 b.parameters = | 458 b.parameters = |
| 457 executableElement.type.parameters.map(serializeParam).toList(); | 459 executableElement.type.parameters.map(serializeParam).toList(); |
| 458 if (executableElement is PropertyAccessorElement) { | 460 if (executableElement is PropertyAccessorElement) { |
| 459 if (executableElement.isGetter) { | 461 if (executableElement.isGetter) { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 } | 547 } |
| 546 b.isInitializingFormal = parameter.isInitializingFormal; | 548 b.isInitializingFormal = parameter.isInitializingFormal; |
| 547 DartType type = parameter.type; | 549 DartType type = parameter.type; |
| 548 if (parameter.isInitializingFormal && parameter.hasImplicitType) { | 550 if (parameter.isInitializingFormal && parameter.hasImplicitType) { |
| 549 b.hasImplicitType = true; | 551 b.hasImplicitType = true; |
| 550 // We don't store the type of initializing formals that have an implicit | 552 // We don't store the type of initializing formals that have an implicit |
| 551 // type, because the type is inherited from the field. | 553 // type, because the type is inherited from the field. |
| 552 } else { | 554 } else { |
| 553 if (type is FunctionType) { | 555 if (type is FunctionType) { |
| 554 b.isFunctionTyped = true; | 556 b.isFunctionTyped = true; |
| 555 if (!type.returnType.isVoid) { | 557 b.type = serializeTypeRef(type.returnType, parameter); |
| 556 b.type = serializeTypeRef(type.returnType, parameter); | |
| 557 } | |
| 558 b.parameters = type.parameters | 558 b.parameters = type.parameters |
| 559 .map((parameter) => serializeParam(parameter, context)) | 559 .map((parameter) => serializeParam(parameter, context)) |
| 560 .toList(); | 560 .toList(); |
| 561 } else { | 561 } else { |
| 562 b.type = serializeTypeRef(type, context); | 562 b.type = serializeTypeRef(type, context); |
| 563 b.hasImplicitType = parameter.hasImplicitType; | 563 b.hasImplicitType = parameter.hasImplicitType; |
| 564 } | 564 } |
| 565 } | 565 } |
| 566 return b; | 566 return b; |
| 567 } | 567 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 581 } | 581 } |
| 582 | 582 |
| 583 /** | 583 /** |
| 584 * Compute the reference index which should be stored in a [EntityRef]. | 584 * Compute the reference index which should be stored in a [EntityRef]. |
| 585 * | 585 * |
| 586 * If [linked] is true, and a new reference has to be created, the reference | 586 * If [linked] is true, and a new reference has to be created, the reference |
| 587 * will only be stored in [linkedReferences]. | 587 * will only be stored in [linkedReferences]. |
| 588 */ | 588 */ |
| 589 int serializeReferenceForType(DartType type, bool linked) { | 589 int serializeReferenceForType(DartType type, bool linked) { |
| 590 Element element = type.element; | 590 Element element = type.element; |
| 591 LibraryElement dependentLibrary = element.library; | 591 LibraryElement dependentLibrary = element?.library; |
| 592 if (dependentLibrary == null) { | 592 if (dependentLibrary == null) { |
| 593 assert(type.isDynamic); | 593 assert(type.isDynamic || type.isVoid); |
| 594 if (type is UndefinedTypeImpl) { | 594 if (type is UndefinedTypeImpl) { |
| 595 return serializeUnresolvedReference(); | 595 return serializeUnresolvedReference(); |
| 596 } | 596 } |
| 597 // Note: for a type which is truly `dynamic`, fall through to use | 597 // Note: for a type which is truly `dynamic` or `void`, fall through to |
| 598 // [_getElementReferenceId]. | 598 // use [_getElementReferenceId]. |
| 599 } | 599 } |
| 600 return _getElementReferenceId(element, linked: linked); | 600 return _getElementReferenceId(element, linked: linked); |
| 601 } | 601 } |
| 602 | 602 |
| 603 /** | 603 /** |
| 604 * Serialize the given [typedefElement], creating an [UnlinkedTypedef]. | 604 * Serialize the given [typedefElement], creating an [UnlinkedTypedef]. |
| 605 */ | 605 */ |
| 606 UnlinkedTypedefBuilder serializeTypedef( | 606 UnlinkedTypedefBuilder serializeTypedef( |
| 607 FunctionTypeAliasElement typedefElement) { | 607 FunctionTypeAliasElement typedefElement) { |
| 608 UnlinkedTypedefBuilder b = new UnlinkedTypedefBuilder(); | 608 UnlinkedTypedefBuilder b = new UnlinkedTypedefBuilder(); |
| 609 b.name = typedefElement.name; | 609 b.name = typedefElement.name; |
| 610 b.nameOffset = typedefElement.nameOffset; | 610 b.nameOffset = typedefElement.nameOffset; |
| 611 b.typeParameters = | 611 b.typeParameters = |
| 612 typedefElement.typeParameters.map(serializeTypeParam).toList(); | 612 typedefElement.typeParameters.map(serializeTypeParam).toList(); |
| 613 if (!typedefElement.returnType.isVoid) { | 613 b.returnType = serializeTypeRef(typedefElement.returnType, typedefElement); |
| 614 b.returnType = | |
| 615 serializeTypeRef(typedefElement.returnType, typedefElement); | |
| 616 } | |
| 617 b.parameters = typedefElement.parameters.map(serializeParam).toList(); | 614 b.parameters = typedefElement.parameters.map(serializeParam).toList(); |
| 618 b.documentationComment = serializeDocumentation(typedefElement); | 615 b.documentationComment = serializeDocumentation(typedefElement); |
| 619 return b; | 616 return b; |
| 620 } | 617 } |
| 621 | 618 |
| 622 /** | 619 /** |
| 623 * Serialize the given [typeParameter] into an [UnlinkedTypeParam]. | 620 * Serialize the given [typeParameter] into an [UnlinkedTypeParam]. |
| 624 */ | 621 */ |
| 625 UnlinkedTypeParamBuilder serializeTypeParam( | 622 UnlinkedTypeParamBuilder serializeTypeParam( |
| 626 TypeParameterElement typeParameter) { | 623 TypeParameterElement typeParameter) { |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 743 int slot = ++numSlots; | 740 int slot = ++numSlots; |
| 744 if (type != null) { | 741 if (type != null) { |
| 745 deferredLinkedTypes | 742 deferredLinkedTypes |
| 746 .add(() => serializeTypeRef(type, context, linked: true, slot: slot)); | 743 .add(() => serializeTypeRef(type, context, linked: true, slot: slot)); |
| 747 } | 744 } |
| 748 return slot; | 745 return slot; |
| 749 } | 746 } |
| 750 | 747 |
| 751 int _getElementReferenceId(Element element, {bool linked: false}) { | 748 int _getElementReferenceId(Element element, {bool linked: false}) { |
| 752 return referenceMap.putIfAbsent(element, () { | 749 return referenceMap.putIfAbsent(element, () { |
| 753 LibraryElement dependentLibrary = element.library; | 750 LibraryElement dependentLibrary = element?.library; |
| 754 int unit; | 751 int unit; |
| 755 if (element.library == null) { | 752 if (dependentLibrary == null) { |
| 756 assert(element == librarySerializer.typeProvider.dynamicType.element); | 753 assert(element == librarySerializer.typeProvider.dynamicType.element || |
| 754 element == null); |
| 757 unit = 0; | 755 unit = 0; |
| 758 dependentLibrary = librarySerializer.libraryElement; | 756 dependentLibrary = librarySerializer.libraryElement; |
| 759 } else { | 757 } else { |
| 760 CompilationUnitElement unitElement = | 758 CompilationUnitElement unitElement = |
| 761 element.getAncestor((Element e) => e is CompilationUnitElement); | 759 element.getAncestor((Element e) => e is CompilationUnitElement); |
| 762 unit = dependentLibrary.units.indexOf(unitElement); | 760 unit = dependentLibrary.units.indexOf(unitElement); |
| 763 assert(unit != -1); | 761 assert(unit != -1); |
| 764 } | 762 } |
| 765 int numTypeParameters = 0; | 763 int numTypeParameters = 0; |
| 766 if (element is TypeParameterizedElement) { | 764 if (element is TypeParameterizedElement) { |
| 767 numTypeParameters = element.typeParameters.length; | 765 numTypeParameters = element.typeParameters.length; |
| 768 } | 766 } |
| 769 LinkedReferenceBuilder linkedReference = new LinkedReferenceBuilder( | 767 LinkedReferenceBuilder linkedReference = new LinkedReferenceBuilder( |
| 770 dependency: librarySerializer.serializeDependency(dependentLibrary), | 768 dependency: librarySerializer.serializeDependency(dependentLibrary), |
| 771 kind: _getReferenceKind(element), | 769 kind: _getReferenceKind(element), |
| 772 unit: unit, | 770 unit: unit, |
| 773 numTypeParameters: numTypeParameters); | 771 numTypeParameters: numTypeParameters); |
| 772 String name = element == null ? 'void' : element.name; |
| 774 if (linked) { | 773 if (linked) { |
| 775 linkedReference.name = element.name; | 774 linkedReference.name = name; |
| 776 } else { | 775 } else { |
| 777 assert(unlinkedReferences.length == linkedReferences.length); | 776 assert(unlinkedReferences.length == linkedReferences.length); |
| 778 // Figure out a prefix that may be used to refer to the given type. | 777 // Figure out a prefix that may be used to refer to the given type. |
| 779 // TODO(paulberry): to avoid subtle relinking inconsistencies we | 778 // TODO(paulberry): to avoid subtle relinking inconsistencies we |
| 780 // should use the actual prefix from the AST (a given type may be | 779 // should use the actual prefix from the AST (a given type may be |
| 781 // reachable via multiple prefixes), but sadly, this information is | 780 // reachable via multiple prefixes), but sadly, this information is |
| 782 // not recorded in the element model. | 781 // not recorded in the element model. |
| 783 int prefixReference = 0; | 782 int prefixReference = 0; |
| 784 PrefixElement prefix = librarySerializer.prefixMap[element]; | 783 PrefixElement prefix = librarySerializer.prefixMap[element]; |
| 785 if (prefix != null) { | 784 if (prefix != null) { |
| 786 prefixReference = serializePrefix(prefix); | 785 prefixReference = serializePrefix(prefix); |
| 787 } | 786 } |
| 788 unlinkedReferences.add(new UnlinkedReferenceBuilder( | 787 unlinkedReferences.add(new UnlinkedReferenceBuilder( |
| 789 name: element.name, prefixReference: prefixReference)); | 788 name: name, prefixReference: prefixReference)); |
| 790 } | 789 } |
| 791 int index = linkedReferences.length; | 790 int index = linkedReferences.length; |
| 792 linkedReferences.add(linkedReference); | 791 linkedReferences.add(linkedReference); |
| 793 return index; | 792 return index; |
| 794 }); | 793 }); |
| 795 } | 794 } |
| 796 } | 795 } |
| 797 | 796 |
| 798 /** | 797 /** |
| 799 * Instances of this class keep track of intermediate state during | 798 * Instances of this class keep track of intermediate state during |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 996 exportNames.add(new LinkedExportNameBuilder( | 995 exportNames.add(new LinkedExportNameBuilder( |
| 997 name: name, | 996 name: name, |
| 998 dependency: serializeDependency(dependentLibrary), | 997 dependency: serializeDependency(dependentLibrary), |
| 999 unit: unit, | 998 unit: unit, |
| 1000 kind: kind)); | 999 kind: kind)); |
| 1001 } | 1000 } |
| 1002 pb.exportNames = exportNames; | 1001 pb.exportNames = exportNames; |
| 1003 return pb; | 1002 return pb; |
| 1004 } | 1003 } |
| 1005 } | 1004 } |
| OLD | NEW |