Skip to content

Commit

Permalink
fix Issue 23558 - add __traits(getModuleClasses [, module name])
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Feb 7, 2023
1 parent 1661e1b commit 3bec540
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 2 deletions.
1 change: 1 addition & 0 deletions compiler/src/dmd/frontend.h
Expand Up @@ -8707,6 +8707,7 @@ struct Id final
static Identifier* getVisibility;
static Identifier* parent;
static Identifier* child;
static Identifier* getModuleClasses;
static Identifier* getMember;
static Identifier* getOverloads;
static Identifier* getVirtualFunctions;
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dmd/id.d
Expand Up @@ -462,6 +462,7 @@ immutable Msgtable[] msgtable =
{ "getVisibility" },
{ "parent" },
{ "child" },
{ "getModuleClasses" },
{ "getMember" },
{ "getOverloads" },
{ "getVirtualFunctions" },
Expand Down
59 changes: 58 additions & 1 deletion compiler/src/dmd/traits.d
Expand Up @@ -14,6 +14,7 @@
module dmd.traits;

import core.stdc.stdio;
import core.stdc.string;

import dmd.aggregate;
import dmd.arraytypes;
Expand Down Expand Up @@ -743,6 +744,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
auto se = new StringExp(e.loc, id.toString());
return se.expressionSemantic(sc);
}

if (e.ident == Id.fullyQualifiedName) // https://dlang.org/spec/traits.html#fullyQualifiedName
{
if (dim != 1)
Expand Down Expand Up @@ -779,6 +781,60 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
return se.expressionSemantic(sc);

}

if (e.ident == Id.getModuleClasses)
{
/* https://dlang.org/spec/traits.html#getModuleClasses
*/
Module m;
if (dim == 0)
{
m = sc._module; // default to current module
if (!m)
return False();
}
else if (dim == 1)
{
auto o = (*e.args)[0];
auto s = getDsymbol(o);
if (s)
{
if (auto imp = s.isImport())
m = imp.mod;
else
m = s.isModule();
}
if (!m)
{
e.error("in expression `%s` `%s` must be a module", e.toChars(), o.toChars());
return ErrorExp.get();
}
}
else
return dimError(0);

ClassDeclarations aclasses;
foreach (member; (*m.members)[])
{
//printf("\tmember '%s'\n", member.toChars());
member.addLocalClass(&aclasses); // same way genModuleInfo() does it
}

auto exps = new Expressions(aclasses.length);
foreach (i, cd; aclasses)
{
const p = cd.toPrettyChars();
//printf("class %s\n", p);
const s = p[0 .. strlen(p)];
auto se = new StringExp(e.loc, s);
(*exps)[i] = se;
}

Expression ex = new TupleExp(e.loc, exps);
ex = ex.expressionSemantic(sc);
return ex;
}

if (e.ident == Id.getProtection || e.ident == Id.getVisibility)
{
if (dim != 1)
Expand Down Expand Up @@ -2244,7 +2300,7 @@ private void traitNotFound(TraitsExp e)
initialized = true; // lazy initialization

// All possible traits
__gshared Identifier*[59] idents =
__gshared Identifier*[60] idents =
[
&Id.isAbstractClass,
&Id.isArithmetic,
Expand Down Expand Up @@ -2281,6 +2337,7 @@ private void traitNotFound(TraitsExp e)
&Id.child,
&Id.getLinkage,
&Id.getMember,
&Id.getModuleClasses,
&Id.getOverloads,
&Id.getVirtualFunctions,
&Id.getVirtualMethods,
Expand Down
17 changes: 17 additions & 0 deletions compiler/test/compilable/test23558.d
@@ -0,0 +1,17 @@
/* TEST_OUTPUT:
---
getModuleClasses: tuple("test23558.C")
getModuleClasses: tuple("std.stdio.StdioException")
---
*/

// https://issues.dlang.org/show_bug.cgi?id=23558

import std.stdio;

class C { }

pragma(msg, "getModuleClasses: ", __traits(getModuleClasses));
pragma(msg, "getModuleClasses: ", __traits(getModuleClasses, std.stdio));

//pragma(msg, "getClassInfos: ", __traits(getModuleClasses, 3));
3 changes: 2 additions & 1 deletion druntime/src/object.d
Expand Up @@ -246,7 +246,8 @@ class Object
* }
* ---
*/
deprecated static Object factory(string classname)
deprecated("use __traits(getModuleClasses) instead")
static Object factory(string classname)
{
auto ci = TypeInfo_Class.find(classname);
if (ci)
Expand Down

0 comments on commit 3bec540

Please sign in to comment.