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 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 for (MethodElement method in cls.methods) { | 424 for (MethodElement method in cls.methods) { |
425 if (method.isStatic && method.isPublic) { | 425 if (method.isStatic && method.isPublic) { |
426 // TODO(paulberry): should numTypeParameters include class params? | 426 // TODO(paulberry): should numTypeParameters include class params? |
427 bs.add(new UnlinkedPublicNameBuilder( | 427 bs.add(new UnlinkedPublicNameBuilder( |
428 name: method.name, | 428 name: method.name, |
429 kind: ReferenceKind.method, | 429 kind: ReferenceKind.method, |
430 numTypeParameters: method.typeParameters.length)); | 430 numTypeParameters: method.typeParameters.length)); |
431 } | 431 } |
432 } | 432 } |
433 for (ConstructorElement constructor in cls.constructors) { | 433 for (ConstructorElement constructor in cls.constructors) { |
434 if (constructor.isPublic && | 434 if (constructor.isPublic && constructor.name.isNotEmpty) { |
435 constructor.name.isNotEmpty) { | |
436 // TODO(paulberry): should numTypeParameters include class params? | 435 // TODO(paulberry): should numTypeParameters include class params? |
437 bs.add(new UnlinkedPublicNameBuilder( | 436 bs.add(new UnlinkedPublicNameBuilder( |
438 name: constructor.name, | 437 name: constructor.name, |
439 kind: ReferenceKind.constructor, | 438 kind: ReferenceKind.constructor, |
440 numTypeParameters: 0)); | 439 numTypeParameters: 0)); |
441 } | 440 } |
442 } | 441 } |
443 return bs; | 442 return bs; |
444 } | 443 } |
445 return null; | 444 return null; |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 b.defaultValue = serializeConstExpr(initializer); | 659 b.defaultValue = serializeConstExpr(initializer); |
661 } | 660 } |
662 } | 661 } |
663 return b; | 662 return b; |
664 } | 663 } |
665 | 664 |
666 /** | 665 /** |
667 * Serialize the given [prefix] into an index into the references table. | 666 * Serialize the given [prefix] into an index into the references table. |
668 */ | 667 */ |
669 int serializePrefix(PrefixElement element) { | 668 int serializePrefix(PrefixElement element) { |
670 return referenceMap.putIfAbsent(element, () { | 669 return referenceMap.putIfAbsent(element, |
671 assert(unlinkedReferences.length == linkedReferences.length); | 670 () => serializeUnlinkedReference(element.name, ReferenceKind.prefix)); |
672 int index = unlinkedReferences.length; | |
673 unlinkedReferences.add(new UnlinkedReferenceBuilder(name: element.name)); | |
674 linkedReferences | |
675 .add(new LinkedReferenceBuilder(kind: ReferenceKind.prefix)); | |
676 return index; | |
677 }); | |
678 } | 671 } |
679 | 672 |
680 /** | 673 /** |
681 * Compute the reference index which should be stored in a [EntityRef]. | 674 * Compute the reference index which should be stored in a [EntityRef]. |
682 * | 675 * |
683 * If [linked] is true, and a new reference has to be created, the reference | 676 * If [linked] is true, and a new reference has to be created, the reference |
684 * will only be stored in [linkedReferences]. | 677 * will only be stored in [linkedReferences]. |
685 */ | 678 */ |
686 int serializeReferenceForType(DartType type, bool linked) { | 679 int serializeReferenceForType(DartType type, bool linked) { |
687 Element element = type.element; | 680 Element element = type.element; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
789 serializeTypeRef(typeArguments[i], context, linked: linked)); | 782 serializeTypeRef(typeArguments[i], context, linked: linked)); |
790 } | 783 } |
791 b.typeArguments = serializedArguments; | 784 b.typeArguments = serializedArguments; |
792 } | 785 } |
793 } | 786 } |
794 } | 787 } |
795 return b; | 788 return b; |
796 } | 789 } |
797 | 790 |
798 /** | 791 /** |
| 792 * Create a new entry in the references table ([UnlinkedLibrary.references] |
| 793 * and [LinkedLibrary.references]) representing an entity having the given |
| 794 * [name] and [kind]. If [unit] is given, it is the index of the compilation |
| 795 * unit containing the entity being referred to. If [prefixReference] is |
| 796 * given, it indicates the entry in the references table for the prefix. |
| 797 */ |
| 798 int serializeUnlinkedReference(String name, ReferenceKind kind, |
| 799 {int unit: 0, int prefixReference: 0}) { |
| 800 assert(unlinkedReferences.length == linkedReferences.length); |
| 801 int index = unlinkedReferences.length; |
| 802 unlinkedReferences.add(new UnlinkedReferenceBuilder( |
| 803 name: name, prefixReference: prefixReference)); |
| 804 linkedReferences.add(new LinkedReferenceBuilder(kind: kind, unit: unit)); |
| 805 return index; |
| 806 } |
| 807 |
| 808 /** |
799 * Return the index of the entry in the references table | 809 * Return the index of the entry in the references table |
800 * ([UnlinkedLibrary.references] and [LinkedLibrary.references]) used for | 810 * ([UnlinkedLibrary.references] and [LinkedLibrary.references]) used for |
801 * unresolved references. A new entry is added to the table if necessary to | 811 * unresolved references. A new entry is added to the table if necessary to |
802 * satisfy the request. | 812 * satisfy the request. |
803 */ | 813 */ |
804 int serializeUnresolvedReference() { | 814 int serializeUnresolvedReference() { |
805 // TODO(paulberry): in order for relinking to work, we need to record the | 815 // TODO(paulberry): in order for relinking to work, we need to record the |
806 // name and prefix of the unresolved symbol. This is not (yet) encoded in | 816 // name and prefix of the unresolved symbol. This is not (yet) encoded in |
807 // the element model. For the moment we use a name that can't possibly | 817 // the element model. For the moment we use a name that can't possibly |
808 // ever exist. | 818 // ever exist. |
809 if (unresolvedReferenceIndex == null) { | 819 if (unresolvedReferenceIndex == null) { |
810 assert(unlinkedReferences.length == linkedReferences.length); | 820 return serializeUnlinkedReference( |
811 unresolvedReferenceIndex = unlinkedReferences.length; | 821 '*unresolved*', ReferenceKind.unresolved); |
812 unlinkedReferences | |
813 .add(new UnlinkedReferenceBuilder(name: '*unresolved*')); | |
814 linkedReferences | |
815 .add(new LinkedReferenceBuilder(kind: ReferenceKind.unresolved)); | |
816 } | 822 } |
817 return unresolvedReferenceIndex; | 823 return unresolvedReferenceIndex; |
818 } | 824 } |
819 | 825 |
820 /** | 826 /** |
821 * Serialize the given [variable], creating an [UnlinkedVariable]. | 827 * Serialize the given [variable], creating an [UnlinkedVariable]. |
822 */ | 828 */ |
823 UnlinkedVariableBuilder serializeVariable(PropertyInducingElement variable) { | 829 UnlinkedVariableBuilder serializeVariable(PropertyInducingElement variable) { |
824 UnlinkedVariableBuilder b = new UnlinkedVariableBuilder(); | 830 UnlinkedVariableBuilder b = new UnlinkedVariableBuilder(); |
825 b.name = variable.name; | 831 b.name = variable.name; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
896 int unit; | 902 int unit; |
897 if (dependentLibrary == null) { | 903 if (dependentLibrary == null) { |
898 unit = 0; | 904 unit = 0; |
899 dependentLibrary = librarySerializer.libraryElement; | 905 dependentLibrary = librarySerializer.libraryElement; |
900 } else { | 906 } else { |
901 CompilationUnitElement unitElement = | 907 CompilationUnitElement unitElement = |
902 element.getAncestor((Element e) => e is CompilationUnitElement); | 908 element.getAncestor((Element e) => e is CompilationUnitElement); |
903 unit = dependentLibrary.units.indexOf(unitElement); | 909 unit = dependentLibrary.units.indexOf(unitElement); |
904 assert(unit != -1); | 910 assert(unit != -1); |
905 } | 911 } |
906 LinkedReferenceBuilder linkedReference = new LinkedReferenceBuilder( | 912 ReferenceKind kind = _getReferenceKind(element); |
907 dependency: librarySerializer.serializeDependency(dependentLibrary), | |
908 kind: _getReferenceKind(element), | |
909 unit: unit); | |
910 if (element is TypeParameterizedElement) { | |
911 linkedReference.numTypeParameters = element.typeParameters.length; | |
912 } | |
913 String name = element == null ? 'void' : element.name; | 913 String name = element == null ? 'void' : element.name; |
| 914 int index; |
| 915 LinkedReferenceBuilder linkedReference; |
914 if (linked) { | 916 if (linked) { |
915 linkedReference.name = name; | 917 linkedReference = |
| 918 new LinkedReferenceBuilder(kind: kind, unit: unit, name: name); |
916 Element enclosing = element?.enclosingElement; | 919 Element enclosing = element?.enclosingElement; |
917 if (enclosing is ClassElement) { | 920 if (enclosing is ClassElement) { |
918 linkedReference.containingReference = | 921 linkedReference.containingReference = |
919 _getElementReferenceId(enclosing, linked: linked); | 922 _getElementReferenceId(enclosing, linked: linked); |
920 linkedReference.numTypeParameters += enclosing.typeParameters.length; | 923 linkedReference.numTypeParameters = enclosing.typeParameters.length; |
921 } | 924 } |
| 925 index = linkedReferences.length; |
| 926 linkedReferences.add(linkedReference); |
922 } else { | 927 } else { |
923 assert(unlinkedReferences.length == linkedReferences.length); | 928 assert(unlinkedReferences.length == linkedReferences.length); |
924 int prefixReference = 0; | 929 int prefixReference = 0; |
925 Element enclosing = element?.enclosingElement; | 930 Element enclosing = element?.enclosingElement; |
926 if (enclosing == null || enclosing is CompilationUnitElement) { | 931 if (enclosing == null || enclosing is CompilationUnitElement) { |
927 // Figure out a prefix that may be used to refer to the given element. | 932 // Figure out a prefix that may be used to refer to the given element. |
928 // TODO(paulberry): to avoid subtle relinking inconsistencies we | 933 // TODO(paulberry): to avoid subtle relinking inconsistencies we |
929 // should use the actual prefix from the AST (a given type may be | 934 // should use the actual prefix from the AST (a given type may be |
930 // reachable via multiple prefixes), but sadly, this information is | 935 // reachable via multiple prefixes), but sadly, this information is |
931 // not recorded in the element model. | 936 // not recorded in the element model. |
932 PrefixElement prefix = librarySerializer.prefixMap[element]; | 937 PrefixElement prefix = librarySerializer.prefixMap[element]; |
933 if (prefix != null) { | 938 if (prefix != null) { |
934 prefixReference = serializePrefix(prefix); | 939 prefixReference = serializePrefix(prefix); |
935 } | 940 } |
936 } else { | 941 } else { |
937 prefixReference = _getElementReferenceId(enclosing, linked: linked); | 942 prefixReference = _getElementReferenceId(enclosing, linked: linked); |
938 } | 943 } |
939 unlinkedReferences.add(new UnlinkedReferenceBuilder( | 944 index = serializeUnlinkedReference(name, kind, |
940 name: name, prefixReference: prefixReference)); | 945 prefixReference: prefixReference, unit: unit); |
| 946 linkedReference = linkedReferences[index]; |
941 } | 947 } |
942 int index = linkedReferences.length; | 948 linkedReference.dependency = |
943 linkedReferences.add(linkedReference); | 949 librarySerializer.serializeDependency(dependentLibrary); |
| 950 if (element is TypeParameterizedElement) { |
| 951 linkedReference.numTypeParameters += element.typeParameters.length; |
| 952 } |
944 return index; | 953 return index; |
945 }); | 954 }); |
946 } | 955 } |
947 | 956 |
948 int _getLengthPropertyReference(int prefix) { | 957 int _getLengthPropertyReference(int prefix) { |
949 assert(unlinkedReferences.length == linkedReferences.length); | 958 return serializeUnlinkedReference('length', ReferenceKind.length, |
950 int index = linkedReferences.length; | 959 prefixReference: prefix); |
951 unlinkedReferences.add( | |
952 new UnlinkedReferenceBuilder(name: 'length', prefixReference: prefix)); | |
953 LinkedReferenceBuilder linkedReference = | |
954 new LinkedReferenceBuilder(kind: ReferenceKind.length); | |
955 linkedReferences.add(linkedReference); | |
956 return index; | |
957 } | 960 } |
958 } | 961 } |
959 | 962 |
960 /** | 963 /** |
961 * Instances of this class keep track of intermediate state during | 964 * Instances of this class keep track of intermediate state during |
962 * serialization of a single constant [Expression]. | 965 * serialization of a single constant [Expression]. |
963 */ | 966 */ |
964 class _ConstExprSerializer extends AbstractConstExprSerializer { | 967 class _ConstExprSerializer extends AbstractConstExprSerializer { |
965 final _CompilationUnitSerializer serializer; | 968 final _CompilationUnitSerializer serializer; |
966 | 969 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1003 } | 1006 } |
1004 } | 1007 } |
1005 | 1008 |
1006 @override | 1009 @override |
1007 EntityRefBuilder serializeConstructorName( | 1010 EntityRefBuilder serializeConstructorName( |
1008 TypeName type, SimpleIdentifier name) { | 1011 TypeName type, SimpleIdentifier name) { |
1009 EntityRefBuilder typeRef = serializer.serializeTypeRef(type.type, null); | 1012 EntityRefBuilder typeRef = serializer.serializeTypeRef(type.type, null); |
1010 if (name == null) { | 1013 if (name == null) { |
1011 return typeRef; | 1014 return typeRef; |
1012 } else { | 1015 } else { |
1013 int typeId = typeRef.reference; | 1016 LinkedReference typeLinkedRef = |
1014 LinkedReference typeLinkedRef = serializer.linkedReferences[typeId]; | 1017 serializer.linkedReferences[typeRef.reference]; |
1015 serializer.unlinkedReferences.add(new UnlinkedReferenceBuilder( | 1018 int refId = serializer.serializeUnlinkedReference( |
1016 name: name.name, prefixReference: typeId)); | 1019 name.name, ReferenceKind.constructor, |
1017 int refId = serializer.linkedReferences.length; | 1020 prefixReference: typeRef.reference, unit: typeLinkedRef.unit); |
1018 serializer.linkedReferences.add(new LinkedReferenceBuilder( | |
1019 kind: ReferenceKind.constructor, unit: typeLinkedRef.unit)); | |
1020 return new EntityRefBuilder( | 1021 return new EntityRefBuilder( |
1021 reference: refId, typeArguments: typeRef.typeArguments); | 1022 reference: refId, typeArguments: typeRef.typeArguments); |
1022 } | 1023 } |
1023 } | 1024 } |
1024 | 1025 |
1025 EntityRefBuilder serializeIdentifier(Identifier identifier) { | 1026 EntityRefBuilder serializeIdentifier(Identifier identifier) { |
1026 Element element = identifier.staticElement; | 1027 Element element = identifier.staticElement; |
1027 assert(element != null); | 1028 assert(element != null); |
1028 // The only supported instance property accessor - `length`. | 1029 // The only supported instance property accessor - `length`. |
1029 if (identifier is PrefixedIdentifier && | 1030 if (identifier is PrefixedIdentifier && |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1253 exportNames.add(new LinkedExportNameBuilder( | 1254 exportNames.add(new LinkedExportNameBuilder( |
1254 name: name, | 1255 name: name, |
1255 dependency: serializeDependency(dependentLibrary), | 1256 dependency: serializeDependency(dependentLibrary), |
1256 unit: unit, | 1257 unit: unit, |
1257 kind: kind)); | 1258 kind: kind)); |
1258 } | 1259 } |
1259 pb.exportNames = exportNames; | 1260 pb.exportNames = exportNames; |
1260 return pb; | 1261 return pb; |
1261 } | 1262 } |
1262 } | 1263 } |
OLD | NEW |