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 dart2js.serialization; | 5 library dart2js.serialization; |
6 | 6 |
7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../common/resolution.dart'; |
8 import '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
9 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
10 import '../elements/elements.dart'; | 11 import '../elements/elements.dart'; |
| 12 import '../library_loader.dart' show LibraryProvider; |
11 import '../util/enumset.dart'; | 13 import '../util/enumset.dart'; |
12 | 14 |
13 import 'constant_serialization.dart'; | 15 import 'constant_serialization.dart'; |
14 import 'element_serialization.dart'; | 16 import 'element_serialization.dart'; |
15 import 'json_serializer.dart'; | 17 import 'json_serializer.dart'; |
16 import 'keys.dart'; | 18 import 'keys.dart'; |
17 import 'type_serialization.dart'; | 19 import 'type_serialization.dart'; |
18 import 'values.dart'; | 20 import 'values.dart'; |
19 | 21 |
20 export 'task.dart' show LibraryDeserializer; | 22 export 'task.dart' show LibraryDeserializer; |
(...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
914 /// [element]. If not object is stored for [tag], [getDecoder] returns `null`. | 916 /// [element]. If not object is stored for [tag], [getDecoder] returns `null`. |
915 void onElement(Element element, ObjectDecoder getDecoder(String tag)) {} | 917 void onElement(Element element, ObjectDecoder getDecoder(String tag)) {} |
916 | 918 |
917 /// Called to deserialize custom data from [decoder]. | 919 /// Called to deserialize custom data from [decoder]. |
918 dynamic onData(ObjectDecoder decoder) {} | 920 dynamic onData(ObjectDecoder decoder) {} |
919 } | 921 } |
920 | 922 |
921 /// Context for parallel deserialization. | 923 /// Context for parallel deserialization. |
922 class DeserializationContext { | 924 class DeserializationContext { |
923 final DiagnosticReporter reporter; | 925 final DiagnosticReporter reporter; |
| 926 final Resolution resolution; |
| 927 final LibraryProvider libraryProvider; |
924 Map<Uri, LibraryElement> _uriMap = <Uri, LibraryElement>{}; | 928 Map<Uri, LibraryElement> _uriMap = <Uri, LibraryElement>{}; |
925 List<Deserializer> deserializers = <Deserializer>[]; | 929 List<Deserializer> deserializers = <Deserializer>[]; |
926 List<DeserializerPlugin> plugins = <DeserializerPlugin>[]; | 930 List<DeserializerPlugin> plugins = <DeserializerPlugin>[]; |
927 | 931 |
928 DeserializationContext(this.reporter); | 932 DeserializationContext(this.reporter, this.resolution, this.libraryProvider); |
929 | 933 |
930 LibraryElement lookupLibrary(Uri uri) { | 934 LibraryElement lookupLibrary(Uri uri) { |
| 935 // TODO(johnniwinther): Move this to the library loader by making a |
| 936 // [Deserializer] a [LibraryProvider]. |
931 return _uriMap.putIfAbsent(uri, () { | 937 return _uriMap.putIfAbsent(uri, () { |
932 Uri foundUri; | 938 Uri foundUri; |
933 LibraryElement foundLibrary; | 939 LibraryElement foundLibrary; |
934 for (Deserializer deserializer in deserializers) { | 940 for (Deserializer deserializer in deserializers) { |
935 LibraryElement library = deserializer.lookupLibrary(uri); | 941 LibraryElement library = deserializer.lookupLibrary(uri); |
936 if (library != null) { | 942 if (library != null) { |
937 if (foundLibrary != null) { | 943 if (foundLibrary != null) { |
938 reporter.reportErrorMessage(NO_LOCATION_SPANNABLE, | 944 reporter.reportErrorMessage(NO_LOCATION_SPANNABLE, |
939 MessageKind.DUPLICATE_SERIALIZED_LIBRARY, { | 945 MessageKind.DUPLICATE_SERIALIZED_LIBRARY, { |
940 'libraryUri': uri, | 946 'libraryUri': uri, |
941 'sourceUri1': foundUri, | 947 'sourceUri1': foundUri, |
942 'sourceUri2': deserializer.sourceUri | 948 'sourceUri2': deserializer.sourceUri |
943 }); | 949 }); |
944 } | 950 } |
945 foundUri = deserializer.sourceUri; | 951 foundUri = deserializer.sourceUri; |
946 foundLibrary = library; | 952 foundLibrary = library; |
947 } | 953 } |
948 } | 954 } |
949 return foundLibrary; | 955 return foundLibrary; |
950 }); | 956 }); |
951 } | 957 } |
| 958 |
| 959 LibraryElement findLibrary(Uri uri) { |
| 960 LibraryElement library = lookupLibrary(uri); |
| 961 return library ?? libraryProvider.lookupLibrary(uri); |
| 962 } |
952 } | 963 } |
953 | 964 |
954 /// Deserializer for a closed collection of libraries. | 965 /// Deserializer for a closed collection of libraries. |
955 // TODO(johnniwinther): Support per-library deserialization and dependencies | 966 // TODO(johnniwinther): Support per-library deserialization and dependencies |
956 // between deserialized subcomponent. | 967 // between deserialized subcomponent. |
957 class Deserializer { | 968 class Deserializer { |
958 final DeserializationContext context; | 969 final DeserializationContext context; |
959 final SerializationDecoder decoder; | 970 final SerializationDecoder decoder; |
960 final Uri sourceUri; | 971 final Uri sourceUri; |
961 ObjectDecoder _headerObject; | 972 ObjectDecoder _headerObject; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1017 /// Returns the deserialized [Element] for [id]. | 1028 /// Returns the deserialized [Element] for [id]. |
1018 Element deserializeElement(int id) { | 1029 Element deserializeElement(int id) { |
1019 if (id == null) throw new ArgumentError('Deserializer.getElement(null)'); | 1030 if (id == null) throw new ArgumentError('Deserializer.getElement(null)'); |
1020 Element element = _elementMap[id]; | 1031 Element element = _elementMap[id]; |
1021 if (element == null) { | 1032 if (element == null) { |
1022 ObjectDecoder decoder = elements.getObject(id); | 1033 ObjectDecoder decoder = elements.getObject(id); |
1023 SerializedElementKind elementKind = | 1034 SerializedElementKind elementKind = |
1024 decoder.getEnum(Key.KIND, SerializedElementKind.values); | 1035 decoder.getEnum(Key.KIND, SerializedElementKind.values); |
1025 if (elementKind == SerializedElementKind.EXTERNAL_LIBRARY) { | 1036 if (elementKind == SerializedElementKind.EXTERNAL_LIBRARY) { |
1026 Uri uri = decoder.getUri(Key.URI); | 1037 Uri uri = decoder.getUri(Key.URI); |
1027 element = context.lookupLibrary(uri); | 1038 element = context.findLibrary(uri); |
1028 if (element == null) { | 1039 if (element == null) { |
1029 throw new StateError("Missing library for $uri."); | 1040 throw new StateError("Missing library for $uri."); |
1030 } | 1041 } |
1031 } else if (elementKind == SerializedElementKind.EXTERNAL_LIBRARY_MEMBER) { | 1042 } else if (elementKind == SerializedElementKind.EXTERNAL_LIBRARY_MEMBER) { |
1032 LibraryElement library = decoder.getElement(Key.LIBRARY); | 1043 LibraryElement library = decoder.getElement(Key.LIBRARY); |
1033 String name = decoder.getString(Key.NAME); | 1044 String name = decoder.getString(Key.NAME); |
1034 bool isGetter = decoder.getBool(Key.GETTER, isOptional: true); | 1045 bool isGetter = decoder.getBool(Key.GETTER, isOptional: true); |
1035 element = library.find(name); | 1046 element = library.find(name); |
1036 if (element == null) { | 1047 if (element == null) { |
1037 throw new StateError("Missing library member for $name in $library."); | 1048 throw new StateError("Missing library member for $name in $library."); |
1038 } | 1049 } |
1039 if (isGetter != null) { | 1050 if (isGetter != null) { |
1040 AbstractFieldElement abstractField = element; | 1051 AbstractFieldElement abstractField = element; |
1041 element = isGetter ? abstractField.getter : abstractField.setter; | 1052 element = isGetter ? abstractField.getter : abstractField.setter; |
1042 if (element == null) { | 1053 if (element == null) { |
1043 throw new StateError( | 1054 throw new StateError( |
1044 "Missing ${isGetter ? 'getter' : 'setter'} for " | 1055 "Missing ${isGetter ? 'getter' : 'setter'} for " |
1045 "$name in $library."); | 1056 "$name in $library."); |
1046 } | 1057 } |
1047 } | 1058 } |
1048 } else if (elementKind == SerializedElementKind.EXTERNAL_CLASS_MEMBER) { | 1059 } else if (elementKind == SerializedElementKind.EXTERNAL_CLASS_MEMBER) { |
1049 ClassElement cls = decoder.getElement(Key.CLASS); | 1060 ClassElement cls = decoder.getElement(Key.CLASS); |
| 1061 cls.ensureResolved(context.resolution); |
1050 String name = decoder.getString(Key.NAME); | 1062 String name = decoder.getString(Key.NAME); |
1051 bool isGetter = decoder.getBool(Key.GETTER, isOptional: true); | 1063 bool isGetter = decoder.getBool(Key.GETTER, isOptional: true); |
1052 element = cls.lookupLocalMember(name); | 1064 element = cls.lookupLocalMember(name); |
1053 if (element == null) { | 1065 if (element == null) { |
1054 throw new StateError("Missing class member for $name in $cls."); | 1066 throw new StateError("Missing class member for $name in $cls."); |
1055 } | 1067 } |
1056 if (isGetter != null) { | 1068 if (isGetter != null) { |
1057 AbstractFieldElement abstractField = element; | 1069 AbstractFieldElement abstractField = element; |
1058 element = isGetter ? abstractField.getter : abstractField.setter; | 1070 element = isGetter ? abstractField.getter : abstractField.setter; |
1059 if (element == null) { | 1071 if (element == null) { |
1060 throw new StateError( | 1072 throw new StateError( |
1061 "Missing ${isGetter ? 'getter' : 'setter'} for $name in $cls."); | 1073 "Missing ${isGetter ? 'getter' : 'setter'} for $name in $cls."); |
1062 } | 1074 } |
1063 } | 1075 } |
1064 } else if (elementKind == SerializedElementKind.EXTERNAL_CONSTRUCTOR) { | 1076 } else if (elementKind == SerializedElementKind.EXTERNAL_CONSTRUCTOR) { |
1065 ClassElement cls = decoder.getElement(Key.CLASS); | 1077 ClassElement cls = decoder.getElement(Key.CLASS); |
| 1078 cls.ensureResolved(context.resolution); |
1066 String name = decoder.getString(Key.NAME); | 1079 String name = decoder.getString(Key.NAME); |
1067 element = cls.lookupConstructor(name); | 1080 element = cls.lookupConstructor(name); |
1068 if (element == null) { | 1081 if (element == null) { |
1069 throw new StateError("Missing constructor for $name in $cls."); | 1082 throw new StateError("Missing constructor for $name in $cls."); |
1070 } | 1083 } |
1071 } else { | 1084 } else { |
1072 element = ElementDeserializer.deserialize(decoder, elementKind); | 1085 element = ElementDeserializer.deserialize(decoder, elementKind); |
1073 } | 1086 } |
1074 _elementMap[id] = element; | 1087 _elementMap[id] = element; |
1075 | 1088 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1116 | 1129 |
1117 /// Returns the value used to store [key] as a property in the encoding an | 1130 /// Returns the value used to store [key] as a property in the encoding an |
1118 /// [ObjectValue]. | 1131 /// [ObjectValue]. |
1119 /// | 1132 /// |
1120 /// Different encodings have different restrictions and capabilities as how | 1133 /// Different encodings have different restrictions and capabilities as how |
1121 /// to store a [Key] value. For instance: A JSON encoding needs to convert | 1134 /// to store a [Key] value. For instance: A JSON encoding needs to convert |
1122 /// [Key] to a [String] to store it in a JSON object; a Dart encoding can | 1135 /// [Key] to a [String] to store it in a JSON object; a Dart encoding can |
1123 /// choose to store a [Key] as an [int] or as the [Key] itself. | 1136 /// choose to store a [Key] as an [int] or as the [Key] itself. |
1124 getObjectPropertyValue(Key key); | 1137 getObjectPropertyValue(Key key); |
1125 } | 1138 } |
OLD | NEW |