## Agents
- User `jq` to analyze json outputs from ast.
- [poolmanager.json](./poolmanager.json) - ast generated by solc.
## Testing and Debugging
Always use `lsp-bench` as the first choice when you want to debug lsp methods and their output. The lsp-bench is located locally at ../solidity-lsp-benchmarks.
There are many examples on ./benchmarks on how to write a simple yaml config to you needs.
## Building
Always build with `--release` flag
## Memory Optimization Notes (branch: cleanup/dead-code-and-memory)
### Current state
| v0.1.24 baseline | 230 MB | — |
| Before this work (pre-branch) | 394 MB | +164 MB |
| After extract_decl_nodes + remove ast field | 309 MB | +79 MB |
| After with_capacity + build-filtered-map (P2) | **254 MB** | **+24 MB** |
Reclaimed **140 MB** of the 164 MB regression. The remaining +24 MB matches the
~23 MB of new retained data structures (`decl_index` + `DeclNode` contents).
### Completed optimizations
- **Removed `CachedBuild.ast` field** — raw JSON no longer retained after construction.
- **P2: build-filtered-map** — replaced `node.clone()` → strip with selective field
copy in `walk_and_extract()`. Eliminated 234 MB of transient allocations (629→395 MB).
- **Pre-sized HashMaps** — `with_capacity()` in `cache_ids()`, `extract_decl_nodes()`,
`build_completion_cache()`, `build_hint_index()`, `build_constructor_index()`.
### DHAT profiling results (poolmanager-t-full.json, 95 files)
```
Before P2 After P2
Total allocated: 629 MB → 395 MB (-37%)
Peak (t-gmax): 277 MB → 243 MB (-12%)
Retained (t-end): 60 MB → 60 MB (unchanged)
RSS observed: 310 MB → 254 MB (-18%)
```
**Retained memory breakdown (t-end, unchanged):**
| 1 | 16.4 MB | `cache_ids()` → `nodes` HashMap | All AST nodes with src, referencedDeclaration, etc. Existed in v0.1.24 too. |
| 2 | 12.6 MB | `walk_and_extract()` → `decl_index` + `node_id_to_source_path` | **New** — typed declaration index. |
| 3 | 4.1 MB | `FunctionDefinition` structs in `decl_index` | **New** |
| 4 | 4.1 MB | `ContractDefinition` structs (includes child `nodes` array) | **New** — P1 target. |
| 5 | 2.0 MB | `VariableDeclaration` structs | **New** |
| 6 | 1.9 MB | `CompletionCache` | Partially new. |
| 7+ | 3.4 MB | Strings, other indexes | Mixed. |
**Key insight:** The remaining +24 MB RSS gap is real retained data (~23 MB of new
`decl_index` structures), not fragmentation. The 395 MB of transient churn still
causes some fragmentation, but the gap is now within the expected range.
### Remaining optimization targets (diminishing returns)
1. **P1: ContractDefinition.nodes** (4.1 MB retained) — only needs selectors + doc text for
`resolve_inheritdoc_typed()`, not the full child nodes. Could save ~2-3 MB retained.
2. **P3: CompletionCache** (1.9 MB) — check for name duplication with `nodes`.
3. **Further transient reduction** — the initial JSON parse (`serde_json::from_str`) allocates
the full AST tree (~70+ MB for BTreeMap nodes), which is then walked by `cache_ids()` and
`extract_decl_nodes()`. Streaming parse could avoid this but is a large refactor.