75c8f427cc
R=floitsch@google.com BUG= Review URL: https://codereview.chromium.org//11827017 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@16840 260f80e4-7a28-3924-810f-c04153c831b5
974 lines
26 KiB
Dart
974 lines
26 KiB
Dart
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
// VM-specific implementation of the dart:mirrors library.
|
|
|
|
// These values are allowed to be passed directly over the wire.
|
|
bool _isSimpleValue(var value) {
|
|
return (value == null || value is num || value is String || value is bool);
|
|
}
|
|
|
|
Map _filterMap(Map old_map, bool filter(key, value)) {
|
|
Map new_map = new Map();
|
|
old_map.forEach((key, value) {
|
|
if (filter(key, value)) {
|
|
new_map[key] = value;
|
|
}
|
|
});
|
|
return new_map;
|
|
}
|
|
|
|
String _makeSignatureString(TypeMirror returnType,
|
|
List<ParameterMirror> parameters) {
|
|
StringBuffer buf = new StringBuffer();
|
|
buf.add(returnType.qualifiedName);
|
|
buf.add(' (');
|
|
bool found_optional_param = false;
|
|
for (int i = 0; i < parameters.length; i++) {
|
|
var param = parameters[i];
|
|
if (param.isOptional && !found_optional_param) {
|
|
buf.add('[');
|
|
found_optional_param = true;
|
|
}
|
|
buf.add(param.type.qualifiedName);
|
|
if (i < (parameters.length - 1)) {
|
|
buf.add(', ');
|
|
}
|
|
}
|
|
if (found_optional_param) {
|
|
buf.add(']');
|
|
}
|
|
buf.add(')');
|
|
return buf.toString();
|
|
}
|
|
|
|
class _LocalMirrorSystemImpl implements MirrorSystem {
|
|
_LocalMirrorSystemImpl(this.libraries, this.isolate)
|
|
: _functionTypes = new Map<String, FunctionTypeMirror>() {}
|
|
|
|
final Map<String, LibraryMirror> libraries;
|
|
final IsolateMirror isolate;
|
|
|
|
TypeMirror _dynamicType = null;
|
|
|
|
TypeMirror get dynamicType {
|
|
if (_dynamicType == null) {
|
|
_dynamicType =
|
|
new _LocalClassMirrorImpl(
|
|
null, 'Dynamic', false, null, null, [], null,
|
|
const {}, const {}, const {});
|
|
}
|
|
return _dynamicType;
|
|
}
|
|
|
|
TypeMirror _voidType = null;
|
|
|
|
TypeMirror get voidType {
|
|
if (_voidType == null) {
|
|
_voidType =
|
|
new _LocalClassMirrorImpl(
|
|
null, 'void', false, null, null, [], null,
|
|
const {}, const {}, const {});
|
|
}
|
|
return _voidType;
|
|
}
|
|
|
|
final Map<String, FunctionTypeMirror> _functionTypes;
|
|
FunctionTypeMirror _lookupFunctionTypeMirror(
|
|
TypeMirror returnType,
|
|
List<ParameterMirror> parameters) {
|
|
var sigString = _makeSignatureString(returnType, parameters);
|
|
var mirror = _functionTypes[sigString];
|
|
if (mirror == null) {
|
|
mirror = new _LocalFunctionTypeMirrorImpl(null,
|
|
sigString,
|
|
returnType,
|
|
parameters);
|
|
_functionTypes[sigString] = mirror;
|
|
}
|
|
return mirror;
|
|
}
|
|
|
|
String toString() => "MirrorSystem for isolate '${isolate.debugName}'";
|
|
}
|
|
|
|
abstract class _LocalMirrorImpl implements Mirror {
|
|
int get hashCode {
|
|
throw new UnimplementedError('Mirror.hashCode is not implemented');
|
|
}
|
|
|
|
// Local mirrors always return the same MirrorSystem. This field
|
|
// is more interesting once we implement remote mirrors.
|
|
MirrorSystem get mirrors => _Mirrors.currentMirrorSystem();
|
|
}
|
|
|
|
class _LocalIsolateMirrorImpl extends _LocalMirrorImpl
|
|
implements IsolateMirror {
|
|
_LocalIsolateMirrorImpl(this.debugName, this._rootLibrary) {}
|
|
|
|
final String debugName;
|
|
final bool isCurrent = true;
|
|
|
|
var _rootLibrary;
|
|
LibraryMirror get rootLibrary {
|
|
if (_rootLibrary is _LazyLibraryMirror) {
|
|
_rootLibrary = _rootLibrary.resolve(mirrors);
|
|
}
|
|
return _rootLibrary;
|
|
}
|
|
|
|
String toString() => "IsolateMirror on '$debugName'";
|
|
}
|
|
|
|
// A VMReference is used to hold a reference to a VM-internal object,
|
|
// which can include things like libraries, classes, etc.
|
|
class VMReference extends NativeFieldWrapperClass1 {
|
|
}
|
|
|
|
abstract class _LocalVMObjectMirrorImpl extends _LocalMirrorImpl {
|
|
_LocalVMObjectMirrorImpl(this._reference) {}
|
|
|
|
// For now, all VMObjects hold a VMReference. We could consider
|
|
// storing the Object reference itself here if the object is a Dart
|
|
// language objects (except for objects of type VMReference, of
|
|
// course).
|
|
VMReference _reference;
|
|
}
|
|
|
|
abstract class _LocalObjectMirrorImpl extends _LocalVMObjectMirrorImpl
|
|
implements ObjectMirror {
|
|
_LocalObjectMirrorImpl(ref) : super(ref) {}
|
|
|
|
Future<InstanceMirror> invoke(String memberName,
|
|
List positionalArguments,
|
|
[Map<String,dynamic> namedArguments]) {
|
|
if (namedArguments != null) {
|
|
throw new UnimplementedError(
|
|
'named argument support is not implemented');
|
|
}
|
|
// Walk the arguments and make sure they are legal.
|
|
for (int i = 0; i < positionalArguments.length; i++) {
|
|
var arg = positionalArguments[i];
|
|
_validateArgument(i, arg);
|
|
}
|
|
Completer<InstanceMirror> completer = new Completer<InstanceMirror>();
|
|
try {
|
|
completer.complete(
|
|
_invoke(this, memberName, positionalArguments));
|
|
} catch (exception, s) {
|
|
completer.completeError(exception, s);
|
|
}
|
|
return completer.future;
|
|
}
|
|
|
|
Future<InstanceMirror> getField(String fieldName)
|
|
{
|
|
Completer<InstanceMirror> completer = new Completer<InstanceMirror>();
|
|
try {
|
|
completer.complete(_getField(this, fieldName));
|
|
} catch (exception, s) {
|
|
completer.completeError(exception, s);
|
|
}
|
|
return completer.future;
|
|
}
|
|
|
|
Future<InstanceMirror> setField(String fieldName, Object arg)
|
|
{
|
|
_validateArgument(0, arg);
|
|
|
|
Completer<InstanceMirror> completer = new Completer<InstanceMirror>();
|
|
try {
|
|
completer.complete(_setField(this, fieldName, arg));
|
|
} catch (exception, s) {
|
|
completer.completeError(exception, s);
|
|
}
|
|
return completer.future;
|
|
}
|
|
|
|
static _validateArgument(int i, Object arg)
|
|
{
|
|
if (arg is Mirror) {
|
|
if (arg is! InstanceMirror) {
|
|
throw new MirrorException(
|
|
'positional argument $i ($arg) was not an InstanceMirror');
|
|
}
|
|
} else if (!_isSimpleValue(arg)) {
|
|
throw new MirrorException(
|
|
'positional argument $i ($arg) was not a simple value');
|
|
}
|
|
}
|
|
|
|
static _invoke(ref, memberName, positionalArguments)
|
|
native 'LocalObjectMirrorImpl_invoke';
|
|
|
|
static _getField(ref, fieldName)
|
|
native 'LocalObjectMirrorImpl_getField';
|
|
|
|
static _setField(ref, fieldName, value)
|
|
native 'LocalObjectMirrorImpl_setField';
|
|
}
|
|
|
|
// Prints a string as it might appear in dart program text.
|
|
// TODO(turnidge): Consider truncating.
|
|
String _dartEscape(String str) {
|
|
bool isNice(int code) => (code >= 32 && code <= 126);
|
|
|
|
StringBuffer buf = new StringBuffer();
|
|
for (int i = 0; i < str.length; i++) {
|
|
var input = str[i];
|
|
String output;
|
|
switch (input) {
|
|
case '\\' :
|
|
output = r'\\';
|
|
break;
|
|
case "\'" :
|
|
output = r"\'";
|
|
break;
|
|
case '\n' :
|
|
output = r'\n';
|
|
break;
|
|
case '\r' :
|
|
output = r'\r';
|
|
break;
|
|
case '\f' :
|
|
output = r'\f';
|
|
break;
|
|
case '\b' :
|
|
output = r'\b';
|
|
break;
|
|
case '\t' :
|
|
output = r'\t';
|
|
break;
|
|
case '\v' :
|
|
output = r'\v';
|
|
break;
|
|
default:
|
|
int code = input.charCodeAt(0);
|
|
if (isNice(code)) {
|
|
output = input;
|
|
} else {
|
|
output = '\\u{${code.toRadixString(16)}}';
|
|
}
|
|
break;
|
|
}
|
|
buf.add(output);
|
|
}
|
|
return buf.toString();
|
|
}
|
|
|
|
class _LocalInstanceMirrorImpl extends _LocalObjectMirrorImpl
|
|
implements InstanceMirror {
|
|
_LocalInstanceMirrorImpl(ref,
|
|
this._type,
|
|
this._reflectee) : super(ref) {}
|
|
|
|
var _type;
|
|
ClassMirror get type {
|
|
if (_type is! Mirror) {
|
|
_type = _type.resolve(mirrors);
|
|
}
|
|
return _type;
|
|
}
|
|
|
|
// LocalInstanceMirrors always reflect local instances
|
|
bool hasReflectee = true;
|
|
|
|
var _reflectee;
|
|
get reflectee => _reflectee;
|
|
|
|
String toString() {
|
|
if (_isSimpleValue(_reflectee)) {
|
|
if (_reflectee is String) {
|
|
return "InstanceMirror on <'${_dartEscape(_reflectee)}'>";
|
|
} else {
|
|
return "InstanceMirror on <$_reflectee>";
|
|
}
|
|
} else {
|
|
return "InstanceMirror on instance of '${type.simpleName}'";
|
|
}
|
|
}
|
|
}
|
|
|
|
class _LocalClosureMirrorImpl extends _LocalInstanceMirrorImpl
|
|
implements ClosureMirror {
|
|
_LocalClosureMirrorImpl(ref,
|
|
type,
|
|
reflectee,
|
|
this.function) : super(ref, type, reflectee) {}
|
|
|
|
final MethodMirror function;
|
|
|
|
String get source {
|
|
throw new UnimplementedError(
|
|
'ClosureMirror.source is not implemented');
|
|
}
|
|
|
|
Future<InstanceMirror> apply(List<Object> positionalArguments,
|
|
[Map<String,Object> namedArguments]) {
|
|
if (namedArguments != null) {
|
|
throw new UnimplementedError(
|
|
'named argument support is not implemented');
|
|
}
|
|
// Walk the arguments and make sure they are legal.
|
|
for (int i = 0; i < positionalArguments.length; i++) {
|
|
var arg = positionalArguments[i];
|
|
_LocalObjectMirrorImpl._validateArgument(i, arg);
|
|
}
|
|
Completer<InstanceMirror> completer = new Completer<InstanceMirror>();
|
|
try {
|
|
completer.complete(
|
|
_apply(this, positionalArguments));
|
|
} catch (exception) {
|
|
completer.completeError(exception);
|
|
}
|
|
return completer.future;
|
|
}
|
|
|
|
Future<InstanceMirror> findInContext(String name) {
|
|
throw new UnimplementedError(
|
|
'ClosureMirror.findInContext() is not implemented');
|
|
}
|
|
|
|
static _apply(ref, positionalArguments)
|
|
native 'LocalClosureMirrorImpl_apply';
|
|
}
|
|
|
|
class _LazyTypeMirror {
|
|
_LazyTypeMirror(this.libraryName, this.typeName) {}
|
|
|
|
TypeMirror resolve(MirrorSystem mirrors) {
|
|
if (libraryName == null) {
|
|
// TODO(turnidge): Remove support for 'Dynamic'.
|
|
if ((typeName == 'dynamic') || (typeName == 'Dynamic')) {
|
|
return mirrors.dynamicType;
|
|
} else if (typeName == 'void') {
|
|
return mirrors.voidType;
|
|
} else {
|
|
throw new UnimplementedError(
|
|
"Mirror for type '$typeName' is not implemented");
|
|
}
|
|
}
|
|
var resolved = mirrors.libraries[libraryName].members[typeName];
|
|
if (resolved == null) {
|
|
throw new UnimplementedError(
|
|
"Mirror for type '$typeName' is not implemented");
|
|
}
|
|
return resolved;
|
|
}
|
|
|
|
final String libraryName;
|
|
final String typeName;
|
|
}
|
|
|
|
class _LocalClassMirrorImpl extends _LocalObjectMirrorImpl
|
|
implements ClassMirror {
|
|
_LocalClassMirrorImpl(ref,
|
|
this.simpleName,
|
|
this.isClass,
|
|
this._owner,
|
|
this._superclass,
|
|
this._superinterfaces,
|
|
this._defaultFactory,
|
|
this.members,
|
|
this.constructors,
|
|
this.typeVariables) : super(ref) {}
|
|
|
|
final String simpleName;
|
|
|
|
String _qualifiedName = null;
|
|
String get qualifiedName {
|
|
if (_owner != null) {
|
|
if (_qualifiedName == null) {
|
|
_qualifiedName = '${owner.qualifiedName}.${simpleName}';
|
|
}
|
|
} else {
|
|
// The owner of a ClassMirror is null in certain odd cases, like
|
|
// 'void', 'Dynamic' and function type mirrors.
|
|
_qualifiedName = simpleName;
|
|
}
|
|
return _qualifiedName;
|
|
}
|
|
|
|
var _owner;
|
|
DeclarationMirror get owner {
|
|
if (_owner != null && _owner is! Mirror) {
|
|
_owner = _owner.resolve(mirrors);
|
|
}
|
|
return _owner;
|
|
}
|
|
|
|
bool get isPrivate => simpleName.startsWith('_');
|
|
|
|
final bool isTopLevel = true;
|
|
|
|
SourceLocation get location {
|
|
throw new UnimplementedError(
|
|
'ClassMirror.location is not implemented');
|
|
}
|
|
|
|
final bool isClass;
|
|
|
|
var _superclass;
|
|
ClassMirror get superclass {
|
|
if (_superclass is! Mirror) {
|
|
_superclass = _superclass.resolve(mirrors);
|
|
}
|
|
return _superclass;
|
|
}
|
|
|
|
var _superinterfaces;
|
|
List<ClassMirror> get superinterfaces {
|
|
if (_superinterfaces.length > 0 &&
|
|
_superinterfaces[0] is! Mirror) {
|
|
List<ClassMirror> resolved = new List<ClassMirror>();
|
|
for (int i = 0; i < _superinterfaces.length; i++) {
|
|
resolved.add(_superinterfaces[i].resolve(mirrors));
|
|
}
|
|
_superinterfaces = resolved;
|
|
}
|
|
return _superinterfaces;
|
|
}
|
|
|
|
var _defaultFactory;
|
|
ClassMirror get defaultFactory {
|
|
if (_defaultFactory != null && _defaultFactory is! Mirror) {
|
|
_defaultFactory = _defaultFactory.resolve(mirrors);
|
|
}
|
|
return _defaultFactory;
|
|
}
|
|
|
|
final Map<String, Mirror> members;
|
|
|
|
Map<String, MethodMirror> _methods = null;
|
|
Map<String, MethodMirror> _getters = null;
|
|
Map<String, MethodMirror> _setters = null;
|
|
Map<String, VariableMirror> _variables = null;
|
|
|
|
Map<String, MethodMirror> get methods {
|
|
if (_methods == null) {
|
|
_methods = _filterMap(
|
|
members,
|
|
(key, value) => (value is MethodMirror && value.isRegularMethod));
|
|
}
|
|
return _methods;
|
|
}
|
|
|
|
Map<String, MethodMirror> get getters {
|
|
if (_getters == null) {
|
|
_getters = _filterMap(
|
|
members,
|
|
(key, value) => (value is MethodMirror && value.isGetter));
|
|
}
|
|
return _getters;
|
|
}
|
|
|
|
Map<String, MethodMirror> get setters {
|
|
if (_setters == null) {
|
|
_setters = _filterMap(
|
|
members,
|
|
(key, value) => (value is MethodMirror && value.isSetter));
|
|
}
|
|
return _setters;
|
|
}
|
|
|
|
Map<String, VariableMirror> get variables {
|
|
if (_variables == null) {
|
|
_variables = _filterMap(
|
|
members,
|
|
(key, value) => (value is VariableMirror));
|
|
}
|
|
return _variables;
|
|
}
|
|
|
|
Map<String, MethodMirror> constructors;
|
|
Map<String, TypeVariableMirror> typeVariables;
|
|
|
|
Map<String, TypeMirror> get typeArguments {
|
|
throw new UnimplementedError(
|
|
'ClassMirror.typeArguments is not implemented');
|
|
}
|
|
|
|
bool get isOriginalDeclaration {
|
|
throw new UnimplementedError(
|
|
'ClassMirror.isOriginalDeclaration is not implemented');
|
|
}
|
|
|
|
ClassMirror get genericDeclaration {
|
|
throw new UnimplementedError(
|
|
'ClassMirror.originalDeclaration is not implemented');
|
|
}
|
|
|
|
String toString() => "ClassMirror on '$simpleName'";
|
|
|
|
Future<InstanceMirror> newInstance(String constructorName,
|
|
List positionalArguments,
|
|
[Map<String,dynamic> namedArguments]) {
|
|
if (namedArguments != null) {
|
|
throw new UnimplementedError(
|
|
'named argument support is not implemented');
|
|
}
|
|
// Walk the arguments and make sure they are legal.
|
|
for (int i = 0; i < positionalArguments.length; i++) {
|
|
var arg = positionalArguments[i];
|
|
_LocalObjectMirrorImpl._validateArgument(i, arg);
|
|
}
|
|
Completer<InstanceMirror> completer = new Completer<InstanceMirror>();
|
|
try {
|
|
completer.complete(
|
|
_invokeConstructor(this, constructorName, positionalArguments));
|
|
} catch (exception) {
|
|
completer.completeError(exception);
|
|
}
|
|
return completer.future;
|
|
}
|
|
|
|
static _invokeConstructor(ref, constructorName, positionalArguments)
|
|
native 'LocalClassMirrorImpl_invokeConstructor';
|
|
}
|
|
|
|
class _LazyFunctionTypeMirror {
|
|
_LazyFunctionTypeMirror(this.returnType, this.parameters) {}
|
|
|
|
ClassMirror resolve(MirrorSystem mirrors) {
|
|
return mirrors._lookupFunctionTypeMirror(returnType.resolve(mirrors),
|
|
parameters);
|
|
}
|
|
|
|
final returnType;
|
|
final List<ParameterMirror> parameters;
|
|
}
|
|
|
|
class _LocalFunctionTypeMirrorImpl extends _LocalClassMirrorImpl
|
|
implements FunctionTypeMirror {
|
|
_LocalFunctionTypeMirrorImpl(ref,
|
|
simpleName,
|
|
this._returnType,
|
|
this.parameters)
|
|
: super(ref,
|
|
simpleName,
|
|
true,
|
|
null,
|
|
new _LazyTypeMirror('dart:core', 'Object'),
|
|
[ new _LazyTypeMirror('dart:core', 'Function') ],
|
|
null,
|
|
const {},
|
|
const {},
|
|
const {});
|
|
|
|
var _returnType;
|
|
TypeMirror get returnType {
|
|
if (_returnType is! Mirror) {
|
|
_returnType = _returnType.resolve(mirrors);
|
|
}
|
|
return _returnType;
|
|
}
|
|
|
|
final List<ParameterMirror> parameters;
|
|
|
|
String toString() => "FunctionTypeMirror on '$simpleName'";
|
|
}
|
|
|
|
|
|
class _LazyTypeVariableMirror {
|
|
_LazyTypeVariableMirror(this._variableName, this._owner) {}
|
|
|
|
TypeVariableMirror resolve(MirrorSystem mirrors) {
|
|
ClassMirror owner = _owner.resolve(mirrors);
|
|
return owner.typeVariables[_variableName];
|
|
}
|
|
|
|
final String _variableName;
|
|
final _LazyTypeMirror _owner;
|
|
}
|
|
|
|
class _LocalTypeVariableMirrorImpl extends _LocalMirrorImpl
|
|
implements TypeVariableMirror {
|
|
_LocalTypeVariableMirrorImpl(this.simpleName,
|
|
this._owner,
|
|
this._upperBound) {}
|
|
final String simpleName;
|
|
|
|
String _qualifiedName = null;
|
|
String get qualifiedName {
|
|
if (_qualifiedName == null) {
|
|
_qualifiedName = '${owner.qualifiedName}.${simpleName}';
|
|
}
|
|
return _qualifiedName;
|
|
}
|
|
|
|
var _owner;
|
|
DeclarationMirror get owner {
|
|
if (_owner is! Mirror) {
|
|
_owner = _owner.resolve(mirrors);
|
|
}
|
|
return _owner;
|
|
}
|
|
|
|
bool get isPrivate => false;
|
|
|
|
final bool isTopLevel = false;
|
|
|
|
SourceLocation get location {
|
|
throw new UnimplementedError(
|
|
'TypeVariableMirror.location is not implemented');
|
|
}
|
|
|
|
var _upperBound;
|
|
TypeMirror get upperBound {
|
|
if (_upperBound is! Mirror) {
|
|
_upperBound = _upperBound.resolve(mirrors);
|
|
}
|
|
return _upperBound;
|
|
}
|
|
|
|
String toString() => "TypeVariableMirror on '$simpleName'";
|
|
}
|
|
|
|
|
|
class _LocalTypedefMirrorImpl extends _LocalMirrorImpl
|
|
implements TypedefMirror {
|
|
_LocalTypedefMirrorImpl(this.simpleName,
|
|
this._owner,
|
|
this._referent) {}
|
|
final String simpleName;
|
|
|
|
String _qualifiedName = null;
|
|
String get qualifiedName {
|
|
if (_qualifiedName == null) {
|
|
_qualifiedName = '${owner.qualifiedName}.${simpleName}';
|
|
}
|
|
return _qualifiedName;
|
|
}
|
|
|
|
var _owner;
|
|
DeclarationMirror get owner {
|
|
if (_owner is! Mirror) {
|
|
_owner = _owner.resolve(mirrors);
|
|
}
|
|
return _owner;
|
|
}
|
|
|
|
bool get isPrivate => false;
|
|
|
|
final bool isTopLevel = true;
|
|
|
|
SourceLocation get location {
|
|
throw new UnimplementedError(
|
|
'TypedefMirror.location is not implemented');
|
|
}
|
|
|
|
var _referent;
|
|
TypeMirror get referent {
|
|
if (_referent is! Mirror) {
|
|
_referent = _referent.resolve(mirrors);
|
|
}
|
|
return _referent;
|
|
}
|
|
|
|
String toString() => "TypedefMirror on '$simpleName'";
|
|
}
|
|
|
|
|
|
class _LazyLibraryMirror {
|
|
_LazyLibraryMirror(this.libraryName) {}
|
|
|
|
LibraryMirror resolve(MirrorSystem mirrors) {
|
|
return mirrors.libraries[libraryName];
|
|
}
|
|
|
|
final String libraryName;
|
|
}
|
|
|
|
class _LocalLibraryMirrorImpl extends _LocalObjectMirrorImpl
|
|
implements LibraryMirror {
|
|
_LocalLibraryMirrorImpl(ref,
|
|
this.simpleName,
|
|
this.url,
|
|
this.members) : super(ref) {}
|
|
|
|
final String simpleName;
|
|
|
|
// The simple name and the qualified name are the same for a library.
|
|
String get qualifiedName => simpleName;
|
|
|
|
// Always null for libraries.
|
|
final DeclarationMirror owner = null;
|
|
|
|
// Always false for libraries.
|
|
final bool isPrivate = false;
|
|
|
|
// Always false for libraries.
|
|
final bool isTopLevel = false;
|
|
|
|
SourceLocation get location {
|
|
throw new UnimplementedError(
|
|
'LibraryMirror.location is not implemented');
|
|
}
|
|
|
|
final String url;
|
|
final Map<String, Mirror> members;
|
|
|
|
Map<String, ClassMirror> _classes = null;
|
|
Map<String, MethodMirror> _functions = null;
|
|
Map<String, MethodMirror> _getters = null;
|
|
Map<String, MethodMirror> _setters = null;
|
|
Map<String, VariableMirror> _variables = null;
|
|
|
|
Map<String, ClassMirror> get classes {
|
|
if (_classes == null) {
|
|
_classes = _filterMap(members,
|
|
(key, value) => (value is ClassMirror));
|
|
}
|
|
return _classes;
|
|
}
|
|
|
|
Map<String, MethodMirror> get functions {
|
|
if (_functions == null) {
|
|
_functions = _filterMap(members,
|
|
(key, value) => (value is MethodMirror));
|
|
}
|
|
return _functions;
|
|
}
|
|
|
|
Map<String, MethodMirror> get getters {
|
|
if (_getters == null) {
|
|
_getters = _filterMap(functions,
|
|
(key, value) => (value.isGetter));
|
|
}
|
|
return _getters;
|
|
}
|
|
|
|
Map<String, MethodMirror> get setters {
|
|
if (_setters == null) {
|
|
_setters = _filterMap(functions,
|
|
(key, value) => (value.isSetter));
|
|
}
|
|
return _setters;
|
|
}
|
|
|
|
Map<String, VariableMirror> get variables {
|
|
if (_variables == null) {
|
|
_variables = _filterMap(members,
|
|
(key, value) => (value is VariableMirror));
|
|
}
|
|
return _variables;
|
|
}
|
|
|
|
String toString() => "LibraryMirror on '$simpleName'";
|
|
}
|
|
|
|
class _LocalMethodMirrorImpl extends _LocalMirrorImpl
|
|
implements MethodMirror {
|
|
_LocalMethodMirrorImpl(this.simpleName,
|
|
this._owner,
|
|
this.parameters,
|
|
this._returnType,
|
|
this.isStatic,
|
|
this.isAbstract,
|
|
this.isGetter,
|
|
this.isSetter,
|
|
this.isConstructor,
|
|
this.isConstConstructor,
|
|
this.isGenerativeConstructor,
|
|
this.isRedirectingConstructor,
|
|
this.isFactoryConstructor) {}
|
|
|
|
final String simpleName;
|
|
|
|
String _qualifiedName = null;
|
|
String get qualifiedName {
|
|
if (_qualifiedName == null) {
|
|
_qualifiedName = '${owner.qualifiedName}.${simpleName}';
|
|
}
|
|
return _qualifiedName;
|
|
}
|
|
|
|
var _owner;
|
|
DeclarationMirror get owner {
|
|
if (_owner is! Mirror) {
|
|
_owner = _owner.resolve(mirrors);
|
|
}
|
|
return _owner;
|
|
}
|
|
|
|
bool get isPrivate {
|
|
return simpleName.startsWith('_') || constructorName.startsWith('_');
|
|
}
|
|
|
|
bool get isTopLevel => owner is LibraryMirror;
|
|
|
|
SourceLocation get location {
|
|
throw new UnimplementedError(
|
|
'MethodMirror.location is not implemented');
|
|
}
|
|
|
|
var _returnType;
|
|
TypeMirror get returnType {
|
|
if (_returnType is! Mirror) {
|
|
_returnType = _returnType.resolve(mirrors);
|
|
}
|
|
return _returnType;
|
|
}
|
|
|
|
final List<ParameterMirror> parameters;
|
|
|
|
final bool isStatic;
|
|
final bool isAbstract;
|
|
|
|
bool get isRegularMethod => !isGetter && !isSetter && !isConstructor;
|
|
|
|
TypeMirror get isOperator {
|
|
throw new UnimplementedError(
|
|
'MethodMirror.isOperator is not implemented');
|
|
}
|
|
|
|
final bool isGetter;
|
|
final bool isSetter;
|
|
final bool isConstructor;
|
|
|
|
var _constructorName = null;
|
|
String get constructorName {
|
|
if (_constructorName == null) {
|
|
if (!isConstructor) {
|
|
_constructorName = '';
|
|
} else {
|
|
var parts = simpleName.split('.');
|
|
if (parts.length > 2) {
|
|
throw new MirrorException(
|
|
'Internal error in MethodMirror.constructorName: '
|
|
'malformed name <$simpleName>');
|
|
} else if (parts.length == 2) {
|
|
_constructorName = parts[1];
|
|
} else {
|
|
_constructorName = '';
|
|
}
|
|
}
|
|
}
|
|
return _constructorName;
|
|
}
|
|
|
|
final bool isConstConstructor;
|
|
final bool isGenerativeConstructor;
|
|
final bool isRedirectingConstructor;
|
|
final bool isFactoryConstructor;
|
|
|
|
String toString() => "MethodMirror on '$simpleName'";
|
|
}
|
|
|
|
class _LocalVariableMirrorImpl extends _LocalMirrorImpl
|
|
implements VariableMirror {
|
|
_LocalVariableMirrorImpl(this.simpleName,
|
|
this._owner,
|
|
this._type,
|
|
this.isStatic,
|
|
this.isFinal) {}
|
|
|
|
final String simpleName;
|
|
|
|
String _qualifiedName = null;
|
|
String get qualifiedName {
|
|
if (_qualifiedName == null) {
|
|
_qualifiedName = '${owner.qualifiedName}.${simpleName}';
|
|
}
|
|
return _qualifiedName;
|
|
}
|
|
|
|
var _owner;
|
|
DeclarationMirror get owner {
|
|
if (_owner is! Mirror) {
|
|
_owner = _owner.resolve(mirrors);
|
|
}
|
|
return _owner;
|
|
}
|
|
|
|
bool get isPrivate {
|
|
return simpleName.startsWith('_');
|
|
}
|
|
|
|
bool get isTopLevel {
|
|
return owner is LibraryMirror;
|
|
}
|
|
|
|
SourceLocation get location {
|
|
throw new UnimplementedError(
|
|
'VariableMirror.location is not implemented');
|
|
}
|
|
|
|
var _type;
|
|
TypeMirror get type {
|
|
if (_type is! Mirror) {
|
|
_type = _type.resolve(mirrors);
|
|
}
|
|
return _type;
|
|
}
|
|
|
|
final bool isStatic;
|
|
final bool isFinal;
|
|
|
|
String toString() => "VariableMirror on '$simpleName'";
|
|
}
|
|
|
|
class _LocalParameterMirrorImpl extends _LocalVariableMirrorImpl
|
|
implements ParameterMirror {
|
|
_LocalParameterMirrorImpl(type, this.isOptional)
|
|
: super('<TODO:unnamed>', null, type, false, false) {}
|
|
|
|
final bool isOptional;
|
|
|
|
String get defaultValue {
|
|
throw new UnimplementedError(
|
|
'ParameterMirror.defaultValue is not implemented');
|
|
}
|
|
|
|
bool get hasDefaultValue {
|
|
throw new UnimplementedError(
|
|
'ParameterMirror.hasDefaultValue is not implemented');
|
|
}
|
|
}
|
|
|
|
class _Mirrors {
|
|
// Does a port refer to our local isolate?
|
|
static bool isLocalPort(SendPort port) native 'Mirrors_isLocalPort';
|
|
|
|
static MirrorSystem _currentMirrorSystem = null;
|
|
|
|
// Creates a new local MirrorSystem.
|
|
static MirrorSystem makeLocalMirrorSystem()
|
|
native 'Mirrors_makeLocalMirrorSystem';
|
|
|
|
// The MirrorSystem for the current isolate.
|
|
static MirrorSystem currentMirrorSystem() {
|
|
if (_currentMirrorSystem == null) {
|
|
_currentMirrorSystem = makeLocalMirrorSystem();
|
|
}
|
|
return _currentMirrorSystem;
|
|
}
|
|
|
|
static Future<MirrorSystem> mirrorSystemOf(SendPort port) {
|
|
Completer<MirrorSystem> completer = new Completer<MirrorSystem>();
|
|
if (isLocalPort(port)) {
|
|
// Make a local mirror system.
|
|
try {
|
|
completer.complete(currentMirrorSystem());
|
|
} catch (exception) {
|
|
completer.completeError(exception);
|
|
}
|
|
} else {
|
|
// Make a remote mirror system
|
|
throw new UnimplementedError(
|
|
'Remote mirror support is not implemented');
|
|
}
|
|
return completer.future;
|
|
}
|
|
|
|
// Creates a new local InstanceMirror
|
|
static InstanceMirror makeLocalInstanceMirror(Object reflectee)
|
|
native 'Mirrors_makeLocalInstanceMirror';
|
|
|
|
// Creates a new local mirror for some Object.
|
|
static InstanceMirror reflect(Object reflectee) {
|
|
return makeLocalInstanceMirror(reflectee);
|
|
}
|
|
}
|