Skip to content

refactor: adapt eventide APIs and deco options - #363

Closed
16bit-ykiko wants to merge 3 commits into
mainfrom
deco-option
Closed

16bit-ykiko wants to merge 3 commits into
mainfrom
deco-option

Conversation

@16bit-ykiko

@16bit-ykiko 16bit-ykiko commented Mar 21, 2026 •

Copy link
Copy Markdown
Member

Summary

  • migrate feature and test code to the current eventide IPC/LSP namespaces and targets
  • switch CLI parsing in clice and unit tests to deco-based options
  • fix CMake/spdlog configuration and remove remaining build warnings

Verification

  • cmake --build build/Debug -j4

Summary by CodeRabbit

  • New Features

    • Added a command-line interface with --mode, --help, --version, socket settings, and worker management options.
  • Bug Fixes

    • Ensured functions return deterministically on all code paths to avoid unexpected behavior.
  • Refactor

    • Migrated protocol usage to the IPC/LSP protocol and updated build/linking configuration and test wiring.
  • Chores

    • Updated ignore rules to exclude additional tooling directories.

@coderabbitai

coderabbitai Bot commented Mar 21, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 551ad04c-e173-4376-bf95-a0b45c03e8d7

📥 Commits

Reviewing files that changed from the base of the PR and between 8e53790 and 14c7212.

📒 Files selected for processing (3)
  • tests/unit/feature/document_link_tests.cpp
  • tests/unit/feature/folding_range_tests.cpp
  • tests/unit/feature/inlay_hint_tests.cpp
✅ Files skipped from review due to trivial changes (2)
  • tests/unit/feature/folding_range_tests.cpp
  • tests/unit/feature/inlay_hint_tests.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/unit/feature/document_link_tests.cpp

📝 Walkthrough

Walkthrough

The PR migrates feature and test code from language-level protocol types to LSP/IPC protocol types, adds deco-based CLI parsing and options handling, updates CMake FetchContent and target links (removing tomlplusplus and changing eventide feature flags), and adds explicit returns and small toolchain/formatting adjustments.

Changes

