import 'package:collection/collection.dart'; import 'package:quiver/core.dart'; abstract class Reflector { String getName(Symbol symbol); ReflectedClass reflectClass(Type clazz); ReflectedFunction reflectFunction(Function function); ReflectedType reflectType(Type type); ReflectedInstance reflectInstance(Object object); } abstract class ReflectedInstance { final ReflectedType type; final ReflectedClass clazz; final Object reflectee; const ReflectedInstance(this.type, this.clazz, this.reflectee); @override int get hashCode => hash2(type, clazz); @override bool operator ==(other) => other is ReflectedInstance && other.type == type && other.clazz == clazz; ReflectedInstance getField(String name); } abstract class ReflectedType { final String name; final List typeParameters; final Type reflectedType; const ReflectedType(this.name, this.typeParameters, this.reflectedType); @override int get hashCode => hash3(name, typeParameters, reflectedType); @override bool operator ==(other) => other is ReflectedType && other.name == name && const ListEquality() .equals(other.typeParameters, typeParameters) && other.reflectedType == reflectedType; ReflectedInstance newInstance( String constructorName, List positionalArguments, [Map namedArguments, List typeArguments]); bool isAssignableTo(ReflectedType other); } abstract class ReflectedClass extends ReflectedType { final List annotations; final List constructors; final List declarations; const ReflectedClass( String name, List typeParameters, this.annotations, this.constructors, this.declarations, Type reflectedType) : super(name, typeParameters, reflectedType); @override int get hashCode => hash4(super.hashCode, annotations, constructors, declarations); @override bool operator ==(other) => other is ReflectedClass && super == other && const ListEquality() .equals(other.annotations, annotations) && const ListEquality() .equals(other.constructors, constructors) && const ListEquality() .equals(other.declarations, declarations); } class ReflectedDeclaration { final String name; final bool isStatic; final ReflectedFunction function; const ReflectedDeclaration(this.name, this.isStatic, this.function); @override int get hashCode => hash3(name, isStatic, function); @override bool operator ==(other) => other is ReflectedDeclaration && other.name == name && other.isStatic == isStatic && other.function == function; } abstract class ReflectedFunction { final String name; final List typeParameters; final List annotations; final ReflectedType returnType; final List parameters; final bool isGetter, isSetter; const ReflectedFunction(this.name, this.typeParameters, this.annotations, this.returnType, this.parameters, this.isGetter, this.isSetter); @override int get hashCode => hashObjects([ name, typeParameters, annotations, returnType, parameters, isGetter, isSetter ]); @override bool operator ==(other) => other is ReflectedFunction && other.name == name && const ListEquality() .equals(other.typeParameters, typeParameters) && const ListEquality() .equals(other.annotations, annotations) && other.returnType == returnType && const ListEquality() .equals(other.parameters, other.parameters) && other.isGetter == isGetter && other.isSetter == isSetter; ReflectedInstance invoke(Invocation invocation); } class ReflectedParameter { final String name; final List annotations; final ReflectedType type; final bool isRequired; final bool isNamed; const ReflectedParameter( this.name, this.annotations, this.type, this.isRequired, this.isNamed); @override int get hashCode => hashObjects([name, annotations, type, isRequired, isNamed]); @override bool operator ==(other) => other is ReflectedParameter && other.name == name && const ListEquality() .equals(other.annotations, annotations) && other.type == type && other.isRequired == isRequired && other.isNamed == isNamed; } class ReflectedTypeParameter { final String name; const ReflectedTypeParameter(this.name); @override int get hashCode => hashObjects([name]); @override bool operator ==(other) => other is ReflectedTypeParameter && other.name == name; }