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

Side by Side Diff: pkg/compiler/lib/src/serialization/system.dart

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

Powered by Google App Engine
This is Rietveld 408576698