Changelog
v0.1.32
Features
- Alias-aware navigation —
textDocument/definition,textDocument/declaration,textDocument/implementation,textDocument/references, andtextDocument/renameall work correctly through import aliases (e.g.import {Foo as Bar}) (#197) - Goto-implementation fallback — when no implementations are found for a function, falls back to goto-definition instead of returning nothing (#200)
- Live buffer compilation —
textDocument/didChangecompiles the editor buffer directly, providing cross-file diagnostics for unsaved edits - Startup update check — the server checks GitHub releases on startup and shows a
window/showMessagenotification when a newer version is available; controlled by thecheckForUpdatessetting (default:true)
Fixes
- Stale results in 10 LSP handlers — handlers returned
Ok(None)(JSONnull) instead ofOk(Some(vec![]))(JSON[]) when they computed zero results; LSP clients (notably Neovim) interpretednullas "server couldn't compute" and kept displaying stale data; affected handlers:inlayHint,references,workspace/symbol,documentSymbol,documentHighlight,documentLink,foldingRange,selectionRange,codeAction(#201, #202) solidity.clearCachefull reset — the command now wipes all in-memory caches (ast_cache,completion_cache,sub_caches,semantic_token_cache,path_interner) in addition to the on-disk cache directory; previously only the project-root entry was evicted fromast_cache- Empty build protection — cross-file solc errors no longer replace a valid cached AST with an empty build
- Alias goto-implementation — import alias at usage site now targets the original definition, not the alias itself
Tests
- 647 tests, 0 failures, 0 warnings
v0.1.31
Fixes
- Precise
fromRangesin call hierarchy —callHierarchy/incomingCallsandcallHierarchy/outgoingCallsnow prefermember_location(the identifier-only span) oversrc(the full expression span) forMemberAccessnodes; e.g.slot0.protocolFee().getZeroForOneFee()producesfromRangespointing at justprotocolFeeandgetZeroForOneFeeinstead of the entire chain (#191) - Cross-build node ID mismatch in
textDocument/implementation— the handler used the file build'starget_idto look upbase_function_implementationin the project build, which could resolve to a completely different function; now re-resolves the target bybyte_to_id()per build (#193)
Docs
- Neovim call hierarchy handler snippet — outgoing calls now use
ctx.params.item.urifor the file path instead ofvim.api.nvim_buf_get_name(ctx.bufnr)(which returns the wrong file whenprepareCallHierarchyresolves to a different file); both handlers sort quickfix items by line then column
Tests
- 622 tests, 0 failures, 0 warnings
v0.1.30
Features
- Project-wide
PathInternerfor canonical file IDs — solc assigns file IDs sequentially based on input order, causing cross-compilation reference bugs; the interner assigns deterministic IDs so all builds share the same ID space (#185) textDocument/hover— show AST node ID (NodeId: `<id>`) in hover tooltips for debugging; references showNodeId: `<id>` referencedDeclaration: `<decl_id>`textDocument/references— qualifier-aware reference resolution; "Find All References" on a container (contract/library/interface) now includes qualified type paths where the container appears as a prefix (e.g.,PoolinPool.State) (#187)textDocument/definition— qualifier segment goto; clicking the qualifier in a qualified type path (e.g.,PoolinPool.State) navigates to the container declaration instead of the struct/enum (#187)CachedBuildgainsqualifier_refsfield (HashMap<NodeId, Vec<NodeId>>) — maps container declaration IDs toIdentifierPathnode IDs used as qualifiers; built at cache time bybuild_qualifier_refs()and merged across builds viamerge_missing_from()(#187)NodeInfogainsscopefield — the containing declaration's node ID from the ASTscopeproperty; used to resolve qualified type path containers (#187)dedup_locations()removes both exact and contained-range duplicates from reference results, preventing qualified type paths from producing duplicate entries (#187)- Two-phase project index — phase 1 compiles src-closure for fast time-to-first-reference, phase 2 compiles full closure (src + test + script) in background (#189)
- Parallel sub-cache compilation — library sub-projects now build concurrently via
JoinSetinstead of sequentially; Asyncswap benchmark: 53.5s to 15.8s (3.4x speedup) (#190) solidity/subCachesLoadedprogress token — emitted when all library sub-caches are built and loaded, allowing benchmarks and editors to detect full pipeline completion (#190)- AST-only sub-cache compilation — sub-cache builds request only AST output (no codegen settings, no contract outputs), letting solc skip codegen entirely (#190)
- Semaphore-based concurrency cap for parallel sub-cache builds — limits parallelism to
available_parallelism()to avoid thrashing on smaller machines (#190) Displayimpl forPragmaConstraint— log messages now show>=0.8.0 <0.9.0instead of debug-format dumps (#190)textDocument/prepareCallHierarchy+callHierarchy/incomingCalls+callHierarchy/outgoingCalls— navigate call graphs across contracts and libraries; tracks function calls (FunctionCallwithkind == "functionCall"), modifier invocations, and base constructor specifiers; container aggregation (incoming/outgoing on a contract = union of all its callables); narrowfromRangesusingexpression.srcfor direct calls andmemberLocationfor member-access calls; call hierarchy index built at cache time alongside existing goto/references indexes (#191)textDocument/implementation— "Go to Implementation" jumps from interface/abstract function declarations to their concrete implementations; builds a bidirectionalbase_function_implementationindex from solc'sbaseFunctions/baseModifiersAST fields at cache time; searches file, project, and sub-cache builds (#193)textDocument/references— interface/implementation equivalence; "Find All References" onPoolManager.swapnow also returns call sites that referenceIPoolManager.swap, and vice versa; uses thebase_function_implementationindex to expand the target ID set (#193)callHierarchy/incomingCalls— interface/implementation equivalence; incoming callers via interface-typed references (e.g.,manager.swap()wheremanagerisIPoolManager) are now included when querying the implementing function (#193)
Performance
- Remove
evm.gasEstimatesfrom solc output selection — gas estimation consumed 88% of compile time (SmarDex 510-file project: 56s to 6s). Removedgas.rs,GasKey,gas_index, gas inlay hints, gas hover, andgasEstimatessetting (#189, #190) - Clean up LSP log messages — remove redundant/noisy logs (per-lib build/load lines, discovered N files, compiled with no mismatches, cache saved, path interner count), simplify cache hit/miss messages, suppress zero-count diagnostic messages (#190)
Fixes
- Fix stale-offset duplicate references after editing — "Find All References" no longer produces bogus duplicates (e.g. 734 instead of 729 results) when the project cache has stale byte offsets for the current file;
goto_references_for_target()now excludes the current file from the project-cache scan since the fresh file-level build already covers it (#185) CompletionCachefile IDs are now canonicalized through thePathInternerremap, preventing scope-range mismatches across compilations (#185)- Removed dead
remap_src_file_idandremap_node_info_file_idsfunctions; simplifiedmerge_scoped_cached_build()by removing ~50 lines ofid_remapmachinery (#185) - Sub-cache loading flag was never reset to
falseafter completion — now correctly cleared (#190)
Tests
- 621 tests, 0 failures, 0 warnings
Benchmarks
| Project | Files | Before | After | Speedup |
|---|---|---|---|---|
| SmarDex | 510 | ~56s | 8.9s | 6.3x |
| Asyncswap | 108 + 1108 lib | ~57s | 22.1s | 2.6x |
v0.1.29
Features
textDocument/codeAction— JSON-driven quickfix engine; handlesunused-importforge-lint diagnostic with a "Remove unused import" action (#168)workspace/executeCommand—solidity.clearCacheandsolidity.reindexcommands (#175)textDocument/completion— import path completions inside import strings (#173)- Non-blocking
didSavewith per-URI watch channel serialisation — rapid saves collapse instead of stacking (#171)
Fixes
- Skip redundant solc rebuild on save when file content is unchanged — eliminates ~5s recompilation from format-on-save loops on large projects (#181)
- Wrap
collect_import_pragmasinspawn_blocking— the transitive import FS crawl no longer blocks the tokio async runtime, preventing request timeouts on first save of large files (#181) textDocument/referencesnow returns results for state variables and other declarations (was returning null) — 11 refs forShop.sol, 67 forPoolManager.t.sol- Guarantee full rebuild when reindex races with a running didSave worker (#178)
- Tree-sitter import/assembly string completion guards (#177)
- Use
project_cache_key()in executeCommand and wake reindex worker correctly (#176)
Benchmarks
Shop.sol: 26/26 methods, references 11 results, rename 11 edits, codeAction workingPoolManager.t.sol: 26/26 methods, references 67 results, 1082 inlay hints at 9.3ms
v0.1.28
Features
- Drop v1 cache path; v2 cache is now the only supported mode
- Auto-create
.gitignorein the cache directory on first write workspace/executeCommand—solidity.clearCachedeletes the on-disk cache and wipes in-memory AST, forcing a clean rebuild;solidity.reindexevicts in-memory AST and triggers a fast background reindex from the warm disk cache- Cache fingerprint now includes
lsp_versionso upgrading the server binary automatically invalidates stale caches; optimizer settings (optimizer,optimizer_runs,via_ir) removed from the fingerprint as they do not affect the reference index
Fixes
- Pull settings via
workspace/configurationwheninitializationOptionsis absent — fixes Neovim which sends settings only via pull requests, not asinitializationOptions(#164) - Use import-closure for project index: BFS from source/test/script roots via forge remappings compiles only files the project actually imports (~510 vs 1788 for v4-core), cross-file
referencedDeclarationIDs now populated correctly (#165) - Resolve solc version from transitive import pragmas: intersects pragma constraints across the full import graph so a wildcard pragma file importing an exact-version file picks a compatible solc, fixing empty ASTs and broken goto-definition (#162)
- Use tree-sitter for import parsing in pragma graph walk, correctly handling multi-line import directives
- Correct
textDocument/renamefor aliased imports (import {A as B}andimport './X.sol' as Y) (#167) - Fix config profile fallback and lint parsing
- Incremental reindex safety with threshold gating and scoped cache merge; warm-load reconciles changed files and persists cache aggressively (#156)
Docs
- Add
--stdioto Neovimcmdsnippets inDOCS.md - Add
projectIndexsettings to all editor config examples - Add missing
willCreate/didCreate/willDelete/didDeletecapabilities toneovim-plugin-lsp.lua - Fix
CONTRIBUTING.md: correct fixture name, test count (600), and project structure - Fix stale benchmark config references across profiling and completions docs
v0.1.27
Features
projectIndex.fullProjectScansetting to enable full project source indexing at startup (#152)- Persistent reference cache with atomic writes and single-flight sync (#153)
- Auto-create
.gitignorein cache directory (#154) - Incremental reindex safety with threshold gating and scoped cache merge (#156)
- Drop v1 cache path; v2 cache is now the only supported mode
Fixes
- Pull settings via
workspace/configurationwheninitializationOptionsis absent (#164) - Resolve solc version from transitive import pragmas (#162)
- Use import-closure for project index with full cross-file references (#165)
- Correct
textDocument/renamefor aliased imports (import {A as B}andimport './X.sol' as Y) (#167)
Tests
- 600 total tests, 0 warnings
v0.1.26
Features
- File operation behaviors are configurable via:
fileOperations.templateOnCreatefileOperations.updateImportsOnRenamefileOperations.updateImportsOnDelete
- Default file-operation settings are enabled.
- Template/scaffolding naming standardized to
templateOnCreate.
Fixes
- Improve file creation scaffolding flow to avoid missing scaffold content on new files.
- Fix duplicate/incorrect scaffold insertion timing during create-file lifecycle.
- Improve auto-import completion behavior for top-level symbols and import edit attachment.
Benchmarks
- Added/updated benchmark coverage for file-operation lifecycle flows (
willCreateFiles,willRenameFiles,willDeleteFiles) and auto-import scenarios.
v0.1.25
Performance
- Replace clone-then-strip with build-filtered-map in
walk_and_extract()(#132)build_filtered_decl()/build_filtered_contract()iterate borrowed node fields and only clone fields that pass the STRIP_FIELDS filter, skipping heavy subtrees (body,modifiers,value,overrides, etc.)- Eliminates 234 MB of transient allocations (629→395 MB total, -37%)
- RSS: 310 MB → 254 MB (down from 394 MB pre-optimization)
- Pre-size HashMaps with
with_capacity()incache_ids(),extract_decl_nodes(),build_completion_cache(),build_hint_index(),build_constructor_index()(#132) - Remove dead
goto_references()andgoto_references_with_index()functions (#132) - Gate
SolcOutput/SourceEntrybehind#[cfg(test)](#132)
Fixes
- Fix cross-file references contamination: use
nameLocationinstead ofsrcinresolve_target_location()so "Find All References" onIPoolManager managerreturns references tomanager, not to theIPoolManagerinterface (#131) - Fix non-deterministic hover on inherited contracts:
byte_to_id()now prefers nodes withreferencedDeclarationwhen two nodes share the same span length (#131)
Memory
| State | RSS | vs v0.1.24 |
|---|---|---|
| v0.1.24 baseline | 230 MB | — |
| Before optimization | 394 MB | +164 MB |
| v0.1.25 | 254 MB | +24 MB |
DHAT profiling (poolmanager-t-full.json, 95 files):
| Metric | v0.1.24 | v0.1.25 | Delta |
|---|---|---|---|
| Total allocated | 629 MB | 395 MB | -37% |
| Peak (t-gmax) | 277 MB | 243 MB | -12% |
| Retained (t-end) | 60 MB | 60 MB | unchanged |
Tests
- 458 total tests, 0 warnings
Benchmarks
Updated for Shop.sol (all competitors), Pool.sol (v0.1.25 vs v0.1.24), and PoolManager.t.sol (v0.1.25 vs v0.1.24).
v0.1.24
Features
- Project-wide source indexing for cross-file references (#115, #119)
- Semantic tokens range and delta support
- LSP settings configuration (#112)
- Benchmark configs with server registry and didChange snapshots (#121)
Performance
textDocument/documentLinkreturns only import links, not every identifier (#122)- Drop optimizer and conditionally exclude gasEstimates from solc input (#117)
Fixes
- Handle
{value: ...}/{gas: ...}modifier calls in inlay hints and signature help (#125, #116) - Correct signatureHelp cursor positions to inside function call parens
- Remap all tests from forge to solc fixture (#123)
- CI: checkout submodules so fixture-based tests can find v4-core
Tests
- 466 total tests, 0 warnings
Benchmark (v4-core Pool.sol)
| Method | p95 |
|---|---|
| initialize | 12.9ms |
| completion | 0.4ms |
| hover | 23.1ms |
| definition | 11.1ms |
| references | 19.4ms |
| rename | 21.2ms |
| inlayHint | 2.8ms |
| signatureHelp | 11.7ms |
| semanticTokens/full | 3.7ms |
Scorecard: 15/18 wins vs solc, nomicfoundation, juanfranblanco, qiuxiang
v0.1.23
Features
textDocument/signatureHelp— shows function signature and active parameter while typing (#110)- Opt-in gas estimates via
@custom:lsp-enable gas-estimatesNatSpec tag (#109)
v0.1.22
Improvements
- Use
svm-rsas a library for solc version management (#106, #105)svm::installed_versions()for discovering installed solc versionssvm::version_binary()for resolving solc binary pathssvm::install()for auto-installing missing versions (async, native)- No longer shells out to the
svmCLI or manually walks the filesystem
v0.1.21
Features
- Auto-detect solc version from
pragma solidityand resolve matching binary (#93, #95)- Parses pragma constraints: exact (
0.8.26), caret (^0.8.0), gte (>=0.8.0), range (>=0.6.2 <0.9.0) - Scans svm-rs and solc-select install directories for matching versions
- Auto-installs missing versions via
svm-rslibrary - Cross-platform support (macOS, Linux, Windows)
- Cached version list (scanned once per session)
- Parses pragma constraints: exact (
- Solc version resolution respects both pragma and foundry.toml (#103)
- Exact pragmas (
=0.7.6) always honoured — foundry.toml cannot override - Wildcard pragmas (
^0.8.0) use foundry.toml version if it satisfies the constraint - No pragma falls back to foundry.toml, then system solc
- Exact pragmas (
- Foundry config support for compiler settings (#103)
- Reads
via_ir,optimizer,optimizer_runs,evm_versionfromfoundry.toml - Passes settings to solc standard JSON (
viaIR,optimizer,evmVersion) - Reads
ignored_error_codesto suppress matching diagnostics - Fixes "Stack too deep" errors for projects requiring
via_ir(e.g. EkuboProtocol/evm-contracts)
- Reads
- Callsite parameter documentation on hover (#103)
- Hovering over arguments in function/event calls shows
@paramdoc from the called definition - Uses tree-sitter on the live buffer to find enclosing call and argument index
- Resolves via
HintIndex(exact offset or(name, arg_count)fallback) for param name anddecl_id - Looks up
@paramdoc fromDocIndexor raw NatSpec with@inheritdocresolution
- Hovering over arguments in function/event calls shows
- Gas estimates in hover, inlay hints, and code lens (#91, #94)
GasIndexbuilt from solc contract output (creation + external/internal costs)- Hover shows gas cost for functions and deploy cost for contracts
- Fire icon (🔥) with formatted numbers (e.g.
125,432)
- Use solc directly for AST + diagnostics, 11x faster on large projects (#90)
- Use solc userdoc/devdoc for hover documentation (#99)
DocIndexbuilt from solc contract output at cache time with pre-resolved@inheritdoc- Hover on parameters and return values shows
@param/@returndocs from parent function - Works at both declaration site and any usage inside the function body
- Structured rendering: notice,
@devdetails, params table, returns table - Typed selectors:
FuncSelector,EventSelector,Selectorenum,MethodIdnewtype - Replaces raw
Stringselectors throughout gas, hover, completion, and inlay hints
Refactor
- Gas inlay hints use tree-sitter positions from the live buffer (#96)
- Fixes hints drifting to wrong positions during editing
- Function gas hints support opening/closing brace placement (
FN_GAS_HINT_POSITIONconstant) - Contract deploy hints show
codeDepositCostwhentotalCostis infinite - Libraries and interfaces now show deploy cost hints
- Remove code lens — gas info is covered by inlay hints and hover (#96)
Fixes
- Improve natspec tag formatting in hover (#98)
@devnow renders with a bold**@dev**header above italic content@custom:tags and other unknown@tags render with bold label and italic content
- Bound
foundry.tomlsearch at git repo root (#89) - Hover works when file has compilation errors (#92)
Tests
- 423 total tests, 0 warnings
v0.1.20
Features
- Tree-sitter enhanced goto definition (#66, #79)
- Inlay hints v2 — tree-sitter positions + AST semantics (#61, #81)
- Respect
foundry.tomllint ignore andlint_on_buildconfig (#84, #87) - Introduce
NodeId/FileIdnewtypes and sharedSourceLocparser (#86)
Fixes
- Goto definition returns wrong result after unsaved edits (#83)
- Bound
foundry.tomlsearch at git repo root (#89)
v0.1.19
Refactor
- Rewrite
textDocument/documentSymbolandworkspace/symbolto use tree-sitter instead of Forge AST (#77, #78)- Symbols no longer depend on
forge build— works on any Solidity file immediately documentSymbolreads from text_cache with disk fallbackworkspace/symbolscans open files only
- Symbols no longer depend on
- Clean up semantic tokens to avoid overriding tree-sitter highlights (#78)
- Remove modifiers, builtin types, pragmas, variables, and member expressions from LSP tokens
- Prevents
@lsp.typemod.*priority 126-127 from overriding tree-sitter colors
Performance
textDocument/documentSymbol3.2x faster (3.24ms → 1.02ms)workspace/symbol6.4x faster (6.08ms → 0.95ms)
Features
- Add
textDocument/semanticTokens/fullvia tree-sitter (#75, #76)
Notes
Symbol kinds
The documentSymbol response returns hierarchical symbols with the following kind mappings:
| Solidity construct | LSP SymbolKind |
|---|---|
contract | CLASS |
interface | INTERFACE |
library | NAMESPACE |
function | FUNCTION |
constructor | CONSTRUCTOR |
fallback / receive | FUNCTION |
state variable | FIELD |
event | EVENT |
error | EVENT |
modifier | METHOD |
struct | STRUCT |
struct member | FIELD |
enum | ENUM |
enum value | ENUM_MEMBER |
using ... for | PROPERTY |
type ... is ... | TYPE_PARAMETER |
pragma | STRING |
import | MODULE |
Functions include a detail string with parameters and return types (e.g. (address to, uint256 amount) returns (bool)).
Contracts, structs, and enums are returned as parent symbols with their members nested as children. Top-level declarations (pragma, import, free functions, free structs/enums) appear at root level.
Semantic tokens and tree-sitter coexistence
LSP semantic tokens in Neovim have higher priority (125-127) than tree-sitter highlights (100). When both emit tokens for the same range, LSP wins. This causes problems when @lsp.typemod.* groups fall back to the generic @lsp highlight with undesirable colors.
The approach taken here: only emit semantic tokens where the LSP adds value that tree-sitter cannot provide. Let tree-sitter handle syntax it already highlights well (builtins, variables, member access, pragmas, modifiers). The LSP focuses on declaration identifiers, parameters, type references, and call targets where semantic knowledge matters.
v0.1.18
Features
- Context-sensitive
type(X).completions (#70)- Typing
type(ContractName).now showscreationCode,runtimeCode,name,interfaceId - Typing
type(IntegerType).showsmin,max
- Typing
Fixes
- Skip using-for completions on contract/library/interface names (#71, #72)
Lock.no longer returns Pool and SafeCast library functions fromusing Pool for *andusing SafeCast for *- Using-for completions now only appear when completing on a value of a matching type, not on a contract/library/interface name
- Fix SIMD chunk selection skipping past target column in
position_to_byte_offset(#73, #74)- The SIMD-accelerated position calculation introduced in #68 could pick a chunk boundary past the target column on long lines, returning the wrong byte offset
- Go-to-definition on
AlreadyUnlockedin PoolManager.sol resolved torevertWithin CustomRevert.sol instead of the correcterror AlreadyUnlocked()in IPoolManager.sol
Performance
- SIMD-accelerated position calculation via
lintspec-coreTextIndex (#68)position_to_byte_offsetandbyte_offset_to_positionnow use a single SIMD pass over 128-byte chunks instead of a full linear scan- Short linear walk (at most 128 bytes) from the nearest chunk to the exact position
Refactor
- Rewrite position conversion to use
lintspec-corecompute_indicesandTextIndex(#64, #68) - Simplify conversion functions, use builtin traits and constructors
- Improved identifier validation for Solidity keywords
v0.1.17
Fixes
- Simplify diagnostic path matching to fix silent drop (#63)
v0.1.16
Features
- Scope-aware completion with inheritance resolution (#57)
- Completions are now filtered by the current scope (contract, function, block)
- Inherited members from parent contracts are resolved and included
- Replaces the previous
fast/fullcompletion mode split with a single unified engine
Fixes
- Use relative path to filter out diagnostics (#55)
- Build diagnostic filtering now correctly matches files using relative paths
- Fixes cases where diagnostics from dependency files were incorrectly included
Deprecations
--completion-modeflag is deprecated (#59)- The
fast/fullsplit is no longer needed — scope-aware completions are always active
- The
New Contributors
- @libkakashi — chore: add Zed editor setup section in docs (#60)
Other
- Refactor build module: simplify diagnostic filtering, extract path comparison helper
- Add Zed editor setup section in docs (#60)
- 272 total tests, 0 warnings
v0.1.15
Fixes
- AST cache now updates when build has warnings but no errors (#41)
- The
build_succeededcheck useddiagnostics.is_empty()which blocked cache updates for files with unused variables or other warnings - Changed to only block on
DiagnosticSeverity::ERROR, so warnings pass through
- The
- Cross-file rename reads from in-memory editor buffers instead of disk (#50)
rename_symbolacceptstext_buffersparameter reflecting unsaved editor state- No more disk writes behind the editor's back
- Full
WorkspaceEditreturned to client for all files (#50)- Previously split edits between client (current file) and server-side
fs::write(other files) - Now the complete edit set is returned to the client
- Previously split edits between client (current file) and server-side
nameLocationsindex fallback in references (#50)- Nodes without
nameLocationsarray now correctly fall through tonameLocationorsrc
- Nodes without
- Stale AST range correction during rename (#50)
find_identifier_on_linescans the current line to correct shifted column positions after unsaved edits
- All LSP handlers read source from
text_cacheinstead ofstd::fs::read(#50) - Respect
includeDeclarationintextDocument/references(#49) - Use cached AST for
workspace/symbolinstead of rebuilding (#46) - Clear caches on
did_closeto free memory (#45) - Encoding-aware UTF-16 position conversion (#39)
- Remove document version when publishing diagnostics (#40)
- Pass
--ignore-eip-3860and--ignored-error-codes 5574to forge build (#11)
Features
- Announce full version string in LSP
initializeresponse (#51)- e.g.
0.1.15+commit.abc1234.macos.aarch64
- e.g.
Tests
- 10 new regression tests for bugs fixed in #41 and #50
tests/build.rs: warning-only builds succeed, error builds fail, empty diagnostics succeedtests/rename.rs: nameLocations fallback, text_buffers usage, cross-file WorkspaceEdit, stale AST correction, identifier extraction
- Solidity fixture files in
example/for rename tests (A.sol, B.sol, C.sol, Counter.sol) - 186 total tests, 0 warnings
New Contributors
- @beeb — fix: remove document version when publishing diagnostics (#40), filed issues #32, #33, #34, #35, #36, #37, #38, #41
Other
rustfmt.tomlandcargo fmtacross codebase (#42)- Benchmark config updated with all implemented LSP methods
v0.1.14
Fixes
textDocument/definitionandtextDocument/declarationnow return proper range width instead of zero-width ranges (#30)goto_bytes()returns(file_path, byte_offset, length)— extracts the length field fromnameLocationorsrcgoto_declaration()computesendfrombyte_offset + length, so editors correctly highlight the target symbol- Previously
start == endin the returnedLocation, making it impossible for the editor to highlight the target
Tests
- 4 new goto range-length tests:
Hooks(len 5),Pool(len 4),SafeCast(len 8), Yul external reference (nonzero) - 168 total tests, 0 warnings
v0.1.13
Features
textDocument/documentLink— every reference in a file is a clickable link- Import paths link to the imported file (resolves
absolutePathfrom AST) - All nodes with
referencedDeclarationlink to their definition viaid_to_location - Uses pre-indexed
CachedBuild.nodes— no extra AST traversal at request time
Fixes
--versionnow shows commit hash when installed from crates.io (reads.cargo_vcs_info.jsonas fallback)
Tests
- 11 document link tests (CI-safe, real fixture data from
pool-manager-ast.json) - 164 total tests, 0 warnings
v0.1.12
Features
- Cross-file "Find All References" — scans all cached AST builds to find usages across files that don't share a build scope
- Cross-file "Rename" — renames symbols across all cached builds, not just the current file's dependency tree
CachedBuildstruct — pre-computescache_ids()once per cache insert instead of N+1 times per request
Performance
cache_ids()no longer called at request time — all node indexing happens on file saveget_or_fetch_build()deduplicates cache-miss logic across goto, references, rename, hover, and document symbol handlers
Tests
- 12 new cross-file reference tests (CI-safe, hardcoded AST values from fixture)
- 153 total tests, 0 warnings
v0.1.11
Features
--version/-Vflag with full build metadata: version, commit hash, OS, architecture- GPG-signed release checksums for binary verification
CONTRIBUTING.mdwith project structure and development workflow
Improvements
- Remove redundant timestamp from tracing log output
- Add
build.rsto embed git commit hash at compile time - Add
public-key.ascfor release signature verification - Updated README with CLI usage examples, all flags, and verification instructions
v0.1.10
Features
textDocument/hover— show Solidity signatures, NatSpec documentation, and selectors on hover- Signature generation for functions, contracts, structs, enums, errors, events, modifiers, variables, UDVTs
- NatSpec formatting:
@notice,@param,@return,@devrendered as structured markdown - Display
functionSelector,errorSelector,eventSelectorfrom AST in hover output @inheritdocresolution viafunctionSelectormatching between implementation and parent interface — correctly handles overloaded functions- 25 hover tests against Uniswap v4 PoolManager AST
v0.1.8
Features
- Full completion engine with chain resolution, using-for directives, and type casts (~1400 lines, 86 tests)
--completion-modeflag:fast(default) pre-built completions,fullper-request scope filtering- Dot-completion for structs, contracts, libraries, magic globals (
msg,block,tx,abi,type) - Chain completions through function return types, mappings, type casts
using-fordirective support (e.g.PoolKey.toId(),BalanceDelta.amount0())- Method identifier completions with 4-byte selectors and full signatures
- Keyword, global function, ether/time unit completions
Performance
- Arc-based zero-copy AST cache — eliminates 7MB+ deep clones per handler request
- Non-blocking completion cache — returns static completions immediately while cache builds in background
document_symbolusesast_cacheinstead of shelling out toforge aston every request- Removed blocking
log_messagefrom completion handler to fix cancel+re-trigger lag
Yul
- Yul
externalReferencessupport for goto-definition and find-references
v0.1.7
- Yul externalReferences support for goto-definition and find-references
- Completion engine with chain resolution, using-for, and type casts
v0.1.6
- Fix rename in tests
- Fix: ignore bytecode size warnings for all sol files
- Enable goto definition for import statement strings
- Handle ImportDirective nodes in goto definition
- Add absolute_path field to NodeInfo struct
v0.1.4
- Fix: only update AST cache when build succeeds
- Fix: preserve AST cache on file changes to keep go-to-definition working during errors