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>
This commit is contained in:
ykiko
2026-04-08 22:18:25 +08:00
committed by GitHub
parent 9c9e6b0bcb
commit 2bbdf6c02b
9 changed files with 239 additions and 178 deletions

View File

@@ -735,17 +735,18 @@ void MasterServer::register_handlers() {
if(hosts.empty()) {
auto entries = workspace.cdb.lookup(path, {.suppress_logging = true});
for(std::size_t i = 0; i < entries.size(); ++i) {
auto& entry = entries[i];
auto& cmd = entries[i];
auto argv = cmd.to_argv();
std::string desc;
for(std::size_t j = 0; j < entry.arguments.size(); ++j) {
llvm::StringRef a(entry.arguments[j]);
for(std::size_t j = 0; j < argv.size(); ++j) {
llvm::StringRef a(argv[j]);
if(a.starts_with("-D") || a.starts_with("-O") || a.starts_with("-std=") ||
a.starts_with("-g")) {
if(!desc.empty())
desc += ' ';
desc += entry.arguments[j];
if((a == "-D" || a == "-O") && j + 1 < entry.arguments.size()) {
desc += entry.arguments[++j];
desc += argv[j];
if((a == "-D" || a == "-O") && j + 1 < argv.size()) {
desc += argv[++j];
}
}
}
@@ -757,7 +758,7 @@ void MasterServer::register_handlers() {
continue;
ext::ContextItem item;
item.label = desc;
item.description = entry.directory.str();
item.description = cmd.resolved.directory.str();
item.uri = uri_opt->str();
all_items.push_back(std::move(item));
}