On Wednesday, 21 March 2012 at 15:11:47 UTC, Andrei Alexandrescu wrote:
class Foo
{
int a;
int b;

mixin NonSerialized!(b);
}

I think the liability here is that b needs to appear in two places, once in the declaration proper and then in the NonSerialized part. (A possible advantage is that sometimes it may be advantageous to keep all symbols with a specific attribute in one place.) A possibility would be to make the mixin expand to the field and the metadata at once.


In case my proof of concept which was posted in another thread was overlooked... it was my goal to address this very issue... also it's possible to change the datatype of the members in the "parallel annotation class"(Foo_Serializable in my limited example), and store any extra user data there if so desired while keeping the real class clean... and then simply traverse with __traits.

import std.stdio;
import std.array;
import std.string;
import std.algorithm;

string attr(string complex_decl)
{
  string org_struct;
  string ser_struct;

  auto lines = splitLines(complex_decl);

  {
    auto decl = split(stripLeft(lines[0]));

    if(decl[0]=="struct")
    {
      org_struct = decl[0] ~ " " ~ decl[1];
      ser_struct = decl[0] ~ " " ~ decl[1] ~ "_Serializable";
    }
    else
      return complex_decl;
  }

  foreach(line; lines[1..$])
  {
auto attr = findSplitAfter(stripLeft(line), "@NonSerialized ");

    if(attr[0]=="@NonSerialized ")
      org_struct ~= attr[1];
    else
    {
      org_struct ~= attr[1];
      ser_struct ~= attr[1];
    }
  }

  return ser_struct ~ "\n" ~ org_struct;
}

mixin(attr(q{struct Foo
{
  @NonSerialized int x;
  @NonSerialized int y;
  int z;
}}));

void main()
{
  auto m = [ __traits(allMembers, Foo) ];
  writeln("Normal members of Foo:", m);

  auto n = [ __traits(allMembers, Foo_Serializable) ];
  writeln("Serializable members of Foo:", n);
}

Reply via email to