A library for semantic analysis of ink! smart contract code.


Keywords
blockchain, smart-contract, polkadot, substrate, ink, analyzer, rust, semantic-analyzer, smart-contracts
Licenses
MIT/Apache-2.0

Documentation

icon ink! Analyzer

A collection of modular and reusable libraries and tools for semantic analysis of ink! smart contract code.

ink! analyzer aims to improve ink! language support in integrated development environments (IDEs), source code editors and other development tools by providing modular and reusable building blocks for implementing features like diagnostics, code completion, code/intent actions and hover content for the ink! programming language which is used for writing smart contracts for blockchains built with Substrate.

Architecture

This repository contains 4 main crates:

This crate implements utilities for performing semantic analysis of ink! smart contract code. It therefore implements the core functionality of ink! analyzer at a high level.

It currently implements an Analysis entry point that accepts a string representation (&str) of ink! smart contract code as input and defines associated methods that compute:

  • diagnostics - errors and warnings based on ink! semantic rules.
  • quickfixes - suggested edits/code actions for diagnostic errors and warnings.
  • completions - completion suggestions for ink! attribute macros and arguments.
  • code/intent actions - contextual assists for adding relevant ink! attribute macros, arguments and entities.
  • hover content - descriptive/informational text for ink! attribute macros and arguments.
  • inlay hints - inline type and format information for ink! attribute arguments values (e.g. u32 | _ | @ for ink! message selectors).
  • signature help - popup information for valid ink! attribute arguments for the current context/cursor position.

This crate implements the Language Server Protocol (LSP) and acts as a backend that provides language support features like diagnostic errors, code completion suggestions, code/intent actions and hover content to IDEs, code editors and other development tools.

It uses the semantic analyzer as the engine for providing ink! language support features by:

  • translating LSP requests into semantic analyzer interface calls.
  • translating semantic analysis results into corresponding LSP types.

It additionally uses rust-analyzer's lsp-server crate to handle LSP protocol handshaking and parsing messages, and the lsp-types crate for LSP type definitions.

Its compiled binary can be used with any LSP client that can be configured to launch an LSP server using an executable command (i.e. the path to the ink-lsp-server binary) and can use stdio (standard in/standard out) as the message transport.

This crate implements types, abstractions and utilities for parsing ink! smart contract code into ink! intermediate representations (IRs) and abstractions.

It implements types and abstractions for all ink! entities (e.g contracts, storage, events, topics, impls, constructors, messages, selectors, tests, trait definitions, chain extensions, storage items e.t.c).

It uses rust-analyzer's ra_ap_syntax crate for generating the syntax tree of the ink! smart contract code that it then converts into ink! entity intermediate representations and abstractions.

It uses ra_ap_syntax instead of other Rust parsing and syntax tree libraries because ink! analyzer has similar design goals to rust-analyzer. The most important being that parsing should be:

  • resilient (even if the input is invalid, parser tries to see as much syntax tree fragments in the input as it can).
  • lossless (even if the input is invalid, the tree produced by the parser represents it exactly).

It's the main dependency for the semantic analyzer crate.

This crate implements procedural macros used primarily by the ink-analyzer-ir crate.

Installation and Usage

Check the readme of each crate for installation and usage instructions and links to documentation.

Documentation

Or you can access documentation locally by running the following command from the project root

cargo doc --open

To open crate specific docs, see instructions in the readme in each crate's directory.

Testing

You can run unit and integration tests for all the core functionality for all crates by running the following command from the project root

Option 1: Native Rust and cargo

cargo test

NOTE: To run only tests for a single crate, add a -p <crate_name> argument to the above command e.g.

cargo test -p ink-analyzer-ir

Option 2: Docker

Build the docker image.

docker build -t ink-analyzer .

Run tests from the container.

docker run -it ink-analyzer

NOTE: To run only tests for a single crate, add a -p <crate_name> argument to the docker run command e.g.

docker run -it ink-analyzer -p ink-analyzer-ir

License

Licensed under either MIT or Apache-2.0 license at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Acknowledgements

🌱 Funded by: the Web3 Foundation.