diff --git a/lib/src/converters/class_converter.dart b/lib/src/converters/class_converter.dart index 43d54ad..bf4bd4a 100644 --- a/lib/src/converters/class_converter.dart +++ b/lib/src/converters/class_converter.dart @@ -12,25 +12,28 @@ class ClassConverter implements Converter { TypeInformationRetriever get _typeInformationRetriever => TypeInformationRetrieverLocator.instance; - BaseIntermediateObject toBaseIntermediateObject(Object value) { + BaseIntermediateObject toBaseIntermediateObject(Object value, + [ClassMapping classMapping = null]) { var valueType = value.runtimeType; if (converters.containsKey(valueType)) return converters[valueType].from(value); - if (value is List) { - return new ListIntermediateObject() - ..values = value.map((v) => toBaseIntermediateObject(v)).toList(); - } + if (classMapping == null) { + if (value is List) { + return new ListIntermediateObject() + ..values = value.map((v) => toBaseIntermediateObject(v)).toList(); + } - if (_isPrimitive(value)) - return new NativeIntermediateObject() - ..objectType = valueType - ..value = value; + if (_isPrimitive(value)) + return new NativeIntermediateObject() + ..objectType = valueType + ..value = value; - if (_isEnum(value)) { - return new NativeIntermediateObject() - ..objectType = int - ..value = (value as dynamic).index; + if (_isEnum(value)) { + return new NativeIntermediateObject() + ..objectType = int + ..value = (value as dynamic).index; + } } var hashCode = value.hashCode; @@ -41,17 +44,17 @@ class ClassConverter implements Converter { ..properties = {}; seenHashCodes.add(hashCode); - var generatedMap = - _typeInformationRetriever.getClassGeneratedMap(valueType); + if (classMapping == null) + classMapping = _typeInformationRetriever.getClassGeneratedMap(valueType); var properties = {}; //Faster than foreach loop - for (var i = 0; i < generatedMap.fields.length; i++) { - var property = generatedMap.fields[i]; + for (var i = 0; i < classMapping.fields.length; i++) { + var property = classMapping.fields[i]; var getter = property.fieldMapping.getter; properties[property.fieldMapping.name] = - toBaseIntermediateObject(getter(value)); + toBaseIntermediateObject(getter(value), property.classMapping); } return new ClassIntermediateObject() diff --git a/lib/src/converters/converters.dart b/lib/src/converters/converters.dart index bc86366..8d8b25d 100644 --- a/lib/src/converters/converters.dart +++ b/lib/src/converters/converters.dart @@ -4,6 +4,7 @@ import 'dart:convert'; import 'package:nomirrorsmap/src/conversion_objects/conversion_objects.dart'; import 'package:nomirrorsmap/src/shared/shared.dart'; +import 'dart:collection'; part 'converter.dart'; part 'class_converter.dart'; diff --git a/lib/src/converters/json_converter.dart b/lib/src/converters/json_converter.dart index 984cb80..b32422f 100644 --- a/lib/src/converters/json_converter.dart +++ b/lib/src/converters/json_converter.dart @@ -85,20 +85,24 @@ class JsonConverter implements Converter { if (_includeMetadata) setMetaData(stringBuffer, baseObjectData); - for (var key in baseObjectData.properties.keys) { + var lastKey = baseObjectData.properties.keys.length > 0 + ? baseObjectData.properties.keys.last + : null; + baseObjectData.properties.forEach((key, value) { stringBuffer.write("\"$key\":"); - _fromBaseObjectData(baseObjectData.properties[key], stringBuffer); - if (baseObjectData.properties.keys.last != key) stringBuffer.write(","); - } + _fromBaseObjectData(value, stringBuffer); + if (lastKey != key) stringBuffer.write(","); + }); stringBuffer.write("}"); } if (baseObjectData is ListIntermediateObject) { stringBuffer.write("["); + var lastIndex = baseObjectData.values.length - 1; for (var i = 0; i < baseObjectData.values.length; i++) { var value = baseObjectData.values[i]; _fromBaseObjectData(value, stringBuffer); - if (i != (baseObjectData.values.length - 1)) stringBuffer.write(","); + if (i != lastIndex) stringBuffer.write(","); } stringBuffer.write("]"); } diff --git a/lib/src/converters/mapping_store/class_property.dart b/lib/src/converters/mapping_store/class_property.dart index 0beb8c8..f42dddf 100644 --- a/lib/src/converters/mapping_store/class_property.dart +++ b/lib/src/converters/mapping_store/class_property.dart @@ -3,4 +3,5 @@ part of nomirrorsmap.converters; class ClassField { Type type; FieldMapping fieldMapping; + ClassMapping classMapping; } diff --git a/lib/src/converters/mapping_store/no_mirrors_map_store.dart b/lib/src/converters/mapping_store/no_mirrors_map_store.dart index 971c036..1756146 100644 --- a/lib/src/converters/mapping_store/no_mirrors_map_store.dart +++ b/lib/src/converters/mapping_store/no_mirrors_map_store.dart @@ -15,7 +15,8 @@ class NoMirrorsMapStore implements TypeInformationRetriever { ..name = fieldName); } - static Map _classMappingsByType = {}; + static SplayTreeMap _classMappingsByType = + new SplayTreeMap((a, b) => a == b ? 0 : 1); ClassMapping getClassGeneratedMap(Type type) { var classMapping = _classMappingsByType[type]; @@ -41,7 +42,8 @@ class NoMirrorsMapStore implements TypeInformationRetriever { return classMapping; } - static Map _classMappingsByListType = {}; + static SplayTreeMap _classMappingsByListType = + new SplayTreeMap((a, b) => a == b ? 0 : 1); ClassMapping getClassGeneratedMapByListType(Type type) { var classMapping = _classMappingsByListType[type]; @@ -70,12 +72,19 @@ class NoMirrorsMapStore implements TypeInformationRetriever { ..fieldMapping = _fieldMappings.firstWhere((p) => p.name == k)); }); - _classMappings.add(new ClassMapping() + var classMapping = new ClassMapping() ..type = type ..listType = listType ..fullName = fullName ..instantiate = instantiate - ..fields = classFields); + ..fields = classFields; + _classMappings.add(classMapping); + + _classMappings.forEach((cm) { + cm.fields.where((field) => field.type == type).forEach((field) { + field.classMapping = classMapping; + }); + }); } static void registerEnum(Type type, List values) { diff --git a/test/all_test.dart b/test/all_test.dart index 147573d..a2bc600 100644 --- a/test/all_test.dart +++ b/test/all_test.dart @@ -11,7 +11,6 @@ import 'test_mappings.dart' as test_mappings; import 'type_to_type_objects.dart' as objects; import 'test_objects.dart'; import 'new_transformer_tests.dart'; -import 'package:reflective/reflective.dart'; part 'type_to_type_tests.dart'; @@ -24,10 +23,10 @@ main() async { group("Transformer", () => TransformerTests.run()); var noMirrorsMapInstances = { + 'Mappings Based': () {}, 'Mirrors Based': () { useMirrors(); - }, - 'Mappings Based': () {} + } }; for (var noMirrorsMapFuncKey in noMirrorsMapInstances.keys) { @@ -76,6 +75,9 @@ main() async { ..parents = [] ]); + noMirrorsMap.convert( + list, new ClassConverter(), new NewtonSoftJsonConverter()); + var stopwatch = new Stopwatch()..start(); noMirrorsMap.convert( list, new ClassConverter(), new NewtonSoftJsonConverter());