Permalink
Browse files

new trait: getProtection (cleaned up)

  • Loading branch information...
1 parent b41a2c3 commit 638594e625ad1ef6f8787d9c9a9aeb6a8156cfdb @adamdruppe committed Apr 1, 2012
Showing with 123 additions and 0 deletions.
  1. +1 −0 src/idgen.c
  2. +53 −0 src/traits.c
  3. +69 −0 test/runnable/traits.d
View
@@ -322,6 +322,7 @@ Msgtable msgtable[] =
{ "isLazy" },
{ "hasMember" },
{ "identifier" },
+ { "getProtection" },
{ "parent" },
{ "getMember" },
{ "getOverloads" },
View
@@ -206,6 +206,59 @@ Expression *TraitsExp::semantic(Scope *sc)
StringExp *se = new StringExp(loc, s->ident->toChars());
return se->semantic(sc);
}
+ else if (ident == Id::getProtection)
+ {
+ if (dim != 1)
+ goto Ldimerror;
+ Object *o = (*args)[0];
+ Dsymbol *s = getDsymbol(o);
+ if(!s)
+ {
+ // it might also be a trait getMember or something,
+ // which returns a dot expression rather than a symbol
+ if(o->dyncast() == DYNCAST_EXPRESSION)
+ {
+ Expression *e = (Expression *) o;
+
+ if (e->op == TOKdotvar)
+ {
+ DotVarExp *dv = (DotVarExp *)e;
+ s = dv->var->isDeclaration();
+ }
+ }
+ }
+ if(!s)
+ {
+ bool gagError = false;
+ if(o->dyncast() == DYNCAST_EXPRESSION)
+ {
+ Expression *e = (Expression *) o;
+ if(e->op == TOKerror)
+ gagError = true;
+ }
+
+ if(!gagError)
+ error("argument %s has no protection", o->toChars());
+
+ goto Lfalse;
+ }
+
+ PROT protection = s->prot();
+
+ const char *protName =
+ protection == PROTundefined ? ""
+ : protection == PROTnone ? "none"
+ : protection == PROTprivate ? "private"
+ : protection == PROTpackage ? "package"
+ : protection == PROTprotected ? "protected"
+ : protection == PROTpublic ? "public"
+ : protection == PROTexport ? "export"
+ : (assert(0), ""); // unknown
+
+ StringExp *se = new StringExp(loc, (char*) protName);
+ return se->semantic(sc);
+ }
+
else if (ident == Id::parent)
{
if (dim != 1)
@@ -729,6 +729,75 @@ void test7608()
/********************************************************/
+private struct TestProt1 {}
+package struct TestProt2 {}
+protected struct TestProt3 {}
+public struct TestProt4 {}
+export struct TestProt5 {}
+
+void getProtection()
+{
+ class Test
+ {
+ private { int va; void fa(){} }
+ package { int vb; void fb(){} }
+ protected { int vc; void fc(){} }
+ public { int vd; void fd(){} }
+ export { int ve; void fe(){} }
+ }
+ Test t;
+
+ // TOKvar and VarDeclaration
+ static assert(__traits(getProtection, Test.va) == "private");
+ static assert(__traits(getProtection, Test.vb) == "package");
+ static assert(__traits(getProtection, Test.vc) == "protected");
+ static assert(__traits(getProtection, Test.vd) == "public");
+ static assert(__traits(getProtection, Test.ve) == "export");
+
+ // TOKdotvar and VarDeclaration
+ static assert(__traits(getProtection, t.va) == "private");
+ static assert(__traits(getProtection, t.vb) == "package");
+ static assert(__traits(getProtection, t.vc) == "protected");
+ static assert(__traits(getProtection, t.vd) == "public");
+ static assert(__traits(getProtection, t.ve) == "export");
+
+ // TOKvar and FuncDeclaration
+ static assert(__traits(getProtection, Test.fa) == "private");
+ static assert(__traits(getProtection, Test.fb) == "package");
+ static assert(__traits(getProtection, Test.fc) == "protected");
+ static assert(__traits(getProtection, Test.fd) == "public");
+ static assert(__traits(getProtection, Test.fe) == "export");
+
+ // TOKdotvar and FuncDeclaration
+ static assert(__traits(getProtection, t.fa) == "private");
+ static assert(__traits(getProtection, t.fb) == "package");
+ static assert(__traits(getProtection, t.fc) == "protected");
+ static assert(__traits(getProtection, t.fd) == "public");
+ static assert(__traits(getProtection, t.fe) == "export");
+
+ // TOKtype
+ static assert(__traits(getProtection, TestProt1) == "private");
+ static assert(__traits(getProtection, TestProt2) == "package");
+ static assert(__traits(getProtection, TestProt3) == "protected");
+ static assert(__traits(getProtection, TestProt4) == "public");
+ static assert(__traits(getProtection, TestProt5) == "export");
+
+ // This specific pattern is important to ensure it always works
+ // through reflection, however that becomes implemented
+ static assert(__traits(getProtection, __traits(getMember, t, "va")) == "private");
+ static assert(__traits(getProtection, __traits(getMember, t, "vb")) == "package");
+ static assert(__traits(getProtection, __traits(getMember, t, "vc")) == "protected");
+ static assert(__traits(getProtection, __traits(getMember, t, "vd")) == "public");
+ static assert(__traits(getProtection, __traits(getMember, t, "ve")) == "export");
+ static assert(__traits(getProtection, __traits(getMember, t, "fa")) == "private");
+ static assert(__traits(getProtection, __traits(getMember, t, "fb")) == "package");
+ static assert(__traits(getProtection, __traits(getMember, t, "fc")) == "protected");
+ static assert(__traits(getProtection, __traits(getMember, t, "fd")) == "public");
+ static assert(__traits(getProtection, __traits(getMember, t, "fe")) == "export");
+}
+
+/********************************************************/
+
int main()
{
test1();

0 comments on commit 638594e

Please sign in to comment.