1 module ut.meta.functions;
2 
3 
4 import ut.meta;
5 import mirror.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 
130 @("return.bySymbol")
131 @safe pure unittest {
132     import std.meta: staticMap;
133 
134     alias mod = Module!("modules.functions");
135     alias functions = mod.FunctionsBySymbol;
136 
137     static assert(is(functions[0].overloads[0].ReturnType == int));
138     static assert(is(functions[0].overloads[1].ReturnType == double));
139     static assert(is(functions[1].overloads[0].ReturnType == double));
140     static assert(is(functions[2].overloads[0].ReturnType == void));
141 }
142 
143 
144 @("return.byOverload")
145 @safe pure unittest {
146     import std.meta: staticMap;
147     import std.traits: ReturnType;
148     static import modules.functions;
149 
150     alias mod = Module!("modules.functions");
151     alias return_(alias F) = F.ReturnType;
152     alias returnTypes = staticMap!(return_, mod.FunctionsByOverload);
153 
154     shouldEqual!(
155         returnTypes,
156         AliasSeq!(
157             int, double, double, void, void, void, void, int,
158             ReturnType!(modules.functions.voldermort),
159             ReturnType!(modules.functions.voldermortArray),
160             string,
161         ),
162     );
163 }