## Summary
- **Public feature types**: Move `SemanticToken`, `FoldingRange`,
`DocumentSymbol`, `InlayHint`, and `HintCategory` from internal `.cpp`
files to `feature.h` as public API types. Each feature now exposes two
overloads: a raw overload returning offset-based types and a protocol
overload that converts to LSP wire-format with explicit
`PositionEncoding`.
- **Snapshot testing**: Add corpus-driven snapshot tests using
`ASSERT_SNAPSHOT_GLOB` for semantic tokens, folding ranges, inlay hints,
document symbols, and TU index. Tests compile real C++ corpus files,
format output as YAML flow mappings, and diff against `.snap.yml`
baselines.
- **Test infrastructure**: Add `compile_file()` to `Tester`,
`yaml_str()` utility, `--corpus-dir` / `--snapshot-dir` CLI options, and
`--verbose` flag for unit tests. Migrate to kotatsu's unified
`kota::zest::Options` API.
- **Toolchain robustness**: Filter unknown cc1 args via
`clang::driver::getDriverOptTable()` to handle system compilers newer
than embedded LLVM.
- **Dependency bump**: Update kotatsu to 7381404 (unified zest Options,
out-param `from_json` API).
## Details
### Feature type changes
All five feature modules (`semantic_tokens`, `folding_ranges`,
`document_symbols`, `inlay_hints`, `document_links`) now follow the same
two-overload pattern. The raw overload returns offset-based structs
suitable for indexing and testing; the protocol overload adds
`PositionEncoding` conversion for LSP responses. `stateful_worker.cpp`
explicitly passes `PositionEncoding::UTF16` at every call site.
### Snapshot tests
Corpus files live in `tests/corpus/` (organized by language construct).
Snapshot baselines live in `tests/snapshots/<feature>/`. Format lambdas
are inlined directly in test bodies — no separate format functions for
single-use formatters. YAML output uses flow mappings (`- { key: value
}`) for compact, diffable baselines.
### cc1 arg filtering
`src/command/toolchain.cpp` now parses the cc1 argument list through
LLVM's driver option table and drops any args classified as
`UnknownClass`. This prevents compilation failures when the system
compiler emits flags that the embedded LLVM version doesn't recognize.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
290 lines
9.3 KiB
TOML
290 lines
9.3 KiB
TOML
# tombi: format.rules.table-keys-order.disabled = true
|
|
|
|
[workspace]
|
|
name = "clice"
|
|
version = "0.1.0"
|
|
description = "A next-generation C++ language server for modern C++"
|
|
authors = [
|
|
"ykiko <ykiko@clice.io>",
|
|
"clice contributors <clice@clice.io>",
|
|
]
|
|
license = "Apache-2.0"
|
|
license-file = "LICENSE"
|
|
readme = "README.md"
|
|
documentation = "https://docs.clice.io/clice/"
|
|
repository = "https://github.com/clice-io/clice"
|
|
channels = ["conda-forge"]
|
|
platforms = ["win-64", "linux-64", "osx-arm64", "osx-64", "linux-aarch64", "win-arm64"]
|
|
|
|
[environments]
|
|
default = ["build", "test"]
|
|
package = ["build", "test", "package"]
|
|
cross-macos-x64 = ["build", "package", "cross-macos-x64"]
|
|
cross-linux-aarch64 = ["build", "package", "cross-linux-aarch64"]
|
|
cross-windows-arm64 = ["build", "package", "cross-windows-arm64"]
|
|
node = ["node"]
|
|
format = ["format"]
|
|
test-run = ["test"]
|
|
|
|
# ============================================================================== #
|
|
# DEPENDENCIES #
|
|
# ============================================================================== #
|
|
[feature.build]
|
|
platforms = ["win-64", "linux-64", "osx-arm64", "osx-64", "linux-aarch64"]
|
|
|
|
[feature.build.dependencies]
|
|
python = ">=3.13"
|
|
cmake = ">=3.30"
|
|
ninja = "*"
|
|
clang = "==20.1.8"
|
|
clangxx = "==20.1.8"
|
|
lld = "==20.1.8"
|
|
llvm-tools = "==20.1.8"
|
|
clang-tools = "==20.1.8"
|
|
compiler-rt = "==20.1.8"
|
|
flatbuffers = "==25.9.23"
|
|
|
|
[feature.build.target.win-64.dependencies]
|
|
sccache = "*"
|
|
|
|
[feature.build.target.linux-64.dependencies]
|
|
sysroot_linux-64 = "==2.17"
|
|
gcc = "==14.2.0"
|
|
gxx = "==14.2.0"
|
|
ccache = "*"
|
|
|
|
[feature.build.target.osx-arm64.dependencies]
|
|
ccache = "*"
|
|
|
|
[feature.build.target.linux-64.activation]
|
|
scripts = ["scripts/activate_linux.sh"]
|
|
|
|
[feature.build.target.win-64.activation]
|
|
scripts = ["scripts/activate_asan.bat"]
|
|
|
|
# macOS x64 (from arm64): clang natively supports cross-arch, no extra deps.
|
|
[feature.cross-macos-x64.target.osx-arm64.dependencies]
|
|
|
|
[feature.cross-macos-x64.target.osx-arm64.activation]
|
|
scripts = ["scripts/activate_cross_macos.sh"]
|
|
|
|
# Linux aarch64 (from x64): needs aarch64 sysroot and cross gcc for libstdc++.
|
|
[feature.cross-linux-aarch64.target.linux-64.dependencies]
|
|
sysroot_linux-aarch64 = "==2.17"
|
|
gcc_linux-aarch64 = "==14.2.0"
|
|
gxx_linux-aarch64 = "==14.2.0"
|
|
|
|
[feature.cross-linux-aarch64.target.linux-64.activation]
|
|
scripts = ["scripts/activate_cross_linux.sh"]
|
|
|
|
# Windows arm64 (from x64): Windows SDK on CI already includes ARM64 libs.
|
|
[feature.cross-windows-arm64.target.win-64.dependencies]
|
|
|
|
[feature.cross-windows-arm64.target.win-64.activation]
|
|
scripts = ["scripts/activate_cross_windows.bat"]
|
|
|
|
[feature.test.dependencies]
|
|
python = ">=3.13"
|
|
|
|
# On macOS, the system Apple clang emits vendor-specific flags that upstream
|
|
# LLVM cannot parse. Providing upstream clang + lld in PATH prevents
|
|
# fallback to /usr/bin/clang++ and satisfies toolchain.cmake's -fuse-ld=lld.
|
|
[feature.test.target.osx-64.dependencies]
|
|
clang = "==20.1.8"
|
|
clangxx = "==20.1.8"
|
|
lld = "==20.1.8"
|
|
|
|
[feature.test.target.osx-arm64.dependencies]
|
|
clang = "==20.1.8"
|
|
clangxx = "==20.1.8"
|
|
lld = "==20.1.8"
|
|
|
|
[feature.test.pypi-dependencies]
|
|
pytest = "*"
|
|
pytest-asyncio = ">=1.1.0"
|
|
pytest-timeout = "*"
|
|
pygls = ">=2.0.0"
|
|
lsprotocol = ">=2024.0.0"
|
|
|
|
[feature.package.dependencies]
|
|
xz = ">=5.8.1,<6"
|
|
|
|
[feature.package.tasks.package-config]
|
|
args = [{ arg = "type", default = "RelWithDebInfo" }]
|
|
cmd = """
|
|
cmake -B build/{{ type }} -G Ninja \
|
|
-DCMAKE_BUILD_TYPE={{ type }} \
|
|
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain.cmake \
|
|
-DCLICE_RELEASE=ON
|
|
"""
|
|
|
|
[feature.package.tasks.package]
|
|
args = [{ arg = "type", default = "RelWithDebInfo" }]
|
|
depends-on = [
|
|
{ task = "package-config", args = ["{{ type }}"] },
|
|
{ task = "cmake-build", args = ["{{ type }}"] },
|
|
]
|
|
|
|
# ============================================================================== #
|
|
# CMAKE #
|
|
# ============================================================================== #
|
|
[feature.build.tasks.cmake-config]
|
|
args = [
|
|
{ arg = "type", default = "RelWithDebInfo" },
|
|
{ arg = "ci", default = "OFF" },
|
|
]
|
|
cmd = """
|
|
cmake -B build/{{ type }} -G Ninja \
|
|
-DCMAKE_BUILD_TYPE={{ type }} \
|
|
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain.cmake \
|
|
-DCLICE_ENABLE_TEST=ON \
|
|
-DCLICE_CI_ENVIRONMENT={{ ci }}
|
|
"""
|
|
|
|
[feature.build.tasks.cmake-build]
|
|
args = [{ arg = "type", default = "RelWithDebInfo" }]
|
|
cmd = "cmake --build build/{{ type }}"
|
|
|
|
[feature.build.tasks.build]
|
|
args = [
|
|
{ arg = "type", default = "RelWithDebInfo" },
|
|
{ arg = "ci", default = "OFF" },
|
|
]
|
|
depends-on = [
|
|
{ task = "cmake-config", args = ["{{ type }}", "{{ ci }}"] },
|
|
{ task = "cmake-build", args = ["{{ type }}"] },
|
|
]
|
|
|
|
[feature.build.tasks.clang-tidy]
|
|
args = [{ arg = "type", default = "RelWithDebInfo" }]
|
|
depends-on = [{ task = "lint-cpp", args = ["{{ type }}"] }]
|
|
|
|
[feature.test.tasks.unit-test]
|
|
args = [{ arg = "type", default = "RelWithDebInfo" }]
|
|
cmd = './build/{{ type }}/bin/unit_tests --test-dir="./tests/data" --snapshot-dir="./tests/snapshots" --corpus-dir="./tests/corpus" --verbose'
|
|
|
|
[feature.test.tasks.integration-test]
|
|
args = [{ arg = "type", default = "RelWithDebInfo" }]
|
|
cmd = """
|
|
pytest -s --log-cli-level=INFO --timeout=300 --timeout-method=thread \
|
|
tests/integration --executable=./build/{{ type }}/bin/clice
|
|
"""
|
|
|
|
[feature.test.tasks.smoke-test]
|
|
args = [{ arg = "type", default = "RelWithDebInfo" }]
|
|
cmd = """
|
|
python tests/replay.py tests/smoke/*.jsonl \
|
|
--clice=./build/{{ type }}/bin/clice
|
|
"""
|
|
|
|
[feature.test.tasks.test]
|
|
args = [{ arg = "type", default = "RelWithDebInfo" }]
|
|
depends-on = [
|
|
{ task = "unit-test", args = ["{{ type }}"] },
|
|
{ task = "integration-test", args = ["{{ type }}"] },
|
|
{ task = "smoke-test", args = ["{{ type }}"] },
|
|
]
|
|
|
|
# ============================================================================== #
|
|
# HELPER TASKS #
|
|
# ============================================================================== #
|
|
[tasks.build-llvm]
|
|
cmd = ["python3", "scripts/build-llvm.py"]
|
|
|
|
[tasks.upload-llvm]
|
|
args = ["workflow_id", "llvm_version", { "arg" = "branch", default = "main" }]
|
|
cmd = """
|
|
gh workflow run upload-llvm.yml \
|
|
--ref {{ branch }} \
|
|
--field workflow_id={{workflow_id}} \
|
|
--field version={{llvm_version}}
|
|
"""
|
|
|
|
[tasks.delete-artifacts]
|
|
args = ["file_name"]
|
|
cmd = ["scripts/delete-artifacts.bash", "{{ file_name }}"]
|
|
|
|
[dependencies]
|
|
|
|
# ============================================================================== #
|
|
# DOCS & VSCODE EXTENSION #
|
|
# ============================================================================== #
|
|
[feature.node]
|
|
platforms = ["win-64", "linux-64", "osx-arm64", "osx-64", "linux-aarch64"]
|
|
|
|
[feature.node.dependencies]
|
|
nodejs = ">=20"
|
|
pnpm = "*"
|
|
|
|
[feature.node.tasks]
|
|
build-docs = { cwd = "docs", cmd = "pnpm run docs:build", depends-on = ["install-docs"] }
|
|
preview-docs = { cwd = "docs", cmd = "pnpm run docs:preview", depends-on = ["install-docs"] }
|
|
build-vscode = { cwd = "editors/vscode", cmd = "pnpm run package", depends-on = ["install-vscode"] }
|
|
publish-vscode = { cwd = "editors/vscode", cmd = "pnpm run publish", depends-on = ["install-vscode"] }
|
|
|
|
[feature.node.tasks.install-docs]
|
|
cwd = "docs"
|
|
cmd = "pnpm install"
|
|
inputs = ["docs/package.json", "docs/pnpm-lock.yaml"]
|
|
outputs = ["docs/node_modules/.modules.yaml"]
|
|
|
|
[feature.node.tasks.install-vscode]
|
|
cwd = "editors/vscode"
|
|
cmd = "pnpm install"
|
|
inputs = ["editors/vscode/package.json", "editors/vscode/pnpm-lock.yaml"]
|
|
outputs = ["editors/vscode/node_modules/.modules.yaml"]
|
|
|
|
# ============================================================================== #
|
|
# FORMAT #
|
|
# ============================================================================== #
|
|
[feature.format]
|
|
platforms = ["win-64", "linux-64", "osx-arm64", "osx-64", "linux-aarch64"]
|
|
|
|
[feature.format.dependencies]
|
|
ruff = "*"
|
|
tombi = "*"
|
|
stylua = "*"
|
|
fd-find = "*"
|
|
prettier = "*"
|
|
clang-format = "==21.1.7"
|
|
|
|
[feature.format.tasks]
|
|
format-cpp = "fd -H -e cpp -e h -e cc -e hpp -e cppm -x clang-format -i"
|
|
format-python = "ruff format ."
|
|
format-lua = "stylua ."
|
|
format-web = "fd -H -e js -e ts -e css -x prettier --write"
|
|
format-markdown = "fd -H -e md -x prettier --write"
|
|
format-json = "fd -H -e json -E package-lock.json -x prettier --write"
|
|
format-toml = "fd -H -e toml -x tombi format"
|
|
format-yaml = """
|
|
fd -H -e yaml -e yml -E pnpm-lock.yaml -E '*.snap.yml' -x prettier --write && \
|
|
fd -H "^\\.clang-(format|tidy)$" -x prettier --write --parser yaml
|
|
"""
|
|
format = { depends-on = [
|
|
"format-cpp",
|
|
"format-python",
|
|
"format-lua",
|
|
"format-web",
|
|
"format-markdown",
|
|
"format-json",
|
|
"format-toml",
|
|
"format-yaml"
|
|
] }
|
|
|
|
# ============================================================================== #
|
|
# LINT #
|
|
# ============================================================================== #
|
|
[feature.format.tasks.lint-python]
|
|
cmd = "ruff check ."
|
|
|
|
[feature.build.tasks.lint-cpp]
|
|
args = [{ arg = "type", default = "RelWithDebInfo" }]
|
|
cmd = "python scripts/run_clang_tidy.py build/{{ type }}"
|
|
|
|
[feature.build.tasks.lint]
|
|
args = [{ arg = "type", default = "RelWithDebInfo" }]
|
|
depends-on = [
|
|
"lint-python",
|
|
{ task = "lint-cpp", args = ["{{ type }}"] },
|
|
]
|