[codex] support project-level constexpr generation#95
Conversation
Reviewer's GuideAdds project-level constexpr support to xrobot_gen_main, hardens YAML/config structure validation, adjusts manifest parsing to preserve indentation, wires constexpr header generation into the main flow, and updates docs and versioning to reflect the new behavior. Sequence diagram for xrobot_gen_main generation with constexpr supportsequenceDiagram
actor Developer
participant CLI as xrobot_gen_main
participant Main as GenerateMain_main
participant FS as FileSystem
participant YAML as YAML_loader
Developer->>CLI: invoke with --output and optional --config/--modules
CLI->>Main: parse args and enter main()
Main->>FS: check config_path.exists()
alt config file exists
Main->>YAML: _load_config_file(config_path)
YAML-->>Main: validated_config_dict or error
else config path specified but missing
Main-->>Developer: [WARN] Configuration file not found
end
alt no modules passed on CLI
Main->>Main: extract_modules_from_config(config_data)
alt modules from config
Main->>FS: verify each Module/<name>/<name>.hpp
FS-->>Main: header exists or [WARN]
else no modules in config
Main->>Main: auto_discover_modules()
end
end
alt config file does not exist
Main->>Main: extract_constructor_args(modules, Modules/, config_path)
Main->>FS: write default User/xrobot.yaml
end
Main->>Main: generate_xrobot_main_code(hw_var, modules, config_data)
Main->>FS: write User/xrobot_main.hpp
Main->>Main: _generate_constexpr_header(config_data)
alt constexprs present and valid
Main->>FS: write xrobot_constexpr.hpp
else no constexprs
Main->>Main: skip constexpr header
end
Main-->>Developer: [SUCCESS] messages
rect rgb(255,230,230)
Main->>Main: validation helpers (_require_mapping, _validate_constexpr_ref)
Main-->>CLI: raise TypeError/ValueError/FileNotFoundError
CLI-->>Developer: exit(1) with readable error
end
Entity-relationship diagram for User_xrobot_yaml configuration structureerDiagram
CONFIG {
string global_settings
string constexpr_includes
string constexprs
string modules
}
GLOBAL_SETTINGS {
int monitor_sleep_ms
}
CONSTEXPR_DEF {
string name
string type
any value
}
MODULE_ENTRY {
string id
string name
}
CONSTRUCTOR_ARGS {
string key
any value
}
TEMPLATE_ARGS {
string key
any value
}
CONFIG ||--|{ GLOBAL_SETTINGS : has
CONFIG ||--o{ CONSTEXPR_DEF : defines
CONFIG ||--o{ MODULE_ENTRY : configures
MODULE_ENTRY ||--o{ CONSTRUCTOR_ARGS : has
MODULE_ENTRY ||--o{ TEMPLATE_ARGS : has
CONSTEXPR_DEF }o--o{ CONSTRUCTOR_ARGS : referenced_as_constexpr
CONSTEXPR_DEF }o--o{ TEMPLATE_ARGS : referenced_as_constexpr
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- The constexpr support currently hardcodes both the namespace (
XRobotProject) and the header name (xrobot_constexpr.hpp); consider making these configurable (via CLI flags or top-level config fields) so projects with existing naming/namespace conventions can adopt this feature without patching the generator. - You now have several scattered structural validations for the config (top-level mapping checks,
modulesitem shape,global_settings,constructor_args,template_args); it might be worth centralizing this into a single_validate_config(config)helper to keep the rules consistent betweengenerate_xrobot_main_code,extract_modules_from_config, and future callers.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The constexpr support currently hardcodes both the namespace (`XRobotProject`) and the header name (`xrobot_constexpr.hpp`); consider making these configurable (via CLI flags or top-level config fields) so projects with existing naming/namespace conventions can adopt this feature without patching the generator.
- You now have several scattered structural validations for the config (top-level mapping checks, `modules` item shape, `global_settings`, `constructor_args`, `template_args`); it might be worth centralizing this into a single `_validate_config(config)` helper to keep the rules consistent between `generate_xrobot_main_code`, `extract_modules_from_config`, and future callers.
## Individual Comments
### Comment 1
<location path="src/xrobot/GenerateMain.py" line_range="78" />
<code_context>
return manifest_data
+def _validate_constexpr_ref(name: str) -> str:
+ if not isinstance(name, str) or not re.match(r"^[A-Za-z_]\w*$", name):
+ raise ValueError(f"[ERROR] Invalid constexpr reference: {name!r}")
+ return name
</code_context>
<issue_to_address>
**issue (bug_risk):** Using `re.match` here will raise `NameError` unless `re` is imported.
To avoid this runtime NameError, add `import re` alongside the other standard-library imports in this module.
</issue_to_address>
### Comment 2
<location path="README.md" line_range="340-341" />
<code_context>
+ `modules` is the module instance list; `id` becomes the generated C++ instance name, and `name` is the module class name.
+- `constructor_args` 与 `template_args` 会按配置顺序展开到构造参数和模板参数中。
+ `constructor_args` and `template_args` are expanded into constructor arguments and template arguments in config order.
+- `{constexpr: Name}` 会展开为 `XRobotProject::Name`;若顶层存在 `constexprs`,则会额外生成 `xrobot_constexpr.hpp`。
+ `{constexpr: Name}` expands to `XRobotProject::Name`; when top-level `constexprs` exists, `xrobot_constexpr.hpp` is generated alongside the main file.
+- `@instance_id` 会被当作已有 C++ 实例名直接引用,例如 `@cam` 会展开为 `cam`。
+ `@instance_id` is emitted as a direct C++ instance reference, for example `@cam` expands to `cam`.
</code_context>
<issue_to_address>
**issue (typo):** Use plural verb with plural subject in "when top-level `constexprs` exist".
Since `constexprs` is plural, this should say `when top-level constexprs exist` (not `exists`).
```suggestion
- `{constexpr: Name}` 会展开为 `XRobotProject::Name`;若顶层存在 `constexprs`,则会额外生成 `xrobot_constexpr.hpp`。
`{constexpr: Name}` expands to `XRobotProject::Name`; when top-level `constexprs` exist, `xrobot_constexpr.hpp` is generated alongside the main file.
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| return manifest_data | ||
|
|
||
| def _validate_constexpr_ref(name: str) -> str: | ||
| if not isinstance(name, str) or not re.match(r"^[A-Za-z_]\w*$", name): |
There was a problem hiding this comment.
issue (bug_risk): Using re.match here will raise NameError unless re is imported.
To avoid this runtime NameError, add import re alongside the other standard-library imports in this module.
| - `{constexpr: Name}` 会展开为 `XRobotProject::Name`;若顶层存在 `constexprs`,则会额外生成 `xrobot_constexpr.hpp`。 | ||
| `{constexpr: Name}` expands to `XRobotProject::Name`; when top-level `constexprs` exists, `xrobot_constexpr.hpp` is generated alongside the main file. |
There was a problem hiding this comment.
issue (typo): Use plural verb with plural subject in "when top-level constexprs exist".
Since constexprs is plural, this should say when top-level constexprs exist (not exists).
| - `{constexpr: Name}` 会展开为 `XRobotProject::Name`;若顶层存在 `constexprs`,则会额外生成 `xrobot_constexpr.hpp`。 | |
| `{constexpr: Name}` expands to `XRobotProject::Name`; when top-level `constexprs` exists, `xrobot_constexpr.hpp` is generated alongside the main file. | |
| - `{constexpr: Name}` 会展开为 `XRobotProject::Name`;若顶层存在 `constexprs`,则会额外生成 `xrobot_constexpr.hpp`。 | |
| `{constexpr: Name}` expands to `XRobotProject::Name`; when top-level `constexprs` exist, `xrobot_constexpr.hpp` is generated alongside the main file. |
This change adds project-level constexpr generation to
xrobot_gen_mainand tightens the generator's configuration parsing so invalid YAML and malformed config structures fail with clear errors instead of leaking Python tracebacks or silently degrading into incomplete output.Before this change, project code could only pass literal values or ad-hoc string expressions through
User/xrobot.yaml. That made it awkward to express strongly typed compile-time configuration shared across modules, especially for template arguments and aggregate constructor arguments. In the same area, the generator's parser had several edge cases that were unsafe in practice: nested manifest YAML could be flattened by indentation loss, top-level non-mapping YAML could reach deep code paths and crash withAttributeError, and malformedglobal_settings/modulesentries could be silently ignored or fail unclearly.The root cause was that
GenerateMain.pyonly handled simple value formatting and assumed a mostly well-formed config tree. It had no project-level constexpr emission path, no dedicated config loader with structural validation, and manifest parsing stripped indentation from lines before handing them to YAML parsing.The fix adds a project-level
constexprs/constexpr_includessurface toUser/xrobot.yaml. When present,xrobot_gen_mainnow emitsxrobot_constexpr.hpp, and bothconstructor_argsandtemplate_argscan reference generated symbols using{constexpr: Name}. The generator remains in a singleGenerateMain.pyfile, keeps the existing CLI entrypoint, and the package version is bumped to0.2.9. README usage was updated to match the real current behavior, including the single-file generator, theUser/xrobot.yamllayout, and thexrobot_setupflow.This PR also hardens config parsing behavior. Manifest parsing now preserves indentation so nested YAML structures survive round-tripping. Config loading validates that the top-level YAML is a mapping, and generation now validates
global_settings, eachmodules[*]entry, and per-moduleconstructor_args/template_argsmappings explicitly. On CLI failure paths, these validation errors are surfaced as readable command-line errors instead of raw stack traces.Validation was done in three layers. First,
python3 -m compileall src/xrobot/GenerateMain.pywas run on the final branch state. Second, an ad-hoc parsing regression and boundary verification matrix was executed with 22 passing checks, covering valid generation, malformed YAML, top-level type errors, malformed module entries, invalid constexpr references, and CLI error surfaces. Third, a local multi-module smoke run exercised real generator flows with mockBlinkLED,WebotsCamera,ArmorDetector, andPoseFiltermodules, covering manifest-driven default config generation, nested manifest args, config-driven module discovery,@instancereferences, and the newconstexprs/constexpr_includesemission path. Together these checks verify both the new feature and the generator's failure behavior on malformed input.Summary by Sourcery
Add project-level constexpr header generation to xrobot_gen_main and harden configuration parsing and CLI error handling.
New Features:
Bug Fixes:
Enhancements:
Build:
Documentation: