Index: tool/input_sdk/private/js_mirrors.dart |
diff --git a/tool/input_sdk/private/js_mirrors.dart b/tool/input_sdk/private/js_mirrors.dart |
index b39ebd865b2f51388b86d427d9c2bc0428960001..2b7b04797e504e5c269b6a531429ab41b444a67f 100644 |
--- a/tool/input_sdk/private/js_mirrors.dart |
+++ b/tool/input_sdk/private/js_mirrors.dart |
@@ -4,11 +4,19 @@ |
library dart._js_mirrors; |
-getName(symbol) { |
- throw new UnimplementedError("MirrorSystem.getName unimplemented"); |
+import 'dart:collection'; |
+import 'dart:mirrors'; |
+import 'dart:_foreign_helper' show JS; |
+ |
+// TODO(vsm): This a workaround for: |
+// https://github.com/dart-lang/dev_compiler/issues/219 |
+import 'dart:js'; |
+ |
+String getName(Symbol symbol) { |
+ return JS('String', '#.toString().substring(8, #.toString().length - 2)', symbol, symbol); |
Jennifer Messerly
2015/06/15 16:42:02
Not sure toString the best way to implement this?
vsm
2015/06/15 20:59:47
Done - thanks!
|
} |
-getSymbol(name, library) { |
+Symbol getSymbol(name, library) { |
throw new UnimplementedError("MirrorSystem.getSymbol unimplemented"); |
} |
@@ -17,10 +25,146 @@ final currentJsMirrorSystem = |
"MirrorSystem.currentJsMirrorSystem unimplemented"); |
-reflect(reflectee) { |
- throw new UnimplementedError("MirrorSystem.reflect unimplemented"); |
+InstanceMirror reflect(reflectee) { |
+ return new JsInstanceMirror._(reflectee); |
Jennifer Messerly
2015/06/15 16:42:02
silly: could be => ?
vsm
2015/06/15 20:59:47
Done.
|
+} |
+ |
+TypeMirror reflectType(Type key) { |
+ // FIXME(vsm): Might not be a class. |
Jennifer Messerly
2015/06/15 16:42:02
TODO? or did you mean to fix before landing?
vsm
2015/06/15 20:59:46
I'll update the mirrors bug.
|
+ return new JsClassMirror._(key); |
+} |
+ |
+final dynamic _dart = JS('', 'dart'); |
Jennifer Messerly
2015/06/15 16:42:02
Not sure this field is worth it? if we're hardcodi
vsm
2015/06/15 20:59:47
Leaf had been moving / hiding some of our runtime
Jennifer Messerly
2015/06/15 21:40:16
eventually, yeah, things will move ... but we'll h
|
+final _metadata = JS('', '#.metadata', _dart); |
+ |
+dynamic _dload(obj, String name) { |
Jennifer Messerly
2015/06/15 16:42:02
btw, if we wanted to make these APIs available sta
vsm
2015/06/15 20:59:47
thanks for filing!
|
+ return JS('', '#.dload(#, #)', _dart, obj, name); |
+} |
+ |
+void _dput(obj, String name, val) { |
+ JS('', '#.dput(#, #, #)', _dart, obj, name, val); |
+} |
+ |
+dynamic _dsend(obj, String name, List args) { |
+ return JS('', '#.dsendArray(#, #, #)', _dart, obj, name, args); |
+} |
+ |
+class JsInstanceMirror implements InstanceMirror { |
+ Object _instance; |
Jennifer Messerly
2015/06/15 16:42:01
final?
vsm
2015/06/15 20:59:46
Done.
|
+ |
+ JsInstanceMirror._(this._instance); |
+ |
+ Object get reflectee { |
Jennifer Messerly
2015/06/15 16:42:02
This could just make `reflectee` be the final fiel
vsm
2015/06/15 20:59:47
Done.
|
+ return this._instance; |
+ } |
+ |
+ InstanceMirror getField(Symbol symbol) { |
+ var name = getName(symbol); |
+ var field = _dload(_instance, name); |
+ return new JsInstanceMirror._(field); |
+ } |
+ |
+ InstanceMirror setField(Symbol symbol, Object value) { |
+ var name = getName(symbol); |
+ var field = _dput(_instance, name, value); |
+ return new JsInstanceMirror._(field); |
+ } |
+ |
+ InstanceMirror invoke(Symbol symbol, List<dynamic> args, [Map<Symbol, dynamic> namedArgs]) { |
Jennifer Messerly
2015/06/15 16:42:02
long line
vsm
2015/06/15 20:59:47
Done.
|
+ var name = getName(symbol); |
+ var result = _dsend(_instance, name, args); |
Jennifer Messerly
2015/06/15 16:42:01
TODO: named args?
or maybe implement it:
if
vsm
2015/06/15 20:59:47
Code stolen! :-)
|
+ return new JsInstanceMirror._(result); |
+ } |
} |
-reflectType(Type key) { |
- throw new UnimplementedError("MirrorSystem.reflectType unimplemented"); |
+class JsClassMirror implements ClassMirror { |
+ final Type _cls; |
+ Symbol _simpleName; |
Jennifer Messerly
2015/06/15 16:42:02
final Symbol simpleName?
and init like:
JsClassM
vsm
2015/06/15 20:59:47
Done.
|
+ |
+ List<InstanceMirror> _metadata; |
Jennifer Messerly
2015/06/15 16:42:01
these could probably be final too, but would need
vsm
2015/06/15 20:59:47
Yes, I also need to make this immutable (see comme
|
+ Map<Symbol, MethodMirror> _declarations; |
+ |
+ Symbol get simpleName => _simpleName; |
+ |
+ // These need to be immutable when escaping from this class. |
+ List<InstanceMirror> get metadata => _metadata; |
+ Map<Symbol, MethodMirror> get declarations => _declarations; |
+ |
+ JsClassMirror._(this._cls) { |
+ _simpleName = new Symbol(JS('String', '#.name', _cls)); |
+ |
+ // Load metadata. |
+ var fn = JS('List<InstanceMirror>', '#[dart.metadata]', _cls); |
Jennifer Messerly
2015/06/15 16:42:02
fyi, I don't think we parse this. (but we should)
|
+ _metadata = (fn == null) ? [] : fn().map((i) => new JsInstanceMirror._(i)); |
Jennifer Messerly
2015/06/15 16:42:02
this looks like it's assigning Iterable<InstanceMi
vsm
2015/06/15 20:59:47
Good catch! - this is the problem with just emitti
|
+ |
+ // Load declarations. |
+ // FIXME(vsm): This is only populating the default constructor right now. |
+ _declarations = new Map<Symbol, MethodMirror>(); |
+ _declarations[_simpleName] = new JsMethodMirror._(this, _cls); |
+ } |
+ |
+ InstanceMirror newInstance(Symbol constructorName, List args, [Map<Symbol, dynamic> namedArgs]) { |
Jennifer Messerly
2015/06/15 16:42:01
long line
vsm
2015/06/15 20:59:47
Done.
|
+ // FIXME(vsm): Support named constructors and named arguments. |
+ assert(getName(constructorName) == ""); |
+ assert(namedArgs == null || namedArgs.isEmpty); |
+ var instance = JS('', '#.instantiate(#, #)', _dart, _cls, args); |
+ return new JsInstanceMirror._(instance); |
+ } |
+} |
+ |
+class JsTypeMirror implements TypeMirror { |
+ final Type reflectedType; |
+ |
+ JsTypeMirror._(this.reflectedType); |
+} |
+ |
+class JsParameterMirror implements ParameterMirror { |
+ final String _name; |
+ final TypeMirror type; |
+ final List<InstanceMirror> metadata = []; |
+ |
+ JsParameterMirror._(this._name, Type t) : type = new JsTypeMirror._(t); |
+} |
+ |
+class JsMethodMirror implements MethodMirror { |
+ final String _name; |
+ final dynamic _method; |
+ List<ParameterMirror> _params; |
+ |
+ JsMethodMirror._(JsClassMirror cls, this._method) : _name = getName(cls._simpleName) { |
Jennifer Messerly
2015/06/15 16:42:01
long line
vsm
2015/06/15 20:59:46
Done.
|
+ var ftype = JS('', '#.classGetConstructorType(#)', _dart, cls._cls); |
+ _params = _createParameterMirrorList(ftype); |
+ } |
+ |
+ // TODO(vsm): Support named constructors. |
+ Symbol get constructorName => new Symbol(''); |
+ List<ParameterMirror> get parameters => _params; |
+ |
+ List<ParameterMirror> _createParameterMirrorList(ftype) { |
+ if (ftype == null) { |
+ // TODO(vsm): No explicit constructor. Verify this. |
+ return []; |
+ } |
+ |
+ // TODO(vsm): Add named args. |
+ List args = ftype.args; |
+ List opts = ftype.optionals; |
+ var params = new List<ParameterMirror>(args.length + opts.length); |
+ |
+ for (var i = 0; i < args.length; ++i) { |
+ var type = args[i]; |
+ // TODO(vsm): Recover the param name. |
+ var param = new JsParameterMirror._('', type); |
+ params[i] = param; |
+ } |
+ |
+ for (var i = 0; i < opts.length; ++i) { |
+ var type = opts[i]; |
+ // TODO(vsm): Recover the param name. |
+ var param = new JsParameterMirror._('', type); |
+ params[i + args.length] = param; |
+ } |
+ |
+ return params; |
+ } |
} |