- Rust (stable)
- Foundry (
forgemust be in your PATH) - A Foundry project to test against (e.g. Uniswap v4-core)
git clone https://github.com/asyncswap/solidity-language-server.git
cd solidity-language-server
cargo build --release
cargo testsrc/
├── main.rs # CLI entry point, clap args, tracing setup
├── lib.rs # Module declarations
├── lsp.rs # LSP server, handler dispatch, capabilities
├── build.rs # forge build + diagnostics
├── config.rs # LSP settings deserialization
├── completion.rs # Completion engine, chain resolution, using-for
├── file_operations.rs # willCreate/willRename/willDelete file ops
├── folding.rs # textDocument/foldingRange
├── goto.rs # goto-definition, goto-declaration, AST node caching
├── highlight.rs # textDocument/documentHighlight
├── hover.rs # textDocument/hover, NatSpec, selectors, @inheritdoc
├── inlay_hints.rs # textDocument/inlayHint
├── links.rs # textDocument/documentLink
├── lint.rs # forge lint diagnostics
├── project_cache.rs # v2 on-disk shard cache, single-flight sync
├── references.rs # find-references, Yul external refs
├── rename.rs # prepare-rename, rename (including aliased imports)
├── runner.rs # solc subprocess runner
├── selection.rs # textDocument/selectionRange
├── semantic_tokens.rs # textDocument/semanticTokens (full/range/delta)
├── solar_runner.rs # experimental Solar parser backend
├── solc.rs # solc invocation and output parsing
├── solc_ast/ # AST node types and visitor (12 sub-modules)
├── symbols.rs # document/workspace symbols
├── types.rs # shared type definitions
└── utils.rs # shared utilities
docs/pages/ # Vocs docs content (quickstart, setup, reference, benchmarks)
build.rs # Compile-time: git commit hash, OS, arch
cargo test # all tests (600 currently)
cargo test hover # run hover tests only
cargo test completion # run completion tests onlyTests use poolmanager.json (Uniswap v4 fixture) committed in the repo.
Build and point your editor at the binary:
cargo build --release
# binary is at target/release/solidity-language-serverOr install locally:
cargo install --path .Test against a real Foundry project — the LSP needs foundry.toml in the project root.
- Create the module — e.g.
src/feature.rs - Register in
src/lib.rs— addpub mod feature; - Add capability in
src/lsp.rs— in theinitializehandler'sServerCapabilities - Add handler in
src/lsp.rs— implement theLanguageServertrait method - Use
ast_cache— read fromself.ast_cacheinstead of callingself.compiler.ast()directly - Write tests — use
poolmanager.jsonfixture, assert against known node IDs - Add docs — document behavior in
docs/pages/reference/*.md(and update setup/quickstart pages if needed)
The compiler AST is the foundation. Use jq to explore:
# Find a node by ID
jq '.. | objects | select(.id == 1767)' poolmanager.json
# Find nodes by type
jq '[.. | objects | select(.nodeType == "FunctionDefinition")] | length' poolmanager.json
# Find nodes with a specific field
jq '.. | objects | select(.functionSelector != null) | {id, name, functionSelector}' poolmanager.jsonSee documentation site and docs/pages/reference/ for implementation-deep feature guides.
- Create an issue describing the feature or bug
- Branch from
main:git checkout -b feature/your-feature - Make your changes with tests
- Ensure
cargo testpasses andcargo checkhas no warnings - Open a PR referencing the issue
Releases are automated. When a v* tag is pushed:
- CI builds release binaries for macOS (arm64, x86_64), Linux (x86_64), and Windows (x86_64)
- Generates SHA-256 checksums
- GPG-signs the checksums
- Creates a GitHub Release with all artifacts
Tag protection rules restrict who can push release tags.