A language server implementation for the WGSL shading language

Overview

wgsl-analyzer

wgsl-analyzer is a language server plugin for the WGSL Shading language.

It comes with a VS Code plugin located in ./editors/code, but due to the nature of the language server protocol it should be possible to create plugins for other editors as well.

Installation (VS Code)

The extension is published on the marketplace, so you can simply download the extension like any other.

If you are not using a platform for which the vscode extension ships prebuilt binaries (currently only windows-x64, linux-x64 and macos-x64), then you need to compile the language server yourself:

cargo install --git https://github.com/wgsl-analyzer/wgsl-analyzer wgsl_analyzer

Specify the server path in the settings:

{
    "wgsl-analyzer.server.path": "~/.cargo/bin/wgsl_analyzer"
}

Building from source

The lsp server can be built using cargo build --release -p wgsl_analyzer.

The vscode extension can either be built as a platform-specific extension which bundles the language server binary, or as a platform-independant one.

Platform independant extension:

cd editors/code && npm run package

Platform-specific extension:

Copy the server binary (either wgsl_analyzer or wgsl_analyzer.exe) to ./editors/code/out, the run npm run package -- --target -o wgsl_analyzer- .vsix where the target is one of the targets listed as platform-specific extension targets.

Design

The design is heavily inspired (and in large parts copied from) rust-analyzer. See rust-analyzer/docs/dev/architecture.md for a summary of the architecture.

