1 2 module witchcraft.mixins.classes; 3 4 mixin template WitchcraftClass() 5 { 6 import witchcraft; 7 8 import std.meta; 9 import std.traits; 10 11 static class ClassMixin(T) : Class 12 if(is(T == class)) 13 { 14 this() 15 { 16 foreach(name; FieldNameTuple!T) 17 { 18 _fields[name] = new FieldMixin!(T, name); 19 } 20 21 foreach(name; __traits(derivedMembers, T)) 22 { 23 static if(is(typeof(__traits(getMember, T, name)) == function)) 24 { 25 static if(name != "__ctor" && name != "__dtor") 26 { 27 foreach(index, overload; __traits(getOverloads, T, name)) 28 { 29 _methods[name] ~= new MethodMixin!(T, name, index); 30 } 31 } 32 } 33 } 34 } 35 36 @property 37 override Object create() const 38 { 39 return T.classinfo.create; 40 } 41 42 const(Attribute)[] getAttributes() const 43 { 44 alias attributes = AliasSeq!(__traits(getAttributes, T)); 45 auto values = new Attribute[attributes.length]; 46 47 foreach(index, attribute; attributes) 48 { 49 values[index] = new AttributeImpl!attribute; 50 } 51 52 return values; 53 } 54 55 override const(Constructor)[] getConstructors() const 56 { 57 static if(__traits(hasMember, T, "__ctor")) 58 { 59 alias constructors = AliasSeq!(__traits(getOverloads, T, "__ctor")); 60 auto values = new Constructor[constructors.length]; 61 62 foreach(index, constructor; constructors) 63 { 64 values[index] = new ConstructorMixin!(T, index); 65 } 66 67 return values; 68 } 69 else 70 { 71 return [ ]; 72 } 73 } 74 75 const(Type) getDeclaringType() const 76 { 77 alias Parent = Alias!(__traits(parent, T)); 78 79 return inspect!Parent; 80 } 81 82 const(TypeInfo) getDeclaringTypeInfo() const 83 { 84 alias Parent = Alias!(__traits(parent, T)); 85 86 static if(__traits(compiles, typeid(Parent))) 87 { 88 return typeid(Parent); 89 } 90 else 91 { 92 return null; 93 } 94 } 95 96 override const(InterfaceType)[] getInterfaces() const 97 { 98 alias Interfaces = InterfacesTuple!T; 99 auto values = new InterfaceType[Interfaces.length]; 100 101 foreach(index, IFace; Interfaces) 102 { 103 values[index] = cast(InterfaceType) inspect!IFace; 104 } 105 106 return values; 107 } 108 109 string getFullName() const 110 { 111 return fullyQualifiedName!T; 112 } 113 114 string getName() const 115 { 116 return T.stringof; 117 } 118 119 string getProtection() const 120 { 121 return __traits(getProtection, T); 122 } 123 124 override const(Class) getSuperClass() const 125 { 126 static if(is(Unqual!T == Object)) 127 { 128 return null; 129 } 130 else 131 { 132 alias Bases = BaseClassesTuple!T; 133 134 static if(Bases.length > 0) 135 { 136 return cast(const(Class)) inspect!(Bases[0]); 137 } 138 else 139 { 140 return null; 141 } 142 } 143 } 144 145 override const(TypeInfo) getSuperTypeInfo() const 146 { 147 static if(is(Unqual!T == Object)) 148 { 149 return null; 150 } 151 else 152 { 153 alias Bases = BaseClassesTuple!T; 154 155 static if(Bases.length > 0) 156 { 157 return typeid(Bases[0]); 158 } 159 else 160 { 161 return null; 162 } 163 } 164 } 165 166 override const(TypeInfo) getTypeInfo() const 167 { 168 return T.classinfo; 169 } 170 171 @property 172 override bool isAbstract() const 173 { 174 return __traits(isAbstractClass, T); 175 } 176 177 @property 178 final bool isAccessible() const 179 { 180 return true; 181 } 182 183 @property 184 override bool isFinal() const 185 { 186 return __traits(isFinalClass, T); 187 } 188 189 override bool isSubClassOf(const Class other) const 190 { 191 return _d_isbaseof(T.classinfo, cast(ClassInfo) other.getTypeInfo); 192 } 193 194 override bool isSuperClassOf(const Class other) const 195 { 196 return _d_isbaseof(cast(ClassInfo) other.getTypeInfo, T.classinfo); 197 } 198 } 199 }