1 2 module witchcraft.mixins.interfaces; 3 4 mixin template WitchcraftInterface(T) 5 { 6 import witchcraft; 7 8 import std.meta; 9 import std.traits; 10 11 static class InterfaceTypeMixin(T) : InterfaceType 12 if(is(T == interface)) 13 { 14 this() 15 { 16 foreach(name; __traits(derivedMembers, T)) 17 { 18 static if(is(typeof(__traits(getMember, T, name)) == function)) 19 { 20 static if(name != "__ctor" && name != "__dtor") 21 { 22 foreach(index, overload; __traits(getOverloads, T, name)) 23 { 24 _methods[name] ~= new MethodMixin!(T, name, index); 25 } 26 } 27 } 28 } 29 } 30 31 const(Attribute)[] getAttributes() const 32 { 33 alias attributes = AliasSeq!(__traits(getAttributes, T)); 34 auto values = new Attribute[attributes.length]; 35 36 foreach(index, attribute; attributes) 37 { 38 values[index] = new AttributeImpl!attribute; 39 } 40 41 return values; 42 } 43 44 const(Type) getDeclaringType() const 45 { 46 alias Parent = Alias!(__traits(parent, T)); 47 48 return inspect!Parent; 49 } 50 51 const(TypeInfo) getDeclaringTypeInfo() const 52 { 53 alias Parent = Alias!(__traits(parent, T)); 54 55 static if(__traits(compiles, typeid(Parent))) 56 { 57 return typeid(Parent); 58 } 59 else 60 { 61 return null; 62 } 63 } 64 65 override const(Field) getField(string name) const 66 { 67 auto ptr = name in _fields; 68 return ptr ? *ptr : null; 69 } 70 71 override const(Field)[] getFields() const 72 { 73 return _fields.values; 74 } 75 76 string getFullName() const 77 { 78 return fullyQualifiedName!T; 79 } 80 81 override const(Method)[] getMethods(string name) const 82 { 83 auto ptr = name in _methods; 84 return ptr ? *ptr : null; 85 } 86 87 override const(Method)[] getMethods() const 88 { 89 const(Method)[] methods; 90 91 foreach(overloads; _methods.values) 92 { 93 methods ~= overloads; 94 } 95 96 return methods; 97 } 98 99 string getName() const 100 { 101 return T.stringof; 102 } 103 104 string getProtection() const 105 { 106 return __traits(getProtection, T); 107 } 108 109 override const(TypeInfo) getTypeInfo() const 110 { 111 return typeid(T); 112 } 113 114 @property 115 final bool isAccessible() const 116 { 117 return true; 118 } 119 } 120 }