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