Chromium Code Reviews| 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..c76972be111bf67a9758ac4cd6a16e991c016bd7 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]; |
|
Jennifer Messerly
2013/01/25 01:19:59
fwiw, I think you could do:
state[inflated] =
Alan Knight
2013/01/26 01:33:38
I had that at one point and it appeared to work, b
|
| + } |
| + } |
| + 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>(); |
| + var _map = new Map(); |
|
Jennifer Messerly
2013/01/25 01:19:59
final?
Alan Knight
2013/01/26 01:33:38
Done.
|
| List fieldList; |
| _MapWrapper(this.fieldList); |
| _MapWrapper.fromMap(this._map, this.fieldList); |
| operator [](key) => _map[fieldList[key].name]; |
| + |
| operator []=(key, value) { _map[fieldList[key].name] = value; } |
| get length => _map.length; |