August 18, 2021

Good Evening,

I am currently creating the first core.codegen prototypes and I gave myself the task to create a type from an existing one that has added fields.

This is the code which uses core reflect.

import core.reflect.reflect;
import core.reflect.dscope;

AggregateDeclaration aggregateFromType(const Type type)
{
    AggregateDeclaration result = null;
    if (auto ts = cast(TypeStruct)type)
    {
        result = ts.sym;
    } else if (auto tc = cast(TypeClass)type)
    {
        result = tc.sym;
    }
    return result;
}

struct S
{
    int x;
    int y;
}
//@(core.codegen)
template addField(T, Type type, string name)
{
    mixin(() {
        static immutable srcAggType = cast(immutable Type) nodeFromName("T");
        static immutable srcAgg = cast(immutable AggregateDeclaration) aggregateFromType(srcAggType);
        assert(srcAgg, "type was not an aggregate");
        string result = "struct addField {";
        foreach(f;srcAgg.fields)
        {
            result ~= "  " ~ f.type.identifier ~ " " ~ f.name ~ ";\n";
        }
        result ~= "  " ~ type.identifier ~ " " ~ name ~ ";\n";
        result ~= "}\n";
        return result;
    } ());
}

static immutable ModuleScope = currentScope(); // we need to get our module scope here
                                               // because the place nodeFromName is used in has no scope
alias i32 = int; // right now we nee this to make 'int' into a declarartion.

alias SwithZW = addField!(addField!(S, cast(Type)nodeFromName("i32", ModuleScope), "z"), cast(Type)nodeFromName("i32", ModuleScope), "w");

pragma(msg, __traits(allMembers, SwithZW));
// outputs: tuple("x", "y", "z", "w");

I find it compelling enough that I am considering not to work on core.codegen at the moment.

strings are actually alright to do this.
of course working with longer strings will quickly run into ctfe limitations.

If only someone would improve the ctfe engine ;)

Cheers,

Stefan

P.S. this code needs a small extension to the compiler which allows static class literals to be used as template parameters but this is actually trivial to do :)

I'll post a PR for that soon.