Tags: clice-io/clice
Tags
chore(build): upgrade toolchain to clang 22 and LLVM prebuilt r2 (#550) ## Summary Toolchain upgrade: - Compiler toolchain: clang 20.1.8 → 22.1.8, GCC 14.2.0 → 15.1.0 - LLVM prebuilt: 21.1.8+r1 → 21.1.8+r2 (rebuilt with the clang 22 toolchain) - build-llvm workflow: DIA SDK off, patches applied from clice-llvm, windows-2022 runner macOS dynamic-linking fixes — libc++ ≥ 21 moved string hashing into the dylib as `__hash_memory` (llvm/llvm-project#77653), which surfaced two latent issues in our setup: - Strip `_LIBCPP_DISABLE_AVAILABILITY` from the kotatsu targets. With libc++ ≥ 21 headers that macro makes the headers emit references to dylib-only symbols the macOS system libc++ does not ship, which broke the x64 cross link and made binaries depend on conda's libc++ at runtime. Temporary workaround until the flag is removed upstream in kotatsu. - Pass `--no-default-config` to clang on Apple, via the toolchain file so the LLVM prebuilt builds inherit it. conda-forge clang 22's bundled config files inject `-L`/`-rpath` pointing into the conda env at link time, binding binaries to `@rpath/libc++.1.dylib` with an rpath valid only on the build machine — the VSCode E2E job caught them failing to load anywhere else. With config files disabled, binaries link the system libc++, gated safely by availability annotations. - Add a Debug-only rpath to the env's libc++: the prebuilt ASan dylibs still reference conda's libc++, and Debug binaries are CI-internal. Goes away with the next prebuilt respin. - Cleanups: drop the redundant availability defines and the dead macOS cross activation script/env. ## Test plan - [x] Full CI matrix green: Linux/Windows/macOS native, all three cross pairs, editor E2E on both platforms - [x] macOS release artifacts link `/usr/lib/libc++.1.dylib` with no conda env rpath (verified via `otool -L`)
feat(driver): one subcommand per translation unit (#539) ## Why Upcoming features (`clice lint` with cross-TU caching, ahead-of-time indexing, documentation data generation) are all CLI applications over the same core, but the CLI surface lived as one monolithic `clice.cc`. This PR gives every subcommand its own home before those features land. ## What - `src/driver/` holds one translation unit per subcommand: `serve`, `query`, `worker`, plus new stubs `index`, `doc`, `lint`, `format`. Each file owns its options struct and registers a deco command with the root `SubCommander` through an `add_*` builder. - `clice.cc` shrinks to collection and registration (206 → ~60 lines). Behavior parity everywhere: dispatch, `--version`, root/per-command `--help`, missing/unknown subcommand handling, worker defaults, query port validation. - Stubs print a one-line self-description to stderr and exit non-zero, so scripts can detect the command is unavailable while humans learn what it will do. - Commands are constructed inside the builders and moved into the `SubCommander` (owning overload); help re-constructs a fresh command for usage printing, so no closure captures a moved-from object. - New `tests/integration/lifecycle/test_subcommands.py` pins the whole surface: all seven names registered in root usage, stub messages and exit codes, per-command help, unknown-subcommand failure. ## Tests - Unit: 1059; Integration: 304 (incl. 4 new CLI surface tests); Smoke: 3/3.
feat(tests): generate folding-ranges doc from snapshot fixtures (#535) ## Why Feature docs are hand-maintained support checklists with no mechanical connection to tests: nothing verifies that a checked item actually works, and nothing flags when behavior changes. This PR pilots the inversion for folding ranges: snapshot fixtures become the single source of truth and the doc checklist is generated from them. ## Design Each fixture under `tests/data/folding_range/<section>/` carries a doc header that is a plain markdown document behind `///`: ```cpp /// # Preprocessor conditional folding (`#if` / `#ifdef` ...) /// /// - status: partial /// - issues: clangd#1661, clangd#2059 /// /// Branch regions delimited by `#else` fold today; a bare /// `#if ... #endif` block without an `#else` does not fold yet. <example code — doubles as the doc example> ``` - The h1 title marks the file as a doc item (files without it are supplementary tests, excluded from docs); stripped of the `///` prefix the whole header renders as-is in any markdown viewer. - Grouping comes from one-level section subdirectories (`fold_kinds/`, `refinements/`); generated doc regions are keyed by the directory name, while human headings and prose stay hand-written. - `status` semantics: `supported` → `[x]`, compiled, snapshot proves the behavior; `partial` → `[ ]` with a _(partial)_ marker, compiled, snapshot records the current partial behavior so improvements surface as diffs; `unsupported` → skipped by the snapshot glob, snapshot pinned to `UNSUPPORTED`, implementing the capability later surfaces as a diff prompting the status flip. - `tests/tools/feature_docs.py` renders headers into marker-delimited regions of `docs/en/features/folding-ranges.md` (`update`) and fails on drift (`check`, now part of `pixi run unit-test`). The C++ side reads only the `status` key via a shared ten-line helper — there is no grammar to drift between the two parsers. ## Notable corrections found by review - Two preprocessor fixtures initially marked unsupported actually fold `#else`-delimited branches today; they are now `partial` with snapshots recording the true current behavior (bare `#if...#endif` still does not fold — clangd#1661). The `partial` tier exists because of this finding. - All supported items' snapshots were verified to demonstrate their claimed capability. ## Migration The 14 checklist items of the old hand-written doc are preserved (titles, statuses, examples, issue links, client-support notes). Legacy inline test cases are untouched and migrate in follow-up per-feature PRs. ## Tests - Unit: 1052 passed on both RelWithDebInfo and Debug, including the doc-sync check - Integration: 300 passed; Smoke: 3/3 - `format` → `check` round-trip verified stable
feat(tests): generate folding-ranges doc from snapshot fixtures (#535) ## Why Feature docs are hand-maintained support checklists with no mechanical connection to tests: nothing verifies that a checked item actually works, and nothing flags when behavior changes. This PR pilots the inversion for folding ranges: snapshot fixtures become the single source of truth and the doc checklist is generated from them. ## Design Each fixture under `tests/data/folding_range/<section>/` carries a doc header that is a plain markdown document behind `///`: ```cpp /// # Preprocessor conditional folding (`#if` / `#ifdef` ...) /// /// - status: partial /// - issues: clangd#1661, clangd#2059 /// /// Branch regions delimited by `#else` fold today; a bare /// `#if ... #endif` block without an `#else` does not fold yet. <example code — doubles as the doc example> ``` - The h1 title marks the file as a doc item (files without it are supplementary tests, excluded from docs); stripped of the `///` prefix the whole header renders as-is in any markdown viewer. - Grouping comes from one-level section subdirectories (`fold_kinds/`, `refinements/`); generated doc regions are keyed by the directory name, while human headings and prose stay hand-written. - `status` semantics: `supported` → `[x]`, compiled, snapshot proves the behavior; `partial` → `[ ]` with a _(partial)_ marker, compiled, snapshot records the current partial behavior so improvements surface as diffs; `unsupported` → skipped by the snapshot glob, snapshot pinned to `UNSUPPORTED`, implementing the capability later surfaces as a diff prompting the status flip. - `tests/tools/feature_docs.py` renders headers into marker-delimited regions of `docs/en/features/folding-ranges.md` (`update`) and fails on drift (`check`, now part of `pixi run unit-test`). The C++ side reads only the `status` key via a shared ten-line helper — there is no grammar to drift between the two parsers. ## Notable corrections found by review - Two preprocessor fixtures initially marked unsupported actually fold `#else`-delimited branches today; they are now `partial` with snapshots recording the true current behavior (bare `#if...#endif` still does not fold — clangd#1661). The `partial` tier exists because of this finding. - All supported items' snapshots were verified to demonstrate their claimed capability. ## Migration The 14 checklist items of the old hand-written doc are preserved (titles, statuses, examples, issue links, client-support notes). Legacy inline test cases are untouched and migrate in follow-up per-feature PRs. ## Tests - Unit: 1052 passed on both RelWithDebInfo and Debug, including the doc-sync check - Integration: 300 passed; Smoke: 3/3 - `format` → `check` round-trip verified stable
refactor(tests): replace shared corpus with per-feature snapshot dirs (… …#534) ## Why The shared snapshot corpus (`tests/corpus/`) ran every corpus file through five unrelated feature suites (folding_range, semantic_tokens, document_symbol, inlay_hint, tu_index). Language constructs do not map 1:1 across features, so each corpus file generated noise snapshots for features that do not care about it, making snapshot review scale badly. ## What - Remove the shared corpus mechanism: `tests/corpus/`, the `--corpus-dir` CLI option, the `corpus_dir` global, and its references in `pixi.toml` and the docs. - Re-point each of the five snapshot glob tests at its own curated directory `tests/data/<feature>/`, following the existing `tests/data/hover/` pattern. The dump/transform logic is kept unchanged for reuse in the upcoming per-feature snapshot migration. - Seed each directory with a feature-tailored `basic.cpp` plus a `DisableFormat: true` `.clang-format` (fixture layout is part of the tested input; formatting would invalidate line/column-sensitive snapshots). - Regenerate snapshots; each seed produces richer output for its feature than the old shared corpus file did. ## Tests - Unit: 1026 passed (12 pre-existing skips) - Integration: 300 passed - Smoke: 3/3 passed
fix(vscode): interim display name pending marketplace (#529) Microsoft's Marketplace policy permanently reserves deleted extension display names, which currently blocks publishing `clice-io.clice` with the display name `clice` (held by the removed predecessor extension). Use `clice vscode` as an interim display name so the extension can ship; a release request for the original name is pending with Marketplace support. Display-name changes are plain updates — the extension ID stays `clice-io.clice`, so this is fully reversible once the name is released.