[core.reflect] looking at module dependencies

Stefan Koch uplink.coder at googlemail.com
Fri Oct 1 14:56:10 UTC 2021


On Friday, 1 October 2021 at 14:44:24 UTC, Stefan Koch wrote:
> Good day everyone,
>
> I know multiple programs have been written in order to make 
> sense of phobos dependencies.
>
> I am going to show how you can get the set of modules a module 
> is 'statically' dependent upon.  (this means the set won't 
> include non-instantiated templates. or failing `static if` 
> statements)
>
> ```D
> import core.reflect.reflect;
> import core.reflect.transitiveVisitor;
>
> import std_traits = std.traits;
> import std_stdio = std.stdio;
> import core.stdc.stdio;
>
> static immutable node = nodeFromName("std_traits", 
> ReflectFlags.Everything);
> static immutable node2 = nodeFromName("std_stdio", 
> ReflectFlags.Everything);
>
> import std; // for basename join and writeln
>
> void main()
> {
>     auto std_traits_deps = referencedFiles(node);
>     auto std_stdio_deps = referencedFiles(node2);
>
>     writeln("std.traits deps: ", std_traits_deps.map!(e => 
> baseName(e)).join("\n"));
>     writeln("std.stdio deps: ", std_stdio_deps.map!(e => 
> baseName(e)).join(", "));
> }
>
> string[] referencedFiles(const Node n)
> {
>     class FileLocationVisitor : TransitiveVisitor
>     {
>         alias visit = TransitiveVisitor.visit;
>
>         override void visit(Location loc)
>         {
>             if (loc.filename !in fileSet)
>             {
>                 fileSet[loc.filename] = 1;
>             }
>         }
>
>         int[string] fileSet;
>     }
>
>     scope fileLocationCollector = new FileLocationVisitor();
>     (cast()n).accept(fileLocationCollector);
>
>     return fileLocationCollector.fileSet.keys;
> }
> ```
>
> and the result of these few lines is the following output.
>
> ```
> std.traits deps: traits.d
> std.stdio deps: , time.d, string.d, memory.d-mixin-32, errno.d, 
> checkedint.d, uio.d, time.d, stdio.d, capacity.d, functional.d, 
> array.d, atomic.d, comparison.d, utf.d, memory.d, inet.d, 
> string.d, atomic.d-mixin-324, lifetime.d, time.d, unistd.d, 
> atomic.d-mixin-271, destruction.d, equality.d, mutation.d, 
> traits.d, conv.d, atomic.d, comparison.d, demangle.d, 
> cstring.d, functional.d-mixin-446, bitop.d, in_.d, sysv_x64.d, 
> hash.d, stdlib.d, fcntl.d, memory.d, lifetime.d, exception.d, 
> exception.d, stdio.d, wchar_.d, netdb.d, ascii.d, stdio.d, 
> socket.d, typecons.d, object.d, convert.d, stdio.d-mixin-5219, 
> traits.d-mixin-127, signal.d
> ```
>
> Which could surely be prettified. with the appropriate Phobos 
> range functions.
> So now you know :) why hello world takes ages. importing 
> std.stdio pulls in the world :)
>
> Please let me know if this needs more explanation and if you 
> found the usage of core.reflect intuitive.

Note. Those are only the _direct_ dependencies as I don't crawl 
the import-graph right now.
Reflecting over import graphs is currently being implemented.
However the trees get so huge that I have trouble debugging it.



More information about the Digitalmars-d mailing list