| 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 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 * | 679 * |
| 680 * [context] is the element within which the [EntityRef] will be | 680 * [context] is the element within which the [EntityRef] will be |
| 681 * interpreted; this is used to serialize type parameters. | 681 * interpreted; this is used to serialize type parameters. |
| 682 */ | 682 */ |
| 683 EntityRefBuilder serializeTypeRef(DartType type, Element context, | 683 EntityRefBuilder serializeTypeRef(DartType type, Element context, |
| 684 {bool linked: false, int slot}) { | 684 {bool linked: false, int slot}) { |
| 685 EntityRefBuilder b = new EntityRefBuilder(slot: slot); | 685 EntityRefBuilder b = new EntityRefBuilder(slot: slot); |
| 686 if (type is TypeParameterType) { | 686 if (type is TypeParameterType) { |
| 687 b.paramReference = findTypeParameterIndex(type, context); | 687 b.paramReference = findTypeParameterIndex(type, context); |
| 688 } else { | 688 } else { |
| 689 b.reference = serializeReferenceForType(type, linked); | 689 if (type is FunctionType && |
| 690 type.element.enclosingElement is ParameterElement) { |
| 691 // Code cannot refer to function types implicitly defined by parameters |
| 692 // directly, so if we get here, we must be serializing a linked |
| 693 // reference from type inference. |
| 694 assert(linked); |
| 695 ParameterElement parameterElement = type.element.enclosingElement; |
| 696 while (true) { |
| 697 Element parent = parameterElement.enclosingElement; |
| 698 if (parent is ExecutableElement) { |
| 699 Element grandParent = parent.enclosingElement; |
| 700 b.implicitFunctionTypeIndices |
| 701 .insert(0, parent.parameters.indexOf(parameterElement)); |
| 702 if (grandParent is ParameterElement) { |
| 703 // Function-typed parameter inside a function-typed parameter. |
| 704 parameterElement = grandParent; |
| 705 continue; |
| 706 } else { |
| 707 // Function-typed parameter inside a top level function or method. |
| 708 b.reference = _getElementReferenceId(parent, linked: linked); |
| 709 break; |
| 710 } |
| 711 } else { |
| 712 throw new StateError( |
| 713 'Unexpected element enclosing parameter: ${parent.runtimeType}')
; |
| 714 } |
| 715 } |
| 716 } else { |
| 717 b.reference = serializeReferenceForType(type, linked); |
| 718 } |
| 690 List<DartType> typeArguments = getTypeArguments(type); | 719 List<DartType> typeArguments = getTypeArguments(type); |
| 691 if (typeArguments != null) { | 720 if (typeArguments != null) { |
| 692 // Trailing type arguments of type 'dynamic' should be omitted. | 721 // Trailing type arguments of type 'dynamic' should be omitted. |
| 693 int numArgsToSerialize = typeArguments.length; | 722 int numArgsToSerialize = typeArguments.length; |
| 694 while (numArgsToSerialize > 0 && | 723 while (numArgsToSerialize > 0 && |
| 695 typeArguments[numArgsToSerialize - 1].isDynamic) { | 724 typeArguments[numArgsToSerialize - 1].isDynamic) { |
| 696 --numArgsToSerialize; | 725 --numArgsToSerialize; |
| 697 } | 726 } |
| 698 if (numArgsToSerialize > 0) { | 727 if (numArgsToSerialize > 0) { |
| 699 List<EntityRefBuilder> serializedArguments = <EntityRefBuilder>[]; | 728 List<EntityRefBuilder> serializedArguments = <EntityRefBuilder>[]; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 .add(() => serializeTypeRef(type, context, linked: true, slot: slot)); | 823 .add(() => serializeTypeRef(type, context, linked: true, slot: slot)); |
| 795 } | 824 } |
| 796 return slot; | 825 return slot; |
| 797 } | 826 } |
| 798 | 827 |
| 799 int _getElementReferenceId(Element element, {bool linked: false}) { | 828 int _getElementReferenceId(Element element, {bool linked: false}) { |
| 800 return referenceMap.putIfAbsent(element, () { | 829 return referenceMap.putIfAbsent(element, () { |
| 801 if (element is ConstructorElement && element.displayName.isEmpty) { | 830 if (element is ConstructorElement && element.displayName.isEmpty) { |
| 802 return _getElementReferenceId(element.enclosingElement, linked: linked); | 831 return _getElementReferenceId(element.enclosingElement, linked: linked); |
| 803 } | 832 } |
| 804 if (element is MethodElement && !element.isStatic) { | |
| 805 throw new StateError('Only static methods can be serialized.'); | |
| 806 } | |
| 807 if (element is PropertyAccessorElement) { | |
| 808 Element enclosing = element.enclosingElement; | |
| 809 if (!(enclosing is CompilationUnitElement || element.isStatic)) { | |
| 810 throw new StateError( | |
| 811 'Only top-level or static property accessors can be serialized.'); | |
| 812 } | |
| 813 } | |
| 814 LibraryElement dependentLibrary = element?.library; | 833 LibraryElement dependentLibrary = element?.library; |
| 815 int unit; | 834 int unit; |
| 816 if (dependentLibrary == null) { | 835 if (dependentLibrary == null) { |
| 817 assert(element == librarySerializer.typeProvider.dynamicType.element || | 836 assert(element == librarySerializer.typeProvider.dynamicType.element || |
| 818 element == null); | 837 element == null); |
| 819 unit = 0; | 838 unit = 0; |
| 820 dependentLibrary = librarySerializer.libraryElement; | 839 dependentLibrary = librarySerializer.libraryElement; |
| 821 } else { | 840 } else { |
| 822 CompilationUnitElement unitElement = | 841 CompilationUnitElement unitElement = |
| 823 element.getAncestor((Element e) => e is CompilationUnitElement); | 842 element.getAncestor((Element e) => e is CompilationUnitElement); |
| 824 unit = dependentLibrary.units.indexOf(unitElement); | 843 unit = dependentLibrary.units.indexOf(unitElement); |
| 825 assert(unit != -1); | 844 assert(unit != -1); |
| 826 } | 845 } |
| 827 int numTypeParameters = 0; | 846 int numTypeParameters = 0; |
| 828 if (element is TypeParameterizedElement) { | 847 if (element is TypeParameterizedElement) { |
| 829 numTypeParameters = element.typeParameters.length; | 848 numTypeParameters = element.typeParameters.length; |
| 830 } | 849 } |
| 831 LinkedReferenceBuilder linkedReference = new LinkedReferenceBuilder( | 850 LinkedReferenceBuilder linkedReference = new LinkedReferenceBuilder( |
| 832 dependency: librarySerializer.serializeDependency(dependentLibrary), | 851 dependency: librarySerializer.serializeDependency(dependentLibrary), |
| 833 kind: _getReferenceKind(element), | 852 kind: _getReferenceKind(element), |
| 834 unit: unit, | 853 unit: unit, |
| 835 numTypeParameters: numTypeParameters); | 854 numTypeParameters: numTypeParameters); |
| 836 String name = element == null ? 'void' : element.name; | 855 String name = element == null ? 'void' : element.name; |
| 837 if (linked) { | 856 if (linked) { |
| 838 linkedReference.name = name; | 857 linkedReference.name = name; |
| 858 Element enclosing = element?.enclosingElement; |
| 859 if (enclosing is ClassElement) { |
| 860 linkedReference.containingReference = |
| 861 _getElementReferenceId(enclosing, linked: linked); |
| 862 } |
| 839 } else { | 863 } else { |
| 840 assert(unlinkedReferences.length == linkedReferences.length); | 864 assert(unlinkedReferences.length == linkedReferences.length); |
| 841 int prefixReference = 0; | 865 int prefixReference = 0; |
| 842 Element enclosing = element?.enclosingElement; | 866 Element enclosing = element?.enclosingElement; |
| 843 if (enclosing == null || enclosing is CompilationUnitElement) { | 867 if (enclosing == null || enclosing is CompilationUnitElement) { |
| 844 // Figure out a prefix that may be used to refer to the given element. | 868 // Figure out a prefix that may be used to refer to the given element. |
| 845 // TODO(paulberry): to avoid subtle relinking inconsistencies we | 869 // TODO(paulberry): to avoid subtle relinking inconsistencies we |
| 846 // should use the actual prefix from the AST (a given type may be | 870 // should use the actual prefix from the AST (a given type may be |
| 847 // reachable via multiple prefixes), but sadly, this information is | 871 // reachable via multiple prefixes), but sadly, this information is |
| 848 // not recorded in the element model. | 872 // not recorded in the element model. |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1117 exportNames.add(new LinkedExportNameBuilder( | 1141 exportNames.add(new LinkedExportNameBuilder( |
| 1118 name: name, | 1142 name: name, |
| 1119 dependency: serializeDependency(dependentLibrary), | 1143 dependency: serializeDependency(dependentLibrary), |
| 1120 unit: unit, | 1144 unit: unit, |
| 1121 kind: kind)); | 1145 kind: kind)); |
| 1122 } | 1146 } |
| 1123 pb.exportNames = exportNames; | 1147 pb.exportNames = exportNames; |
| 1124 return pb; | 1148 return pb; |
| 1125 } | 1149 } |
| 1126 } | 1150 } |
| OLD | NEW |