| 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.elements; | 5 library dart2js.serialization.elements; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../constants/constructors.dart'; | 8 import '../constants/constructors.dart'; |
| 9 import '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
| 10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
| 11 import '../elements/elements.dart'; | 11 import '../elements/elements.dart'; |
| 12 import 'constant_serialization.dart'; | 12 import 'constant_serialization.dart'; |
| 13 import 'keys.dart'; | 13 import 'keys.dart'; |
| 14 import 'modelz.dart'; | 14 import 'modelz.dart'; |
| 15 import 'serialization.dart'; | 15 import 'serialization.dart'; |
| 16 | 16 |
| 17 /// Enum kinds used for encoding [Element]s. | 17 /// Enum kinds used for encoding [Element]s. |
| 18 enum SerializedElementKind { | 18 enum SerializedElementKind { |
| 19 LIBRARY, | 19 LIBRARY, |
| 20 COMPILATION_UNIT, | 20 COMPILATION_UNIT, |
| 21 CLASS, | 21 CLASS, |
| 22 ENUM, | 22 ENUM, |
| 23 NAMED_MIXIN_APPLICATION, |
| 23 GENERATIVE_CONSTRUCTOR, | 24 GENERATIVE_CONSTRUCTOR, |
| 24 FACTORY_CONSTRUCTOR, | 25 FACTORY_CONSTRUCTOR, |
| 25 TOPLEVEL_FIELD, | 26 TOPLEVEL_FIELD, |
| 26 STATIC_FIELD, | 27 STATIC_FIELD, |
| 27 INSTANCE_FIELD, | 28 INSTANCE_FIELD, |
| 28 TOPLEVEL_FUNCTION, | 29 TOPLEVEL_FUNCTION, |
| 29 TOPLEVEL_GETTER, | 30 TOPLEVEL_GETTER, |
| 30 TOPLEVEL_SETTER, | 31 TOPLEVEL_SETTER, |
| 31 STATIC_FUNCTION, | 32 STATIC_FUNCTION, |
| 32 STATIC_GETTER, | 33 STATIC_GETTER, |
| 33 STATIC_SETTER, | 34 STATIC_SETTER, |
| 34 INSTANCE_FUNCTION, | 35 INSTANCE_FUNCTION, |
| 35 INSTANCE_GETTER, | 36 INSTANCE_GETTER, |
| 36 INSTANCE_SETTER, | 37 INSTANCE_SETTER, |
| 37 LOCAL_FUNCTION, | 38 LOCAL_FUNCTION, |
| 38 TYPEDEF, | 39 TYPEDEF, |
| 39 TYPEVARIABLE, | 40 TYPEVARIABLE, |
| 40 PARAMETER, | 41 PARAMETER, |
| 41 INITIALIZING_FORMAL, | 42 INITIALIZING_FORMAL, |
| 42 IMPORT, | 43 IMPORT, |
| 43 EXPORT, | 44 EXPORT, |
| 44 PREFIX, | 45 PREFIX, |
| 46 EXTERNAL_LIBRARY, |
| 47 EXTERNAL_LIBRARY_MEMBER, |
| 48 EXTERNAL_STATIC_MEMBER, |
| 49 EXTERNAL_CONSTRUCTOR, |
| 45 } | 50 } |
| 46 | 51 |
| 47 /// Set of serializers used to serialize different kinds of elements by | 52 /// Set of serializers used to serialize different kinds of elements by |
| 48 /// encoding into them into [ObjectEncoder]s. | 53 /// encoding into them into [ObjectEncoder]s. |
| 49 /// | 54 /// |
| 50 /// This class is called from the [Serializer] when an [Element] needs | 55 /// This class is called from the [Serializer] when an [Element] needs |
| 51 /// serialization. The [ObjectEncoder] ensures that any [Element], [DartType], | 56 /// serialization. The [ObjectEncoder] ensures that any [Element], [DartType], |
| 52 /// and [ConstantExpression] that the serialized [Element] depends upon are also | 57 /// and [ConstantExpression] that the serialized [Element] depends upon are also |
| 53 /// serialized. | 58 /// serialized. |
| 54 const List<ElementSerializer> ELEMENT_SERIALIZERS = const [ | 59 const List<ElementSerializer> ELEMENT_SERIALIZERS = const [ |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 } | 250 } |
| 246 | 251 |
| 247 class ClassSerializer implements ElementSerializer { | 252 class ClassSerializer implements ElementSerializer { |
| 248 const ClassSerializer(); | 253 const ClassSerializer(); |
| 249 | 254 |
| 250 SerializedElementKind getSerializedKind(Element element) { | 255 SerializedElementKind getSerializedKind(Element element) { |
| 251 if (element.isClass) { | 256 if (element.isClass) { |
| 252 ClassElement cls = element; | 257 ClassElement cls = element; |
| 253 if (cls.isEnumClass) { | 258 if (cls.isEnumClass) { |
| 254 return SerializedElementKind.ENUM; | 259 return SerializedElementKind.ENUM; |
| 260 } else if (cls.isMixinApplication) { |
| 261 if (!cls.isUnnamedMixinApplication) { |
| 262 return SerializedElementKind.NAMED_MIXIN_APPLICATION; |
| 263 } |
| 264 } else { |
| 265 return SerializedElementKind.CLASS; |
| 255 } | 266 } |
| 256 return SerializedElementKind.CLASS; | |
| 257 } | 267 } |
| 258 return null; | 268 return null; |
| 259 } | 269 } |
| 260 | 270 |
| 261 static List<Element> getMembers(ClassElement element) { | 271 static List<Element> getMembers(ClassElement element) { |
| 262 List<Element> members = <Element>[]; | 272 List<Element> members = <Element>[]; |
| 263 element.forEachLocalMember(members.add); | 273 element.forEachLocalMember(members.add); |
| 264 if (element.isPatched) { | 274 if (element.isPatched) { |
| 265 element.implementation.forEachLocalMember((Element member) { | 275 element.implementation.forEachLocalMember((Element member) { |
| 266 if (!member.isPatch) { | 276 if (!member.isPatch) { |
| 267 members.add(member); | 277 members.add(member); |
| 268 } | 278 } |
| 269 }); | 279 }); |
| 270 } | 280 } |
| 271 return members; | 281 return members; |
| 272 } | 282 } |
| 273 | 283 |
| 274 void serialize(ClassElement element, | 284 void serialize(ClassElement element, |
| 275 ObjectEncoder encoder, | 285 ObjectEncoder encoder, |
| 276 SerializedElementKind kind) { | 286 SerializedElementKind kind) { |
| 277 encoder.setElement(Key.LIBRARY, element.library); | 287 encoder.setElement(Key.LIBRARY, element.library); |
| 278 encoder.setElement(Key.COMPILATION_UNIT, element.compilationUnit); | 288 encoder.setElement(Key.COMPILATION_UNIT, element.compilationUnit); |
| 279 encoder.setString(Key.NAME, element.name); | 289 encoder.setString(Key.NAME, element.name); |
| 280 SerializerUtil.serializePosition(element, encoder); | 290 SerializerUtil.serializePosition(element, encoder); |
| 281 encoder.setTypes(Key.TYPE_VARIABLES, element.typeVariables); | 291 encoder.setTypes(Key.TYPE_VARIABLES, element.typeVariables); |
| 282 encoder.setBool(Key.IS_ABSTRACT, element.isAbstract); | 292 encoder.setBool(Key.IS_ABSTRACT, element.isAbstract); |
| 283 if (element.isUnnamedMixinApplication) { | |
| 284 encoder.setBool(Key.IS_UNNAMED_MIXIN_APPLICATION, true); | |
| 285 } | |
| 286 if (element.supertype != null) { | |
| 287 encoder.setType(Key.SUPERTYPE, element.supertype); | |
| 288 } | |
| 289 // TODO(johnniwinther): Make [OrderedTypeSet] easier to (de)serialize. | |
| 290 ObjectEncoder supertypes = encoder.createObject(Key.SUPERTYPES); | |
| 291 supertypes.setTypes(Key.TYPES, | |
| 292 element.allSupertypesAndSelf.types.toList()); | |
| 293 supertypes.setTypes(Key.SUPERTYPES, | |
| 294 element.allSupertypesAndSelf.supertypes.toList()); | |
| 295 supertypes.setInts(Key.OFFSETS, element.allSupertypesAndSelf.levelOffsets); | |
| 296 encoder.setTypes(Key.INTERFACES, element.interfaces.toList()); | |
| 297 SerializerUtil.serializeMembers(getMembers(element), encoder); | 293 SerializerUtil.serializeMembers(getMembers(element), encoder); |
| 298 encoder.setBool(Key.IS_PROXY, element.isProxy); | 294 encoder.setBool(Key.IS_PROXY, element.isProxy); |
| 299 if (kind == SerializedElementKind.ENUM) { | 295 if (kind == SerializedElementKind.ENUM) { |
| 300 EnumClassElement enumClass = element; | 296 EnumClassElement enumClass = element; |
| 301 encoder.setElements(Key.FIELDS, enumClass.enumValues); | 297 encoder.setElements(Key.FIELDS, enumClass.enumValues); |
| 302 } | 298 } |
| 299 if (element.isObject) return; |
| 300 |
| 301 List<InterfaceType> mixins = <InterfaceType>[]; |
| 302 ClassElement superclass = element.superclass; |
| 303 while (superclass.isUnnamedMixinApplication) { |
| 304 MixinApplicationElement mixinElement = superclass; |
| 305 mixins.add(element.thisType.asInstanceOf(mixinElement.mixin)); |
| 306 superclass = mixinElement.superclass; |
| 307 } |
| 308 mixins = mixins.reversed.toList(); |
| 309 InterfaceType supertype = element.thisType.asInstanceOf(superclass); |
| 310 |
| 311 |
| 312 encoder.setType(Key.SUPERTYPE, supertype); |
| 313 encoder.setTypes(Key.MIXINS, mixins); |
| 314 encoder.setTypes(Key.INTERFACES, element.interfaces.toList()); |
| 315 |
| 316 if (element.isMixinApplication) { |
| 317 MixinApplicationElement mixinElement = element; |
| 318 encoder.setType(Key.MIXIN, mixinElement.mixinType); |
| 319 } |
| 303 } | 320 } |
| 304 } | 321 } |
| 305 | 322 |
| 306 class ConstructorSerializer implements ElementSerializer { | 323 class ConstructorSerializer implements ElementSerializer { |
| 307 const ConstructorSerializer(); | 324 const ConstructorSerializer(); |
| 308 | 325 |
| 309 SerializedElementKind getSerializedKind(Element element) { | 326 SerializedElementKind getSerializedKind(Element element) { |
| 310 if (element.isGenerativeConstructor) { | 327 if (element.isGenerativeConstructor) { |
| 311 return SerializedElementKind.GENERATIVE_CONSTRUCTOR; | 328 return SerializedElementKind.GENERATIVE_CONSTRUCTOR; |
| 312 } else if (element.isFactoryConstructor) { | 329 } else if (element.isFactoryConstructor) { |
| 313 return SerializedElementKind.FACTORY_CONSTRUCTOR; | 330 return SerializedElementKind.FACTORY_CONSTRUCTOR; |
| 314 } | 331 } |
| 315 return null; | 332 return null; |
| 316 } | 333 } |
| 317 | 334 |
| 318 void serialize(ConstructorElement element, | 335 void serialize(ConstructorElement element, |
| 319 ObjectEncoder encoder, | 336 ObjectEncoder encoder, |
| 320 SerializedElementKind kind) { | 337 SerializedElementKind kind) { |
| 321 encoder.setElement(Key.CLASS, element.enclosingClass); | 338 encoder.setElement(Key.CLASS, element.enclosingClass); |
| 322 encoder.setType(Key.TYPE, element.type); | 339 encoder.setType(Key.TYPE, element.type); |
| 323 encoder.setString(Key.NAME, element.name); | 340 encoder.setString(Key.NAME, element.name); |
| 324 SerializerUtil.serializePosition(element, encoder); | 341 SerializerUtil.serializePosition(element, encoder); |
| 325 SerializerUtil.serializeParameters(element, encoder); | 342 SerializerUtil.serializeParameters(element, encoder); |
| 326 encoder.setBool(Key.IS_CONST, element.isConst); | 343 encoder.setBool(Key.IS_CONST, element.isConst); |
| 327 // TODO(johnniwinther): Handle external constructors. | |
| 328 encoder.setBool(Key.IS_EXTERNAL, element.isExternal); | 344 encoder.setBool(Key.IS_EXTERNAL, element.isExternal); |
| 329 if (element.isExternal) return; | 345 if (element.isExternal) return; |
| 330 if (element.isConst && !element.isFromEnvironmentConstructor) { | 346 if (element.isConst && !element.isFromEnvironmentConstructor) { |
| 331 ConstantConstructor constantConstructor = element.constantConstructor; | 347 ConstantConstructor constantConstructor = element.constantConstructor; |
| 332 ObjectEncoder constantEncoder = | 348 ObjectEncoder constantEncoder = |
| 333 encoder.createObject(Key.CONSTRUCTOR); | 349 encoder.createObject(Key.CONSTRUCTOR); |
| 334 const ConstantConstructorSerializer().visit( | 350 const ConstantConstructorSerializer().visit( |
| 335 constantConstructor, constantEncoder); | 351 constantConstructor, constantEncoder); |
| 336 } | 352 } |
| 337 } | 353 } |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 /// | 590 /// |
| 575 /// This is used by the [Deserializer]. | 591 /// This is used by the [Deserializer]. |
| 576 class ElementDeserializer { | 592 class ElementDeserializer { |
| 577 | 593 |
| 578 /// Deserializes an [Element] from an [ObjectDecoder]. | 594 /// Deserializes an [Element] from an [ObjectDecoder]. |
| 579 /// | 595 /// |
| 580 /// The class is called from the [Deserializer] when an [Element] | 596 /// The class is called from the [Deserializer] when an [Element] |
| 581 /// needs deserialization. The [ObjectDecoder] ensures that any [Element], | 597 /// needs deserialization. The [ObjectDecoder] ensures that any [Element], |
| 582 /// [DartType], and [ConstantExpression] that the deserialized [Element] | 598 /// [DartType], and [ConstantExpression] that the deserialized [Element] |
| 583 /// depends upon are available. | 599 /// depends upon are available. |
| 584 static Element deserialize(ObjectDecoder decoder) { | 600 static Element deserialize( |
| 585 SerializedElementKind elementKind = | 601 ObjectDecoder decoder, |
| 586 decoder.getEnum(Key.KIND, SerializedElementKind.values); | 602 SerializedElementKind elementKind) { |
| 587 switch (elementKind) { | 603 switch (elementKind) { |
| 588 case SerializedElementKind.LIBRARY: | 604 case SerializedElementKind.LIBRARY: |
| 589 return new LibraryElementZ(decoder); | 605 return new LibraryElementZ(decoder); |
| 590 case SerializedElementKind.COMPILATION_UNIT: | 606 case SerializedElementKind.COMPILATION_UNIT: |
| 591 return new CompilationUnitElementZ(decoder); | 607 return new CompilationUnitElementZ(decoder); |
| 592 case SerializedElementKind.CLASS: | 608 case SerializedElementKind.CLASS: |
| 593 return new ClassElementZ(decoder); | 609 return new ClassElementZ(decoder); |
| 594 case SerializedElementKind.ENUM: | 610 case SerializedElementKind.ENUM: |
| 595 return new EnumClassElementZ(decoder); | 611 return new EnumClassElementZ(decoder); |
| 612 case SerializedElementKind.NAMED_MIXIN_APPLICATION: |
| 613 return new NamedMixinApplicationElementZ(decoder); |
| 596 case SerializedElementKind.TOPLEVEL_FIELD: | 614 case SerializedElementKind.TOPLEVEL_FIELD: |
| 597 return new TopLevelFieldElementZ(decoder); | 615 return new TopLevelFieldElementZ(decoder); |
| 598 case SerializedElementKind.STATIC_FIELD: | 616 case SerializedElementKind.STATIC_FIELD: |
| 599 return new StaticFieldElementZ(decoder); | 617 return new StaticFieldElementZ(decoder); |
| 600 case SerializedElementKind.INSTANCE_FIELD: | 618 case SerializedElementKind.INSTANCE_FIELD: |
| 601 return new InstanceFieldElementZ(decoder); | 619 return new InstanceFieldElementZ(decoder); |
| 602 case SerializedElementKind.GENERATIVE_CONSTRUCTOR: | 620 case SerializedElementKind.GENERATIVE_CONSTRUCTOR: |
| 603 return new GenerativeConstructorElementZ(decoder); | 621 return new GenerativeConstructorElementZ(decoder); |
| 604 case SerializedElementKind.FACTORY_CONSTRUCTOR: | 622 case SerializedElementKind.FACTORY_CONSTRUCTOR: |
| 605 return new FactoryConstructorElementZ(decoder); | 623 return new FactoryConstructorElementZ(decoder); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 630 case SerializedElementKind.PARAMETER: | 648 case SerializedElementKind.PARAMETER: |
| 631 return new ParameterElementZ(decoder); | 649 return new ParameterElementZ(decoder); |
| 632 case SerializedElementKind.INITIALIZING_FORMAL: | 650 case SerializedElementKind.INITIALIZING_FORMAL: |
| 633 return new InitializingFormalElementZ(decoder); | 651 return new InitializingFormalElementZ(decoder); |
| 634 case SerializedElementKind.IMPORT: | 652 case SerializedElementKind.IMPORT: |
| 635 return new ImportElementZ(decoder); | 653 return new ImportElementZ(decoder); |
| 636 case SerializedElementKind.EXPORT: | 654 case SerializedElementKind.EXPORT: |
| 637 return new ExportElementZ(decoder); | 655 return new ExportElementZ(decoder); |
| 638 case SerializedElementKind.PREFIX: | 656 case SerializedElementKind.PREFIX: |
| 639 return new PrefixElementZ(decoder); | 657 return new PrefixElementZ(decoder); |
| 658 case SerializedElementKind.EXTERNAL_LIBRARY: |
| 659 case SerializedElementKind.EXTERNAL_LIBRARY_MEMBER: |
| 660 case SerializedElementKind.EXTERNAL_STATIC_MEMBER: |
| 661 case SerializedElementKind.EXTERNAL_CONSTRUCTOR: |
| 662 break; |
| 640 } | 663 } |
| 641 throw new UnsupportedError("Unexpected element kind '${elementKind}."); | 664 throw new UnsupportedError("Unexpected element kind '${elementKind}."); |
| 642 } | 665 } |
| 643 } | 666 } |
| OLD | NEW |