marlersoft / win32jsongen

Generates the JSON Win32 metadata files for: https://github.com/marlersoft/win32json
MIT License
35 stars 11 forks source link

Cyclic Dependency Resolution #2

Open marler8997 opened 3 years ago

marler8997 commented 3 years ago

Some languages cannot handle cyclic dependencies between modules (i.e. Go, Odin). I've created this issue to see if we can address this.

The current idea is to create a post-processing tool that will transform the JSON files in such a way that languages without inter-module cyclic dependency support can use a set of JSON files without any of these cyclic dependencies.

My current idea is to split JSON files into multiple "levels" in such a way as to remove all cyclic dependencies. I believe this could be done by ensuring that declarations from "higher level" JSON files never reference types from "lower level" ones. So a module "Foo.json" could get split into multiple files like this:

Foo.json
Foo.level1.json
Foo.level2.json
...

The transformation guarantees that types from "higher levels" never reference types from "lower levels". So in this case, "Foo.level2.json" never references declarations from "Foo.level1.json" nor "Foo.json".

Also note that constants/functions are never referenced within the metadata itself, it is only types that are referenced. This means that "Foo.levelX.json" files will only contains types.

Along with this, the transformation will also add an extra field to all ApiRef types that indicate the "Level" the type is now located, so binding generators can know which file the type come from.

Also note that I expect that the main module generated from "Foo" would also expose the types from its higher level modules through aliases. In order to do this, maybe we can add additional typedef types inside the main module that point to the types in the higher level modules.

Note that if there are types that have "direct cyclic dependencies" between modules, then this solution will need an additional mechanism, namely, the generation of new modules for holding the combination of types that contain these directly cyclic dependencies.

marler8997 commented 3 years ago

As of version 10.0.19041.202-preview, there are 28,676 type definitions (this does not include constants/functions). 559 of those are involved in "inter-module cycles". So around 2% of all types in the metadata have cyclic import dependencies.

NOTE: there could be bugs in my tool so this number might be wrong

So, one way to solve this is to move all these "cyclic types" into a single module that would serve is the "core" of the metadata to house any types that have these cyclic dependencies.