Add Fields to a struct with core.reflect

Stefan Koch uplink.coder at googlemail.com
Wed Aug 18 22:27:14 UTC 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.

```d
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.


More information about the Digitalmars-d mailing list