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

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

Issue 1811173003: Support per-library serialization. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 9 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) 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; 5 library dart2js.serialization;
6 6
7 import '../elements/elements.dart'; 7 import '../elements/elements.dart';
8 import '../constants/expressions.dart'; 8 import '../constants/expressions.dart';
9 import '../dart_types.dart'; 9 import '../dart_types.dart';
10 10
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 81
82 /// The name of the encoder kind. Use for error reporting. 82 /// The name of the encoder kind. Use for error reporting.
83 String get _name; 83 String get _name;
84 84
85 void _checkKey(K key) { 85 void _checkKey(K key) {
86 if (_map.containsKey(key)) { 86 if (_map.containsKey(key)) {
87 throw new StateError("$_name value '$key' already in $_map."); 87 throw new StateError("$_name value '$key' already in $_map.");
88 } 88 }
89 } 89 }
90 90
91 /// Maps the [key] entry to the [value] in the encoded object.
92 void setValue(K key, Value value) {
93 _checkKey(key);
94 _map[key] = value;
95 }
96
97
91 /// Maps the [key] entry to the enum [value] in the encoded object. 98 /// Maps the [key] entry to the enum [value] in the encoded object.
92 void setEnum(K key, var value) { 99 void setEnum(K key, var value) {
93 _checkKey(key); 100 _checkKey(key);
94 _map[key] = new EnumValue(value); 101 _map[key] = new EnumValue(value);
95 } 102 }
96 103
97 /// Maps the [key] entry to the [element] in the encoded object. 104 /// Maps the [key] entry to the [element] in the encoded object.
98 void setElement(K key, Element element) { 105 void setElement(K key, Element element) {
99 _checkKey(key); 106 _checkKey(key);
100 _map[key] = _serializer.createElementValue(element); 107 _map[key] = _serializer.createElementValue(element);
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 final ObjectValue objectValue; 578 final ObjectValue objectValue;
572 579
573 DataObject(Value id, EnumValue kind) 580 DataObject(Value id, EnumValue kind)
574 : this.id = id, 581 : this.id = id,
575 this.objectValue = 582 this.objectValue =
576 new ObjectValue(<Key, Value>{Key.ID: id, Key.KIND: kind}); 583 new ObjectValue(<Key, Value>{Key.ID: id, Key.KIND: kind});
577 584
578 Map<Key, Value> get map => objectValue.map; 585 Map<Key, Value> get map => objectValue.map;
579 } 586 }
580 587
588 /// Function used to filter which element serialized.
589 typedef bool IncludeElementFunction(Element element);
Siggi Cherem (dart-lang) 2016/03/18 20:00:20 IncludeElementFunction => ElementMatcher
Johnni Winther 2016/03/29 09:05:54 Done.
590
591 bool includeAllElements(Element element) => true;
592
581 /// Serializer for the transitive closure of a collection of libraries. 593 /// Serializer for the transitive closure of a collection of libraries.
582 /// 594 ///
583 /// The serializer creates an [ObjectValue] model of the [Element], [DartType] 595 /// The serializer creates an [ObjectValue] model of the [Element], [DartType]
584 /// and [ConstantExpression] values in the transitive closure of the serialized 596 /// and [ConstantExpression] values in the transitive closure of the serialized
585 /// libraries. 597 /// libraries.
586 /// 598 ///
587 /// The model layout of the produced [objectValue] is: 599 /// The model layout of the produced [objectValue] is:
588 /// 600 ///
589 /// { // Header object 601 /// { // Header object
590 /// Key.ELEMENTS: [ 602 /// Key.ELEMENTS: [
591 /// {...}, // [ObjectValue] of the 0th [Element]. 603 /// {...}, // [ObjectValue] of the 0th [Element].
592 /// ... 604 /// ...
593 /// {...}, // [ObjectValue] of the n-th [Element]. 605 /// {...}, // [ObjectValue] of the n-th [Element].
594 /// ], 606 /// ],
595 /// Key.TYPES: [ 607 /// Key.TYPES: [
596 /// {...}, // [ObjectValue] of the 0th [DartType]. 608 /// {...}, // [ObjectValue] of the 0th [DartType].
597 /// ... 609 /// ...
598 /// {...}, // [ObjectValue] of the n-th [DartType]. 610 /// {...}, // [ObjectValue] of the n-th [DartType].
599 /// ], 611 /// ],
600 /// Key.CONSTANTS: [ 612 /// Key.CONSTANTS: [
601 /// {...}, // [ObjectValue] of the 0th [ConstantExpression]. 613 /// {...}, // [ObjectValue] of the 0th [ConstantExpression].
602 /// ... 614 /// ...
603 /// {...}, // [ObjectValue] of the n-th [ConstantExpression]. 615 /// {...}, // [ObjectValue] of the n-th [ConstantExpression].
604 /// ], 616 /// ],
605 /// } 617 /// }
606 /// 618 ///
607 // TODO(johnniwinther): Support per-library serialization and dependencies 619 // TODO(johnniwinther): Support dependencies between serialized subcomponent.
608 // between serialized subcomponent.
609 class Serializer { 620 class Serializer {
610 final SerializationEncoder _encoder;
611 List<SerializerPlugin> plugins = <SerializerPlugin>[]; 621 List<SerializerPlugin> plugins = <SerializerPlugin>[];
612 622
623 Map<Uri, dynamic> _dependencyMap = <Uri, dynamic>{};
613 Map<Element, DataObject> _elementMap = <Element, DataObject>{}; 624 Map<Element, DataObject> _elementMap = <Element, DataObject>{};
614 Map<ConstantExpression, DataObject> _constantMap = 625 Map<ConstantExpression, DataObject> _constantMap =
615 <ConstantExpression, DataObject>{}; 626 <ConstantExpression, DataObject>{};
616 Map<DartType, DataObject> _typeMap = <DartType, DataObject>{}; 627 Map<DartType, DataObject> _typeMap = <DartType, DataObject>{};
617 List _pendingList = []; 628 List _pendingList = [];
629 IncludeElementFunction includeElement;
Siggi Cherem (dart-lang) 2016/03/18 20:00:20 rename to `shouldInclude`: ElementMatcher shoul
Johnni Winther 2016/03/29 09:05:54 Done.
618 630
619 Serializer(this._encoder); 631 // TODO(johnniwinther): Replace [includeElement] with a general strategy.
632 Serializer({this.includeElement: includeAllElements});
620 633
621 /// Add the transitive closure of [library] to this serializer. 634 /// Add the transitive closure of [library] to this serializer.
622 void serialize(LibraryElement library) { 635 void serialize(LibraryElement library) {
623 // Call [_getElementDataObject] for its side-effect: To create a 636 // Call [_getElementId] for its side-effect: To create a
624 // [DataObject] for [library]. If not already created, this will 637 // [DataObject] for [library]. If not already created, this will
625 // put the serialization of [library] in the work queue. 638 // put the serialization of [library] in the work queue.
626 _getElementDataObject(library); 639 _getElementId(library);
627 } 640 }
628 641
629 void _emptyWorklist() { 642 void _emptyWorklist() {
630 while (_pendingList.isNotEmpty) { 643 while (_pendingList.isNotEmpty) {
631 _pendingList.removeLast()(); 644 _pendingList.removeLast()();
632 } 645 }
633 } 646 }
634 647
635 /// Returns the [DataObject] for [element]. 648 /// Returns the id [Value] for [element].
636 /// 649 ///
637 /// If [constant] has no [DataObject], a new [DataObject] is created and 650 /// If [element] has no [DataObject], a new [DataObject] is created and
638 /// encoding the [ObjectValue] for [constant] is put into the work queue of 651 /// encoding the [ObjectValue] for [element] is put into the work queue of
639 /// this serializer. 652 /// this serializer.
640 DataObject _getElementDataObject(Element element) { 653 Value _getElementId(Element element) {
641 if (element == null) { 654 if (element == null) {
642 throw new ArgumentError('Serializer._getElementDataObject(null)'); 655 throw new ArgumentError('Serializer._getElementDataObject(null)');
643 } 656 }
644 DataObject dataObject = _elementMap[element]; 657 DataObject dataObject = _elementMap[element];
645 if (dataObject == null) { 658 if (dataObject == null) {
646 // Run through [ELEMENT_SERIALIZERS] sequentially to find the one that 659 if (!includeElement(element)) {
647 // deals with [element]. 660 if (element.isLibrary) {
648 for (ElementSerializer serializer in ELEMENT_SERIALIZERS) { 661 LibraryElement library = element;
649 SerializedElementKind kind = serializer.getSerializedKind(element); 662 _elementMap[element] = dataObject = new DataObject(
650 if (kind != null) { 663 new IntValue(_elementMap.length),
651 dataObject = new DataObject( 664 new EnumValue(SerializedElementKind.EXTERNAL_LIBRARY));
652 new IntValue(_elementMap.length), new EnumValue(kind)); 665 ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
653 _elementMap[element] = dataObject; 666 encoder.setUri(Key.URI, library.canonicalUri, library.canonicalUri);
654 // Delay the serialization of the element itself to avoid loops, and 667 } else if (element.isStatic) {
655 // to keep the call stack small. 668 Value classId =_getElementId(element.enclosingClass);
656 _pendingList.add(() { 669 _elementMap[element] = dataObject = new DataObject(
657 ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map); 670 new IntValue(_elementMap.length),
658 serializer.serialize(element, encoder, kind); 671 new EnumValue(SerializedElementKind.EXTERNAL_STATIC_MEMBER));
672 ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
673 encoder.setValue(Key.CLASS, classId);
674 encoder.setString(Key.NAME, element.name);
675 } else if (element.isConstructor) {
676 Value classId =_getElementId(element.enclosingClass);
677 _elementMap[element] = dataObject = new DataObject(
678 new IntValue(_elementMap.length),
679 new EnumValue(SerializedElementKind.EXTERNAL_CONSTRUCTOR));
680 ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
681 encoder.setValue(Key.CLASS, classId);
Siggi Cherem (dart-lang) 2016/03/18 20:00:20 Just to check: does the classId include the librar
Johnni Winther 2016/03/29 09:05:54 The class will be an EXTERNAL_LIBRARY_MEMBER, whic
682 encoder.setString(Key.NAME, element.name);
683 } else {
684 Value libraryId =_getElementId(element.library);
685 _elementMap[element] = dataObject = new DataObject(
686 new IntValue(_elementMap.length),
687 new EnumValue(SerializedElementKind.EXTERNAL_LIBRARY_MEMBER));
688 ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
689 encoder.setValue(Key.LIBRARY, libraryId);
690 encoder.setString(Key.NAME, element.name);
691 }
692 } else {
693 // Run through [ELEMENT_SERIALIZERS] sequentially to find the one that
694 // deals with [element].
695 for (ElementSerializer serializer in ELEMENT_SERIALIZERS) {
696 SerializedElementKind kind = serializer.getSerializedKind(element);
697 if (kind != null) {
698 _elementMap[element] = dataObject = new DataObject(
699 new IntValue(_elementMap.length), new EnumValue(kind));
700 // Delay the serialization of the element itself to avoid loops, and
701 // to keep the call stack small.
702 _pendingList.add(() {
703 ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
704 serializer.serialize(element, encoder, kind);
659 705
660 MapEncoder pluginData; 706 MapEncoder pluginData;
661 for (SerializerPlugin plugin in plugins) { 707 for (SerializerPlugin plugin in plugins) {
662 plugin.onElement(element, (String tag) { 708 plugin.onElement(element, (String tag) {
663 if (pluginData == null) { 709 if (pluginData == null) {
664 pluginData = encoder.createMap(Key.DATA); 710 pluginData = encoder.createMap(Key.DATA);
665 } 711 }
666 return pluginData.createObject(tag); 712 return pluginData.createObject(tag);
667 }); 713 });
668 } 714 }
669 }); 715 });
716 }
670 } 717 }
671 } 718 }
672 } 719 }
673 if (dataObject == null) { 720 if (dataObject == null) {
674 throw new UnsupportedError( 721 throw new UnsupportedError(
675 'Unsupported element: $element (${element.kind})'); 722 'Unsupported element: $element (${element.kind})');
676 } 723 }
677 return dataObject; 724 return dataObject.id;
678 } 725 }
679 726
680 /// Creates the [ElementValue] for [element]. 727 /// Creates the [ElementValue] for [element].
681 /// 728 ///
682 /// If [element] has not already been serialized, it is added to the work 729 /// If [element] has not already been serialized, it is added to the work
683 /// queue of this serializer. 730 /// queue of this serializer.
684 ElementValue createElementValue(Element element) { 731 ElementValue createElementValue(Element element) {
685 return new ElementValue(element, _getElementDataObject(element).id); 732 return new ElementValue(element, _getElementId(element));
686 } 733 }
687 734
688 /// Returns the [DataObject] for [constant]. 735 /// Returns the id [Value] for [constant].
689 /// 736 ///
690 /// If [constant] has no [DataObject], a new [DataObject] is created and 737 /// If [constant] has no [DataObject], a new [DataObject] is created and
691 /// encoding the [ObjectValue] for [constant] is put into the work queue of 738 /// encoding the [ObjectValue] for [constant] is put into the work queue of
692 /// this serializer. 739 /// this serializer.
693 DataObject _getConstantDataObject(ConstantExpression constant) { 740 Value _getConstantId(ConstantExpression constant) {
694 return _constantMap.putIfAbsent(constant, () { 741 return _constantMap.putIfAbsent(constant, () {
695 DataObject dataObject = new DataObject( 742 DataObject dataObject = new DataObject(
696 new IntValue(_constantMap.length), new EnumValue(constant.kind)); 743 new IntValue(_constantMap.length), new EnumValue(constant.kind));
697 // Delay the serialization of the constant itself to avoid loops, and to 744 // Delay the serialization of the constant itself to avoid loops, and to
698 // keep the call stack small. 745 // keep the call stack small.
699 _pendingList.add(() => _encodeConstant(constant, dataObject)); 746 _pendingList.add(() => _encodeConstant(constant, dataObject));
700 return dataObject; 747 return dataObject;
701 }); 748 }).id;
702 } 749 }
703 750
704 /// Encodes [constant] into the [ObjectValue] of [dataObject]. 751 /// Encodes [constant] into the [ObjectValue] of [dataObject].
705 void _encodeConstant(ConstantExpression constant, DataObject dataObject) { 752 void _encodeConstant(ConstantExpression constant, DataObject dataObject) {
706 const ConstantSerializer().visit(constant, 753 const ConstantSerializer().visit(constant,
707 new ObjectEncoder(this, dataObject.map)); 754 new ObjectEncoder(this, dataObject.map));
708 } 755 }
709 756
710 /// Creates the [ConstantValue] for [constant]. 757 /// Creates the [ConstantValue] for [constant].
711 /// 758 ///
712 /// If [constant] has not already been serialized, it is added to the work 759 /// If [constant] has not already been serialized, it is added to the work
713 /// queue of this serializer. 760 /// queue of this serializer.
714 ConstantValue createConstantValue(ConstantExpression constant) { 761 ConstantValue createConstantValue(ConstantExpression constant) {
715 return new ConstantValue(constant, _getConstantDataObject(constant).id); 762 return new ConstantValue(constant, _getConstantId(constant));
716 } 763 }
717 764
718 /// Returns the [DataObject] for [type]. 765 /// Returns the id [Value] for [type].
719 /// 766 ///
720 /// If [type] has no [DataObject], a new [DataObject] is created and 767 /// If [type] has no [DataObject], a new [DataObject] is created and
721 /// encoding the [ObjectValue] for [type] is put into the work queue of this 768 /// encoding the [ObjectValue] for [type] is put into the work queue of this
722 /// serializer. 769 /// serializer.
723 DataObject _getTypeDataObject(DartType type) { 770 Value _getTypeId(DartType type) {
724 return _typeMap.putIfAbsent(type, () { 771 DataObject dataObject = _typeMap[type];
725 DataObject dataObject = new DataObject( 772 if (dataObject == null) {
773 _typeMap[type] = dataObject = new DataObject(
726 new IntValue(_typeMap.length), new EnumValue(type.kind)); 774 new IntValue(_typeMap.length), new EnumValue(type.kind));
727 // Delay the serialization of the type itself to avoid loops, and to keep 775 // Delay the serialization of the type itself to avoid loops, and to keep
728 // the call stack small. 776 // the call stack small.
729 _pendingList.add(() => _encodeType(type, dataObject)); 777 _pendingList.add(() => _encodeType(type, dataObject));
730 return dataObject; 778 }
731 }); 779 return dataObject.id;
732 } 780 }
733 781
734 /// Encodes [type] into the [ObjectValue] of [dataObject]. 782 /// Encodes [type] into the [ObjectValue] of [dataObject].
735 void _encodeType(DartType type, DataObject dataObject) { 783 void _encodeType(DartType type, DataObject dataObject) {
736 const TypeSerializer().visit(type, new ObjectEncoder(this, dataObject.map)); 784 const TypeSerializer().visit(type, new ObjectEncoder(this, dataObject.map));
737 } 785 }
738 786
739 /// Creates the [TypeValue] for [type]. 787 /// Creates the [TypeValue] for [type].
740 /// 788 ///
741 /// If [type] has not already been serialized, it is added to the work 789 /// If [type] has not already been serialized, it is added to the work
742 /// queue of this serializer. 790 /// queue of this serializer.
743 TypeValue createTypeValue(DartType type) { 791 TypeValue createTypeValue(DartType type) {
744 return new TypeValue(type, _getTypeDataObject(type).id); 792 return new TypeValue(type, _getTypeId(type));
745 } 793 }
746 794
747 ObjectValue get objectValue { 795 ObjectValue get objectValue {
748 _emptyWorklist(); 796 _emptyWorklist();
749 797
750 Map<Key, Value> map = <Key, Value>{}; 798 Map<Key, Value> map = <Key, Value>{};
751 map[Key.ELEMENTS] = 799 map[Key.ELEMENTS] =
752 new ListValue(_elementMap.values.map((l) => l.objectValue).toList()); 800 new ListValue(_elementMap.values.map((l) => l.objectValue).toList());
753 if (_typeMap.isNotEmpty) { 801 if (_typeMap.isNotEmpty) {
754 map[Key.TYPES] = 802 map[Key.TYPES] =
755 new ListValue(_typeMap.values.map((l) => l.objectValue).toList()); 803 new ListValue(_typeMap.values.map((l) => l.objectValue).toList());
756 } 804 }
757 if (_constantMap.isNotEmpty) { 805 if (_constantMap.isNotEmpty) {
758 map[Key.CONSTANTS] = 806 map[Key.CONSTANTS] =
759 new ListValue(_constantMap.values.map((l) => l.objectValue).toList()); 807 new ListValue(_constantMap.values.map((l) => l.objectValue).toList());
760 } 808 }
761 return new ObjectValue(map); 809 return new ObjectValue(map);
762 } 810 }
763 811
764 String toText() { 812 String toText(SerializationEncoder encoder) {
765 return _encoder.encode(objectValue); 813 return encoder.encode(objectValue);
766 } 814 }
767 815
768 String prettyPrint() { 816 String prettyPrint() {
769 PrettyPrintEncoder encoder = new PrettyPrintEncoder(); 817 PrettyPrintEncoder encoder = new PrettyPrintEncoder();
770 return encoder.toText(objectValue); 818 return encoder.toText(objectValue);
771 } 819 }
772 } 820 }
773 821
774 /// Plugin for serializing additional data for an [Element]. 822 /// Plugin for serializing additional data for an [Element].
775 class SerializerPlugin { 823 class SerializerPlugin {
(...skipping 10 matching lines...) Expand all
786 class DeserializerPlugin { 834 class DeserializerPlugin {
787 const DeserializerPlugin(); 835 const DeserializerPlugin();
788 836
789 /// Called upon the deserialization of [element]. 837 /// Called upon the deserialization of [element].
790 /// 838 ///
791 /// Use [getDecoder] to retrieve the data object with id [tag] stored for 839 /// Use [getDecoder] to retrieve the data object with id [tag] stored for
792 /// [element]. If not object is stored for [tag], [getDecoder] returns `null`. 840 /// [element]. If not object is stored for [tag], [getDecoder] returns `null`.
793 void onElement(Element element, ObjectDecoder getDecoder(String tag)) {} 841 void onElement(Element element, ObjectDecoder getDecoder(String tag)) {}
794 } 842 }
795 843
844 /// Context for parallel deserialization.
845 class DeserializationContext {
846 Map<Uri, LibraryElement> _uriMap = <Uri, LibraryElement>{};
847 List<Deserializer> deserializers = <Deserializer>[];
848
849 LibraryElement lookupLibrary(Uri uri) {
850 return _uriMap.putIfAbsent(uri, () {
851 for (Deserializer deserializer in deserializers) {
852 LibraryElement library = deserializer.lookupLibrary(uri);
853 if (library != null) {
854 return library;
855 }
856 }
857 return null;
858 });
859 }
860 }
861
796 /// Deserializer for a closed collection of libraries. 862 /// Deserializer for a closed collection of libraries.
797 // TODO(johnniwinther): Support per-library deserialization and dependencies 863 // TODO(johnniwinther): Support per-library deserialization and dependencies
798 // between deserialized subcomponent. 864 // between deserialized subcomponent.
799 class Deserializer { 865 class Deserializer {
866 final DeserializationContext context;
800 final SerializationDecoder decoder; 867 final SerializationDecoder decoder;
801 List<DeserializerPlugin> plugins = <DeserializerPlugin>[]; 868 List<DeserializerPlugin> plugins = <DeserializerPlugin>[];
802 ObjectDecoder _headerObject; 869 ObjectDecoder _headerObject;
803 ListDecoder _elementList; 870 ListDecoder _elementList;
804 ListDecoder _typeList; 871 ListDecoder _typeList;
805 ListDecoder _constantList; 872 ListDecoder _constantList;
806 Map<int, Element> _elementMap = {}; 873 Map<int, Element> _elementMap = {};
807 Map<int, DartType> _typeMap = {}; 874 Map<int, DartType> _typeMap = {};
808 Map<int, ConstantExpression> _constantMap = {}; 875 Map<int, ConstantExpression> _constantMap = {};
809 876
810 Deserializer.fromText(String text, this.decoder) { 877 Deserializer.fromText(this.context, String text, this.decoder) {
811 _headerObject = new ObjectDecoder(this, decoder.decode(text)); 878 _headerObject = new ObjectDecoder(this, decoder.decode(text));
879 context.deserializers.add(this);
812 } 880 }
813 881
814 /// Returns the [ListDecoder] for the [Element]s in this deserializer. 882 /// Returns the [ListDecoder] for the [Element]s in this deserializer.
815 ListDecoder get elements { 883 ListDecoder get elements {
816 if (_elementList == null) { 884 if (_elementList == null) {
817 _elementList = _headerObject.getList(Key.ELEMENTS); 885 _elementList = _headerObject.getList(Key.ELEMENTS);
818 } 886 }
819 return _elementList; 887 return _elementList;
820 } 888 }
821 889
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 } 921 }
854 return null; 922 return null;
855 } 923 }
856 924
857 /// Returns the deserialized [Element] for [id]. 925 /// Returns the deserialized [Element] for [id].
858 Element deserializeElement(int id) { 926 Element deserializeElement(int id) {
859 if (id == null) throw new ArgumentError('Deserializer.getElement(null)'); 927 if (id == null) throw new ArgumentError('Deserializer.getElement(null)');
860 Element element = _elementMap[id]; 928 Element element = _elementMap[id];
861 if (element == null) { 929 if (element == null) {
862 ObjectDecoder decoder = elements.getObject(id); 930 ObjectDecoder decoder = elements.getObject(id);
863 element = ElementDeserializer.deserialize(decoder); 931 SerializedElementKind elementKind =
932 decoder.getEnum(Key.KIND, SerializedElementKind.values);
933 if (elementKind == SerializedElementKind.EXTERNAL_LIBRARY) {
934 Uri uri = decoder.getUri(Key.URI);
935 element = context.lookupLibrary(uri);
936 if (element == null) {
937 throw new StateError("Missing library for $uri.");
938 }
939 } else if (elementKind == SerializedElementKind.EXTERNAL_LIBRARY_MEMBER) {
940 LibraryElement library = decoder.getElement(Key.LIBRARY);
941 String name = decoder.getString(Key.NAME);
942 element = library.find(name);
943 if (element == null) {
944 throw new StateError("Missing library member for $name in $library.");
945 }
946 } else if (elementKind == SerializedElementKind.EXTERNAL_STATIC_MEMBER) {
947 ClassElement cls = decoder.getElement(Key.CLASS);
948 String name = decoder.getString(Key.NAME);
949 element = cls.lookupLocalMember(name);
950 if (element == null) {
951 throw new StateError("Missing static member for $name in $cls.");
952 }
953 } else if (elementKind == SerializedElementKind.EXTERNAL_CONSTRUCTOR) {
954 ClassElement cls = decoder.getElement(Key.CLASS);
955 String name = decoder.getString(Key.NAME);
956 element = cls.lookupConstructor(name);
957 if (element == null) {
958 throw new StateError("Missing constructor for $name in $cls.");
959 }
960 } else {
961 element = ElementDeserializer.deserialize(decoder, elementKind);
962 }
864 _elementMap[id] = element; 963 _elementMap[id] = element;
865 964
866 MapDecoder pluginData = decoder.getMap(Key.DATA, isOptional: true); 965 MapDecoder pluginData = decoder.getMap(Key.DATA, isOptional: true);
867 // Call plugins even when there is no data, so they can take action in 966 // Call plugins even when there is no data, so they can take action in
868 // this case. 967 // this case.
869 for (DeserializerPlugin plugin in plugins) { 968 for (DeserializerPlugin plugin in plugins) {
870 plugin.onElement(element, 969 plugin.onElement(element,
871 (String tag) => pluginData?.getObject(tag, isOptional: true)); 970 (String tag) => pluginData?.getObject(tag, isOptional: true));
872 } 971 }
873 } 972 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 1005
907 /// Returns the value used to store [key] as a property in the encoding an 1006 /// Returns the value used to store [key] as a property in the encoding an
908 /// [ObjectValue]. 1007 /// [ObjectValue].
909 /// 1008 ///
910 /// Different encodings have different restrictions and capabilities as how 1009 /// Different encodings have different restrictions and capabilities as how
911 /// to store a [Key] value. For instance: A JSON encoding needs to convert 1010 /// to store a [Key] value. For instance: A JSON encoding needs to convert
912 /// [Key] to a [String] to store it in a JSON object; a Dart encoding can 1011 /// [Key] to a [String] to store it in a JSON object; a Dart encoding can
913 /// choose to store a [Key] as an [int] or as the [Key] itself. 1012 /// choose to store a [Key] as an [int] or as the [Key] itself.
914 getObjectPropertyValue(Key key); 1013 getObjectPropertyValue(Key key);
915 } 1014 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698