mirror of
https://github.com/logos-co/logos-cpp-sdk.git
synced 2026-08-31 17:51:07 +00:00
feat(generator): emit the derived module identity methods
Run logos-lidl's injectIdentityMethods() on every ModuleDecl this generator
emits code from, and give the cdylib dispatch a body for the two methods it
adds.
Injection happens at EMISSION points, never at artifact points:
* generateInterfaceWrappers -- one load point covering both --dep and
--interface, so a consumer sees name()/version() on every dependency and
bound interface;
* --from-header --backend cdylib and --lidl --backend cdylib, so the provider
answers them;
* NOT --header-to-lidl, which writes the published contract.
The distinction is belt-and-braces rather than load-bearing: the injected
methods are `derived` and lidlSerialize omits those, so the .lidl a
--from-header build writes stays byte-identical to what --header-to-lidl writes
for the same header.
The dispatch emits a literal for a derived identity method instead of the usual
lidlImpl().<name>(...) -- the author's impl class has no such member, so
delegating would not compile. The literal is the module's own name and version,
so it cannot drift from the metadata the module was built with. A module that
declares name() itself is not derived and still reaches its impl.
290/290 tests pass, 4 new: that the emitted literal is the module's OWN version
(a test at 1.0.0 could not tell a correct generator from one that fell back),
that identity is listed for introspection as well as dispatched, that an
author's own name() still reaches the impl, and that a versionless declaration
falls back rather than emitting "" -- which would read as a failed call.
Requires logos-lidl#10; flake.lock pins that branch until it merges.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
f291efa2e8
commit
1e516c02ce
+34
-2
@@ -168,6 +168,18 @@ static bool generateInterfaceWrappers(const QVector<InterfaceSpec>& ifaces,
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Consumers see name()/version() on every dependency and bound
|
||||
// interface. Added here rather than read from the .lidl: the
|
||||
// artifact carries only what the author wrote, and the provider
|
||||
// adds the same two methods from the same function.
|
||||
QString idErr;
|
||||
if (!lidlInjectIdentity(mod, &idErr)) {
|
||||
err << spec.path << ": " << idErr << "\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
noteOptionalPositionalSlots(mod, spec.path, err);
|
||||
|
||||
const QString className = toPascalCase(spec.name);
|
||||
@@ -591,7 +603,14 @@ int main(int argc, char* argv[])
|
||||
return 4;
|
||||
}
|
||||
|
||||
const ModuleDecl& mod = pr.module;
|
||||
ModuleDecl mod = pr.module;
|
||||
{
|
||||
QString idErr;
|
||||
if (!lidlInjectIdentity(mod, &idErr)) {
|
||||
err << headerPath << ": " << idErr << "\n";
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
QString genDirPath = outputDir.isEmpty()
|
||||
? QDir::current().filePath("generated")
|
||||
: outputDir;
|
||||
@@ -617,6 +636,9 @@ int main(int argc, char* argv[])
|
||||
if (!mod.events.empty())
|
||||
outs.append({qs(mod.name) + "_events_cdylib.cpp",
|
||||
lidlMakeEventsSourceCdylib(mod, implClass, implHeader)});
|
||||
// Identity methods are `derived`, and lidlSerialize omits
|
||||
// those — so this stays byte-identical to what
|
||||
// --header-to-lidl writes for the same header.
|
||||
outs.append({qs(mod.name) + ".lidl", lidlSerialize(mod)});
|
||||
for (const Out& o : outs) {
|
||||
const QString abs = QDir(genDirPath).filePath(o.file);
|
||||
@@ -692,7 +714,17 @@ int main(int argc, char* argv[])
|
||||
<< " (line " << pr.errorLine << ")\n";
|
||||
return 4;
|
||||
}
|
||||
const ModuleDecl& mod = pr.module;
|
||||
ModuleDecl mod = pr.module;
|
||||
{
|
||||
// Contract-first: the committed .lidl is untouched; the
|
||||
// provider's dispatch and method listing gain the identity
|
||||
// methods the same way every consumer does.
|
||||
QString idErr;
|
||||
if (!lidlInjectIdentity(mod, &idErr)) {
|
||||
err << lidlPath << ": " << idErr << "\n";
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
QString cdErr;
|
||||
if (!lidlCdylibSupported(mod, &cdErr)) {
|
||||
err << "Error: module not cdylib-eligible: " << cdErr << "\n";
|
||||
|
||||
Reference in New Issue
Block a user