1 
2 module witchcraft.members;
3 
4 import witchcraft;
5 
6 import std.algorithm;
7 import std.array;
8 
9 /++
10  + Represents a set of behaviours common to reflective elements.
11  ++/
12 interface Member
13 {
14     /++
15      + Returns an array of attributes that are attached to this element.
16      +
17      + Returns:
18      +   An array of attributes.
19      ++/
20     const(Attribute)[] getAttributes() const;
21 
22     /++
23      + Returns an array of attributes of the given type that are attched to
24      + this element. If no such attributes exist, an empty array is returned.
25      +
26      + Params:
27      +   attributeType = The type of attribute to filter by.
28      +
29      + Returns:
30      +   An array of attributes.
31      ++/
32     final const(Attribute)[] getAttributes(Type attributeType) const
33     {
34         return getAttributes
35             .filter!(a => a.getAttributeType == attributeType)
36             .array;
37     }
38 
39     /++
40      + Returns an array of attributes of the given type that are attched to
41      + this element. If no such attributes exist, an empty array is returned.
42      +
43      + Params:
44      +   attributeTypeInfo = The type of attribute to filter by.
45      +
46      + Returns:
47      +   An array of attributes.
48      ++/
49     final const(Attribute)[] getAttributes(TypeInfo attributeTypeInfo) const
50     {
51         return getAttributes
52             .filter!(a => a.getAttributeTypeInfo == attributeTypeInfo)
53             .array;
54     }
55 
56     /++
57      + Ditto, but the type is given by template parameter.
58      +
59      + Params:
60      +   T = The type of attribute to filter by.
61      +
62      + Returns:
63      +   An array of attributes.
64      ++/
65     final const(Attribute)[] getAttributes(T)() const
66     {
67         return getAttributes(typeid(T));
68     }
69 
70     final bool hasAttribute(TypeInfo info) const {
71         return getAttributes.canFind!(a => a.getAttributeTypeInfo == info);
72     }
73 
74     final bool hasAttribute(T)() const {
75         return hasAttribute(typeid(T));
76     }
77 
78     /++
79      + Returns the type that encapsulates this one. Null is returned if this
80      + is the topmost element, or if the outer type lacks reflective meta
81      + information.
82      +
83      + Returns:
84      +   The declaring element's type.
85      ++/
86     const(Type) getDeclaringType() const;
87 
88     /++
89      + Returns a `TypeInfo` object for the declaring element.
90      +
91      + Returns:
92      +   The type of the declaring element.
93      +
94      + See_Also:
95      +   getDeclaringType
96      ++/
97     const(TypeInfo) getDeclaringTypeInfo() const;
98 
99     /++
100      + The name of the element.
101      +
102      + Returns:
103      +   The name of this element.
104      ++/
105     string getName() const;
106 
107     /++
108      + Returns the fully-qualified name of the element, including the package
109      + and module name, and any types that might enclose it.
110      +
111      + Returns:
112      +   The fully-qualified name of this element.
113      ++/
114     string getFullName() const;
115 
116     /++
117      + Returns a string that represents this element's declared protection.
118      +
119      + Returns:
120      +   This element's protection.
121      ++/
122     string getProtection() const;
123 
124     @property
125     bool isAccessible() const;
126 }