Header-first universal modules go header -> .lidl -> cdylib backend. The
impl-header parser captures /// and /** */ doc comments into method/event
descriptions, but the .lidl serializer emitted only the signature, so the
descriptions were dropped — introspection (lm methods / --json, getMethods)
then showed no docs (regressing the wrap-external-lib + tutorial doctests).
Serialize each method/event's description as a trailing `description "..."`
clause (escaped for the string literal; the lexer already decodes \\ \" \n
\t) and parse it back in parseMethodDef/parseEventDef. Module description
now escaped too. Verified: /// docs survive header -> .lidl -> getMethods.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Routing core universal modules through the cdylib backend surfaced gaps
between the cdylib subset and what the std apiStyle handled — a universal
module that built under std must also build as a header-first cdylib.
- lidl parser: restore the return-shape flags (resultReturn / jsonReturn)
from the parsed return TypeExpr, so a header -> .lidl -> cdylib round-trip
(the universal path, needed to feed the Qt glue) preserves the semantics
the impl-header parser sets from C++ types (StdLogosResult -> result;
LogosMap/LogosList -> json). Without this the cdylib codegen/eligibility
mis-handled result / map / list returns.
- cdylib eligibility + dispatch: `void` is not a lidlBuiltinType, so the
parser yields it as a Named "void" (header path uses empty name) — treat
both as void in the eligibility check and the dispatch (was relying on
lidlTypeToQt=="void", which didn't match Named "void" -> generated an
`auto result = <void call>`).
- typeSupported: accept `any` (both directions), `void`/`result` (returns),
arrays-of-any, and Map ({k:v}/LogosMap) — the Qt-free-via-nlohmann set.
Verified: a probe with void / LogosMap / LogosList / StdLogosResult /
const returns is cdylib-eligible and dispatches correctly.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* handle reserved words in names/parameters correctly
* parser: accept reserved words as dependency names too
Addresses review feedback on the depends list: parseMetadata() still
hard-required LidlToken::Ident for each entry, so a dependency named after a
keyword (e.g. `version`) would fail to parse even though lidlSerialize()
emits it unquoted. Use atName() there too, consistent with the
contextual-keyword rule applied to the other name positions. Adds a
KeywordAsDependencyName regression test.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>