Skip to content

feat(generator): emit the derived module identity methods - #141

Merged
dlipicar merged 2 commits into
masterfrom
feat/identity-methods
Aug 20, 2026
Merged

feat(generator): emit the derived module identity methods#141
dlipicar merged 2 commits into
masterfrom
feat/identity-methods

Conversation

@dlipicar

Copy link
Copy Markdown
Contributor

Runs logos-lidl's injectIdentityMethods() on every ModuleDecl this generator emits code from, and gives the cdylib dispatch a body for the two methods it adds.

Depends on logos-co/logos-lidl#10. flake.lock pins that branch until it merges.

Where injection goes

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

That 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 body

A derived identity method emits a literal 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, unchanged.

Verification

290/290 tests pass, 4 new. Worth noting what they pin:

  • the emitted literal is the module's own version — a fixture at 1.0.0 could not tell a correct generator from one silently falling back to the default
  • identity is listed for introspection as well as dispatched, so lm and untyped callers see what is callable
  • an author's own name() still reaches the impl (the logos-delivery-module case)
  • a versionless declaration falls back rather than emitting "", which would read as a failed call rather than as "unversioned"

End to end: test_basic_module_cpp — a universal module with zero source changes — answers nametest_basic_module_cpp and version1.0.0 through logoscore, and lm methods lists both with descriptions.

🤖 Generated with Claude Code

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>
@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown

📊 cpp-sdk doc-test report

The real accounts module, run through a logoscore daemon with the whole stack built against this commit of the C++ SDK — rendered alongside the commands actually run and their output (updated each run, commit 72b269e):

Pages can take a minute to update after the run finishes.

@dlipicar

Copy link
Copy Markdown
Contributor Author

On the red doc-tests

Two causes, both ordering rather than defects in this PR — recording the analysis so it isn't re-derived.

1. lidl/identity.hpp: No such file or directory

cpp-generator now needs logos-lidl with the identity pass (logos-co/logos-lidl#10). The doc-test builds logos-qt-generator from logos-qt-sdk master, and qt-sdk's flake declares:

logos-cpp-sdk.inputs.logos-lidl.follows = "logos-lidl";

so this repo compiles against the consumer's logos-lidl, not its own lock. qt-sdk master still pins the old one.

I initially read this as the vendored share/lidl-frontend/lidl_compat.h growing a dependency its consumers can't satisfy, and moved the helper into a private header to decouple it. That was wrong, and testing it said so: with the helper moved, the same combination still failed — one file earlier, inside cpp-sdk itself. The follows above is the coupling, and no header layout changes it. Reverted; this PR is unchanged.

Clears when logos-co/logos-lidl#10 merges and qt-sdk master's lidl pin advances — i.e. after logos-co/logos-qt-sdk#35, which re-points it.

2. capability_module ... declares no interface

The doc-test resolves an old logos-capability-module against module-builder master, which now rejects interface-less core modules. Already fixed upstream by the 2026-08-20 migration (c670f7f); the doc-test picks it up as its pins advance.

What is green

test passes here (290/290, 4 new). The identity chain is verified end to end on the integration gate — logos-co/logos-workspace#101 — where all four repos are pinned together: 18 of 21 test-module targets build, and the two failures reproduce with logos-qt-sdk swapped for plain master.

…anded

logos-co/logos-lidl#10 merged as ae3ffe0. The lock pointed at the PR branch
while it was open; this re-points it at master.

The narHash is unchanged across the move (sha256-WHmisUvYA8DQ2ZxSF2mM2...),
so the merged tree is byte-identical to the branch this was built and tested
against.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@dlipicar
dlipicar merged commit 1f69bca into master Aug 20, 2026
5 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant