Skip to content

Generate through xr-syntax 0.3.0; add User Code regions to LibXR.CMake - #34

Merged
Jiu-xiao merged 3 commits into
devfrom
feat/xr-syntax-generation-20261012
Oct 13, 2026
Merged

Jiu-xiao merged 3 commits into
devfrom
feat/xr-syntax-generation-20261012

Conversation

@Jiu-xiao

Copy link
Copy Markdown
Member

The generator uses xr-syntax 0.3.0 for its C++ layout, for assembling generated files and for reading and writing cmake/LibXR.CMake. cpp_layout.py and cmake_text.py are gone, along with every regular expression that parsed CMake.

Changes

  • STM32, HPM and MSPM0 code generation lay out statements with xr_syntax.format.layout_statement.
  • app_main.cpp, app_main.h and flash_map.hpp are assembled by CppFileBuilder.
  • LibXR.CMake is read and written through the CMake frontend.

Generated output

  • Generated files are byte-identical to libxr 6.0.1 on bsp-dev-c (default and sentry configs), bsp-dev-mc02 and bsp_stm32f103. The one exception is cmake/LibXR.CMake, which changes as described below.

  • cmake/LibXR.CMake gets two User Code regions, kept on regeneration:

    • CompileOptions, before add_subdirectory(LibXR), for options such as LIBXR_SHARED_BUILD;
    • ApplicationSettings, at the end of the file.
  • The first line now mentions the two regions. A file with the earlier first line is still taken as the current format.

  • Before writing, the result goes through the same check as the next read. When an existing file has parse errors or malformed, duplicate or unknown User Code markers, the row and column are reported and nothing is written.

  • Settings are now edited by CMake syntax instead of regular expressions. Most differences fix wrong output from 6.0.1:

    • SET in upper case no longer gets a second line;
    • a multi-line set no longer leaves a broken last line;
    • text in comments and strings is left alone;
    • a setting added after a multi-line bracket comment no longer lands inside the comment.

    Every difference is listed with its input, old output and new output in the work report and goes into the 6.0.2 release notes.

  • Downgrade: libxr 6.0.1 reads a file written by this version as an earlier format and migrates it again, which duplicates sections. BSPs pin the generator version in libxr_config.yaml.

Requires xr-syntax 0.3.0 on PyPI (xrobot-org/xr-syntax#3), so CI installs only after that release. All tests pass locally on Windows with Python 3.13 (628 passed).

libxr.cpp_layout is gone: the layout of the generated C++ comes from
xr_syntax.format. That module holds the line-breaking rules of both
generators, each behind its own entry point and on shared primitives; the
three code generators call layout_statement instead of their own line breaker.

Pin xr-syntax 0.3.0.
app_main.cpp, app_main.h and flash_map.hpp are built through the shared file
builder, which parses the whole file once at the build boundary; app_main.h and
flash_map.hpp hold no user code, so they require a clean parse. HPM and MSPM0
assemble app_main.cpp through the same helper as STM32.

The generated output is unchanged: the clang-format format tests and the
generator tests pass.
libxr.cmake_text is gone: LibXR.CMake is read and written with CMakeDocument
and CMakeFileBuilder, so the block structure, the User Code regions and the
settings are found by the CMake lexer instead of by regular expressions over
whole lines.

The settings keep the user's writing: LIBXR_SYSTEM is written into the existing
line, LIBXR_DRIVER and the optimization levels are added after the line they
belong to, and XROBOT_MODULES_DIR follows the entry source and is removed
together with the line it is on. Both branches check the text they are about to
write with the very same checks the next read applies, so a file the generator
would refuse is never written, and the notice names the two User Code regions
that a user may edit.
@greptile-apps

greptile-apps Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5

[High impact] Upgrades code generation to use external formatting library.

Fix the empty nested setting edit before merging, because regeneration can delete user-written commands.

Fix All in Claude CodeFindings

  1. P1 User-written blocks get deleted ▶
  2. P2 Value-edit test changes no value ▶
Fix with agent prompt
### Issue 1
src/libxr/generator_stm32_cmake.py:422-424
When a valueless `set(LIBXR_SYSTEM)` sits inside an `if`, `foreach`, or function, `_statement_of` returns the entire enclosing block. This replacement deletes that block and every other command inside it. For example, a block containing `set(LIBXR_SYSTEM )` and `set(KEEP 1)` becomes just `set(LIBXR_SYSTEM None)` on regeneration.

Update only the selected command, and add a test that preserves its surrounding block.

### Issue 2
tests/test_generator_stm32_cmake.py:1053-1056
`test_a_value_is_replaced_without_touching_the_rest_of_the_line` adds a comment to `LIBXR_DRIVER`, then compares the result with an identical string. It never checks the new `_set_system` value edit, so it can pass even if that edit removes comments or changes spacing.

Use a different `LIBXR_SYSTEM` value with a trailing comment, then assert that regeneration changes the value while preserving the comment and spacing.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

The PR moves C++ layout and file assembly to xr-syntax 0.3.0 and uses its CMake frontend to edit LibXR.CMake.

  • LibXR.CMake keeps commands in two named User Code regions.
  • CMake settings follow parsed commands instead of matching text.
  • C++ generators keep their output while using shared xr-syntax tools.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Read LibXR.CMake] --> B[Check parsing and markers]
  B --> C[Extract settings and User Code]
  C --> D[Correct LIBXR_SYSTEM]
  D --> E{Nested setting has no value?}
  E -->|Yes| F[Replace enclosing block]
  E -->|No| G[Edit selected value]
  F --> H[Render and check output]
  G --> H
  H --> I[Write LibXR.CMake]
