Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(461)

Unified Diff: dart/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart

Issue 15858005: Implement get/set field in library and class mirrors. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: dart/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart
diff --git a/dart/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart b/dart/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart
index 85b9ee55a8b728a593bdd5c1e76724b6b3599150..fa3f9cd4316dcd1e1115e6846328360c27e45470 100644
--- a/dart/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart
+++ b/dart/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart
@@ -14,10 +14,77 @@ patch class MirrorSystem {
}
class _MirrorSystem implements MirrorSystem {
+ TypeMirror get dynamicType => _dynamicType;
+ TypeMirror get voidType => _voidType;
+
+ final static TypeMirror _dynamicType =
+ new _TypeMirror(const Symbol('dynamic'));
+ final static TypeMirror _voidType = new _TypeMirror(const Symbol('void'));
+
+ static final Map<String, List<LibraryMirror>> librariesByName =
+ computeLibrariesByName();
+
+ Iterable<LibraryMirror> findLibrary(Symbol libraryName) {
+ return new List<LibraryMirror>.from(librariesByName[_n(libraryName)]);
+ }
+
+ static Map<String, List<LibraryMirror>> computeLibrariesByName() {
+ var result = new Map<String, List<LibraryMirror>>();
+ var jsLibraries = JS('=List|Null', 'init.libraries');
+ if (jsLibraries == null) return result;
+ for (List data in jsLibraries) {
+ String name = data[0];
+ Uri uri = Uri.parse(data[1]);
+ List<String> classes = data[2];
+ List<String> functions = data[3];
+ var libraries = result.putIfAbsent(name, () => <LibraryMirror>[]);
+ libraries.add(new _LibraryMirror(name, uri, classes, functions));
+ }
+ return result;
+ }
+}
+
+class _TypeMirror implements TypeMirror {
+ final Symbol simpleName;
+ _TypeMirror(this.simpleName);
+}
+
+class _LibraryMirror extends _ObjectMirror implements LibraryMirror {
+ final String _name;
+ final Uri uri;
+ final List<String> _classes;
+ final List<String> _functions;
+
+ _LibraryMirror(this._name, this.uri, this._classes, this._functions);
+
+ Map<Symbol, ClassMirror> get classes {
+ var result = new Map<Symbol, ClassMirror>();
+ for (int i = 0; i < _classes.length; i += 2) {
+ Symbol symbol = _s(_classes[i]);
+ result[symbol] = _reflectClass(symbol, _classes[i + 1]);
+ }
+ return result;
+ }
+
+ InstanceMirror setField(Symbol fieldName, Object arg) {
+ // TODO(ahe): This is extremely dangerous!!!
+ JS('void', r'$[#] = #', _n(fieldName), arg);
+ return new _InstanceMirror(arg);
+ }
+
+ InstanceMirror getField(Symbol fieldName) {
+ // TODO(ahe): This is extremely dangerous!!!
+ return new _InstanceMirror(JS('', r'$[#]', _n(fieldName)));
+ }
}
String _n(Symbol symbol) => _symbol_dev.Symbol.getName(symbol);
+Symbol _s(String name) {
+ if (name == null) return null;
+ return new _symbol_dev.Symbol.unvalidated(name);
+}
+
patch MirrorSystem currentMirrorSystem() => _currentMirrorSystem;
final _MirrorSystem _currentMirrorSystem = new _MirrorSystem();
@@ -32,11 +99,13 @@ patch InstanceMirror reflect(Object reflectee) {
final Expando<ClassMirror> _classMirrors = new Expando<ClassMirror>();
-patch ClassMirror reflectClass(Type key) => _reflectClass(key);
+patch ClassMirror reflectClass(Type key) => __reflectClass(key);
// TODO(ahe): This is a workaround for http://dartbug.com/10543
-ClassMirror _reflectClass(Type key) {
- String className = '$key';
+ClassMirror __reflectClass(Type key) => _reflectClass(_s('$key'), null);
+
+ClassMirror _reflectClass(Symbol symbol, String fields) {
+ String className = _n(symbol);
var constructor = Primitives.getConstructor(className);
if (constructor == null) {
// Probably an intercepted class.
@@ -45,13 +114,23 @@ ClassMirror _reflectClass(Type key) {
}
var mirror = _classMirrors[constructor];
if (mirror == null) {
- mirror = new _ClassMirror(className, constructor);
+ mirror = new _ClassMirror(symbol, constructor, fields);
_classMirrors[constructor] = mirror;
}
return mirror;
}
-class _InstanceMirror extends InstanceMirror {
+abstract class _ObjectMirror implements ObjectMirror {
+ Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) {
+ return new Future<InstanceMirror>(() => this.setField(fieldName, value));
+ }
+
+ Future<InstanceMirror> getFieldAsync(Symbol fieldName) {
+ return new Future<InstanceMirror>(() => this.getField(fieldName));
+ }
+}
+
+class _InstanceMirror extends _ObjectMirror implements InstanceMirror {
final reflectee;
@@ -59,7 +138,7 @@ class _InstanceMirror extends InstanceMirror {
bool get hasReflectee => true;
- ClassMirror get type => _reflectClass(reflectee.runtimeType);
+ ClassMirror get type => __reflectClass(reflectee.runtimeType);
Future<InstanceMirror> invokeAsync(Symbol memberName,
List<Object> positionalArguments,
@@ -98,10 +177,6 @@ class _InstanceMirror extends InstanceMirror {
return new _InstanceMirror(delegate(invocation));
}
- Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) {
- return new Future<InstanceMirror>(() => setField(fieldName, value));
- }
-
InstanceMirror setField(Symbol fieldName, Object arg) {
_invoke(
fieldName, JSInvocationMirror.SETTER, 'set\$${_n(fieldName)}', [arg]);
@@ -113,10 +188,6 @@ class _InstanceMirror extends InstanceMirror {
fieldName, JSInvocationMirror.GETTER, 'get\$${_n(fieldName)}', []);
}
- Future<InstanceMirror> getFieldAsync(Symbol fieldName) {
- return new Future<InstanceMirror>(() => getField(fieldName));
- }
-
delegate(Invocation invocation) {
return JSInvocationMirror.invokeFromMirror(invocation, reflectee);
}
@@ -124,12 +195,71 @@ class _InstanceMirror extends InstanceMirror {
String toString() => 'InstanceMirror($reflectee)';
}
-class _ClassMirror extends ClassMirror {
- final String _name;
+class _ClassMirror extends _ObjectMirror implements ClassMirror {
+ final Symbol simpleName;
final _jsConstructor;
+ final String _fields;
- _ClassMirror(this._name, this._jsConstructor) {
+ _ClassMirror(this.simpleName, this._jsConstructor, this._fields);
+
+ Map<Symbol, Mirror> get members {
+ var result = new Map<Symbol, Mirror>();
+ var s = _fields.split(";");
+ var fields = s[1] == "" ? [] : s[1].split(",");
+ for (String field in fields) {
+ _VariableMirror mirror = new _VariableMirror.from(field);
+ result[mirror.simpleName] = mirror;
+ }
+ return result;
}
- String toString() => 'ClassMirror($_name)';
+ InstanceMirror setField(Symbol fieldName, Object arg) {
+ // TODO(ahe): This is extremely dangerous!!!
+ JS('void', r'$[#] = #', '${_n(simpleName)}_${_n(fieldName)}', arg);
+ return new _InstanceMirror(arg);
+ }
+
+ InstanceMirror getField(Symbol fieldName) {
+ // TODO(ahe): This is extremely dangerous!!!
+ return new _InstanceMirror(
+ JS('', r'$[#]', '${_n(simpleName)}_${_n(fieldName)}'));
+ }
+
+ String toString() => 'ClassMirror(${_n(simpleName)})';
+}
+
+class _VariableMirror implements VariableMirror {
+ final Symbol simpleName;
+ final String _jsName;
+ final bool _readOnly;
+
+ _VariableMirror(this.simpleName, this._jsName, this._readOnly);
+
+ factory _VariableMirror.from(String descriptor) {
+ int length = descriptor.length;
+ var code = fieldCode(descriptor.codeUnitAt(length - 1));
+ if (code == 0) {
+ throw new RuntimeError('Bad field descriptor: $descriptor');
+ }
+ bool hasGetter = (code & 3) != 0;
+ bool hasSetter = (code >> 2) != 0;
+ String jsName;
+ String accessorName = jsName = descriptor.substring(0, length - 1);
+ int divider = descriptor.indexOf(":");
+ if (divider > 0) {
+ accessorName = accessorName.substring(0, divider);
+ jsName = accessorName.substring(divider + 1);
+ }
+ bool readOnly = hasSetter;
Johnni Winther 2013/05/23 20:21:59 Shouldn't it be [: readOnly = !hasSetter :] ?
ahe 2013/05/24 12:00:13 Fixed in CL 15895002.
+ return new _VariableMirror(_s(accessorName), jsName, readOnly);
+ }
+
+ TypeMirror get type => _MirrorSystem._dynamicType;
+
+ static int fieldCode(int code) {
+ if (code >= 60 && code <= 64) return code - 59;
+ if (code >= 123 && code <= 126) return code - 117;
+ if (code >= 37 && code <= 43) return code - 27;
+ return 0;
+ }
}
« no previous file with comments | « dart/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart ('k') | dart/tests/lib/mirrors/mirrors_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698