platform/angel_container/lib/src/mirrors/reflector.dart

205 lines
5.9 KiB
Dart

import 'dart:mirrors' as dart;
import 'package:angel_container/angel_container.dart';
import 'package:angel_container/src/reflector.dart';
/// A [Reflector] implementation that forwards to `dart:mirrors`.
///
/// Useful on the server, where reflection is supported.
class MirrorsReflector implements Reflector {
const MirrorsReflector();
@override
String getName(Symbol symbol) => dart.MirrorSystem.getName(symbol);
@override
ReflectedClass reflectClass(Type clazz) {
var mirror = dart.reflectType(clazz);
if (mirror is dart.ClassMirror) {
return new _ReflectedClassMirror(mirror);
} else {
throw new ArgumentError('$clazz is not a class.');
}
}
@override
ReflectedFunction reflectFunction(Function function) {
var closure = dart.reflect(function) as dart.ClosureMirror;
return new _ReflectedMethodMirror(closure.function);
}
@override
ReflectedType reflectType(Type type) {
var mirror = dart.reflectType(type);
if (!mirror.hasReflectedType) {
return reflectType(dynamic);
} else {
if (mirror is dart.ClassMirror) {
return new _ReflectedClassMirror(mirror);
} else {
return new _ReflectedTypeMirror(mirror);
}
}
}
@override
ReflectedInstance reflectInstance(Object object) {
return new _ReflectedInstanceMirror(object);
}
}
class _ReflectedTypeParameter extends ReflectedTypeParameter {
final dart.TypeVariableMirror mirror;
_ReflectedTypeParameter(this.mirror)
: super(dart.MirrorSystem.getName(mirror.simpleName));
}
class _ReflectedTypeMirror extends ReflectedType {
final dart.TypeMirror mirror;
_ReflectedTypeMirror(this.mirror)
: super(
dart.MirrorSystem.getName(mirror.simpleName),
mirror.typeVariables
.map((m) => new _ReflectedTypeParameter(m))
.toList(),
mirror.reflectedType,
);
@override
bool isAssignableTo(ReflectedType other) {
return other is _ReflectedTypeMirror && mirror.isAssignableTo(other.mirror);
}
@override
T newInstance<T>(String constructorName, List positionalArguments,
[Map<String, dynamic> namedArguments, List<Type> typeArguments]) {
throw new ReflectionException(
'$name is not a class, and therefore cannot be instantiated.');
}
}
class _ReflectedClassMirror extends ReflectedClass {
final dart.ClassMirror mirror;
_ReflectedClassMirror(this.mirror)
: super(
dart.MirrorSystem.getName(mirror.simpleName),
mirror.typeVariables
.map((m) => new _ReflectedTypeParameter(m))
.toList(),
[],
[],
_declarationsOf(mirror),
mirror.reflectedType,
);
static List<ReflectedFunction> _constructorsOf(dart.ClassMirror mirror) {
var out = <ReflectedFunction>[];
for (var key in mirror.declarations.keys) {
var value = mirror.declarations[key];
if (value is dart.MethodMirror && value.isConstructor) {
out.add(new _ReflectedMethodMirror(value));
}
}
return out;
}
static List<ReflectedDeclaration> _declarationsOf(dart.ClassMirror mirror) {
var out = <ReflectedDeclaration>[];
for (var key in mirror.declarations.keys) {
var value = mirror.declarations[key];
if (value is dart.MethodMirror && !value.isConstructor) {
out.add(new _ReflectedDeclarationMirror(
dart.MirrorSystem.getName(key), value));
}
}
return out;
}
@override
List<ReflectedInstance> get annotations =>
mirror.metadata.map((m) => new _ReflectedInstanceMirror(m)).toList();
@override
List<ReflectedFunction> get constructors => _constructorsOf(mirror);
@override
bool isAssignableTo(ReflectedType other) {
return other is _ReflectedTypeMirror && mirror.isAssignableTo(other.mirror);
}
@override
T newInstance<T>(String constructorName, List positionalArguments,
[Map<String, dynamic> namedArguments, List<Type> typeArguments]) {
return mirror
.newInstance(new Symbol(constructorName), positionalArguments)
.reflectee as T;
}
}
class _ReflectedDeclarationMirror extends ReflectedDeclaration {
final String name;
final dart.MethodMirror mirror;
_ReflectedDeclarationMirror(this.name, this.mirror)
: super(name, mirror.isStatic, null);
@override
bool get isStatic => mirror.isStatic;
@override
ReflectedFunction get function => new _ReflectedMethodMirror(mirror);
}
class _ReflectedInstanceMirror extends ReflectedInstance {
final dart.InstanceMirror mirror;
_ReflectedInstanceMirror(this.mirror)
: super(new _ReflectedClassMirror(mirror.type),
new _ReflectedClassMirror(mirror.type), mirror.reflectee);
@override
T invoke<T>(Invocation invocation) {
return mirror.delegate(invocation) as T;
}
}
class _ReflectedMethodMirror extends ReflectedFunction {
final dart.MethodMirror mirror;
_ReflectedMethodMirror(this.mirror)
: super(
dart.MirrorSystem.getName(mirror.simpleName),
<ReflectedTypeParameter>[],
mirror.metadata
.map((mirror) => new _ReflectedInstanceMirror(mirror))
.toList(),
!mirror.returnType.hasReflectedType
? const MirrorsReflector().reflectType(dynamic)
: const MirrorsReflector()
.reflectType(mirror.returnType.reflectedType),
mirror.parameters.map(_reflectParameter).toList(),
mirror.isGetter,
mirror.isSetter);
static ReflectedParameter _reflectParameter(dart.ParameterMirror mirror) {
return new ReflectedParameter(
dart.MirrorSystem.getName(mirror.simpleName),
mirror.metadata
.map((mirror) => new _ReflectedInstanceMirror(mirror))
.toList(),
const MirrorsReflector().reflectType(mirror.type.reflectedType),
!mirror.isOptional,
mirror.isNamed);
}
}