Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(103)

Side by Side Diff: tests/compiler/dart2js/serialization/helper.dart

Issue 1975153002: Support (de)serialization from command-line (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comments. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 'dart:io'; 8 import 'dart:io';
9 9
10 import 'package:compiler/src/commandline_options.dart'; 10 import 'package:compiler/src/commandline_options.dart';
11 import 'package:compiler/src/common.dart';
12 import 'package:compiler/src/common/backend_api.dart';
13 import 'package:compiler/src/common/names.dart'; 11 import 'package:compiler/src/common/names.dart';
14 import 'package:compiler/src/common/resolution.dart';
15 import 'package:compiler/src/compiler.dart'; 12 import 'package:compiler/src/compiler.dart';
16 import 'package:compiler/src/elements/elements.dart';
17 import 'package:compiler/src/io/source_file.dart';
18 import 'package:compiler/src/scanner/scanner.dart';
19 import 'package:compiler/src/script.dart';
20 import 'package:compiler/src/serialization/impact_serialization.dart';
21 import 'package:compiler/src/serialization/json_serializer.dart';
22 import 'package:compiler/src/serialization/modelz.dart';
23 import 'package:compiler/src/serialization/resolved_ast_serialization.dart';
24 import 'package:compiler/src/serialization/serialization.dart';
25 import 'package:compiler/src/serialization/task.dart';
26 import 'package:compiler/src/tokens/token.dart';
27 import 'package:compiler/src/universe/call_structure.dart';
28 import 'package:compiler/src/universe/world_impact.dart';
29 import 'package:compiler/src/universe/use.dart';
30 13
31 import '../memory_compiler.dart'; 14 import '../memory_compiler.dart';
32 15
33 class Arguments { 16 class Arguments {
34 final String filename; 17 final String filename;
35 final int index; 18 final int index;
36 final bool loadSerializedData; 19 final bool loadSerializedData;
37 final bool saveSerializedData; 20 final bool saveSerializedData;
38 final String serializedDataFileName; 21 final String serializedDataFileName;
39 final bool verbose; 22 final bool verbose;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 if (file.existsSync()) { 64 if (file.existsSync()) {
82 print('Loading data from $file'); 65 print('Loading data from $file');
83 serializedData = file.readAsStringSync(); 66 serializedData = file.readAsStringSync();
84 } 67 }
85 } 68 }
86 if (serializedData == null) { 69 if (serializedData == null) {
87 Compiler compiler = compilerFor( 70 Compiler compiler = compilerFor(
88 options: [Flags.analyzeAll]); 71 options: [Flags.analyzeAll]);
89 compiler.serialization.supportSerialization = true; 72 compiler.serialization.supportSerialization = true;
90 await compiler.run(Uris.dart_core); 73 await compiler.run(Uris.dart_core);
91 serializedData = serialize( 74 BufferedEventSink sink = new BufferedEventSink();
92 compiler, 75 compiler.serialization.serializeToSink(
93 compiler.libraryLoader.libraries) 76 sink, compiler.libraryLoader.libraries);
94 .toText(const JsonSerializationEncoder()); 77 serializedData = sink.text;
95 if (arguments.saveSerializedData) { 78 if (arguments.saveSerializedData) {
96 File file = new File(arguments.serializedDataFileName); 79 File file = new File(arguments.serializedDataFileName);
97 print('Saving data to $file'); 80 print('Saving data to $file');
98 file.writeAsStringSync(serializedData); 81 file.writeAsStringSync(serializedData);
99 } 82 }
100 } 83 }
101 return serializedData; 84 return serializedData;
102 } 85 }
103
104 Serializer serialize(
105 Compiler compiler,
106 Iterable<LibraryElement> libraries) {
107 assert(compiler.serialization.supportSerialization);
108
109 Serializer serializer = new Serializer();
110 SerializerPlugin backendSerializer =
111 compiler.backend.serialization.serializer;
112 serializer.plugins.add(backendSerializer);
113 serializer.plugins.add(new ResolutionImpactSerializer(
114 compiler.resolution, backendSerializer));
115 serializer.plugins.add(new ResolvedAstSerializerPlugin(
116 compiler.resolution, backendSerializer));
117
118 for (LibraryElement library in libraries) {
119 serializer.serialize(library);
120 }
121 return serializer;
122 }
123
124 void deserialize(Compiler compiler,
125 String serializedData) {
126 Deserializer deserializer = new Deserializer.fromText(
127 new DeserializationContext(),
128 serializedData,
129 const JsonSerializationDecoder());
130 deserializer.plugins.add(compiler.backend.serialization.deserializer);
131 compiler.serialization.deserializer =
132 new _DeserializerSystem(
133 compiler,
134 deserializer,
135 compiler.backend.impactTransformer);
136 }
137
138
139 const String WORLD_IMPACT_TAG = 'worldImpact';
140
141 class ResolutionImpactSerializer extends SerializerPlugin {
142 final Resolution resolution;
143 final SerializerPlugin nativeDataSerializer;
144
145 ResolutionImpactSerializer(this.resolution, this.nativeDataSerializer);
146
147 @override
148 void onElement(Element element, ObjectEncoder createEncoder(String tag)) {
149 if (resolution.hasBeenResolved(element)) {
150 ResolutionImpact impact = resolution.getResolutionImpact(element);
151 ObjectEncoder encoder = createEncoder(WORLD_IMPACT_TAG);
152 new ImpactSerializer(element, encoder, nativeDataSerializer)
153 .serialize(impact);
154 }
155 }
156 }
157
158 class ResolutionImpactDeserializer extends DeserializerPlugin {
159 Map<Element, ResolutionImpact> impactMap = <Element, ResolutionImpact>{};
160 final DeserializerPlugin nativeDataDeserializer;
161
162 ResolutionImpactDeserializer(this.nativeDataDeserializer);
163
164 @override
165 void onElement(Element element, ObjectDecoder getDecoder(String tag)) {
166 ObjectDecoder decoder = getDecoder(WORLD_IMPACT_TAG);
167 if (decoder != null) {
168 impactMap[element] =
169 ImpactDeserializer.deserializeImpact(
170 element, decoder, nativeDataDeserializer);
171 }
172 }
173 }
174
175 class _DeserializerSystem extends DeserializerSystem {
176 final Compiler _compiler;
177 final Deserializer _deserializer;
178 final List<LibraryElement> deserializedLibraries = <LibraryElement>[];
179 final ResolutionImpactDeserializer _resolutionImpactDeserializer;
180 final ResolvedAstDeserializerPlugin _resolvedAstDeserializer;
181 final ImpactTransformer _impactTransformer;
182
183 factory _DeserializerSystem(
184 Compiler compiler,
185 Deserializer deserializer,
186 ImpactTransformer impactTransformer) {
187 List<DeserializerPlugin> plugins = <DeserializerPlugin>[];
188 DeserializerPlugin backendDeserializer =
189 compiler.backend.serialization.deserializer;
190 deserializer.plugins.add(backendDeserializer);
191 ResolutionImpactDeserializer resolutionImpactDeserializer =
192 new ResolutionImpactDeserializer(backendDeserializer);
193 deserializer.plugins.add(resolutionImpactDeserializer);
194 ResolvedAstDeserializerPlugin resolvedAstDeserializer
195 = new ResolvedAstDeserializerPlugin(
196 compiler.parsingContext, backendDeserializer);
197 deserializer.plugins.add(resolvedAstDeserializer);
198 return new _DeserializerSystem._(
199 compiler,
200 deserializer,
201 impactTransformer,
202 resolutionImpactDeserializer,
203 resolvedAstDeserializer);
204 }
205
206 _DeserializerSystem._(
207 this._compiler,
208 this._deserializer,
209 this._impactTransformer,
210 this._resolutionImpactDeserializer,
211 this._resolvedAstDeserializer);
212
213
214 @override
215 Future<LibraryElement> readLibrary(Uri resolvedUri) {
216 LibraryElement library = _deserializer.lookupLibrary(resolvedUri);
217 if (library != null) {
218 deserializedLibraries.add(library);
219 return Future.forEach(library.compilationUnits,
220 (CompilationUnitElement compilationUnit) {
221 ScriptZ script = compilationUnit.script;
222 return _compiler.readScript(script.readableUri)
223 .then((Script newScript) {
224 script.file = newScript.file;
225 _resolvedAstDeserializer.sourceFiles[script.resourceUri] =
226 newScript.file;
227 });
228 }).then((_) => library);
229 }
230 return new Future<LibraryElement>.value(library);
231 }
232
233 // TODO(johnniwinther): Remove the need for this method.
234 @override
235 bool hasResolvedAst(ExecutableElement element) {
236 return getResolvedAst(element) != null;
237 }
238
239 @override
240 ResolvedAst getResolvedAst(ExecutableElement element) {
241 return _resolvedAstDeserializer.getResolvedAst(element);
242 }
243
244 @override
245 bool hasResolutionImpact(Element element) {
246 if (element.isConstructor &&
247 element.enclosingClass.isUnnamedMixinApplication) {
248 return true;
249 }
250 return _resolutionImpactDeserializer.impactMap.containsKey(element);
251 }
252
253 @override
254 ResolutionImpact getResolutionImpact(Element element) {
255 if (element.isConstructor &&
256 element.enclosingClass.isUnnamedMixinApplication) {
257 ClassElement superclass = element.enclosingClass.superclass;
258 ConstructorElement superclassConstructor =
259 superclass.lookupConstructor(element.name);
260 assert(invariant(element, superclassConstructor != null,
261 message: "Superclass constructor '${element.name}' called from "
262 "${element} not found in ${superclass}."));
263 // TODO(johnniwinther): Compute callStructure. Currently not used.
264 CallStructure callStructure;
265 return _resolutionImpactDeserializer.impactMap.putIfAbsent(element, () {
266 return new DeserializedResolutionImpact(
267 staticUses: <StaticUse>[new StaticUse.superConstructorInvoke(
268 superclassConstructor, callStructure)]);
269 });
270 }
271 return _resolutionImpactDeserializer.impactMap[element];
272 }
273
274 @override
275 WorldImpact computeWorldImpact(Element element) {
276 ResolutionImpact resolutionImpact = getResolutionImpact(element);
277 assert(invariant(element, resolutionImpact != null,
278 message: 'No impact found for $element (${element.library})'));
279 if (element is ExecutableElement) {
280 getResolvedAst(element);
281 }
282 return _impactTransformer.transformResolutionImpact(resolutionImpact);
283 }
284
285 @override
286 bool isDeserialized(Element element) {
287 return deserializedLibraries.contains(element.library);
288 }
289 }
290
291 const String RESOLVED_AST_TAG = 'resolvedAst';
292
293 class ResolvedAstSerializerPlugin extends SerializerPlugin {
294 final Resolution resolution;
295 final SerializerPlugin nativeDataSerializer;
296
297 ResolvedAstSerializerPlugin(this.resolution, this.nativeDataSerializer);
298
299 @override
300 void onElement(Element element, ObjectEncoder createEncoder(String tag)) {
301 assert(invariant(element, element.isDeclaration,
302 message: "Element $element must be the declaration"));
303 if (element is MemberElement) {
304 assert(invariant(element, resolution.hasResolvedAst(element),
305 message: "Element $element must have a resolved ast"));
306 ResolvedAst resolvedAst = resolution.getResolvedAst(element);
307 ObjectEncoder objectEncoder = createEncoder(RESOLVED_AST_TAG);
308 new ResolvedAstSerializer(
309 objectEncoder,
310 resolvedAst,
311 nativeDataSerializer).serialize();
312 }
313 }
314 }
315
316 class ResolvedAstDeserializerPlugin extends DeserializerPlugin {
317 final ParsingContext parsingContext;
318 final DeserializerPlugin nativeDataDeserializer;
319 final Map<Uri, SourceFile> sourceFiles = <Uri, SourceFile>{};
320
321 Map<MemberElement, ObjectDecoder> _decoderMap =
322 <MemberElement, ObjectDecoder>{};
323 Map<Uri, Token> beginTokenMap = <Uri, Token>{};
324
325 ResolvedAstDeserializerPlugin(
326 this.parsingContext, this.nativeDataDeserializer);
327
328 bool hasResolvedAst(ExecutableElement element) {
329 return getResolvedAst(element) != null;
330 }
331
332 ResolvedAst getResolvedAst(ExecutableElement element) {
333 if (element.hasResolvedAst) {
334 return element.resolvedAst;
335 }
336
337 ObjectDecoder decoder = _decoderMap[element.memberContext];
338 if (decoder != null) {
339 ResolvedAstDeserializer.deserialize(
340 element.memberContext, decoder, parsingContext, findToken,
341 nativeDataDeserializer);
342 _decoderMap.remove(element);
343 assert(invariant(element, element.hasResolvedAst,
344 message: "ResolvedAst not computed for $element."));
345 return element.resolvedAst;
346 }
347 return null;
348 }
349
350 Token findToken(Uri uri, int offset) {
351 Token beginToken = beginTokenMap.putIfAbsent(uri, () {
352 SourceFile sourceFile = sourceFiles[uri];
353 if (sourceFile == null) {
354 throw 'No source file found for $uri in:\n '
355 '${sourceFiles.keys.join('\n ')}';
356 }
357 return new Scanner(sourceFile).tokenize();
358 });
359 return ResolvedAstDeserializer.findTokenInStream(beginToken, offset);
360 }
361
362 @override
363 void onElement(Element element, ObjectDecoder getDecoder(String tag)) {
364 ObjectDecoder decoder = getDecoder(RESOLVED_AST_TAG);
365 if (decoder != null) {
366 _decoderMap[element] = decoder;
367 }
368 }
369 }
370
OLDNEW
« no previous file with comments | « tests/compiler/dart2js/serialization/equivalence_test.dart ('k') | tests/compiler/dart2js/serialization/impact_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698