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