fix: read every dependency entry through one pass over the array

The object form reached the umbrella's members and constructor but not its
includes: that emitter still read each element as a plain string, so a module
declared in object form came out as a member whose type was never included, and
the aggregate no longer compiled. It is the Qt-free umbrella, which is what
every universal core module and every cdylib module generates, so the form the
previous commit set out to support failed there in a new way rather than
working.

Reading the array element by element is what let one pass disagree with the
next, so no reader does that any more: dependencyNames() answers what an array
declares, once, and the emitters walk names. That leaves the entry form knowable
in exactly one place, and the includes and members of an aggregate can no longer
be built from different answers.

The umbrella emission moves to generator_lib alongside the per-module wrapper
emitters it mirrors, returning the text instead of writing it, so what it
generates can be asserted on directly; main.cpp writes what it returns. Output
for string-form dependencies is byte-identical in both API styles, with and
without interface dependencies.

The listing mode (`--metadata` with no `--module-dir`) went the same way — it
was the last reader still deciding on its own.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Dario Gabriel Lipicar
2026-07-31 01:30:27 -03:00
co-authored by Claude Opus 5
parent 0ad68c252e
commit a9ffd6b4d3
7 changed files with 305 additions and 157 deletions
@@ -394,12 +394,9 @@ ImplParseResult parseImplHeader(const QString& headerPath,
result.module.version = obj.value("version").toString().toStdString();
result.module.description = obj.value("description").toString().toStdString();
result.module.category = obj.value("category").toString().toStdString();
QJsonArray deps = obj.value("dependencies").toArray();
for (const QJsonValue& v : deps) {
const QString depName = dependencyName(v);
if (!depName.isEmpty())
result.module.depends.push_back(depName.toStdString());
}
const QJsonArray deps = obj.value("dependencies").toArray();
for (const QString& depName : dependencyNames(deps))
result.module.depends.push_back(depName.toStdString());
// Read events declared in metadata.json
QJsonArray events = obj.value("events").toArray();