2d193d80cd4684566458c54db77ff445a82986bb
505 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2d193d80cd |
fix: adapt clice source code for LLVM 22.1 API changes
Major LLVM 22.1 breaking changes addressed: - NestedNameSpecifier changed from pointer to value type - ElaboratedType removed (merged into individual type nodes) - DependentTemplateSpecializationType merged into TemplateSpecializationType - TreeTransform overrides now require additional parameters - TagDecl::getTypeForDecl() removed, use ASTContext::getTagType() - InjectedClassNameType::getInjectedSpecializationType() removed - TypedefTypeLoc::getTypedefNameDecl() renamed to getDecl() - AnonymousTagLocations renamed to AnonymousTagNameStyle - DIAG macro expanded from 11 to 13 parameters - Header moves: clang/Driver/Options.h → clang/Options/Options.h - ClangTidyModuleRegistry.h renamed to ClangTidyModule.h - createDiagnostics/createFileManager API changes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
3e73150569 |
feat(ci): add LLVM 22.1 distribution components
LLVM 22.1 introduced new CMake targets (clangAnalysisLifetimeSafety, clangOptions, clangDependencyScanning, LLVMPlugins) that existing components depend on. Add them to the distribution component list. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
17e68010a0 |
feat(server): improve configuration file handling (#423)
## Summary
- **`[[rules]]`**: TOML array-of-tables config for per-file compilation
flag rules with glob pattern matching (`append`/`remove`). Patterns are
pre-compiled at config load time. Rules whose patterns all fail to
compile are dropped entirely (no silent no-op entries), and rules now
apply uniformly to every compilation — including the header-context
fallback path used when editing a header without its own CDB entry.
- **CDB auto-scan**: Default search scans workspace root + all immediate
subdirectories for `compile_commands.json`, replacing the hardcoded
directory list.
- **LSP `initializationOptions`**: Clients can pass config as JSON via
the LSP initialize request; priority is `initializationOptions >
clice.toml > defaults`.
- **XDG cache paths**: Default cache/index/logging paths prefer
`$XDG_CACHE_HOME/clice/<workspace-hash>/`; fall back to
`$HOME/.cache/clice/<hash>/`, then `<workspace>/.clice/`.
- **`${workspace}` substitution**: supported in `cache_dir`,
`index_dir`, `logging_dir`, and every `compile_commands_paths` entry.
No-op when `workspace_root` is empty.
- **Partial config support**: All TOML/JSON fields are optional via
`kota::meta::defaulted<T>`, so minimal config files work correctly.
- **Detailed diagnostics**: malformed `clice.toml` now logs line, column
and parser description (via toml++ direct parse); a malformed workspace
config surfaces a clear fallback warning instead of silently reverting
to defaults.
## Test plan
- [x] 28 unit tests for config (full suite 545 unit tests pass, Debug)
- [x] 119 integration tests pass
- [x] 2 smoke tests pass
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* XDG-based, workspace-scoped project cache (PCH/PCM and header caches
moved under project cache) with workspace fallback
* Initialization options JSON can override config (takes precedence over
file/defaults)
* Per-file pattern rules to append/remove compile flags; expanded
discovery of compilation databases (multiple paths)
* **Refactor**
* Configuration fields reorganized under a project scope; runtime
behavior now respects project-scoped values
* **Tests**
* New unit and integration tests for config parsing, rule matching, and
persistent cache behavior
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
|
||
|
|
3fa653bcaf |
feat(completion): mark deprecated symbols with strikethrough (#414)
## Summary - Check `CXAvailability_Deprecated` on `CodeCompletionResult` and set `CompletionItemTag::Deprecated` - Editors render deprecated completions with a strikethrough on the label ## Test plan - [x] `DeprecatedTag` — `[[deprecated]]` function gets the tag - [x] `NotDeprecated` — normal function has no Deprecated tag - [x] All 491 unit tests pass - [x] `pixi run format` clean Stacked on #411. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Code completion now marks deprecated declarations with a deprecated tag so users can see deprecated items in completion lists. * **Tests** * Added unit tests ensuring deprecated declarations produce completion items with the deprecated tag and non-deprecated items do not. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
592b37417e |
feat: cross-compile & upgrade LLVM to 21.1.8 (#390)
## Summary
This PR adds cross-compilation support for three new target platforms,
upgrades LLVM to 21.1.8, and overhauls the CI pipelines around
cross-builds and testing.
## Cross-compilation
New target triples accepted via `-DCLICE_TARGET_TRIPLE=...`:
| Target triple | Host | Output |
|---|---|---|
| `x86_64-apple-darwin` | macos-15 (arm64) | macOS x64 |
| `aarch64-linux-gnu` | ubuntu-24.04 (x64) | Linux arm64 |
| `aarch64-pc-windows-msvc` | windows-2025 (x64) | Windows arm64 |
- `cmake/toolchain.cmake` — maps `CLICE_TARGET_TRIPLE` to
`CMAKE_SYSTEM_NAME`/`CMAKE_SYSTEM_PROCESSOR`/compiler `--target`; picks
up conda aarch64 sysroot when cross-compiling Linux.
- `cmake/llvm.cmake` — forwards target platform/arch to `setup-llvm.py`
so the right prebuilt LLVM is downloaded for the target.
- `CMakeLists.txt` — uses a host-side `flatc` from `PATH` under
`CMAKE_CROSSCOMPILING` instead of the in-tree target build.
- `pixi.toml`:
- Adds `osx-64`, `linux-aarch64`, `win-arm64` platforms.
- New environments: `cross-macos-x64`, `cross-linux-aarch64` (adds
`gcc_linux-aarch64` + `sysroot_linux-aarch64`), `cross-windows-arm64`.
- New lightweight `test-run` env used on native ARM/x64 runners to
execute cross-built artifacts (pulls in upstream clang+lld on macOS so
tests don't fall back to Apple clang).
- `scripts/activate_cross_linux.sh` — exports `CONDA_PREFIX`-relative
paths for the aarch64 toolchain.
- `scripts/build-llvm.py` — `--target-triple` support and a
`build_native_tools()` helper that produces host `llvm-tblgen` /
`clang-tblgen` needed when cross-compiling LLVM itself.
## LLVM upgrade 21.1.4 → 21.1.8
- `cmake/package.cmake` bumps `setup_llvm("21.1.8")`.
- `config/llvm-manifest.json` regenerated with 6 new cross-compiled
entries and a new `arch` field on every entry so lookup is `(version,
platform, arch, lto, build_type)`.
- `scripts/setup-llvm.py` — honours the new `arch` field when resolving
artifacts.
- `scripts/update-llvm-version.py` (new) — single-call version bump
across `package.cmake` + manifest.
- `scripts/validate-llvm-components.py` (new) — scans the LLVM source
tree for library targets and diffs them against
`scripts/llvm-components.json` to catch stale/misspelled component names
before a build.
- `scripts/llvm-components.json` (new) — explicit allow-list of required
LLVM/Clang library targets used by `build-llvm.py`.
## CI changes
- `.github/workflows/build-llvm.yml`:
- Adds `workflow_dispatch` with `llvm_version`, `skip_upload`, `skip_pr`
inputs.
- Matrix extended with the 6 cross-compile entries (2 per new platform:
RelWithDebInfo ± LTO).
- `build clice` / test / prune steps gated on `!matrix.target_triple`
for cross-builds; cross-built LTO entries apply the native prune
manifest (arch-independent).
- Cross-compiled binary architecture is verified with `file(1)`.
- New `upload` job triggered by `workflow_dispatch` pushes artifacts to
`clice-io/clice-llvm` and hands the manifest off to the next job.
- `.github/workflows/test-cmake.yml`:
- Build matrix gains three `build_only: true` cross entries that upload
`bin/` + `lib/` artifacts.
- New `test-cross` job runs on native `macos-15-intel`,
`ubuntu-24.04-arm`, `windows-11-arm` runners, downloads the cross-built
artifacts, and runs unit / integration / smoke tests under the
`test-run` pixi env.
- Cache keys now include `target_triple` so native and cross builds
don't collide.
- `.github/workflows/publish-clice.yml`:
- Three additional release artifacts for the new targets
(`clice-x86_64-macos-darwin`, `clice-aarch64-linux-gnu`,
`clice-aarch64-windows-msvc`), each with a matching `-symbol` archive.
## Compatibility
- All existing native builds and tests are preserved; cross entries are
additive.
- `Debug` + ASAN remains disabled on Windows (`llvm_mode == Debug && os
== windows-*` no longer appends `-asan`).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
418e190fa0 |
chore(deps): migrate from eventide to kotatsu (#428)
## Summary - The `eventide` dep was renamed to [kotatsu](https://github.com/clice-io/kotatsu) with a broad rename of CMake identifiers, namespaces, header paths, and a few module reorgs (`serde` → `codec`, `reflection` → `meta`, `common` → `support`). Align clice to the new names. - CMake: FetchContent target, option prefix (`ETD_*` → `KOTA_*`, `ETD_SERDE_*` → `KOTA_CODEC_*`), target names (`eventide::{ipc::lsp,serde::toml,deco,zest}` → `kota::{ipc::lsp,codec::toml,deco,zest}`). - Namespaces: `eventide::` → `kota::`, `eventide::serde::` → `kota::codec::`, `eventide::refl::` → `kota::meta::`. The short `et` alias is dropped — all usages now spell `kota::` directly. - Headers: `eventide/*` → `kota/*`, including special cases `serde/serde/raw_value.h` → `codec/raw_value.h`, `ipc/json_codec.h` → `ipc/codec/json.h`, `common/meta.h` → `support/type_traits.h`, `common/ranges.h` → `support/ranges.h`. - Kotatsu split `JsonPeer` / `BincodePeer` out of `ipc/peer.h` into the codec-specific headers; added `kota/ipc/codec/{json,bincode}.h` includes where those types are used. - Depends on clice-io/kotatsu#110 (already merged) to prevent `-Wall -Wextra -Werror` from transitively propagating out of `kota::project_options`. ## Test plan - [x] `pixi run unit-test RelWithDebInfo` — 518/518 pass (9 skipped, unchanged from main) - [x] `pixi run integration-test RelWithDebInfo` — 119/119 pass - [x] `pixi run smoke-test RelWithDebInfo` — 2/2 pass - [x] `pixi run format` clean ## Notes - `tests/smoke/rapid_edit.jsonl` was intentionally left untouched: the embedded `#include "eventide/..."` strings are frozen snapshots of file contents the client sent at record time, not clice source. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated internal dependencies from `eventide` to `kota`, including async runtime, IPC transport, serialization codec, and metadata libraries. * Updated build configuration and CMake variables to align with the new dependency. * **Refactor** * Migrated internal implementation to use `kota` namespace and APIs throughout the codebase. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
d42d9d5b29 |
refactor(document links): use Lexer for unified directive argument scanning (#421)
## Summary - Replace hand-written character scanning in `document_links.cpp` with the project's `Lexer` class for finding filename arguments in preprocessor directives - Extend `Lexer` to activate `header_name` mode for `#embed`/`#include_next`, and expose `set_header_name_mode()` for `__has_include`/`__has_embed` contexts - Remove unused `Include::filename_range` field (had a latent assert crash on macro-expanded includes) - Add `MacroInclude` unit test covering `#include MACRO` scenario ## Test plan - [x] 498 unit tests pass (including new `MacroInclude` test) - [x] 119 integration tests pass - [x] 2/2 smoke tests pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Document links now resolve includes written via macros; directive parsing recognizes include, include_next, embed and __has_* patterns more reliably using lexer-driven argument detection. * **Refactor** * Removed an internal filename-range field previously stored for include directives. * **Tests** * Added unit tests covering directive argument extraction and macro-based include linking. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
9c89d20e76 |
feat(tests): add compile_with_modules helper to Tester (#420)
## Summary - Add `add_module()` and `compile_with_modules()` to the `Tester` test framework - Supports both separate `add_module()` calls and single-string `#[filename]` syntax via `add_files()` - Automatically scans module dependencies with `scan_precise`, topologically sorts, builds PCMs in order, then compiles the main file - Temporary PCM files cleaned up automatically in destructor - Migrated `ModuleImport` and `ModuleReexport` semantic tokens tests to use the new API ## Test plan - [x] All 505 unit tests pass - [x] All 113 integration tests pass - [x] All 2 smoke tests pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Centralized, module-aware test compilation with automatic module discovery, dependency ordering, and cycle detection. * Unified "compile with modules" flow; tests now add module sources directly and no longer manage temporary module artifacts manually. * Reduced duplicated compile/diagnostic logic and improved cleanup of generated artifacts. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
8bafaa8171 |
feat(document links): preserve PCH document links and add #embed support (#413)
## Summary - PCH compilation now serializes document links via `pch_links_json` in `BuildResult` and stores them in `PCHState` - Master server merges PCH document links with main-file links on `textDocument/documentLink` requests, fixing missing links for `#include` directives inside the preamble - Adds document link support for `#embed` and `__has_embed` directives ## Test plan - [x] Unit tests: `DocumentLink.Embed` and `DocumentLink.HasEmbed` added - [x] Integration tests: `test_document_links.py` verifies PCH + main merge and `#embed` links - [x] All 483 unit tests pass - [x] All 4 integration tests pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Document links now detect embeds and __has_embed directives for both quoted and angled filenames. * Document links produced during precompiled builds are cached and merged into document-link responses for more complete link sets. * **Tests** * Added integration tests for merged PCH/main links and embed/has-embed cases. * Added unit tests verifying embed handling under C++23. * **Chores** * Added test fixtures and compile command entries for document-links tests. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
92dae18fd4 |
feat(semantic tokens): highlight module names in declarations and imports (#417)
## Summary - Highlight module name identifiers (e.g. `foo`, `bar` in `export module foo.bar;`) as `SymbolKind::Module` in semantic tokens - Highlight import module names (e.g. `foo` in `import foo;`) using `directives.imports` name locations - Module declarations use `getCurrentNamedModule()->DefinitionLoc` + lexer scan to find name tokens ## Test plan - [x] `SemanticTokens.ModuleDeclaration` — `export module foo;` - [x] `SemanticTokens.ModuleDeclarationDotted` — `export module foo.bar;` - [x] `SemanticTokens.ModuleImport` — PCM build + `import foo;` - [x] All 16 SemanticTokens tests pass, no regressions 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Enhanced semantic token support for C++20 modules, including dotted module names, partitions, fragments, imports and re-exports for more accurate highlighting. * **Bug Fixes** * Improved conflict resolution so directive tokens no longer mask other semantic kinds; ensures `module`/`import` used as identifiers are tokenized correctly. * **Tests** * Added unit tests covering module declarations, imports, partitions and edge cases. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
e554660c06 |
fix(completion): use class name for constructor/deduction guide labels (#416)
## Summary Fixes a bug where constructors and deduction guides had labels like `vector<_Tp, _Alloc>` instead of just `vector`, causing: 1. Label deduplication to fail (class `vector` != constructor `vector<_Tp, _Alloc>`) 2. Selecting the completion to insert invalid text `vector<_Tp, _Alloc>` Now uses `getParent()->getName()` for constructors and `getDeducedTemplate()->getName()` for deduction guides. ## Test plan - [x] All 494 unit tests pass (existing `DeduplicateByLabel` test covers this) - [x] `pixi run format` clean 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Constructor and deduction-guide completions now show the parent type name without template parameters, improving readability and preventing duplicate entries. * **Tests** * Added a unit test verifying completion items for these entries use the parent type name (no template-parameterized labels) and insertion text starts with that name. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
342d82a7aa |
chore: add CLAUDE.md, clang-tidy, and agent workflow tooling (#419)
## Summary - Add `.claude/CLAUDE.md` with project guide, C++ coding style, correction patterns from past AI interactions, and pre-commit/pre-PR workflows - Add `.claude/commands/` with `/build`, `/test`, `/format` slash commands for Claude Code - Add `.clang-tidy` configuration - Add `scripts/run_clang_tidy.py` for parallel clang-tidy with progress reporting (reads CDB, filters to `src/` and `tests/` only) - Add pixi tasks: `clang-tidy`, `lint-cpp`, `lint-python`, `lint` - Add `clang-tools` dependency for clang-tidy - Update `.gitignore` to track `.claude/CLAUDE.md` and `.claude/commands/` ## Test plan - [x] `pixi run format` passes - [x] `pixi run lint-python` passes (ruff check) - [x] `scripts/run_clang_tidy.py` correctly filters to project files only 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
3dab2ead93 |
feat(completion): snippet insertion for function/method parameters (#412)
## Summary
- Generate LSP snippet placeholders (`${1:param}`, `${2:param}`) for
function and method completions in non-bundle mode
- Controlled by
`CodeCompletionOptions::enable_function_arguments_snippet` (default off)
- No-arg functions produce plain text insertion (no empty snippet)
- Bundle mode is unaffected — snippets only apply when each overload is
a separate item
- Optional chunks (default arguments) are skipped in snippet generation
## Example
```
// Before: typing "fo" and selecting foooo inserts just "foooo"
// After: typing "fo" and selecting foooo inserts "foooo(${1:int x}, ${2:float y})"
```
## Test plan
- [x] `SnippetFunctionArgs` — verifies placeholders are generated
- [x] `SnippetNoArgs` — no-arg functions don't produce snippet
- [x] `SnippetDisabled` — respects the option flag
- [x] `SnippetBundleMode` — bundle mode doesn't generate snippets
- [x] `SnippetMethod` — works for member methods too
- [x] All 494 unit tests pass
- [x] `pixi run format` clean
Stacked on #411.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **New Features**
* Code completion now generates function argument snippets with
interactive placeholders, helping users efficiently navigate through
parameters during autocompletion. The feature works with functions and
methods, with configurable options to control behavior for overloaded
scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
|
||
|
|
bd238fe59c |
feat(completion): signature display, underscore filtering, label dedup (#411)
## Summary - Extract function/method signatures from Clang `CodeCompletionString` into `labelDetails.detail` (parameter list) and `labelDetails.description` (return type) - Filter `_`/`__` prefixed internal symbols (e.g. `_Vector_base`, `_Alloc`) unless the user explicitly typed `_` - Fix `completion_kind` isa ordering: `CXXMethodDecl` checked before `FunctionDecl` so methods get correct Kind - Bundle mode: extend overload bundling to Method and Constructor (was Function only) - Bundle mode: deduplicate by label — when the same name appears as Class + Constructor + deduction guide, keep only one (priority: Class > Function > Constructor) - Bundled overloads show `(…) +N overloads` in `labelDetails.detail` instead of `detail` ## Test plan - [x] 12 unit tests covering: signature extraction, return type, overload bundling, underscore filtering, label deduplication, non-bundle mode, method signatures - [x] All 489 unit tests pass - [x] `pixi run format` applied 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Code completion now displays function signatures and return types in completion items * Overloaded functions are bundled together with a count indicator * Internal symbols (underscore-prefixed) are filtered from suggestions unless explicitly typed * Duplicate completion items are deduplicated while preserving higher-priority variants <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
8b3e3a9595 |
refactor(tests): reorganize integration tests into domain-based subdirectories (#409)
## Summary - Extract shared test utilities into `tests/integration/utils/` (client, workspace, assertions, wait, cache) - Migrate 12 test files into categorized subdirectories: `lifecycle/`, `compilation/`, `features/`, `modules/`, `extensions/`, `stress/` - Merge `test_include_completion.py` + `test_import_completion.py` → `features/test_completion.py` - Remove stale directory-tree comments and section divider comments ## Test plan - [x] `pytest --collect-only` collects all 113 tests - [x] All test module imports verified - [x] `pixi run format` applied 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Reorganized integration suites: added new feature tests (completion, server) and removed older duplicated modules. * Centralized shared test utilities and assertion helpers for diagnostics, workspace operations, waiting/synchronization, and cache inspection. * **Chores / Refactor** * Standardized test client lifecycle and helper usage across suites for more reliable test flows. * Improved server session lifecycle handling for more predictable document/session resets during tests. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
2bbdf6c02b |
refactor(command): split CompilationContext into ResolvedFlags → CompileCommand → to_argv() (#408)
## Summary
- Replace flat `CompilationContext { directory, arguments }` with a
three-layer abstraction: `ResolvedFlags` (file-independent flags) →
`CompileCommand` (+ source file) → `to_argv()` (full argv on demand)
- `ResolvedFlags.flags` never contains source file path or
`-main-file-name`, making it directly usable as a clean cache key input
(e.g. PCH sharing across files with identical preambles)
- `to_argv()` handles `-main-file-name` insertion for cc1 mode
automatically — consumers no longer need to search/replace in the
argument list
- Eliminates the pollute-then-clean anti-pattern in `lookup()` and the
manual source-file replacement in `fill_header_context_args()`
## Test plan
- [x] `pixi run format` — no changes
- [x] `pixi run unit-test` — 481 passed
- [x] `pixi run integration-test` — 113 passed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Unified compile-command handling across the server and tools for more
consistent argument and flag behavior (driver vs frontend modes).
* **New Features**
* Added an LRU-backed in-memory cache to improve performance and
eviction control.
* **Chores**
* Added an option to control injection of resource-directory flags
(enabled by default).
* **Tests**
* Updated unit and integration tests to adopt the new command
representation and verify cache behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
|
||
|
|
9c9e6b0bcb |
refactor: introduce Workspace/Session state model and clarify component responsibilities (#406)
## Summary Introduces a two-layer state model that cleanly separates disk-based project state from per-open-file editing state, and redistributes responsibilities across server components so each has a single, clear role. ## New types **Workspace** — all persistent, project-wide shared state: - CompilationDatabase, PathPool, DependencyGraph, CompileGraph - path_to_module mapping, PCH cache, PCM cache, PCM paths - ProjectIndex, MergedIndex shards - CliceConfig - Methods: on_file_saved(), on_file_closed(), load/save/cleanup_cache(), build_module_map(), fill_pcm_deps(), cancel_all() **Session** — volatile per-open-file editing state: - text, version, generation, ast_dirty - pch_ref (references Workspace.pch_cache), ast_deps, header_context - file_index (OpenFileIndex for unsaved buffer) - path_id member for self-identification ## Component responsibilities after refactor | Component | Role | Owns state? | |-----------|------|-------------| | **Workspace** | Disk truth + shared caches | Yes (all project state) | | **Session** | One open file editing state | Yes (per-file only) | | **Compiler** | Compilation pipeline, worker communication | No (references only) | | **Indexer** | Index queries + background indexing scheduling | Scheduling state only | | **MasterServer** | LSP protocol dispatch + lifecycle coordination | sessions map | ## What moved where **Into Workspace** (from Compiler/MasterServer): - PCH/PCM cache management (load_cache, save_cache, cleanup_cache) - Module map building (build_module_map, fill_pcm_deps) - File lifecycle hooks (on_file_saved, on_file_closed) - cancel_all, OpenFileIndex/MergedIndexShard type definitions **Into Session** (from Compiler documents map): - Document text, version, generation, ast_dirty - PCH reference, dependency snapshot, header context **Into Indexer** (from MasterServer): - Background indexing queue, scheduling state, idle timer - schedule(), enqueue(), run_background_indexing() **Into syntax/completion.h** (from Compiler): - detect_completion_context() — pure text parsing - complete_module_import() — prefix match on module names - complete_include_path() — directory listing against search paths **Inlined into MasterServer** (from Compiler): - didOpen/didChange/didClose/didSave handlers - switchContext/currentContext - publish_diagnostics/clear_diagnostics **Deleted from Compiler** (9 methods): - open_document, apply_changes, close_document, on_save - switch_context, get_active_context, invalidate_host_contexts - on_file_closed, on_file_saved, complete_include, complete_import ## Tests - 481 tests pass (465 existing + 16 new completion tests) - New: tests/unit/syntax/completion_tests.cpp ## Diff stats 15 files changed, +1857, -1555 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Enhanced completion support for include paths and module imports with improved context detection. * Added background indexing system for automatic project symbol indexing. * **Bug Fixes** * Improved reliability of document change tracking and compilation state management. * Better handling of header file compilation contexts. * **Tests** * Added unit tests for completion context detection and module/include path completion. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
bb0b160a28 |
refactor(server): extract Indexer and Compiler from MasterServer (#403)
## Summary - **Extract `Indexer` class** — owns all index state (ProjectIndex, MergedIndex shards, OpenFileIndex) and query methods (definition, references, call/type hierarchy, workspace symbol search) - **Extract `Compiler` class** — owns document state, PCH/PCM cache, compile argument resolution, header context, `ensure_compiled`, and worker forwarding - **MasterServer is now a pure LSP handler registration layer** (~700 lines, down from ~3200) - **`MergedIndexShard`** wraps `index::MergedIndex` with a lazily-cached PositionMapper; `OpenFileIndex` gains matching `find_occurrence()`/`find_relations()` APIs — callers get pre-converted LSP ranges directly - **Indexer returns typed values** (`vector<Location>`, `vector<CallHierarchyIncomingCall>`, etc.) instead of pre-serialized JSON, fixing the references handler from JSON string surgery to simple vector concatenation - **Fix**: duplicate `workspace/symbol` loop in the original code ## Test plan - [x] 465 unit tests pass - [x] 113 integration tests pass - [x] 2/2 smoke tests pass - [x] `clang-format` applied 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Server-side C++ compilation orchestration (module & precompiled header builds) with LSP-integrated document handling. * **Improvements** * Deterministic, persistent, dependency-aware caching to avoid redundant rebuilds and speed up incremental work. * Better cross-file indexing and navigation, improved diagnostics and more reliable include/import-aware completions. * **Tests** * Unit tests updated to the unified worker query/build request shapes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
ada202e489 |
feat(index): piggyback indexing on PCH/PCM builds and open-file compiles (#402)
## Summary Piggyback index construction onto existing compilation steps, eliminating redundant recompilation in background indexing: - **`TUIndex::build` gains `interested_only` parameter**: `true` traverses only the main file's top-level decls; `false` (default) traverses the full AST - **PCH build indexes preamble headers**: stateless worker calls `TUIndex::build(unit)` (full traversal) after successful `BuildPCH`, clears `main_file_index`, serializes and sends back; master merges into MergedIndex - **PCM build indexes module interface**: stateless worker calls `TUIndex::build(unit, true)` after successful `BuildPCM`; master merges into MergedIndex - **Open-file compile indexes main file**: stateful worker calls `TUIndex::build(unit, true)` after successful `Compile`, serialized in `CompileResult` - **New `OpenFileIndex` in-memory structure**: master holds `FileIndex + SymbolTable + buffer text` per open file — not persisted to disk, not merged, discarded on close - **Dual-source query path**: `query_index_relations`, `lookup_symbol_at_position`, `find_symbol_definition_location`, all hierarchy handlers, and `workspace/symbol` check `OpenFileIndex` first (fresher), then fall back to `MergedIndex` (disk-indexed) - **Background indexing skips open files**: checked via `documents.count()`; on `didClose` the file is re-queued into `index_queue` - **`didSave` re-queues non-open dependents**: dirtied files from `compile_graph->update()` that are not open get pushed into `index_queue` for background re-indexing - **Extract `lookup_occurrence` helper**: binary search + forward scan picking the innermost (narrowest) match, replacing a broken `while/break/break` pattern - **Extract `find_symbol_info` helper**: consolidates 6 duplicated "search open file indices then ProjectIndex" lookups into one method - **`resolve_hierarchy_item` checks open file indices**: no longer limited to ProjectIndex only ## Test plan - [x] 465 unit tests pass - [x] 105 integration tests pass (including all `test_index` cases: GoToDefinition, FindReferences, CallHierarchy, TypeHierarchy, WorkspaceSymbol) - [x] Manual: open a file and immediately use GoToDefinition — should work without waiting for background indexing - [x] Manual: close a file and verify background indexing picks it up and produces a MergedIndex shard 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
836f415e50 |
feat: header context protocol — queryContext, currentContext, switchContext (#398)
## Summary Add three LSP protocol extensions that allow users to manage compilation contexts for header files and source files with multiple CDB entries. ### Protocol extensions (`protocol.h`) | Command | Purpose | |---------|---------| | `clice/queryContext` | List all possible contexts for a file. Headers → host source files; sources → CDB entries. Paginated (10 per page, `offset` param). | | `clice/currentContext` | Query the active context override for a file (null if default). | | `clice/switchContext` | Set the active context, invalidate caches, trigger recompilation. | ### Header context resolution (`master_server.cpp`, `dependency_graph.cpp`) - `find_host_sources()`: BFS the reverse include graph to find source files that transitively include a header - `find_include_chain()`: BFS the forward include graph to find the shortest include chain from host to header - `resolve_header_context()`: walks the include chain, extracts content before each `#include` directive, concatenates with `#line` markers into a preamble file (hash-addressed under `.clice/header_context/`) - `fill_header_context_args()`: uses the host source's CDB entry, replaces source path with header path, injects `-include preamble.h` ### Compilation flow - Default: headers compile as standalone files (no context) - After `switchContext`: `fill_compile_args` checks `active_contexts` first → uses host's CDB entry + preamble injection - Fallback: if no CDB entry and no active context, auto-resolves via `resolve_header_context` - `#include` directive matching uses precise filename extraction from `"..."` / `<...>`, not substring matching ### Source file multiple contexts (`multi_context` workspace) - `queryContext` on a source file returns all CDB entries with distinguishing labels (extracted from `-D`, `-O`, `-std=` flags) ### Test data - `header_context/`: non-self-contained 3-level chain (`main.cpp` → `utils.h` → `inner.h`), `types.h` provides `Point` struct - `multi_context/`: single source with two CDB entries (`-DCONFIG_A`, `-DCONFIG_B`) ### Tests (9 integration tests) - queryContext returns host sources for headers - queryContext returns CDB entries for source files - currentContext defaults to null - switchContext sets active context, currentContext reflects it - Full flow: open → query → switch → hover works in non-self-contained header - Deep nested: switchContext + hover on `inner.h` (3 levels deep) - Multiple CDB entries: queryContext returns both CONFIG_A and CONFIG_B ## Test plan - [x] Unit tests: 465 passed - [x] Integration tests: 113 passed (9 new header context tests) - [x] Smoke test: 1/1 passed - [ ] Manual VSCode testing 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
1627b96d2b |
fix: linking required LLVM libs only (#339)
This patch restricts the GLOB expression to only LLVM & Clang libraries,
avoiding linking to a large list of libraries when using system LLVM.
Also, this patch explicitly avoids linking to `LLVM-<ver>` and
`clang-cpp`, as they will cause lots of duplicate symbol errors
Below is a small set of errors generated when linking to `clang-cpp`:
```
ld.lld: error: duplicate symbol: clang::ast_matchers::internal::DynTypedMatcher::constructRestrictedWrapper(clang::ast_matchers::internal::DynTypedMatcher const&, clang::ASTNodeKind)
>>> defined at libclangASTMatchers.a(ASTMatchersInternal.cpp.obj)
>>> defined at libclang-cpp.dll.a(libclang-cpp.dll)
ld.lld: error: duplicate symbol: clang::Stmt::getEndLoc() const
>>> defined at libclangAST.a(Stmt.cpp.obj)
>>> defined at libclang-cpp.dll.a(libclang-cpp.dll)
ld.lld: error: duplicate symbol: clang::ast_matchers::internal::createAndVerifyRegex(llvm::StringRef, llvm::Regex::RegexFlags, llvm::StringRef)
>>> defined at libclangASTMatchers.a(ASTMatchersInternal.cpp.obj)
>>> defined at libclang-cpp.dll.a(libclang-cpp.dll)
ld.lld: error: duplicate symbol: clang::ast_matchers::internal::BoundNodesTreeBuilder::addMatch(clang::ast_matchers::internal::BoundNodesTreeBuilder const&)
>>> defined at libclangASTMatchers.a(ASTMatchersInternal.cpp.obj)
>>> defined at libclang-cpp.dll.a(libclang-cpp.dll)
ld.lld: error: duplicate symbol: clang::Stmt::getStmtClassName() const
>>> defined at libclangAST.a(Stmt.cpp.obj)
>>> defined at libclang-cpp.dll.a(libclang-cpp.dll)
ld.lld: error: duplicate symbol: clang::ast_matchers::internal::getExpansionLocOfMacro(llvm::StringRef, clang::SourceLocation, clang::ASTContext const&)
>>> defined at libclangASTMatchers.a(ASTMatchersInternal.cpp.obj)
>>> defined at libclang-cpp.dll.a(libclang-cpp.dll)
ld.lld: error: duplicate symbol: clang::transformer::remove(std::__1::function<llvm::Expected<clang::CharSourceRange> (clang::ast_matchers::MatchFinder::MatchResult const&)>)
>>> defined at libclangTransformer.a(RewriteRule.cpp.obj)
>>> defined at libclang-cpp.dll.a(libclang-cpp.dll)
ld.lld: error: duplicate symbol: clang::ast_matchers::internal::hasAnyOverloadedOperatorNameFunc(llvm::ArrayRef<llvm::StringRef const*>)
>>> defined at libclangASTMatchers.a(ASTMatchersInternal.cpp.obj)
>>> defined at libclang-cpp.dll.a(libclang-cpp.dll)
ld.lld: error: duplicate symbol: clang::transformer::detail::makeEditGenerator(clang::transformer::ASTEdit)
>>> defined at libclangTransformer.a(RewriteRule.cpp.obj)
>>> defined at libclang-cpp.dll.a(libclang-cpp.dll)
ld.lld: error: duplicate symbol: clang::Stmt::stripLabelLikeStatements() const
>>> defined at libclangAST.a(Stmt.cpp.obj)
>>> defined at libclang-cpp.dll.a(libclang-cpp.dll)
ld.lld: error: duplicate symbol: clang::Stmt::IgnoreContainers(bool)
>>> defined at libclangAST.a(Stmt.cpp.obj)
>>> defined at libclang-cpp.dll.a(libclang-cpp.dll)
ld.lld: error: duplicate symbol: clang::WhileStmt::getConditionVariable()
>>> defined at libclangAST.a(Stmt.cpp.obj)
>>> defined at libclang-cpp.dll.a(libclang-cpp.dll)
ld.lld: error: duplicate symbol: clang::ValueStmt::getExprStmt() const
>>> defined at libclangAST.a(Stmt.cpp.obj)
>>> defined at libclang-cpp.dll.a(libclang-cpp.dll)
ld.lld: error: duplicate symbol: clang::ast_matchers::internal::matchesAnyBase(clang::CXXRecordDecl const&, clang::ast_matchers::internal::Matcher<clang::CXXBaseSpecifier> const&, clang::ast_matchers::internal::ASTMatchFinder*, clang::ast_matchers::internal::BoundNodesTreeBuilder*)
>>> defined at libclangASTMatchers.a(ASTMatchersInternal.cpp.obj)
>>> defined at libclang-cpp.dll.a(libclang-cpp.dll)
ld.lld: error: duplicate symbol: clang::IfStmt::getConditionVariable()
>>> defined at libclangAST.a(Stmt.cpp.obj)
>>> defined at libclang-cpp.dll.a(libclang-cpp.dll)
ld.lld: error: duplicate symbol: clang::transformer::detail::buildMatchers(clang::transformer::RewriteRuleBase const&)
>>> defined at libclangTransformer.a(RewriteRule.cpp.obj)
>>> defined at libclang-cpp.dll.a(libclang-cpp.dll)
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Improved build configuration to explicitly discover and link LLVM and
Clang libraries plus optional z/zstd compression libraries; updated
linking to include these groups and retained the static Clang build
definition, resulting in more reliable and consistent compilation across
environments.
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
|
||
|
|
a40c0b3bf8 |
docs: expand compilation database generation guide (#401)
## Summary - Fill in Visual Studio, Makefile, Meson sections (previously TODO) - Expand Xmake section with CLI and VSCode extension workflows - Simplify Others section to recommend [catter](https://github.com/clice-io/catter) - Fix CJK-Latin spacing in Chinese docs - English and Chinese docs updated in sync Supersedes #313 by @Stehsaer. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Stehsaer <Stehsaer@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
d253c1f099 |
feat: collect #embed and __has_embed directives in PPCallbacks (#309)
## Summary - Add `Embed` and `HasEmbed` structs to `directive.h` for storing `#embed` / `__has_embed` directive info - Implement `EmbedDirective` and `HasEmbed` PPCallbacks in `DirectiveCollector`, using the current `CompilationUnitRef` API - Add unit tests for both directives (including non-existent file handling) Rebased onto current main, resolving conflicts from the `Compiler/` → `compile/` restructuring and the `CompilationUnitRef` API migration. Original PR by @Guo-Shiyu. ## Test plan - [x] `pixi run unit-test` — 465 tests passed, 0 failures Co-authored-by: ykiko <ykikoykikoykiko@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
0c107fc2c5 |
chore: disable coderabbit auto summary on PRs (#400)
## Summary - Disable CodeRabbit's auto-generated PR summary while keeping code review enabled 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Configuration updates to automated review processes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
018bad4ea8 |
ci: add conventional commit format check (#399)
## Summary - Add `conventional-commit` CI job that validates PR titles and push commit messages follow the `type(scope)?: description` format - Valid types: `feat`, `fix`, `refactor`, `chore`, `build`, `ci`, `docs`, `test`, `perf`, `style`, `revert` - Runs on both PR and push events, skips tag pushes - Zero dependencies, pure bash regex check ## Test plan - [x] PR title of this PR itself passes the check - [ ] CI runs and passes 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Enhanced continuous integration pipeline to validate commit message formatting standards on all pull requests and commits. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
e239b0d32c |
feat: smart PCH rebuild, #include/import completion, rapid-edit robustness (#394)
## Summary ### Preamble completeness check - `is_preamble_complete()` in `scan.cpp`: checks whether `#include`/`import`/`export module` directives in the preamble region are syntactically complete (have closing `>`/`"`/`;`) - `ensure_pch` defers PCH rebuild when preamble is incomplete (user still typing), reuses old PCH instead of failing ### #include / import completion - Master intercepts completion requests in `#include "..."` / `#include <...>` / `import ...` contexts before forwarding to worker - `complete_include()`: searches include paths (from compile args via `SearchConfig`) using `DirListingCache`, supports quoted/angled/multi-level paths - `complete_import()`: filters `path_to_module` map by prefix - Word boundary checks prevent false matches (e.g. `important` not treated as `import`) ### Detached compile task (rapid-edit fix) - Compile operations (`ensure_deps` + `send_stateful` + `publish_diagnostics`) run as detached tasks via `loop.schedule()`, independent of the LSP request coroutine chain - LSP `$/cancelRequest` can no longer kill in-flight compilations — previously, cancellation would destroy the `ensure_compiled` coroutine frame, leaving `doc.compiling` permanently set and hanging all subsequent requests - `CompileGuard` RAII ensures `doc.compiling` is always cleaned up even if the detached task fails - Stale feature requests (where `ast_dirty` became true after compile finished) are dropped before forwarding to worker ### Other fixes - `signal(SIGPIPE, SIG_IGN)` on POSIX: prevents server crash when LSP client disconnects mid-write - `CompilationUnitRef::file_path()` / `deps()`: null-check `FileEntryRef` to prevent segfault on invalid FileID - `stateless_worker.cpp`: log BuildPCH diagnostic errors for debuggability - Default worker counts changed to 2 stateful + 3 stateless - `logging_dir` default changed to `.clice/logs` in config ### Tests - 19 unit tests for `is_preamble_complete` (incomplete `#include`, `import`, `export module`, mixed cases) - Integration tests: `test_include_completion.py` (5 tests), `test_import_completion.py` (4 tests), `test_rapid_edit.py` (2 tests), `test_pch.py` (4 new tests) - Smoke test: `rapid_edit.jsonl` — recorded VSCode session with 40 rapid edits + 61 cancel requests ## Test plan - [x] Unit tests: 463 passed - [x] Integration tests: 104 passed - [x] Smoke test (rapid_edit.jsonl): PASS - [x] Manual VSCode testing with `#include <iostream>` project 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
aae246e465 |
feat: classify more semantic token modifiers (#395)
## Summary - add declaration helpers to classify semantic token modifiers such as readonly, static, abstract, virtual, default library, and constructor/destructor - unwrap template declarations before applying attribute-style modifiers so modifier checks hit the underlying declaration - keep templated/dependent-name handling and expand emitted semantic token modifiers in `semantic_tokens.cpp` ## Testing - Not run (not requested in this turn) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Enhanced semantic token analysis to improve code recognition and more accurate classification of declarations across C++ and Objective-C codebases. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d04bc6f774 |
feat: register server capability correctly (#397)
## Summary - register workspace and text document capabilities through the structured LSP capability types - advertise completion, signature help, declaration, definition, implementation, type definition, and reference support more explicitly - add placeholder handlers for declaration, type definition, and implementation requests so the advertised capabilities have matching routes ## Testing - Not run (not requested) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added workspace folder support for improved project tracking. * Registered navigation handlers for type-definition, implementation, and declaration (currently return a “not supported yet” placeholder). * **Improvements** * Enhanced completion and signature help with explicit trigger characters and clearer capability declarations. * **Tests** * Relaxed capability assertions to recognize more nuanced enabled/disabled states. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8d4ad26834 |
feat: classify dependent-name semantic token modifier (#387)
## Summary - classify unresolved using declarations with the `dependentName` semantic token modifier - include the declaration modifier on definitions to match clangd's semantic token behavior - extend the semantic token modifier legend coverage in integration tests ## Testing - pixi run python -m pytest -s --log-cli-level=INFO tests/integration/test_server.py -k 'semantic_token_modifier_legend or capabilities' --executable=./build/bin/clice <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added many new semantic token modifiers (deprecated, deduced, readonly, static, abstract, virtual, dependent-name, constructor/destructor, user-defined, mutable-usage flags) and new scope markers (function, class, file, global). * Improved tagging for declarations, definitions and dependent names in semantic tokens. * **Tests** * Added an integration test verifying the semantic token modifier legend and its ordering. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b6886d222b |
feat: per-session file-based logging with crash capture (#393)
## Summary
Implement structured file-based logging with per-component separation
and crash stacktrace capture.
### Log output structure
```
.clice/logs/2026-04-05_10-30-00_<pid>/
master.log
SF-0.log
SF-1.log
SL-0.log
```
### Changes
**Logging infrastructure** (`logging.h`, `logging.cpp`)
- `file_logger()` creates a dual-sink logger (file + stderr), so logs go
to both the file and terminal
- Pre-checks log directory creation and file writability before
constructing spdlog sinks; falls back to existing stderr logger on
failure
- `install_crash_handler()` uses LLVM's `AddSignalHandler` +
`PrintStackTraceOnErrorSignal` to write crash stacktraces into the
component's log file (and also to stderr)
- Fix `LOG_MESSAGE` macro: wrap in `do { } while(0)` to prevent
dangling-else
- Fix typo: `file_loggger` → `file_logger`
**Config** (`config.h`, `config.cpp`)
- Add `logging_dir` field to `CliceConfig`, defaulting to
`<cache_dir>/logs/`
- Apply `${workspace}` variable substitution to `logging_dir`
**Master server** (`master_server.h`, `master_server.cpp`)
- After config loads, create a session directory named
`<timestamp>_<pid>` under `logging_dir` and switch master to file
logging
- Pass session log directory to worker pool
**Worker pool** (`worker_pool.h`, `worker_pool.cpp`)
- Pass `--worker-name` (e.g. `SF-0`, `SL-1`) and `--log-dir` to spawned
worker processes
- Add `log_dir` to `WorkerPoolOptions`
**Workers** (`stateful_worker.h/cpp`, `stateless_worker.h/cpp`)
- Accept `worker_name` and `log_dir` parameters; switch to file logging
when `log_dir` is provided
**CLI cleanup** (`clice.cc`)
- Remove `--stateful-worker-count`, `--stateless-worker-count` from CLI
(config-file only)
- Group internal worker args (`--worker-memory-limit`, `--worker-name`,
`--log-dir`) separately
**Docs** (`docs/clice.toml`)
- Fix `logging_dir` example: `.clice/logging` → `.clice/logs`
## Test plan
- [x] `pixi run cmake-build RelWithDebInfo` compiles successfully
- [ ] Verify log files created under `.clice/logs/<timestamp>_<pid>/`
- [ ] Verify each component writes to its own file
- [ ] Verify crash stacktrace appears in component log file
- [ ] Verify `logging_dir` override in `clice.toml` works
- [ ] Verify graceful fallback when log directory is not writable
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Session-specific logging directories (timestamped) and per-worker log
files
* CLI options to set worker name and log directory; general log level
control
* Configurable logging directory with default `<cache_dir>/logs/`
* **Bug Fixes**
* Fixed file-logging name/initialization issues; ensures directory
creation and deterministic filenames
* Added crash-handler support to append stack traces to logs
* **Documentation**
* Updated example config to use `${workspace}/.clice/logs`
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
c14b8de18f |
chore: remove xmake, clean up unused files, simplify CLI parsing (#392)
## Summary - **Remove xmake build system**: delete `xmake.lua`, `test-xmake.yml` workflow, and all xmake-related pixi tasks - **Migrate packaging to CMake**: `publish-clice.yml` now uses `cmake -DCLICE_RELEASE=ON` instead of xmake pack - **Clean up**: remove unused `tests/uv.lock`, `.xmake/` from `.gitignore`, xmake references from docs - **Benchmark CI**: change trigger from `pull_request` to `workflow_dispatch` (manual only) - **Simplify CLI parsing**: use `DecoKV(style = KVStyle::JoinedOrSeparate)` in `clice.cc` and `unit_tests.cc`, replacing verbose `DecoKVStyled` with manual `static_cast` bitmask; use comma separators; explicit `names` only for underscore fields ## Test plan - [x] `pixi run cmake-build RelWithDebInfo` compiles successfully - [x] Verify `pixi run test` passes - [x] Verify `pixi run package` produces correct archives via CMake release build - [x] Verify benchmark workflow can be triggered manually via `gh workflow run benchmark` 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Consolidated CI workflows; some automated triggers converted to manual invocation * Standardized shell for workflow steps and removed legacy build workflow * Switched packaging/build tasks to a CMake/Ninja flow and updated artifact paths * Adjusted ignore rules to include previously-ignored build metadata * **Documentation** * Removed XMake-specific build and test instructions; docs now reflect the CMake-based workflow * **Style** * Updated CLI option declaration style (no user-facing flag name changes) <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
3838bedcbf |
feat: persistent PCH/PCM cache across sessions (#391)
## Summary
PCH and PCM artifacts are now cached to disk at
`.clice/cache/{pch/,pcm/}` with content-addressed filenames, so they
survive server restarts. Dependency metadata is persisted in
`cache.json` (using eventide serde) with a shared path table for
deduplication.
### Key changes
- **protocol.h**: `output_path` field on `BuildPCHParams` /
`BuildPCMParams` so master specifies where workers write
- **stateless_worker.cpp**: Atomic write via `.tmp` + `fs::rename`;
`CompilationUnit` destroyed before rename to flush the file to disk;
fallback to temp file when `output_path` is empty (unit tests)
- **master_server.h**: `PCMState` struct, `pcm_states` map,
`load_cache()` / `save_cache()` / `cleanup_cache()` methods
- **master_server.cpp**: Cache lifecycle — load from `cache.json` on
startup, save after each PCH/PCM build and on exit; deterministic path
computation (`xxh3` preamble hash for PCH, module name + source path
hash for PCM); stale files (>7 days) cleaned on startup; `cache.json`
uses shared path table to avoid redundant storage of header paths across
entries
- **filesystem.h**: `fs::rename()` helper; `ThreadSafeFS` broadened to
match `.pch` extension instead of `preamble-` prefix
- **tests**: 11 new integration tests covering PCH/PCM persistence,
cross-session reuse, staleness detection, shared preamble dedup, and
restart survival; unit tests updated with `output_path`
### Naming scheme
- **PCH**: `.clice/cache/pch/<016x(xxh3(preamble))>.pch`
- **PCM**:
`.clice/cache/pcm/<module_name>-<016x(xxh3(source_path))>.pcm`
## Test plan
- [x] Unit tests — 448 passed
- [x] Integration tests — 92 passed (including 11 new persistent cache
tests)
- [x] Smoke tests — 1 passed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
31d9c609b6 |
fix: data race in stateful worker between Compile and DocumentUpdate (#389)
## Summary Fix two data races in the stateful worker that caused spurious "redefinition" errors during rapid edits, and remove a didChange workaround that is no longer needed after clice-io/eventide#95. ### stateful_worker.cpp **Compile handler**: move `params` → `doc` field copy **after** `strand.lock()`. Previously the copy happened before the lock, so a concurrent Compile request waiting on the strand could overwrite `doc.text` while `et::queue` was reading it on the thread pool: ``` T1: Compile A → doc.text = text_A → lock → et::queue reads doc.text T2: Compile B → doc.text = text_B → waits for strand (overwrites!) T3: et::queue sees text_B instead of text_A → PCH/text mismatch ``` **DocumentUpdate handler**: only mark `dirty`, stop modifying `doc.text`/`doc.version`. The event loop notification can fire while `et::queue` work is running on the thread pool — writing `doc.text` from one thread while reading it from another is a data race. ### master_server.cpp Remove the `{0,0}-{0,0}` range workaround for whole-document `didChange`. eventide's variant deserialization now correctly rejects `TextDocumentContentChangePartial` when the `range` field is absent (clice-io/eventide#95), so `TextDocumentContentChangeWholeDocument` is matched as intended. ### protocol.h Remove `text` field from `DocumentUpdateParams` — the worker no longer needs it since DocumentUpdate only sets the dirty flag. ### Integration tests (+312 lines) Extend test_staleness.py from 5 to 14 tests covering document lifecycle: - `didChange` body edit → recompilation with updated diagnostics - `didChange` preamble edit → PCH rebuild + clean recompilation - `didClose` + reopen → compiles fresh from disk - `didClose` → hover returns None - `didSave` header → dependent file recompiles - `didSave` module → CompileGraph dependents invalidated ## Test plan - [x] 422 unit tests pass (426 on CI with extra test suites) - [x] 14 integration tests pass locally - [x] Depends on clice-io/eventide#95 (merged) 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Smaller document-update notifications sent to background workers (only path and version). * **Bug Fixes** * Reduced races and unnecessary work between update and compile flows. * Prevented notifications from overwriting in-memory document text, improving state consistency. * Safer concurrent handling to avoid mid-request eviction of active documents. * **Tests** * Added integration tests for staleness, dependency propagation, and LSP lifecycle. * Updated unit tests to match revised update behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
a1b6c0632d |
refactor(semantic): rewrite template resolver — eliminate SubstType, fix crashes (#388)
## Summary Rewrites the template resolver to eliminate `SubstType`/`CodeSynthesisContexts` dependency, fixing widespread crashes on real-world C++ code. ### What changed **Architecture**: replaced double-TreeTransform (PseudoInstantiator + SubstType) with single-layer design: - **`SubstituteOnly`** — new lightweight TreeTransform for Phase 2 (typedef expansion + parameter substitution). Does NOT override `TransformDependentNameType`, breaking the typedef ↔ lookup infinite cycle. - **`PseudoInstantiator`** — retains heuristic lookup (the unique value clang doesn't provide), delegates substitution to `SubstituteOnly`. **Deleted**: - `DesugarOnly` class - `instantiate()` method and all `CodeSynthesisContexts` / `SubstType` usage - `state()` / `rewind()` stack management - `std::abort()` on valid NNS kinds - `#ifndef NDEBUG` debug flag + `std::print` logging **Added**: - `SubstituteOnly` class with depth guard - `InstantiationStack::findArgument()` — depth/index based parameter lookup - CTD→TST resolution for `DependentTemplateSpecializationType` (enables `__alloc_traits::rebind<T>::other` resolution) - `active_resolutions` (DNT cycle detection) + `active_ctd_lookups` (CTD cycle detection via RAII guard) - Stack frame pollution fix: pop lookup frames before further `TransformType` - Pack argument support (single-element forwarding) - Null safety on all Transform return paths - Structured `LOG_DEBUG` trace logging with indentation - `--log-level` / `--test-filter` CLI options for unit test runner - Bounds checks in `hole()`, `ResugarOnly`, `visitTemplateDeclContexts` **Tests**: 20 → 36 passing test cases (+5 documented TODOs for known limitations). New coverage: recursive base classes, multiple inheritance, typedef chains, CRTP, `remove_reference` partial specs, `std::map`, `std::basic_string`, pack forwarding. ### Stress test result ``` CDB: llvm-project build (4669 C++ files) Types resolved: 3,690,190 Types unchanged: 75,907,298 Crashes: 0 ``` Before this PR, the same test produced ~52% crash rate (413 crashes in 800 files). ### Known limitations (documented as TODOs) - NTTP partial specialization matching (`enable_if<true, X>`, `A<X, 0>`) - Template template parameter deduction - Non-dependent qualifier nested class templates (`Outer<int>::Inner<X>`) - Multi-element pack expansion - `CXXDependentScopeMemberExpr` lookup (unimplemented) - Operator-name lookup in dependent contexts 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Enhanced template resolution with improved cycle detection to prevent infinite loops * Better type substitution handling for complex dependent types * **Bug Fixes** * Fixed edge cases in template specialization resolution * Improved null-safety in type transformations * Enhanced handling of standard library template traits * **Tests** * Expanded test coverage for recursive and complex template patterns * Added validation for standard library type resolution <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
1dd94e54c0 |
feat: two-layer staleness tracking with concurrent compilation dedup (#386)
## Summary Replace the `didSave` sledgehammer (`pch_hashes.clear()` + mark-all-dirty) with precise per-file dependency tracking that avoids unnecessary recompilation. ### Two-layer staleness detection After each successful compilation, a `DepsSnapshot` is captured (interned path IDs + xxh3 content hashes + timestamp). On the next feature request, `deps_changed()` checks: - **Layer 1 (fast):** stat each dep, compare mtime against `build_at`. If mtime is older → skip. Uses strict `<` so same-second modifications fall through. - **Layer 2 (precise):** for files with newer mtime, re-hash content and compare. Catches touch-without-change (git checkout, backup restore) without false rebuilds. Special cases: files unreadable at build time (hash=0) always fall through to Layer 2; disappeared files are detected via stat failure. ### Consolidated PCH state Scatter of four maps (`pch_paths`, `pch_bounds`, `pch_hashes`, `pch_building`) → single `PCHState` struct with `path`, `bound`, `hash`, `deps`, `building` fields. `DepsSnapshot` and `SymbolInfo` moved out of `MasterServer` to namespace scope. ### Concurrent compilation dedup - **`ensure_compiled`:** `DocumentState::compiling` event prevents duplicate AST compilations. Waiters `co_await` the event and check `ast_dirty` after waking. When deps change is detected during an in-flight build, `generation` is bumped so the builder's generation check prevents it from incorrectly clearing `ast_dirty`. - **`ensure_pch`:** `PCHState::building` event deduplicates PCH builds. Waiters re-validate `preamble_hash` after waking to handle edits during the wait. The `bound==0` path waits for in-flight builds before erasing. Old PCH is deleted and path cleared before rebuild starts, so waiters never see a stale path on failure. ### `didSave` changes Removed the blanket `pch_hashes.clear()` + mark-all-dirty on save. Staleness is now detected lazily via `deps_changed()` at the next feature request. `didSave` still invalidates `CompileGraph` dependents for module deps. ### FIXME noted Rapid `didChange` edits (especially preamble changes) can cause the stateful worker to compile with stale/concatenated text. Root cause is in the worker, not in staleness tracking — noted as FIXME for a follow-up PR. ## Test plan 13 integration tests covering: - [x] Header mtime change → AST recompilation - [x] Preamble header change → PCH rebuild - [x] No change → fast path (cached AST reused) - [x] Touch without content change → Layer 2 hash skips recompile - [x] Header replaced with different content → detected - [x] Fix error in header → diagnostics clear - [x] Multiple files sharing header → each detects independently - [x] Transitive header change → detected through include chain - [x] didChange body edit → recompilation with updated diagnostics - [x] didClose + reopen → compiles new disk content - [x] didClose → hover returns None - [x] didSave header → dependent file recompiles - [x] didSave module → CompileGraph dependents invalidated 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
e24eff6c16 |
refactor: pull-based compilation for document lifecycle (#385)
## Summary Replace the push-based compilation model with a pull-based (lazy) model where compilation is driven entirely by feature requests. ### Server core (`master_server.cpp/h`) - **Remove** `schedule_build()`, `run_build_drain()`, debounce timers, and `DocumentState` flags (`build_running`, `build_requested`, `drain_scheduled`) - **Remove** `debounce_ms` config field - `didOpen`/`didChange` only update `DocumentState` and mark `ast_dirty` — no compilation triggered - `didSave` marks dependent docs dirty via `CompileGraph::update()`, invalidates PCH hashes, marks **all** open documents `ast_dirty` (header saves), and queues background indexing - **Implement** `ensure_compiled(path_id)` — the pull-based entry point called by `forward_stateful()`/`forward_stateless()` before every feature request: 1. Fast-path if `!ast_dirty` 2. Compile C++20 module deps via `compile_graph->compile_deps()` 3. Build/reuse PCH via `ensure_pch()` (only attach on success) 4. Send `CompileParams` to stateful worker 5. Publish diagnostics, clear dirty, schedule indexing 6. Generation mismatch → return `false`, keep dirty for retry - `forward_stateless()` now also calls `compile_graph->compile_deps()` before stateless requests (completion/signatureHelp) - Move module-implementation-unit implicit dependency handling into `resolve_fn` (was duplicated in `run_build_drain` and `ensure_compiled`) ### CompileGraph (`compile_graph.cpp/h`) - **Add** `compile_deps(path_id)` — compiles all transitive module dependencies but NOT the file itself (used for plain .cpp files that `import` modules) - Unify `compile`/`compile_deps` via `compile_impl(path_id, ancestors, dispatch_self)` parameter - `compile_deps` compiles dependencies concurrently via `when_all` - Extract `finish()` lambda to deduplicate `compiling=false; completion->set()` cleanup across all exit paths - Use `std::ranges::remove` instead of legacy `std::remove` ### Test infrastructure (`conftest.py`) - `open_and_wait()` now sends a hover request to trigger `ensure_compiled()` (pull-based model requires a feature request to compile) - Fix URI handling: send percent-encoded URI on the wire, normalize for internal lookups, store diagnostics under both raw and normalized URI keys - Add `_normalize_uri()` helper using `urllib.parse.unquote` ### Integration tests - Update all tests for pull-based model: no more waiting on `didOpen` diagnostics - `_wait_for_index()` sends hover to trigger compilation before polling `workspace/symbol` - `test_hover_save_close` simplified — hover directly triggers compilation - `test_save_recompile` and `test_pch_*` wait for fresh diagnostics after hover-triggered recompilation ### Unit tests (`compile_graph_tests.cpp`) - Extract `compiled`/`graph` as TEST_SUITE members with `std::optional<CompileGraph>` - Extract `execute(callback)` helper to deduplicate event_loop boilerplate - Add 8 new `compile_deps` tests: no-deps, single dep, chain, diamond, failure, plain-cpp, concurrent dedup, resolve-once - Remove redundant `inline` on file-scope helpers ## Test plan - [x] Unit tests: 426 passed, 5 skipped - [x] Smoke tests: 1/1 passed - [x] Integration tests: 69 passed, 0 failed, no hangs 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
c697ffcf91 |
chore(vscode): move dev configs to repo root (#384)
## What changed
This PR moves the shared VS Code development workflow to the repository
root.
It adds repo-level `.vscode/launch.json` and `.vscode/tasks.json` so
contributors can debug `clice` and the VS Code extension from the root
workspace with relative paths.
The checked-in tasks are intentionally limited to extension-side `pnpm`
workflows such as installing dependencies and running the extension
watcher. They do not build the `clice` executable or unit tests.
It also updates `.gitignore` to allow only those two shared VS Code
config files to be committed, while continuing to ignore other local
`.vscode` files.
Finally, it removes the duplicate `editors/vscode/.vscode` folder so
there is a single supported VS Code setup in the repo.
## Why
The previous setup split VS Code configs between local-only root files
and tracked configs under `editors/vscode/.vscode`, which made the
development/debug flow less consistent.
Keeping only extension-side tasks avoids baking a specific native build
workflow into committed editor config while still making extension
development usable out of the box.
## Developer impact
Contributors can now open the repository root in VS Code and use the
checked-in launch/tasks configs directly.
The extension debug configs only disable competing C/C++ language
extensions (`clangd` and `cpptools`) instead of disabling every
extension.
All committed paths remain relative to `${workspaceFolder}`.
## Validation
- Ran `python3 -m json.tool .vscode/launch.json`
- Ran `python3 -m json.tool .vscode/tasks.json`
|
||
|
|
94bc872cdb |
feat: add LSP trace recording and smoke test replay (#383)
## Summary Add LSP trace recording and replay-based smoke testing infrastructure. ### clice changes (`src/clice.cc`) - Add `--log-level` CLI option with validation (rejects unknown levels instead of silently defaulting to off) - Add `--record <path>` CLI option that wraps the transport with `RecordingTransport` to capture client→server messages as timestamped JSONL - Works in both pipe and socket modes - Fix exit code: `loop.run()` returns non-zero after `uv_stop()`, explicitly return 0 after clean shutdown ### Compile logging (`src/compile/compilation.cpp`) - Print compile commands at debug log level ### Replay script (`tests/replay.py`) - Timestamp-based pacing: sleeps between messages based on recorded intervals, faithful to original editor session - Automatic workspace path rewriting: infers repo root from script location, rewrites absolute paths in trace so CI replay works without extra arguments - Handles server→client requests (workDoneProgress/create, registerCapability, etc.) with default responses - Waits for all pending responses before sending shutdown/exit - Detects server exit mid-replay and fails pending futures immediately instead of hanging - Reports PASS/FAIL/SKIP with stderr tail on failure ### CI & config - Add `smoke-test` pixi task and CI workflow step (runs after integration tests) - `.gitattributes`: mark `tests/smoke/*.jsonl` as `linguist-generated binary` to suppress diffs - Add sample trace file `tests/smoke/session.jsonl` ### VSCode extension - Add restart command (`clice.restart`) - Support `CLICE_MODE` env var to override mode setting (for debug launch configs) - Split launch configs into socket/pipe variants with `--disable-extensions` ## Test plan - [x] `python tests/replay.py tests/smoke/session.jsonl --clice ./build/RelWithDebInfo/bin/clice` passes locally - [ ] CI smoke test passes on Linux/macOS/Windows 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
e43bb14998 |
feat: implement index system with LSP query handlers (#382)
## Summary Implement the complete index system for cross-file LSP features. This adds persistent two-tier indexing (ProjectIndex + per-file MergedIndex shards), background indexing triggered on idle, and index-based query handlers for major LSP requests. ### Index Data Layer (`src/index/`) - **TUIndex**: Add binary serialization/deserialization via FlatBuffers, enabling IPC between stateless worker and master server - **ProjectIndex**: Add symbol name/kind storage, `PathPool` path normalization (backslash -> forward slash), and binary persistence - **MergedIndex**: Add `content` field to store file content for reliable offset<->position mapping; add `removed` bitmap for garbage collection of deleted entries; filter removed IDs in `lookup()` queries - **schema.fbs**: Add TUIndex tables, `Symbol.name` field, `MergedIndex.removed` bitmap and `MergedIndex.content` string ### Server (`src/server/`) - **Background indexing**: Idle-triggered coroutine dequeues files from CDB, dispatches `IndexParams` to stateless workers, merges returned `TUIndex` into ProjectIndex/MergedIndex, and persists to `.clice/index/` - **Index persistence**: `save_index()` / `load_index()` for startup restoration; only rewrites shards flagged `need_rewrite()` - **LSP handlers**: - `textDocument/definition` -- index-first lookup with stateful worker fallback - `textDocument/references` -- cross-file reference query via index - `callHierarchy/prepare`, `incomingCalls`, `outgoingCalls` -- Caller/Callee relation traversal - `typeHierarchy/prepare`, `supertypes`, `subtypes` -- Base/Derived relation traversal - `workspace/symbol` -- case-insensitive substring search over ProjectIndex symbols - **Stateless worker**: Add `Index` request handler that builds `TUIndex` from compiled AST and returns serialized data - **Config**: Add `enable_indexing` (default true) and `idle_timeout_ms` (default 3000ms) ### Fixes and Cross-platform - **ElaboratedType handling** in `decl_of()` for correct Base/Derived relation emission - **Windows path normalization** in `PathPool::intern()` and `ProjectIndex::from()` (backslash -> forward slash) - **`.gitattributes`**: Force LF in `tests/data/**` to prevent CRLF byte-offset mismatches on Windows CI - **Test fixture**: Clean `.clice/` before each test for hermetic index state ### Tests - **370-line** `index_query_tests.cpp`: unit tests for occurrence lookup, relation queries, content retrieval, removed bitmap filtering - **282-line** `test_index.py`: E2E integration tests for GoToDefinition, FindReferences, CallHierarchy (prepare/incoming/outgoing), TypeHierarchy (prepare/supertypes/subtypes), WorkspaceSymbol - Updated existing MergedIndex and ProjectIndex tests for new schema fields ## Test plan - [x] 414 C++ unit tests pass (including new IndexQuery, MergedIndex, ProjectIndex tests) - [x] 69 Python integration tests pass (including 10 new index feature tests) - [x] CI green on Linux, macOS, Windows - [ ] Manual smoke test with VSCode extension --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
21a969af27 |
feat: integrate PCH into MasterServer build drain (#381)
## Summary - Add `ensure_pch()` helper to MasterServer that builds/reuses precompiled headers via stateless workers, with preamble hash-based staleness detection (xxh3_64bits) - Fix `BuildPCHParams` to carry `preamble_bound` so the stateless worker truncates content at the preamble boundary (fixes redefinition errors when PCH included full file) - Wire PCH into both `run_build_drain` (stateful compile path) and `forward_stateless` (completion/signatureHelp path) - Add PCH state cleanup on `didClose` and hash invalidation on `didSave` ## Test plan - [x] 398 unit tests pass (including 6 new PCH tests: PreambleHash x3, PCHWorker x2, BuildPCHRequest assertion) - [x] 5 new integration tests pass (`test_pch.py`: diagnostics on open, body edit recompile, no-include file, hover with PCH, completion with PCH) - [x] 21 existing integration tests pass unchanged - [x] Build succeeds with 0 errors 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Precompiled header (PCH) caching to speed compilations and reduce edit latency * Automatic attachment of cached PCH to compile requests, improving hover and completion responsiveness * Module-aware completions expanded to include available module artifacts from other files * **Bug Fixes** * PCH cache cleared on file close; saving now triggers broader PCH invalidation to prevent stale PCH use * **Tests** * Added unit and integration tests exercising PCH build, reuse, and editor interactions <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
084f3b2d22 |
docs(cmake): restore ASan workaround comments (#380)
## Summary - Restore comment explaining clang-cl manual ASan runtime linking workaround - Restore comment explaining OPT:NOICF for ASan ODR false positives on Windows These were accidentally removed in #379. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Improved internal build configuration for Debug builds on Windows to enhance development and testing infrastructure with better error detection and optimization settings. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
eb0a6b35ee |
refactor(cmake): clean up toolchain and CMakeLists separation (#379)
## Summary Improve CMake build system: cleaner separation, compiler caching, and release packaging. ### Toolchain & Build - Clean up `toolchain.cmake` to only contain clang/lld-specific setup (compiler paths, linker selection, llvm tools), allowing other toolchains like GCC to work without it - Add ccache (Linux/macOS) and sccache (Windows) support via toolchain auto-detection - Move project-universal flags (`-ffunction-sections`, `--gc-sections`, `-static-libstdc++`, etc.) to `CMakeLists.txt` so they apply regardless of toolchain - Add `-fno-exceptions` to project compile options; fix `/EHs-c-` for proper MSVC exception disabling - Use MSVC/clang-cl frontend detection instead of `WIN32` for MSVC-specific linker flags - Declare missing options: `CLICE_USE_LIBCXX`, `CLICE_OFFLINE_BUILD`, `CLICE_ENABLE_BENCHMARK`, `CLICE_RELEASE` ### Release Packaging (`cmake/release.cmake`) - Strip debug symbols and produce separate symbol archives (`.debug` / `.dSYM` / `.pdb`) - Windows: copy PDB via `$<TARGET_PDB_FILE:clice>`; macOS: use `copy_directory` for dSYM bundle - Package clice binary + clang resource dir + config into distributable tarball/zip - `cmake/archive.cmake` helper for cross-platform archive creation - Activated via `-DCLICE_RELEASE=ON` (auto-enables LTO) ### Code Cleanup - Replace manual 40+ line source file list with `GLOB_RECURSE` for clice-core - Fix duplicate `include_resolver.cpp` entry - Use build-time `add_custom_target` for clang resource dir copy (instead of configure-time `file(COPY)`) - Gate `scan_benchmark` behind `CLICE_ENABLE_BENCHMARK` option ### CI - Add compiler cache with env var control (`CCACHE_DIR`/`SCCACHE_DIR`) and `actions/cache` for persistence - Proper cache lifecycle: zero-stats before build, show-stats + stop-server after - Stop sccache server before pixi cleanup to fix Windows EBUSY error - Pass `CLICE_ENABLE_BENCHMARK=ON` in benchmark workflow - Platform-specific ccache/sccache dependencies in pixi.toml ## Test plan - [x] Local build (RelWithDebInfo) passes - [x] Local release build (LTO + strip + pack) produces correct archives - [ ] CI: Linux Debug/RelWithDebInfo - [ ] CI: macOS Debug/RelWithDebInfo - [ ] CI: Windows Debug/RelWithDebInfo - [ ] CI: Benchmark (all platforms) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
bc04845293 |
refactor(tests): CMake-based CDB, workspace fixture, test cleanup (#378)
## Summary - **CMake-based CDB generation for module tests**: Replace hand-written compile_commands.json with CMakeLists.txt (CMake 3.28 `FILE_SET CXX_MODULES`) in all 26 `tests/data/modules/*/` directories. CDB is generated on-the-fly via `cmake -G Ninja` during test setup. - **`@pytest.mark.workspace()` decorator**: Introduce a marker + fixture pattern so tests declare their workspace via decorator and receive a resolved `workspace` path. The fixture auto-generates CDB when a CMakeLists.txt is present. - **`CliceClient` helper methods**: Add `initialize()`, `open()`, `wait_diagnostics()`, and `open_and_wait()` to reduce boilerplate across all test files. - **Use `asyncio_mode = "auto"`**: Switch from `@pytest_asyncio.fixture` + `@pytest.mark.asyncio` to `@pytest.fixture` + auto mode for proper Pylance type inference on fixtures. - **Test cleanup**: Remove redundant section separators and docstrings, delete `tests/pyproject.toml` (config moved to `pytest.ini`). - **Format task**: Add `.cppm` to `format-cpp` glob pattern. - **CI fix**: Disable `CMAKE_CXX_SCAN_FOR_MODULES` and prefer pixi clang++ to fix macOS CI where CMake rejects module scanning. ## Test plan - [x] All 26 module test directories have CMakeLists.txt with FILE_SET CXX_MODULES - [x] generate_cdb() produces valid compile_commands.json with module flags - [x] Integration tests pass locally - [ ] CI passes on all platforms (Linux, macOS, Windows) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Unified fixtures and client workflow: new init/open/wait helpers, workspace marker support, bounded diagnostics waiting, CMake-based compilation-database generation, and directory-backed temp-file workflows; enabled asyncio test mode. * **Chores** * Added many C++20 module test projects and test data; removed prior test pyproject in favor of pytest config; updated formatter to include .cppm files. * **Style** * Reformatted many module/source implementations to consistent multi-line function bodies. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
0a891d8b4a |
refactor(tests): use Tester fixture, normalize helpers, add index tests (#377)
## Summary - **Use `Tester` as fixture base** for all test suites that need compilation, replacing `TesterFixture` and removing redundant `tester.clear()` calls (eventide zest now creates fresh instances per TEST_CASE) - **Remove local `Tester` variables** in `compilation_tests`, `template_resolver_tests`, `selection_tests` — use inherited fixture members directly - **Normalize helper naming**: `expect_xxx` → `EXPECT_XXX`, `go_to_definition` → `GO_TO_DEFINITION` for consistency - **Extract shared `test/cdb_helper.h`**: deduplicate `CDBEntry`, `json_escape`, `build_cdb_json` from `dependency_graph_tests` and `compile_graph_integration_tests` - **Add new test files/cases**: `project_index_tests.cpp`, expanded `tu_index_tests`, `merged_index_tests`, `compilation_tests` ## Test plan - [x] All existing unit tests pass - [x] New index tests (TUIndex, MergedIndex, ProjectIndex) pass - [x] Compilation tests (PCH, PCM, stop) pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Standardized test fixtures and helper naming, moved suites to a shared fixture, and unified in-memory VFS and compile flows. * Added broad new coverage: indexing, project indexing, compilation/PCH, diagnostics, semantic features, and many targeted unit cases. * Introduced a small compile-database helper and improved driver-style test compilation paths. * **Chores** * Consolidated and reorganized test utilities and tester APIs for easier maintenance and reuse. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
6d3b6acc82 |
feat: initial CompileGraph integration into MasterServer (#376)
## Summary Initial integration of `CompileGraph` (#375) into `MasterServer`, enabling basic end-to-end C++20 module support: on-demand PCM building, dependency-ordered compilation, cascade invalidation on save, and diagnostic integration. This is a **first-pass implementation** — the core pipeline works, but there are known areas for follow-up: - PCM files go to system temp dir instead of `.clice/cache/`; no disk cleanup on invalidation - `run_build_drain` scans imports itself rather than delegating fully to CompileGraph - No incremental/partial rebuild (full PCM rebuild on any change) - Cycle detection is tested at unit level but integration-level coverage is minimal ## Changes ### Module dependency compilation (`master_server.cpp`) Before sending a file to the stateful worker, `run_build_drain` now: 1. Scans imports via `scan_precise()` to discover module dependencies 2. Compiles each dep through `compile_graph->compile()`, which recursively builds transitive PCMs 3. Handles implementation units — `module M;` implicitly needs the interface PCM 4. Passes all built PCMs to the stateful worker, excluding the file's own PCM 5. Skips compile on dep failure and resets `build_running` / `drain_scheduled` 6. Re-lookups iterators after `co_await` to avoid use-after-invalidation ### Cascade invalidation (`didSave` / `didClose`) - `didSave`: calls `compile_graph->update()` to mark transitive dependents dirty, removes stale PCM paths, schedules rebuilds for open dirtied files - `didClose`: cancels in-flight compilations for the closed file ### Other fixes in this PR - Debounce timers switched to `shared_ptr` to prevent use-after-free when `didClose` destroys the timer mid-wait - `fill_compile_args` returns `bool`; callers handle empty CDB gracefully - Adapt all `PositionMapper` call sites to the new `optional` return API from eventide ## Test plan - [x] 25 C++ unit tests for CompileGraph (cycles, partial failure, cancel, update, empty graph) - [x] 24 C++ integration tests with real clang PCM compilation - [x] 3 worker-level module tests (BuildPCM, PCM-dependent compile, multi-module) - [x] 26 Python LSP integration tests (single module through circular deps, hover, error diagnostics) - [x] 371 unit tests + 54 integration tests pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
7ed558c1e7 |
feat: add CompileGraph for pull-based module dependency compilation (#375)
## Summary
Add `CompileGraph`, a pull-based async scheduler for C++20 module
compilation. When a file is compiled that imports modules, the graph
automatically resolves, builds, and caches PCM dependencies in the
correct order before the main compile proceeds.
## Design
### Data model
Each compilation unit (`CompileUnit`) tracks:
- `dependencies` / `dependents` — forward and reverse dependency edges
- `dirty` / `compiling` — current state flags
- `generation` — monotonic counter incremented by `update()`, used for
ABA-safe stale detection
- `source` + `completion` — cancellation token source and completion
event for cooperative async
### `compile(path_id)` — pull-based compilation
Lazily resolves dependencies (via `resolve_fn`) on first access, then
recursively compiles all transitive deps before dispatching the unit
itself:
- **Concurrent**: sibling deps compiled in parallel via `when_all`
- **Dedup**: diamond dependencies (A->B->D, A->C->D) — the second branch
waits on the first via `completion.wait()` instead of re-compiling
- **Cycle detection**: per-branch `ancestors` set (passed by value)
catches direct cycles; `has_wait_cycle()` BFS catches cross-branch
cycles (e.g. `1->{2,3}, 2->3, 3->2`) that would deadlock at
`completion.wait()`
- **Cancellation**: all `co_await` wrapped with `with_token()`, so
`update()` can cancel in-flight compilations immediately
- **Generation check**: captures generation counter before `co_await`;
if `update()` bumped it during dispatch, the result is discarded (unit
stays dirty)
### `update(path_id)` — cascade invalidation
BFS along `dependents` edges to mark the entire reverse-transitive
closure as dirty. For the source node, clears `resolved` and dependency
edges so they are re-scanned on next compile. Cancels any in-flight
compilations via `source->cancel()`.
## Test plan
22 unit tests covering:
- [x] No deps, single dep, chain, diamond (compile ordering + dedup)
- [x] Update invalidation, cascade through chains and diamonds
- [x] Re-resolution after update (deps can change)
- [x] Stale back-edge cleanup
- [x] Direct cycle detection (A->B->A)
- [x] Cross-branch cycle detection (when_all deadlock case)
- [x] Self-loop
- [x] Dispatch failure propagation
- [x] cancel_all + recompile
- [x] Update during in-flight compile (cancellation + generation check)
- [x] CI green on Linux, macOS, Windows
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
|
||
|
|
a536865fca |
feat: add scan_module_decl() fallback for conditional module declarations (#373)
## Summary - Add `scan_module_decl()` — a lightweight preprocessor-based fallback that resolves module declarations inside `#if`/`#ifdef` conditionals. When `scan()` detects `need_preprocess=true`, this function runs clang's preprocessor to evaluate conditions and extract the actual module name. It stops lexing as soon as the module declaration is found, making it much cheaper than `scan_precise()`. - Integrate the fallback into `scan_dependency_graph()` for wave 0 source files, so conditional module declarations (e.g. `#ifdef USE_MODULES / export module M; / #endif`) are correctly registered in the dependency graph. - Add comprehensive test cases covering all C++20 module declaration forms from cppreference, including `scan_module_decl()` tests for conditional resolution and `scan_precise()` tests for module import semantics. ## Test plan - [x] All 310 unit tests pass (0 failures, 9 skipped) - [x] `scan()` tests cover: primary interface, implementation, dotted names, partitions, GMF, conditional module declarations, private module fragment - [x] `scan_module_decl()` tests cover: basic, conditional with `-D`, conditional with `#if` expression, GMF with conditional, implementation unit, dotted name, partition, no-module file - [x] `scan_precise()` tests cover: named import, multiple imports, dotted import, partition import, export-import, export-import partition, implementation import, GMF with import, mixed includes/imports, no-module file 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Improved detection of module declarations hidden by conditional compilation via a lightweight fallback scan. Resolved module vs. interface classification is cached to avoid repeated work and is used consistently in dependency mapping. * Better handling and classification of module imports, partitions, and global-fragment includes when building module relationships. * **Tests** * Added comprehensive unit tests covering module declaration extraction, fallback resolution under preprocessor guards, imports, partitions, includes, and macro-driven cases. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
f8a39147a7 |
feat: add include resolver, dependency graph, BFS scanner (#368)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
46ba1e4db6 |
refactor: simplify CompilationDatabase, extract ArgumentParser, remove pimpl (#371)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
498c975042 |
feat: add SearchConfig, ToolchainProvider, PathPool and related tests (#370)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |