// 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; final emptyList = new UnmodifiableListView([]); final emptyMap = new UnmodifiableMapView({}); class _InternalMirrorError { final String _msg; const _InternalMirrorError(String this._msg); String toString() => _msg; } Map _filterMap(Map old_map, bool filter(Symbol key, value)) { Map new_map = new Map(); old_map.forEach((key, value) { if (filter(key, value)) { new_map[key] = value; } }); return new UnmodifiableMapView(new_map); } Map _makeMemberMap(List mirrors) { return new UnmodifiableMapView( new Map.fromIterable( mirrors, key: (e) => e.simpleName)); } 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); } Symbol _computeQualifiedName(DeclarationMirror owner, Symbol simpleName) { if (owner == null) return simpleName; return _s('${_n(owner.qualifiedName)}.${_n(simpleName)}'); } String _makeSignatureString(TypeMirror returnType, List 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(); } List _metadata(reflectee) native 'DeclarationMirror_metadata'; bool _subtypeTest(Type a, Type b) native 'TypeMirror_subtypeTest'; bool _moreSpecificTest(Type a, Type b) native 'TypeMirror_moreSpecificTest'; 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 Map libraries; final IsolateMirror isolate; _LocalMirrorSystem(List libraries, this.isolate) : this.libraries = new Map.fromIterable( libraries, key: (e) => e.uri); TypeMirror _dynamicType = null; TypeMirror get dynamicType { if (_dynamicType == null) { _dynamicType = new _SpecialTypeMirror('dynamic'); } return _dynamicType; } TypeMirror _voidType = null; TypeMirror get voidType { if (_voidType == null) { _voidType = new _SpecialTypeMirror('void'); } return _voidType; } 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 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 get parameters { if (isGetter) return emptyList; return new UnmodifiableListView( [new _SyntheticSetterParameter(this, this._target)]); } List get metadata => emptyList; String get source => null; SourceLocation get location => 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; List get metadata => emptyList; SourceLocation get location => throw new UnimplementedError(); } 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 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); } } 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 hasReflectee = true; get reflectee => _reflectee; 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"; } 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. _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 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 positionalArguments, [Map 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; Type _instantiator; _LocalClassMirror(reflectee, reflectedType, String simpleName, this._owner, this.isAbstract, this._isGeneric, this._isMixinAlias, this._isGenericDeclaration) : 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) { _owner = _library(_reflectee); } return _owner; } bool get isPrivate => _n(simpleName).startsWith('_'); final bool isTopLevel = true; SourceLocation get location { throw new UnimplementedError('ClassMirror.location is not implemented'); } 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 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(); 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 get staticMembers { if (_cachedStaticMembers == null) { var result = new Map(); 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(result); } return _cachedStaticMembers; } var _cachedInstanceMembers; Map get instanceMembers { if (_cachedInstanceMembers == null) { var result = new Map(); 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(result); } return _cachedInstanceMembers; } Map _declarations; Map get declarations { if (_declarations != null) return _declarations; var decls = new Map(); decls.addAll(_members); decls.addAll(_constructors); typeVariables.forEach((tv) => decls[tv.simpleName] = tv); return _declarations = new UnmodifiableMapView(decls); } Map _cachedMembers; Map get _members { if (_cachedMembers == null) { var whoseMembers = _isMixinAlias ? _trueSuperclass : this; _cachedMembers = _makeMemberMap(mixin._computeMembers(whoseMembers.mixin._reflectee)); } return _cachedMembers; } Map _cachedMethods; Map get _methods { if (_cachedMethods == null) { _cachedMethods = _filterMap( _members, (key, value) => (value is MethodMirror && value.isRegularMethod)); } return _cachedMethods; } Map _cachedConstructors; Map get _constructors { if (_cachedConstructors == null) { var constructorsList = _computeConstructors(_reflectee); var stringName = _n(simpleName); constructorsList.forEach((c) => c._patchConstructorName(stringName)); _cachedConstructors = new Map.fromIterable(constructorsList, key: (e) => e.simpleName); } return _cachedConstructors; } bool get _isAnonymousMixinApplication { if (_isMixinAlias) return false; // Named mixin application. if (mixin == this) return false; // Not a mixin application. return true; } List _typeVariables = null; List get typeVariables { if (_typeVariables == null) { if (_isAnonymousMixinApplication) return _typeVariables = emptyList; _typeVariables = new List(); 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 _typeArguments = null; List 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 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 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 _moreSpecificTest(_reflectedType, other._reflectedType) || _moreSpecificTest(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 _library(reflectee) native "ClassMirror_library"; 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) native "ClassMirror_members"; _computeConstructors(reflectee) 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 { _LocalFunctionTypeMirror(reflectee, reflectedType) : super(reflectee, reflectedType, null, null, 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 = this._FunctionTypeMirror_call_method(_reflectee); } return _callMethod; } TypeMirror _returnType = null; TypeMirror get returnType { if (_returnType == null) { _returnType = reflectType( _FunctionTypeMirror_return_type(_reflectee, _instantiator)); } return _returnType; } List _parameters = null; List get parameters { if (_parameters == null) { _parameters = _FunctionTypeMirror_parameters(_reflectee); _parameters = new UnmodifiableListView(_parameters); } return _parameters; } bool get isOriginalDeclaration => true; get originalDeclaration => this; get typeVariables => emptyList; get typeArguments => emptyList; get metadata => emptyList; Map get members => emptyMap; Map get constructors => emptyMap; String toString() => "FunctionTypeMirror on '${_n(simpleName)}'"; MethodMirror _FunctionTypeMirror_call_method(reflectee) native "FunctionTypeMirror_call_method"; static Type _FunctionTypeMirror_return_type(reflectee, instantiator) native "FunctionTypeMirror_return_type"; List _FunctionTypeMirror_parameters(reflectee) 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('_'); List 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; SourceLocation get location { throw new UnimplementedError( 'TypeVariableMirror.location is not implemented'); } 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 get typeVariables => emptyList; List 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 _moreSpecificTest(_reflectedType, other._reflectedType) || _moreSpecificTest(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) { _owner = _LocalClassMirror._library(_reflectee); } return _owner; } SourceLocation get location { throw new UnimplementedError('TypedefMirror.location is not implemented'); } 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 _typeVariables = null; List get typeVariables { if (_typeVariables == null) { _typeVariables = new List(); 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 _typeArguments = null; List 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 _moreSpecificTest(_reflectedType, other._reflectedType) || _moreSpecificTest(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; SourceLocation get location { throw new UnimplementedError('LibraryMirror.location is not implemented'); } Map _declarations; Map get declarations { if (_declarations != null) return _declarations; return _declarations = new UnmodifiableMapView(_members); } Map _cachedMembers; Map get _members { if (_cachedMembers == null) { _cachedMembers = _makeMemberMap(_computeMembers(_reflectee)); } return _cachedMembers; } List 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; final LibraryMirror targetLibrary; final List combinators; final Symbol prefix; final bool isImport; final List metadata; _LocalLibraryDependencyMirror(this.sourceLibrary, this.targetLibrary, this.combinators, prefixString, this.isImport, unwrappedMetadata) : prefix = _s(prefixString), metadata = new UnmodifiableListView(unwrappedMetadata.map(reflect)); bool get isExport => !isImport; } class _LocalCombinatorMirror extends _LocalMirror implements CombinatorMirror { final List identifiers; final bool isShow; _LocalCombinatorMirror(identifierString, this.isShow) : this.identifiers = [_s(identifierString)]; bool get isHide => !isShow; } class _LocalMethodMirror extends _LocalDeclarationMirror implements MethodMirror { final bool isStatic; final bool isAbstract; final bool isGetter; final bool isSetter; final bool isConstructor; final bool isConstConstructor; final bool isGenerativeConstructor; final bool isRedirectingConstructor; final bool isFactoryConstructor; final bool isOperator; static const _operators = const ["%", "&", "*", "+", "-", "/", "<", "<<", "<=", "==", ">", ">=", ">>", "[]", "[]=", "^", "|", "~", "unary-", "~/"]; _LocalMethodMirror(reflectee, String simpleName, this._owner, this.isStatic, this.isAbstract, this.isGetter, this.isSetter, this.isConstructor, this.isConstConstructor, this.isGenerativeConstructor, this.isRedirectingConstructor, this.isFactoryConstructor) : this.isOperator = _operators.contains(simpleName), super(reflectee, _s(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); } return _owner; } bool get isPrivate => _n(simpleName).startsWith('_') || _n(constructorName).startsWith('_'); bool get isTopLevel => owner is LibraryMirror; bool get isSynthetic => false; SourceLocation _location; SourceLocation get location { if (_location == null) { _location = _MethodMirror_location(_reflectee); } return _location; } Type get _instantiator { var o = owner; while (o is MethodMirror) o = o.owner; return o._instantiator; } TypeMirror _returnType = null; TypeMirror get returnType { if (_returnType == null) { if (isConstructor) { _returnType = owner; } else { _returnType = reflectType( _MethodMirror_return_type(_reflectee, _instantiator)); } } return _returnType; } List _parameters = null; List 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 _source = null; String get source { if (_source == null) { _source = _MethodMirror_source(_reflectee); } return _source; } 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) native "MethodMirror_owner"; static dynamic _MethodMirror_return_type(reflectee, instantiator) native "MethodMirror_return_type"; List _MethodMirror_parameters(reflectee) native "MethodMirror_parameters"; static String _MethodMirror_source(reflectee) native "MethodMirror_source"; static SourceLocation _MethodMirror_location(reflectee) native "MethodMirror_location"; } 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; SourceLocation get location { throw new UnimplementedError('VariableMirror.location is not implemented'); } 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; List get metadata { if (_unmirroredMetadata == null) return emptyList; return new UnmodifiableListView(_unmirroredMetadata.map(reflect)); } Type get _instantiator { var o = owner; while (o is MethodMirror) o = o.owner; return o._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; List 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 get typeVariables => emptyList; List get typeArguments => emptyList; bool get isOriginalDeclaration => true; TypeMirror get originalDeclaration => this; SourceLocation get location { throw new UnimplementedError('TypeMirror.location is not implemented'); } Symbol get qualifiedName => simpleName; // TODO(11955): Remove once dynamicType and voidType are canonical objects in // the object store. 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 = 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; } // 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 _declarationCache = new Expando("ClassMirror"); static Expando _instanitationCache = new Expando("TypeMirror"); static ClassMirror reflectClass(Type key) { var classMirror = _declarationCache[key]; if (classMirror == null) { classMirror = makeLocalClassMirror(key); _declarationCache[key] = classMirror; if (!classMirror._isGeneric) { _instanitationCache[key] = classMirror; } } return classMirror; } static TypeMirror reflectType(Type key) { var typeMirror = _instanitationCache[key]; if (typeMirror == null) { typeMirror = makeLocalTypeMirror(key); _instanitationCache[key] = typeMirror; if (typeMirror is ClassMirror && !typeMirror._isGeneric) { _declarationCache[key] = typeMirror; } } return typeMirror; } }