digitalmars.D.learn - List classes at compile time
- =?UTF-8?B?Tm/DqQ==?= Falzon (41/41) Oct 19 2024 tl;dr: is it possible to iterate over all classes in a program at
- evilrat (48/54) Oct 19 2024 No, parent class can not possibly know who extends it, just think
- =?UTF-8?B?Tm/DqQ==?= Falzon (3/3) Oct 21 2024 Thank you for the detailed answer! I will look into feasibility
tl;dr: is it possible to iterate over all classes in a program at
compile time (or possibly all derived classes from a given base
class) to use in a mixin?
Longer version:
Hi! I'm essentially trying to select which class to
instantiate/use as template argument based on a runtime string
(user provided). Something like:
```
string s = args[1];
if (s == "foo") { import foo; return Driver!Foo.run(); }
if (s == "bar") { import bar; return Driver!Bar.run(); }
if (s == "baz") { import baz; return Driver!Baz.run(); }
...
```
Using mixins, I managed to reduce this to:
```
static foreach(name; ["Foo", "Bar", "Baz"])
{
mixin(iq{
if (s == "$(name.toLower)")
{
import $(name.toLower);
return Driver!$(name).run();
}
}.text);
}
```
But it would be even nicer not to have to list the classes by
hand, of course (there might be hundreds eventually).
The closest I got so far is to generate the list of names with a
pre-build command that greps through the sources for relevant
class names, and a file import:
```
const names = import("names.csv").split(",");
```
But that feels like cheating, and it's of course error-prone
since it's text based. Also, if I'm going to run a pre-build
command, I might as well just generate the boilerplate source
code there and just compile the file directly.
Would there a cleaner, D-like way to achieve this? Or a
completely different approach to the problem?
Oct 19 2024
On Saturday, 19 October 2024 at 08:51:20 UTC, NoƩ Falzon wrote:tl;dr: is it possible to iterate over all classes in a program at compile time (or possibly all derived classes from a given base class) to use in a mixin?No, parent class can not possibly know who extends it, just think about dynamic libraries... And unfortunately there is no single place to know every possible module used in a build for various reasons, the closest thing you can do is obtain modules present in a separate compilation unit, i.e. a module with its imports. as seen with 'dummy' module parent, you cannot get above it. in this case dummy module is here, but if for example I also had another module I can't access it this way without importing it some way or another. ```d import std.stdio; import std.algorithm; import dummy; enum foo = "we need foo just to get something accessible in this module"; pragma(msg, __traits(allMembers, __traits(parent, foo))); // prints AliasSeq!("object", "std", "dummy", "foo") //pragma(msg, __traits(allMembers, __traits(parent, dummy))); // Error: argument `dummy` has no parent ```The closest I got so far is to generate the list of names with a pre-build command that greps through the sources for relevant class names, and a file import:The only improvement to this I can think of is to use D AST parser that reliably understands code structure. The example of this you can find in godot-d class finder, other than that it works exactly same. https://github.com/godot-dlang/godot-dlang/blob/534024c7e27522d6120a9b64e8ef183b79416539/modules/tools/classfinder/godot/tools/classfinder/package.d Just in case, there is a possible way to get modules at RUNTIME, and from there ModuleInfo has list of classes and other type information. https://dlang.org/phobos/object.html#.ModuleInfo.localClasses ```d import std.stdio; void main() { // ModuleInfo without parenthesis will call opDelegate to acquire list of modules known at runtime foreach(m; ModuleInfo) { writeln(m.name); } } ``` prints rt.lifetime rt.dmain2 core.internal.gc.proxy rt.deh_win64_posix core.exception ...
Oct 19 2024
Thank you for the detailed answer! I will look into feasibility at runtime, or I'll default back to generating the list programmatically to feed into the mixin.
Oct 21 2024








=?UTF-8?B?Tm/DqQ==?= Falzon <falzon.noe gmail.com>