Skip to content

Commit

Permalink
Allow ignoring built-in property names on call-exp and templatized pr…
Browse files Browse the repository at this point in the history
…operty with UFCS.

For array types, followings are already allowed:
  darr.init(...), sarr.ptr(...), aarr.stringof(...)

I'm not sure that it is a feature or bug, but if it's expected, following should work, too:
  arr.sort!"a>b"
  • Loading branch information
9rnsr committed Jun 4, 2012
1 parent e9538dc commit 41ad40e
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 8 deletions.
40 changes: 32 additions & 8 deletions src/expression.c
Expand Up @@ -7123,15 +7123,31 @@ Expression *DotTemplateInstanceExp::semantic(Scope *sc, int flag)
#endif

UnaExp::semantic(sc);
Expression *e = new DotIdExp(loc, e1, ti->name);
if (e1->op == TOKerror)
return e1;

if (e1->op == TOKimport && ((ScopeExp *)e1)->sds->isModule())
e = ((DotIdExp *)e)->semantic(sc, 1);
Expression *e;
DotIdExp *die = new DotIdExp(loc, e1, ti->name);

if (flag || !e1->type || e1->op == TOKtype ||
e1->op == TOKimport && ((ScopeExp *)e1)->sds->isModule())
{
e = die->semantic(sc, 1);
}
else
{
Type *t1b = e1->type->toBasetype();
if ((t1b->ty == Tarray || t1b->ty == Tsarray || t1b->ty == Taarray ||
t1b->ty == Tnull || t1b->isTypeBasic() && t1b->ty != Tvoid))
{
/* No built-in type has templatized property, so can short cut.
*/
return resolveUFCSProperties(sc, this);
}

unsigned errors = global.startGagging();
e = ((DotIdExp *)e)->semantic(sc, 1);
if (global.endGagging(errors) && !flag)
e = die->semantic(sc, 1);
if (global.endGagging(errors))
{
return resolveUFCSProperties(sc, this);
}
Expand Down Expand Up @@ -7381,9 +7397,13 @@ Expression *CallExp::resolveUFCS(Scope *sc)

//printf("resolveUCSS %s, e->op = %s\n", toChars(), Token::toChars(e->op));
Type *t = e->type->toBasetype();
if (t->ty == Taarray && !tiargs)
if (t->ty == Taarray)
{
if (ident == Id::remove)
if (tiargs)
{
goto Lshift;
}
else if (ident == Id::remove)
{
/* Transform:
* aa.remove(arg) into delete aa[arg]
Expand Down Expand Up @@ -7429,8 +7449,12 @@ Expression *CallExp::resolveUFCS(Scope *sc)
goto Lshift;
}
}
else if (t->ty == Tarray || t->ty == Tsarray)
else if (t->ty == Tarray || t->ty == Tsarray ||
t->ty == Tnull || t->isTypeBasic() && t->ty != Tvoid)
{
/* In basic, built-in types don't have normal and templatized
* member functions. So can short cut.
*/
Lshift:
if (!arguments)
arguments = new Expressions();
Expand Down
51 changes: 51 additions & 0 deletions test/runnable/ufcs.d
Expand Up @@ -110,6 +110,56 @@ void test2()
assert((s.nar!int = 2) == 2); assert((s.naz!int = 2) == 2);
}

/*******************************************/

auto init(T)(T val) { return 1; }

auto sort(alias fun, T)(T val) { return 1; }

@property auto max(alias fun, T)(T val) { return 1; }

@property auto infinity(alias opt, T)(T val) { return 1; }

void test3()
{
// See built-in 'init' property
assert(1 .init == 0);
assert([1] .init == null);
assert([1:1].init == null);
assert(1.0 .init is double.nan);
assert(10i .init is idouble.nan);
assert('c' .init == 0xFF);
assert("s" .init == null);

// x.init() has parens, so it runs UFCS call
assert( 1 .init() == 1);
assert([1] .init() == 1);
assert([1:1].init() == 1);
assert(1.0 .init() == 1);
assert(10i .init() == 1);
assert('c' .init() == 1);
assert("s" .init() == 1);

// x.init!YYY matches templatized UFCS call.
assert( 1 .init!int() == 1);
assert([1] .init!(int[])() == 1);
assert([1:1].init!(int[int])() == 1);
assert(1.0 .init!double() == 1);
assert(10i .init!idouble() == 1);
assert('c' .init!char() == 1);
assert("s" .init!string() == 1);

assert([1].sort!"a<b"() == 1);
assert([1].sort == [1]);

// templatized properties runs UFCS call.
assert(1024.max!"a<b" == 1);
assert(1024.max == int.max);

assert(3.14.infinity!"+" == 1);
assert(3.14.infinity == (double).infinity);
}

/*******************************************/
// 662

Expand Down Expand Up @@ -259,6 +309,7 @@ int main()
{
test1();
test2();
test3();
test682();
test3382();
test7670();
Expand Down

0 comments on commit 41ad40e

Please sign in to comment.