Skip to content
Browse files

Merge pull request #856 from adamdruppe/protection_trait

Protection trait
  • Loading branch information...
2 parents c08223a + 2cb747d commit 913b485bcbf72119f793c1f9df7e560030396bb6 @WalterBright WalterBright committed
Showing with 123 additions and 20 deletions.
  1. +4 −11 src/attrib.c
  2. +1 −8 src/doc.c
  3. +3 −0 src/dsymbol.h
  4. +1 −0 src/idgen.c
  5. +0 −1 src/json.c
  6. +45 −0 src/traits.c
  7. +69 −0 test/runnable/traits.d
View
15 src/attrib.c
@@ -723,17 +723,10 @@ void ProtDeclaration::protectionToCBuffer(OutBuffer *buf, enum PROT protection)
{
const char *p;
- switch (protection)
- {
- case PROTprivate: p = "private"; break;
- case PROTpackage: p = "package"; break;
- case PROTprotected: p = "protected"; break;
- case PROTpublic: p = "public"; break;
- case PROTexport: p = "export"; break;
- default:
- assert(0);
- break;
- }
+ p = Pprotectionnames[protection];
+
+ assert(p);
+
buf->writestring(p);
buf->writeByte(' ');
}
View
9 src/doc.c
@@ -558,15 +558,8 @@ void ScopeDsymbol::emitMemberComments(Scope *sc)
void emitProtection(OutBuffer *buf, PROT prot)
{
- const char *p;
+ const char *p = Pprotectionnames[prot];
- switch (prot)
- {
- case PROTpackage: p = "package"; break;
- case PROTprotected: p = "protected"; break;
- case PROTexport: p = "export"; break;
- default: p = NULL; break;
- }
if (p)
buf->printf("%s ", p);
}
View
3 src/dsymbol.h
@@ -96,6 +96,9 @@ enum PROT
PROTexport,
};
+// this is used for printing the protection in json, traits, docs, etc.
+static const char* Pprotectionnames[] = {NULL, "none", "private", "package", "protected", "public", "export"};
+
/* State of symbol in winding its way through the passes of the compiler
*/
enum PASS
View
1 src/idgen.c
@@ -323,6 +323,7 @@ Msgtable msgtable[] =
{ "isLazy" },
{ "hasMember" },
{ "identifier" },
+ { "getProtection" },
{ "parent" },
{ "getMember" },
{ "getOverloads" },
View
1 src/json.c
@@ -44,7 +44,6 @@ const char Ptype[] = "type";
const char Pcomment[] = "comment";
const char Pmembers[] = "members";
const char Pprotection[] = "protection";
-const char* Pprotectionnames[] = {NULL, "none", "private", "package", "protected", "public", "export"};
void JsonRemoveComma(OutBuffer *buf);
View
45 src/traits.c
@@ -221,6 +221,51 @@ Expression *TraitsExp::semantic(Scope *sc)
StringExp *se = new StringExp(loc, id->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 = Pprotectionnames[protection];
+
+ StringExp *se = new StringExp(loc, (char *) protName);
+ return se->semantic(sc);
+ }
+
else if (ident == Id::parent)
{
if (dim != 1)
View
69 test/runnable/traits.d
@@ -796,6 +796,75 @@ struct A8972
/********************************************************/
+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();

1 comment on commit 913b485

@TurkeyMan

Wow, I was just thinking this would be really useful on Friday! ;)

Please sign in to comment.
Something went wrong with that request. Please try again.