I completed the support of List(and Map) property in Entity class, and this works for both dynamic(with dart:mirrors lib for Dart VM) and static mode(for javascript).
But I haven't tested on javascript mode yet, but it should work. Also I haven't tested the map case. I will do it later.
This version was committed to Github.
Following is the sample code to show the support of List field in a class.
class A { int _i = 0; List<B> _bs = []; A(this._i, this._bs); factory A.create() => new A(111, []); int get i => _i; void set i(int ii) { _i == ii; } List<B> get bs => _bs; void set bs(List<B> bs) {_bs = bs; } } class B { String _s = 'zz'; B(this._s); factory B.create() => new B('ss'); String get s => _s; void set s(String ss) { _s == ss; } } test_simple_model() { A a = new A.create()..i = 10 ..bs.add(new B.create()..s = "vvv") ..bs.add(new B.create()..s = "eee"); String json = sampleJsonMapper.toJson(a); print(">>A@1 test_toJson json: ${json}"); A a1 = sampleJsonMapper.fromJson(A, json); print(">>A@2 test_Json a1: ${a1}"); }
And the output of execution:
>>A@1 test_toJson json: {"i": 111,"bs": [{"s": "ss"},{"s": "ss"}]} >> obj: Instance of 'A' >>A@2 test_Json a1: Instance of 'A' >> json: {"i": 10,"bs": [{"s": "ss"},{"s": "vv"}]}
Actually the support of generic type property was a bit difficult due to some confusing behavior of reflectedType property of ClassMirror. And some irreversible operation of types and typeArguments behavior.
But by keeping type instead of extracting from ClassMirror, I could avoid the current restriction of Miror library. Probably Dart is still early stage, such mirror behavior should be refined.
Following are the problems I found:
1) why we cannot do followings:
var t1 = List<A>;
var cmirr = reflectClass(List<A>);
while we can do for none generic class:
car t = A;
var cmirr = reflectClass<A);
2) how can I create ClassMirror object which has reflectedType.
if we create CirrorClass through reflectClass(new List<B>().runtimeType),
it does not have reflectedType. but if we get ClassMirror from bs of A, it has a reflectedType. So there should be some way to create Mirror class which has reflectedType.
3) the reflectClass<List<A>) has all information to make cmirror to have reflectedType(since argumentType A is provided).
It should return ClassMirror with reflectedType.
I think this is very inconvenient behavior, and should be called a bug.library dart_generics_test; import 'dart:mirrors'; class A { int _i = 0; List<B> _bs = []; int get i => _i; void set i(int ii) { _i == ii; } List<B> get bs => _bs; void set bs(List<B> bs) {_bs = bs; } } class B { String _s = 'zz'; String get s => _s; void set s(String ss) { _s == ss; } } test_generics() { { /* ClassMirror immir0 = reflectClass(List<B>); // <== this cannot be compiled! Type t0 = immir0.reflectedType; print(">> ${t0}"); */ // following code is to get a Type of List<B>, a work around to avoid above problem. InstanceMirror immir = reflect(new List<B>()); Type t = immir.type.reflectedType; print(">>1.1 ${t}"); /* ClassMirror cmirr = reflectClass(t); Type t2 = cmirr.reflectedType; // here t2 == t, but it throws exception print(">>1.2 ${t2}"); */ /* * Unhandled exception: Unsupported operation: Declarations of generics have no reflected type #0 _LocalClassMirrorImpl.reflectedType (dart:mirrors-patch/mirrors_impl.dart:304:7) #1 test_generics (file:///opt/dart-workspace/reflective_web_dev_kit/sample_app/bin/sample_json_mapper_test.dart:76:21) #2 main (file:///opt/dart-workspace/reflective_web_dev_kit/sample_app/bin/sample_json_mapper_test.dart:81:16) * */ } { Type t1 = new B("nn").runtimeType; print(">>2.1 ${t1}"); ClassMirror cmirr1 = reflectClass(t1); Type t2 = cmirr1.reflectedType; // this is ok print(">>2.1 ${t2}"); } { Type t1 = new List<B>().runtimeType; // return List<B> print(">>3.1 t1: ${t1}"); ClassMirror cmirr1 = reflectClass(t1); Type t2 = cmirr1.runtimeType; // return _LocalClassMirrorImpl print(">>3.2 t2: ${t2}"); print(">>3.3 cmirr1.hasReflectedType: ${cmirr1.hasReflectedType}"); Type t4 = cmirr1.reflectedType; // here it should be t4 == t0, but it throws exception print(">>3.3 t4: ${t4}"); } { ClassMirror cmirr = reflectClass(A); cmirr.getters.forEach((k, MethodMirror md){ Type tm = (md.returnType as ClassMirror).reflectedType; // this is OK print(">>4.1 k: ${k}, tm: ${tm}"); }); } } main() { test_generics(); }
No comments:
Post a Comment