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

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

Issue 1192103002: Support serialization of the compiler backbone. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library dart2js.serialization.elements;
6
7 import '../constants/expressions.dart';
8 import '../dart_types.dart';
9 import '../dart2jslib.dart' show SourceSpan;
10 import '../elements/elements.dart';
11 import '../tree/tree.dart';
12 import 'constant_serialization.dart';
13 import 'keys.dart';
14 import 'modelz.dart';
15 import 'serialization.dart';
16
17 /// Enum kinds used for encoding [Element]s.
18 enum SerializedElementKind {
19 LIBRARY,
20 COMPILATION_UNIT,
21 CLASS,
22 GENERATIVE_CONSTRUCTOR,
23 FACTORY_CONSTRUCTOR,
24 TOPLEVEL_FIELD,
25 STATIC_FIELD,
26 INSTANCE_FIELD,
27 TOPLEVEL_FUNCTION,
28 TOPLEVEL_GETTER,
29 TOPLEVEL_SETTER,
30 STATIC_FUNCTION,
31 STATIC_GETTER,
32 STATIC_SETTER,
33 INSTANCE_FUNCTION,
34 INSTANCE_GETTER,
35 INSTANCE_SETTER,
36 TYPEDEF,
37 TYPEVARIABLE,
38 PARAMETER,
39 INITIALIZING_FORMAL,
40 }
41
42 /// Set serializers used to serialize the different kinds of elements.
43 const List<ElementSerializer> ELEMENT_SERIALIZERS = const [
44 const LibrarySerializer(),
45 const CompilationUnitSerializer(),
46 const ClassSerializer(),
47 const ConstructorSerializer(),
48 const FieldSerializer(),
49 const FunctionSerializer(),
50 const TypedefSerializer(),
51 const TypeVariableSerializer(),
52 const ParameterSerializer(),
53 ];
54
55 /// Interface for a function that can serialize a set of element kinds.
56 abstract class ElementSerializer {
57 /// Returns the [SerializedElementKind] for [element] if this serializer
58 /// supports serialization of [element] or `null` otherwise.
59 SerializedElementKind getSerializedKind(Element element);
60
61 /// Serializes [element] into the [serializer] using the [kind] computed
62 /// by [getSerializedKind].
63 void serialize(Element element,
64 ObjectSerializer serializer,
65 SerializedElementKind kind);
66 }
67
68 class SerializerUtil {
floitsch 2015/06/26 20:54:04 generally we don't have utility classes (according
Johnni Winther 2015/07/03 12:13:44 I don't like the mixing of public classes and top
69 /// Serialize the declared members of [element] into [serializer].
70 static void serializeMembers(ScopeContainerElement element,
71 ObjectSerializer serializer) {
72 MapSerializer mapSerializer = serializer.createMap(Key.MEMBERS);
73 element.forEachLocalMember((Element member) {
74 String name = member.name;
75 if (member.isSetter) {
76 name = '$name,=';
77 }
78 mapSerializer.setElement(name, member);
79 });
80 }
81
82 /// Serialize the source position of [element] into [serializer].
83 static void serializePosition(Element element, ObjectSerializer serializer) {
84 if (element.sourcePosition != null) {
85 SourceSpan position = element.sourcePosition;
86 serializer.setInt(Key.OFFSET, position.begin);
87 if (position.uri != element.compilationUnit.script.resourceUri) {
88 // TODO(johnniwinther): What is the base URI in the case?
89 serializer.setUri(Key.URI, element.library.canonicalUri, position.uri);
90 }
91 int length = position.end - position.begin;
92 if (element.name.length != length) {
93 serializer.setInt(Key.LENGTH, length);
94 }
95 }
96 }
97
98 /// Serialize the parameters of [element] into [serializer].
99 static void serializerParameters(FunctionElement element,
floitsch 2015/06/26 20:54:04 serializeParameters
Johnni Winther 2015/07/03 12:13:44 Done.
100 ObjectSerializer serializer) {
101 FunctionType type = element.type;
102 serializer.setType(Key.RETURN_TYPE, type.returnType);
103 serializer.setElements(Key.PARAMETERS, element.parameters);
104 }
105
106 /// Returns a function that addeds the underlying declared elements for a
107 /// particular element into [list].
108 ///
109 /// For instance, for an [AbstractFieldElement] the getter and setter elements
110 /// are added, if available.
111 static flattenElements(List<Element> list) {
112 return (Element element) {
113 // TODO(johnniwinther): Handle ambiguous elements.
114 if (element.isAmbiguous) return;
115 if (element.isAbstractField) {
116 AbstractFieldElement abstractField = element;
117 if (abstractField.getter != null) {
118 list.add(abstractField.getter);
119 }
120 if (abstractField.setter != null) {
121 list.add(abstractField.setter);
122 }
123 } else {
124 list.add(element);
125 }
126 };
127 }
128 }
129
130 class LibrarySerializer implements ElementSerializer {
131 const LibrarySerializer();
132
133 SerializedElementKind getSerializedKind(Element element) {
134 if (element.isLibrary) {
135 return SerializedElementKind.LIBRARY;
136 }
137 return null;
138 }
139
140 void serialize(LibraryElement element,
141 ObjectSerializer serializer,
142 SerializedElementKind kind) {
143 serializer.setUri(
144 Key.CANONICAL_URI, element.canonicalUri, element.canonicalUri);
145 serializer.setString(Key.LIBRARY_NAME, element.getLibraryName());
146 SerializerUtil.serializeMembers(element, serializer);
147 serializer.setElement(Key.COMPILATION_UNIT, element.entryCompilationUnit);
148 serializer.setElements(
149 Key.COMPILATION_UNITS, element.compilationUnits.toList());
150 ListSerializer tags = serializer.createList(Key.TAGS);
151 void addTags(LibraryElement library) {
floitsch 2015/06/26 20:54:04 new line before and after nested functions.
Johnni Winther 2015/07/03 12:13:44 Done.
152 for (LibraryTag tag in library.tags) {
153 if (tag is Import) {
154 ObjectSerializer importTag = tags.createObject();
155 importTag.setString(Key.KIND, 'import');
156 importTag.setElement(Key.LIBRARY, library.getLibraryFromTag(tag));
157 } else if (tag is Export) {
158 ObjectSerializer exportTag = tags.createObject();
159 exportTag.setString(Key.KIND, 'export');
160 exportTag.setElement(Key.LIBRARY, library.getLibraryFromTag(tag));
161 }
162 }
163 }
164 addTags(element);
165
166 List<Element> imports = <Element>[];
167 element.forEachImport(SerializerUtil.flattenElements(imports));
168 serializer.setElements(Key.IMPORTS, imports);
169
170 List<Element> exports = <Element>[];
171 element.forEachExport(SerializerUtil.flattenElements(exports));
172 serializer.setElements(Key.EXPORTS, exports);
173 }
174 }
175
176 class CompilationUnitSerializer implements ElementSerializer {
177 const CompilationUnitSerializer();
178
179 SerializedElementKind getSerializedKind(Element element) {
180 if (element.isCompilationUnit) {
181 return SerializedElementKind.COMPILATION_UNIT;
182 }
183 return null;
184 }
185
186 void serialize(CompilationUnitElement element,
187 ObjectSerializer serializer,
188 SerializedElementKind kind) {
189 serializer.setElement(Key.LIBRARY, element.library);
190 serializer.setUri(
191 Key.URI, element.library.canonicalUri, element.script.resourceUri);
192 List<Element> elements = <Element>[];
193 element.forEachLocalMember((e) => elements.add(e));
194 serializer.setElements(Key.ELEMENTS, elements);
195 }
196 }
197
198 class ClassSerializer implements ElementSerializer {
199 const ClassSerializer();
200
201 SerializedElementKind getSerializedKind(Element element) {
202 if (element.isClass) {
203 return SerializedElementKind.CLASS;
204 }
205 return null;
206 }
207
208 void serialize(ClassElement element,
209 ObjectSerializer serializer,
210 SerializedElementKind kind) {
211 serializer.setElement(Key.LIBRARY, element.library);
212 serializer.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
213 serializer.setString(Key.NAME, element.name);
214 SerializerUtil.serializePosition(element, serializer);
215 serializer.setTypes(Key.TYPE_VARIABLES, element.typeVariables);
216 serializer.setBool(Key.IS_ABSTRACT, element.isAbstract);
217 if (element.supertype != null) {
218 serializer.setType(Key.SUPERTYPE, element.supertype);
219 }
220 // TODO(johnniwinther): Make [OrderedTypeSet] easier to (de)serialize.
221 ObjectSerializer supertypes = serializer.createObject(Key.SUPERTYPES);
222 supertypes.setTypes(Key.TYPES,
223 element.allSupertypesAndSelf.types.toList());
224 supertypes.setTypes(Key.SUPERTYPES,
225 element.allSupertypesAndSelf.supertypes.toList());
226 supertypes.setInts(Key.OFFSETS, element.allSupertypesAndSelf.levelOffsets);
227 serializer.setTypes(Key.INTERFACES, element.interfaces.toList());
228 SerializerUtil.serializeMembers(element, serializer);
229 }
230 }
231
232 class ConstructorSerializer implements ElementSerializer {
233 const ConstructorSerializer();
234
235 SerializedElementKind getSerializedKind(Element element) {
236 if (element.isGenerativeConstructor) {
237 return SerializedElementKind.GENERATIVE_CONSTRUCTOR;
238 } else if (element.isFactoryConstructor) {
239 return SerializedElementKind.FACTORY_CONSTRUCTOR;
240 }
241 return null;
242 }
243
244 void serialize(ConstructorElement element,
245 ObjectSerializer serializer,
246 SerializedElementKind kind) {
247 serializer.setElement(Key.CLASS, element.enclosingClass);
248 serializer.setType(Key.TYPE, element.type);
249 serializer.setString(Key.NAME, element.name);
250 SerializerUtil.serializePosition(element, serializer);
251 SerializerUtil.serializerParameters(element, serializer);
252 serializer.setBool(Key.IS_CONST, element.isConst);
253 if (element.isConst && !element.isFromEnvironmentConstructor) {
254 ConstantConstructor constantConstructor = element.constantConstructor;
255 ObjectSerializer constantSerializer =
256 serializer.createObject(Key.CONSTRUCTOR);
257 const ConstantConstructorSerializer().visit(
258 constantConstructor, constantSerializer);
259 constantSerializer.setEnum(Key.KIND, constantConstructor.kind);
260 switch (constantConstructor.kind) {
261 case ConstantConstructorKind.GENERATIVE:
262 GenerativeConstantConstructor generativeConstantConstructor =
263 constantConstructor;
264 constantSerializer.setType(
265 Key.TYPE, generativeConstantConstructor.type);
266 MapSerializer defaults = constantSerializer.createMap(Key.DEFAULTS);
267 generativeConstantConstructor.defaultValues.forEach((key, e) {
268 defaults.setConstant('$key', e);
269 });
270 ListSerializer fields = constantSerializer.createList(Key.FIELDS);
271 generativeConstantConstructor.fieldMap.forEach(
272 (FieldElement f, ConstantExpression e) {
273 ObjectSerializer fieldSerializer = fields.createObject();
274 fieldSerializer.setElement(Key.FIELD, f);
275 fieldSerializer.setConstant(Key.CONSTANT, e);
276 });
277 if (generativeConstantConstructor
278 .superConstructorInvocation != null) {
279 constantSerializer.setConstant(Key.CONSTRUCTOR,
280 generativeConstantConstructor.superConstructorInvocation);
281 }
282 break;
283 case ConstantConstructorKind.REDIRECTING_GENERATIVE:
284 RedirectingGenerativeConstantConstructor
285 redirectingGenerativeConstantConstructor =
286 constantConstructor;
287 MapSerializer defaults = constantSerializer.createMap(Key.DEFAULTS);
288 redirectingGenerativeConstantConstructor.defaultValues.forEach(
289 (key, ConstantExpression e) {
290 defaults.setConstant('$key', e);
291 });
292 constantSerializer.setConstant(Key.CONSTRUCTOR,
293 redirectingGenerativeConstantConstructor
294 .thisConstructorInvocation);
295 break;
296 case ConstantConstructorKind.REDIRECTING_FACTORY:
297 RedirectingFactoryConstantConstructor
298 redirectingFactoryConstantConstructor = constantConstructor;
299 constantSerializer.setConstant(Key.CONSTRUCTOR,
300 redirectingFactoryConstantConstructor
301 .targetConstructorInvocation);
302 break;
303 }
304 }
305 }
306 }
307
308 class FieldSerializer implements ElementSerializer {
309 const FieldSerializer();
310
311 SerializedElementKind getSerializedKind(Element element) {
312 if (element.isField) {
313 if (element.isTopLevel) return SerializedElementKind.TOPLEVEL_FIELD;
314 if (element.isStatic) return SerializedElementKind.STATIC_FIELD;
315 if (element.isInstanceMember) return SerializedElementKind.INSTANCE_FIELD;
316 }
317 return null;
318 }
319
320 void serialize(FieldElement element,
321 ObjectSerializer serializer,
322 SerializedElementKind kind) {
323 serializer.setString(Key.NAME, element.name);
324 SerializerUtil.serializePosition(element, serializer);
325 serializer.setType(Key.TYPE, element.type);
326 serializer.setBool(Key.IS_FINAL, element.isFinal);
327 serializer.setBool(Key.IS_CONST, element.isConst);
328 if (element.isConst) {
329 ConstantExpression constant = element.constant;
330 serializer.setConstant(Key.CONSTANT, constant);
331 }
332 if (kind != SerializedElementKind.TOPLEVEL_FIELD) {
333 serializer.setElement(Key.CLASS, element.enclosingClass);
334 } else {
335 serializer.setElement(Key.LIBRARY, element.library);
336 serializer.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
337 }
338 }
339 }
340
341 class FunctionSerializer implements ElementSerializer {
342 const FunctionSerializer();
343
344 SerializedElementKind getSerializedKind(Element element) {
345 if (element.isFunction) {
346 if (element.isTopLevel) return SerializedElementKind.TOPLEVEL_FUNCTION;
347 if (element.isStatic) return SerializedElementKind.STATIC_FUNCTION;
348 if (element.isInstanceMember) return SerializedElementKind.INSTANCE_FUNCTI ON;
floitsch 2015/06/26 20:54:04 long lines.
Johnni Winther 2015/07/03 12:13:44 Done.
349 }
350 if (element.isGetter) {
351 if (element.isTopLevel) return SerializedElementKind.TOPLEVEL_GETTER;
352 if (element.isStatic) return SerializedElementKind.STATIC_GETTER;
353 if (element.isInstanceMember) return SerializedElementKind.INSTANCE_GETTER ;
354 }
355 if (element.isSetter) {
356 if (element.isTopLevel) return SerializedElementKind.TOPLEVEL_SETTER;
357 if (element.isStatic) return SerializedElementKind.STATIC_SETTER;
358 if (element.isInstanceMember) return SerializedElementKind.INSTANCE_SETTER ;
359 }
360 return null;
361 }
362
363 void serialize(FunctionElement element,
364 ObjectSerializer serializer,
365 SerializedElementKind kind) {
366 serializer.setString(Key.NAME, element.name);
367 SerializerUtil.serializePosition(element, serializer);
368 serializer.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
369 SerializerUtil.serializerParameters(element, serializer);
370 serializer.setType(Key.TYPE, element.type);
371 if (element.isFunction) {
372 serializer.setBool(Key.IS_OPERATOR, element.isOperator);
373 }
374 if (element.enclosingClass != null) {
375 serializer.setElement(Key.CLASS, element.enclosingClass);
376 } else {
377 serializer.setElement(Key.LIBRARY, element.library);
378 serializer.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
379 }
380 }
381 }
382
383 class TypedefSerializer implements ElementSerializer {
384 const TypedefSerializer();
385
386 SerializedElementKind getSerializedKind(Element element) {
387 if (element.isTypedef) {
388 return SerializedElementKind.TYPEDEF;
389 }
390 return null;
391 }
392
393 void serialize(TypedefElement element,
394 ObjectSerializer serializer,
395 SerializedElementKind kind) {
396 serializer.setString(Key.NAME, element.name);
397 SerializerUtil.serializePosition(element, serializer);
398 serializer.setType(Key.ALIAS, element.alias);
399 serializer.setElement(Key.LIBRARY, element.library);
400 serializer.setTypes(Key.TYPE_VARIABLES, element.typeVariables);
401 serializer.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
402 }
403 }
404
405 class TypeVariableSerializer implements ElementSerializer {
406 const TypeVariableSerializer();
407
408 SerializedElementKind getSerializedKind(Element element) {
409 if (element.isTypeVariable) {
410 return SerializedElementKind.TYPEVARIABLE;
411 }
412 return null;
413 }
414
415 void serialize(TypeVariableElement element,
416 ObjectSerializer serializer,
417 SerializedElementKind kind) {
418 serializer.setElement(Key.TYPE_DECLARATION, element.typeDeclaration);
419 serializer.setString(Key.NAME, element.name);
420 SerializerUtil.serializePosition(element, serializer);
421 TypeDeclarationElement typeDeclaration = element.typeDeclaration;
422 serializer.setType(Key.TYPE, element.type);
423 serializer.setInt(Key.INDEX, element.index);
424 serializer.setType(Key.BOUND, element.bound);
425 }
426 }
427
428 class ParameterSerializer implements ElementSerializer {
429 const ParameterSerializer();
430
431 SerializedElementKind getSerializedKind(Element element) {
432 if (element.isParameter) {
433 return SerializedElementKind.PARAMETER;
434 } else if (element.isInitializingFormal) {
435 return SerializedElementKind.INITIALIZING_FORMAL;
436 }
437 return null;
438 }
439
440 void serialize(ParameterElement element,
441 ObjectSerializer serializer,
442 SerializedElementKind kind) {
443 serializer.setElement(Key.FUNCTION, element.functionDeclaration);
444 serializer.setString(Key.NAME, element.name);
445 SerializerUtil.serializePosition(element, serializer);
446 serializer.setType(Key.TYPE, element.type);
447 serializer.setBool(Key.IS_OPTIONAL, element.isOptional);
448 serializer.setBool(Key.IS_NAMED, element.isNamed);
449 if (element.isOptional) {
450 serializer.setConstant(Key.CONSTANT, element.constant);
451 }
452 if (element.isInitializingFormal) {
453 InitializingFormalElement initializingFormal = element;
454 serializer.setElement(Key.FIELD, initializingFormal.fieldElement);
455 }
456 }
457 }
458
459 class ElementDeserializer {
460 static Element deserialize(ObjectDeserializer deserializer) {
461 SerializedElementKind elementKind =
462 deserializer.getEnum(Key.KIND, SerializedElementKind.values);
463 switch (elementKind) {
464 case SerializedElementKind.LIBRARY:
465 return new LibraryElementZ(deserializer);
466 case SerializedElementKind.COMPILATION_UNIT:
467 return new CompilationUnitElementZ(deserializer);
468 case SerializedElementKind.CLASS:
469 return new ClassElementZ(deserializer);
470 case SerializedElementKind.TOPLEVEL_FIELD:
471 return new TopLevelFieldElementZ(deserializer);
472 case SerializedElementKind.STATIC_FIELD:
473 return new StaticFieldElementZ(deserializer);
474 case SerializedElementKind.INSTANCE_FIELD:
475 return new InstanceFieldElementZ(deserializer);
476 case SerializedElementKind.GENERATIVE_CONSTRUCTOR:
477 return new GenerativeConstructorElementZ(deserializer);
478 case SerializedElementKind.FACTORY_CONSTRUCTOR:
479 return new FactoryConstructorElementZ(deserializer);
480 case SerializedElementKind.TOPLEVEL_FUNCTION:
481 return new TopLevelFunctionElementZ(deserializer);
482 case SerializedElementKind.STATIC_FUNCTION:
483 return new StaticFunctionElementZ(deserializer);
484 case SerializedElementKind.INSTANCE_FUNCTION:
485 return new InstanceFunctionElementZ(deserializer);
486 case SerializedElementKind.TOPLEVEL_GETTER:
487 return new TopLevelGetterElementZ(deserializer);
488 case SerializedElementKind.STATIC_GETTER:
489 return new StaticGetterElementZ(deserializer);
490 case SerializedElementKind.INSTANCE_GETTER:
491 return new InstanceGetterElementZ(deserializer);
492 case SerializedElementKind.TOPLEVEL_SETTER:
493 return new TopLevelSetterElementZ(deserializer);
494 case SerializedElementKind.STATIC_SETTER:
495 return new StaticSetterElementZ(deserializer);
496 case SerializedElementKind.INSTANCE_SETTER:
497 return new InstanceSetterElementZ(deserializer);
498 case SerializedElementKind.TYPEDEF:
499 return new TypedefElementZ(deserializer);
500 case SerializedElementKind.TYPEVARIABLE:
501 return new TypeVariableElementZ(deserializer);
502 case SerializedElementKind.PARAMETER:
503 return new ParameterElementZ(deserializer);
504 case SerializedElementKind.INITIALIZING_FORMAL:
505 return new InitializingFormalElementZ(deserializer);
506 }
507 throw new UnsupportedError("Unexpected element kind '${elementKind}.");
508 }
509 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698