DIP23 draft: Fixing properties redux
kenji hara
k.hara.pg at gmail.com
Sun Feb 3 04:37:25 PST 2013
2013/2/3 Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org>
> Walter and I have had a discussion on how to finalize properties.
>
> http://wiki.dlang.org/DIP23
Awesome!!
After reading it, I thought that there is some consistent rules.
1. When a function is annotated with @property, it cannot be called with
parenthesis syntax.
2. 0-arg functions which not annotated with @property can be called without
parentheses.
3. Ref return getter can make "auxiliary setter", if formal getter is
missing.
4. `typeof(exp)` never returns "function type". In other words, the actual
type of `exp` and `typeof(exp)` should be same.
5. Both `&prop` and `&func` should return function pointer / delegate object
6. UFCS CAN NOT call global setter by getter syntax.
I think that 4 to 6 are important points of this DIP. Based on the rules, I
could write an exhaustive test case.
alias Type = int;
unittest
{
struct S
{
@property Type foo(); // formal getter
@property void bar(Type); // formal setter
@property ref Type baz(); // ref return getter == auxiliary setter
}
S s;
static assert( __traits(compiles, { s.foo; }));
static assert(!__traits(compiles, { s.foo(); }));
static assert(is(typeof(s.foo) == Type));
static assert(is(typeof(&s.foo) == Type delegate()));
static assert( __traits(compiles, { s.bar = 1; }));
static assert(!__traits(compiles, { s.bar(1); }));
static assert(is(typeof(s.bar)) == false);
static assert(is(typeof(&s.bar) == void delegate(Type)));
static assert( __traits(compiles, { s.baz; }));
static assert(!__traits(compiles, { s.baz(); }));
static assert( __traits(compiles, { s.baz = 1; }));
static assert(is(typeof(s.baz) == Type));
static assert(is(typeof(&s.foo) == ref Type delegate()));
}
unittest
{
struct S
{
Type foo(); // 0-arg function
void bar(Type n); // 1-arg function
ref Type baz(); // 0-arg ref return function
}
S s;
static assert( __traits(compiles, { s.foo; }));
static assert( __traits(compiles, { s.foo(); }));
static assert(is(typeof(s.foo) == Type));
static assert(is(typeof(&s.foo) == Type delegate()));
static assert(!__traits(compiles, { s.bar = 1; }));
static assert( __traits(compiles, { s.bar(1); }));
static assert(is(typeof(s.bar)) == false);
static assert(is(typeof(&s.bar) == void delegate(Type)));
static assert( __traits(compiles, { s.baz; }));
static assert( __traits(compiles, { s.baz = 1; }));
static assert( __traits(compiles, { s.baz(); }));
static assert(is(typeof(s.baz) == Type));
static assert(is(typeof(&s.baz) == ref Type delegate()));
}
@property Type foo();
@property void bar(Type);
@property ref Type baz();
unittest
{
static assert( __traits(compiles, { foo; }));
static assert(!__traits(compiles, { foo(); }));
static assert(is(typeof(foo) == Type));
static assert(is(typeof(&foo) == Type function()));
static assert( __traits(compiles, { bar = 1; }));
static assert(!__traits(compiles, { bar(1); }));
static assert(is(typeof(bar)) == false);
static assert(is(typeof(&bar) == Type function()));
static assert( __traits(compiles, { baz; }));
static assert(!__traits(compiles, { baz(); }));
static assert( __traits(compiles, { baz = 1; }));
static assert(!__traits(compiles, { baz() = 1; }));
static assert(is(typeof(baz) == Type));
static assert(is(typeof(&baz) == ref Type function()));
}
@property Type foh(Type);
@property void bah(Type n, Type m);
@property ref Type bas(Type);
Type hoo(Type);
void var(Type, Type);
ref Type vaz(Type);
unittest
{
static assert( __traits(compiles, { foh = 1; }) &&
!__traits(compiles, { hoo = 1; }));
static assert(!__traits(compiles, { foh(1); }) &&
__traits(compiles, { hoo(1); }));
static assert(!__traits(compiles, { 1.foh; }) &&
__traits(compiles, { 1.hoo; }));
static assert(!__traits(compiles, { 1.foh(); }) &&
__traits(compiles, { 1.hoo(); }));
static assert(!__traits(compiles, { bah(1, 2); }) &&
__traits(compiles, { var(1, 2); }));
static assert( __traits(compiles, { 1.bah = 2; }) &&
!__traits(compiles, { 1.var = 2; }));
static assert(!__traits(compiles, { 1.bah(2); }) &&
__traits(compiles, { 1.var(2); }));
static assert( __traits(compiles, { bas = 1; }) &&
!__traits(compiles, { vaz = 1; }));
static assert(!__traits(compiles, { bas(1); }) &&
__traits(compiles, { vaz(1); }));
static assert(!__traits(compiles, { bas(1) = 2; }) &&
__traits(compiles, { vaz(1) = 2; }));
static assert(!__traits(compiles, { 1.bas; }) &&
__traits(compiles, { 1.vaz; }));
static assert(!__traits(compiles, { 1.bas = 2; }) &&
__traits(compiles, { 1.vaz = 2; }));
static assert(!__traits(compiles, { 1.bas(); }) &&
__traits(compiles, { 1.vaz(); }));
static assert(!__traits(compiles, { 1.bas() = 2; }) &&
__traits(compiles, { 1.vaz() = 2; }));
}
Is this correct?
Kenji Hara
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20130203/9133bbba/attachment-0001.html>
More information about the Digitalmars-d
mailing list