Skip to content

Commit 00977b0

Browse files
committed
deduplicate the 'isSomeFunction' equivalent
1 parent 86e66c5 commit 00977b0

1 file changed

Lines changed: 63 additions & 60 deletions

File tree

src/dmd/traits.d

Lines changed: 63 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module dmd.traits;
1414

1515
import core.stdc.stdio;
1616
import core.stdc.string;
17+
1718
import dmd.aggregate;
1819
import dmd.arraytypes;
1920
import dmd.canthrow;
@@ -444,6 +445,52 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)
444445
return new IntegerExp(e.loc, false, Type.tbool);
445446
}
446447

448+
/**
449+
Gets a function type from a given AST node
450+
if the node is a function of some sort.
451+
452+
Params:
453+
o = an AST node to check for a `TypeFunction`
454+
fdp = optional pointer to a function declararion, to be set
455+
if `o` is a function declarartion.
456+
457+
Returns:
458+
a type node if `o` is a declaration of
459+
a delegate, function, function-pointer
460+
or a variable of the former. Otherwise, `null`.
461+
*/
462+
463+
static TypeFunction traitsFuncArg(RootObject o, FuncDeclaration* fdp = null)
464+
{
465+
auto s = getDsymbolWithoutExpCtx(o);
466+
auto t = isType(o);
467+
TypeFunction tf = null;
468+
469+
if (s)
470+
{
471+
auto fd = s.isFuncDeclaration();
472+
if (fd)
473+
{
474+
t = fd.type;
475+
if (fdp)
476+
*fdp = fd;
477+
}
478+
else if (auto vd = s.isVarDeclaration())
479+
t = vd.type;
480+
}
481+
if (t)
482+
{
483+
if (t.ty == Tfunction)
484+
tf = cast(TypeFunction)t;
485+
else if (t.ty == Tdelegate)
486+
tf = cast(TypeFunction)t.nextOf();
487+
else if (t.ty == Tpointer && t.nextOf().ty == Tfunction)
488+
tf = cast(TypeFunction)t.nextOf();
489+
}
490+
491+
return tf;
492+
}
493+
447494
Expression isX(T)(bool function(T) fp)
448495
{
449496
if (!dim)
@@ -978,26 +1025,8 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)
9781025
if (dim != 1)
9791026
return dimError(1);
9801027

981-
auto o = (*e.args)[0];
982-
auto s = getDsymbolWithoutExpCtx(o);
983-
auto t = isType(o);
984-
TypeFunction tf = null;
985-
if (s)
986-
{
987-
if (auto fd = s.isFuncDeclaration())
988-
t = fd.type;
989-
else if (auto vd = s.isVarDeclaration())
990-
t = vd.type;
991-
}
992-
if (t)
993-
{
994-
if (t.ty == Tfunction)
995-
tf = cast(TypeFunction)t;
996-
else if (t.ty == Tdelegate)
997-
tf = cast(TypeFunction)t.nextOf();
998-
else if (t.ty == Tpointer && t.nextOf().ty == Tfunction)
999-
tf = cast(TypeFunction)t.nextOf();
1000-
}
1028+
TypeFunction tf = traitsFuncArg((*e.args)[0]);
1029+
10011030
if (!tf)
10021031
{
10031032
e.error("first argument is not a function");
@@ -1028,27 +1057,18 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)
10281057
LINK link;
10291058
int varargs;
10301059
auto o = (*e.args)[0];
1031-
auto t = isType(o);
1032-
TypeFunction tf = null;
1033-
if (t)
1034-
{
1035-
if (t.ty == Tfunction)
1036-
tf = cast(TypeFunction)t;
1037-
else if (t.ty == Tdelegate)
1038-
tf = cast(TypeFunction)t.nextOf();
1039-
else if (t.ty == Tpointer && t.nextOf().ty == Tfunction)
1040-
tf = cast(TypeFunction)t.nextOf();
1041-
}
1060+
1061+
FuncDeclaration fd;
1062+
TypeFunction tf = traitsFuncArg(o, &fd);
1063+
10421064
if (tf)
10431065
{
10441066
link = tf.linkage;
10451067
varargs = tf.varargs;
10461068
}
10471069
else
10481070
{
1049-
auto s = getDsymbol(o);
1050-
FuncDeclaration fd;
1051-
if (!s || (fd = s.isFuncDeclaration()) is null)
1071+
if (!fd)
10521072
{
10531073
e.error("argument to `__traits(getFunctionVariadicStyle, %s)` is not a function", o.toChars());
10541074
return new ErrorExp();
@@ -1078,29 +1098,20 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)
10781098
if (dim != 2)
10791099
return dimError(2);
10801100

1081-
auto o1 = (*e.args)[1];
10821101
auto o = (*e.args)[0];
1083-
auto t = isType(o);
1084-
TypeFunction tf = null;
1085-
if (t)
1086-
{
1087-
if (t.ty == Tfunction)
1088-
tf = cast(TypeFunction)t;
1089-
else if (t.ty == Tdelegate)
1090-
tf = cast(TypeFunction)t.nextOf();
1091-
else if (t.ty == Tpointer && t.nextOf().ty == Tfunction)
1092-
tf = cast(TypeFunction)t.nextOf();
1093-
}
1102+
auto o1 = (*e.args)[1];
1103+
1104+
FuncDeclaration fd;
1105+
TypeFunction tf = traitsFuncArg(o, &fd);
1106+
10941107
Parameters* fparams;
10951108
if (tf)
10961109
{
10971110
fparams = tf.parameters;
10981111
}
10991112
else
11001113
{
1101-
auto s = getDsymbol(o);
1102-
FuncDeclaration fd;
1103-
if (!s || (fd = s.isFuncDeclaration()) is null)
1114+
if (!fd)
11041115
{
11051116
e.error("first argument to `__traits(getParameterStorageClasses, %s, %s)` is not a function",
11061117
o.toChars(), o1.toChars());
@@ -1180,17 +1191,9 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)
11801191

11811192
LINK link;
11821193
auto o = (*e.args)[0];
1183-
auto t = isType(o);
1184-
TypeFunction tf = null;
1185-
if (t)
1186-
{
1187-
if (t.ty == Tfunction)
1188-
tf = cast(TypeFunction)t;
1189-
else if (t.ty == Tdelegate)
1190-
tf = cast(TypeFunction)t.nextOf();
1191-
else if (t.ty == Tpointer && t.nextOf().ty == Tfunction)
1192-
tf = cast(TypeFunction)t.nextOf();
1193-
}
1194+
1195+
TypeFunction tf = traitsFuncArg(o);
1196+
11941197
if (tf)
11951198
link = tf.linkage;
11961199
else

0 commit comments

Comments
 (0)