mirror of
https://github.com/logos-co/logos-tutorial.git
synced 2026-08-30 20:31:06 +00:00
demonstrate and validate method doc comments (wrapping-c-library)
Add /// doc comments to the calc module's methods and assert they surface via `lm methods` (human + --json) and `logoscore module-info`. Corrects the stale lm output (provider-path introspection lists only impl methods, not eventResponse/initLogos). Regenerated the tutorial markdown. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
3e77b0b333
commit
aa3cccb27a
@@ -370,14 +370,29 @@ public:
|
||||
// ── Public API — every method here is callable over IPC ──────────
|
||||
// The generator maps C++ types onto the wire automatically:
|
||||
// int64_t ↔ int std::string ↔ QString bool ↔ bool
|
||||
//
|
||||
// A `///` doc comment directly above a method becomes that method's
|
||||
// `description` in getMethods() — surfaced by `lm`, `logoscore
|
||||
// module-info`, and Basecamp's Methods list. (Plain `//` comments
|
||||
// like this block are ignored, so they never leak into the API.)
|
||||
|
||||
/// Adds two integers and returns the sum.
|
||||
int64_t add(int64_t a, int64_t b);
|
||||
|
||||
/// Multiplies two integers and returns the product.
|
||||
int64_t multiply(int64_t a, int64_t b);
|
||||
|
||||
/// Computes the factorial n! of a non-negative integer.
|
||||
int64_t factorial(int64_t n);
|
||||
|
||||
/// Returns the nth Fibonacci number (0-indexed).
|
||||
int64_t fibonacci(int64_t n);
|
||||
|
||||
/// Returns the version string of the wrapped libcalc C library.
|
||||
std::string libVersion();
|
||||
|
||||
// Fire-and-forget: looks up the version, then emits it as an event
|
||||
// instead of returning it. Used by the QML tutorial (Part 2).
|
||||
/// Looks up the library version and emits it as a `versionReady`
|
||||
/// event instead of returning it. Used by the QML tutorial (Part 2).
|
||||
void libVersionNotify();
|
||||
|
||||
// ── Events ───────────────────────────────────────────────────────
|
||||
@@ -409,6 +424,7 @@ logos_events:
|
||||
| `StdLogosResult` | `LogosResult` (from `<logos_result.h>`) — `{ success, value, error }` |
|
||||
|
||||
- Use `int64_t` for integers (not `int`) — that's the type the parser recognizes.
|
||||
- **Document methods with `///`.** A doc comment (`///` or `/** … */`) directly above a method becomes its `description` in the module's introspection, surfaced by `lm`, `logoscore module-info`, and Basecamp. Plain `//` comments are ignored, so only intentional docs are exposed — you'll see this in action in Step 5.
|
||||
- Events are declared in a `logos_events:` section. The token is recognized by the generator before preprocessing; under a normal compile it just expands to `public`.
|
||||
|
||||
### 3.5 `src/calc_module_impl.cpp` — Implementation
|
||||
@@ -585,48 +601,48 @@ Dependencies: (none)
|
||||
./lm/bin/lm methods result/lib/calc_module_plugin.dylib
|
||||
```
|
||||
|
||||
Output:
|
||||
Output — each method you declared, with its `///` doc comment shown on a
|
||||
`Description:` line:
|
||||
|
||||
```
|
||||
Plugin Methods:
|
||||
===============
|
||||
|
||||
void eventResponse(QString eventName, QVariantList args)
|
||||
Signature: eventResponse(QString,QVariantList)
|
||||
Invokable: no
|
||||
|
||||
void initLogos(LogosAPI* api)
|
||||
Signature: initLogos(LogosAPI*)
|
||||
Invokable: yes
|
||||
|
||||
int add(int a, int b)
|
||||
Signature: add(int,int)
|
||||
Invokable: yes
|
||||
Description: Adds two integers and returns the sum.
|
||||
|
||||
int multiply(int a, int b)
|
||||
Signature: multiply(int,int)
|
||||
Invokable: yes
|
||||
Description: Multiplies two integers and returns the product.
|
||||
|
||||
int factorial(int n)
|
||||
Signature: factorial(int)
|
||||
Invokable: yes
|
||||
Description: Computes the factorial n! of a non-negative integer.
|
||||
|
||||
int fibonacci(int n)
|
||||
Signature: fibonacci(int)
|
||||
Invokable: yes
|
||||
Description: Returns the nth Fibonacci number (0-indexed).
|
||||
|
||||
QString libVersion()
|
||||
Signature: libVersion()
|
||||
Invokable: yes
|
||||
Description: Returns the version string of the wrapped libcalc C library.
|
||||
|
||||
void libVersionNotify()
|
||||
Signature: libVersionNotify()
|
||||
Invokable: yes
|
||||
Description: Looks up the library version and emits it as a `versionReady` event instead of returning it. Used by the QML tutorial (Part 2).
|
||||
```
|
||||
|
||||
Notice the signatures are **Qt-typed** (`int`, `QString`) even though you wrote `int64_t` / `std::string`. That's the generated glue at work: `lm` is inspecting the synthesized Qt plugin, not your impl class. Your `int64_t add(int64_t, int64_t)` shows up on the wire as `add(int,int)`.
|
||||
Two things to notice:
|
||||
|
||||
The `eventResponse` signal and `initLogos` method are also part of the generated wrapper — you didn't write them. `initLogos` is how the host hands the module its `LogosAPI`; `eventResponse` is the channel your `versionReady` event travels over. Both come for free with `interface: universal`.
|
||||
- **Signatures are Qt-typed** (`int`, `QString`) even though you wrote `int64_t` / `std::string`. That's the generated glue: `lm` reports the wire types the synthesized Qt plugin exposes, so `int64_t add(int64_t, int64_t)` shows up as `add(int,int)`.
|
||||
- **Each `Description:` line is your `///` doc comment**, carried through the module's `getMethods()` introspection. Plain `//` comments (like the type-mapping note in the header) are deliberately ignored, so only intentional docs surface; an undocumented method simply omits the line. The same descriptions appear in `logoscore module-info` and Basecamp's Methods list.
|
||||
|
||||
### 5.4 JSON output
|
||||
|
||||
@@ -643,6 +659,7 @@ For scripting and CI, use `--json`:
|
||||
```json
|
||||
[
|
||||
{
|
||||
"description": "Adds two integers and returns the sum.",
|
||||
"isInvokable": true,
|
||||
"name": "add",
|
||||
"parameters": [
|
||||
@@ -656,6 +673,9 @@ For scripting and CI, use `--json`:
|
||||
]
|
||||
```
|
||||
|
||||
The `description` field is the method's `///` doc comment. Methods
|
||||
without a doc comment omit it.
|
||||
|
||||
---
|
||||
|
||||
## Step 6: Test with `logoscore`
|
||||
@@ -696,9 +716,9 @@ modules/calc_module/
|
||||
└── variant # Platform variant identifier
|
||||
```
|
||||
|
||||
### 6.3 Call methods
|
||||
### 6.3 Start the daemon and load the module
|
||||
|
||||
Start the daemon and call methods:
|
||||
Start the daemon and load `calc_module`:
|
||||
|
||||
```bash
|
||||
./logos/bin/logoscore -D -m ./modules &
|
||||
@@ -712,6 +732,43 @@ sleep 3
|
||||
./logos/bin/logoscore load-module calc_module
|
||||
```
|
||||
|
||||
### 6.4 Inspect methods and their docs
|
||||
|
||||
`module-info` lists each method with its signature and the `///` description you wrote — the same docs `lm` showed, here straight from the module's `getPluginMethods` introspection:
|
||||
|
||||
```bash
|
||||
./logos/bin/logoscore module-info calc_module
|
||||
```
|
||||
|
||||
```
|
||||
Name: calc_module
|
||||
Version: v1.0.0
|
||||
Status: loaded
|
||||
PID: 48213
|
||||
Uptime: 3s
|
||||
|
||||
Methods:
|
||||
add(a: int, b: int) -> int
|
||||
Adds two integers and returns the sum.
|
||||
multiply(a: int, b: int) -> int
|
||||
Multiplies two integers and returns the product.
|
||||
factorial(n: int) -> int
|
||||
Computes the factorial n! of a non-negative integer.
|
||||
fibonacci(n: int) -> int
|
||||
Returns the nth Fibonacci number (0-indexed).
|
||||
libVersion() -> QString
|
||||
Returns the version string of the wrapped libcalc C library.
|
||||
libVersionNotify() -> void
|
||||
Looks up the library version and emits it as a `versionReady` event instead of returning it. Used by the QML tutorial (Part 2).
|
||||
```
|
||||
|
||||
An undocumented method would still appear, just without the indented
|
||||
description line.
|
||||
|
||||
### 6.5 Call methods
|
||||
|
||||
Now call them:
|
||||
|
||||
```bash
|
||||
./logos/bin/logoscore call calc_module add 3 5
|
||||
```
|
||||
|
||||
@@ -369,14 +369,29 @@ sections:
|
||||
// ── Public API — every method here is callable over IPC ──────────
|
||||
// The generator maps C++ types onto the wire automatically:
|
||||
// int64_t ↔ int std::string ↔ QString bool ↔ bool
|
||||
//
|
||||
// A `///` doc comment directly above a method becomes that method's
|
||||
// `description` in getMethods() — surfaced by `lm`, `logoscore
|
||||
// module-info`, and Basecamp's Methods list. (Plain `//` comments
|
||||
// like this block are ignored, so they never leak into the API.)
|
||||
|
||||
/// Adds two integers and returns the sum.
|
||||
int64_t add(int64_t a, int64_t b);
|
||||
|
||||
/// Multiplies two integers and returns the product.
|
||||
int64_t multiply(int64_t a, int64_t b);
|
||||
|
||||
/// Computes the factorial n! of a non-negative integer.
|
||||
int64_t factorial(int64_t n);
|
||||
|
||||
/// Returns the nth Fibonacci number (0-indexed).
|
||||
int64_t fibonacci(int64_t n);
|
||||
|
||||
/// Returns the version string of the wrapped libcalc C library.
|
||||
std::string libVersion();
|
||||
|
||||
// Fire-and-forget: looks up the version, then emits it as an event
|
||||
// instead of returning it. Used by the QML tutorial (Part 2).
|
||||
/// Looks up the library version and emits it as a `versionReady`
|
||||
/// event instead of returning it. Used by the QML tutorial (Part 2).
|
||||
void libVersionNotify();
|
||||
|
||||
// ── Events ───────────────────────────────────────────────────────
|
||||
@@ -407,6 +422,7 @@ sections:
|
||||
| `StdLogosResult` | `LogosResult` (from `<logos_result.h>`) — `{ success, value, error }` |
|
||||
|
||||
- Use `int64_t` for integers (not `int`) — that's the type the parser recognizes.
|
||||
- **Document methods with `///`.** A doc comment (`///` or `/** … */`) directly above a method becomes its `description` in the module's introspection, surfaced by `lm`, `logoscore module-info`, and Basecamp. Plain `//` comments are ignored, so only intentional docs are exposed — you'll see this in action in Step 5.
|
||||
- Events are declared in a `logos_events:` section. The token is recognized by the generator before preprocessing; under a normal compile it just expands to `public`.
|
||||
|
||||
- title: "`src/calc_module_impl.cpp` — Implementation"
|
||||
@@ -570,49 +586,51 @@ sections:
|
||||
- "int factorial(int n)"
|
||||
- "int fibonacci(int n)"
|
||||
- "QString libVersion()"
|
||||
- "Description: Adds two integers and returns the sum."
|
||||
- "Description: Returns the version string of the wrapped libcalc C library."
|
||||
post_text: |
|
||||
Output:
|
||||
Output — each method you declared, with its `///` doc comment shown on a
|
||||
`Description:` line:
|
||||
|
||||
```
|
||||
Plugin Methods:
|
||||
===============
|
||||
|
||||
void eventResponse(QString eventName, QVariantList args)
|
||||
Signature: eventResponse(QString,QVariantList)
|
||||
Invokable: no
|
||||
|
||||
void initLogos(LogosAPI* api)
|
||||
Signature: initLogos(LogosAPI*)
|
||||
Invokable: yes
|
||||
|
||||
int add(int a, int b)
|
||||
Signature: add(int,int)
|
||||
Invokable: yes
|
||||
Description: Adds two integers and returns the sum.
|
||||
|
||||
int multiply(int a, int b)
|
||||
Signature: multiply(int,int)
|
||||
Invokable: yes
|
||||
Description: Multiplies two integers and returns the product.
|
||||
|
||||
int factorial(int n)
|
||||
Signature: factorial(int)
|
||||
Invokable: yes
|
||||
Description: Computes the factorial n! of a non-negative integer.
|
||||
|
||||
int fibonacci(int n)
|
||||
Signature: fibonacci(int)
|
||||
Invokable: yes
|
||||
Description: Returns the nth Fibonacci number (0-indexed).
|
||||
|
||||
QString libVersion()
|
||||
Signature: libVersion()
|
||||
Invokable: yes
|
||||
Description: Returns the version string of the wrapped libcalc C library.
|
||||
|
||||
void libVersionNotify()
|
||||
Signature: libVersionNotify()
|
||||
Invokable: yes
|
||||
Description: Looks up the library version and emits it as a `versionReady` event instead of returning it. Used by the QML tutorial (Part 2).
|
||||
```
|
||||
|
||||
Notice the signatures are **Qt-typed** (`int`, `QString`) even though you wrote `int64_t` / `std::string`. That's the generated glue at work: `lm` is inspecting the synthesized Qt plugin, not your impl class. Your `int64_t add(int64_t, int64_t)` shows up on the wire as `add(int,int)`.
|
||||
Two things to notice:
|
||||
|
||||
The `eventResponse` signal and `initLogos` method are also part of the generated wrapper — you didn't write them. `initLogos` is how the host hands the module its `LogosAPI`; `eventResponse` is the channel your `versionReady` event travels over. Both come for free with `interface: universal`.
|
||||
- **Signatures are Qt-typed** (`int`, `QString`) even though you wrote `int64_t` / `std::string`. That's the generated glue: `lm` reports the wire types the synthesized Qt plugin exposes, so `int64_t add(int64_t, int64_t)` shows up as `add(int,int)`.
|
||||
- **Each `Description:` line is your `///` doc comment**, carried through the module's `getMethods()` introspection. Plain `//` comments (like the type-mapping note in the header) are deliberately ignored, so only intentional docs surface; an undocumented method simply omits the line. The same descriptions appear in `logoscore module-info` and Basecamp's Methods list.
|
||||
|
||||
- title: "JSON output"
|
||||
text: "For scripting and CI, use `--json`:"
|
||||
@@ -625,10 +643,12 @@ sections:
|
||||
./lm/bin/lm methods result/lib/calc_module_plugin.dylib --json
|
||||
expect_contains:
|
||||
- '"name": "add"'
|
||||
- '"description": "Adds two integers and returns the sum."'
|
||||
post_text: |
|
||||
```json
|
||||
[
|
||||
{
|
||||
"description": "Adds two integers and returns the sum.",
|
||||
"isInvokable": true,
|
||||
"name": "add",
|
||||
"parameters": [
|
||||
@@ -642,6 +662,9 @@ sections:
|
||||
]
|
||||
```
|
||||
|
||||
The `description` field is the method's `///` doc comment. Methods
|
||||
without a doc comment omit it.
|
||||
|
||||
# ── Step 6: Test with logoscore ─────────────────────────────────────────────
|
||||
- title: "Test with `logoscore`"
|
||||
step: true
|
||||
@@ -667,15 +690,49 @@ sections:
|
||||
└── variant # Platform variant identifier
|
||||
```
|
||||
|
||||
- title: "Call methods"
|
||||
text: "Start the daemon and call methods:"
|
||||
- title: "Start the daemon and load the module"
|
||||
text: "Start the daemon and load `calc_module`:"
|
||||
run: "./logos/bin/logoscore -D -m ./modules &"
|
||||
|
||||
- run: "sleep 3"
|
||||
|
||||
- run: "./logos/bin/logoscore load-module calc_module"
|
||||
|
||||
- run: "./logos/bin/logoscore call calc_module add 3 5"
|
||||
- title: "Inspect methods and their docs"
|
||||
text: "`module-info` lists each method with its signature and the `///` description you wrote — the same docs `lm` showed, here straight from the module's `getPluginMethods` introspection:"
|
||||
run: "./logos/bin/logoscore module-info calc_module"
|
||||
expect_contains:
|
||||
- "Adds two integers and returns the sum."
|
||||
- "Returns the version string of the wrapped libcalc C library."
|
||||
post_text: |
|
||||
```
|
||||
Name: calc_module
|
||||
Version: v1.0.0
|
||||
Status: loaded
|
||||
PID: 48213
|
||||
Uptime: 3s
|
||||
|
||||
Methods:
|
||||
add(a: int, b: int) -> int
|
||||
Adds two integers and returns the sum.
|
||||
multiply(a: int, b: int) -> int
|
||||
Multiplies two integers and returns the product.
|
||||
factorial(n: int) -> int
|
||||
Computes the factorial n! of a non-negative integer.
|
||||
fibonacci(n: int) -> int
|
||||
Returns the nth Fibonacci number (0-indexed).
|
||||
libVersion() -> QString
|
||||
Returns the version string of the wrapped libcalc C library.
|
||||
libVersionNotify() -> void
|
||||
Looks up the library version and emits it as a `versionReady` event instead of returning it. Used by the QML tutorial (Part 2).
|
||||
```
|
||||
|
||||
An undocumented method would still appear, just without the indented
|
||||
description line.
|
||||
|
||||
- title: "Call methods"
|
||||
text: "Now call them:"
|
||||
run: "./logos/bin/logoscore call calc_module add 3 5"
|
||||
expect_contains:
|
||||
- '"result":8'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user