Comments
  • textureLoad does not allows texture_multisampled_2d

    textureLoad does not allows texture_multisampled_2d

    no overload of `textureLoad` found for given arguments. Found (texture_2d_multisampled<f32>, vec2<i32>, i32), expected one of:
    fn(texture_1d<T>, i32, i32) -> vec4<T>
    fn(texture_2d<T>, vec2<i32>, i32) -> vec4<T>
    fn(texture_2d_array<T>, vec2<i32>, i32, i32) -> vec4<T>
    fn(texture_3d<T>, vec3<i32>, i32) -> vec4<T>
    fn(texture_2d_multisampled_array<T>, vec2<i32>, i32) -> vec4<T>
    fn(texture_depth_2d, vec2<i32>, i32) -> f32
    fn(texture_depth_2d_array, vec2<i32>, i32, i32) -> f32
    fn(texture_depth_2d_multisampled, vec2<i32>, i32) -> f32
    fn(texture_external, vec2<i32>) -> vec4<f32>
    fn(texture_storage_1d<F,read>, i32) -> F::StorageType
    fn(texture_storage_2d<F,read>, vec2<i32>) -> F::StorageType
    fn(texture_storage_2d_array<F,read>, vec2<i32>, i32) -> F::StorageType
    fn(texture_storage_3d<F,read>, vec3<i32>) -> F::StorageType
    
    opened by IcanDivideBy0 16
  • Support #import syntax in fragment and vertex input

    Support #import syntax in fragment and vertex input

    Bevy started using #import statements directly in the fragment shader input. This currently breaks wgsl-analyzer, both the formatter and the linter.

    For example:

    @fragment
    fn fragment(
        #import bevy_pbr::mesh_vertex_output
    ) -> @location(0) vec4<f32> {
        return material.color * textureSample(base_color_texture, base_color_sampler, uv);
    }
    

    from: https://github.com/bevyengine/bevy/blob/main/assets/shaders/custom_material.wgsl

    opened by IceSentry 7
  • Array syntax does not allow for unbounded declarations in structs

    Array syntax does not allow for unbounded declarations in structs

    Storage buffers require structs to be defined without declared bounds for arrays, e.g.

    struct PositionsBuffer {
      // TODO: runtime-sized array syntax may have changed
      pos: array<vec2<f32>>;
    };
    // A storage buffer, for reading and writing
    [[group(0), binding(0)]]
    var<storage,read_write> pbuf: PositionsBuffer;
    

    The parser doesn't allow this and errors with expected LessThan, Comma, GreaterThan or Ident, but found ShiftRight at the array declaration.

    opened by iamseb 4
  • Running cargo install for wgsl analyzer fails to compile

    Running cargo install for wgsl analyzer fails to compile

    So i use neovim/helix, and i wanted to install this LSP. So i copy the command: cargo install --git https://github.com/wgsl-analyzer/wgsl-analyzer wgsl_analyzer into my terminal, and it compiles mostly everything, but then i run into an error: '"Let...else" statements are unstable' then it tells me it could not compile 'hir' due to previous error.

    Has anyone else encountered this issue? I have cargo installed, I'm on windows 11.

    opened by tastetest 2
  • build fails compiling hir

    build fails compiling hir

       Compiling hir v0.0.0 (/Users/lee/.cargo/git/checkouts/wgsl-analyzer-78f816c0d319358c/73a7553/crates/hir)
    error[E0658]: `let...else` statements are unstable
      --> crates/hir/src/diagnostics/precedence.rs:18:9
       |
    18 | /         let hir_def::expr::Expr::BinaryOp { op, lhs, rhs } = expr
    19 | |         else {
    20 | |             continue;
    21 | |         };
       | |__________^
       |
       = n
    

    building on macos

    opened by mighdoll 2
  • Add proper support for type constructors

    Add proper support for type constructors

    Because a type constructor can be a builtin type or a type alias, properly handle that case. Also avoid improperly parsing (valid_function)(), which is an error in the spec.

    I used builtins for the new constructors/conversions, to allow easy maintenance.

    This also incidentally adds a couple of one line changes where our handling of references wasn't quite right. With this PR and #52, we can fully support https://github.com/linebender/piet-gpu's new wgsl pipeline

    opened by DJMcNab 2
  • Very high memory usage when autocompleting function arguments

    Very high memory usage when autocompleting function arguments

    When wgsl-analyzer tries to autocomplete an argument to the main function of a fragment shader, the wgsl_analyzer binary consumes all available memory (around 15G on my system) and locks up. It could also be caused when there is invalid syntax in the function declaration.

    For instance, it happens when I have the following code, and I start adding an argument to the fs_main function:

    [[stage(fragment)]]
    fn fs_main(...) -> [[location(0)]] vec4<f32> {
        return vec4<f32>(0.4, 0.2, 0.9, 1.0);
    }
    

    I have trace information for the wgsl-analyzer extension turned on in my VSCode workspace settings with

    "wgsl-analyzer.trace.extension": true,
    "wgsl-analyzer.trace.server": true
    

    However, I don't seem to get any errors in the output panel, expect when I kill the wgsl_analyzer process and see:

    WGSL-Analyzer: LSP request failed{"method":"experimental/inlayHints","param":{"textDocument":{"uri":"file:///home/dieff/Workspace/wgpu/basic/src/shader.wgsl"},"range":{"start":{"line":0,"character":0},"end":{"line":23,"character":0}}},"error":{}}
    

    I'm using the following: wgsl_analyzer binary: built fresh from master with Rust 1.60.0 VSCode: 1.66.1 VSCode Extension: 0.4.3 from the extension marketplace uname -a: Linux hex2-desktop 5.17.1 NixOS SMP PREEMPT Mon Mar 28 08:03:22 UTC 2022 x86_64 GNU/Linux

    opened by Dieff 2
  • Support type aliasing

    Support type aliasing

    Got to admit, I don't understand all of this, but it seems to work now :)

    image

    I did the alias "unwrapping" inside expect_ty_inner... maybe it would be better to do it some earlier point?

    • [ ] resolve TODO comments
    opened by johanhelsing 2
  • Nvim configuration

    Nvim configuration

    I tried to add wgsl_analyser to my nvim config, but got an error with fairly correct configuration.

    [lspconfig] Spawning server with cmd: '$HOME/.cargo/bin/wgsl_analyzer' failed. 1The language server is either not installed, missing from PATH, or not executable.
    

    init.lua

    
    local lspconfig = require("lspconfig")
    local configs = require("lspconfig.configs")
    
    if not configs.wgsl_analyzer then
    	configs.wgsl_analyzer = {
    		default_config = {
    			cmd = { "$HOME/.cargo/bin/wgsl_analyzer" },
    			filetypes = { "wgsl" },
    			root_dir = lspconfig.util.root_pattern(".git", "wgsl"),
    			settings = {},
    		},
    	}
    end
    
    lspconfig.wgsl_analyzer.setup({
    	on_attach = lsp_opts.on_attach,
    	capabilities = lsp_opts.capabilities,
    })
    

    Maybe I should pass arguments to the cmd?

    opened by pudnax 2
  • CRITICAL: Properly report that we don't support non-`file` schemed paths

    CRITICAL: Properly report that we don't support non-`file` schemed paths

    Without this, when viewing a file in the diff editor, we appear to overwrite our in-memory file contents with the LHS of the editor (generally the old version). This is very bad; when you perform an edit, this means the change gets applied as-if it were on the wrong version of the file. This means that running formatting after applying this edit does bad things to your document.

    If you run into this bug, the current fix is to close the file, then re-open the file (then run the standard undo command (i.e. CTRL + Z).

    This PR implements a hack to make this failure mode less likely to occur; it should be sufficient for now. In future, we should properly handle different schemes. An observation along these lines is that for our project model, all paths provided by the LSP can be treated as entirely opaque. This makes things implementing this properly much easier.

    I can confirm that normal operations still work with this change, and I can no longer reproduce the original bug.

    @jakobhellermann I think this should probably land quite quickly, as there's a significant risk of data loss here.

    opened by DJMcNab 1
  • Add a diagnostic for precedence issues

    Add a diagnostic for precedence issues

    See also https://github.com/linebender/piet-gpu/pull/203/commits/5bd3a3639f783e3fb677ec3cace14766aaa78006 and https://github.com/gfx-rs/naga/issues/2098

    I first tried to address this in naga, but got a bit lost in their code. I think having this be a diagnostic rather than a parsing error does make some amount of sense (and I couldn't work out how to neatly make it a parsing error); the cases are somewhat disjointed, so implementing this at the parsing layer is awkward

    See also https://github.com/gpuweb/gpuweb/issues/1146#issuecomment-714721825 (linked in the code)

    opened by DJMcNab 1
  • Missing some diagnostics and inlay hints in Neovim lsp

    Missing some diagnostics and inlay hints in Neovim lsp

    As I understand each editor renders inlay hints differently and I need to handle it like rust-tools does it.

    Also I noticed that in default configuration compared to vs code missing diagnostics like incompatible function arguments and unknown variables. Enabling more diagnostics(nagaParsing, nagaValidation) changes nothing.

    [ERROR][2022-12-09 15:20:14] .../vim/lsp/rpc.lua:733	"rpc"	"wgsl_analyzer"	"stderr"	"2022-12-09T09:20:14.692543Z  INFO wgsl_analyzer: Initialized\n"
    [WARN][2022-12-09 15:20:14] .../lua/vim/lsp.lua:1065	"server_request: no handler found for"	"wgsl-analyzer/requestConfiguration"
    [WARN][2022-12-09 15:20:14] .../lua/vim/lsp.lua:1065	"server_request: no handler found for"	"wgsl-analyzer/requestConfiguration"
    [ERROR][2022-12-09 15:20:14] .../vim/lsp/rpc.lua:733	"rpc"	"wgsl_analyzer"	"stderr"	'2022-12-09T09:20:14.697209Z ERROR wgsl_analyzer::main_loop: Failed to fetch the server settings: ResponseError { code: -32601, message: "MethodNotFound", data: None }\n2022-12-09T09:20:14.697307Z ERROR wgsl_analyzer::main_loop: Failed to fetch the server settings: ResponseError { code: -32601, message: "MethodNotFound", data: None }\n'
    

    LSP itself is working

     Detected filetype:   wgsl
     
     1 client(s) attached to this buffer: 
     
     Client: wgsl_analyzer (id: 1, pid: nil, bufnr: [1])
     	filetypes:       wgsl
     	autostart:       true
     	root directory:  /home/komm/Work/Rust/pilka
     	cmd:             wgsl_analyzer
    
    opened by pudnax 0
  • Block comment being parsed as error.

    Block comment being parsed as error.

    Installed with mason on neovim. tag=v0.6.0#17abe2df93ff75fc496a9641e2f37ae6d302f07a Normal comments with // works fine. However, block comments with /* */ shows error expected Fn, Struct, Var, blah, blah ....

    At first I thought maybe this was problem with nvim-treesitter which formats code but after removing treesitter config lsp still showed the error.

    I was going to ask on tracker issue whether this is yet to implement feature or what but didn't see anything related to comments.

    [EDIT] I'm not sure if this is analyzer problem or not but since its related to lsp I came here.

    shot

    opened by autofool 0
  • Not Able to Find Type Definitions in Function-only #import

    Not Able to Find Type Definitions in Function-only #import

    Version: 0.5.3 System: Ubuntu 20.04.5 LTS

    In the screenshot, type Sample is defined in bevy_hikari::reservoir_types, which is included in bevy_hikari::reservoir_bindings above. But the checker cannot find the type in the scope and report as an error, and not be able to give useful lints about any functions defined in bevy_hikari::reservoir_functions.

    Screenshot 2022-11-11 04:57:02

    opened by cryscan 0
  • Parser hangs on particular `switch`

    Parser hangs on particular `switch`

    Create or open a .wgsl file that contains the following contents:

    fn foo() {
        switch bar() {
            case 2 {
                return;
            }
        }
    }
    

    The language server then hangs, using 100% of one core. The return inside of a case (not default) seems to be necessary for this to happen.

    Platform: macOS wgsl-analyzer extension version: v0.5.0 from the Visual Studio Marketplace

    Stack of the one thread that's not waiting on a lock:

    Thread_3618378
    thread_start  (in libsystem_pthread.dylib) + 15  [0x7ff816c19f6b]
    _pthread_start  (in libsystem_pthread.dylib) + 125  [0x7ff816c1e4e1]
    std::sys::unix::thread::Thread::new::thread_start::hf7c5ae502e9a7ed8  (in wgsl_analyzer) + 39  [0x10cf4ba77]
    core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h41e079531fd114d4  (in wgsl_analyzer) + 117  [0x10cc09745]
    std::sys_common::backtrace::__rust_begin_short_backtrace::he55594ae8ab29083  (in wgsl_analyzer) + 243  [0x10cc09ec3]
    _$LT$F$u20$as$u20$threadpool..FnBox$GT$::call_box::h952c18c157544748  (in wgsl_analyzer) + 156  [0x10cbbb08c]
    alloc::vec::in_place_collect::_$LT$impl$u20$alloc..vec..spec_from_iter..SpecFromIter$LT$T$C$I$GT$$u20$for$u20$alloc..vec..Vec$LT$T$GT$$GT$::from_iter::h53ae295f712095ec  (in wgsl_analyzer) + 92  [0x10cbb7b2c]
    _$LT$core..iter..adapters..filter_map..FilterMap$LT$I$C$F$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$::next::h2b5fa11a8664d474  (in wgsl_analyzer) + 116  [0x10cbb3f54]
    wgsl_analyzer::handlers::publish_diagnostics::h48ce7736f513300e  (in wgsl_analyzer) + 103  [0x10cbc0997]
    ide::Analysis::diagnostics::h4963cf8f69fd57ad  (in wgsl_analyzer) + 40  [0x10cc1c3b8]
    salsa::Cancelled::catch::h6cfefdc0ff4643e9  (in wgsl_analyzer) + 46  [0x10cc3107e]
    ide::diagnostics::diagnostics::h285d1f187b5d84ab  (in wgsl_analyzer) + 64  [0x10cc2dd20]
    _$LT$DB$u20$as$u20$base_db..SourceDatabase$GT$::parse_with_unconfigured::h01ae270dff6cb0ac  (in wgsl_analyzer) + 23  [0x10cc2fc37]
    _$LT$DB$u20$as$u20$base_db..SourceDatabase$GT$::parse_with_unconfigured::__shim::h135e49c671022b76  (in wgsl_analyzer) + 79  [0x10ce5ebff]
    _$LT$salsa..derived..DerivedStorage$LT$Q$C$MP$GT$$u20$as$u20$salsa..plumbing..QueryStorageOps$LT$Q$GT$$GT$::try_fetch::hf6d7b9a97d53b7df  (in wgsl_analyzer) + 683  [0x10ce6c2ab]
    salsa::derived::slot::Slot$LT$Q$C$MP$GT$::read::h08f08bce97bbd1ae  (in wgsl_analyzer) + 978  [0x10ce562b2]
    salsa::derived::slot::Slot$LT$Q$C$MP$GT$::read_upgrade::hd850f526280525fd  (in wgsl_analyzer) + 2717  [0x10ce4ff1d]
    salsa::runtime::Runtime::execute_query_implementation::hfe81e01d70cd166f  (in wgsl_analyzer) + 386  [0x10ce785b2]
    _$LT$base_db..ParseWithUnconfiguredQuery$u20$as$u20$salsa..plumbing..QueryFunction$GT$::execute::h3dd313f8cda08df0  (in wgsl_analyzer) + 208  [0x10ce5f010]
    syntax::parse_entrypoint::h42c8674a0ccd309d  (in wgsl_analyzer) + 28  [0x10ce864dc]
    wgsl_parser::parse_entrypoint::h0f8ae45d2397d797  (in wgsl_analyzer) + 36  [0x10ce97d44]
    parser::parse::h5f728cf8e7ad3516  (in wgsl_analyzer) + 191  [0x10ce9b2ff]
    wgsl_parser::grammar::file::hc1f42db4eb337018  (in wgsl_analyzer) + 9253  [0x10ce88b65]
    wgsl_parser::grammar::compound_statement::h77c34d044ee9453f  (in wgsl_analyzer) + 399  [0x10ce8b71f]
    wgsl_parser::grammar::statement::h563327540f460b5a  (in wgsl_analyzer) + 3243,3557,...  [0x10ce8c55b,0x10ce8c695,...]
    
    opened by kpreid 0
Releases(v0.6.0)
Owner
null
The SATySFi Language Server

[WIP] SATySFi Language Server This repository is work-in-progress yet. Features Kind Function Done codeAction Add the definition of an undefined comma

monaqa 50 Dec 24, 2022
A language server for lua written in rust

lua-analyzer lua-analyzer is a lsp server for lua. This is mostly for me to learn the lsp protocol and language analysis so suggestions are helpful. T

null 61 Dec 11, 2022
Erlang Language Platform. LSP server and CLI.

Erlang Language Platform (ELP) Description ELP integrates Erlang into modern IDEs via the language server protocol. ELP was inspired by rust-analyzer.

WhatsApp 31 Aug 7, 2023
RusTiny -- A Rust implementation of Tiny+ language

RusTiny -- A Rust implementation of Tiny+ language 编译器实践 基本要求: 参考《编译原理及实践》的TINY语言编译器(已上传到群中)完成TINY+ 语言(见附录 A)的解释器:即给定满足 TINY+语言的源代码输入,你的解 释器可以给出对其的解释执

M4tsuri 2 May 22, 2022
rlox-interpreter is an AST-walking implementation of Bob Nystrom's Lox language in Rust.

rlox-interpreter rlox-interpreter is an AST-walking implementation of Bob Nystrom's Lox language in Rust. Disclaimer: This is my first Rust project, d

Paul Fedorow 3 Oct 5, 2022
Locast to Emby/Plex/Channels server

This application provides an interface between locast.org and Media Servers like Plex Media Server (PMS) and Emby by acting like an HDHomerun or an m3u tuner and an XMLTV provider.

Wouter de Bie 51 Sep 10, 2022
Björn - The AS207960 ACME server

Björn - The AS207960 ACME server Björn is not a full CA upon to itself, but contains many of the building blocks of a complete ACME CA. Components Bjö

AS207960 / Glauca 5 Feb 17, 2022
Rust 版本的 UnblockNeteaseMusic/server ,以效能、穩定性及可維護性為目標。

【開發中】unm-server-rust Rust 版本的 UnblockNeteaseMusic/server ,以效能、穩定性及可維護性為目標。 安裝 最新版本 下載二進位檔案 前往 Actions 分頁找到 “Build binaries for UNM“,點開後可從 Artifacts 中

Unblock Netease Music 维护小组 123 Dec 26, 2022
Automatically download minecraft server jars in one line

MCDL Automatically download minecraft server jars in one line (or one click) Installation Download (Windows, Linux) Install via cargo: cargo install m

Isaac Hirschfeld 1 Oct 26, 2021
Unofficial Bitwarden compatible server written in Rust, formerly known as bitwarden_rs

Alternative implementation of the Bitwarden server API written in Rust and compatible with upstream Bitwarden clients*, perfect for self-hosted deploy

Daniel García 21.5k Jan 8, 2023
Axum server starter template

Axum Starter Template A template to get started with Axum Features Tracing and bunyan formatting SQLx support (with testing) Server as library Example

Jordan 2 Jan 15, 2022
A small in-house bot of the TTC Discord Server

Welcome to The Terminal cafe Support Bot Repository Hello, hope you are having a nice day. This is the official repository for The Terminal Cafe Suppo

null 5 Jul 4, 2022
Lightweight tool for simple deployment (server+client)

deploy Lightweight tool for simple deployment (server+client) Usage You first need a key value pair: deploy generate-keys Public-Key: Used on the serv

Jan-Mirko Otter 0 Dec 27, 2021
A server to continously poll nearly always-on sites to verify that your internet connectivity stays up

Dead Router A server to continously poll nearly always-on sites to verify that your internet connectivity stays up! If one or more of the servers stop

null 0 Feb 5, 2022
Proxmox Backup Server and Client

Build & Release Notes rustup Toolchain We normally want to build with the rustc Debian package. To do that you can set the following rustup configurat

Read-Only Proxmox Projects Repository Clone. 26 Dec 26, 2022
xrd a next-gen server controller for TrackMania Forever and Nations ESWC

xrd is a next-gen server controller for TrackMania Forever and Nations ESWC that is designed to be hassle-free and easily updatable (with a bus factor of 0).

Autumn Leaf 6 Mar 26, 2022
The missing link to modern server controlling for TrackMania Forever.

xrd (XASeCo Replacing Daemon) xrd is a next-gen server controller for TrackMania Forever and Nations ESWC that is designed to be hassle-free and easil

Autumn Leaf 6 Mar 26, 2022
Basic ActivityPub Server (in Rust)

Basic ActivityPub Server (in Rust) This is a deep-dive on this blog post: https://blog.joinmastodon.org/2018/06/how-to-implement-a-basic-activitypub-s

Mat 10 Nov 24, 2022
A rust(serenity) based discord bot for the hacksquad discord server

A Discord Bot for Hacksquad How to Deploy? Requirements Docker Docker Compose Steps To Run Copy the docker-compose.yml and .env.example files to your

HackSquad 5 Jan 4, 2023