1 2 module witchcraft.types; 3 4 import witchcraft; 5 6 import std.algorithm; 7 import std.array; 8 import std.range; 9 10 abstract class Type : Member 11 { 12 protected: 13 Field[string] _fields; 14 Method[][string] _methods; 15 16 public: 17 /++ 18 + Looks up a field by name. 19 + 20 + Params: 21 + name = The name of the field. 22 + 23 + Returns: 24 + The field object, or null if no such field exists. 25 ++/ 26 const(Field) getField(string name) const 27 { 28 auto ptr = name in _fields; 29 return ptr ? *ptr : null; 30 } 31 32 final string[] getFieldNames() const 33 { 34 return getFields 35 .map!"a.getName" 36 .array; 37 } 38 39 /++ 40 + Returns an array of all fields defined by this type. 41 + 42 + Returns: 43 + All fields objects on this type. 44 ++/ 45 const(Field)[] getFields() const 46 { 47 return _fields.values; 48 } 49 50 final const(Method) getMethod(string name, Type[] parameterTypes...) const 51 { 52 // Iterate up the inheritance tree. 53 return this.getMethods(name).retro 54 .filter!(m => m.getParameterTypes == parameterTypes) 55 .takeOne 56 .chain(null.only) 57 .front; 58 } 59 60 final const(Method) getMethod(string name, TypeInfo[] parameterTypeInfos) const 61 { 62 // Iterate up the inheritance tree. 63 return this.getMethods(name).retro 64 .filter!(m => m.getParameterTypeInfos == parameterTypeInfos) 65 .takeOne 66 .chain(null.only) 67 .front; 68 } 69 70 final const(Method) getMethod(TList...)(string name) const 71 { 72 auto parameterTypeInfos = new TypeInfo[TList.length]; 73 74 foreach(index, Type; TList) 75 { 76 parameterTypeInfos[index] = typeid(Type); 77 } 78 79 return this.getMethod(name, parameterTypeInfos); 80 } 81 82 const(Method)[] getMethods() const 83 { 84 const(Method)[] methods; 85 86 // Flatten the overloads array. 87 foreach(overloads; _methods.values) 88 { 89 methods ~= overloads; 90 } 91 92 return methods; 93 } 94 95 final string[] getMethodNames() const 96 { 97 return getMethods 98 .map!"a.getName" 99 .array; 100 } 101 102 const(Method)[] getMethods(string name) const 103 { 104 auto ptr = name in _methods; 105 return ptr ? *ptr : [ ]; 106 } 107 108 abstract const(TypeInfo) getTypeInfo() const; 109 110 @property 111 bool isAggregate() const 112 { 113 return false; 114 } 115 116 @property 117 bool isArray() const 118 { 119 return false; 120 } 121 122 @property 123 bool isAssocArray() const 124 { 125 return false; 126 } 127 128 @property 129 bool isBuiltIn() const 130 { 131 return false; 132 } 133 134 @property 135 bool isClass() const 136 { 137 return false; 138 } 139 140 @property 141 bool isInterface() const 142 { 143 return false; 144 } 145 146 @property 147 bool isModule() const 148 { 149 return false; 150 } 151 152 @property 153 bool isPointer() const 154 { 155 return false; 156 } 157 158 @property 159 bool isPrimitive() const 160 { 161 return false; 162 } 163 164 @property 165 bool isStaticArray() const 166 { 167 return false; 168 } 169 170 @property 171 bool isString() const 172 { 173 return false; 174 } 175 176 @property 177 bool isStruct() const 178 { 179 return false; 180 } 181 182 override string toString() const 183 { 184 return getFullName; 185 } 186 }