On Saturday, 23 October 2021 at 20:24:32 UTC, Tim wrote:
import std.traits, std.stdio;
string generateLogCode(alias func)()
{
string code = "writeln(";
code ~= "\"" ~ fullyQualifiedName!func ~ "(\"";
foreach(i, param; ParameterIdentifierTuple!func)
{
if(i)
code ~= ", \", \"";
code ~= ", " ~ param;
}
code ~= ", \");\");";
return code;
}
enum OUTPUT_REPRO_CASE = q{
pragma(msg, generateLogCode!(__traits(parent, {}))());
mixin(generateLogCode!(__traits(parent, {}))());
};
void test(int a, int[] b)
{
mixin(OUTPUT_REPRO_CASE);
}
void main()
{
test(1, [2, 3]);
}
That worked! I needed to modify it a bit, since there is the
"execution_count_to_log_reproduction_on"-template parameterto the
enum. If I try to use that inside the token string, it just says
it can't find the identifier, so I had to inject some non-token
string in the middle that plays nice with the token string, where
I can actually reference the parameter.
For completeness, here is how the code looks like now (I am
completely horrified by the result):
string generate_call_to_log_reproduction(alias func)(){
string code =
"dlog(generate_reproduction_for_current_function_call!("~fullyQualifiedName!func~", [get_string_argument_list_of_function!([ParameterIdentifierTuple!(__traits(parent, {}))])])(context.temp_allocator";
foreach(i, param; ParameterIdentifierTuple!func)
code ~= "," ~ param;
code ~= "));";
return code;
}
string generate_call_to_log_execution_count(alias func)(){
return "dlog(\""~fullyQualifiedName!(func)~" execution count:
%lld\", execution_count);";
}
enum OUTPUT_REPRO_CASE(s64
execution_count_to_log_reproduction_on = -1) = q{
static s64 execution_count = 0;
if(context.settings.debug_.output_call_counts_for_reproducible_functions){
mixin(generate_call_to_log_execution_count!(__traits(parent,
{})));
}
} ~ "if(execution_count ==
"~execution_count_to_log_reproduction_on.stringof~")"~q{
{
mixin(generate_call_to_log_reproduction!(__traits(parent,
{}))());
trigger_breakpoint();
}
execution_count++;
};
and the usage just looks like this:
void some_function(int a, int b){
mixin(OUTPUT_REPRO_CASE!());
return a + b;
}
The "mixin(OUTPUT_REPRO_CASE!());" then expands to:
static s64 execution_count = 0;
if(context.settings.debug_.output_call_counts_for_reproducible_functions){
mixin(generate_call_to_log_execution_count!(__traits(parent,
{})));
}
if(execution_count == -1L){
mixin(generate_call_to_log_reproduction!(__traits(parent,
{}))());
trigger_breakpoint();
}
execution_count++;
Thanks for your help!!!