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 }