Cohort / File(s) Summary
Git & Build Config
/.gitignore, CMakeLists.txt, cmake/package.cmake
Added ignore entries for .codex/, .claude/, openspec/; adjusted MSVC/Clang compile-option handling; replaced/updated FetchContent deps (removed tomlplusplus), changed eventide/ SPDLOG cache flags, and modified target link libraries for clice-core, clice, and unit_tests.
CLI & Test Runner
src/clice.cc, tests/unit/unit_tests.cc
Added clice::Options and deco-based CLI parsing (mode, host, port, worker counts, memory, help/version); unit test runner now parses --test-filter via a TestOptions struct with deco parsing.
Feature API / Protocol Migration
src/feature/feature.h, src/feature/diagnostics.cpp, src/feature/code_completion.cpp, src/feature/document_links.cpp, src/feature/document_symbols.cpp, src/feature/folding_ranges.cpp, src/feature/formatting.cpp, src/feature/hover.cpp, src/feature/inlay_hints.cpp, src/feature/semantic_tokens.cpp, src/feature/signature_help.cpp
Repointed includes/aliases from eventide::language to eventide::ipc::lsp/eventide::ipc::protocol; added centralized to_range helper in feature.h; updated URI creation to use LSP-specific API; removed several file-local protocol aliases and helpers.
Compiler / Resolver Fixes
src/compile/diagnostic.cpp, src/compile/toolchain.cpp, src/semantic/resolver.cpp
Added explicit fall-through-safe return std::nullopt; / empty-vector / lookup_result() returns; replaced std::format usage with llvm::SmallString for GCC toolchain argument construction.
Tests: Protocol & Mapper Updates
tests/unit/feature/*, tests/unit/test/tester.h (many files)
Updated test-local protocol aliases from eventide::language::protocol to eventide::ipc::protocol; updated test uses of PositionMapper to feature::PositionMapper / eventide::ipc::lsp::PositionMapper where applicable; no test logic changes beyond type/source adjustments.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🐰 I nudged the protocol leaves aside,
Swapped language paths for LSP tide,
Deco lent ears for flags we send,
CMake gardens pruned to make amends,
Hooray — a hop toward cleaner stride! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 19.23% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main refactoring work: adapting to eventide APIs and switching to deco options, which are the primary changes across the codebase.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch deco-option

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@16bit-ykiko 16bit-ykiko changed the title Adapt eventide APIs and deco options refactor: adapt eventide APIs and deco options Mar 21, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
tests/unit/feature/inlay_hint_tests.cpp (1)

27-29: ⚠️ Potential issue | 🟠 Major

Inconsistent namespace usage: eventide::language::PositionMapper should be eventide::ipc::lsp::PositionMapper.

Line 28 still uses eventide::language::PositionMapper, but the rest of the codebase has migrated to eventide::ipc::lsp::PositionMapper (as shown in src/feature/feature.h lines 23-24). This inconsistency may cause compilation issues or link against the wrong implementation.

🐛 Suggested fix
     hints_map.clear();
-    eventide::language::PositionMapper converter(tester.unit->interested_content(),
-                                                 feature::PositionEncoding::UTF8);
+    feature::PositionMapper converter(tester.unit->interested_content(),
+                                      feature::PositionEncoding::UTF8);

Or use the fully qualified name:

     hints_map.clear();
-    eventide::language::PositionMapper converter(tester.unit->interested_content(),
-                                                 feature::PositionEncoding::UTF8);
+    eventide::ipc::lsp::PositionMapper converter(tester.unit->interested_content(),
+                                                 feature::PositionEncoding::UTF8);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/feature/inlay_hint_tests.cpp` around lines 27 - 29, Update the
inconsistent type usage by replacing eventide::language::PositionMapper with
eventide::ipc::lsp::PositionMapper where it is constructed (the line creating
PositionMapper with tester.unit->interested_content() and
feature::PositionEncoding::UTF8); ensure any related includes or using
directives reference the ipc::lsp namespace so the test links against the
correct implementation and compiles consistently with the rest of the codebase.
tests/unit/feature/document_link_tests.cpp (1)

26-30: ⚠️ Potential issue | 🟠 Major

Inconsistent namespace usage: eventide::language::PositionMapper should be migrated.

Similar to the issue in tests/unit/feature/inlay_hint_tests.cpp, line 27-28 uses eventide::language::PositionMapper while the rest of the codebase has migrated to eventide::ipc::lsp::PositionMapper.

🐛 Suggested fix
 auto to_local_range(const protocol::Range& range) -> LocalSourceRange {
-    eventide::language::PositionMapper converter(tester.unit->interested_content(),
-                                                 feature::PositionEncoding::UTF8);
+    feature::PositionMapper converter(tester.unit->interested_content(),
+                                      feature::PositionEncoding::UTF8);
     return LocalSourceRange(converter.to_offset(range.start), converter.to_offset(range.end));
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/feature/document_link_tests.cpp` around lines 26 - 30, The helper
function to_local_range currently constructs a PositionMapper using the old
namespace eventide::language::PositionMapper; change that to use the migrated
eventide::ipc::lsp::PositionMapper so the codebase is consistent: update the
constructor call inside to_local_range to instantiate
eventide::ipc::lsp::PositionMapper(tester.unit->interested_content(),
feature::PositionEncoding::UTF8) and return
LocalSourceRange(converter.to_offset(range.start),
converter.to_offset(range.end)) as before.
🧹 Nitpick comments (1)
cmake/package.cmake (1)

44-45: Using main branch for eventide may cause build instability.

Pinning to a specific Git tag or commit SHA is recommended for reproducible builds. The main branch can change at any time, potentially breaking the build or introducing unexpected behavior.

♻️ Suggested fix: Pin to a specific commit or tag
 FetchContent_Declare(
     eventide
     GIT_REPOSITORY https://github.com/clice-io/eventide
-    GIT_TAG main
+    GIT_TAG <specific-commit-sha-or-tag>
     GIT_SHALLOW TRUE
 )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmake/package.cmake` around lines 44 - 45, The package.cmake entry currently
pins the eventide dependency to the mutable branch via the GIT_TAG value "main";
update this to a stable, immutable identifier by replacing GIT_TAG main with a
specific release tag or commit SHA for eventide (and keep GIT_SHALLOW TRUE if
desired) so builds are reproducible—locate the GIT_TAG setting in
cmake/package.cmake and set it to the chosen tag or commit SHA instead of
"main".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/clice.cc`:
- Around line 12-15: The declaration for the CLI flag `mode` (the DecoKV block
around the variable `mode`) is inconsistent with the runtime check that treats
it as required; update the DecoKV for `mode` to set required = true so parsing
fails early, and then remove the redundant runtime presence check that inspects
`mode` (the block around the current lines 66-68), or alternatively keep the
runtime check but change its error text to match the parser's style—prefer the
first option: set required = true in the DecoKV for `mode` and delete the manual
validation that exits when `mode` is empty.

In `@tests/unit/unit_tests.cc`:
- Around line 23-29: The code silently ignores parse errors from
deco::cli::parse<TestOptions> and proceeds with an empty filter; instead, check
parsed.has_value() and fail fast when it is false: retrieve and log the parse
error (e.g., from parsed.error() or equivalent) and exit with a non-zero status
(or assert/FAIL in tests) before using parsed->options.test_filter; update the
block around the parsed variable in unit_tests.cc to mirror the main
entrypoint's behavior by emitting the error message and terminating when parsing
fails.

---

Outside diff comments:
In `@tests/unit/feature/document_link_tests.cpp`:
- Around line 26-30: The helper function to_local_range currently constructs a
PositionMapper using the old namespace eventide::language::PositionMapper;
change that to use the migrated eventide::ipc::lsp::PositionMapper so the
codebase is consistent: update the constructor call inside to_local_range to
instantiate
eventide::ipc::lsp::PositionMapper(tester.unit->interested_content(),
feature::PositionEncoding::UTF8) and return
LocalSourceRange(converter.to_offset(range.start),
converter.to_offset(range.end)) as before.

In `@tests/unit/feature/inlay_hint_tests.cpp`:
- Around line 27-29: Update the inconsistent type usage by replacing
eventide::language::PositionMapper with eventide::ipc::lsp::PositionMapper where
it is constructed (the line creating PositionMapper with
tester.unit->interested_content() and feature::PositionEncoding::UTF8); ensure
any related includes or using directives reference the ipc::lsp namespace so the
test links against the correct implementation and compiles consistently with the
rest of the codebase.

---

Nitpick comments:
In `@cmake/package.cmake`:
- Around line 44-45: The package.cmake entry currently pins the eventide
dependency to the mutable branch via the GIT_TAG value "main"; update this to a
stable, immutable identifier by replacing GIT_TAG main with a specific release
tag or commit SHA for eventide (and keep GIT_SHALLOW TRUE if desired) so builds
are reproducible—locate the GIT_TAG setting in cmake/package.cmake and set it to
the chosen tag or commit SHA instead of "main".

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f7372c28-9655-46ef-a743-efc13665c596

📥 Commits

Reviewing files that changed from the base of the PR and between 73afcfb and 8e53790.

📒 Files selected for processing (28)
  • .gitignore
  • CMakeLists.txt
  • cmake/package.cmake
  • src/clice.cc
  • src/compile/diagnostic.cpp
  • src/compile/toolchain.cpp
  • src/feature/code_completion.cpp
  • src/feature/diagnostics.cpp
  • src/feature/document_links.cpp
  • src/feature/document_symbols.cpp
  • src/feature/feature.h
  • src/feature/folding_ranges.cpp
  • src/feature/formatting.cpp
  • src/feature/hover.cpp
  • src/feature/inlay_hints.cpp
  • src/feature/semantic_tokens.cpp
  • src/feature/signature_help.cpp
  • src/semantic/resolver.cpp
  • tests/unit/feature/code_completion_tests.cpp
  • tests/unit/feature/document_link_tests.cpp
  • tests/unit/feature/document_symbol_tests.cpp
  • tests/unit/feature/folding_range_tests.cpp
  • tests/unit/feature/hover_tests.cpp
  • tests/unit/feature/inlay_hint_tests.cpp
  • tests/unit/feature/semantic_tokens_tests.cpp
  • tests/unit/feature/signature_help_tests.cpp
  • tests/unit/test/tester.h
  • tests/unit/unit_tests.cc
💤 Files with no reviewable changes (8)
  • src/feature/semantic_tokens.cpp
  • src/feature/inlay_hints.cpp
  • src/feature/signature_help.cpp
  • src/feature/hover.cpp
  • src/feature/formatting.cpp
  • src/feature/document_symbols.cpp
  • src/feature/code_completion.cpp
  • src/feature/folding_ranges.cpp

Comment thread src/clice.cc
Comment on lines +12 to +15
DecoKV(names = {"--mode"};
help = "Running mode: pipe, socket, stateless-worker, stateful-worker";
required = false;)
<std::string> mode;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Inconsistency between declaration and runtime validation for --mode.

The --mode option is declared with required = false on line 14, but line 66-68 treats it as required at runtime. Consider either:

  1. Setting required = true in the declaration so parsing fails early with a proper message, or
  2. Keeping the current approach but ensuring the error message matches what the library would produce.
💡 Suggested fix: Mark mode as required in declaration
     DecoKV(names = {"--mode"};
            help = "Running mode: pipe, socket, stateless-worker, stateful-worker";
-           required = false;)
+           required = true;)
     <std::string> mode;

Then remove the redundant check:

-    if(!opts.mode.has_value()) {
-        std::println(stderr, "error: --mode is required");
-        return 1;
-    }
-
-    std::println("mode: {}", *opts.mode);
+    std::println("mode: {}", *opts.mode);

Also applies to: 66-68

🧰 Tools
🪛 Cppcheck (2.20.0)

[error] 12-12: syntax error

(syntaxError)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/clice.cc` around lines 12 - 15, The declaration for the CLI flag `mode`
(the DecoKV block around the variable `mode`) is inconsistent with the runtime
check that treats it as required; update the DecoKV for `mode` to set required =
true so parsing fails early, and then remove the redundant runtime presence
check that inspects `mode` (the block around the current lines 66-68), or
alternatively keep the runtime check but change its error text to match the
parser's style—prefer the first option: set required = true in the DecoKV for
`mode` and delete the manual validation that exits when `mode` is empty.

Comment thread tests/unit/unit_tests.cc
Comment on lines +23 to +29
auto args = deco::util::argvify(argc, argv);
auto parsed = deco::cli::parse<TestOptions>(args);

std::string_view filter = {};
if(parsed.has_value() && parsed->options.test_filter.has_value()) {
filter = *parsed->options.test_filter;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
sed -n '44,60p' src/clice.cc
printf '\n---\n'
sed -n '23,31p' tests/unit/unit_tests.cc

Repository: clice-io/clice

Length of output: 875


🏁 Script executed:

# Verify the parse error handling pattern across the codebase
rg "deco::cli::parse" -A 5 -B 1

Repository: clice-io/clice

Length of output: 819


Fail fast when Deco rejects the CLI.

If deco::cli::parse<TestOptions> returns an error, the code silently continues with an empty filter and runs the full test suite. This differs from the main entrypoint (src/clice.cc), which explicitly checks !result.has_value() and exits with an error message. Invalid or typo'd --test-filter invocations will silently succeed instead of failing.

Suggested fix
     auto args = deco::util::argvify(argc, argv);
     auto parsed = deco::cli::parse<TestOptions>(args);
+    if(!parsed.has_value()) {
+        return 1;
+    }

     std::string_view filter = {};
-    if(parsed.has_value() && parsed->options.test_filter.has_value()) {
+    if(parsed->options.test_filter.has_value()) {
         filter = *parsed->options.test_filter;
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
auto args = deco::util::argvify(argc, argv);
auto parsed = deco::cli::parse<TestOptions>(args);
std::string_view filter = {};
if(parsed.has_value() && parsed->options.test_filter.has_value()) {
filter = *parsed->options.test_filter;
}
auto args = deco::util::argvify(argc, argv);
auto parsed = deco::cli::parse<TestOptions>(args);
if(!parsed.has_value()) {
return 1;
}
std::string_view filter = {};
if(parsed->options.test_filter.has_value()) {
filter = *parsed->options.test_filter;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/unit_tests.cc` around lines 23 - 29, The code silently ignores
parse errors from deco::cli::parse<TestOptions> and proceeds with an empty
filter; instead, check parsed.has_value() and fail fast when it is false:
retrieve and log the parse error (e.g., from parsed.error() or equivalent) and
exit with a non-zero status (or assert/FAIL in tests) before using
parsed->options.test_filter; update the block around the parsed variable in
unit_tests.cc to mirror the main entrypoint's behavior by emitting the error
message and terminating when parsing fails.

@16bit-ykiko
16bit-ykiko deleted the deco-option branch March 22, 2026 16:16
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