Skip to content

Commit

Permalink
Merge pull request #7106 from JinShil/static_alias_this_3
Browse files Browse the repository at this point in the history
Fix Issue 17684 - [REG 2.062] static alias this (Part 3)
  • Loading branch information
WalterBright committed Aug 30, 2017
2 parents 6a52bfa + bc8d7d8 commit c179e9c
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 60 deletions.
25 changes: 25 additions & 0 deletions src/ddmd/expressionsem.d
Expand Up @@ -4312,6 +4312,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
result = ex;
return;
}

// for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
if (e.e1.op == TOKtype)
e.e1 = resolveAliasThis(sc, e.e1);

e.e1 = resolveProperties(sc, e.e1);
e.e1 = e.e1.toBoolean(sc);
if (e.e1.type == Type.terror)
Expand Down Expand Up @@ -7950,6 +7955,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor

// same as for AndAnd
Expression e1x = exp.e1.semantic(sc);

// for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
if (e1x.op == TOKtype)
e1x = resolveAliasThis(sc, e1x);

e1x = resolveProperties(sc, e1x);
e1x = e1x.toBoolean(sc);
uint cs1 = sc.callSuper;
Expand All @@ -7968,6 +7978,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor

Expression e2x = exp.e2.semantic(sc);
sc.mergeCallSuper(exp.loc, cs1);

// for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
if (e2x.op == TOKtype)
e2x = resolveAliasThis(sc, e2x);

e2x = resolveProperties(sc, e2x);

auto f1 = checkNonAssignmentArrayOp(e1x);
Expand Down Expand Up @@ -8022,6 +8037,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor

// same as for OrOr
Expression e1x = exp.e1.semantic(sc);

// for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
if (e1x.op == TOKtype)
e1x = resolveAliasThis(sc, e1x);

e1x = resolveProperties(sc, e1x);
e1x = e1x.toBoolean(sc);
uint cs1 = sc.callSuper;
Expand All @@ -8040,6 +8060,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor

Expression e2x = exp.e2.semantic(sc);
sc.mergeCallSuper(exp.loc, cs1);

// for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
if (e2x.op == TOKtype)
e2x = resolveAliasThis(sc, e2x);

e2x = resolveProperties(sc, e2x);

auto f1 = checkNonAssignmentArrayOp(e1x);
Expand Down
5 changes: 5 additions & 0 deletions src/ddmd/statementsem.d
Expand Up @@ -2796,6 +2796,11 @@ else
rs.exp = inferType(rs.exp, fld.treq.nextOf().nextOf());

rs.exp = rs.exp.semantic(sc);

// for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
if (rs.exp.op == TOKtype)
rs.exp = resolveAliasThis(sc, rs.exp);

rs.exp = resolveProperties(sc, rs.exp);
if (rs.exp.checkType())
rs.exp = new ErrorExp();
Expand Down
135 changes: 75 additions & 60 deletions test/runnable/test17684.d
@@ -1,117 +1,132 @@
struct IntFieldTest
struct StructField(T)
{
static int Field;
static T Field;
static alias Field this;
}

struct IntPropertyTest
struct StructProperty(T)
{
static int Field;
static T Field;

static @property int property()
static @property T property()
{
return Field;
}

static @property void property(int value)
static @property void property(T value)
{
Field = value;
}

static alias property this;
}

struct BoolFieldTest
class ClassField(T)
{
static bool Field;
static T Field;
static alias Field this;
}

struct BoolPropertyTest
class ClassProperty(T)
{
static bool Field;
static T Field;

static @property bool property()
static @property T property()
{
return Field;
}

static @property void property(bool value)
static @property void property(T value)
{
Field = value;
}

static alias property this;
}

void main()
bool boolTest(T)()
{
// Test `static alias this` to a field of boolean type
BoolFieldTest = false;
assert(BoolFieldTest == false);
alias t = T;

t = false; // tests AssignExp
assert(t == false);

bool boolValue = BoolFieldTest;
bool boolValue = t; // tests AssignExp
assert(boolValue == false);

BoolFieldTest = !BoolFieldTest;
assert(BoolFieldTest == true);
t = !t; // tests NotExp
assert(t == true);

boolValue = BoolFieldTest;
boolValue = t;
assert(boolValue == true);

// Test `static alias this` to a property of boolean type
BoolPropertyTest = false;
assert(BoolPropertyTest == false);
assert(boolValue && t); // tests AndAndExp
assert(t && boolValue);

boolValue = BoolPropertyTest;
assert(boolValue == false);
boolValue = false;
assert(boolValue || t); // tests OrOrExp
assert(t || boolValue);

BoolPropertyTest = !BoolPropertyTest;
assert(BoolPropertyTest == true);
assert(t != boolValue); // tests CmpExp
assert(boolValue != t);

boolValue = BoolPropertyTest;
assert(boolValue == true);

// Test `static alias this` to a field of int type
IntFieldTest = 42; // test assignment
assert(IntFieldTest == 42);

int intValue = IntFieldTest;
assert(intValue == 42);
boolValue = true;
assert(t == boolValue);
assert(boolValue == t);

IntFieldTest++; // test a few unary and binary operators
assert(IntFieldTest == 43);
t = true;
return t; // tests ReturnStatement
}

IntFieldTest += 1;
assert(IntFieldTest == 44);
int intTest(T)()
{
alias t = T;

IntFieldTest--;
assert(IntFieldTest == 43);
t = 42; // tests AssignExp
assert(t == 42);

IntFieldTest -= 1;
assert(IntFieldTest == 42);
int intValue = t;
assert(intValue == 42);

assert(~IntFieldTest == ~42);
assert(t == 42); // tests CmpExp
assert(42 == t);
assert(t != 43);
assert(43 != t);
assert(t < 43);
assert(43 > t);
assert(t <= 42);
assert(42 >= t);

// Test `static alias this` to a property of int type
IntPropertyTest = 42; // test assignment
assert(IntPropertyTest == 42);
// These currently don't work for properties due to https://issues.dlang.org/show_bug.cgi?id=8006
static if (!(typeid(T) is typeid(StructProperty!int)) && !(typeid(T) is typeid(ClassProperty!int)))
{
t++; // test a few unary and binary operators
assert(t == 43);

intValue = IntPropertyTest;
assert(intValue == 42);
t += 1;
assert(t == 44);

// These currently don't work due to https://issues.dlang.org/show_bug.cgi?id=8006
// IntPropertyTest++;
// assert(IntPropertyTest == 43);
t--;
assert(t == 43);

// IntPropertyTest += 1;
// assert(IntPropertyTest == 44);
t -= 1;
assert(t == 42);
}

// IntPropertyTest--;
// assert(IntPropertyTest == 43);
assert(~t == ~42); // tests ComExp

// IntPropertyTest -= 1;
// assert(IntPropertyTest == 42);
return t; // tests ReturnStatement
}

assert(~IntPropertyTest == ~42);
void main()
{
assert(boolTest!(StructField!(bool))());
assert(boolTest!(StructProperty!(bool))());
assert(boolTest!(ClassField!(bool))());
assert(boolTest!(ClassProperty!(bool))());

assert(intTest!(StructField!(int))() == 42);
assert(intTest!(StructProperty!(int))() == 42);
assert(intTest!(ClassField!(int))() == 42);
assert(intTest!(ClassProperty!(int))() == 42);
}

0 comments on commit c179e9c

Please sign in to comment.