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     ret.functions = [ staticMap!(toFunction, module_.Functions) ];
60 
61     return ret;
62 }
63 
64 
65 /**
66    A D module.
67  */
68 struct Module {
69     string name;
70     Aggregate[] aggregates;
71     Variable[] variables;
72     Function[] functions;
73 }
74 
75 
76 /**
77    A user-defined type (struct, class, or enum).
78  */
79 struct Aggregate {
80     string name;
81     Variable[] fields;
82     Function[] functions;
83     // UDAs?
84 }
85 
86 struct Type {
87     string name;
88     // UDAs?
89 }
90 
91 /// A variable
92 struct Variable {
93     string type;
94     string name;
95     // UDAs?
96 }
97 
98 
99 /// A free function
100 struct Function {
101     string name;
102     Type returnType;
103     Parameter[] parameters;
104     // UDAs?
105     // Function attributes?
106 }
107 
108 
109 /// A function parameter
110 struct Parameter {
111     import std.traits: ParameterStorageClass;
112 
113     string type;
114     string name;
115     string default_;  /// default value, if any
116     ParameterStorageClass storageClass;
117 }
118 
119 
120 // TODO:
121 // * Module {c,d}tors
122 // * Unit tests
123 // * Class hierachies
124 // * Aliases?