| Index: pkg/serialization/lib/src/basic_rule.dart
|
| diff --git a/pkg/serialization/lib/src/basic_rule.dart b/pkg/serialization/lib/src/basic_rule.dart
|
| index adbd9ea9cce7646b7a0f9825b749f20fbd8a4590..a22ea0a2841be1885309df0d81f2ade9fed5ed97 100644
|
| --- a/pkg/serialization/lib/src/basic_rule.dart
|
| +++ b/pkg/serialization/lib/src/basic_rule.dart
|
| @@ -137,9 +137,26 @@ class BasicRule extends SerializationRule {
|
| createStateHolder() =>
|
| useMaps ? new _MapWrapper(fields.contents) : new List(fields.length);
|
|
|
| - /** Wrap the state if it's passed in as a map. */
|
| - makeIndexableByNumber(state) =>
|
| - (state is Map) ? new _MapWrapper.fromMap(state, fields.contents) : state;
|
| + /**
|
| + * Wrap the state if it's passed in as a map, and if the keys are references,
|
| + * resolve them to the strings we expect. We leave the previous keys in there
|
| + * as well, as they shouldn't be harmful, and it costs more to remove them.
|
| + */
|
| + makeIndexableByNumber(state) {
|
| + if (!(state is Map)) return state;
|
| + // TODO(alanknight): This is quite inefficient, and we do it twice per
|
| + // instance. If the keys are references, we need to turn them into strings
|
| + // before we can look at indexing them by field position. It's also eager,
|
| + // but we know our keys are always primitives, so we don't have to worry
|
| + // about their instances not having been created yet.
|
| + for (var each in state.keys) {
|
| + if (each is Reference) {
|
| + var inflated = each.inflated();
|
| + state[inflated] = state[each];
|
| + }
|
| + }
|
| + return new _MapWrapper.fromMap(state, fields.contents);
|
| + }
|
|
|
| /**
|
| * Extract the state from [object] using an instanceMirror and the field
|
| @@ -152,12 +169,27 @@ class BasicRule extends SerializationRule {
|
| keysAndValues(fields).forEach(
|
| (index, field) {
|
| var value = _value(mirror, field);
|
| + callback(field.name);
|
| callback(checkForEssentialLists(index, value));
|
| result[index] = value;
|
| });
|
| return _unwrap(result);
|
| }
|
|
|
| + flatten(state, Writer writer) {
|
| + if (state is List) {
|
| + keysAndValues(state).forEach((index, value) {
|
| + state[index] = writer._referenceFor(value);
|
| + });
|
| + } else {
|
| + var newState = new Map();
|
| + keysAndValues(state).forEach((key, value) {
|
| + newState[writer._referenceFor(key)] = writer._referenceFor(value);
|
| + });
|
| + return newState;
|
| + }
|
| + }
|
| +
|
| /**
|
| * If the value is a List, and the field is a constructor field or
|
| * otherwise specially designated, we wrap it in something that indicates
|
| @@ -219,8 +251,12 @@ class BasicRule extends SerializationRule {
|
| fields.figureOutFields();
|
| }
|
|
|
| + bool get hasVariableLengthEntries => false;
|
| +
|
| + int get dataLength => fields.length;
|
| +
|
| /**
|
| - * Extract the value of the field [fieldName] from the object reflected
|
| + * Extract the value of [field] from the object reflected
|
| * by [mirror].
|
| */
|
| // TODO(alanknight): The framework should be resilient if there are fields
|
| @@ -514,7 +550,7 @@ class _FieldList extends Iterable {
|
| */
|
| void figureOutFields() {
|
| Iterable names(Iterable<DeclarationMirror> mirrors) =>
|
| - mirrors.mappedBy((each) => each.simpleName);
|
| + mirrors.mappedBy((each) => each.simpleName).toList();
|
|
|
| if (!_shouldFigureOutFields || !regularFields().isEmpty) return;
|
| var fields = publicFields(mirror);
|
| @@ -528,6 +564,8 @@ class _FieldList extends Iterable {
|
| addAllNotExplicitlyExcluded(names(gettersWithSetters));
|
| addAllNotExplicitlyExcluded(names(gettersThatMatchConstructor));
|
| }
|
| +
|
| + toString() => "FieldList($contents)";
|
| }
|
|
|
| /**
|
| @@ -570,9 +608,8 @@ class Constructor {
|
| constructFrom(state, Reader r) {
|
| // TODO(alanknight): Handle named parameters
|
| Collection inflated = fieldNumbers.mappedBy(
|
| - (x) => (x is int) ? reflect(r.inflateReference(state[x])) : reflect(x))
|
| - .toList();
|
| - var result = type.newInstance(name, inflated);
|
| + (x) => (x is int) ? reflect(r.inflateReference(state[x])) : reflect(x));
|
| + var result = type.newInstance(name, inflated.toList());
|
| return deprecatedFutureValue(result);
|
| }
|
| }
|
| @@ -582,12 +619,13 @@ class Constructor {
|
| * from the index into a field name and then looks it up in the map.
|
| */
|
| class _MapWrapper {
|
| - Map<String, dynamic> _map = new Map<String, dynamic>();
|
| + final _map;
|
| List fieldList;
|
| - _MapWrapper(this.fieldList);
|
| + _MapWrapper(this.fieldList) : _map = new Map();
|
| _MapWrapper.fromMap(this._map, this.fieldList);
|
|
|
| operator [](key) => _map[fieldList[key].name];
|
| +
|
| operator []=(key, value) { _map[fieldList[key].name] = value; }
|
| get length => _map.length;
|
|
|
|
|