1 /**
2    This module provides the CTFE variant of compile-time reflection,
3    allowing client code to use regular D functions (as opposed to
4    template metaprogramming) to operate on the contents of a D module
5    using string mixins.
6  */
7 
8 module mirror.ctfe;
9 
10 
11 /**
12    Returns compile-time reflection information about a D module.
13  */
14 Module module_(string moduleName)() {
15     import mirror.meta: ModuleTemplate = Module;
16     import std.meta: staticMap;
17 
18     Module ret;
19     ret.name = moduleName;
20 
21     alias module_ = ModuleTemplate!moduleName;
22 
23     enum toType(T) = Aggregate(__traits(identifier, T));
24     ret.aggregates = [ staticMap!(toType, module_.Aggregates) ];
25 
26     enum toVariable(alias V) = Variable(V.Type.stringof, V.name);
27     ret.variables = [ staticMap!(toVariable, module_.Variables) ];
28 
29     template toFunction(alias F) {
30 
31         import std.range: iota;
32         import std.meta: aliasSeqOf;
33         import std.traits: ReturnType, Parameters, ParameterDefaults, ParameterIdentifierTuple;
34 
35         template toDefault(size_t i) {
36             static if(is(ParameterDefaults!(F.symbol)[i] == void))
37                 enum toDefault = "";
38             else
39                 enum toDefault = ParameterDefaults!(F.symbol)[i].stringof;
40         }
41 
42         template toParameter(size_t i) {
43             import std.traits: ParameterStorageClassTuple;
44 
45             enum toParameter = Parameter(
46                 Parameters!(F.symbol)[i].stringof,
47                 ParameterIdentifierTuple!(F.symbol)[i],
48                 toDefault!i,
49                 ParameterStorageClassTuple!(F.symbol)[i],
50             );
51         }
52 
53         enum toFunction = Function(
54             F.identifier,
55             Type(ReturnType!(F.symbol).stringof),
56             [staticMap!(toParameter, aliasSeqOf!(Parameters!(F.symbol).length.iota))],
57         );
58     }
59 
60     ret.functions = [ staticMap!(toFunction, module_.FunctionsBySymbol) ];
61 
62     return ret;
63 }
64 
65 
66 /**
67    A D module.
68  */
69 struct Module {
70     string name;
71     Aggregate[] aggregates;
72     Variable[] variables;
73     Function[] functions;
74 }
75 
76 
77 /**
78    A user-defined type (struct, class, or enum).
79  */
80 struct Aggregate {
81     string name;
82     Variable[] fields;
83     Function[] functions;
84     // UDAs?
85 }
86 
87 struct Type {
88     string name;
89     // UDAs?
90 }
91 
92 /// A variable
93 struct Variable {
94     string type;
95     string name;
96     // UDAs?
97 }
98 
99 
100 /// A free function
101 struct Function {
102     string name;
103     Type returnType;
104     Parameter[] parameters;
105     // UDAs?
106     // Function attributes?
107 }
108 
109 
110 /// A function parameter
111 struct Parameter {
112     import std.traits: ParameterStorageClass;
113 
114     string type;
115     string name;
116     string default_;  /// default value, if any
117     ParameterStorageClass storageClass;
118 }
119 
120 
121 // TODO:
122 // * Module {c,d}tors
123 // * Unit tests
124 // * Class hierachies
125 // * Aliases?