Files
sdk/runtime/lib/mirrors_impl.dart
T
Regis Crelier 7f57ebcfa1 Remove signature classes from the VM.
They were used as the class of closure instances and as the type class of
function types.
All closure instances now have class _Closure and function types are represented
by a new class FunctionType extending AbstractType.
Fix issue 24567 and add regression test.

R=asiva@google.com, rmacnak@google.com

Review URL: https://codereview.chromium.org/1584223006 .
2016-01-19 16:32:59 -08:00

1679 lines
51 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.
import "dart:collection" show UnmodifiableListView, UnmodifiableMapView;
import "dart:async" show Future;
var dirty = false;
final emptyList = new UnmodifiableListView([]);
final emptyMap = new UnmodifiableMapView({});
class _InternalMirrorError {
final String _msg;
const _InternalMirrorError(String this._msg);
String toString() => _msg;
}
String _n(Symbol symbol) => internal.Symbol.getName(symbol);
Symbol _s(String name) {
if (name == null) return null;
return new internal.Symbol.unvalidated(name);
}
Symbol _computeQualifiedName(DeclarationMirror owner, Symbol simpleName) {
if (owner == null) return simpleName;
return _s('${_n(owner.qualifiedName)}.${_n(simpleName)}');
}
String _makeSignatureString(TypeMirror returnType,
List<ParameterMirror> parameters) {
StringBuffer buf = new StringBuffer();
buf.write('(');
bool found_optional_positional = false;
bool found_optional_named = false;
for (int i = 0; i < parameters.length; i++) {
var param = parameters[i];
if (param.isOptional && param.isNamed && !found_optional_named) {
buf.write('{');
found_optional_named = true;
}
if (param.isOptional && !param.isNamed && !found_optional_positional) {
buf.write('[');
found_optional_positional = true;
}
if (param.isNamed) {
buf.write(_n(param.simpleName));
buf.write(': ');
}
buf.write(_n(param.type.qualifiedName));
if (i < (parameters.length - 1)) {
buf.write(', ');
}
}
if (found_optional_named) {
buf.write('}');
}
if (found_optional_positional) {
buf.write(']');
}
buf.write(') -> ');
buf.write(_n(returnType.qualifiedName));
return buf.toString();
}
SourceLocation _location(reflectee)
native "DeclarationMirror_location";
List _metadata(reflectee)
native 'DeclarationMirror_metadata';
bool _subtypeTest(Type a, Type b)
native 'TypeMirror_subtypeTest';
class _AccessorCacheAssociation {
String key;
Function value;
bool usedSinceGrowth = true;
_AccessorCacheAssociation(this.key, this.value);
}
/**
* A map that will grow as associations are added but will prefer to evict
* associations that have not been used since the last growth when needing to
* grow again. Implemented as an open addressing hash table.
*/
class _AccessorCache {
List table;
int shift;
int mask;
int capacity; // Max number of associations before we start evicting/growing.
int size = 0; // Current number of associations.
/**
* Create a cache whose capacity is 75% of 2^shift.
*/
_AccessorCache.withInitialShift(int shift) {
// The scheme used here for handling collisions relies on there always
// being at least one empty slot.
if (shift < 1) throw new Exception("_AccessorCache requires a shift >= 1");
initWithShift(shift);
}
void initWithShift(int shift) {
this.shift = shift;
this.mask = (1 << shift) - 1;
this.capacity = (1 << shift) * 3 ~/ 4;
this.table = new List(1 << shift);
assert(table.length > capacity);
}
int scanFor(String key) {
var start = key.hashCode & mask;
var index = start;
do {
var assoc = table[index];
if (null == assoc || assoc.key == key) {
return index;
}
index = (index + 1) & mask;
} while (index != start);
// Should never happen because we start evicting associations before the
// table is full.
throw new Exception("Internal error: _AccessorCache table full");
}
int scanForEmpty(String key) {
var start = key.hashCode & mask;
var index = start;
do {
if (null == table[index]) {
return index;
}
index = (index + 1) & mask;
} while (index != start);
// Should never happen because we start evicting associations before the
// table is full.
throw new Exception("Internal error: _AccessorCache table full");
}
void fixCollisionsAfter(int start) {
var assoc;
var index = (start + 1) & mask;
while (null != (assoc = table[index])) {
var newIndex = scanFor(assoc.key);
if (newIndex != index) {
assert(table[newIndex] == null);
table[newIndex] = assoc;
table[index] = null;
}
index = (index + 1) & mask;
}
}
void grow() {
var oldTable = table;
initWithShift(shift + 1);
for (int oldIndex = 0; oldIndex < oldTable.length; oldIndex++) {
var assoc = oldTable[oldIndex];
if (assoc != null) {
var newIndex = scanForEmpty(assoc.key);
assoc.usedSinceGrowth = false;
table[newIndex] = assoc;
}
}
}
void tryToShrinkOtherwiseGrow() {
// Remove any associations not accessed since the last growth. If we are
// unable to free any slots, grow.
bool needToGrow = true;
for (int i = 0; i < table.length; i++) {
var assoc = table[i];
if (null != assoc && (!assoc.usedSinceGrowth || null == assoc.value)) {
table[i] = null;
size--;
fixCollisionsAfter(i);
needToGrow = false;
}
}
if (needToGrow) grow();
}
operator []=(String key, Function value) {
int index = scanFor(key);
var assoc = table[index];
if (null != assoc) {
// Existing key, replace value.
assert(assoc.key == key);
assoc.value = value;
assoc.usedSinceGrowth = true;
} else {
// New key.
var newAssoc = new _AccessorCacheAssociation(key, value);
if (size == capacity) {
// No free slots.
tryToShrinkOtherwiseGrow();
index = scanFor(key);
assert(table[index] == null);
}
table[index] = newAssoc;
size++;
}
}
Function operator [](String key) {
var index = scanFor(key);
var assoc = table[index];
if (null == assoc) return null;
assoc.usedSinceGrowth = true;
return assoc.value;
}
}
class _LocalMirrorSystem extends MirrorSystem {
final TypeMirror dynamicType = new _SpecialTypeMirror('dynamic');
final TypeMirror voidType = new _SpecialTypeMirror('void');
var _libraries;
Map<Uri, LibraryMirror> get libraries {
if ((_libraries == null) || dirty) {
_libraries = new Map<Uri, LibraryMirror>.fromIterable(
_computeLibraries(), key: (e) => e.uri);
}
return _libraries;
}
static _computeLibraries() native "MirrorSystem_libraries";
var _isolate;
IsolateMirror get isolate {
if (_isolate == null) {
_isolate = _computeIsolate();
}
return _isolate;
}
static _computeIsolate() native "MirrorSystem_isolate";
String toString() => "MirrorSystem for isolate '${isolate.debugName}'";
}
class _SourceLocation implements SourceLocation {
_SourceLocation(uriString, this.line, this.column)
: this.sourceUri = Uri.parse(uriString);
// Line and column positions are 1-origin, or 0 if unknown.
final int line;
final int column;
final Uri sourceUri;
String toString() {
return column == 0 ? "$sourceUri:$line" : "$sourceUri:$line:$column";
}
}
abstract class _LocalMirror implements Mirror {}
class _LocalIsolateMirror extends _LocalMirror implements IsolateMirror {
final String debugName;
final LibraryMirror rootLibrary;
_LocalIsolateMirror(this.debugName, this.rootLibrary);
bool get isCurrent => true;
String toString() => "IsolateMirror on '$debugName'";
}
class _SyntheticAccessor implements MethodMirror {
final DeclarationMirror owner;
final Symbol simpleName;
final bool isGetter;
final bool isStatic;
final bool isTopLevel;
final _target;
_SyntheticAccessor(this.owner,
this.simpleName,
this.isGetter,
this.isStatic,
this.isTopLevel,
this._target);
bool get isSynthetic => true;
bool get isRegularMethod => false;
bool get isOperator => false;
bool get isConstructor => false;
bool get isConstConstructor => false;
bool get isGenerativeConstructor => false;
bool get isFactoryConstructor => false;
bool get isExternal => false;
bool get isRedirectingConstructor => false;
bool get isAbstract => false;
bool get isSetter => !isGetter;
bool get isPrivate => _n(simpleName).startsWith('_');
Symbol get qualifiedName => _computeQualifiedName(owner, simpleName);
Symbol get constructorName => const Symbol('');
TypeMirror get returnType => _target.type;
List<ParameterMirror> get parameters {
if (isGetter) return emptyList;
return new UnmodifiableListView(
[new _SyntheticSetterParameter(this, this._target)]);
}
SourceLocation get location => null;
List<InstanceMirror> get metadata => emptyList;
String get source => null;
}
class _SyntheticSetterParameter implements ParameterMirror {
final DeclarationMirror owner;
final VariableMirror _target;
_SyntheticSetterParameter(this.owner, this._target);
Symbol get simpleName => _target.simpleName;
Symbol get qualifiedName => _computeQualifiedName(owner, simpleName);
TypeMirror get type => _target.type;
bool get isOptional => false;
bool get isNamed => false;
bool get isStatic => false;
bool get isTopLevel => false;
bool get isConst => false;
bool get isFinal => true;
bool get isPrivate => false;
bool get hasDefaultValue => false;
InstanceMirror get defaultValue => null;
SourceLocation get location => null;
List<InstanceMirror> get metadata => emptyList;
}
abstract class _LocalObjectMirror extends _LocalMirror implements ObjectMirror {
final _reflectee; // May be a MirrorReference or an ordinary object.
_LocalObjectMirror(this._reflectee);
InstanceMirror invoke(Symbol memberName,
List positionalArguments,
[Map<Symbol, dynamic> namedArguments]) {
int numPositionalArguments = positionalArguments.length;
int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
int numArguments = numPositionalArguments + numNamedArguments;
List arguments = new List(numArguments);
arguments.setRange(0, numPositionalArguments, positionalArguments);
List names = new List(numNamedArguments);
int argumentIndex = numPositionalArguments;
int nameIndex = 0;
if (numNamedArguments > 0) {
namedArguments.forEach((name, value) {
arguments[argumentIndex++] = value;
names[nameIndex++] = _n(name);
});
}
return reflect(this._invoke(_reflectee, _n(memberName), arguments, names));
}
InstanceMirror getField(Symbol memberName) {
return reflect(this._invokeGetter(_reflectee, _n(memberName)));
}
InstanceMirror setField(Symbol memberName, Object value) {
this._invokeSetter(_reflectee, _n(memberName), value);
return reflect(value);
}
delegate(Invocation invocation) {
if (invocation.isMethod) {
return this.invoke(invocation.memberName,
invocation.positionalArguments,
invocation.namedArguments).reflectee;
}
if (invocation.isGetter) {
return this.getField(invocation.memberName).reflectee;
}
if (invocation.isSetter) {
var unwrapped = _n(invocation.memberName);
var withoutEqual = _s(unwrapped.substring(0, unwrapped.length - 1));
var arg = invocation.positionalArguments[0];
this.setField(withoutEqual, arg).reflectee;
return arg;
}
throw "UNREACHABLE";
}
}
class _LocalInstanceMirror extends _LocalObjectMirror
implements InstanceMirror {
_LocalInstanceMirror(reflectee) : super(reflectee);
ClassMirror _type;
ClassMirror get type {
if (_type == null) {
// Note it not safe to use reflectee.runtimeType because runtimeType may
// be overridden.
_type = reflectType(_computeType(reflectee));
}
return _type;
}
// LocalInstanceMirrors always reflect local instances
bool get hasReflectee => true;
get reflectee => _reflectee;
String toString() => 'InstanceMirror on ${Error.safeToString(_reflectee)}';
bool operator ==(other) {
return other is _LocalInstanceMirror &&
identical(_reflectee, other._reflectee);
}
int get hashCode {
// Avoid hash collisions with the reflectee. This constant is in Smi range
// and happens to be the inner padding from RFC 2104.
return identityHashCode(_reflectee) ^ 0x36363636;
}
static var _getFieldClosures = new _AccessorCache.withInitialShift(4);
static var _setFieldClosures = new _AccessorCache.withInitialShift(4);
_createGetterClosure(unwrapped) {
var atPosition = unwrapped.indexOf('@');
if (atPosition == -1) {
// Public symbol.
return _eval('(x) => x.$unwrapped', null);
} else {
// Private symbol.
var withoutKey = unwrapped.substring(0, atPosition);
var privateKey = unwrapped.substring(atPosition);
return _eval('(x) => x.$withoutKey', privateKey);
}
}
_getFieldSlow(unwrapped) {
// Slow path factored out to give the fast path a better chance at being
// inlined.
var result = reflect(_invokeGetter(_reflectee, unwrapped));
// Wait until success to avoid creating closures for non-existent getters,
// and defer the creation until the next getField invocation.
// o.<operator> is not valid Dart and will cause a compilation error, so
// don't attempt to generate such a closure.
bool isOperator = _LocalMethodMirror._operators.contains(unwrapped);
if (!isOperator) {
_getFieldClosures[unwrapped] = (receiver) {
var getterClosure = _createGetterClosure(unwrapped);
_getFieldClosures[unwrapped] = getterClosure;
return getterClosure(receiver);
};
}
return result;
}
InstanceMirror getField(Symbol memberName) {
var unwrapped = _n(memberName);
var f = _getFieldClosures[unwrapped];
return (f == null) ? _getFieldSlow(unwrapped) : reflect(f(_reflectee));
}
_createSetterClosure(unwrapped) {
var atPosition = unwrapped.indexOf('@');
if (atPosition == -1) {
// Public symbol.
return _eval('(x, v) => x.$unwrapped = v', null);
} else {
// Private symbol.
var withoutKey = unwrapped.substring(0, atPosition);
var privateKey = unwrapped.substring(atPosition);
return _eval('(x, v) => x.$withoutKey = v', privateKey);
}
}
_setFieldSlow(unwrapped, arg) {
// Slow path factored out to give the fast path a better chance at being
// inlined.
_invokeSetter(_reflectee, unwrapped, arg);
var result = reflect(arg);
// Wait until success to avoid creating closures for non-existent setters.
// and defer the creation until the next setField invocation.
_setFieldClosures[unwrapped] = (receiver, argument) {
var setterClosure = _createSetterClosure(unwrapped);
_setFieldClosures[unwrapped] = setterClosure;
return setterClosure(receiver, argument);
};
return result;
}
InstanceMirror setField(Symbol memberName, arg) {
var unwrapped = _n(memberName);
var f = _setFieldClosures[unwrapped];
return (f == null)
? _setFieldSlow(unwrapped, arg)
: reflect(f(_reflectee, arg));
}
static _eval(expression, privateKey)
native "Mirrors_evalInLibraryWithPrivateKey";
// Override to include the receiver in the arguments.
InstanceMirror invoke(Symbol memberName,
List positionalArguments,
[Map<Symbol, dynamic> namedArguments]) {
int numPositionalArguments = positionalArguments.length + 1; // Receiver.
int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
int numArguments = numPositionalArguments + numNamedArguments;
List arguments = new List(numArguments);
arguments[0] = _reflectee; // Receiver.
arguments.setRange(1, numPositionalArguments, positionalArguments);
List names = new List(numNamedArguments);
int argumentIndex = numPositionalArguments;
int nameIndex = 0;
if (numNamedArguments > 0) {
namedArguments.forEach((name, value) {
arguments[argumentIndex++] = value;
names[nameIndex++] = _n(name);
});
}
return reflect(this._invoke(_reflectee, _n(memberName), arguments, names));
}
_invoke(reflectee, functionName, arguments, argumentNames)
native 'InstanceMirror_invoke';
_invokeGetter(reflectee, getterName)
native 'InstanceMirror_invokeGetter';
_invokeSetter(reflectee, setterName, value)
native 'InstanceMirror_invokeSetter';
static _computeType(reflectee)
native 'InstanceMirror_computeType';
}
class _LocalClosureMirror extends _LocalInstanceMirror
implements ClosureMirror {
_LocalClosureMirror(reflectee) : super(reflectee);
MethodMirror _function;
MethodMirror get function {
if (_function == null) {
_function = _computeFunction(reflectee);
}
return _function;
}
InstanceMirror apply(List<Object> positionalArguments,
[Map<Symbol, Object> namedArguments]) {
return this.invoke(#call, positionalArguments, namedArguments);
}
String toString() => "ClosureMirror on '${Error.safeToString(_reflectee)}'";
static _computeFunction(reflectee)
native 'ClosureMirror_function';
}
class _LocalClassMirror extends _LocalObjectMirror
implements ClassMirror {
final Type _reflectedType;
Symbol _simpleName;
DeclarationMirror _owner;
final bool isAbstract;
final bool _isGeneric;
final bool _isMixinAlias;
final bool _isGenericDeclaration;
final bool isEnum;
Type _instantiator;
_LocalClassMirror(reflectee,
reflectedType,
String simpleName,
this._owner,
this.isAbstract,
this._isGeneric,
this._isMixinAlias,
this._isGenericDeclaration,
this.isEnum)
: this._simpleName = _s(simpleName),
this._reflectedType = reflectedType,
this._instantiator = reflectedType,
super(reflectee);
bool get hasReflectedType => !_isGenericDeclaration;
Type get reflectedType {
if (!hasReflectedType) {
throw new UnsupportedError(
"Declarations of generics have no reflected type");
}
return _reflectedType;
}
Symbol get simpleName {
// All but anonymous mixin applications have their name set at construction.
if(_simpleName == null) {
_simpleName = this._mixinApplicationName;
}
return _simpleName;
}
Symbol _qualifiedName = null;
Symbol get qualifiedName {
if (_qualifiedName == null) {
_qualifiedName = _computeQualifiedName(owner, simpleName);
}
return _qualifiedName;
}
DeclarationMirror get owner {
if (_owner == null) {
var uri = _LocalClassMirror._libraryUri(_reflectee);
_owner = currentMirrorSystem().libraries[Uri.parse(uri)];
}
return _owner;
}
bool get isPrivate => _n(simpleName).startsWith('_');
bool get isTopLevel => true;
SourceLocation get location {
return _location(_reflectee);
}
ClassMirror _trueSuperclassField;
ClassMirror get _trueSuperclass {
if (_trueSuperclassField == null) {
Type supertype = isOriginalDeclaration
? _supertype(_reflectedType)
: _supertypeInstantiated(_reflectedType);
if (supertype == null) {
// Object has no superclass.
return null;
}
_trueSuperclassField = reflectType(supertype);
_trueSuperclassField._instantiator = _instantiator;
}
return _trueSuperclassField;
}
ClassMirror get superclass {
return _isMixinAlias ? _trueSuperclass._trueSuperclass : _trueSuperclass;
}
var _superinterfaces;
List<ClassMirror> get superinterfaces {
if (_superinterfaces == null) {
_superinterfaces = isOriginalDeclaration
? _nativeInterfaces(_reflectedType)
: _nativeInterfacesInstantiated(_reflectedType);
_superinterfaces =
new UnmodifiableListView(_superinterfaces.map(reflectType));
}
return _superinterfaces;
}
get _mixinApplicationName {
var mixins = new List<ClassMirror>();
var klass = this;
while (_nativeMixin(klass._reflectedType) != null) {
mixins.add(klass.mixin);
klass = klass.superclass;
}
return _s(
_n(klass.qualifiedName)
+ ' with '
+ mixins.reversed.map((m)=>_n(m.qualifiedName)).join(', '));
}
var _mixin;
ClassMirror get mixin {
if (_mixin == null) {
if (_isMixinAlias) {
Type mixinType = _nativeMixinInstantiated(
_trueSuperclass._reflectedType, _instantiator);
_mixin = reflectType(mixinType);
} else {
Type mixinType = _nativeMixinInstantiated(_reflectedType,
_instantiator);
if (mixinType == null) {
// The reflectee is not a mixin application.
_mixin = this;
} else {
_mixin = reflectType(mixinType);
}
}
}
return _mixin;
}
var _cachedStaticMembers;
Map<Symbol, MethodMirror> get staticMembers {
if (_cachedStaticMembers == null) {
var result = new Map<Symbol, MethodMirror>();
declarations.values.forEach((decl) {
if (decl is MethodMirror && decl.isStatic && !decl.isConstructor) {
result[decl.simpleName] = decl;
}
if (decl is VariableMirror && decl.isStatic) {
var getterName = decl.simpleName;
result[getterName] =
new _SyntheticAccessor(this, getterName, true, true, false, decl);
if (!decl.isFinal) {
var setterName = _asSetter(decl.simpleName, this.owner);
result[setterName] = new _SyntheticAccessor(
this, setterName, false, true, false, decl);
}
}
});
_cachedStaticMembers =
new UnmodifiableMapView<Symbol, MethodMirror>(result);
}
return _cachedStaticMembers;
}
var _cachedInstanceMembers;
Map<Symbol, MethodMirror> get instanceMembers {
if (_cachedInstanceMembers == null) {
var result = new Map<Symbol, MethodMirror>();
if (superclass != null) {
result.addAll(superclass.instanceMembers);
}
declarations.values.forEach((decl) {
if (decl is MethodMirror && !decl.isStatic &&
!decl.isConstructor && !decl.isAbstract) {
result[decl.simpleName] = decl;
}
if (decl is VariableMirror && !decl.isStatic) {
var getterName = decl.simpleName;
result[getterName] =
new _SyntheticAccessor(this, getterName, true, false, false, decl);
if (!decl.isFinal) {
var setterName = _asSetter(decl.simpleName, this.owner);
result[setterName] = new _SyntheticAccessor(
this, setterName, false, false, false, decl);
}
}
});
_cachedInstanceMembers =
new UnmodifiableMapView<Symbol, MethodMirror>(result);
}
return _cachedInstanceMembers;
}
Map<Symbol, DeclarationMirror> _declarations;
Map<Symbol, DeclarationMirror> get declarations {
if (_declarations != null) return _declarations;
var decls = new Map<Symbol, DeclarationMirror>();
var whoseMembers = _isMixinAlias ? _trueSuperclass : this;
var members = mixin._computeMembers(_instantiator,
whoseMembers.mixin._reflectee);
for (var member in members) {
decls[member.simpleName] = member;
}
var constructors = _computeConstructors(_instantiator, _reflectee);
var stringName = _n(simpleName);
for (var constructor in constructors) {
constructor._patchConstructorName(stringName);
decls[constructor.simpleName] = constructor;
}
for (var typeVariable in typeVariables) {
decls[typeVariable.simpleName] = typeVariable;
}
return _declarations =
new UnmodifiableMapView<Symbol, DeclarationMirror>(decls);
}
bool get _isAnonymousMixinApplication {
if (_isMixinAlias) return false; // Named mixin application.
if (mixin == this) return false; // Not a mixin application.
return true;
}
List<TypeVariableMirror> _typeVariables = null;
List<TypeVariableMirror> get typeVariables {
if (_typeVariables == null) {
if (_isAnonymousMixinApplication) return _typeVariables = emptyList;
_typeVariables = new List<TypeVariableMirror>();
List params = _ClassMirror_type_variables(_reflectee);
ClassMirror owner = originalDeclaration;
var mirror;
for (var i = 0; i < params.length; i += 2) {
mirror = new _LocalTypeVariableMirror(
params[i + 1], params[i], owner);
_typeVariables.add(mirror);
}
_typeVariables = new UnmodifiableListView(_typeVariables);
}
return _typeVariables;
}
List<TypeMirror> _typeArguments = null;
List<TypeMirror> get typeArguments {
if(_typeArguments == null) {
if(_isGenericDeclaration || _isAnonymousMixinApplication) {
_typeArguments = emptyList;
} else {
_typeArguments =
new UnmodifiableListView(_computeTypeArguments(_reflectedType));
}
}
return _typeArguments;
}
bool get isOriginalDeclaration => !_isGeneric || _isGenericDeclaration;
ClassMirror get originalDeclaration {
if (isOriginalDeclaration) {
return this;
} else {
return reflectClass(_reflectedType);
}
}
String toString() => "ClassMirror on '${MirrorSystem.getName(simpleName)}'";
InstanceMirror newInstance(Symbol constructorName,
List positionalArguments,
[Map<Symbol, dynamic> namedArguments]) {
// Native code will add the 1 or 2 implicit arguments depending on whether
// we end up invoking a factory or constructor respectively.
int numPositionalArguments = positionalArguments.length;
int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
int numArguments = numPositionalArguments + numNamedArguments;
List arguments = new List(numArguments);
arguments.setRange(0, numPositionalArguments, positionalArguments);
List names = new List(numNamedArguments);
int argumentIndex = numPositionalArguments;
int nameIndex = 0;
if (numNamedArguments > 0) {
namedArguments.forEach((name, value) {
arguments[argumentIndex++] = value;
names[nameIndex++] = _n(name);
});
}
return reflect(_invokeConstructor(_reflectee,
_reflectedType,
_n(constructorName),
arguments,
names));
}
List<InstanceMirror> get metadata {
// Get the metadata objects, convert them into InstanceMirrors using
// reflect() and then make them into a Dart list.
return new UnmodifiableListView(_metadata(_reflectee).map(reflect));
}
bool operator ==(other) {
return this.runtimeType == other.runtimeType &&
this._reflectee == other._reflectee &&
this._reflectedType == other._reflectedType &&
this._isGenericDeclaration == other._isGenericDeclaration;
}
int get hashCode => simpleName.hashCode;
bool isSubtypeOf(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
return _subtypeTest(_reflectedType, other._reflectedType);
}
bool isAssignableTo(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
return _subtypeTest(_reflectedType, other._reflectedType)
|| _subtypeTest(other._reflectedType, _reflectedType);
}
bool isSubclassOf(ClassMirror other) {
if (other is! ClassMirror) throw new ArgumentError(other);
ClassMirror otherDeclaration = other.originalDeclaration;
ClassMirror c = this;
while (c != null) {
c = c.originalDeclaration;
if (c == otherDeclaration) return true;
c = c.superclass;
}
return false;
}
static _libraryUri(reflectee)
native "ClassMirror_libraryUri";
static _supertype(reflectedType)
native "ClassMirror_supertype";
static _supertypeInstantiated(reflectedType)
native "ClassMirror_supertype_instantiated";
static _nativeInterfaces(reflectedType)
native "ClassMirror_interfaces";
static _nativeInterfacesInstantiated(reflectedType)
native "ClassMirror_interfaces_instantiated";
static _nativeMixin(reflectedType)
native "ClassMirror_mixin";
static _nativeMixinInstantiated(reflectedType, instantiator)
native "ClassMirror_mixin_instantiated";
_computeMembers(reflectee, instantiator)
native "ClassMirror_members";
_computeConstructors(reflectee, instantiator)
native "ClassMirror_constructors";
_invoke(reflectee, memberName, arguments, argumentNames)
native 'ClassMirror_invoke';
_invokeGetter(reflectee, getterName)
native 'ClassMirror_invokeGetter';
_invokeSetter(reflectee, setterName, value)
native 'ClassMirror_invokeSetter';
static _invokeConstructor(reflectee, type, constructorName, arguments, argumentNames)
native 'ClassMirror_invokeConstructor';
static _ClassMirror_type_variables(reflectee)
native "ClassMirror_type_variables";
static _computeTypeArguments(reflectee)
native "ClassMirror_type_arguments";
}
class _LocalFunctionTypeMirror extends _LocalClassMirror
implements FunctionTypeMirror {
final _functionReflectee;
_LocalFunctionTypeMirror(reflectee, this._functionReflectee, reflectedType)
: super(reflectee, reflectedType, null, null, false, false, false, false, false);
bool get _isAnonymousMixinApplication => false;
// FunctionTypeMirrors have a simpleName generated from their signature.
Symbol _simpleName = null;
Symbol get simpleName {
if (_simpleName == null) {
_simpleName = _s(_makeSignatureString(returnType, parameters));
}
return _simpleName;
}
MethodMirror _callMethod;
MethodMirror get callMethod {
if (_callMethod == null) {
_callMethod = _FunctionTypeMirror_call_method(_functionReflectee);
}
return _callMethod;
}
TypeMirror _returnType = null;
TypeMirror get returnType {
if (_returnType == null) {
_returnType = reflectType(
_FunctionTypeMirror_return_type(_functionReflectee, _instantiator));
}
return _returnType;
}
List<ParameterMirror> _parameters = null;
List<ParameterMirror> get parameters {
if (_parameters == null) {
_parameters = _FunctionTypeMirror_parameters(_functionReflectee);
_parameters = new UnmodifiableListView(_parameters);
}
return _parameters;
}
bool get isOriginalDeclaration => true;
get originalDeclaration => this;
get typeVariables => emptyList;
get typeArguments => emptyList;
get metadata => emptyList;
get location => null;
String toString() => "FunctionTypeMirror on '${_n(simpleName)}'";
MethodMirror _FunctionTypeMirror_call_method(functionReflectee)
native "FunctionTypeMirror_call_method";
static Type _FunctionTypeMirror_return_type(functionReflectee, instantiator)
native "FunctionTypeMirror_return_type";
List<ParameterMirror> _FunctionTypeMirror_parameters(functionReflectee)
native "FunctionTypeMirror_parameters";
}
abstract class _LocalDeclarationMirror extends _LocalMirror
implements DeclarationMirror {
final _reflectee;
Symbol _simpleName;
_LocalDeclarationMirror(this._reflectee, this._simpleName);
Symbol get simpleName => _simpleName;
Symbol _qualifiedName = null;
Symbol get qualifiedName {
if (_qualifiedName == null) {
_qualifiedName = _computeQualifiedName(owner, simpleName);
}
return _qualifiedName;
}
bool get isPrivate => _n(simpleName).startsWith('_');
SourceLocation get location {
return _location(_reflectee);
}
List<InstanceMirror> get metadata {
// Get the metadata objects, convert them into InstanceMirrors using
// reflect() and then make them into a Dart list.
return new UnmodifiableListView(_metadata(_reflectee).map(reflect));
}
bool operator ==(other) {
return this.runtimeType == other.runtimeType &&
this._reflectee == other._reflectee;
}
int get hashCode => simpleName.hashCode;
}
class _LocalTypeVariableMirror extends _LocalDeclarationMirror
implements TypeVariableMirror {
_LocalTypeVariableMirror(reflectee,
String simpleName,
this._owner)
: super(reflectee, _s(simpleName));
DeclarationMirror _owner;
DeclarationMirror get owner {
if (_owner == null) {
_owner = _TypeVariableMirror_owner(_reflectee).originalDeclaration;
}
return _owner;
}
bool get isStatic => false;
bool get isTopLevel => false;
TypeMirror _upperBound = null;
TypeMirror get upperBound {
if (_upperBound == null) {
_upperBound = reflectType(_TypeVariableMirror_upper_bound(_reflectee));
}
return _upperBound;
}
bool get hasReflectedType => false;
Type get reflectedType {
throw new UnsupportedError('Type variables have no reflected type');
}
Type get _reflectedType => _reflectee;
List<TypeVariableMirror> get typeVariables => emptyList;
List<TypeMirror> get typeArguments => emptyList;
bool get isOriginalDeclaration => true;
TypeMirror get originalDeclaration => this;
String toString() => "TypeVariableMirror on '${_n(simpleName)}'";
operator ==(other) {
return other is TypeVariableMirror
&& simpleName == other.simpleName
&& owner == other.owner;
}
int get hashCode => simpleName.hashCode;
bool isSubtypeOf(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
return _subtypeTest(_reflectedType, other._reflectedType);
}
bool isAssignableTo(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
return _subtypeTest(_reflectedType, other._reflectedType)
|| _subtypeTest(other._reflectedType, _reflectedType);
}
static DeclarationMirror _TypeVariableMirror_owner(reflectee)
native "TypeVariableMirror_owner";
static Type _TypeVariableMirror_upper_bound(reflectee)
native "TypeVariableMirror_upper_bound";
}
class _LocalTypedefMirror extends _LocalDeclarationMirror
implements TypedefMirror {
final Type _reflectedType;
final bool _isGeneric;
final bool _isGenericDeclaration;
_LocalTypedefMirror(reflectee,
this._reflectedType,
String simpleName,
this._isGeneric,
this._isGenericDeclaration,
this._owner)
: super(reflectee, _s(simpleName));
bool get isTopLevel => true;
DeclarationMirror _owner;
DeclarationMirror get owner {
if (_owner == null) {
var uri = _LocalClassMirror._libraryUri(_reflectee);
_owner = currentMirrorSystem().libraries[Uri.parse(uri)];
}
return _owner;
}
TypeMirror _referent = null;
TypeMirror get referent {
if (_referent == null) {
_referent = _nativeReferent(_reflectedType);
_referent._instantiator = _reflectedType;
}
return _referent;
}
bool get hasReflectedType => !_isGenericDeclaration;
Type get reflectedType {
if (!hasReflectedType) {
throw new UnsupportedError(
"Declarations of generics have no reflected type");
}
return _reflectedType;
}
bool get isOriginalDeclaration => !_isGeneric || _isGenericDeclaration;
TypedefMirror get originalDeclaration {
if (isOriginalDeclaration) {
return this;
} else {
return _nativeDeclaration(_reflectedType);
}
}
List<TypeVariableMirror> _typeVariables = null;
List<TypeVariableMirror> get typeVariables {
if (_typeVariables == null) {
_typeVariables = new List<TypeVariableMirror>();
List params = _LocalClassMirror._ClassMirror_type_variables(_reflectee);
TypedefMirror owner = originalDeclaration;
var mirror;
for (var i = 0; i < params.length; i += 2) {
mirror = new _LocalTypeVariableMirror(
params[i + 1], params[i], owner);
_typeVariables.add(mirror);
}
}
return _typeVariables;
}
List<TypeMirror> _typeArguments = null;
List<TypeMirror> get typeArguments {
if(_typeArguments == null) {
if(_isGenericDeclaration) {
_typeArguments = emptyList;
} else {
_typeArguments = new UnmodifiableListView(
_LocalClassMirror._computeTypeArguments(_reflectedType));
}
}
return _typeArguments;
}
String toString() => "TypedefMirror on '${_n(simpleName)}'";
bool isSubtypeOf(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
return _subtypeTest(_reflectedType, other._reflectedType);
}
bool isAssignableTo(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
return _subtypeTest(_reflectedType, other._reflectedType)
|| _subtypeTest(other._reflectedType, _reflectedType);
}
static _nativeReferent(reflectedType)
native "TypedefMirror_referent";
static _nativeDeclaration(reflectedType)
native "TypedefMirror_declaration";
}
Symbol _asSetter(Symbol getter, LibraryMirror library) {
var unwrapped = MirrorSystem.getName(getter);
return MirrorSystem.getSymbol('${unwrapped}=', library);
}
class _LocalLibraryMirror extends _LocalObjectMirror implements LibraryMirror {
final Symbol simpleName;
final Uri uri;
_LocalLibraryMirror(reflectee,
String simpleName,
String url)
: this.simpleName = _s(simpleName),
this.uri = Uri.parse(url),
super(reflectee);
// The simple name and the qualified name are the same for a library.
Symbol get qualifiedName => simpleName;
DeclarationMirror get owner => null;
bool get isPrivate => false;
bool get isTopLevel => false;
Type get _instantiator => null;
Map<Symbol, DeclarationMirror> _declarations;
Map<Symbol, DeclarationMirror> get declarations {
if (_declarations != null) return _declarations;
var decls = new Map<Symbol, DeclarationMirror>();
var members = _computeMembers(_reflectee);
for (var member in members) {
decls[member.simpleName] = member;
}
return _declarations =
new UnmodifiableMapView<Symbol, DeclarationMirror>(decls);
}
SourceLocation get location {
return _location(_reflectee);
}
List<InstanceMirror> get metadata {
// Get the metadata objects, convert them into InstanceMirrors using
// reflect() and then make them into a Dart list.
return new UnmodifiableListView(_metadata(_reflectee).map(reflect));
}
bool operator ==(other) {
return this.runtimeType == other.runtimeType &&
this._reflectee == other._reflectee;
}
int get hashCode => simpleName.hashCode;
String toString() => "LibraryMirror on '${_n(simpleName)}'";
var _cachedLibraryDependencies;
get libraryDependencies {
if (_cachedLibraryDependencies == null) {
_cachedLibraryDependencies = _libraryDependencies(_reflectee);
}
return _cachedLibraryDependencies;
}
_libraryDependencies(reflectee)
native 'LibraryMirror_libraryDependencies';
_invoke(reflectee, memberName, arguments, argumentNames)
native 'LibraryMirror_invoke';
_invokeGetter(reflectee, getterName)
native 'LibraryMirror_invokeGetter';
_invokeSetter(reflectee, setterName, value)
native 'LibraryMirror_invokeSetter';
_computeMembers(reflectee)
native "LibraryMirror_members";
}
class _LocalLibraryDependencyMirror
extends _LocalMirror implements LibraryDependencyMirror {
final LibraryMirror sourceLibrary;
var _targetMirrorOrPrefix;
final List<CombinatorMirror> combinators;
final Symbol prefix;
final bool isImport;
final bool isDeferred;
final List<InstanceMirror> metadata;
_LocalLibraryDependencyMirror(this.sourceLibrary,
this._targetMirrorOrPrefix,
this.combinators,
prefixString,
this.isImport,
this.isDeferred,
unwrappedMetadata)
: prefix = _s(prefixString),
metadata = new UnmodifiableListView(unwrappedMetadata.map(reflect));
bool get isExport => !isImport;
LibraryMirror get targetLibrary {
if (_targetMirrorOrPrefix is _LocalLibraryMirror) {
return _targetMirrorOrPrefix;
}
var mirrorOrNull = _tryUpgradePrefix(_targetMirrorOrPrefix);
if (mirrorOrNull != null) {
_targetMirrorOrPrefix = mirrorOrNull;
}
return mirrorOrNull;
}
Future<LibraryMirror> loadLibrary() {
if (_targetMirrorOrPrefix is _LocalLibraryMirror) {
return new Future.value(_targetMirrorOrPrefix);
}
var savedPrefix = _targetMirrorOrPrefix;
return savedPrefix.loadLibrary().then((_) {
return _tryUpgradePrefix(savedPrefix);
});
}
static _tryUpgradePrefix(libraryPrefix) native "LibraryMirror_fromPrefix";
}
class _LocalCombinatorMirror extends _LocalMirror implements CombinatorMirror {
final List<Symbol> identifiers;
final bool isShow;
_LocalCombinatorMirror(identifierString, this.isShow)
: this.identifiers = [_s(identifierString)];
bool get isHide => !isShow;
}
class _LocalMethodMirror extends _LocalDeclarationMirror
implements MethodMirror {
final Type _instantiator;
final bool isStatic;
final int _kindFlags;
_LocalMethodMirror(reflectee,
String simpleName,
this._owner,
this._instantiator,
this.isStatic,
this._kindFlags)
: super(reflectee, _s(simpleName));
static const kAbstract = 0;
static const kGetter = 1;
static const kSetter = 2;
static const kConstructor = 3;
static const kConstCtor = 4;
static const kGenerativeCtor = 5;
static const kRedirectingCtor = 6;
static const kFactoryCtor = 7;
static const kExternal = 8;
// These offsets much be kept in sync with those in mirrors.h.
bool get isAbstract => 0 != (_kindFlags & (1 << kAbstract));
bool get isGetter => 0 != (_kindFlags & (1 << kGetter));
bool get isSetter => 0 != (_kindFlags & (1 << kSetter));
bool get isConstructor => 0 != (_kindFlags & (1 << kConstructor));
bool get isConstConstructor => 0 != (_kindFlags & (1 << kConstCtor));
bool get isGenerativeConstructor => 0 != (_kindFlags & (1 << kGenerativeCtor));
bool get isRedirectingConstructor => 0 != (_kindFlags & (1 << kRedirectingCtor));
bool get isFactoryConstructor => 0 != (_kindFlags & (1 << kFactoryCtor));
bool get isExternal => 0 != (_kindFlags & (1 << kExternal));
static const _operators = const ["%", "&", "*", "+", "-", "/", "<", "<<",
"<=", "==", ">", ">=", ">>", "[]", "[]=", "^", "|", "~", "unary-", "~/"];
bool get isOperator => _operators.contains(_n(simpleName));
DeclarationMirror _owner;
DeclarationMirror get owner {
// For nested closures it is possible, that the mirror for the owner has not
// been created yet.
if (_owner == null) {
_owner = _MethodMirror_owner(_reflectee, _instantiator);
}
return _owner;
}
bool get isPrivate => _n(simpleName).startsWith('_') ||
_n(constructorName).startsWith('_');
bool get isTopLevel => owner is LibraryMirror;
bool get isSynthetic => false;
TypeMirror _returnType = null;
TypeMirror get returnType {
if (_returnType == null) {
if (isConstructor) {
_returnType = owner;
} else {
_returnType = reflectType(
_MethodMirror_return_type(_reflectee, _instantiator));
}
}
return _returnType;
}
List<ParameterMirror> _parameters = null;
List<ParameterMirror> get parameters {
if (_parameters == null) {
_parameters = _MethodMirror_parameters(_reflectee);
_parameters = new UnmodifiableListView(_parameters);
}
return _parameters;
}
bool get isRegularMethod => !isGetter && !isSetter && !isConstructor;
Symbol _constructorName = null;
Symbol get constructorName {
if (_constructorName == null) {
if (!isConstructor) {
_constructorName = _s('');
} else {
var parts = MirrorSystem.getName(simpleName).split('.');
if (parts.length > 2) {
throw new _InternalMirrorError(
'Internal error in MethodMirror.constructorName: '
'malformed name <$simpleName>');
} else if (parts.length == 2) {
LibraryMirror definingLibrary = owner.owner;
_constructorName = MirrorSystem.getSymbol(parts[1], definingLibrary);
} else {
_constructorName = _s('');
}
}
}
return _constructorName;
}
String get source => _MethodMirror_source(_reflectee);
void _patchConstructorName(ownerName) {
var cn = _n(constructorName);
if (cn == '') {
_simpleName = _s(ownerName);
} else {
_simpleName = _s(ownerName + "." + cn);
}
}
String toString() => "MethodMirror on '${MirrorSystem.getName(simpleName)}'";
static dynamic _MethodMirror_owner(reflectee, instantiator)
native "MethodMirror_owner";
static dynamic _MethodMirror_return_type(reflectee, instantiator)
native "MethodMirror_return_type";
List<ParameterMirror> _MethodMirror_parameters(reflectee)
native "MethodMirror_parameters";
static String _MethodMirror_source(reflectee)
native "MethodMirror_source";
}
class _LocalVariableMirror extends _LocalDeclarationMirror
implements VariableMirror {
final DeclarationMirror owner;
final bool isStatic;
final bool isFinal;
final bool isConst;
_LocalVariableMirror(reflectee,
String simpleName,
this.owner,
this._type,
this.isStatic,
this.isFinal,
this.isConst)
: super(reflectee, _s(simpleName));
bool get isTopLevel => owner is LibraryMirror;
Type get _instantiator {
return owner._instantiator;
}
TypeMirror _type;
TypeMirror get type {
if (_type == null) {
_type = reflectType(_VariableMirror_type(_reflectee, _instantiator));
}
return _type;
}
String toString() => "VariableMirror on '${MirrorSystem.getName(simpleName)}'";
static _VariableMirror_type(reflectee, instantiator)
native "VariableMirror_type";
}
class _LocalParameterMirror extends _LocalVariableMirror
implements ParameterMirror {
final int _position;
final bool isOptional;
final bool isNamed;
final List _unmirroredMetadata;
_LocalParameterMirror(reflectee,
String simpleName,
DeclarationMirror owner,
this._position,
this.isOptional,
this.isNamed,
bool isFinal,
this._defaultValueReflectee,
this._unmirroredMetadata)
: super(reflectee,
simpleName,
owner,
null, // We override the type.
false, // isStatic does not apply.
isFinal,
false // Not const.
);
Object _defaultValueReflectee;
InstanceMirror _defaultValue;
InstanceMirror get defaultValue {
if (!isOptional) {
return null;
}
if (_defaultValue == null) {
_defaultValue = reflect(_defaultValueReflectee);
}
return _defaultValue;
}
bool get hasDefaultValue => _defaultValueReflectee != null;
SourceLocation get location {
throw new UnsupportedError("ParameterMirror.location unimplemented");
}
List<InstanceMirror> get metadata {
if (_unmirroredMetadata == null) return emptyList;
return new UnmodifiableListView(_unmirroredMetadata.map(reflect));
}
Type get _instantiator {
return owner._instantiator;
}
TypeMirror _type = null;
TypeMirror get type {
if (_type == null) {
_type = reflectType(
_ParameterMirror_type(_reflectee, _position, _instantiator));
}
return _type;
}
String toString() => "ParameterMirror on '${_n(simpleName)}'";
static Type _ParameterMirror_type(_reflectee, _position, instantiator)
native "ParameterMirror_type";
}
class _SpecialTypeMirror extends _LocalMirror
implements TypeMirror, DeclarationMirror {
final Symbol simpleName;
_SpecialTypeMirror(String name) : simpleName = _s(name);
bool get isPrivate => false;
bool get isTopLevel => true;
DeclarationMirror get owner => null;
SourceLocation get location => null;
List<InstanceMirror> get metadata => emptyList;
bool get hasReflectedType => simpleName == #dynamic;
Type get reflectedType {
if (simpleName == #dynamic) return dynamic;
throw new UnsupportedError("void has no reflected type");
}
List<TypeVariableMirror> get typeVariables => emptyList;
List<TypeMirror> get typeArguments => emptyList;
bool get isOriginalDeclaration => true;
TypeMirror get originalDeclaration => this;
Symbol get qualifiedName => simpleName;
bool operator ==(other) {
if (other is! _SpecialTypeMirror) {
return false;
}
return this.simpleName == other.simpleName;
}
int get hashCode => simpleName.hashCode;
String toString() => "TypeMirror on '${_n(simpleName)}'";
bool isSubtypeOf(TypeMirror other) {
return simpleName == #dynamic || other is _SpecialTypeMirror;
}
bool isAssignableTo(TypeMirror other) {
return simpleName == #dynamic || other is _SpecialTypeMirror;
}
}
class _Mirrors {
static MirrorSystem _currentMirrorSystem = new _LocalMirrorSystem();
static MirrorSystem currentMirrorSystem() {
return _currentMirrorSystem;
}
// Creates a new local mirror for some Object.
static InstanceMirror reflect(Object reflectee) {
return reflectee is Function
? new _LocalClosureMirror(reflectee)
: new _LocalInstanceMirror(reflectee);
}
static ClassMirror makeLocalClassMirror(Type key)
native "Mirrors_makeLocalClassMirror";
static TypeMirror makeLocalTypeMirror(Type key)
native "Mirrors_makeLocalTypeMirror";
static Expando<ClassMirror> _declarationCache = new Expando("ClassMirror");
static Expando<TypeMirror> _instantiationCache = new Expando("TypeMirror");
static ClassMirror reflectClass(Type key) {
var classMirror = _declarationCache[key];
if (classMirror == null) {
classMirror = makeLocalClassMirror(key);
_declarationCache[key] = classMirror;
if (!classMirror._isGeneric) {
_instantiationCache[key] = classMirror;
}
}
return classMirror;
}
static TypeMirror reflectType(Type key) {
var typeMirror = _instantiationCache[key];
if (typeMirror == null) {
typeMirror = makeLocalTypeMirror(key);
_instantiationCache[key] = typeMirror;
if (typeMirror is ClassMirror && !typeMirror._isGeneric) {
_declarationCache[key] = typeMirror;
}
}
return typeMirror;
}
}