From f9e21febf23338fbcc1b5f1a3b81de0b028a0aa4 Mon Sep 17 00:00:00 2001 From: davidsemakula Date: Sun, 4 Feb 2024 11:07:45 +0300 Subject: [PATCH] fix formatting --- .github/workflows/release.yaml | 3 +- .github/workflows/test.yaml | 3 +- DEVELOPMENT.md | 37 +++--- README.md | 11 +- TESTING.md | 196 ++++++++++++++++++++++------- src/manager.ts | 8 +- src/middleware.ts | 2 +- src/services.ts | 4 +- src/snippets.ts | 9 +- src/test/suite/diagnostics.test.ts | 3 +- 10 files changed, 199 insertions(+), 77 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index db64bb3..0997c62 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -65,7 +65,8 @@ jobs: npm_config_arch: ${{ matrix.npm-config-arch }} run: yarn install --frozen-lockfile - # Auto-downloads the platform specific language server (see https://github.com/ink-analyzer/ink-vscode/blob/master/setup.js). + # Auto-downloads the platform specific language server + # (see https://github.com/ink-analyzer/ink-vscode/blob/master/setup.js). - name: Build packages env: npm_config_arch: ${{ matrix.npm-config-arch }} diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 592371f..ccd36c1 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -26,7 +26,8 @@ jobs: - name: Run lints run: yarn lint - # Auto-downloads the platform specific language server (see https://github.com/ink-analyzer/ink-vscode/blob/master/setup.js). + # Auto-downloads the platform specific language server + # (see https://github.com/ink-analyzer/ink-vscode/blob/master/setup.js). - name: Run tests (Windows and macOS) if: inputs.os != 'ubuntu-latest' env: diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 7a8b7d2..6970fdc 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -8,8 +8,9 @@ - [Node.js >= 16.0](https://nodejs.org/) - [Yarn >= 1.0](https://yarnpkg.com/) -**NOTE:** Older versions of Node.js and Yarn may work, however, they have not been tested and no support will be provided for them. -Similarly other package managers (e.g. [npm](https://www.npmjs.com/) and [pnpm](https://pnpm.io/)) will likely work, but they haven't been tested and no support will be provided for them. +**NOTE:** Older versions of Node.js and Yarn may work, however, they have not been tested and no support will be +provided for them. Similarly other package managers (e.g. [npm](https://www.npmjs.com/) and [pnpm](https://pnpm.io/)) +will likely work, but they haven't been tested and no support will be provided for them. ### Dev Container Development @@ -17,7 +18,8 @@ Similarly other package managers (e.g. [npm](https://www.npmjs.com/) and [pnpm]( - [Docker](https://www.docker.com/) - [Dev Containers Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) -Follow these VS Code Dev Containers tutorials to set up your development environment and get started with container-based development: +Follow these VS Code Dev Containers tutorials to set up your development environment and get started with +container-based development: - [Dev Containers tutorial](https://code.visualstudio.com/docs/devcontainers/tutorial) - [Developing inside a Container](https://code.visualstudio.com/docs/devcontainers/containers) @@ -45,19 +47,26 @@ Run the following command from the project root: yarn install ``` -**NOTE:** The above command is automatically run after the Dev Container is created, so it can be skipped in that context. +**NOTE:** The above command is automatically run after a Dev Container is created, so it can be skipped in that context. ### Debugging - Open the project in VS Code. -- Start a debugging session using either the `Run Extension (alongside Rust Analyzer)` or `Run Extension (without Rust Analyzer)` launch configuration. - - This will open a new VS Code window with the extension loaded and the [`test-fixtures`](/test-fixtures) directory set as the workspace root. +- Start a debugging session using either the `Run Extension (alongside Rust Analyzer)` or + `Run Extension (without Rust Analyzer)` launch configuration. + - This will open a new VS Code window with the extension loaded and the [`test-fixtures`](/test-fixtures) directory + set as the workspace root. - A debugging session can be started in a few ways including: - - Opening the ["Run and Debug" view](https://code.visualstudio.com/docs/editor/debugging#_run-and-debug-view) and selecting and running the preferred launch configuration from the configuration dropdown. - - Selecting `Start Debugging > Run Extension (alongside Rust Analyzer)` or `Start Debugging > Run Extension (without Rust Analyzer)` from the ["Command Palette"](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette). - - Selecting `Run > Start Debugging` from the [application menu](https://code.visualstudio.com/docs/editor/debugging#_run-menu) to run the last run (or default) Debug configuration. + - Opening the ["Run and Debug" view](https://code.visualstudio.com/docs/editor/debugging#_run-and-debug-view) and + selecting and running the preferred launch configuration from the configuration dropdown. + - Selecting `Start Debugging > Run Extension (alongside Rust Analyzer)` or + `Start Debugging > Run Extension (without Rust Analyzer)` from the + ["Command Palette"](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette). + - Selecting `Run > Start Debugging` from the [application menu](https://code.visualstudio.com/docs/editor/debugging#_run-menu) + to run the last run (or default) Debug configuration. -**NOTE:** Extension source code is found in the [`src/`](/src) directory and [`src/extension.ts`](/src/extension.ts) is the entrypoint. +**NOTE:** Extension source code is found in the [`src/`](/src) directory and [`src/extension.ts`](/src/extension.ts) +is the entrypoint. ## Testing @@ -76,7 +85,8 @@ yarn test - Open the project in VS Code. - Start a debugging session using the `Run Extension Tests` launch configuration. -**NOTE:** See the [`Development > Debugging`](#debugging) section above for instructions for starting a debugging session using a launch configuration. +**NOTE:** See the [`Development > Debugging`](#debugging) section above for instructions for starting +a debugging session using a launch configuration. **NOTE:** For instructions for manual feature testing, refer to the ["Manual Feature Testing Guide"](/TESTING.md). @@ -86,9 +96,8 @@ Licensed under [GPL-3.0](/LICENSE). ## Contribution -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in the work by you, as defined in the GPL-3.0 license, shall be -licensed as above, without any additional terms or conditions. +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, +as defined in the GPL-3.0 license, shall be licensed as above, without any additional terms or conditions. ## Acknowledgements diff --git a/README.md b/README.md index d93565a..4643e6c 100644 --- a/README.md +++ b/README.md @@ -96,8 +96,10 @@ This extension provides the following settings: -- `ink-analyzer.server.path`: **(Optional)** Sets the path to ink! Language Server (ink-lsp-server) binary/executable (points to the bundled binary/executable that ships with the extension by default). -- `ink-analyzer.trace.server`: **(Optional)** Enables/disables tracing of the communication between VS Code and the ink! Language Server (not recommended for regular users). +- `ink-analyzer.server.path`: **(Optional)** Sets the path to ink! Language Server (ink-lsp-server) binary/executable + (points to the bundled binary/executable that ships with the extension by default). +- `ink-analyzer.trace.server`: **(Optional)** Enables/disables tracing of the communication between VS Code and + the ink! Language Server (not recommended for regular users). ## Development and Testing @@ -109,9 +111,8 @@ Licensed under [GPL-3.0](/LICENSE). ## Contribution -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in the work by you, as defined in the GPL-3.0 license, shall be -licensed as above, without any additional terms or conditions. +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, +as defined in the GPL-3.0 license, shall be licensed as above, without any additional terms or conditions. ## Acknowledgements diff --git a/TESTING.md b/TESTING.md index d21079c..ab650b7 100644 --- a/TESTING.md +++ b/TESTING.md @@ -4,23 +4,34 @@ ### Option 1: Marketplace Install -- Install the [VS Code extension](https://marketplace.visualstudio.com/items?itemName=ink-analyzer.ink-analyzer) directly from the VS Code marketplace following [this guide](https://code.visualstudio.com/docs/editor/extension-marketplace#_install-an-extension) -- Clone the [VS Code extension repo](https://github.com/ink-analyzer/ink-vscode) and open the [test-fixtures](https://github.com/ink-analyzer/ink-vscode) directory in VS Code. +- Install the [VS Code extension](https://marketplace.visualstudio.com/items?itemName=ink-analyzer.ink-analyzer) + directly from the VS Code marketplace following [this guide](https://code.visualstudio.com/docs/editor/extension-marketplace#_install-an-extension) +- Clone the [VS Code extension repo](https://github.com/ink-analyzer/ink-vscode) and + open the [test-fixtures](https://github.com/ink-analyzer/ink-vscode) directory in VS Code. ### Option 2: Debug Environment -- Follow the VS Code extension's ["Development, Debugging and Automated Testing Guide"](/DEVELOPMENT.md) to set up a test environment. -- Use the "Run Extension (without Rust Analyzer)" launch configuration to test the extension in an isolated environment (see further instructions in the ["Development, Debugging and Automated Testing Guide"](/DEVELOPMENT.md)). +- Follow the VS Code extension's ["Development, Debugging and Automated Testing Guide"](/DEVELOPMENT.md) to set up + a test environment. +- Use the "Run Extension (without Rust Analyzer)" launch configuration to test the extension in an isolated environment + (see further instructions in the ["Development, Debugging and Automated Testing Guide"](/DEVELOPMENT.md)). -**NOTE:** If you're using the Debug Environment option and have already cloned the [VS Code extension repository](https://github.com/ink-analyzer/ink-vscode) in the past, be sure to pull the latest changes to make sure you get the latest release of the language server. +**NOTE:** If you're using the Debug Environment option and have already cloned the +[VS Code extension repository](https://github.com/ink-analyzer/ink-vscode) in the past, +be sure to pull the latest changes to make sure you get the latest release of the language server. ## Testing -The instructions below are written for the [flipper contract in the "test-fixtures" directory/workspace of the VS Code extension's repository](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/flipper/lib.rs) (unless stated otherwise), so open that in VS Code first. +The instructions below are written for the +[flipper contract in the "test-fixtures" directory/workspace of the VS Code extension's repository](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/flipper/lib.rs) +(unless stated otherwise), so open that in VS Code first. ### 1. Commands -You can view a list of all available commands by typing `ink!` into the ["Command Palette"](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) (i.e. type `Cmd/Ctrl + Shift + P` and then type `ink!`), or hovering over the `ink! analyzer` ["Status Bar"](https://code.visualstudio.com/docs/getstarted/userinterface) item. +You can view a list of all available commands by typing `ink!` into the +["Command Palette"](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) +(i.e. type `Cmd/Ctrl + Shift + P` and then type `ink!`), or hovering over the `ink! analyzer` +["Status Bar"](https://code.visualstudio.com/docs/getstarted/userinterface) item. ![command palette](/images/screenshots/command-palette.png 'command palette') @@ -43,31 +54,78 @@ pub struct Flipper { **Expected Result:** -- You should see diagnostic squiggles on the ink! contract `mod` item (i.e. covering the line `pub mod flipper {`). -- Hovering over the squiggles should show a diagnostic message like `Missing ink! storage`. -- Hovering over the squiggles should reveal a "quickfix" to `Add ink! storage "struct".` -- Alternatively, positioning the cursor on the squiggles and clicking the "light bulb" that's triggered by this action will also reveal the above quickfix. +- You should see diagnostic "squiggles" (zigzag underlines) on the ink! contract `mod` item + (i.e. covering the line `pub mod flipper {`). +- Hovering over the "squiggles" should show a diagnostic message like `Missing ink! storage`. +- Hovering over the "squiggles" should reveal a "quickfix" to `Add ink! storage "struct".` +- Alternatively, positioning the cursor on the "squiggles" and clicking the "light bulb" that's triggered by + this action will also reveal the above quickfix. **Additional testing examples:** - Remove other required ink! entities (e.g. remove all ink! messages). -- Add a conflicting argument to one of the ink! attributes (e.g. change `#[ink(constructor)]` to `#[ink(constructor, topic)]` or change `#[ink::contract]` to `#[ink::contract(payable)]`). -- Add an unknown argument to one of the ink! attributes (e.g. change `#[ink(constructor)]` to `#[ink(constructor, xyz)]`). -- Apply an ink! attribute to the wrong Rust item kind (e.g. add an `#[ink::test]` attribute above the line `impl Flipper {`). -- Add unexpected or remove required Rust item invariants e.g. remove the `Self` return type (i.e. remove ` -> Self`) from one of the ink! constructor functions or add a self reference receiver (i.e. add `&self` as the first parameter) to one of the ink! constructor functions. -- Add clashing selectors to ink! constructors or ink! messages (e.g. change all `#[ink(message)]` attributes to `#[ink(message, selector = 1)]`, or add an ink! constructor or ink! message with the same `fn` name as an existing callable e.g. add another ink! message named `flip`). -- Move an ink! entity to the wrong scope (e.g. move an ink! message into the root of the contract `mod` - e.g. move the `flip` ink! message to the line right after the ink! storage `struct`). -- Set a wrong value for an ink! `env` argument value (e.g. replace `#[ink::contract(env = crate::CustomEnvironment)]` with `#[ink::contract(env = self::CustomEnvironment)]` in the [psp22-extension contract](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/psp22-extension/lib.rs) in the test-fixtures directory). -- Remove the `ink::env::Environment` implementation for a custom chain environment type (e.g. remove the `ink::env::Environment` implementation for the `CustomEnvironment` type i.e. by removing the `impl` block starting with the line `impl Environment for CustomEnvironment {` in the [psp22-extension contract](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/psp22-extension/lib.rs) in the test-fixtures directory). -- Remove one of the methods in a trait definition implementation block (e.g. remove the `get(&self) -> bool` method from the `impl` block starting with line `impl Flip for Flipper {` in the [trait-flipper contract](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/trait-flipper/lib.rs) in the test-fixtures directory). -- Add a custom method that's not defined in the trait definition to its implementation block (e.g. add a method named `another` to the `impl` block starting with line `impl Flip for Flipper {` in the [trait-flipper contract](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/trait-flipper/lib.rs) in the test-fixtures directory). -- Modify the signature of a trait definition implementation block method to not match the signature of the similarly named method in the trait definition (e.g. replace the immutable self receiver in `get(&self) -> bool` with a mutable self receiver i.e. `get(&mut self) -> bool`, or replace the `bool` return type with a `Option` return type for the `impl` block starting with line `impl Flip for Flipper {` in the [trait-flipper contract](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/trait-flipper/lib.rs) in the test-fixtures directory). -- Modify the ink! attribute arguments of a trait definition implementation block method to not match those of the similarly named method in the trait definition (e.g. add the ink! `payable` attribute argument to the `get(&self) -> bool` method i.e. replace `#[ink(message)]` with `#[ink(message, payable)]` for the `impl` block starting with line `impl Flip for Flipper {` in the [trait-flipper contract](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/trait-flipper/lib.rs) in the test-fixtures directory). -- Remove the `ink::env::chain_extension::FromStatusCode` implementation for a chain extension's `ErrorCode` type (e.g. remove the `ink::env::chain_extension::FromStatusCode` implementation for the `Psp22Error` type i.e. by removing the `impl` block starting with the line `impl ink::env::chain_extension::FromStatusCode for Psp22Error {` in the [psp22-extension contract](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/psp22-extension/lib.rs) in the test-fixtures directory). -- Use `Self::ErrorCode` in a chain extension (e.g. change the `token_name` extension declaration from `fn token_name(asset_id: u32) -> Result>;` to `fn token_name(asset_id: u32) -> core::result::Result, Self::ErrorCode>;` in the [psp22-extension contract](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/psp22-extension/lib.rs) in the test-fixtures directory). -- Remove at least one SCALE codec trait (i.e. `scale::Encode`, `scale::Decode` and `scale_info::TypeInfo`) implementation (including via `#[derive(...)]` attributes) from a chain extension's `ErrorCode` type or a custom input or output type for one of its methods (e.g. remove the `#[derive(scale::Encode, scale::Decode)]` and/or `#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]` attribute for the `Psp22Error` type i.e. by removing the attributes above the line `pub enum Psp22Error {` in the [psp22-extension contract](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/psp22-extension/lib.rs) in the test-fixtures directory). - -All the above edits should result in diagnostics squiggles that reveal one or more quickfixes for the issues. +- Add a conflicting argument to one of the ink! attributes (e.g. change `#[ink(constructor)]` to + `#[ink(constructor, topic)]` or change `#[ink::contract]` to `#[ink::contract(payable)]`). +- Add an unknown argument to one of the ink! attributes + (e.g. change `#[ink(constructor)]` to `#[ink(constructor, xyz)]`). +- Apply an ink! attribute to the wrong Rust item kind + (e.g. add an `#[ink::test]` attribute above the line `impl Flipper {`). +- Add unexpected or remove required Rust item invariants e.g. remove the `Self` return type (i.e. remove `-> Self`) + from one of the ink! constructor functions or add a self reference receiver (i.e. add `&self` as the first parameter) + to one of the ink! constructor functions. +- Add clashing selectors to ink! constructors or ink! messages (e.g. change all `#[ink(message)]` attributes to + `#[ink(message, selector = 1)]`, or add an ink! constructor or ink! message with the same `fn` name as an + existing callable e.g. add another ink! message named `flip`). +- Move an ink! entity to the wrong scope (e.g. move an ink! message into the root of the contract `mod` - e.g. + move the `flip` ink! message to the line right after the ink! storage `struct`). +- Set a wrong value for an ink! `env` argument value (e.g. replace `#[ink::contract(env = crate::CustomEnvironment)]` + with `#[ink::contract(env = self::CustomEnvironment)]` in the + [psp22-extension contract](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/psp22-extension/lib.rs) + in the test-fixtures directory). +- Remove the `ink::env::Environment` implementation for a custom chain environment type + (e.g. remove the `ink::env::Environment` implementation for the `CustomEnvironment` type i.e. + by removing the `impl` block starting with the line `impl Environment for CustomEnvironment {` in the + [psp22-extension contract](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/psp22-extension/lib.rs) + in the test-fixtures directory). +- Remove one of the methods in a trait definition implementation block (e.g. remove the `get(&self) -> bool` method + from the `impl` block starting with line `impl Flip for Flipper {` in the + [trait-flipper contract](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/trait-flipper/lib.rs) + in the test-fixtures directory). +- Add a custom method that's not defined in the trait definition to its implementation block (e.g. add a method named + `another` to the `impl` block starting with line `impl Flip for Flipper {` in the + [trait-flipper contract](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/trait-flipper/lib.rs) + in the test-fixtures directory). +- Modify the signature of a trait definition implementation block method to not match the signature of the similarly + named method in the trait definition (e.g. replace the immutable self receiver in `get(&self) -> bool` with + a mutable self receiver i.e. `get(&mut self) -> bool`, or replace the `bool` return type with a `Option` + return type for the `impl` block starting with line `impl Flip for Flipper {` in the + [trait-flipper contract](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/trait-flipper/lib.rs) + in the test-fixtures directory). +- Modify the ink! attribute arguments of a trait definition implementation block method to not match those of the + similarly named method in the trait definition (e.g. add the ink! `payable` attribute argument to the + `get(&self) -> bool` method i.e. replace `#[ink(message)]` with `#[ink(message, payable)]` for the `impl` block + starting with line `impl Flip for Flipper {` in the + [trait-flipper contract](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/trait-flipper/lib.rs) + in the test-fixtures directory). +- Remove the `ink::env::chain_extension::FromStatusCode` implementation for a chain extension's `ErrorCode` type (e.g. + remove the `ink::env::chain_extension::FromStatusCode` implementation for the `Psp22Error` type i.e. by removing + the `impl` block starting with the line `impl ink::env::chain_extension::FromStatusCode for Psp22Error {` in the + [psp22-extension contract](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/psp22-extension/lib.rs) + in the test-fixtures directory). +- Use `Self::ErrorCode` in a chain extension (e.g. change the `token_name` extension declaration from + `fn token_name(asset_id: u32) -> Result>;` to + `fn token_name(asset_id: u32) -> core::result::Result, Self::ErrorCode>;` in the + [psp22-extension contract](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/psp22-extension/lib.rs) + in the test-fixtures directory). +- Remove at least one SCALE codec trait (i.e. `scale::Encode`, `scale::Decode` or `scale_info::TypeInfo`) implementation + (including via `#[derive(...)]` attributes) from a chain extension's `ErrorCode` type or a custom input or + output type for one of its methods (e.g. remove the `#[derive(scale::Encode, scale::Decode)]` and/or + `#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]` attribute for the `Psp22Error` type i.e. + by removing the attributes above the line `pub enum Psp22Error {` in the + [psp22-extension contract](https://github.com/ink-analyzer/ink-vscode/blob/master/test-fixtures/psp22-extension/lib.rs) + in the test-fixtures directory). + +All the above edits should result in diagnostics "squiggles" that reveal one or more quickfixes for the issues. **NOTE:** The list of diagnostics and quickfixes above is not exhaustive. @@ -75,43 +133,91 @@ All the above edits should result in diagnostics squiggles that reveal one or mo ![message completions](/images/screenshots/completion.png 'message completions') -- For attribute macro completions, make one of the ink! macro-based attributes "incomplete" (e.g. change `#[ink::contract]` to `#[ink]` or `#[ink::c]`) and either start typing to complete the macro name or hit `Cmd/Ctrl + Space` to trigger a completion proposal manually. -- For "primary" attribute argument completions (e.g. `storage`, `event`, `constructor`, `message` e.t.c), make one of the ink! argument-based attributes "incomplete" (e.g. change `#[ink(storage)]` to `#[ink()]`) and either typing the `(` character, or starting to type inside the parentheses, or hitting `Cmd/Ctrl + Space` should trigger completion proposals. -- For "additional" attribute argument completions (e.g. `payable`, `default`, `selector` for `#[ink(message)]`, or `anonymous` for `#[ink(event)]` e.t.c), add a comma after an existing attribute argument (e.g. change `#[ink(message)]` to `#[ink(message,)]`) and either typing the comma (`,`) character, or hitting `Cmd/Ctrl + Space` should trigger completion proposals. -- For complementary argument completions for ink! attribute macros (e.g. `env` and `keep_attr` for `#[ink::contract]`), add parentheses after the attribute macro (e.g. change `#[ink::contract]` to `#[ink::contract()]`), and either typing the `(` character, or starting to type inside the parentheses, or hitting `Cmd/Ctrl + Space` should trigger completion proposals. +- For attribute macro completions, make one of the ink! macro-based attributes "incomplete" + (e.g. change `#[ink::contract]` to `#[ink]` or `#[ink::c]`) and either start typing to complete the macro name or + hit `Cmd/Ctrl + Space` to trigger a completion proposal manually. +- For "primary" attribute argument completions (e.g. `storage`, `event`, `constructor`, `message` e.t.c), + make one of the ink! argument-based attributes "incomplete" (e.g. change `#[ink(storage)]` to `#[ink()]`) and + either typing the `(` character, or starting to type inside the parentheses, or hitting `Cmd/Ctrl + Space` + should trigger completion proposals. +- For "additional" attribute argument completions + (e.g. `payable`, `default`, `selector` for `#[ink(message)]`, or `anonymous` for `#[ink(event)]` e.t.c), + add a comma after an existing attribute argument (e.g. change `#[ink(message)]` to `#[ink(message,)]`) and + either typing the comma (`,`) character, or hitting `Cmd/Ctrl + Space` should trigger completion proposals. +- For complementary argument completions for ink! attribute macros (e.g. `env` and `keep_attr` for `#[ink::contract]`), + add parentheses after the attribute macro (e.g. change `#[ink::contract]` to `#[ink::contract()]`), and + either typing the `(` character, or starting to type inside the parentheses, or hitting `Cmd/Ctrl + Space` + should trigger completion proposals. ### 4. Hover content ![`env` hover content](/images/screenshots/hover-2.png '`env` hover content') -Hovering over an ink! attribute macro (e.g. `#[ink::contract]`) or argument (e.g. `#[ink(storage)]` or the `env = ...` part in `#[ink::contract(env = crate::Environment)]`) will reveal related usage documentation for the ink! attribute macro or specific ink! attribute argument in a popup. +Hovering over an ink! attribute macro (e.g. `#[ink::contract]`) or argument (e.g. `#[ink(storage)]` or the `env = ...` +part in `#[ink::contract(env = crate::Environment)]`) will reveal related usage documentation for the +ink! attribute macro or specific ink! attribute argument in a popup. ### 5. Code Actions ![contract `mod` code action](/images/screenshots/code-action.png 'contract `mod` code action') -Positioning the cursor either on an ink! attribute (e.g. on an `#[ink::contract]`) or on the "declaration" (e.g. anywhere on the line `pub mod flipper {` but not inside the body) of a Rust item that is either already annotated with ink! attributes or can be annotated with ink! attributes (e.g. `mod`, `struct`, `fn`, `impl` e.t.c) will trigger a "light bulb" with relevant code actions. +Positioning the cursor either on an ink! attribute (e.g. on an `#[ink::contract]`) or on the "declaration" +(e.g. anywhere on the line `pub mod flipper {` but not inside the body) of a Rust item that is either already annotated +with ink! attributes or can be annotated with ink! attributes (e.g. `mod`, `struct`, `fn`, `impl` e.t.c) will trigger +a "light bulb" with relevant code actions. **Testing examples:** -- Positioning the cursor on an ink! attribute (e.g. on `#[ink::contract]`) will trigger a "light bulb" with code actions for adding complementary arguments (if any) to the ink! attribute (i.e. `env` and `keep_attr` for `#[ink(contract)]` or `payable`, `default` and `selector` for `#[ink(message)]`). -- Positioning the cursor on the "declaration" of a Rust item without any other ink! attributes but whose item kind can be annotated with ink! attributes (e.g. `mod`, `struct`, `fn`, `impl` e.t.c) will trigger a "light bulb" with code actions for adding relevant ink! attributes depending on the context (e.g. `Add ink! message attribute` for an `fn` item). -- Positioning the cursor on the ink! contract `mod` item "declaration" (i.e. on the line `pub mod flipper {`) will trigger a "light bulb" with code actions for adding an `ink! event "struct"`, `ink! message "fn"` or `ink! constructor "fn"` to the ink! contract. -- After inserting an ink! event (e.g. use code action described above), positioning the cursor on the ink! event `struct` item "declaration" (i.e. on the line `pub struct MyFlipperEvent {`) will trigger a "light bulb" with code actions for adding an `ink! topic "field"`. -- Positioning the cursor on the item "declaration" of a "test" `mod` (i.e. a `mod` annotated with `#[cfg(test)]` or similar e.g. on the line `mod tests {`) will trigger a "light bulb" with code actions for adding an `ink! test "fn"` to the `mod` item. -- Positioning the cursor on the item "declaration" of a "test" `mod` with an additional `e2e-tests` feature condition (i.e. a `mod` annotated with `#[cfg(all(test, feature = "e2e-tests"))]` or similar e.g. on the line `mod e2e_tests {`) will trigger a "light bulb" with code actions for adding an `ink! e2e test "fn"` to the `mod` item. -- Positioning the cursor on the "declaration" of a Rust item with multiple ink! attributes (e.g. `#[ink(event)]\n#[ink(anonymous)]` e.t.c) will trigger a "light bulb" with code actions for "flattening" the ink! attributes. -- For VS Code version 1.86 or newer, you can enable code actions on empty lines by setting the `Editor › Lightbulb: Enabled` setting to `on` (See [this guide](https://code.visualstudio.com/docs/getstarted/settings) for details - the equivalent entry for `settings.json` is `"editor.lightbulb.enabled" = "on"`), with this setting enabled, positioning the cursor on an empty line will trigger a "light bulb" with code actions for inserting relevant ink! entities for the context (e.g. placing the cursor on the new line between `#![cfg_attr(not(feature = "std"), no_std, no_main)]` and `#[ink::contract]` trigger a "light bulb" with code actions for adding an ink! trait definition, ink! chain extension, ink! storage item or a custom ink! environment at the cursor position). - **NOTE:** Alternatively, to trigger code actions on empty lines without changing the above setting (or on versions of VS Code older than 1.86), you can right-click at the empty line position, and then select `Refactor` from the subsequent context menu to reveal the equivalent code actions. +- Positioning the cursor on an ink! attribute (e.g. on `#[ink::contract]`) will trigger a "light bulb" with code actions + for adding complementary arguments (if any) to the ink! attribute (i.e. `env` and `keep_attr` for `#[ink(contract)]` + or `payable`, `default` and `selector` for `#[ink(message)]`). +- Positioning the cursor on the "declaration" of a Rust item without any other ink! attributes but whose item kind + can be annotated with ink! attributes (e.g. `mod`, `struct`, `fn`, `impl` e.t.c) will trigger a "light bulb" with + code actions for adding relevant ink! attributes depending on the context + (e.g. `Add ink! message attribute` for an `fn` item). +- Positioning the cursor on the ink! contract `mod` item "declaration" (i.e. on the line `pub mod flipper {`) will + trigger a "light bulb" with code actions for adding an `ink! event "struct"`, `ink! message "fn"` or + `ink! constructor "fn"` to the ink! contract. +- After inserting an ink! event (e.g. use code action described above), positioning the cursor on the + ink! event `struct` item "declaration" (i.e. on the line `pub struct MyFlipperEvent {`) will trigger a "light bulb" + with code actions for adding an `ink! topic "field"`. +- Positioning the cursor on the item "declaration" of a "test" `mod` (i.e. a `mod` annotated with `#[cfg(test)]` or + similar e.g. on the line `mod tests {`) will trigger a "light bulb" with code actions for adding an `ink! test "fn"` + to the `mod` item. +- Positioning the cursor on the item "declaration" of a "test" `mod` with an additional `e2e-tests` feature condition + (i.e. a `mod` annotated with `#[cfg(all(test, feature = "e2e-tests"))]` or similar e.g. on the line `mod e2e_tests {`) + will trigger a "light bulb" with code actions for adding an `ink! e2e test "fn"` to the `mod` item. +- Positioning the cursor on the "declaration" of a Rust item with multiple ink! attributes + (e.g. `#[ink(event)]\n#[ink(anonymous)]` e.t.c) will trigger a "light bulb" with code actions for + "flattening" the ink! attributes. +- For VS Code version 1.86 or newer, you can enable code actions on empty lines by changing the + `Editor › Lightbulb: Enabled` setting to `on` (See [this guide](https://code.visualstudio.com/docs/getstarted/settings) + for details - the equivalent entry for `settings.json` is `"editor.lightbulb.enabled" = "on"`), + with this setting enabled, positioning the cursor on an empty line will trigger a "light bulb" with code actions for + inserting relevant ink! entities for the context (e.g. placing the cursor on the new line between + `#![cfg_attr(not(feature = "std"), no_std, no_main)]` and `#[ink::contract]` trigger a "light bulb" with code actions + for adding an ink! trait definition, ink! chain extension, ink! storage item or a custom ink! environment + at the cursor position). + **NOTE:** Alternatively, to trigger code actions on empty lines without changing the above setting + (or on versions of VS Code older than 1.86), you can right-click at the empty line position, + and then select `Refactor` from the subsequent context menu to reveal the equivalent code actions. ### 6. Inlay Hints ![`env: impl Environment` inlay hint](/images/screenshots/inlay-hint.png '`env: impl Environment` inlay hint') -ink! attribute arguments that are expected to have values (e.g. `selector`, `env`, `keep_attr`, `namespace`, `extension`, `handle_status`, `derive` e.t.c) will have inlay hints (additional inline information) about the type of the expected value added right after the `name` part of the `name=value` pair (e.g. `: u32 | _` for `selector`, `: impl Environment` for `env` and `: bool` for `handle_status`). +ink! attribute arguments that are expected to have values +(e.g. `selector`, `env`, `keep_attr`, `namespace`, `extension`, `handle_status`, `derive` e.t.c) +will have inlay hints (additional inline information) about the type of the expected value added right after +the `name` part of the `name=value` pair (e.g. `: u32 | _` for `selector`, `: impl Environment` for `env`, +and `: bool` for `handle_status`). ### 7. Signature Help ![`message` signature help](/images/screenshots/signature-help-3.png '`message` signature help') -When adding ink! attribute arguments (e.g. "primary" like `storage`, `event`, `constructor`, `message` e.t.c or "complementary"/"additional" like `env`, `keep_attr`, `payable`, `selector`, `anonymous` e.t.c), a popup with additional information about the "signature" for the ink! attribute and a description about the current argument can be triggered either automatically after typing the opening parenthesis (`(`) character or a comma (`,`) separator character, or manually by hitting `Cmd/Ctrl + Shift + Space`. +When adding ink! attribute arguments (e.g. "primary" like `storage`, `event`, `constructor`, `message` e.t.c or +"complementary"/"additional" like `env`, `keep_attr`, `payable`, `selector`, `anonymous` e.t.c), +a popup with additional information about the "signature" for the ink! attribute and a description about +the current argument can be triggered either automatically after typing the opening parenthesis +(`(`) character or a comma (`,`) separator character, or manually by hitting `Cmd/Ctrl + Shift + Space`. diff --git a/src/manager.ts b/src/manager.ts index e6d1e2c..502df9a 100644 --- a/src/manager.ts +++ b/src/manager.ts @@ -85,8 +85,9 @@ export default class ExtensionManager { // Shows error message if server binary is missing. const message = 'No ink! Language Server binary found.\n\n' + - 'Please follow [these instructions](https://github.com/ink-analyzer/ink-analyzer/tree/master/crates/lsp-server#installation) to install the ink! Language Server.\n\n' + - 'Then set `ink-analyzer.server.path` in your extension settings to the path to the installed executable binary.'; + 'Please follow [these instructions](https://github.com/ink-analyzer/ink-analyzer/tree/master/crates/lsp-server#installation)' + + ' to install the ink! Language Server.\n\n' + + 'Then set `ink-analyzer.server.path` in your settings to the path to the installed executable binary.'; vscode.window.showErrorMessage(message, 'Got it'); // Update state with error details. @@ -167,7 +168,8 @@ export default class ExtensionManager { async restart() { // Stop and dispose existing client. - // We dispose the existing client because user may be restarting because some settings have changed (e.g. the language server path). + // We dispose the existing client because user may be restarting because some settings have changed + // (e.g. the language server path). if (this.client) { await this.client?.stop(); await this.client.dispose(); diff --git a/src/middleware.ts b/src/middleware.ts index cbbf220..0aa869d 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -3,7 +3,7 @@ import * as lsp_types from 'vscode-languageclient/node'; import * as snippets from './snippets'; -// Code Actions middleware that adds support for snippets (tab stops and/or placeholders) in text edits returned by code actions. +// Code Actions middleware that adds support for snippets (tab stops and/or placeholders) in text edits in code actions. // LSP (v3.17) only supports snippets in completions. // Ref: https://github.com/microsoft/language-server-protocol/issues/592 // Ref: https://github.com/microsoft/language-server-protocol/issues/724 diff --git a/src/services.ts b/src/services.ts index 5831d17..11a0ad8 100644 --- a/src/services.ts +++ b/src/services.ts @@ -45,8 +45,8 @@ export async function initializeProject(client: lsp_types.LanguageClient, manage // Delete placeholder activation file if request is successful. fs.unlinkSync(path.join(projectPath, NEW_PROJECT_ACTIVATION_FILE)); - // This is a hack to save the workspace edit (VS Code doesn't do this automatically) - // that the language server sends in response to a successful request. + // This is a hack to save the workspace edit that the language server sends in response to a successful request + // (VS Code doesn't do this automatically). // Ref: https://github.com/microsoft/vscode-languageserver-node/issues/1272 // Ref: https://github.com/microsoft/vscode-languageserver-node/pull/1273 // FIXME: Remove this and intercept and save workspace edits in middleware when `middleware.workspace.handleApplyEdit` ships. diff --git a/src/snippets.ts b/src/snippets.ts index 3523c21..45b92f7 100644 --- a/src/snippets.ts +++ b/src/snippets.ts @@ -73,7 +73,7 @@ export function tokenize(snippet: string): SnippetToken[] { return snippetTokens; } -// Parses snippet text (if any) into a `vscode.SnippetString` if and only if it has at least one tab stop or placeholder. +// Parses snippet text (if any) into a `vscode.SnippetString` if it has at least one tab stop or placeholder. // Ref: https://code.visualstudio.com/docs/editor/userdefinedsnippets#_snippet-syntax export function parse(text: string, indentingConfig?: IndentingConfig): vscode.SnippetString | undefined { const tokens = tokenize(text); @@ -132,9 +132,10 @@ type IndentingConfig = { prevCharacter?: string; }; -// Determines whether, indenting/formatting for snippets needs to be "de-normalized" based on the snippet, text document and an insert position. -// "De-normalizing" of indenting/formatting is necessary because VS Code "normalizes" whitespace/indenting for snippet edits -// by auto inserting extra whitespace/indenting after new lines (this behaviour can't be disabled). +// Determines whether, indenting/formatting for snippets needs to be "de-normalized" based on the snippet, +// text document and an insert position. +// "De-normalizing" of indenting/formatting is necessary because VS Code "normalizes" whitespace/indenting +// for snippet edits by auto inserting extra whitespace/indenting after new lines (this behaviour can't be disabled). // So we remove either top-level or one level of indenting (i.e. tabs and spaces after new lines) on all lines, // and let VSCode handle the indenting/formatting. // Ref: https://github.com/microsoft/vscode/issues/145374#issuecomment-1255322331 diff --git a/src/test/suite/diagnostics.test.ts b/src/test/suite/diagnostics.test.ts index ac31aaa..3228d9d 100644 --- a/src/test/suite/diagnostics.test.ts +++ b/src/test/suite/diagnostics.test.ts @@ -22,7 +22,8 @@ const DIAGNOSTICS_TESTS: Array = [ name: 'missing `#[ink::contract]`', // Removes `#[ink::contract]`. edits: [{ text: '', startPos: [2, 0], endPos: [2, 17] }], - // Expects 10 diagnostic errors/warnings (i.e 1 storage, 2 events, 1 constructor and 6 messages without a contract parent). + // Expects 10 diagnostic errors/warnings + // (i.e 1 storage, 2 events, 1 constructor and 6 messages without a contract parent). results: 10, }, {