OLD | NEW |
---|---|
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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_helper; | 5 library dart2js.serialization_helper; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'package:async_helper/async_helper.dart'; | 8 import 'package:async_helper/async_helper.dart'; |
9 import 'package:expect/expect.dart'; | 9 import 'package:expect/expect.dart'; |
10 import 'package:compiler/compiler_new.dart'; | |
10 import 'package:compiler/src/commandline_options.dart'; | 11 import 'package:compiler/src/commandline_options.dart'; |
11 import 'package:compiler/src/common/backend_api.dart'; | 12 import 'package:compiler/src/common/backend_api.dart'; |
12 import 'package:compiler/src/common/names.dart'; | 13 import 'package:compiler/src/common/names.dart'; |
13 import 'package:compiler/src/common/resolution.dart'; | 14 import 'package:compiler/src/common/resolution.dart'; |
14 import 'package:compiler/src/compiler.dart'; | 15 import 'package:compiler/src/compiler.dart'; |
15 import 'package:compiler/src/elements/elements.dart'; | 16 import 'package:compiler/src/elements/elements.dart'; |
16 import 'package:compiler/src/filenames.dart'; | 17 import 'package:compiler/src/filenames.dart'; |
18 import 'package:compiler/src/io/source_file.dart'; | |
19 import 'package:compiler/src/scanner/scanner.dart'; | |
17 import 'package:compiler/src/serialization/element_serialization.dart'; | 20 import 'package:compiler/src/serialization/element_serialization.dart'; |
18 import 'package:compiler/src/serialization/impact_serialization.dart'; | 21 import 'package:compiler/src/serialization/impact_serialization.dart'; |
19 import 'package:compiler/src/serialization/json_serializer.dart'; | 22 import 'package:compiler/src/serialization/json_serializer.dart'; |
23 import 'package:compiler/src/serialization/resolved_ast_serialization.dart'; | |
20 import 'package:compiler/src/serialization/serialization.dart'; | 24 import 'package:compiler/src/serialization/serialization.dart'; |
25 import 'package:compiler/src/serialization/modelz.dart'; | |
21 import 'package:compiler/src/serialization/task.dart'; | 26 import 'package:compiler/src/serialization/task.dart'; |
27 import 'package:compiler/src/tokens/token.dart'; | |
28 import 'package:compiler/src/script.dart'; | |
22 import 'package:compiler/src/universe/world_impact.dart'; | 29 import 'package:compiler/src/universe/world_impact.dart'; |
23 import 'memory_compiler.dart'; | 30 import 'memory_compiler.dart'; |
24 | 31 |
25 | 32 |
26 Future<String> serializeDartCore() async { | 33 Future<String> serializeDartCore({bool serializeResolvedAst: false}) async { |
27 Compiler compiler = compilerFor( | 34 Compiler compiler = compilerFor( |
28 options: [Flags.analyzeAll]); | 35 options: [Flags.analyzeAll]); |
29 compiler.serialization.supportSerialization = true; | 36 compiler.serialization.supportSerialization = true; |
30 await compiler.run(Uris.dart_core); | 37 await compiler.run(Uris.dart_core); |
31 return serialize(compiler, compiler.libraryLoader.libraries) | 38 return serialize( |
32 .toText(const JsonSerializationEncoder()); | 39 compiler, |
40 compiler.libraryLoader.libraries, | |
41 serializeResolvedAst: serializeResolvedAst) | |
42 .toText(const JsonSerializationEncoder()); | |
33 } | 43 } |
34 | 44 |
35 Serializer serialize(Compiler compiler, Iterable<LibraryElement> libraries) { | 45 Serializer serialize( |
46 Compiler compiler, | |
47 Iterable<LibraryElement> libraries, | |
48 {bool serializeResolvedAst: false}) { | |
36 assert(compiler.serialization.supportSerialization); | 49 assert(compiler.serialization.supportSerialization); |
37 | 50 |
38 Serializer serializer = new Serializer(); | 51 Serializer serializer = new Serializer(); |
39 serializer.plugins.add(compiler.backend.serialization.serializer); | 52 serializer.plugins.add(compiler.backend.serialization.serializer); |
40 serializer.plugins.add(new ResolutionImpactSerializer(compiler.resolution)); | 53 serializer.plugins.add(new ResolutionImpactSerializer(compiler.resolution)); |
54 if (serializeResolvedAst) { | |
55 serializer.plugins.add( | |
56 new ResolvedAstSerializerPlugin(compiler.resolution)); | |
57 } | |
41 | 58 |
42 for (LibraryElement library in libraries) { | 59 for (LibraryElement library in libraries) { |
43 serializer.serialize(library); | 60 serializer.serialize(library); |
44 } | 61 } |
45 return serializer; | 62 return serializer; |
46 } | 63 } |
47 | 64 |
48 void deserialize(Compiler compiler, String serializedData) { | 65 void deserialize(Compiler compiler, |
66 String serializedData, | |
Siggi Cherem (dart-lang)
2016/04/08 16:55:33
reminder to run dartfmt before submitting :)
Johnni Winther
2016/04/11 08:54:04
I think we need to on all unittests....
Siggi Cherem (dart-lang)
2016/04/11 17:48:07
Ah - good point, I didn't realize this was on the
| |
67 {bool deserializeResolvedAst: false}) { | |
49 Deserializer deserializer = new Deserializer.fromText( | 68 Deserializer deserializer = new Deserializer.fromText( |
50 new DeserializationContext(), | 69 new DeserializationContext(), |
51 serializedData, | 70 serializedData, |
52 const JsonSerializationDecoder()); | 71 const JsonSerializationDecoder()); |
53 deserializer.plugins.add(compiler.backend.serialization.deserializer); | 72 deserializer.plugins.add(compiler.backend.serialization.deserializer); |
54 compiler.serialization.deserializer = | 73 compiler.serialization.deserializer = |
55 new _DeserializerSystem( | 74 new _DeserializerSystem( |
75 compiler, | |
56 deserializer, | 76 deserializer, |
57 compiler.backend.impactTransformer); | 77 compiler.backend.impactTransformer, |
78 deserializeResolvedAst: deserializeResolvedAst); | |
58 } | 79 } |
59 | 80 |
60 | 81 |
61 const String WORLD_IMPACT_TAG = 'worldImpact'; | 82 const String WORLD_IMPACT_TAG = 'worldImpact'; |
62 | 83 |
63 class ResolutionImpactSerializer extends SerializerPlugin { | 84 class ResolutionImpactSerializer extends SerializerPlugin { |
64 final Resolution resolution; | 85 final Resolution resolution; |
65 | 86 |
66 ResolutionImpactSerializer(this.resolution); | 87 ResolutionImpactSerializer(this.resolution); |
67 | 88 |
(...skipping 13 matching lines...) Expand all Loading... | |
81 @override | 102 @override |
82 void onElement(Element element, ObjectDecoder getDecoder(String tag)) { | 103 void onElement(Element element, ObjectDecoder getDecoder(String tag)) { |
83 ObjectDecoder decoder = getDecoder(WORLD_IMPACT_TAG); | 104 ObjectDecoder decoder = getDecoder(WORLD_IMPACT_TAG); |
84 if (decoder != null) { | 105 if (decoder != null) { |
85 impactMap[element] = ImpactDeserializer.deserializeImpact(decoder); | 106 impactMap[element] = ImpactDeserializer.deserializeImpact(decoder); |
86 } | 107 } |
87 } | 108 } |
88 } | 109 } |
89 | 110 |
90 class _DeserializerSystem extends DeserializerSystem { | 111 class _DeserializerSystem extends DeserializerSystem { |
112 final Compiler _compiler; | |
91 final Deserializer _deserializer; | 113 final Deserializer _deserializer; |
92 final List<LibraryElement> deserializedLibraries = <LibraryElement>[]; | 114 final List<LibraryElement> deserializedLibraries = <LibraryElement>[]; |
93 final ResolutionImpactDeserializer _resolutionImpactDeserializer = | 115 final ResolutionImpactDeserializer _resolutionImpactDeserializer = |
94 new ResolutionImpactDeserializer(); | 116 new ResolutionImpactDeserializer(); |
117 final ResolvedAstDeserializerPlugin _resolvedAstDeserializer; | |
95 final ImpactTransformer _impactTransformer; | 118 final ImpactTransformer _impactTransformer; |
119 final bool _deserializeResolvedAst; | |
96 | 120 |
97 _DeserializerSystem(this._deserializer, this._impactTransformer) { | 121 _DeserializerSystem( |
122 Compiler compiler, | |
123 this._deserializer, | |
124 this._impactTransformer, | |
125 {bool deserializeResolvedAst: false}) | |
126 : this._compiler = compiler, | |
127 this._deserializeResolvedAst = deserializeResolvedAst, | |
128 this._resolvedAstDeserializer = deserializeResolvedAst | |
129 ? new ResolvedAstDeserializerPlugin(compiler.parsing) : null { | |
98 _deserializer.plugins.add(_resolutionImpactDeserializer); | 130 _deserializer.plugins.add(_resolutionImpactDeserializer); |
131 if (_deserializeResolvedAst) { | |
132 _deserializer.plugins.add(_resolvedAstDeserializer); | |
133 } | |
99 } | 134 } |
100 | 135 |
101 LibraryElement readLibrary(Uri resolvedUri) { | 136 @override |
137 Future<LibraryElement> readLibrary(Uri resolvedUri) { | |
Siggi Cherem (dart-lang)
2016/04/08 16:55:33
consider using async for this body?
Johnni Winther
2016/04/11 08:54:04
This is a precursor the 'actual' deserializer so I
| |
102 LibraryElement library = _deserializer.lookupLibrary(resolvedUri); | 138 LibraryElement library = _deserializer.lookupLibrary(resolvedUri); |
103 if (library != null) { | 139 if (library != null) { |
104 deserializedLibraries.add(library); | 140 deserializedLibraries.add(library); |
141 if (_deserializeResolvedAst) { | |
142 return Future.forEach(library.compilationUnits, | |
143 (CompilationUnitElement compilationUnit) { | |
144 Script script = compilationUnit.script; | |
145 return _compiler.readScript(script.readableUri) | |
146 .then((Script newScript) { | |
147 _resolvedAstDeserializer.sourceFiles[script.resourceUri] = | |
148 newScript.file; | |
149 }); | |
150 }).then((_) => library); | |
151 } | |
105 } | 152 } |
106 return library; | 153 return new Future<LibraryElement>.value(library); |
107 } | 154 } |
108 | 155 |
156 @override | |
157 ResolvedAst getResolvedAst(Element element) { | |
158 if (_resolvedAstDeserializer != null) { | |
159 return _resolvedAstDeserializer.getResolvedAst(element); | |
160 } | |
161 return null; | |
162 } | |
163 | |
164 @override | |
109 ResolutionImpact getResolutionImpact(Element element) { | 165 ResolutionImpact getResolutionImpact(Element element) { |
110 return _resolutionImpactDeserializer.impactMap[element]; | 166 return _resolutionImpactDeserializer.impactMap[element]; |
111 } | 167 } |
112 | 168 |
113 @override | 169 @override |
114 WorldImpact computeWorldImpact(Element element) { | 170 WorldImpact computeWorldImpact(Element element) { |
115 ResolutionImpact resolutionImpact = getResolutionImpact(element); | 171 ResolutionImpact resolutionImpact = getResolutionImpact(element); |
116 if (resolutionImpact == null) { | 172 if (resolutionImpact == null) { |
117 print('No impact found for $element (${element.library})'); | 173 print('No impact found for $element (${element.library})'); |
118 return const WorldImpact(); | 174 return const WorldImpact(); |
119 } else { | 175 } else { |
120 return _impactTransformer.transformResolutionImpact(resolutionImpact); | 176 return _impactTransformer.transformResolutionImpact(resolutionImpact); |
121 } | 177 } |
122 } | 178 } |
123 | 179 |
124 @override | 180 @override |
125 bool isDeserialized(Element element) { | 181 bool isDeserialized(Element element) { |
126 return deserializedLibraries.contains(element.library); | 182 return deserializedLibraries.contains(element.library); |
127 } | 183 } |
128 } | 184 } |
185 | |
186 const String RESOLVED_AST_TAG = 'resolvedAst'; | |
187 | |
188 class ResolvedAstSerializerPlugin extends SerializerPlugin { | |
189 final Resolution resolution; | |
190 | |
191 ResolvedAstSerializerPlugin(this.resolution); | |
192 | |
193 @override | |
194 void onElement(Element element, ObjectEncoder createEncoder(String tag)) { | |
195 if (element is MemberElement && resolution.hasResolvedAst(element)) { | |
196 ResolvedAst resolvedAst = resolution.getResolvedAst(element); | |
197 ObjectEncoder objectEncoder = createEncoder(RESOLVED_AST_TAG); | |
198 new ResolvedAstSerializer(objectEncoder, resolvedAst).serialize(); | |
199 } | |
200 } | |
201 } | |
202 | |
203 class ResolvedAstDeserializerPlugin extends DeserializerPlugin { | |
204 final Parsing parsing; | |
205 final Map<Uri, SourceFile> sourceFiles = <Uri, SourceFile>{}; | |
206 | |
207 Map<Element, ResolvedAst> _resolvedAstMap = <Element, ResolvedAst>{}; | |
208 Map<Element, ObjectDecoder> _decoderMap = <Element, ObjectDecoder>{}; | |
209 Map<Uri, Token> beginTokenMap = <Uri, Token>{}; | |
210 | |
211 ResolvedAstDeserializerPlugin(this.parsing); | |
212 | |
213 ResolvedAst getResolvedAst(Element element) { | |
214 ResolvedAst resolvedAst = _resolvedAstMap[element]; | |
215 if (resolvedAst == null) { | |
216 ObjectDecoder decoder = _decoderMap[element]; | |
217 if (decoder != null) { | |
218 resolvedAst = _resolvedAstMap[element] = | |
219 ResolvedAstDeserializer.deserialize( | |
220 element, decoder, parsing, findToken); | |
221 _decoderMap.remove(element); | |
222 } | |
223 } | |
224 return resolvedAst; | |
225 } | |
226 | |
227 Token findToken(Uri uri, int offset) { | |
228 Token beginToken = beginTokenMap.putIfAbsent(uri, () { | |
229 SourceFile sourceFile = sourceFiles[uri]; | |
230 if (sourceFile == null) { | |
231 throw 'No source file found for $uri in:\n ' | |
232 '${sourceFiles.keys.join('\n ')}'; | |
233 } | |
234 return new Scanner(sourceFile).tokenize(); | |
235 }); | |
236 return ResolvedAstDeserializer.findTokenInStream(beginToken, offset); | |
237 } | |
238 | |
239 @override | |
240 void onElement(Element element, ObjectDecoder getDecoder(String tag)) { | |
241 ObjectDecoder decoder = getDecoder(RESOLVED_AST_TAG); | |
242 if (decoder != null) { | |
243 _decoderMap[element] = decoder; | |
244 } | |
245 } | |
246 } | |
247 | |
OLD | NEW |