Using ddmd to tighten up imports
Joakim via Digitalmars-d
digitalmars-d at puremagic.com
Thu Dec 25 11:09:31 PST 2014
I wanted a tool to help me find imported symbols, so that I can
import a module and use whatever I want from it initially (import
std.stdio;) then go back and selectively add the symbols I
actually used later (import std.stdio : writefln, writeln;).
Using ddmd to dump this info seemed enticing, so I contacted
Daniel and got him to push his latest ddmd port from a few weeks
ago:
https://github.com/yebblies/dmd/tree/newmagic
This new ddmd branch is only tested on Win32: it sometimes
segfaults in codegen on Linux/x86, but the frontend is all that's
needed so that's fine.
I looked through the ddmd source and found the spot in dsymbol.d
where the imported symbols are resolved. I dumped those resolved
symbols and disabled codegen in mars.d, so that I don't have to
see any segfaults. The tiny patch is here:
https://gist.github.com/joakim-noah/09cf49bee3d82b03a54f
There's no real reason to use ddmd- regular dmd can be used
instead with a slightly modified version of this patch- but I'd
like to see others use the ddmd frontend to write more tools like
this, so I'll detail the steps I took to build and use ddmd.
First, I pulled Dan's branch into my local dmd repo and checked
it out:
git remote add -t newmagic ddmd
https://github.com/yebblies/dmd.git
git fetch ddmd
git checkout -b newmagic ddmd/newmagic
Then, I built dmd and ddmd, after making sure I had a dmd.conf
and phobos built, as ddmd relies on phobos:
make -f posix.mak
cd src
make -f posix.mak ddmd
I applied the above patch and rebuilt ddmd:
git apply import.patch
make -f posix.mak ddmd
Finally, I ran it on a sample file:
./ddmd ../samples/sieve.d
That dumps out 2054 instances of symbols that are resolved from
either the sample file or all the other modules it imports. To
see only what the sample file imports:
./ddmd ../samples/sieve.d | grep "from ../samples/sieve.d"
found writefln from ../samples/sieve.d:12 in
./../../phobos/std/stdio.d:3063 - 'writefln(T...)(T args)'
found writefln from ../samples/sieve.d:39 in
./../../phobos/std/stdio.d:3063 - 'writefln(T...)(T args)'
That shows two invocations of writefln from sieve.d and where
they were imported from.
I tried running this modified ddmd on std.stdio (ddmd -c
../../phobos/std/stdio.d) and more narrowly scoping some of the
imports, PR in progress:
https://github.com/D-Programming-Language/phobos/pull/2809
However, I found that the more narrowly scoped imports in
std.stdio would compile fine with dmd, but the entire phobos
would not. Turns out the problem is that imported symbols from
templates are not searched for if the module is compiled without
instantiating them, so I got around this by building the unit
tests:
./ddmd -unittest ../../phobos/std/stdio.d | grep "from
../../phobos/std/stdio.d"
That found many more resolved symbols- 764 instances of resolved
symbol imports as opposed to 156 when simply compiling the
module- and after updating std.stdio with those new symbols, I
had no problem building phobos or running its unit tests.
Obviously, this simple output can be cleaned up and made much
more user-friendly and a lot more such tools can be built using
the ddmd frontend. Another cleanup I'd like to use is to write
code with auto types everywhere, then employ a similar tool to
replace them with the actual inferred types, saving me from
looking up the types.
I hope this spurs others to try building similar tools based on
the ddmd frontend, happy ddmd spelunking!
More information about the Digitalmars-d
mailing list