Loading

Reviews (1) · Last reviewed commit: "Read and write LibXR.CMake through the C..." · Reviewed by Greptile

Comment on lines +422 to +424
document = document.replace_statement(
_statement_of(document, view), f"set(LIBXR_SYSTEM {system})\n"
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 User-written blocks get deleted

When a valueless set(LIBXR_SYSTEM) sits inside an if, foreach, or function, _statement_of returns the entire enclosing block. This replacement deletes that block and every other command inside it. For example, a block containing set(LIBXR_SYSTEM ) and set(KEEP 1) becomes just set(LIBXR_SYSTEM None) on regeneration.

Update only the selected command, and add a test that preserves its surrounding block.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/libxr/generator_stm32_cmake.py
Line: 422-424

Comment:
**User-written blocks get deleted**

When a valueless `set(LIBXR_SYSTEM)` sits inside an `if`, `foreach`, or function, `_statement_of` returns the entire enclosing block. This replacement deletes that block and every other command inside it. For example, a block containing `set(LIBXR_SYSTEM )` and `set(KEEP 1)` becomes just `set(LIBXR_SYSTEM None)` on regeneration.

Update only the selected command, and add a test that preserves its surrounding block.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

Comment on lines +1053 to +1056
self.assertEqual(
written,
commented.replace("set(LIBXR_DRIVER st) # driver", "set(LIBXR_DRIVER st) # driver"),
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Value-edit test changes no value

test_a_value_is_replaced_without_touching_the_rest_of_the_line adds a comment to LIBXR_DRIVER, then compares the result with an identical string. It never checks the new _set_system value edit, so it can pass even if that edit removes comments or changes spacing.

Use a different LIBXR_SYSTEM value with a trailing comment, then assert that regeneration changes the value while preserving the comment and spacing.

Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/test_generator_stm32_cmake.py
Line: 1053-1056

Comment:
**Value-edit test changes no value**

`test_a_value_is_replaced_without_touching_the_rest_of_the_line` adds a comment to `LIBXR_DRIVER`, then compares the result with an identical string. It never checks the new `_set_system` value edit, so it can pass even if that edit removes comments or changes spacing.

Use a different `LIBXR_SYSTEM` value with a trailing comment, then assert that regeneration changes the value while preserving the comment and spacing.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

@Jiu-xiao
Jiu-xiao merged commit 168d287 into dev Oct 13, 2026
80 of 136 checks passed
@Jiu-xiao
Jiu-xiao deleted the feat/xr-syntax-generation-20261012 branch October 13, 2026 21:18
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