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

Unified Diff: pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart

Issue 2535273002: Better mirrors support for mixins and private fields (Closed)
Patch Set: Address comments Created 4 years, 1 month 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
« no previous file with comments | « pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart b/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart
index 6c985d79c0e830447fad5f0e16ff962a5dc0013e..856009661428ad901676bb45967c5ab67bbcd2e4 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart
@@ -71,71 +71,108 @@ dynamic _defaultConstructorType(type) {
return JS('', '#.definiteFunctionType(#, [])', _dart, type);
}
+dynamic _getMixins(type) {
+ return JS('', '#.getMixins(#, [])', _dart, type);
+}
+
typedef T _Lazy<T>();
+dynamic _getESSymbol(Symbol symbol) =>
+ _internal.Symbol.getNativeSymbol(symbol as _internal.Symbol);
+
+dynamic _getMember(Symbol symbol) {
+ var privateSymbol = _getESSymbol(symbol);
+ if (privateSymbol != null) {
+ return privateSymbol;
+ }
+ return getName(symbol);
+}
+
String _getNameForESSymbol(member) {
// Convert private JS symbol "Symbol(_foo)" to string "_foo".
+ assert(JS('bool', 'typeof # == "symbol"', member));
var str = member.toString();
assert(str.startsWith('Symbol(') && str.endsWith(')'));
return str.substring(7, str.length - 1);
}
-Map _toDartMap(data) {
+Symbol _getSymbolForESSymbol(member) {
+ var name = _getNameForESSymbol(member);
+ return new _internal.Symbol.es6(name, member);
+}
+
+// The [member] must be either a string (public) or an ES6 symbol (private).
+Symbol _getSymbolForMember(member) {
+ if (member is String) {
+ return new Symbol(member);
+ } else {
+ var name = _getNameForESSymbol(member);
+ return new _internal.Symbol.es6(name, member);
+ }
+}
+
+Map<Symbol, dynamic> _toDartMap(data) {
if (data == null) return {};
- var map = JS('Map', '#.map(#)', _dart, data);
+ var map = new Map<Symbol, dynamic>();
// Note: we recorded a map from fields/methods to their type and metadata.
// The key is a string name for public members but an ES6 symbol for private
// ones. That's works nicely for dynamic operations, but dart:mirrors expects
- // strings, so we convert back here.
+ // Dart symbols, so we convert here.
+ var publicMembers = JS('', 'Object.getOwnPropertyNames(#)', data);
+ for (var member in publicMembers) {
+ var symbol = new Symbol(member);
+ map[symbol] = JS('', '#[#]', data, member);
+ }
+
var privateMembers = JS('', 'Object.getOwnPropertySymbols(#)', data);
for (var member in privateMembers) {
- var name = _getNameForESSymbol(member);
- map[name] = JS('', '#[#]', data, member);
+ var symbol = _getSymbolForESSymbol(member);
+ map[symbol] = JS('', '#[#]', data, member);
}
return map;
}
-Map _getConstructors(obj) {
+Map<Symbol, dynamic> _getConstructors(obj) {
List sig = JS('', '#.getConstructorSig(#)', _dart, obj);
return _toDartMap(sig);
}
-Map _getFields(obj) {
+Map<Symbol, dynamic> _getFields(obj) {
List sig = JS('', '#.getFieldSig(#)', _dart, obj);
return _toDartMap(sig);
}
-Map _getMethods(obj) {
+Map<Symbol, dynamic> _getMethods(obj) {
List sig = JS('', '#.getMethodSig(#)', _dart, obj);
return _toDartMap(sig);
}
-Map _getGetters(obj) {
+Map<Symbol, dynamic> _getGetters(obj) {
List sig = JS('', '#.getGetterSig(#)', _dart, obj);
return _toDartMap(sig);
}
-Map _getSetters(obj) {
+Map<Symbol, dynamic> _getSetters(obj) {
List sig = JS('', '#.getSetterSig(#)', _dart, obj);
return _toDartMap(sig);
}
-Map _getStaticFields(obj) {
+Map<Symbol, dynamic> _getStaticFields(obj) {
List sig = JS('', '#.getStaticFieldSig(#)', _dart, obj);
return _toDartMap(sig);
}
-Map _getStatics(obj) {
+Map<Symbol, dynamic> _getStatics(obj) {
List sig = JS('', '#.getStaticSig(#)', _dart, obj);
return _toDartMap(sig);
}
-Map _getStaticGetters(obj) {
+Map<Symbol, dynamic> _getStaticGetters(obj) {
List sig = JS('', '#.getStaticGetterSig(#)', _dart, obj);
return _toDartMap(sig);
}
-Map _getStaticSetters(obj) {
+Map<Symbol, dynamic> _getStaticSetters(obj) {
List sig = JS('', '#.getStaticSetterSig(#)', _dart, obj);
return _toDartMap(sig);
}
@@ -211,21 +248,7 @@ class JsInstanceMirror extends JsObjectMirror implements InstanceMirror {
// Returns a String for public members or an ES6 symbol for private members.
_getAccessor(dynamic reflectee, Symbol symbol, [List<dynamic> args,
Map<Symbol, dynamic> namedArgs]) {
- var name = getName(symbol);
- if (!name.startsWith('_')) return name;
-
- // TODO(vsm): Ideally, we'd record ES6 symbols properly during codegen if
- // mirrors is enabled. Here, we're trying to recover it from the receiver
- // instead.
- //
- // Get private fields and members. Members are on proto.
- var privateMembers = JS('', 'Object.getOwnPropertySymbols(#)', reflectee)
- ..addAll(JS('', 'Object.getOwnPropertySymbols(#.__proto__)', reflectee));
- for (var member in privateMembers) {
- var privateName = _getNameForESSymbol(member);
- if (name == privateName) return member;
- }
- return new NoSuchMethodError(reflectee, symbol, args, namedArgs);
+ return _getMember(symbol);
}
InstanceMirror getField(Symbol symbol) {
@@ -275,7 +298,7 @@ class JsClassMirror extends JsMirror implements ClassMirror {
final dynamic _raw;
// TODO(vsm): Do this properly
- final ClassMirror mixin = null;
+ ClassMirror _mixin = null;
List<TypeMirror> _typeArguments;
List<InstanceMirror> _metadata;
@@ -305,67 +328,67 @@ class JsClassMirror extends JsMirror implements ClassMirror {
_declarations = new Map<Symbol, DeclarationMirror>();
var unwrapped = _unwrap(_cls);
var constructors = _getConstructors(unwrapped);
- constructors.forEach((String name, ft) {
- var symbol = new Symbol(name);
- _declarations[symbol] = new JsMethodMirror._constructor(this, name, ft);
+ constructors.forEach((symbol, ft) {
+ var name = getName(symbol);
+ _declarations[symbol] = new JsMethodMirror._constructor(this, symbol, ft);
});
if (constructors.isEmpty) {
// Add a default
var name = 'new';
var ft = _defaultConstructorType(_unwrap(_cls));
var symbol = new Symbol(name);
- _declarations[symbol] = new JsMethodMirror._constructor(this, name, ft);
+ _declarations[symbol] = new JsMethodMirror._constructor(this, symbol, ft);
}
var fields = _getFields(unwrapped);
- fields.forEach((String name, t) {
- var symbol = new Symbol(name);
+ fields.forEach((symbol, t) {
var metadata = [];
if (t is List) {
metadata = t.skip(1).toList();
t = t[0];
}
- _declarations[symbol] = new JsVariableMirror._(name, _wrap(t), metadata);
+ _declarations[symbol] = new JsVariableMirror._(symbol, _wrap(t), metadata);
});
var methods = _getMethods(unwrapped);
- methods.forEach((String name, ft) {
- var symbol = new Symbol(name);
- _declarations[symbol] = new JsMethodMirror._instanceMethod(this, name, ft);
+ methods.forEach((symbol, ft) {
+ var name = getName(symbol);
+ _declarations[symbol] = new JsMethodMirror._instanceMethod(this, symbol, ft);
});
var getters = _getGetters(unwrapped);
- getters.forEach((String name, ft) {
- var symbol = new Symbol(name);
- _declarations[symbol] = new JsMethodMirror._instanceMethod(this, name, ft);
+ getters.forEach((symbol, ft) {
+ var name = getName(symbol);
+ _declarations[symbol] = new JsMethodMirror._instanceMethod(this, symbol, ft);
});
var setters = _getSetters(unwrapped);
- setters.forEach((String name, ft) {
- name += '=';
- var symbol = new Symbol(name);
- _declarations[symbol] = new JsMethodMirror._instanceMethod(this, name, ft);
+ setters.forEach((symbol, ft) {
+ var name = getName(symbol) + '=';
+ // Create a separate symbol for the setter.
+ symbol = new _internal.Symbol.es6(name, _getESSymbol(symbol));
+ _declarations[symbol] = new JsMethodMirror._instanceMethod(this, symbol, ft);
});
var staticFields = _getStaticFields(unwrapped);
- staticFields.forEach((String name, t) {
- var symbol = new Symbol(name);
+ staticFields.forEach((symbol, t) {
+ var name = getName(symbol);
var metadata = [];
if (t is List) {
metadata = t.skip(1).toList();
t = t[0];
}
- _declarations[symbol] = new JsVariableMirror._(name, _wrap(t), metadata);
+ _declarations[symbol] = new JsVariableMirror._(symbol, _wrap(t), metadata);
});
var statics = _getStatics(unwrapped);
- statics.forEach((String name, ft) {
- var symbol = new Symbol(name);
- _declarations[symbol] = new JsMethodMirror._staticMethod(this, name, ft);
+ statics.forEach((symbol, ft) {
+ var name = getName(symbol);
+ _declarations[symbol] = new JsMethodMirror._staticMethod(this, symbol, ft);
});
var staticGetters = _getStaticGetters(unwrapped);
- staticGetters.forEach((String name, ft) {
- var symbol = new Symbol(name);
- _declarations[symbol] = new JsMethodMirror._staticMethod(this, name, ft);
+ staticGetters.forEach((symbol, ft) {
+ var name = getName(symbol);
+ _declarations[symbol] = new JsMethodMirror._staticMethod(this, symbol, ft);
});
var staticSetters = _getStaticSetters(unwrapped);
- staticSetters.forEach((String name, ft) {
- var symbol = new Symbol(name);
- _declarations[symbol] = new JsMethodMirror._staticMethod(this, name, ft);
+ staticSetters.forEach((symbol, ft) {
+ var name = getName(symbol);
+ _declarations[symbol] = new JsMethodMirror._staticMethod(this, symbol, ft);
});
_declarations = new Map<Symbol, DeclarationMirror>.unmodifiable(_declarations);
}
@@ -455,23 +478,44 @@ class JsClassMirror extends JsMirror implements ClassMirror {
}
}
+ ClassMirror get mixin {
+ if (_mixin != null) {
+ return _mixin;
+ }
+ var mixins = _getMixins(_unwrap(_cls));
+ if (mixins == null || mixins.isEmpty) {
+ // If there is no mixin, return this mirror per API.
+ _mixin = this;
+ return _mixin;
+ }
+ if (mixins.length > 1) {
+ throw new UnsupportedError("ClassMirror.mixin not yet supported for "
+ "classes ($_cls) with multiple mixins");
+ }
+ _mixin = reflectType(_wrap(mixins[0]));
+ return _mixin;
+ }
+
String toString() => "ClassMirror on '$_cls'";
}
class JsVariableMirror extends JsMirror implements VariableMirror {
+ final Symbol _symbol;
final String _name;
final TypeMirror type;
final List<InstanceMirror> metadata;
// TODO(vsm): Refactor this out.
- Symbol get simpleName => new Symbol(_name);
+ Symbol get simpleName => _symbol;
// TODO(vsm): Fix this
final bool isStatic = false;
final bool isFinal = false;
- JsVariableMirror._(this._name, Type t, List annotations)
- : type = reflectType(t),
+ JsVariableMirror._(Symbol symbol, Type t, List annotations)
+ : _symbol = symbol,
+ _name = getName(symbol),
+ type = reflectType(t),
metadata = new List<InstanceMirror>.unmodifiable(
annotations.map((a) => reflect(a)));
@@ -479,14 +523,14 @@ class JsVariableMirror extends JsMirror implements VariableMirror {
}
class JsParameterMirror extends JsVariableMirror implements ParameterMirror {
- JsParameterMirror._(String name, Type t, List annotations)
- : super._(name, t, annotations);
+ JsParameterMirror._(Symbol member, Type t, List annotations)
+ : super._(member, t, annotations);
String toString() => "ParameterMirror on '$_name'";
}
class JsMethodMirror extends JsMirror implements MethodMirror {
- // TODO(vsm): This could be a JS symbol for private methods
+ final Symbol _symbol;
final String _name;
List<ParameterMirror> _params;
List<InstanceMirror> _metadata;
@@ -499,25 +543,25 @@ class JsMethodMirror extends JsMirror implements MethodMirror {
bool get isPrivate => _name.startsWith('_');
// TODO(vsm): Refactor this out.
- Symbol get simpleName => new Symbol(_name);
+ Symbol get simpleName => _symbol;
- JsMethodMirror._constructor(JsClassMirror cls, String name, ftype)
- : _name = name, isConstructor = true, isStatic = false {
+ JsMethodMirror._constructor(JsClassMirror cls, Symbol symbol, ftype)
+ : _symbol = symbol, _name = getName(symbol), isConstructor = true, isStatic = false {
_createParameterMirrorList(ftype);
}
- JsMethodMirror._instanceMethod(JsClassMirror cls, String name, ftype)
- : _name = name, isConstructor = false, isStatic = false {
+ JsMethodMirror._instanceMethod(JsClassMirror cls, Symbol symbol, ftype)
+ : _symbol = symbol, _name = getName(symbol), isConstructor = false, isStatic = false {
_createParameterMirrorList(ftype);
}
- JsMethodMirror._staticMethod(JsClassMirror cls, String name, ftype)
- : _name = name, isConstructor = false, isStatic = true {
+ JsMethodMirror._staticMethod(JsClassMirror cls, Symbol symbol, ftype)
+ : _symbol = symbol, _name = getName(symbol), isConstructor = false, isStatic = true {
_createParameterMirrorList(ftype);
}
// TODO(vsm): Support named constructors.
- Symbol get constructorName => isConstructor ? new Symbol(_name) : null;
+ Symbol get constructorName => isConstructor ? _symbol : null;
List<ParameterMirror> get parameters => _params;
List<InstanceMirror> get metadata => _metadata;
@@ -556,7 +600,7 @@ class JsMethodMirror extends JsMirror implements MethodMirror {
var type = args[i];
var metadata = ftype.metadata[i];
// TODO(vsm): Recover the param name.
- var param = new JsParameterMirror._('', _wrap(type), metadata);
+ var param = new JsParameterMirror._(new Symbol(''), _wrap(type), metadata);
params[i] = param;
}
@@ -564,7 +608,7 @@ class JsMethodMirror extends JsMirror implements MethodMirror {
var type = opts[i];
var metadata = ftype.metadata[args.length + i];
// TODO(vsm): Recover the param name.
- var param = new JsParameterMirror._('', _wrap(type), metadata);
+ var param = new JsParameterMirror._(new Symbol(''), _wrap(type), metadata);
params[i + args.length] = param;
}
« no previous file with comments | « pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698