Move lib and scan modules into a package#12766
Conversation
|
Thanks for your pull request and interest in making D better, @thewilsonator! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub run digger -- build "master + dmd#12766" |
|
We've extensively discussed this. Not doing packages. |
|
Nope |
8be3827 to
1c14f8d
Compare
wilzbach
left a comment
There was a problem hiding this comment.
There's zero harm in them and it drastically helps newcomers to get around in the code base.
Walter, as a newcomer to the dmd codebase, I legitimately don't understand why you are so adamant of being against organizing the files in a way that promotes encapsulation, by using packages here. I have talk about it in discord where the expresstionsem file seemed to be importing modules from everywhere with no regards to being organized. |
|
We've been over that many times, including yet another discussion about it recently in the n.g. |
WalterBright
left a comment
There was a problem hiding this comment.
Not approved. See many discussions about this, in the n.g. and at DConf.
Well you have been known to change your mind from time to time, I'm sure @thewilsonator had hope this was one of those cases :) The discussion on the n.g. boiled down to encapsulation. My takeaway from it - correct me if I'm wrong - was that packaging should be done to increase encapsulation, and that spilling modules into package that imports each other is a waste of time. But what @thewilsonator chose as a starting point is a textbook example of packages.
In that regard, making
I'm still very doubtful of some of the packages structures that were floated around in the newsgroup, but this is an obvious case where packages can be used. |
1c14f8d to
7dff295
Compare
On the contrary #12744 (comment) the number of files in
Indeed, there are only two sets of modules that are close to being as encapsulated as they can possibly be and fit for becoming packages at the moment:
|
|
@thewilsonator can you incorporate @Geod24's explanation of the changes in the commit message and PR description? Otherwise, obviously LGTM. |
That's mostly right. I've attempted to prevent a lot of it, such as repeated attempts to have the backend code import from the front end, and root importing from the dmd level. dmd level modules each import every other dmd module (more or less). There is no hierarchy. At one time cparse.d imported target.d, which transitively imports everything else in dmd. @ibuclaw and I worked together to successfully remove that dependency. We could go further and eliminate nearly all dependencies from target.d. There's no reason target.d should be importing statement.d. That sort of work will be worth while. Not having a fake package hierarchy that the code implementation does not remotely respect. For people who want an overview of what the files are, see https://github.com/dlang/dmd/blob/master/src/dmd/README.md which does a more readable and thorough job than any misleading, fake package hierarchy. It could be improved with links to the generated Ddoc documentation files for each module. (Which is why I harangue PR submitters to add proper Ddoc function comments.) I've said all this before, repeatedly. BTW, something that would make dmd much easier to work on would be:
|
Something we can all agree on. I can't recall a seasoned DMD contributors arguing against this rule. I do recall having broken this rule myself, by mistake. This was corrected by @ibuclaw in #10720 and as you can see, there was no disagreement that it was the correct course of action. But that does not in any way justify "Never import a file from an uplevel directory". It doesn't refute any of the arguments that were made, by me or other contributors.
There is no apparent hierarchy to the modules. But there is an inherent hierarchy to DMD's code, otherwise it would be an unworkable mess. There are obvious separation between different components of DMD: the driver ( What us contributors are asking for is to be able to express this separation using D's native unit of encapsulation, a.k.a. the module. (While I'm using the term "module" here, it encompass packages as well - Modules can only scale when used with packages).
What is fake about
READMEs and conventions are no substitutes for using languages features for their intended use.
That's good. And can be pursued in parallel of packaging. The two do not conflict, nor is one a substitute for the other.
This has been worked on by contributors for years now, under the |
This is a misunderstanding. I wanted to remove it from the git source code base, and have it be auto-generated as part of the build process instead.
I'm very glad to see progress on this front. All the .h files need to be removed and auto-generated. It's the flip side of ImportC, which will hopefully eliminate most of the .h => .d conversion nuisance and consequent errors. We can't get to 100% with ImportC due to endless C extensions and things in C that are not representable in D. But we should be able to do 100% for .h file emission for |
I still have occasional doubts about whether integrating it into the compiler was the right choice. I originally had it as a dedicated external tool aimed specifically at translating dmd codebase by having inside knowledge about what equivalent special types are used internally, etc. By the time I stopped working on it, it was able to produce something that was 100% valid and compiled with the test C++ front-end. Whilst generalising it has no doubt made it better for all, it has regressed somewhat on its ability to translate dmd. I do fear that the choice to move it inside the compiler is holding it back though. For instance, why translate a non-trivially templated type (and all its forward referenced dependencies) when a Alas, I digress. :-) |
Emitted as
Indeed. The whole discussion about This PR improves the structure of the code base to make the 95% easier for contributors who have not yet been working on DMD for decades. |
MoonlightSentinel
left a comment
There was a problem hiding this comment.
Rationale outlined in #12766 (comment)
Done |
|
@WalterBright I think it's about time we embrace the D way of doing things in dmd :P We wouldn't be in the worst company: Clang C++ compiler: https://github.com/llvm/llvm-project/tree/llvmorg-12.0.0/clang/lib |
Good question. What dmd has is the package hierarchy literally upside down. May I suggest the chapter "The Dependency-Inversion Principle" in Robert Martin's book "Agile Software Development." https://www.amazon.com/Software-Development-Principles-Patterns-Practices/dp/0135974445
https://github.com/dlang/dmd/blob/master/src/dmd/README.md |
| /** | ||
| * A module defining an abstract library. | ||
| * Implementations for various formats are in separate `libXXX.d` modules. | ||
| * Implementations for various formats are in `src/dmd/lib/` modules. |
There was a problem hiding this comment.
Well technically that's not quite accurate:
- There is a 1-to-1 mapping between modules and files, but they are not the same concept. When referring to modules, we use the name in the
ModuleDeclaration, e.g.dmd.lib.elf; dmd.libstill containsscan*which are not implementation, more like helpers;
But since it's consistent with the previous wording, we can fix it later. I think we have an opportunity to remove the function-backed factory now that we are going with proper encapsulation.
| | [lib/package.d](https://github.com/dlang/dmd/blob/master/src/dmd/lib/package.d) | Abstract library class | | ||
| | [lib/elf.d](https://github.com/dlang/dmd/blob/master/src/dmd/lib/elf.d) | Library in ELF format (Unix) | | ||
| | [lib/mach.d](https://github.com/dlang/dmd/blob/master/src/dmd/lib/mach.d) | Library in Mach-O format (macOS) | | ||
| | [lib/mscoff.d](https://github.com/dlang/dmd/blob/master/src/dmd/lib/mscoff.d) | Library in COFF format (32/64-bit Windows) | | ||
| | [lib/omf.d](https://github.com/dlang/dmd/blob/master/src/dmd/lib/omf.d) | Library in OMF format (legacy 32-bit Windows) | | ||
| | [lib/scanelf.d](https://github.com/dlang/dmd/blob/master/src/dmd/lib/scanelf.d) | Extract symbol names from a library in ELF format | | ||
| | [lib/scanmach.d](https://github.com/dlang/dmd/blob/master/src/dmd/lib/scanmach.d) | Extract symbol names from a library in Mach-O format | | ||
| | [lib/scanmscoff.d](https://github.com/dlang/dmd/blob/master/src/dmd/lib/scanmscoff.d) | Extract symbol names from a library in COFF format | | ||
| | [lib/scanomf.d](https://github.com/dlang/dmd/blob/master/src/dmd/lib/scanomf.d) | Extract symbol names from a library in OMF format | |
There was a problem hiding this comment.
I think you can remove this entire table and simply add the 'lib' folder to 'Directory structure' at the start of the README.
The only symbols declared in these modules used outside them are declared in `src/lib.d`.
This commit changes:
* `lib{elf,mach,mscoff,omf}.d` => `lib/{elf,mach,mscoff,omf}.d`: Those files are only imported by a single module, dmd.lib;
* `lib.d` => `lib/package.d`: The single module importing `lib*.d`, which provides the single entry point for this package;
`scan*.d` => `lib/scan*.d`: Those files are never imported by modules except for the corresponding `lib/{elf,mach,mscoff,omf}.d`;
This increases encapsulation by:
* reducing the visibility of symbols in `scan*.d` to `dmd.lib`, so the context one needs looking at the module in isolation is reduced;
* it reduces the visibility of symbols in `{elf,mach,...}.d`;
* It signals to the reader that `package.d` is the entry point, based on a language feature, not coding convention;
|
@WalterBright Given that this PR has received 6 approvals from community members, are you inclined on accepting this? |
There is a clear consensus that this is what contributors want.
|
@WalterBright what are the pros of not encapsulating these files into packages? Are you worried it's gonna hamper yours and others productivity? |
The only symbols declared in these modules used outside them are declared in
src/lib.d.This commit changes:
lib{elf,mach,mscoff,omf}.d=>lib/{elf,mach,mscoff,omf}.d: Those files are only imported by a single module, dmd.lib;lib.d=>lib/package.d: The single module importinglib*.d, which provides the single entry point for this package;scan*.d=>lib/scan*.d: Those files are never imported by modules except for the correspondinglib/{elf,mach,mscoff,omf}.d;This increases encapsulation by:
scan*.dtodmd.lib, so the context one needs looking at the module in isolation is reduced;{elf,mach,...}.d;package.dis the entry point, based on a language feature, not coding conventionI hope I have all the doc links correct.