1 module ut.meta.reflection.functions;
2 
3 
4 import ut.meta.reflection;
5 import mirror.meta.traits: Parameter;
6 import std.meta: AliasSeq;
7 
8 
9 @("functions.bySymbol")
10 @safe pure unittest {
11     alias mod = Module!("modules.functions");
12     import modules.functions;
13 
14     alias expected = AliasSeq!(
15         FunctionSymbol!(add1, Protection.public_, Linkage.D),
16         FunctionSymbol!(withDefault, Protection.public_, Linkage.D),
17         FunctionSymbol!(storageClasses, Protection.public_, Linkage.D),
18         FunctionSymbol!(exportedFunc, Protection.export_, Linkage.D),
19         FunctionSymbol!(externC, Protection.public_, Linkage.C),
20         FunctionSymbol!(externCpp, Protection.public_, Linkage.Cpp),
21         FunctionSymbol!(identityInt, Protection.public_, Linkage.D, "identityInt", modules.functions),
22         FunctionSymbol!(voldermort, Protection.public_, Linkage.D),
23         FunctionSymbol!(voldermortArray, Protection.public_, Linkage.D),
24         FunctionSymbol!(concatFoo, Protection.public_, Linkage.D),
25     );
26 
27     // pragma(msg, "\n", mod.FunctionsBySymbol.stringof, "\n");
28     shouldEqual!(mod.FunctionsBySymbol, expected);
29 
30     static assert(mod.FunctionsBySymbol[0].overloads.length == 2); // add1
31     static foreach(i; 1..expected.length)
32         static assert(mod.FunctionsBySymbol[i].overloads.length == 1); // everything else
33 }
34 
35 
36 @("functions.byOverload")
37 @safe pure unittest {
38     alias mod = Module!("modules.functions");
39     import modules.functions;
40 
41     alias add1Int = __traits(getOverloads, modules.functions, "add1")[0];
42     alias add1Double = __traits(getOverloads, modules.functions, "add1")[1];
43 
44     alias expected = AliasSeq!(
45         FunctionOverload!(add1Int, Protection.public_, Linkage.D),
46         FunctionOverload!(add1Double, Protection.public_, Linkage.D, "add1", modules.functions, 1),
47         FunctionOverload!(withDefault, Protection.public_, Linkage.D),
48         FunctionOverload!(storageClasses, Protection.public_, Linkage.D),
49         FunctionOverload!(exportedFunc, Protection.export_, Linkage.D),
50         FunctionOverload!(externC, Protection.public_, Linkage.C),
51         FunctionOverload!(externCpp, Protection.public_, Linkage.Cpp),
52         FunctionOverload!(identityInt, Protection.public_, Linkage.D, "identityInt", modules.functions),
53         FunctionOverload!(voldermort, Protection.public_, Linkage.D),
54         FunctionOverload!(voldermortArray, Protection.public_, Linkage.D),
55         FunctionOverload!(concatFoo, Protection.public_, Linkage.D),
56     );
57 
58     // pragma(msg, "\n", mod.FunctionsByOverload.stringof, "\n");
59     shouldEqual!(mod.FunctionsByOverload, expected);
60 }
61 
62 
63 @("problems")
64 @safe pure unittest {
65     alias mod = Module!("modules.problems");
66     static assert(mod.FunctionsBySymbol.length == 0, mod.FunctionsBySymbol.stringof);
67 }
68 
69 
70 
71 @("parameters.add1.bySymbol")
72 @safe pure unittest {
73 
74     alias mod = Module!("modules.functions");
75     alias add1Int = mod.FunctionsBySymbol[0].overloads[0];
76     alias add1Double = mod.FunctionsBySymbol[0].overloads[1];
77     alias withDefaults = mod.FunctionsBySymbol[1].overloads[0];
78 
79     shouldEqual!(
80         add1Int.parameters,
81         AliasSeq!(
82             Parameter!(int, void, "i"),
83             Parameter!(int, void, "j"),
84         )
85     );
86 
87     shouldEqual!(
88         add1Double.parameters,
89         AliasSeq!(
90             Parameter!(double, void, "d0"),
91             Parameter!(double, void, "d1"),
92         )
93     );
94 
95     shouldEqual!(
96         withDefaults.parameters,
97         AliasSeq!(
98             Parameter!(double, void, "fst"),
99             Parameter!(double, 33.3, "snd"),
100         )
101     );
102 }
103 
104 
105 @("parameters.add1.byOverload")
106 @safe pure unittest {
107     alias mod = Module!("modules.functions");
108     alias add1Int = mod.FunctionsByOverload[0];
109     alias add1Double = mod.FunctionsByOverload[1];
110 
111     shouldEqual!(
112         add1Int.parameters,
113         AliasSeq!(
114             Parameter!(int, void, "i"),
115             Parameter!(int, void, "j"),
116         )
117     );
118 
119     shouldEqual!(
120         add1Double.parameters,
121         AliasSeq!(
122             Parameter!(double, void, "d0"),
123             Parameter!(double, void, "d1"),
124         )
125     );
126 }
127 
128 
129 @("parameters.storageClasses")
130 @safe pure unittest {
131 
132     import std.traits: STC = ParameterStorageClass;
133 
134     alias mod = Module!("modules.functions");
135     alias storageClasses = mod.FunctionsByOverload[3];
136 
137     // pragma(msg, "\n", storageClasses.parameters.stringof, "\n");
138 
139     shouldEqual!(
140         storageClasses.parameters,
141         AliasSeq!(
142             Parameter!(int, void, "normal", STC.none),
143             Parameter!(int*, void, "returnScope", STC.return_ | STC.scope_),
144             Parameter!(int, void, "out_", STC.out_),
145             Parameter!(int, void, "ref_", STC.ref_),
146             Parameter!(int, void, "lazy_", STC.lazy_),
147         )
148     );
149 }
150 
151 
152 
153 @("return.bySymbol")
154 @safe pure unittest {
155     import std.meta: staticMap;
156 
157     alias mod = Module!("modules.functions");
158     alias functions = mod.FunctionsBySymbol;
159 
160     static assert(is(functions[0].overloads[0].ReturnType == int));
161     static assert(is(functions[0].overloads[1].ReturnType == double));
162     static assert(is(functions[1].overloads[0].ReturnType == double));
163     static assert(is(functions[2].overloads[0].ReturnType == void));
164 }
165 
166 
167 @("return.byOverload")
168 @safe pure unittest {
169     import std.meta: staticMap;
170     import std.traits: ReturnType;
171     static import modules.functions;
172 
173     alias mod = Module!("modules.functions");
174     alias return_(alias F) = F.ReturnType;
175     alias returnTypes = staticMap!(return_, mod.FunctionsByOverload);
176 
177     shouldEqual!(
178         returnTypes,
179         AliasSeq!(
180             int, double, double, void, void, void, void, int,
181             ReturnType!(modules.functions.voldermort),
182             ReturnType!(modules.functions.voldermortArray),
183             string,
184         ),
185     );
186 }