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 }