├── .editorconfig ├── .github └── workflows │ ├── ci.yaml │ └── netlify.yaml ├── .gitignore ├── README.md ├── bors.toml ├── ra-wasm ├── .cargo │ └── config ├── Cargo.lock ├── Cargo.toml └── src │ ├── lib.rs │ ├── return_types.rs │ └── to_proto.rs ├── rust-pack ├── Cargo.lock ├── Cargo.toml └── src │ ├── main.rs │ └── remove_function.rs ├── rust-toolchain ├── rustfmt.toml └── www ├── .gitignore ├── _headers ├── example-code.rs ├── index.css ├── index.js ├── package.json ├── ra-worker.js ├── rust-grammar.js ├── webpack.config.js └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 4 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [{package.json,*.yaml}] 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | pull_request: 4 | push: 5 | branches: 6 | - master 7 | - trying 8 | - staging 9 | 10 | env: 11 | CARGO_INCREMENTAL: 0 12 | CARGO_NET_RETRY: 10 13 | RUSTUP_MAX_RETRIES: 10 14 | 15 | jobs: 16 | rust: 17 | runs-on: ubuntu-latest 18 | 19 | steps: 20 | - name: Checkout repository 21 | uses: actions/checkout@v2 22 | 23 | - name: Install Rust toolchain 24 | uses: actions-rs/toolchain@v1 25 | with: 26 | toolchain: nightly-2021-11-02 27 | target: wasm32-unknown-unknown 28 | profile: minimal 29 | override: true 30 | components: rustfmt, rust-src 31 | 32 | - name: Install wasm-pack 33 | run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh 34 | 35 | - name: Setup Node 36 | uses: actions/setup-node@v2 37 | with: 38 | node-version: '15' 39 | 40 | - name: Build wasm 41 | run: | 42 | cd rust-pack 43 | cargo run 44 | cd ../ra-wasm 45 | wasm-pack build --target web 46 | 47 | - name: Install www 48 | uses: borales/actions-yarn@v2.0.0 49 | with: 50 | cmd: --cwd www --ignore-engines install # will run `yarn install` command 51 | 52 | - name: Build www 53 | uses: borales/actions-yarn@v2.0.0 54 | with: 55 | cmd: --cwd www --ignore-engines build # will run `yarn build` command 56 | -------------------------------------------------------------------------------- /.github/workflows/netlify.yaml: -------------------------------------------------------------------------------- 1 | name: netlify 2 | on: 3 | push: 4 | branches: 5 | - master 6 | 7 | env: 8 | CARGO_INCREMENTAL: 0 9 | CARGO_NET_RETRY: 10 10 | RUSTUP_MAX_RETRIES: 10 11 | 12 | jobs: 13 | netlify: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Checkout repository 18 | uses: actions/checkout@v2 19 | 20 | - name: Install Rust toolchain 21 | uses: actions-rs/toolchain@v1 22 | with: 23 | toolchain: nightly-2021-11-02 24 | target: wasm32-unknown-unknown 25 | profile: minimal 26 | override: true 27 | components: rustfmt, rust-src 28 | 29 | - name: Install wasm-pack 30 | run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh 31 | 32 | - name: Setup Node 33 | uses: actions/setup-node@v2 34 | with: 35 | node-version: '15' 36 | 37 | - name: Build wasm 38 | run: | 39 | cd rust-pack 40 | cargo run 41 | cd ../ra-wasm 42 | wasm-pack build --target web 43 | 44 | - name: Install www 45 | uses: borales/actions-yarn@v2.0.0 46 | with: 47 | cmd: --cwd www --ignore-engines install # will run `yarn install` command 48 | 49 | - name: Build www 50 | uses: borales/actions-yarn@v2.0.0 51 | with: 52 | cmd: --cwd www --ignore-engines build # will run `yarn build` command 53 | 54 | - name: Setup Netlify headers 55 | run: sudo cp ./www/_headers ./www/dist 56 | 57 | - name: Deploy production to Netlify 58 | uses: South-Paw/action-netlify-deploy@v1.2.0 59 | with: 60 | github-token: ${{ secrets.GITHUB_TOKEN }} 61 | netlify-auth-token: ${{ secrets.NETLIFY_AUTH_TOKEN }} 62 | netlify-site-id: ${{ secrets.NETLIFY_SITE_ID }} 63 | build-dir: './www/dist' -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle 2 | /vendor 3 | target 4 | /_site 5 | .sass-cache 6 | .jekyll-cache 7 | .vscode 8 | *.log -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WASM demo of rust-analyzer 2 | 3 | To run: 4 | 5 | ```shell 6 | $ cd rust-pack 7 | $ cargo run 8 | $ cd ../ra-wasm 9 | $ wasm-pack build --target web --profiling 10 | $ cd ../www 11 | $ yarn 12 | $ yarn start 13 | ``` 14 | -------------------------------------------------------------------------------- /bors.toml: -------------------------------------------------------------------------------- 1 | status = [ 2 | "rust", 3 | ] 4 | delete_merged_branches = true 5 | timeout_sec = 1200 # 20 min 6 | -------------------------------------------------------------------------------- /ra-wasm/.cargo/config: -------------------------------------------------------------------------------- 1 | [target.wasm32-unknown-unknown] 2 | rustflags = ["-C", "target-feature=+atomics,+bulk-memory,+mutable-globals"] 3 | 4 | [unstable] 5 | build-std = ["panic_abort", "std"] -------------------------------------------------------------------------------- /ra-wasm/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "always-assert" 7 | version = "0.1.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "fbf688625d06217d5b1bb0ea9d9c44a1635fd0ee3534466388d18203174f4d11" 10 | dependencies = [ 11 | "log", 12 | ] 13 | 14 | [[package]] 15 | name = "anymap" 16 | version = "0.12.1" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "33954243bd79057c2de7338850b85983a44588021f8a5fee574a8888c6de4344" 19 | 20 | [[package]] 21 | name = "arrayvec" 22 | version = "0.7.2" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" 25 | 26 | [[package]] 27 | name = "autocfg" 28 | version = "1.0.1" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" 31 | 32 | [[package]] 33 | name = "bitflags" 34 | version = "1.3.2" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 37 | 38 | [[package]] 39 | name = "bumpalo" 40 | version = "3.8.0" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" 43 | 44 | [[package]] 45 | name = "cc" 46 | version = "1.0.72" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" 49 | 50 | [[package]] 51 | name = "cfg-if" 52 | version = "1.0.0" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 55 | 56 | [[package]] 57 | name = "chalk-derive" 58 | version = "0.72.0" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | checksum = "50947a8c71b9a6ee75d6c3b74eb320f58668f872a5ca1347a2b664989fbc8ac8" 61 | dependencies = [ 62 | "proc-macro2", 63 | "quote", 64 | "syn", 65 | "synstructure", 66 | ] 67 | 68 | [[package]] 69 | name = "chalk-ir" 70 | version = "0.72.0" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "39fba0a2f05527fb93c5039803c1f1ffaff5d6cebdff936386e1a5cbe7646283" 73 | dependencies = [ 74 | "bitflags", 75 | "chalk-derive", 76 | "lazy_static", 77 | ] 78 | 79 | [[package]] 80 | name = "chalk-recursive" 81 | version = "0.72.0" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | checksum = "d01108bc48af1d40e69b3b7f6923323e904c32476d4974750c474c1f94343e5c" 84 | dependencies = [ 85 | "chalk-derive", 86 | "chalk-ir", 87 | "chalk-solve", 88 | "rustc-hash", 89 | "tracing", 90 | ] 91 | 92 | [[package]] 93 | name = "chalk-solve" 94 | version = "0.72.0" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "ff759b94bbb114254ba01b7a7459f8fa78ae98801a814946ce7ed6d5973c8a06" 97 | dependencies = [ 98 | "chalk-derive", 99 | "chalk-ir", 100 | "ena", 101 | "itertools", 102 | "petgraph", 103 | "rustc-hash", 104 | "tracing", 105 | ] 106 | 107 | [[package]] 108 | name = "console_error_panic_hook" 109 | version = "0.1.7" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" 112 | dependencies = [ 113 | "cfg-if", 114 | "wasm-bindgen", 115 | ] 116 | 117 | [[package]] 118 | name = "countme" 119 | version = "2.0.4" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "328b822bdcba4d4e402be8d9adb6eebf269f969f8eadef977a553ff3c4fbcb58" 122 | dependencies = [ 123 | "dashmap", 124 | "once_cell", 125 | "rustc-hash", 126 | ] 127 | 128 | [[package]] 129 | name = "cov-mark" 130 | version = "2.0.0-pre.1" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | checksum = "0d48d8f76bd9331f19fe2aaf3821a9f9fb32c3963e1e3d6ce82a8c09cef7444a" 133 | 134 | [[package]] 135 | name = "crossbeam-channel" 136 | version = "0.5.1" 137 | source = "registry+https://github.com/rust-lang/crates.io-index" 138 | checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" 139 | dependencies = [ 140 | "cfg-if", 141 | "crossbeam-utils", 142 | ] 143 | 144 | [[package]] 145 | name = "crossbeam-deque" 146 | version = "0.8.1" 147 | source = "registry+https://github.com/rust-lang/crates.io-index" 148 | checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" 149 | dependencies = [ 150 | "cfg-if", 151 | "crossbeam-epoch", 152 | "crossbeam-utils", 153 | ] 154 | 155 | [[package]] 156 | name = "crossbeam-epoch" 157 | version = "0.9.5" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" 160 | dependencies = [ 161 | "cfg-if", 162 | "crossbeam-utils", 163 | "lazy_static", 164 | "memoffset", 165 | "scopeguard", 166 | ] 167 | 168 | [[package]] 169 | name = "crossbeam-utils" 170 | version = "0.8.5" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" 173 | dependencies = [ 174 | "cfg-if", 175 | "lazy_static", 176 | ] 177 | 178 | [[package]] 179 | name = "dashmap" 180 | version = "4.0.2" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c" 183 | dependencies = [ 184 | "cfg-if", 185 | "num_cpus", 186 | ] 187 | 188 | [[package]] 189 | name = "dissimilar" 190 | version = "1.0.3" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | checksum = "31ad93652f40969dead8d4bf897a41e9462095152eb21c56e5830537e41179dd" 193 | 194 | [[package]] 195 | name = "dot" 196 | version = "0.1.4" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | checksum = "a74b6c4d4a1cff5f454164363c16b72fa12463ca6b31f4b5f2035a65fa3d5906" 199 | 200 | [[package]] 201 | name = "drop_bomb" 202 | version = "0.1.5" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1" 205 | 206 | [[package]] 207 | name = "either" 208 | version = "1.6.1" 209 | source = "registry+https://github.com/rust-lang/crates.io-index" 210 | checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" 211 | 212 | [[package]] 213 | name = "ena" 214 | version = "0.14.0" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "d7402b94a93c24e742487327a7cd839dc9d36fec9de9fb25b09f2dae459f36c3" 217 | dependencies = [ 218 | "log", 219 | ] 220 | 221 | [[package]] 222 | name = "expect-test" 223 | version = "1.2.0-pre.1" 224 | source = "registry+https://github.com/rust-lang/crates.io-index" 225 | checksum = "3a2f1664bc69648747878bfe3430ad9b58bc8d9b50b3b1df9f3c081345e33197" 226 | dependencies = [ 227 | "dissimilar", 228 | "once_cell", 229 | ] 230 | 231 | [[package]] 232 | name = "fixedbitset" 233 | version = "0.2.0" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" 236 | 237 | [[package]] 238 | name = "fnv" 239 | version = "1.0.7" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 242 | 243 | [[package]] 244 | name = "form_urlencoded" 245 | version = "1.0.1" 246 | source = "registry+https://github.com/rust-lang/crates.io-index" 247 | checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" 248 | dependencies = [ 249 | "matches", 250 | "percent-encoding", 251 | ] 252 | 253 | [[package]] 254 | name = "fst" 255 | version = "0.4.7" 256 | source = "registry+https://github.com/rust-lang/crates.io-index" 257 | checksum = "7ab85b9b05e3978cc9a9cf8fea7f01b494e1a09ed3037e16ba39edc7a29eb61a" 258 | 259 | [[package]] 260 | name = "hashbrown" 261 | version = "0.11.2" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 264 | 265 | [[package]] 266 | name = "heck" 267 | version = "0.3.3" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" 270 | dependencies = [ 271 | "unicode-segmentation", 272 | ] 273 | 274 | [[package]] 275 | name = "hermit-abi" 276 | version = "0.1.19" 277 | source = "registry+https://github.com/rust-lang/crates.io-index" 278 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 279 | dependencies = [ 280 | "libc", 281 | ] 282 | 283 | [[package]] 284 | name = "idna" 285 | version = "0.2.3" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" 288 | dependencies = [ 289 | "matches", 290 | "unicode-bidi", 291 | "unicode-normalization", 292 | ] 293 | 294 | [[package]] 295 | name = "indexmap" 296 | version = "1.7.0" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" 299 | dependencies = [ 300 | "autocfg", 301 | "hashbrown", 302 | ] 303 | 304 | [[package]] 305 | name = "instant" 306 | version = "0.1.12" 307 | source = "registry+https://github.com/rust-lang/crates.io-index" 308 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 309 | dependencies = [ 310 | "cfg-if", 311 | "js-sys", 312 | "wasm-bindgen", 313 | "web-sys", 314 | ] 315 | 316 | [[package]] 317 | name = "itertools" 318 | version = "0.10.1" 319 | source = "registry+https://github.com/rust-lang/crates.io-index" 320 | checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" 321 | dependencies = [ 322 | "either", 323 | ] 324 | 325 | [[package]] 326 | name = "js-sys" 327 | version = "0.3.55" 328 | source = "registry+https://github.com/rust-lang/crates.io-index" 329 | checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" 330 | dependencies = [ 331 | "wasm-bindgen", 332 | ] 333 | 334 | [[package]] 335 | name = "lazy_static" 336 | version = "1.4.0" 337 | source = "registry+https://github.com/rust-lang/crates.io-index" 338 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 339 | 340 | [[package]] 341 | name = "libc" 342 | version = "0.2.107" 343 | source = "registry+https://github.com/rust-lang/crates.io-index" 344 | checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" 345 | 346 | [[package]] 347 | name = "lock_api" 348 | version = "0.4.5" 349 | source = "registry+https://github.com/rust-lang/crates.io-index" 350 | checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" 351 | dependencies = [ 352 | "scopeguard", 353 | ] 354 | 355 | [[package]] 356 | name = "log" 357 | version = "0.4.14" 358 | source = "registry+https://github.com/rust-lang/crates.io-index" 359 | checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" 360 | dependencies = [ 361 | "cfg-if", 362 | ] 363 | 364 | [[package]] 365 | name = "matches" 366 | version = "0.1.9" 367 | source = "registry+https://github.com/rust-lang/crates.io-index" 368 | checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" 369 | 370 | [[package]] 371 | name = "memchr" 372 | version = "2.4.1" 373 | source = "registry+https://github.com/rust-lang/crates.io-index" 374 | checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" 375 | 376 | [[package]] 377 | name = "memoffset" 378 | version = "0.6.4" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" 381 | dependencies = [ 382 | "autocfg", 383 | ] 384 | 385 | [[package]] 386 | name = "miow" 387 | version = "0.3.7" 388 | source = "registry+https://github.com/rust-lang/crates.io-index" 389 | checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" 390 | dependencies = [ 391 | "winapi", 392 | ] 393 | 394 | [[package]] 395 | name = "num_cpus" 396 | version = "1.13.0" 397 | source = "registry+https://github.com/rust-lang/crates.io-index" 398 | checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" 399 | dependencies = [ 400 | "hermit-abi", 401 | "libc", 402 | ] 403 | 404 | [[package]] 405 | name = "once_cell" 406 | version = "1.8.0" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" 409 | 410 | [[package]] 411 | name = "oorandom" 412 | version = "11.1.3" 413 | source = "registry+https://github.com/rust-lang/crates.io-index" 414 | checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" 415 | 416 | [[package]] 417 | name = "parking_lot" 418 | version = "0.11.2" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" 421 | dependencies = [ 422 | "instant", 423 | "lock_api", 424 | "parking_lot_core", 425 | ] 426 | 427 | [[package]] 428 | name = "parking_lot_core" 429 | version = "0.8.5" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" 432 | dependencies = [ 433 | "cfg-if", 434 | "instant", 435 | "libc", 436 | "redox_syscall", 437 | "smallvec", 438 | "winapi", 439 | ] 440 | 441 | [[package]] 442 | name = "percent-encoding" 443 | version = "2.1.0" 444 | source = "registry+https://github.com/rust-lang/crates.io-index" 445 | checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 446 | 447 | [[package]] 448 | name = "perf-event" 449 | version = "0.4.7" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | checksum = "5396562cd2eaa828445d6d34258ae21ee1eb9d40fe626ca7f51c8dccb4af9d66" 452 | dependencies = [ 453 | "libc", 454 | "perf-event-open-sys", 455 | ] 456 | 457 | [[package]] 458 | name = "perf-event-open-sys" 459 | version = "1.0.1" 460 | source = "registry+https://github.com/rust-lang/crates.io-index" 461 | checksum = "ce9bedf5da2c234fdf2391ede2b90fabf585355f33100689bc364a3ea558561a" 462 | dependencies = [ 463 | "libc", 464 | ] 465 | 466 | [[package]] 467 | name = "petgraph" 468 | version = "0.5.1" 469 | source = "registry+https://github.com/rust-lang/crates.io-index" 470 | checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7" 471 | dependencies = [ 472 | "fixedbitset", 473 | "indexmap", 474 | ] 475 | 476 | [[package]] 477 | name = "pin-project-lite" 478 | version = "0.2.7" 479 | source = "registry+https://github.com/rust-lang/crates.io-index" 480 | checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" 481 | 482 | [[package]] 483 | name = "proc-macro2" 484 | version = "1.0.32" 485 | source = "registry+https://github.com/rust-lang/crates.io-index" 486 | checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" 487 | dependencies = [ 488 | "unicode-xid", 489 | ] 490 | 491 | [[package]] 492 | name = "psm" 493 | version = "0.1.16" 494 | source = "registry+https://github.com/rust-lang/crates.io-index" 495 | checksum = "cd136ff4382c4753fc061cb9e4712ab2af263376b95bbd5bd8cd50c020b78e69" 496 | dependencies = [ 497 | "cc", 498 | ] 499 | 500 | [[package]] 501 | name = "pulldown-cmark" 502 | version = "0.8.0" 503 | source = "registry+https://github.com/rust-lang/crates.io-index" 504 | checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8" 505 | dependencies = [ 506 | "bitflags", 507 | "memchr", 508 | "unicase", 509 | ] 510 | 511 | [[package]] 512 | name = "pulldown-cmark-to-cmark" 513 | version = "6.0.4" 514 | source = "registry+https://github.com/rust-lang/crates.io-index" 515 | checksum = "1f5925e2c68fb0c3c189cd0f6bbcf1e16402a070d4fcaf7600e239e8302dd0e8" 516 | dependencies = [ 517 | "pulldown-cmark", 518 | ] 519 | 520 | [[package]] 521 | name = "quote" 522 | version = "1.0.10" 523 | source = "registry+https://github.com/rust-lang/crates.io-index" 524 | checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" 525 | dependencies = [ 526 | "proc-macro2", 527 | ] 528 | 529 | [[package]] 530 | name = "ra_ap_base_db" 531 | version = "0.0.81" 532 | source = "registry+https://github.com/rust-lang/crates.io-index" 533 | checksum = "18acea3c638b9c88a7dc4f56cfe08a30d31df032081a29a88b68eb7ac122d03f" 534 | dependencies = [ 535 | "ra_ap_cfg", 536 | "ra_ap_profile", 537 | "ra_ap_stdx", 538 | "ra_ap_syntax", 539 | "ra_ap_test_utils", 540 | "ra_ap_tt", 541 | "ra_ap_vfs", 542 | "rustc-hash", 543 | "salsa", 544 | ] 545 | 546 | [[package]] 547 | name = "ra_ap_cfg" 548 | version = "0.0.81" 549 | source = "registry+https://github.com/rust-lang/crates.io-index" 550 | checksum = "7208f76a95cd1d05c855ee992a83163ee343678c93536f42cc17e7bf9292e2ea" 551 | dependencies = [ 552 | "ra_ap_tt", 553 | "rustc-hash", 554 | ] 555 | 556 | [[package]] 557 | name = "ra_ap_hir" 558 | version = "0.0.81" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | checksum = "c86a6002f6f7978d5b07ef08a3ff791bdfb7c85bc78d5964d6d3cbefc2db4b89" 561 | dependencies = [ 562 | "arrayvec", 563 | "either", 564 | "itertools", 565 | "once_cell", 566 | "ra_ap_base_db", 567 | "ra_ap_cfg", 568 | "ra_ap_hir_def", 569 | "ra_ap_hir_expand", 570 | "ra_ap_hir_ty", 571 | "ra_ap_profile", 572 | "ra_ap_stdx", 573 | "ra_ap_syntax", 574 | "ra_ap_tt", 575 | "rustc-hash", 576 | "smallvec", 577 | ] 578 | 579 | [[package]] 580 | name = "ra_ap_hir_def" 581 | version = "0.0.81" 582 | source = "registry+https://github.com/rust-lang/crates.io-index" 583 | checksum = "f456f8b415bc4037816814acadec1e1111db4f1109852ae4786144e537d47034" 584 | dependencies = [ 585 | "anymap", 586 | "cov-mark", 587 | "dashmap", 588 | "drop_bomb", 589 | "either", 590 | "fst", 591 | "indexmap", 592 | "itertools", 593 | "once_cell", 594 | "ra_ap_base_db", 595 | "ra_ap_cfg", 596 | "ra_ap_hir_expand", 597 | "ra_ap_la-arena", 598 | "ra_ap_limit", 599 | "ra_ap_mbe", 600 | "ra_ap_profile", 601 | "ra_ap_stdx", 602 | "ra_ap_syntax", 603 | "ra_ap_tt", 604 | "rustc-hash", 605 | "smallvec", 606 | "tracing", 607 | ] 608 | 609 | [[package]] 610 | name = "ra_ap_hir_expand" 611 | version = "0.0.81" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | checksum = "735a6c7463b4c258d7674fbbf29124e0db7072f58ae44f2ab80c341c98995ee6" 614 | dependencies = [ 615 | "cov-mark", 616 | "either", 617 | "itertools", 618 | "ra_ap_base_db", 619 | "ra_ap_cfg", 620 | "ra_ap_la-arena", 621 | "ra_ap_limit", 622 | "ra_ap_mbe", 623 | "ra_ap_profile", 624 | "ra_ap_syntax", 625 | "ra_ap_tt", 626 | "rustc-hash", 627 | "tracing", 628 | ] 629 | 630 | [[package]] 631 | name = "ra_ap_hir_ty" 632 | version = "0.0.81" 633 | source = "registry+https://github.com/rust-lang/crates.io-index" 634 | checksum = "bfbbbc7d66730ab75e7c35f788b1dbbfbe5c5f6e1f360e7f23dbedc6763242b8" 635 | dependencies = [ 636 | "arrayvec", 637 | "chalk-ir", 638 | "chalk-recursive", 639 | "chalk-solve", 640 | "cov-mark", 641 | "ena", 642 | "itertools", 643 | "once_cell", 644 | "ra_ap_base_db", 645 | "ra_ap_hir_def", 646 | "ra_ap_hir_expand", 647 | "ra_ap_la-arena", 648 | "ra_ap_limit", 649 | "ra_ap_profile", 650 | "ra_ap_stdx", 651 | "ra_ap_syntax", 652 | "rustc-hash", 653 | "scoped-tls", 654 | "smallvec", 655 | "tracing", 656 | ] 657 | 658 | [[package]] 659 | name = "ra_ap_ide" 660 | version = "0.0.81" 661 | source = "registry+https://github.com/rust-lang/crates.io-index" 662 | checksum = "6ea1e8dcc9cf52b5976b5ea2469618f3d68ba1231eca38e9e047a069435da5fe" 663 | dependencies = [ 664 | "cov-mark", 665 | "dot", 666 | "either", 667 | "indexmap", 668 | "itertools", 669 | "oorandom", 670 | "pulldown-cmark", 671 | "pulldown-cmark-to-cmark", 672 | "ra_ap_cfg", 673 | "ra_ap_hir", 674 | "ra_ap_ide_assists", 675 | "ra_ap_ide_completion", 676 | "ra_ap_ide_db", 677 | "ra_ap_ide_diagnostics", 678 | "ra_ap_ide_ssr", 679 | "ra_ap_profile", 680 | "ra_ap_stdx", 681 | "ra_ap_syntax", 682 | "ra_ap_text_edit", 683 | "rustc-hash", 684 | "tracing", 685 | "url", 686 | ] 687 | 688 | [[package]] 689 | name = "ra_ap_ide_assists" 690 | version = "0.0.81" 691 | source = "registry+https://github.com/rust-lang/crates.io-index" 692 | checksum = "719cbe1ffd42b062676ee134cf3e75b7285763e0dfcd222eac30e25a364925d5" 693 | dependencies = [ 694 | "cov-mark", 695 | "either", 696 | "indexmap", 697 | "itertools", 698 | "ra_ap_hir", 699 | "ra_ap_ide_db", 700 | "ra_ap_profile", 701 | "ra_ap_stdx", 702 | "ra_ap_syntax", 703 | "ra_ap_text_edit", 704 | "rustc-hash", 705 | ] 706 | 707 | [[package]] 708 | name = "ra_ap_ide_completion" 709 | version = "0.0.81" 710 | source = "registry+https://github.com/rust-lang/crates.io-index" 711 | checksum = "ed5f1a50d152f77b52fdd3872d1889ade0a27a7e154923035d5bdedc90662672" 712 | dependencies = [ 713 | "cov-mark", 714 | "either", 715 | "itertools", 716 | "once_cell", 717 | "ra_ap_base_db", 718 | "ra_ap_hir", 719 | "ra_ap_ide_db", 720 | "ra_ap_profile", 721 | "ra_ap_stdx", 722 | "ra_ap_syntax", 723 | "ra_ap_text_edit", 724 | "rustc-hash", 725 | "smallvec", 726 | ] 727 | 728 | [[package]] 729 | name = "ra_ap_ide_db" 730 | version = "0.0.81" 731 | source = "registry+https://github.com/rust-lang/crates.io-index" 732 | checksum = "27d805022bb5689cc2622c0771fcb814222dd22e42186fe5b6dd2b8e75cfb82a" 733 | dependencies = [ 734 | "arrayvec", 735 | "cov-mark", 736 | "either", 737 | "fst", 738 | "itertools", 739 | "once_cell", 740 | "ra_ap_base_db", 741 | "ra_ap_hir", 742 | "ra_ap_limit", 743 | "ra_ap_profile", 744 | "ra_ap_stdx", 745 | "ra_ap_syntax", 746 | "ra_ap_text_edit", 747 | "rayon", 748 | "rustc-hash", 749 | "tracing", 750 | ] 751 | 752 | [[package]] 753 | name = "ra_ap_ide_diagnostics" 754 | version = "0.0.81" 755 | source = "registry+https://github.com/rust-lang/crates.io-index" 756 | checksum = "be3f5b1cce595c8031efb3bd29c2a79a871fd99377c7bebaaf6d931648ea8ec4" 757 | dependencies = [ 758 | "cov-mark", 759 | "either", 760 | "itertools", 761 | "ra_ap_cfg", 762 | "ra_ap_hir", 763 | "ra_ap_ide_db", 764 | "ra_ap_profile", 765 | "ra_ap_stdx", 766 | "ra_ap_syntax", 767 | "ra_ap_text_edit", 768 | "rustc-hash", 769 | ] 770 | 771 | [[package]] 772 | name = "ra_ap_ide_ssr" 773 | version = "0.0.81" 774 | source = "registry+https://github.com/rust-lang/crates.io-index" 775 | checksum = "8ec04446bf000541190b01d72a8e03df25007eafb92f7d647c3351e6f128170b" 776 | dependencies = [ 777 | "cov-mark", 778 | "itertools", 779 | "ra_ap_hir", 780 | "ra_ap_ide_db", 781 | "ra_ap_syntax", 782 | "ra_ap_text_edit", 783 | "rustc-hash", 784 | ] 785 | 786 | [[package]] 787 | name = "ra_ap_la-arena" 788 | version = "0.0.81" 789 | source = "registry+https://github.com/rust-lang/crates.io-index" 790 | checksum = "e343e7dc18f9e2d7e888886363ec9b2791c05771a66b252f8b5e877cfd1f2508" 791 | 792 | [[package]] 793 | name = "ra_ap_limit" 794 | version = "0.0.81" 795 | source = "registry+https://github.com/rust-lang/crates.io-index" 796 | checksum = "193a7846e5fd7f4a3b38b3301934f5b8b6b5dd1e377c78c3a18ae32b9bdd99bc" 797 | 798 | [[package]] 799 | name = "ra_ap_mbe" 800 | version = "0.0.81" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | checksum = "8b7eaec720d13883baf9322b7be43c8e653cf9687b108109c6bd9c551047548f" 803 | dependencies = [ 804 | "cov-mark", 805 | "expect-test", 806 | "ra_ap_parser", 807 | "ra_ap_stdx", 808 | "ra_ap_syntax", 809 | "ra_ap_tt", 810 | "rustc-hash", 811 | "smallvec", 812 | "tracing", 813 | ] 814 | 815 | [[package]] 816 | name = "ra_ap_parser" 817 | version = "0.0.81" 818 | source = "registry+https://github.com/rust-lang/crates.io-index" 819 | checksum = "8a0195330c24945d4c11a08520f514b22b229a55fd9d8fb9c83ad6b7649a5c2c" 820 | dependencies = [ 821 | "drop_bomb", 822 | ] 823 | 824 | [[package]] 825 | name = "ra_ap_paths" 826 | version = "0.0.81" 827 | source = "registry+https://github.com/rust-lang/crates.io-index" 828 | checksum = "a1456b50447fc8e24f2f9e17daa180e987abf3781ada8138af88838857f328a8" 829 | 830 | [[package]] 831 | name = "ra_ap_profile" 832 | version = "0.0.81" 833 | source = "registry+https://github.com/rust-lang/crates.io-index" 834 | checksum = "7838c8c503cc0a0e96fdeecbf7b47126809909b78da1c9109a26406634812c24" 835 | dependencies = [ 836 | "cfg-if", 837 | "countme", 838 | "libc", 839 | "once_cell", 840 | "perf-event", 841 | "ra_ap_la-arena", 842 | "winapi", 843 | ] 844 | 845 | [[package]] 846 | name = "ra_ap_stdx" 847 | version = "0.0.81" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | checksum = "dd59660b2f03242bc708bd6dea8b85683c0d6133f18f7f5e0fc41ad5f4d9a875" 850 | dependencies = [ 851 | "always-assert", 852 | "libc", 853 | "miow", 854 | "winapi", 855 | ] 856 | 857 | [[package]] 858 | name = "ra_ap_syntax" 859 | version = "0.0.81" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | checksum = "6f0b1b7d968f7aae4c939a5347cde52048e3c5cb28c53022aec07f13476d5b2f" 862 | dependencies = [ 863 | "cov-mark", 864 | "indexmap", 865 | "itertools", 866 | "once_cell", 867 | "ra_ap_parser", 868 | "ra_ap_profile", 869 | "ra_ap_stdx", 870 | "ra_ap_text_edit", 871 | "rowan", 872 | "rustc-ap-rustc_lexer", 873 | "rustc-hash", 874 | "smol_str", 875 | ] 876 | 877 | [[package]] 878 | name = "ra_ap_test_utils" 879 | version = "0.0.81" 880 | source = "registry+https://github.com/rust-lang/crates.io-index" 881 | checksum = "8654179a63d6db6d6c3fe058d79d7222fa113b565a412514a636a44e2f33b15f" 882 | dependencies = [ 883 | "dissimilar", 884 | "ra_ap_profile", 885 | "ra_ap_stdx", 886 | "rustc-hash", 887 | "text-size", 888 | ] 889 | 890 | [[package]] 891 | name = "ra_ap_text_edit" 892 | version = "0.0.81" 893 | source = "registry+https://github.com/rust-lang/crates.io-index" 894 | checksum = "a7a205da1c3b42baf239198e491664de32199a9d7d51d7255e21afc6921ee484" 895 | dependencies = [ 896 | "text-size", 897 | ] 898 | 899 | [[package]] 900 | name = "ra_ap_tt" 901 | version = "0.0.81" 902 | source = "registry+https://github.com/rust-lang/crates.io-index" 903 | checksum = "bddd128dd71f9069f3f80814cf6499012c8704a33bf8d592304a6ed03f4dc1d4" 904 | dependencies = [ 905 | "ra_ap_stdx", 906 | "smol_str", 907 | ] 908 | 909 | [[package]] 910 | name = "ra_ap_vfs" 911 | version = "0.0.81" 912 | source = "registry+https://github.com/rust-lang/crates.io-index" 913 | checksum = "300c6e920e4c9289705d1d30859cd6ed1156a643f72f20c770e3e57890baa8f8" 914 | dependencies = [ 915 | "fst", 916 | "indexmap", 917 | "ra_ap_paths", 918 | "rustc-hash", 919 | ] 920 | 921 | [[package]] 922 | name = "rayon" 923 | version = "1.5.1" 924 | source = "registry+https://github.com/rust-lang/crates.io-index" 925 | checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" 926 | dependencies = [ 927 | "autocfg", 928 | "crossbeam-deque", 929 | "either", 930 | "rayon-core", 931 | ] 932 | 933 | [[package]] 934 | name = "rayon-core" 935 | version = "1.9.1" 936 | source = "registry+https://github.com/rust-lang/crates.io-index" 937 | checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" 938 | dependencies = [ 939 | "crossbeam-channel", 940 | "crossbeam-deque", 941 | "crossbeam-utils", 942 | "lazy_static", 943 | "num_cpus", 944 | ] 945 | 946 | [[package]] 947 | name = "redox_syscall" 948 | version = "0.2.10" 949 | source = "registry+https://github.com/rust-lang/crates.io-index" 950 | checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" 951 | dependencies = [ 952 | "bitflags", 953 | ] 954 | 955 | [[package]] 956 | name = "rowan" 957 | version = "0.14.1" 958 | source = "registry+https://github.com/rust-lang/crates.io-index" 959 | checksum = "4f77412a3d1f26af0c0783c23b3555a301b1a49805cba7bf9a7827a9e9e285f0" 960 | dependencies = [ 961 | "countme", 962 | "hashbrown", 963 | "memoffset", 964 | "rustc-hash", 965 | "text-size", 966 | ] 967 | 968 | [[package]] 969 | name = "rustc-ap-rustc_lexer" 970 | version = "725.0.0" 971 | source = "registry+https://github.com/rust-lang/crates.io-index" 972 | checksum = "f950742ef8a203aa7661aad3ab880438ddeb7f95d4b837c30d65db1a2c5df68e" 973 | dependencies = [ 974 | "unicode-xid", 975 | ] 976 | 977 | [[package]] 978 | name = "rustc-hash" 979 | version = "1.1.0" 980 | source = "registry+https://github.com/rust-lang/crates.io-index" 981 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 982 | 983 | [[package]] 984 | name = "salsa" 985 | version = "0.17.0-pre.2" 986 | source = "registry+https://github.com/rust-lang/crates.io-index" 987 | checksum = "9b223dccb46c32753144d0b51290da7230bb4aedcd8379d6b4c9a474c18bf17a" 988 | dependencies = [ 989 | "crossbeam-utils", 990 | "indexmap", 991 | "lock_api", 992 | "log", 993 | "oorandom", 994 | "parking_lot", 995 | "rustc-hash", 996 | "salsa-macros", 997 | "smallvec", 998 | ] 999 | 1000 | [[package]] 1001 | name = "salsa-macros" 1002 | version = "0.17.0-pre.2" 1003 | source = "registry+https://github.com/rust-lang/crates.io-index" 1004 | checksum = "ac6c2e352df550bf019da7b16164ed2f7fa107c39653d1311d1bba42d1582ff7" 1005 | dependencies = [ 1006 | "heck", 1007 | "proc-macro2", 1008 | "quote", 1009 | "syn", 1010 | ] 1011 | 1012 | [[package]] 1013 | name = "scoped-tls" 1014 | version = "1.0.0" 1015 | source = "registry+https://github.com/rust-lang/crates.io-index" 1016 | checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" 1017 | 1018 | [[package]] 1019 | name = "scopeguard" 1020 | version = "1.1.0" 1021 | source = "registry+https://github.com/rust-lang/crates.io-index" 1022 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1023 | 1024 | [[package]] 1025 | name = "serde" 1026 | version = "1.0.130" 1027 | source = "registry+https://github.com/rust-lang/crates.io-index" 1028 | checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" 1029 | dependencies = [ 1030 | "serde_derive", 1031 | ] 1032 | 1033 | [[package]] 1034 | name = "serde-wasm-bindgen" 1035 | version = "0.1.3" 1036 | source = "registry+https://github.com/rust-lang/crates.io-index" 1037 | checksum = "7ee6f12f7ed0e7ad2e55200da37dbabc2cadeb942355c5b629aa3771f5ac5636" 1038 | dependencies = [ 1039 | "fnv", 1040 | "js-sys", 1041 | "serde", 1042 | "wasm-bindgen", 1043 | ] 1044 | 1045 | [[package]] 1046 | name = "serde_derive" 1047 | version = "1.0.130" 1048 | source = "registry+https://github.com/rust-lang/crates.io-index" 1049 | checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" 1050 | dependencies = [ 1051 | "proc-macro2", 1052 | "quote", 1053 | "syn", 1054 | ] 1055 | 1056 | [[package]] 1057 | name = "serde_repr" 1058 | version = "0.1.7" 1059 | source = "registry+https://github.com/rust-lang/crates.io-index" 1060 | checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" 1061 | dependencies = [ 1062 | "proc-macro2", 1063 | "quote", 1064 | "syn", 1065 | ] 1066 | 1067 | [[package]] 1068 | name = "smallvec" 1069 | version = "1.7.0" 1070 | source = "registry+https://github.com/rust-lang/crates.io-index" 1071 | checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" 1072 | 1073 | [[package]] 1074 | name = "smol_str" 1075 | version = "0.1.21" 1076 | source = "registry+https://github.com/rust-lang/crates.io-index" 1077 | checksum = "61d15c83e300cce35b7c8cd39ff567c1ef42dde6d4a1a38dbdbf9a59902261bd" 1078 | dependencies = [ 1079 | "serde", 1080 | ] 1081 | 1082 | [[package]] 1083 | name = "spmc" 1084 | version = "0.3.0" 1085 | source = "registry+https://github.com/rust-lang/crates.io-index" 1086 | checksum = "02a8428da277a8e3a15271d79943e80ccc2ef254e78813a166a08d65e4c3ece5" 1087 | 1088 | [[package]] 1089 | name = "stacker" 1090 | version = "0.1.14" 1091 | source = "registry+https://github.com/rust-lang/crates.io-index" 1092 | checksum = "90939d5171a4420b3ff5fbc8954d641e7377335454c259dcb80786f3f21dc9b4" 1093 | dependencies = [ 1094 | "cc", 1095 | "cfg-if", 1096 | "libc", 1097 | "psm", 1098 | "winapi", 1099 | ] 1100 | 1101 | [[package]] 1102 | name = "syn" 1103 | version = "1.0.81" 1104 | source = "registry+https://github.com/rust-lang/crates.io-index" 1105 | checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" 1106 | dependencies = [ 1107 | "proc-macro2", 1108 | "quote", 1109 | "unicode-xid", 1110 | ] 1111 | 1112 | [[package]] 1113 | name = "synstructure" 1114 | version = "0.12.6" 1115 | source = "registry+https://github.com/rust-lang/crates.io-index" 1116 | checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" 1117 | dependencies = [ 1118 | "proc-macro2", 1119 | "quote", 1120 | "syn", 1121 | "unicode-xid", 1122 | ] 1123 | 1124 | [[package]] 1125 | name = "text-size" 1126 | version = "1.1.0" 1127 | source = "registry+https://github.com/rust-lang/crates.io-index" 1128 | checksum = "288cb548dbe72b652243ea797201f3d481a0609a967980fcc5b2315ea811560a" 1129 | 1130 | [[package]] 1131 | name = "tinyvec" 1132 | version = "1.5.1" 1133 | source = "registry+https://github.com/rust-lang/crates.io-index" 1134 | checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" 1135 | dependencies = [ 1136 | "tinyvec_macros", 1137 | ] 1138 | 1139 | [[package]] 1140 | name = "tinyvec_macros" 1141 | version = "0.1.0" 1142 | source = "registry+https://github.com/rust-lang/crates.io-index" 1143 | checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" 1144 | 1145 | [[package]] 1146 | name = "tracing" 1147 | version = "0.1.29" 1148 | source = "registry+https://github.com/rust-lang/crates.io-index" 1149 | checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" 1150 | dependencies = [ 1151 | "cfg-if", 1152 | "pin-project-lite", 1153 | "tracing-attributes", 1154 | "tracing-core", 1155 | ] 1156 | 1157 | [[package]] 1158 | name = "tracing-attributes" 1159 | version = "0.1.18" 1160 | source = "registry+https://github.com/rust-lang/crates.io-index" 1161 | checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e" 1162 | dependencies = [ 1163 | "proc-macro2", 1164 | "quote", 1165 | "syn", 1166 | ] 1167 | 1168 | [[package]] 1169 | name = "tracing-core" 1170 | version = "0.1.21" 1171 | source = "registry+https://github.com/rust-lang/crates.io-index" 1172 | checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" 1173 | dependencies = [ 1174 | "lazy_static", 1175 | ] 1176 | 1177 | [[package]] 1178 | name = "unicase" 1179 | version = "2.6.0" 1180 | source = "registry+https://github.com/rust-lang/crates.io-index" 1181 | checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" 1182 | dependencies = [ 1183 | "version_check", 1184 | ] 1185 | 1186 | [[package]] 1187 | name = "unicode-bidi" 1188 | version = "0.3.7" 1189 | source = "registry+https://github.com/rust-lang/crates.io-index" 1190 | checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" 1191 | 1192 | [[package]] 1193 | name = "unicode-normalization" 1194 | version = "0.1.19" 1195 | source = "registry+https://github.com/rust-lang/crates.io-index" 1196 | checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" 1197 | dependencies = [ 1198 | "tinyvec", 1199 | ] 1200 | 1201 | [[package]] 1202 | name = "unicode-segmentation" 1203 | version = "1.8.0" 1204 | source = "registry+https://github.com/rust-lang/crates.io-index" 1205 | checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" 1206 | 1207 | [[package]] 1208 | name = "unicode-xid" 1209 | version = "0.2.2" 1210 | source = "registry+https://github.com/rust-lang/crates.io-index" 1211 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 1212 | 1213 | [[package]] 1214 | name = "url" 1215 | version = "2.2.2" 1216 | source = "registry+https://github.com/rust-lang/crates.io-index" 1217 | checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" 1218 | dependencies = [ 1219 | "form_urlencoded", 1220 | "idna", 1221 | "matches", 1222 | "percent-encoding", 1223 | ] 1224 | 1225 | [[package]] 1226 | name = "version_check" 1227 | version = "0.9.3" 1228 | source = "registry+https://github.com/rust-lang/crates.io-index" 1229 | checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" 1230 | 1231 | [[package]] 1232 | name = "wasm-bindgen" 1233 | version = "0.2.78" 1234 | source = "registry+https://github.com/rust-lang/crates.io-index" 1235 | checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" 1236 | dependencies = [ 1237 | "cfg-if", 1238 | "wasm-bindgen-macro", 1239 | ] 1240 | 1241 | [[package]] 1242 | name = "wasm-bindgen-backend" 1243 | version = "0.2.78" 1244 | source = "registry+https://github.com/rust-lang/crates.io-index" 1245 | checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" 1246 | dependencies = [ 1247 | "bumpalo", 1248 | "lazy_static", 1249 | "log", 1250 | "proc-macro2", 1251 | "quote", 1252 | "syn", 1253 | "wasm-bindgen-shared", 1254 | ] 1255 | 1256 | [[package]] 1257 | name = "wasm-bindgen-macro" 1258 | version = "0.2.78" 1259 | source = "registry+https://github.com/rust-lang/crates.io-index" 1260 | checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" 1261 | dependencies = [ 1262 | "quote", 1263 | "wasm-bindgen-macro-support", 1264 | ] 1265 | 1266 | [[package]] 1267 | name = "wasm-bindgen-macro-support" 1268 | version = "0.2.78" 1269 | source = "registry+https://github.com/rust-lang/crates.io-index" 1270 | checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" 1271 | dependencies = [ 1272 | "proc-macro2", 1273 | "quote", 1274 | "syn", 1275 | "wasm-bindgen-backend", 1276 | "wasm-bindgen-shared", 1277 | ] 1278 | 1279 | [[package]] 1280 | name = "wasm-bindgen-rayon" 1281 | version = "1.0.3" 1282 | source = "registry+https://github.com/rust-lang/crates.io-index" 1283 | checksum = "df87c67450805c305d3ae44a3ac537b0253d029153c25afc3ecd2edc36ccafb1" 1284 | dependencies = [ 1285 | "js-sys", 1286 | "rayon", 1287 | "spmc", 1288 | "wasm-bindgen", 1289 | ] 1290 | 1291 | [[package]] 1292 | name = "wasm-bindgen-shared" 1293 | version = "0.2.78" 1294 | source = "registry+https://github.com/rust-lang/crates.io-index" 1295 | checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" 1296 | 1297 | [[package]] 1298 | name = "wasm_demo" 1299 | version = "0.1.0" 1300 | dependencies = [ 1301 | "console_error_panic_hook", 1302 | "instant", 1303 | "log", 1304 | "ra_ap_cfg", 1305 | "ra_ap_ide", 1306 | "ra_ap_ide_db", 1307 | "serde", 1308 | "serde-wasm-bindgen", 1309 | "serde_repr", 1310 | "stacker", 1311 | "wasm-bindgen", 1312 | "wasm-bindgen-rayon", 1313 | ] 1314 | 1315 | [[package]] 1316 | name = "web-sys" 1317 | version = "0.3.55" 1318 | source = "registry+https://github.com/rust-lang/crates.io-index" 1319 | checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" 1320 | dependencies = [ 1321 | "js-sys", 1322 | "wasm-bindgen", 1323 | ] 1324 | 1325 | [[package]] 1326 | name = "winapi" 1327 | version = "0.3.9" 1328 | source = "registry+https://github.com/rust-lang/crates.io-index" 1329 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1330 | dependencies = [ 1331 | "winapi-i686-pc-windows-gnu", 1332 | "winapi-x86_64-pc-windows-gnu", 1333 | ] 1334 | 1335 | [[package]] 1336 | name = "winapi-i686-pc-windows-gnu" 1337 | version = "0.4.0" 1338 | source = "registry+https://github.com/rust-lang/crates.io-index" 1339 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1340 | 1341 | [[package]] 1342 | name = "winapi-x86_64-pc-windows-gnu" 1343 | version = "0.4.0" 1344 | source = "registry+https://github.com/rust-lang/crates.io-index" 1345 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1346 | -------------------------------------------------------------------------------- /ra-wasm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wasm_demo" 3 | version = "0.1.0" 4 | authors = ["rust-analyzer developers"] 5 | edition = "2018" 6 | 7 | [lib] 8 | crate-type = ["cdylib"] 9 | 10 | [dependencies] 11 | console_error_panic_hook = { version = "0.1.6" } 12 | instant = { version = "0.1", features = ["wasm-bindgen"] } 13 | log = { version = "0.4.14", features = ["release_max_level_warn"] } 14 | serde = { version = "1.0.125", features = ["derive"] } 15 | serde_repr = "0.1.6" 16 | serde-wasm-bindgen = "0.1.3" 17 | stacker = "0.1.13" 18 | wasm-bindgen = "0.2.72" 19 | wasm-bindgen-rayon = "1.0.2" 20 | 21 | ide = { version = "0.0.81", package = "ra_ap_ide" } 22 | cfg = { version = "0.0.81", package = "ra_ap_cfg" } 23 | ide_db = { version = "0.0.81", package = "ra_ap_ide_db" } 24 | 25 | [package.metadata.wasm-pack.profile.profiling] 26 | wasm-opt = false 27 | -------------------------------------------------------------------------------- /ra-wasm/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg(target_arch = "wasm32")] 2 | #![allow(non_snake_case)] 3 | 4 | use std::sync::Arc; 5 | 6 | use cfg::CfgOptions; 7 | use ide::{ 8 | Analysis, AnalysisHost, Change, CompletionConfig, CrateGraph, CrateId, DiagnosticsConfig, 9 | Edition, FileId, FilePosition, HoverConfig, HoverDocFormat, Indel, InlayHintsConfig, InlayKind, 10 | SourceRoot, TextSize, 11 | }; 12 | use ide_db::{ 13 | base_db::{CrateName, Dependency, Env, FileSet, VfsPath}, 14 | helpers::{ 15 | insert_use::{ImportGranularity, InsertUseConfig, PrefixKind}, 16 | SnippetCap, 17 | }, 18 | search::SearchScope, 19 | }; 20 | use wasm_bindgen::prelude::*; 21 | 22 | mod to_proto; 23 | 24 | mod return_types; 25 | use return_types::*; 26 | 27 | pub use wasm_bindgen_rayon::init_thread_pool; 28 | 29 | #[wasm_bindgen(start)] 30 | pub fn start() { 31 | console_error_panic_hook::set_once(); 32 | log::info!("worker initialized") 33 | } 34 | 35 | #[wasm_bindgen] 36 | pub struct WorldState { 37 | host: AnalysisHost, 38 | file_id: FileId, 39 | } 40 | 41 | pub fn create_source_root(name: &str, f: FileId) -> SourceRoot { 42 | let mut file_set = FileSet::default(); 43 | file_set.insert(f, VfsPath::new_virtual_path(format!("/{}/src/lib.rs", name))); 44 | SourceRoot::new_library(file_set) 45 | } 46 | 47 | pub fn create_crate(crate_graph: &mut CrateGraph, f: FileId) -> CrateId { 48 | let mut cfg = CfgOptions::default(); 49 | cfg.insert_atom("unix".into()); 50 | cfg.insert_key_value("target_arch".into(), "x86_64".into()); 51 | cfg.insert_key_value("target_pointer_width".into(), "64".into()); 52 | crate_graph.add_crate_root( 53 | f, 54 | Edition::Edition2018, 55 | None, 56 | None, 57 | cfg, 58 | Default::default(), 59 | Env::default(), 60 | Vec::new(), 61 | ) 62 | } 63 | 64 | pub fn from_single_file( 65 | text: String, 66 | fake_std: String, 67 | fake_core: String, 68 | fake_alloc: String, 69 | ) -> (AnalysisHost, FileId) { 70 | let mut host = AnalysisHost::default(); 71 | let file_id = FileId(0); 72 | let std_id = FileId(1); 73 | let core_id = FileId(2); 74 | let alloc_id = FileId(3); 75 | 76 | let mut file_set = FileSet::default(); 77 | file_set.insert(file_id, VfsPath::new_virtual_path("/my_crate/main.rs".to_string())); 78 | let source_root = SourceRoot::new_local(file_set); 79 | 80 | let mut change = Change::new(); 81 | change.set_roots(vec![ 82 | source_root, 83 | create_source_root("std", std_id), 84 | create_source_root("core", core_id), 85 | create_source_root("alloc", alloc_id), 86 | ]); 87 | let mut crate_graph = CrateGraph::default(); 88 | let my_crate = create_crate(&mut crate_graph, file_id); 89 | let std_crate = create_crate(&mut crate_graph, std_id); 90 | let core_crate = create_crate(&mut crate_graph, core_id); 91 | let alloc_crate = create_crate(&mut crate_graph, alloc_id); 92 | let core_dep = Dependency::new(CrateName::new("core").unwrap(), core_crate); 93 | let alloc_dep = Dependency::new(CrateName::new("alloc").unwrap(), alloc_crate); 94 | let std_dep = Dependency::new(CrateName::new("std").unwrap(), std_crate); 95 | 96 | crate_graph.add_dep(std_crate, core_dep.clone()).unwrap(); 97 | crate_graph.add_dep(std_crate, alloc_dep.clone()).unwrap(); 98 | crate_graph.add_dep(alloc_crate, core_dep.clone()).unwrap(); 99 | 100 | crate_graph.add_dep(my_crate, core_dep).unwrap(); 101 | crate_graph.add_dep(my_crate, alloc_dep).unwrap(); 102 | crate_graph.add_dep(my_crate, std_dep).unwrap(); 103 | 104 | change.change_file(file_id, Some(Arc::new(text))); 105 | change.change_file(std_id, Some(Arc::new(fake_std))); 106 | change.change_file(core_id, Some(Arc::new(fake_core))); 107 | change.change_file(alloc_id, Some(Arc::new(fake_alloc))); 108 | change.set_crate_graph(crate_graph); 109 | host.apply_change(change); 110 | (host, file_id) 111 | } 112 | 113 | impl WorldState { 114 | fn analysis(&self) -> Analysis { 115 | self.host.analysis() 116 | } 117 | } 118 | 119 | #[wasm_bindgen] 120 | impl WorldState { 121 | #[wasm_bindgen(constructor)] 122 | pub fn new() -> Self { 123 | let (host, file_id) = 124 | from_single_file("".to_owned(), "".to_owned(), "".to_owned(), "".to_owned()); 125 | Self { host, file_id } 126 | } 127 | 128 | pub fn init(&mut self, code: String, fake_std: String, fake_core: String, fake_alloc: String) { 129 | let (host, file_id) = from_single_file(code, fake_std, fake_core, fake_alloc); 130 | self.host = host; 131 | self.file_id = file_id; 132 | } 133 | 134 | pub fn update(&mut self, code: String) -> JsValue { 135 | log::warn!("update"); 136 | let file_id = FileId(0); 137 | let mut change = Change::new(); 138 | change.change_file(file_id, Some(Arc::new(code))); 139 | self.host.apply_change(change); 140 | 141 | let line_index = self.analysis().file_line_index(self.file_id).unwrap(); 142 | 143 | let highlights: Vec<_> = self 144 | .analysis() 145 | .highlight(file_id) 146 | .unwrap() 147 | .into_iter() 148 | .map(|hl| Highlight { 149 | tag: Some(hl.highlight.tag.to_string()), 150 | range: to_proto::text_range(hl.range, &line_index), 151 | }) 152 | .collect(); 153 | 154 | let config = DiagnosticsConfig::default(); 155 | 156 | let diagnostics: Vec<_> = self 157 | .analysis() 158 | .diagnostics(&config, ide::AssistResolveStrategy::All, file_id) 159 | .unwrap() 160 | .into_iter() 161 | .map(|d| { 162 | let Range { startLineNumber, startColumn, endLineNumber, endColumn } = 163 | to_proto::text_range(d.range, &line_index); 164 | Diagnostic { 165 | message: d.message, 166 | severity: to_proto::severity(d.severity), 167 | startLineNumber, 168 | startColumn, 169 | endLineNumber, 170 | endColumn, 171 | } 172 | }) 173 | .collect(); 174 | 175 | serde_wasm_bindgen::to_value(&UpdateResult { diagnostics, highlights }).unwrap() 176 | } 177 | 178 | pub fn inlay_hints(&self) -> JsValue { 179 | let line_index = self.analysis().file_line_index(self.file_id).unwrap(); 180 | let results: Vec<_> = self 181 | .analysis() 182 | .inlay_hints( 183 | &InlayHintsConfig { 184 | type_hints: true, 185 | parameter_hints: true, 186 | chaining_hints: true, 187 | max_length: Some(25), 188 | }, 189 | self.file_id, 190 | ) 191 | .unwrap() 192 | .into_iter() 193 | .map(|ih| InlayHint { 194 | label: Some(ih.label.to_string()), 195 | hint_type: match ih.kind { 196 | InlayKind::TypeHint | InlayKind::ChainingHint => InlayHintType::Type, 197 | InlayKind::ParameterHint => InlayHintType::Parameter, 198 | }, 199 | range: to_proto::text_range(ih.range, &line_index), 200 | }) 201 | .collect(); 202 | serde_wasm_bindgen::to_value(&results).unwrap() 203 | } 204 | 205 | pub fn completions(&self, line_number: u32, column: u32) -> JsValue { 206 | const COMPLETION_CONFIG: CompletionConfig = CompletionConfig { 207 | enable_postfix_completions: true, 208 | enable_imports_on_the_fly: true, 209 | enable_self_on_the_fly: true, 210 | add_call_parenthesis: true, 211 | add_call_argument_snippets: true, 212 | snippet_cap: SnippetCap::new(true), 213 | insert_use: InsertUseConfig { 214 | granularity: ImportGranularity::Module, 215 | enforce_granularity: false, 216 | prefix_kind: PrefixKind::Plain, 217 | group: true, 218 | skip_glob_imports: false, 219 | }, 220 | snippets: Vec::new(), 221 | }; 222 | 223 | log::warn!("completions"); 224 | let line_index = self.analysis().file_line_index(self.file_id).unwrap(); 225 | 226 | let pos = file_position(line_number, column, &line_index, self.file_id); 227 | let res = match self.analysis().completions(&COMPLETION_CONFIG, pos).unwrap() { 228 | Some(items) => items, 229 | None => return JsValue::NULL, 230 | }; 231 | 232 | let items: Vec<_> = 233 | res.into_iter().map(|item| to_proto::completion_item(item, &line_index)).collect(); 234 | serde_wasm_bindgen::to_value(&items).unwrap() 235 | } 236 | 237 | pub fn hover(&self, line_number: u32, column: u32) -> JsValue { 238 | log::warn!("hover"); 239 | let line_index = self.analysis().file_line_index(self.file_id).unwrap(); 240 | 241 | let range = file_range(line_number, column, line_number, column, &line_index, self.file_id); 242 | let info = match self 243 | .analysis() 244 | .hover( 245 | &HoverConfig { 246 | links_in_hover: true, 247 | documentation: Some(HoverDocFormat::Markdown), 248 | }, 249 | range, 250 | ) 251 | .unwrap() 252 | { 253 | Some(info) => info, 254 | _ => return JsValue::NULL, 255 | }; 256 | 257 | let value = info.info.markup.to_string(); 258 | let hover = Hover { 259 | contents: vec![MarkdownString { value }], 260 | range: to_proto::text_range(info.range, &line_index), 261 | }; 262 | 263 | serde_wasm_bindgen::to_value(&hover).unwrap() 264 | } 265 | 266 | pub fn code_lenses(&self) -> JsValue { 267 | log::warn!("code_lenses"); 268 | let line_index = self.analysis().file_line_index(self.file_id).unwrap(); 269 | 270 | let results: Vec<_> = self 271 | .analysis() 272 | .file_structure(self.file_id) 273 | .unwrap() 274 | .into_iter() 275 | .filter(|it| match it.kind { 276 | ide::StructureNodeKind::SymbolKind(it) => matches!( 277 | it, 278 | ide_db::SymbolKind::Trait 279 | | ide_db::SymbolKind::Struct 280 | | ide_db::SymbolKind::Enum 281 | ), 282 | ide::StructureNodeKind::Region => true, 283 | }) 284 | .filter_map(|it| { 285 | let position = 286 | FilePosition { file_id: self.file_id, offset: it.node_range.start() }; 287 | let nav_info = self.analysis().goto_implementation(position).unwrap()?; 288 | 289 | let title = if nav_info.info.len() == 1 { 290 | "1 implementation".into() 291 | } else { 292 | format!("{} implementations", nav_info.info.len()) 293 | }; 294 | 295 | let positions = nav_info 296 | .info 297 | .iter() 298 | .map(|target| target.focus_range.unwrap_or(target.full_range)) 299 | .map(|range| to_proto::text_range(range, &line_index)) 300 | .collect(); 301 | 302 | Some(CodeLensSymbol { 303 | range: to_proto::text_range(it.node_range, &line_index), 304 | command: Some(Command { 305 | id: "editor.action.showReferences".into(), 306 | title, 307 | positions, 308 | }), 309 | }) 310 | }) 311 | .collect(); 312 | 313 | serde_wasm_bindgen::to_value(&results).unwrap() 314 | } 315 | 316 | pub fn references(&self, line_number: u32, column: u32, include_declaration: bool) -> JsValue { 317 | log::warn!("references"); 318 | let line_index = self.analysis().file_line_index(self.file_id).unwrap(); 319 | 320 | let pos = file_position(line_number, column, &line_index, self.file_id); 321 | let search_scope = Some(SearchScope::single_file(self.file_id)); 322 | let ref_results = match self.analysis().find_all_refs(pos, search_scope) { 323 | Ok(Some(info)) => info, 324 | _ => return JsValue::NULL, 325 | }; 326 | 327 | let mut res = vec![]; 328 | for ref_result in ref_results { 329 | if include_declaration { 330 | if let Some(r) = ref_result.declaration { 331 | let r = r.nav.focus_range.unwrap_or(r.nav.full_range); 332 | res.push(Highlight { tag: None, range: to_proto::text_range(r, &line_index) }); 333 | } 334 | } 335 | ref_result.references.iter().for_each(|(_id, ranges)| { 336 | // FIXME: handle multiple files 337 | for (r, _) in ranges { 338 | res.push(Highlight { tag: None, range: to_proto::text_range(*r, &line_index) }); 339 | } 340 | }); 341 | } 342 | 343 | serde_wasm_bindgen::to_value(&res).unwrap() 344 | } 345 | 346 | pub fn prepare_rename(&self, line_number: u32, column: u32) -> JsValue { 347 | log::warn!("prepare_rename"); 348 | let line_index = self.analysis().file_line_index(self.file_id).unwrap(); 349 | 350 | let pos = file_position(line_number, column, &line_index, self.file_id); 351 | let range_info = match self.analysis().prepare_rename(pos).unwrap() { 352 | Ok(refs) => refs, 353 | _ => return JsValue::NULL, 354 | }; 355 | 356 | let range = to_proto::text_range(range_info.range, &line_index); 357 | let file_text = self.analysis().file_text(self.file_id).unwrap(); 358 | let text = file_text[range_info.range].to_owned(); 359 | 360 | serde_wasm_bindgen::to_value(&RenameLocation { range, text }).unwrap() 361 | } 362 | 363 | pub fn rename(&self, line_number: u32, column: u32, new_name: &str) -> JsValue { 364 | log::warn!("rename"); 365 | let line_index = self.analysis().file_line_index(self.file_id).unwrap(); 366 | 367 | let pos = file_position(line_number, column, &line_index, self.file_id); 368 | let change = match self.analysis().rename(pos, new_name).unwrap() { 369 | Ok(change) => change, 370 | Err(_) => return JsValue::NULL, 371 | }; 372 | 373 | let result: Vec<_> = change 374 | .source_file_edits 375 | .iter() 376 | .flat_map(|(_, edit)| edit.iter()) 377 | .map(|atom: &Indel| to_proto::text_edit(atom, &line_index)) 378 | .collect(); 379 | 380 | serde_wasm_bindgen::to_value(&result).unwrap() 381 | } 382 | 383 | pub fn signature_help(&self, line_number: u32, column: u32) -> JsValue { 384 | log::warn!("signature_help"); 385 | let line_index = self.analysis().file_line_index(self.file_id).unwrap(); 386 | 387 | let pos = file_position(line_number, column, &line_index, self.file_id); 388 | let call_info = match self.analysis().call_info(pos) { 389 | Ok(Some(call_info)) => call_info, 390 | _ => return JsValue::NULL, 391 | }; 392 | 393 | let active_parameter = call_info.active_parameter; 394 | let sig_info = to_proto::signature_information(call_info); 395 | 396 | let result = SignatureHelp { 397 | signatures: [sig_info], 398 | activeSignature: 0, 399 | activeParameter: active_parameter, 400 | }; 401 | serde_wasm_bindgen::to_value(&result).unwrap() 402 | } 403 | 404 | pub fn definition(&self, line_number: u32, column: u32) -> JsValue { 405 | log::warn!("definition"); 406 | let line_index = self.analysis().file_line_index(self.file_id).unwrap(); 407 | 408 | let pos = file_position(line_number, column, &line_index, self.file_id); 409 | let nav_info = match self.analysis().goto_definition(pos) { 410 | Ok(Some(nav_info)) => nav_info, 411 | _ => return JsValue::NULL, 412 | }; 413 | 414 | let res = to_proto::location_links(nav_info, &line_index); 415 | serde_wasm_bindgen::to_value(&res).unwrap() 416 | } 417 | 418 | pub fn type_definition(&self, line_number: u32, column: u32) -> JsValue { 419 | log::warn!("type_definition"); 420 | let line_index = self.analysis().file_line_index(self.file_id).unwrap(); 421 | 422 | let pos = file_position(line_number, column, &line_index, self.file_id); 423 | let nav_info = match self.analysis().goto_type_definition(pos) { 424 | Ok(Some(nav_info)) => nav_info, 425 | _ => return JsValue::NULL, 426 | }; 427 | 428 | let res = to_proto::location_links(nav_info, &line_index); 429 | serde_wasm_bindgen::to_value(&res).unwrap() 430 | } 431 | 432 | pub fn document_symbols(&self) -> JsValue { 433 | log::warn!("document_symbols"); 434 | let line_index = self.analysis().file_line_index(self.file_id).unwrap(); 435 | 436 | let struct_nodes = match self.analysis().file_structure(self.file_id) { 437 | Ok(struct_nodes) => struct_nodes, 438 | _ => return JsValue::NULL, 439 | }; 440 | let mut parents: Vec<(DocumentSymbol, Option)> = Vec::new(); 441 | 442 | for symbol in struct_nodes { 443 | let doc_symbol = DocumentSymbol { 444 | name: symbol.label.clone(), 445 | detail: symbol.detail.unwrap_or(symbol.label), 446 | kind: to_proto::symbol_kind(symbol.kind), 447 | range: to_proto::text_range(symbol.node_range, &line_index), 448 | children: None, 449 | tags: [if symbol.deprecated { SymbolTag::Deprecated } else { SymbolTag::None }], 450 | containerName: None, 451 | selectionRange: to_proto::text_range(symbol.navigation_range, &line_index), 452 | }; 453 | parents.push((doc_symbol, symbol.parent)); 454 | } 455 | let mut res = Vec::new(); 456 | while let Some((node, parent)) = parents.pop() { 457 | match parent { 458 | None => res.push(node), 459 | Some(i) => { 460 | let children = &mut parents[i].0.children; 461 | if children.is_none() { 462 | *children = Some(Vec::new()); 463 | } 464 | children.as_mut().unwrap().push(node); 465 | } 466 | } 467 | } 468 | 469 | serde_wasm_bindgen::to_value(&res).unwrap() 470 | } 471 | 472 | pub fn type_formatting(&self, line_number: u32, column: u32, ch: char) -> JsValue { 473 | log::warn!("type_formatting"); 474 | let line_index = self.analysis().file_line_index(self.file_id).unwrap(); 475 | 476 | let mut pos = file_position(line_number, column, &line_index, self.file_id); 477 | pos.offset -= TextSize::of('.'); 478 | 479 | let edit = self.analysis().on_char_typed(pos, ch); 480 | 481 | let (_file, edit) = match edit { 482 | Ok(Some(it)) => it.source_file_edits.into_iter().next().unwrap(), 483 | _ => return JsValue::NULL, 484 | }; 485 | 486 | let change: Vec = to_proto::text_edits(edit, &line_index); 487 | serde_wasm_bindgen::to_value(&change).unwrap() 488 | } 489 | 490 | pub fn folding_ranges(&self) -> JsValue { 491 | log::warn!("folding_ranges"); 492 | let line_index = self.analysis().file_line_index(self.file_id).unwrap(); 493 | if let Ok(folds) = self.analysis().folding_ranges(self.file_id) { 494 | let res: Vec<_> = 495 | folds.into_iter().map(|fold| to_proto::folding_range(fold, &line_index)).collect(); 496 | serde_wasm_bindgen::to_value(&res).unwrap() 497 | } else { 498 | JsValue::NULL 499 | } 500 | } 501 | 502 | pub fn goto_implementation(&self, line_number: u32, column: u32) -> JsValue { 503 | log::warn!("goto_implementation"); 504 | let line_index = self.analysis().file_line_index(self.file_id).unwrap(); 505 | 506 | let pos = file_position(line_number, column, &line_index, self.file_id); 507 | let nav_info = match self.analysis().goto_implementation(pos) { 508 | Ok(Some(it)) => it, 509 | _ => return JsValue::NULL, 510 | }; 511 | let res = to_proto::location_links(nav_info, &line_index); 512 | serde_wasm_bindgen::to_value(&res).unwrap() 513 | } 514 | } 515 | 516 | impl Default for WorldState { 517 | fn default() -> Self { 518 | Self::new() 519 | } 520 | } 521 | 522 | fn file_position( 523 | line_number: u32, 524 | column: u32, 525 | line_index: &ide::LineIndex, 526 | file_id: ide::FileId, 527 | ) -> ide::FilePosition { 528 | let line_col = ide::LineCol { line: line_number - 1, col: column - 1 }; 529 | let offset = line_index.offset(line_col); 530 | ide::FilePosition { file_id, offset } 531 | } 532 | 533 | fn file_range( 534 | start_line_number: u32, 535 | start_column: u32, 536 | end_line_number: u32, 537 | end_column: u32, 538 | line_index: &ide::LineIndex, 539 | file_id: ide::FileId, 540 | ) -> ide::FileRange { 541 | let start_line_col = ide::LineCol { line: start_line_number - 1, col: start_column - 1 }; 542 | let end_line_col = ide::LineCol { line: end_line_number - 1, col: end_column - 1 }; 543 | ide::FileRange { 544 | file_id, 545 | range: ide::TextRange::new( 546 | line_index.offset(start_line_col), 547 | line_index.offset(end_line_col), 548 | ), 549 | } 550 | } 551 | -------------------------------------------------------------------------------- /ra-wasm/src/return_types.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | use serde_repr::Serialize_repr; 3 | 4 | #[derive(Serialize)] 5 | pub struct Hover { 6 | pub range: Range, 7 | pub contents: Vec, 8 | } 9 | 10 | #[derive(Serialize, Deserialize, Clone, Copy)] 11 | pub struct Range { 12 | pub startLineNumber: u32, 13 | pub startColumn: u32, 14 | pub endLineNumber: u32, 15 | pub endColumn: u32, 16 | } 17 | 18 | #[derive(Serialize)] 19 | pub struct MarkdownString { 20 | pub value: String, 21 | } 22 | 23 | #[derive(Serialize, Deserialize)] 24 | pub struct CodeLensSymbol { 25 | pub range: Range, 26 | pub command: Option, 27 | } 28 | 29 | #[derive(Serialize, Deserialize)] 30 | pub struct Command { 31 | pub id: String, 32 | pub title: String, 33 | pub positions: Vec, // customized 34 | } 35 | 36 | #[derive(Serialize)] 37 | pub struct Highlight { 38 | pub tag: Option, 39 | pub range: Range, 40 | } 41 | 42 | #[derive(Serialize_repr)] 43 | #[repr(u8)] 44 | pub enum InlayHintType { 45 | Type = 1, 46 | Parameter = 2, 47 | } 48 | 49 | #[derive(Serialize)] 50 | pub struct InlayHint { 51 | pub label: Option, 52 | pub hint_type: InlayHintType, 53 | pub range: Range, 54 | } 55 | 56 | #[derive(Serialize)] 57 | pub struct TextEdit { 58 | pub range: Range, 59 | pub text: String, 60 | } 61 | 62 | #[derive(Serialize)] 63 | pub struct UpdateResult { 64 | pub diagnostics: Vec, 65 | pub highlights: Vec, 66 | } 67 | 68 | #[derive(Serialize)] 69 | pub struct Diagnostic { 70 | pub message: String, 71 | pub startLineNumber: u32, 72 | pub startColumn: u32, 73 | pub endLineNumber: u32, 74 | pub endColumn: u32, 75 | pub severity: MarkerSeverity, 76 | } 77 | 78 | #[allow(dead_code)] 79 | #[derive(Serialize_repr)] 80 | #[repr(u8)] 81 | pub enum MarkerSeverity { 82 | Hint = 1, 83 | Info = 2, 84 | Warning = 4, 85 | Error = 8, 86 | } 87 | 88 | #[derive(Serialize)] 89 | pub struct RenameLocation { 90 | pub range: Range, 91 | pub text: String, 92 | } 93 | 94 | #[derive(Serialize)] 95 | pub struct CompletionItem { 96 | pub label: String, 97 | pub range: Range, 98 | pub kind: CompletionItemKind, 99 | pub detail: Option, 100 | pub insertText: String, 101 | pub insertTextRules: CompletionItemInsertTextRule, 102 | pub documentation: Option, 103 | pub filterText: String, 104 | pub additionalTextEdits: Vec, 105 | } 106 | 107 | #[allow(dead_code)] 108 | #[derive(Serialize_repr)] 109 | #[repr(u8)] 110 | pub enum CompletionItemKind { 111 | Method = 0, 112 | Function = 1, 113 | Constructor = 2, 114 | Field = 3, 115 | Variable = 4, 116 | Class = 5, 117 | Struct = 6, 118 | Interface = 7, 119 | Module = 8, 120 | Property = 9, 121 | Event = 10, 122 | Operator = 11, 123 | Unit = 12, 124 | Value = 13, 125 | Constant = 14, 126 | Enum = 15, 127 | EnumMember = 16, 128 | Keyword = 17, 129 | Text = 18, 130 | Color = 19, 131 | File = 20, 132 | Reference = 21, 133 | Customcolor = 22, 134 | Folder = 23, 135 | TypeParameter = 24, 136 | User = 25, 137 | Issue = 26, 138 | Snippet = 27, 139 | } 140 | 141 | #[allow(dead_code)] 142 | #[derive(Serialize_repr)] 143 | #[repr(u8)] 144 | pub enum CompletionItemInsertTextRule { 145 | None = 0, 146 | /** 147 | * Adjust whitespace/indentation of multiline insert texts to 148 | * match the current line indentation. 149 | */ 150 | KeepWhitespace = 1, 151 | /** 152 | * `insertText` is a snippet. 153 | */ 154 | InsertAsSnippet = 4, 155 | } 156 | 157 | #[derive(Serialize)] 158 | pub struct ParameterInformation { 159 | pub label: String, 160 | } 161 | 162 | #[derive(Serialize)] 163 | pub struct SignatureInformation { 164 | pub label: String, 165 | pub documentation: Option, 166 | pub parameters: Vec, 167 | } 168 | 169 | #[derive(Serialize)] 170 | pub struct SignatureHelp { 171 | pub signatures: [SignatureInformation; 1], 172 | pub activeSignature: u32, 173 | pub activeParameter: Option, 174 | } 175 | 176 | #[derive(Serialize)] 177 | pub struct LocationLink { 178 | pub originSelectionRange: Range, 179 | pub range: Range, 180 | pub targetSelectionRange: Range, 181 | } 182 | 183 | #[allow(dead_code)] 184 | #[derive(Serialize_repr)] 185 | #[repr(u8)] 186 | pub enum SymbolTag { 187 | None = 0, 188 | Deprecated = 1, 189 | } 190 | 191 | #[allow(dead_code)] 192 | #[derive(Serialize_repr)] 193 | #[repr(u8)] 194 | pub enum SymbolKind { 195 | File = 0, 196 | Module = 1, 197 | Namespace = 2, 198 | Package = 3, 199 | Class = 4, 200 | Method = 5, 201 | Property = 6, 202 | Field = 7, 203 | Constructor = 8, 204 | Enum = 9, 205 | Interface = 10, 206 | Function = 11, 207 | Variable = 12, 208 | Constant = 13, 209 | String = 14, 210 | Number = 15, 211 | Boolean = 16, 212 | Array = 17, 213 | Object = 18, 214 | Key = 19, 215 | Null = 20, 216 | EnumMember = 21, 217 | Struct = 22, 218 | Event = 23, 219 | Operator = 24, 220 | TypeParameter = 25, 221 | } 222 | 223 | #[derive(Serialize)] 224 | pub struct DocumentSymbol { 225 | pub name: String, 226 | pub detail: String, 227 | pub kind: SymbolKind, 228 | pub tags: [SymbolTag; 1], 229 | pub containerName: Option, 230 | pub range: Range, 231 | pub selectionRange: Range, 232 | pub children: Option>, 233 | } 234 | 235 | #[allow(dead_code)] 236 | #[derive(Serialize)] 237 | #[serde(rename_all = "lowercase")] 238 | pub enum FoldingRangeKind { 239 | Comment, 240 | Imports, 241 | Region, 242 | } 243 | 244 | #[derive(Serialize)] 245 | pub struct FoldingRange { 246 | pub start: u32, 247 | pub end: u32, 248 | pub kind: Option, 249 | } 250 | -------------------------------------------------------------------------------- /ra-wasm/src/to_proto.rs: -------------------------------------------------------------------------------- 1 | //! Conversion of rust-analyzer specific types to return_types equivalents. 2 | use crate::return_types; 3 | 4 | pub(crate) fn text_range( 5 | range: ide::TextRange, 6 | line_index: &ide::LineIndex, 7 | ) -> return_types::Range { 8 | let start = line_index.line_col(range.start()); 9 | let end = line_index.line_col(range.end()); 10 | 11 | return_types::Range { 12 | startLineNumber: start.line + 1, 13 | startColumn: start.col + 1, 14 | endLineNumber: end.line + 1, 15 | endColumn: end.col + 1, 16 | } 17 | } 18 | 19 | pub(crate) fn completion_item_kind( 20 | kind: ide::CompletionItemKind, 21 | ) -> return_types::CompletionItemKind { 22 | use return_types::CompletionItemKind::*; 23 | match kind { 24 | ide::CompletionItemKind::Keyword => Keyword, 25 | ide::CompletionItemKind::Snippet => Snippet, 26 | 27 | ide::CompletionItemKind::BuiltinType => Struct, 28 | ide::CompletionItemKind::Binding => Variable, 29 | ide::CompletionItemKind::SymbolKind(it) => match it { 30 | ide::SymbolKind::Const => Constant, 31 | ide::SymbolKind::ConstParam => Constant, 32 | ide::SymbolKind::Enum => Enum, 33 | ide::SymbolKind::Field => Field, 34 | ide::SymbolKind::Function => Function, 35 | ide::SymbolKind::Impl => Interface, 36 | ide::SymbolKind::Label => Constant, 37 | ide::SymbolKind::LifetimeParam => TypeParameter, 38 | ide::SymbolKind::Local => Variable, 39 | ide::SymbolKind::Macro => Function, 40 | ide::SymbolKind::Module => Module, 41 | ide::SymbolKind::SelfParam => Value, 42 | ide::SymbolKind::Static => Value, 43 | ide::SymbolKind::Struct => Struct, 44 | ide::SymbolKind::Trait => Interface, 45 | ide::SymbolKind::TypeAlias => Value, 46 | ide::SymbolKind::TypeParam => TypeParameter, 47 | ide::SymbolKind::Union => Struct, 48 | ide::SymbolKind::ValueParam => TypeParameter, 49 | ide::SymbolKind::Variant => User, 50 | }, 51 | ide::CompletionItemKind::Method => Method, 52 | ide::CompletionItemKind::Attribute => Property, 53 | ide::CompletionItemKind::UnresolvedReference => User, 54 | } 55 | } 56 | 57 | pub(crate) fn severity(s: ide::Severity) -> return_types::MarkerSeverity { 58 | match s { 59 | ide::Severity::Error => return_types::MarkerSeverity::Error, 60 | ide::Severity::WeakWarning => return_types::MarkerSeverity::Hint, 61 | } 62 | } 63 | 64 | pub(crate) fn text_edit(indel: &ide::Indel, line_index: &ide::LineIndex) -> return_types::TextEdit { 65 | let text = indel.insert.clone(); 66 | return_types::TextEdit { range: text_range(indel.delete, line_index), text } 67 | } 68 | 69 | pub(crate) fn text_edits(edit: ide::TextEdit, ctx: &ide::LineIndex) -> Vec { 70 | edit.iter().map(|atom| text_edit(atom, ctx)).collect() 71 | } 72 | 73 | pub(crate) fn completion_item( 74 | item: ide::CompletionItem, 75 | line_index: &ide::LineIndex, 76 | ) -> return_types::CompletionItem { 77 | let mut additional_text_edits = Vec::new(); 78 | let mut edit = None; 79 | // LSP does not allow arbitrary edits in completion, so we have to do a 80 | // non-trivial mapping here. 81 | for atom_edit in item.text_edit().iter() { 82 | if item.source_range().contains_range(atom_edit.delete) { 83 | edit = Some(if atom_edit.delete == item.source_range() { 84 | text_edit(atom_edit, line_index) 85 | } else { 86 | assert!(item.source_range().end() == atom_edit.delete.end()); 87 | let range1 = 88 | ide::TextRange::new(atom_edit.delete.start(), item.source_range().start()); 89 | let range2 = item.source_range(); 90 | let edit1 = ide::Indel::replace(range1, String::new()); 91 | let edit2 = ide::Indel::replace(range2, atom_edit.insert.clone()); 92 | additional_text_edits.push(text_edit(&edit1, line_index)); 93 | text_edit(&edit2, line_index) 94 | }) 95 | } else { 96 | edit = Some(text_edit(atom_edit, line_index)); 97 | } 98 | } 99 | let return_types::TextEdit { range, text } = edit.unwrap(); 100 | 101 | return_types::CompletionItem { 102 | kind: completion_item_kind(item.kind()), 103 | label: item.label().to_string(), 104 | range, 105 | detail: item.detail().map(|it| it.to_string()), 106 | insertText: text, 107 | insertTextRules: if item.is_snippet() { 108 | return_types::CompletionItemInsertTextRule::InsertAsSnippet 109 | } else { 110 | return_types::CompletionItemInsertTextRule::None 111 | }, 112 | documentation: item.documentation().map(|doc| markdown_string(doc.as_str())), 113 | filterText: item.lookup().to_string(), 114 | additionalTextEdits: additional_text_edits, 115 | } 116 | } 117 | 118 | pub(crate) fn signature_information( 119 | call_info: ide::CallInfo, 120 | ) -> return_types::SignatureInformation { 121 | use return_types::{ParameterInformation, SignatureInformation}; 122 | 123 | let label = call_info.signature.clone(); 124 | let documentation = call_info.doc.as_ref().map(|it| markdown_string(it)); 125 | 126 | let parameters: Vec = call_info 127 | .parameter_labels() 128 | .into_iter() 129 | .map(|param| ParameterInformation { label: param.to_string() }) 130 | .collect(); 131 | 132 | SignatureInformation { label, documentation, parameters } 133 | } 134 | 135 | pub(crate) fn location_links( 136 | nav_info: ide::RangeInfo>, 137 | line_index: &ide::LineIndex, 138 | ) -> Vec { 139 | let selection = text_range(nav_info.range, line_index); 140 | nav_info 141 | .info 142 | .into_iter() 143 | .map(|nav| { 144 | let range = text_range(nav.full_range, line_index); 145 | 146 | let target_selection_range = 147 | nav.focus_range.map(|it| text_range(it, line_index)).unwrap_or(range); 148 | 149 | return_types::LocationLink { 150 | originSelectionRange: selection, 151 | range, 152 | targetSelectionRange: target_selection_range, 153 | } 154 | }) 155 | .collect() 156 | } 157 | 158 | pub(crate) fn symbol_kind(kind: ide::StructureNodeKind) -> return_types::SymbolKind { 159 | use return_types::SymbolKind; 160 | 161 | let kind = match kind { 162 | ide::StructureNodeKind::SymbolKind(it) => it, 163 | ide::StructureNodeKind::Region => return SymbolKind::Property, 164 | }; 165 | 166 | match kind { 167 | ide::SymbolKind::Const => SymbolKind::Constant, 168 | ide::SymbolKind::ConstParam => SymbolKind::Constant, 169 | ide::SymbolKind::Enum => SymbolKind::Enum, 170 | ide::SymbolKind::Field => SymbolKind::Field, 171 | ide::SymbolKind::Function => SymbolKind::Function, 172 | ide::SymbolKind::Impl => SymbolKind::Interface, 173 | ide::SymbolKind::Label => SymbolKind::Constant, 174 | ide::SymbolKind::LifetimeParam => SymbolKind::TypeParameter, 175 | ide::SymbolKind::Local => SymbolKind::Variable, 176 | ide::SymbolKind::Macro => SymbolKind::Function, 177 | ide::SymbolKind::Module => SymbolKind::Module, 178 | ide::SymbolKind::SelfParam => SymbolKind::Variable, 179 | ide::SymbolKind::Static => SymbolKind::Constant, 180 | ide::SymbolKind::Struct => SymbolKind::Struct, 181 | ide::SymbolKind::Trait => SymbolKind::Interface, 182 | ide::SymbolKind::TypeAlias => SymbolKind::TypeParameter, 183 | ide::SymbolKind::TypeParam => SymbolKind::TypeParameter, 184 | ide::SymbolKind::Union => SymbolKind::Struct, 185 | ide::SymbolKind::ValueParam => SymbolKind::TypeParameter, 186 | ide::SymbolKind::Variant => SymbolKind::EnumMember, 187 | } 188 | } 189 | 190 | pub(crate) fn folding_range(fold: ide::Fold, ctx: &ide::LineIndex) -> return_types::FoldingRange { 191 | let range = text_range(fold.range, ctx); 192 | return_types::FoldingRange { 193 | start: range.startLineNumber, 194 | end: range.endLineNumber, 195 | kind: match fold.kind { 196 | ide::FoldKind::Comment => Some(return_types::FoldingRangeKind::Comment), 197 | ide::FoldKind::Imports => Some(return_types::FoldingRangeKind::Imports), 198 | ide::FoldKind::Region => Some(return_types::FoldingRangeKind::Region), 199 | _ => None, 200 | }, 201 | } 202 | } 203 | 204 | fn markdown_string(s: &str) -> return_types::MarkdownString { 205 | fn code_line_ignored_by_rustdoc(line: &str) -> bool { 206 | let trimmed = line.trim(); 207 | trimmed == "#" || trimmed.starts_with("# ") || trimmed.starts_with("#\t") 208 | } 209 | 210 | let mut processed_lines = Vec::new(); 211 | let mut in_code_block = false; 212 | for line in s.lines() { 213 | if in_code_block && code_line_ignored_by_rustdoc(line) { 214 | continue; 215 | } 216 | 217 | if line.starts_with("```") { 218 | in_code_block ^= true 219 | } 220 | 221 | let line = if in_code_block && line.starts_with("```") && !line.contains("rust") { 222 | "```rust" 223 | } else { 224 | line 225 | }; 226 | 227 | processed_lines.push(line); 228 | } 229 | 230 | return_types::MarkdownString { value: processed_lines.join("\n") } 231 | } 232 | -------------------------------------------------------------------------------- /rust-pack/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "rust-pack" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /rust-pack/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-pack" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [[bin]] 7 | name = "rust-pack" 8 | 9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 10 | 11 | [dependencies] 12 | -------------------------------------------------------------------------------- /rust-pack/src/main.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused)] 2 | use core::panic; 3 | use std::fs; 4 | use std::fs::read_to_string; 5 | use std::path::Path; 6 | use std::process::Command; 7 | 8 | mod remove_function; 9 | 10 | struct Mod<'a> { 11 | pub_prefix: &'a str, 12 | explicit_path: Option<&'a str>, 13 | name: &'a str, 14 | } 15 | 16 | #[derive(Default, Debug)] 17 | struct ModState<'a> { 18 | path_seen: Option<&'a str>, 19 | in_attribute: bool, 20 | } 21 | 22 | fn remove_comment(line: &str) -> &str { 23 | if let Some((l, _)) = line.split_once("//") { 24 | l.trim() 25 | } else { 26 | line 27 | } 28 | } 29 | 30 | fn clean_token(line: &str) -> &str { 31 | if let Some(l) = line.strip_prefix("r#") { 32 | l 33 | } else { 34 | line 35 | } 36 | } 37 | 38 | fn is_external_mod<'a>(mod_state: &mut ModState<'a>, line: &'a str) -> Option> { 39 | let line = remove_comment(line); 40 | if line.is_empty() { 41 | return None; 42 | } 43 | if line.starts_with("#[path = ") { 44 | mod_state.path_seen = Some(&line[10..line.len() - 2]); 45 | return None; 46 | } 47 | if line.starts_with("#[") { 48 | if !line.ends_with(']') { 49 | mod_state.in_attribute = true; 50 | } 51 | return None; 52 | } 53 | if mod_state.in_attribute { 54 | if line.ends_with(']') { 55 | mod_state.in_attribute = false; 56 | } 57 | return None; 58 | } 59 | let current_mod_state = std::mem::take(mod_state); 60 | if !line.ends_with(';') { 61 | return None; 62 | } 63 | let line = &line[..line.len() - 1]; 64 | if let Some(line) = line.strip_prefix("mod ") { 65 | Some(Mod { 66 | explicit_path: current_mod_state.path_seen, 67 | pub_prefix: "", 68 | name: clean_token(line), 69 | }) 70 | } else if let Some(line) = line.strip_prefix("pub mod ") { 71 | Some(Mod { 72 | explicit_path: current_mod_state.path_seen, 73 | pub_prefix: "pub ", 74 | name: clean_token(line), 75 | }) 76 | } else if let Some(line) = line.strip_prefix("pub(crate) mod ") { 77 | Some(Mod { 78 | explicit_path: current_mod_state.path_seen, 79 | pub_prefix: "pub(crate) ", 80 | name: clean_token(line), 81 | }) 82 | } else if let Some(line) = line.strip_prefix("pub(self) mod ") { 83 | Some(Mod { 84 | explicit_path: current_mod_state.path_seen, 85 | pub_prefix: "pub(self) ", 86 | name: clean_token(line), 87 | }) 88 | } else if let Some(line) = line.strip_prefix("pub(super) mod ") { 89 | Some(Mod { 90 | explicit_path: current_mod_state.path_seen, 91 | pub_prefix: "pub(super) ", 92 | name: clean_token(line), 93 | }) 94 | } else if let Some(line) = line.strip_prefix("pub(in ") { 95 | panic!("pub in not supported: {}", line); 96 | } else { 97 | None 98 | } 99 | } 100 | 101 | trait MyStringMethods { 102 | fn push_line(&mut self, line: &str); 103 | } 104 | 105 | impl MyStringMethods for String { 106 | fn push_line(&mut self, line: &str) { 107 | self.push_str(line); 108 | self.push('\n'); 109 | } 110 | } 111 | 112 | #[derive(Default, Debug)] 113 | struct MyError { 114 | libstack: Vec, 115 | cause_module: String, 116 | } 117 | 118 | fn put_module_in_string( 119 | output: &mut String, 120 | path: &Path, 121 | depth: usize, 122 | mut expand_cnt: i32, 123 | ) -> Result<(), MyError> { 124 | let src = read_to_string(path).map_err(|_x| MyError { 125 | libstack: vec![], 126 | cause_module: path.to_string_lossy().to_string(), 127 | })?; 128 | let mut mod_state = ModState::default(); 129 | for line in src.lines() { 130 | if let Some(m) = is_external_mod(&mut mod_state, line) { 131 | if expand_cnt == 0 { 132 | continue; 133 | }; 134 | let rr = 10000; 135 | expand_cnt -= 1; 136 | println!("{} mod found: {}", ">".repeat(depth), line); 137 | output.push_line(&format!("{}mod {} {{", m.pub_prefix, m.name)); 138 | let mut parent_path = path.parent().unwrap().to_owned(); 139 | let file_name = 140 | path.file_name().unwrap().to_str().unwrap().strip_suffix(".rs").unwrap(); 141 | if file_name != "lib" && file_name != "mod" { 142 | parent_path = parent_path.join(file_name); 143 | } 144 | let same_level_path = parent_path.join(format!("{}.rs", m.name)); 145 | let folder_path = parent_path.join(format!("{}/mod.rs", m.name)); 146 | let child_path = if let Some(ep) = m.explicit_path { 147 | println!("explicit path found: {:?}", ep); 148 | path.parent().unwrap().join(ep) 149 | } else if same_level_path.exists() { 150 | same_level_path 151 | } else if folder_path.exists() { 152 | folder_path 153 | } else { 154 | println!( 155 | "same_level_path: {:?}\nfolder_path: {:?}\n", 156 | same_level_path, folder_path 157 | ); 158 | return Err(MyError { 159 | libstack: vec![path.to_string_lossy().to_string()], 160 | cause_module: folder_path.to_string_lossy().to_string(), 161 | }); 162 | }; 163 | if let Err(mut e) = put_module_in_string(output, &child_path, depth + 1, rr) { 164 | e.libstack.push(path.to_string_lossy().to_string()); 165 | return Err(e); 166 | } 167 | output.push_line("}"); 168 | } else { 169 | output.push_line(line); 170 | } 171 | } 172 | Ok(()) 173 | } 174 | 175 | fn main() { 176 | let rustc_result = Command::new("rustc") 177 | .args(&["--print", "sysroot"]) 178 | .output() 179 | .expect("Failed to execute rustc") 180 | .stdout; 181 | let sysroot = std::str::from_utf8(&rustc_result).expect("rustc output wasn't utf8"); 182 | for what in &["std", "alloc", "core"] { 183 | let path_string = 184 | &format!("{}/lib/rustlib/src/rust/library/{}/src/lib.rs", sysroot.trim(), what); 185 | let path = Path::new(&path_string); 186 | let output_path = format!("../www/fake_{}.rs", what); 187 | let mut output = String::default(); 188 | put_module_in_string(&mut output, path, 0, 4000).unwrap(); 189 | //FIXME: add it when ready: output = remove_function_body(&output); 190 | fs::write(output_path, output.clone()).unwrap(); 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /rust-pack/src/remove_function.rs: -------------------------------------------------------------------------------- 1 | fn pick_char(input: &mut &str) -> char { 2 | let mut iter = input.chars(); 3 | let r = iter.next().unwrap(); 4 | *input = iter.as_str(); 5 | r 6 | } 7 | 8 | fn eat_until(input: &mut &str, output: &mut String, goal: char) { 9 | let mut paran = if goal == 'x' { 2 } else { 0 }; 10 | while input.len() > 0 { 11 | let c = input.chars().next().unwrap(); 12 | if paran > 0 { 13 | if c == ')' || c == ']' || c == '}' { 14 | paran -= 1; 15 | } 16 | } else { 17 | if c == goal || goal == 'x' { 18 | return; 19 | } 20 | if c == '(' || c == '[' || c == '{' { 21 | paran += 1; 22 | } 23 | } 24 | pick_char(input); 25 | output.push(c); 26 | } 27 | } 28 | 29 | pub fn remove_function_body(mut input: &str) -> String { 30 | let mut output = String::new(); 31 | let mut char_seened = 'x'; 32 | while input.len() > 0 { 33 | if char_seened.is_whitespace() { 34 | if let Some(remain) = input.strip_prefix("fn ") { 35 | output.push_str("fn "); 36 | input = remain; 37 | eat_until(&mut input, &mut output, '{'); 38 | output.push_str("{ loop {} }"); 39 | eat_until(&mut input, &mut String::new(), 'x'); 40 | } 41 | } 42 | if input.starts_with("//") { 43 | let (comment, remain) = input.split_once("\n").unwrap(); 44 | output.push_str(comment); 45 | input = remain; 46 | } 47 | char_seened = pick_char(&mut input); 48 | output.push(char_seened); 49 | } 50 | output 51 | } 52 | -------------------------------------------------------------------------------- /rust-toolchain: -------------------------------------------------------------------------------- 1 | nightly-2021-11-02 2 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | reorder_modules = false 2 | use_small_heuristics = "Max" 3 | newline_style = "Unix" 4 | -------------------------------------------------------------------------------- /www/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | fake_*.rs 4 | -------------------------------------------------------------------------------- /www/_headers: -------------------------------------------------------------------------------- 1 | /* 2 | Cross-Origin-Embedder-Policy: require-corp 3 | Cross-Origin-Opener-Policy: same-origin 4 | -------------------------------------------------------------------------------- /www/example-code.rs: -------------------------------------------------------------------------------- 1 | use std::ops::Range; 2 | 3 | fn gav(x: i32, y: i32) -> i64 { 4 | (x - y) * (x + y) 5 | } 6 | 7 | fn main() { 8 | let num = 5; 9 | let a = vec![1, 2, 3]; 10 | let b = Some(2); 11 | let c = None; 12 | let d = Range { start: 1, end: num }; 13 | let e = 1..num; 14 | let f = "sssss".to_string(); 15 | for a in d { 16 | for b in e { 17 | let c = gav(gav(a, b), a); 18 | assert_eq!(gav(a, b), a * a - b * b); 19 | } 20 | } 21 | let f = d 22 | .reduce(|a, b| { 23 | println!("{}", a); 24 | a * b 25 | }) 26 | .unwrap(); 27 | } 28 | -------------------------------------------------------------------------------- /www/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | width: calc(100vw - 1px); 3 | height: calc(100vh - 1px); 4 | margin: 0; 5 | } 6 | -------------------------------------------------------------------------------- /www/index.js: -------------------------------------------------------------------------------- 1 | import 'monaco-editor/esm/vs/editor/browser/controller/coreCommands'; 2 | import 'monaco-editor/esm/vs/editor/browser/widget/codeEditorWidget'; 3 | import 'monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget'; 4 | import 'monaco-editor/esm/vs/editor/browser/widget/diffNavigator'; 5 | import 'monaco-editor/esm/vs/editor/contrib/anchorSelect/anchorSelect'; 6 | import 'monaco-editor/esm/vs/editor/contrib/bracketMatching/bracketMatching'; 7 | import 'monaco-editor/esm/vs/editor/contrib/caretOperations/caretOperations'; 8 | import 'monaco-editor/esm/vs/editor/contrib/caretOperations/transpose'; 9 | import 'monaco-editor/esm/vs/editor/contrib/clipboard/clipboard'; 10 | import 'monaco-editor/esm/vs/editor/contrib/codeAction/codeActionContributions'; 11 | import 'monaco-editor/esm/vs/editor/contrib/codelens/codelensController'; 12 | import 'monaco-editor/esm/vs/editor/contrib/colorPicker/colorContributions'; 13 | import 'monaco-editor/esm/vs/editor/contrib/comment/comment'; 14 | import 'monaco-editor/esm/vs/editor/contrib/contextmenu/contextmenu'; 15 | import 'monaco-editor/esm/vs/editor/contrib/cursorUndo/cursorUndo'; 16 | import 'monaco-editor/esm/vs/editor/contrib/dnd/dnd'; 17 | import 'monaco-editor/esm/vs/editor/contrib/documentSymbols/documentSymbols'; 18 | import 'monaco-editor/esm/vs/editor/contrib/find/findController'; 19 | import 'monaco-editor/esm/vs/editor/contrib/folding/folding'; 20 | import 'monaco-editor/esm/vs/editor/contrib/fontZoom/fontZoom'; 21 | import 'monaco-editor/esm/vs/editor/contrib/format/formatActions'; 22 | import 'monaco-editor/esm/vs/editor/contrib/gotoError/gotoError'; 23 | import 'monaco-editor/esm/vs/editor/contrib/gotoSymbol/goToCommands'; 24 | import 'monaco-editor/esm/vs/editor/contrib/gotoSymbol/link/goToDefinitionAtPosition'; 25 | import 'monaco-editor/esm/vs/editor/contrib/hover/hover'; 26 | import 'monaco-editor/esm/vs/editor/contrib/inPlaceReplace/inPlaceReplace'; 27 | import 'monaco-editor/esm/vs/editor/contrib/indentation/indentation'; 28 | import 'monaco-editor/esm/vs/editor/contrib/inlayHints/inlayHintsController'; 29 | import 'monaco-editor/esm/vs/editor/contrib/linesOperations/linesOperations'; 30 | import 'monaco-editor/esm/vs/editor/contrib/linkedEditing/linkedEditing'; 31 | import 'monaco-editor/esm/vs/editor/contrib/links/links'; 32 | import 'monaco-editor/esm/vs/editor/contrib/multicursor/multicursor'; 33 | import 'monaco-editor/esm/vs/editor/contrib/parameterHints/parameterHints'; 34 | import 'monaco-editor/esm/vs/editor/contrib/rename/rename'; 35 | import 'monaco-editor/esm/vs/editor/contrib/smartSelect/smartSelect'; 36 | import 'monaco-editor/esm/vs/editor/contrib/snippet/snippetController2'; 37 | import 'monaco-editor/esm/vs/editor/contrib/suggest/suggestController'; 38 | import 'monaco-editor/esm/vs/editor/contrib/toggleTabFocusMode/toggleTabFocusMode'; 39 | import 'monaco-editor/esm/vs/editor/contrib/unusualLineTerminators/unusualLineTerminators'; 40 | import 'monaco-editor/esm/vs/editor/contrib/viewportSemanticTokens/viewportSemanticTokens'; 41 | import 'monaco-editor/esm/vs/editor/contrib/wordHighlighter/wordHighlighter'; 42 | import 'monaco-editor/esm/vs/editor/contrib/wordOperations/wordOperations'; 43 | import 'monaco-editor/esm/vs/editor/contrib/wordPartOperations/wordPartOperations'; 44 | import 'monaco-editor/esm/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp'; 45 | import 'monaco-editor/esm/vs/editor/standalone/browser/iPadShowKeyboard/iPadShowKeyboard'; 46 | import 'monaco-editor/esm/vs/editor/standalone/browser/inspectTokens/inspectTokens'; 47 | import 'monaco-editor/esm/vs/editor/standalone/browser/quickAccess/standaloneCommandsQuickAccess'; 48 | import 'monaco-editor/esm/vs/editor/standalone/browser/quickAccess/standaloneGotoLineQuickAccess'; 49 | import 'monaco-editor/esm/vs/editor/standalone/browser/quickAccess/standaloneGotoSymbolQuickAccess'; 50 | import 'monaco-editor/esm/vs/editor/standalone/browser/quickAccess/standaloneHelpQuickAccess'; 51 | import 'monaco-editor/esm/vs/editor/standalone/browser/referenceSearch/standaloneReferenceSearch'; 52 | import 'monaco-editor/esm/vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast'; 53 | 54 | import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'; 55 | import exampleCode from './example-code.rs'; 56 | 57 | import './index.css'; 58 | import { conf, grammar } from './rust-grammar'; 59 | import fake_std from './fake_std.rs'; 60 | import fake_core from './fake_core.rs'; 61 | import fake_alloc from './fake_alloc.rs'; 62 | 63 | var state; 64 | var allTokens; 65 | 66 | self.MonacoEnvironment = { 67 | getWorkerUrl: () => './editor.worker.bundle.js', 68 | }; 69 | 70 | const modeId = 'rust'; 71 | monaco.languages.register({ 72 | id: modeId, 73 | }); 74 | 75 | const delay = (ms) => new Promise((res) => setTimeout(res, ms)); 76 | 77 | monaco.languages.onLanguage(modeId, async () => { 78 | console.log(modeId); 79 | 80 | monaco.languages.setLanguageConfiguration(modeId, conf); 81 | monaco.languages.setMonarchTokensProvider(modeId, grammar); 82 | }); 83 | 84 | const registerRA = async () => { 85 | monaco.languages.registerHoverProvider(modeId, { 86 | provideHover: (_, pos) => state.hover(pos.lineNumber, pos.column), 87 | }); 88 | monaco.languages.registerCodeLensProvider(modeId, { 89 | async provideCodeLenses(m) { 90 | const code_lenses = await state.code_lenses(); 91 | const lenses = code_lenses.map(({ range, command }) => { 92 | const position = { 93 | column: range.startColumn, 94 | lineNumber: range.startLineNumber, 95 | }; 96 | 97 | const references = command.positions.map((pos) => ({ range: pos, uri: m.uri })); 98 | return { 99 | range, 100 | command: { 101 | id: command.id, 102 | title: command.title, 103 | arguments: [ 104 | m.uri, 105 | position, 106 | references, 107 | ], 108 | }, 109 | }; 110 | }); 111 | 112 | return { lenses, dispose() { } }; 113 | }, 114 | }); 115 | monaco.languages.registerReferenceProvider(modeId, { 116 | async provideReferences(m, pos, { includeDeclaration }) { 117 | const references = await state.references(pos.lineNumber, pos.column, includeDeclaration); 118 | if (references) { 119 | return references.map(({ range }) => ({ uri: m.uri, range })); 120 | } 121 | }, 122 | }); 123 | monaco.languages.registerInlayHintsProvider(modeId, { 124 | async provideInlayHints(model, range, token) { 125 | let hints = await state.inlay_hints(); 126 | return hints.map((hint) => { 127 | if (hint.hint_type == 1) { 128 | return { 129 | kind: 1, 130 | position: { column: hint.range.endColumn, lineNumber: hint.range.endLineNumber }, 131 | text: `: ${hint.label}`, 132 | }; 133 | } 134 | if (hint.hint_type == 2) { 135 | return { 136 | kind: 2, 137 | position: { column: hint.range.startColumn, lineNumber: hint.range.startLineNumber }, 138 | text: `${hint.label}:`, 139 | whitespaceAfter: true, 140 | }; 141 | } 142 | }) 143 | } 144 | }); 145 | monaco.languages.registerDocumentHighlightProvider(modeId, { 146 | async provideDocumentHighlights(_, pos) { 147 | return await state.references(pos.lineNumber, pos.column, true); 148 | } 149 | }); 150 | monaco.languages.registerRenameProvider(modeId, { 151 | async provideRenameEdits(m, pos, newName) { 152 | const edits = await state.rename(pos.lineNumber, pos.column, newName); 153 | if (edits) { 154 | return { 155 | edits: edits.map(edit => ({ 156 | resource: m.uri, 157 | edit, 158 | })), 159 | }; 160 | } 161 | }, 162 | async resolveRenameLocation(_, pos) { 163 | return state.prepare_rename(pos.lineNumber, pos.column); 164 | } 165 | }); 166 | monaco.languages.registerCompletionItemProvider(modeId, { 167 | triggerCharacters: [".", ":", "="], 168 | async provideCompletionItems(_m, pos) { 169 | const suggestions = await state.completions(pos.lineNumber, pos.column); 170 | if (suggestions) { 171 | return { suggestions }; 172 | } 173 | }, 174 | }); 175 | monaco.languages.registerSignatureHelpProvider(modeId, { 176 | signatureHelpTriggerCharacters: ['(', ','], 177 | async provideSignatureHelp(_m, pos) { 178 | const value = await state.signature_help(pos.lineNumber, pos.column); 179 | if (!value) return null; 180 | return { 181 | value, 182 | dispose() { }, 183 | }; 184 | }, 185 | }); 186 | monaco.languages.registerDefinitionProvider(modeId, { 187 | async provideDefinition(m, pos) { 188 | const list = await state.definition(pos.lineNumber, pos.column); 189 | if (list) { 190 | return list.map(def => ({ ...def, uri: m.uri })); 191 | } 192 | }, 193 | }); 194 | monaco.languages.registerTypeDefinitionProvider(modeId, { 195 | async provideTypeDefinition(m, pos) { 196 | const list = await state.type_definition(pos.lineNumber, pos.column); 197 | if (list) { 198 | return list.map(def => ({ ...def, uri: m.uri })); 199 | } 200 | }, 201 | }); 202 | monaco.languages.registerImplementationProvider(modeId, { 203 | async provideImplementation(m, pos) { 204 | const list = await state.goto_implementation(pos.lineNumber, pos.column); 205 | if (list) { 206 | return list.map(def => ({ ...def, uri: m.uri })); 207 | } 208 | }, 209 | }); 210 | monaco.languages.registerDocumentSymbolProvider(modeId, { 211 | async provideDocumentSymbols() { 212 | return await state.document_symbols(); 213 | } 214 | }); 215 | monaco.languages.registerOnTypeFormattingEditProvider(modeId, { 216 | autoFormatTriggerCharacters: [".", "="], 217 | async provideOnTypeFormattingEdits(_, pos, ch) { 218 | return await state.type_formatting(pos.lineNumber, pos.column, ch); 219 | } 220 | }); 221 | monaco.languages.registerFoldingRangeProvider(modeId, { 222 | async provideFoldingRanges() { 223 | return await state.folding_ranges(); 224 | } 225 | }); 226 | 227 | class TokenState { 228 | constructor(line = 0) { 229 | this.line = line; 230 | this.equals = () => true; 231 | } 232 | 233 | clone() { 234 | const res = new TokenState(this.line); 235 | res.line += 1; 236 | return res; 237 | } 238 | } 239 | 240 | function fixTag(tag) { 241 | switch (tag) { 242 | case 'builtin': return 'variable.predefined'; 243 | case 'attribute': return 'key'; 244 | case 'macro': return 'number.hex'; 245 | case 'literal': return 'number'; 246 | default: return tag; 247 | } 248 | } 249 | 250 | /*monaco.languages.setTokensProvider(modeId, { 251 | getInitialState: () => new TokenState(), 252 | tokenize(_, st) { 253 | const filteredTokens = allTokens 254 | .filter((token) => token.range.startLineNumber === st.line); 255 | 256 | const tokens = filteredTokens.map((token) => ({ 257 | startIndex: token.range.startColumn - 1, 258 | scopes: fixTag(token.tag), 259 | })); 260 | tokens.sort((a, b) => a.startIndex - b.startIndex); 261 | 262 | return { 263 | tokens, 264 | endState: new TokenState(st.line + 1), 265 | }; 266 | }, 267 | });*/ 268 | }; 269 | 270 | 271 | // Create an RA Web worker 272 | const createRA = async () => { 273 | const worker = new Worker(new URL('./ra-worker.js', import.meta.url)); 274 | const pendingResolve = {}; 275 | 276 | let id = 1; 277 | let ready; 278 | 279 | const callWorker = async (which, ...args) => { 280 | return new Promise((resolve, _) => { 281 | pendingResolve[id] = resolve; 282 | worker.postMessage({ 283 | "which": which, 284 | "args": args, 285 | "id": id 286 | }); 287 | id += 1; 288 | }); 289 | } 290 | 291 | const proxyHandler = { 292 | get: (target, prop, _receiver) => { 293 | if (prop == "then") { 294 | return Reflect.get(target, prop, _receiver); 295 | } 296 | return async (...args) => { 297 | return callWorker(prop, ...args); 298 | } 299 | } 300 | } 301 | 302 | worker.onmessage = (e) => { 303 | if (e.data.id == "ra-worker-ready") { 304 | ready(new Proxy({}, proxyHandler)); 305 | return; 306 | } 307 | const pending = pendingResolve[e.data.id]; 308 | if (pending) { 309 | pending(e.data.result); 310 | delete pendingResolve[e.data.id]; 311 | } 312 | } 313 | 314 | return new Promise((resolve, _) => { 315 | ready = resolve; 316 | }); 317 | } 318 | 319 | const start = async () => { 320 | var loadingText = document.createTextNode("Loading wasm..."); 321 | document.body.appendChild(loadingText); 322 | 323 | let model = monaco.editor.createModel(exampleCode, modeId); 324 | window.editor = monaco.editor; 325 | state = null; //await createRA(); 326 | 327 | async function update() { 328 | const res = await state.update(model.getValue()); 329 | monaco.editor.setModelMarkers(model, modeId, res.diagnostics); 330 | allTokens = res.highlights; 331 | } 332 | 333 | monaco.editor.defineTheme('vscode-dark-plus', { 334 | base: 'vs-dark', 335 | inherit: true, 336 | colors: { 337 | 'editorInlayHint.foreground': '#A0A0A0F0', 338 | 'editorInlayHint.background': '#11223300', 339 | }, 340 | rules: [ 341 | { token: 'keyword.control', foreground: 'C586C0' }, 342 | { token: 'variable', foreground: '9CDCFE' }, 343 | { token: 'support.function', foreground: 'DCDCAA' }, 344 | ], 345 | }); 346 | document.body.removeChild(loadingText); 347 | const initRA = async () => { 348 | state = await createRA(); 349 | await registerRA(); 350 | await state.init(model.getValue(), fake_std, fake_core, fake_alloc); 351 | await update(); 352 | model.onDidChangeContent(update); 353 | }; 354 | initRA(); 355 | const myEditor = monaco.editor.create(document.body, { 356 | theme: 'vscode-dark-plus', 357 | model: model 358 | }); 359 | 360 | window.onresize = () => myEditor.layout(); 361 | }; 362 | 363 | start().then(() => { 364 | console.log("start"); 365 | }) 366 | 367 | -------------------------------------------------------------------------------- /www/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ra-wasm-demo", 3 | "version": "0.1.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "build": "webpack --config webpack.config.js --mode production", 7 | "start": "webpack serve --host 0.0.0.0" 8 | }, 9 | "author": "rust-analyzer developers", 10 | "license": "(MIT OR Apache-2.0)", 11 | "dependencies": { 12 | "monaco-editor": "^0.27.0", 13 | "raw-loader": "^4.0.2", 14 | "text-encoding": "^0.7.0" 15 | }, 16 | "devDependencies": { 17 | "css-loader": "^5.1.3", 18 | "file-loader": "^6.2.0", 19 | "html-webpack-plugin": "^5.3.1", 20 | "style-loader": "^2.0.0", 21 | "webpack": "^5.27.1", 22 | "webpack-cli": "^4.5.0", 23 | "webpack-dev-server": "^3.11.2" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /www/ra-worker.js: -------------------------------------------------------------------------------- 1 | import init, { initThreadPool, WorldState } from '../ra-wasm/pkg/wasm_demo.js'; 2 | 3 | const start = async () => { 4 | await init(); 5 | 6 | // Thread pool initialization with the given number of threads 7 | // (pass `navigator.hardwareConcurrency` if you want to use all cores). 8 | await initThreadPool(navigator.hardwareConcurrency) 9 | 10 | const state = new WorldState(); 11 | 12 | onmessage = (e) => { 13 | const { which, args, id } = e.data; 14 | const result = state[which](...args); 15 | 16 | postMessage({ 17 | id: id, 18 | result: result 19 | }); 20 | }; 21 | }; 22 | 23 | start().then(() => { 24 | postMessage({ 25 | id: "ra-worker-ready" 26 | }) 27 | }) 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /www/rust-grammar.js: -------------------------------------------------------------------------------- 1 | export const conf = { 2 | comments: { 3 | lineComment: '//', 4 | blockComment: ['/*', '*/'] 5 | }, 6 | brackets: [ 7 | ['{', '}'], 8 | ['[', ']'], 9 | ['(', ')'] 10 | ], 11 | autoClosingPairs: [ 12 | { open: '[', close: ']' }, 13 | { open: '{', close: '}' }, 14 | { open: '(', close: ')' }, 15 | { open: '"', close: '"', notIn: ['string'] } 16 | ], 17 | surroundingPairs: [ 18 | { open: '{', close: '}' }, 19 | { open: '[', close: ']' }, 20 | { open: '(', close: ')' }, 21 | { open: '"', close: '"' }, 22 | { open: "'", close: "'" } 23 | ], 24 | folding: { 25 | markers: { 26 | start: new RegExp('^\\s*#pragma\\s+region\\b'), 27 | end: new RegExp('^\\s*#pragma\\s+endregion\\b') 28 | } 29 | } 30 | }; 31 | 32 | export const grammar = { 33 | // Set defaultToken to invalid to see what you do not tokenize yet 34 | // defaultToken: 'invalid', 35 | 36 | keywords: [ 37 | 'as', 'break', 'const', 'crate', 'enum', 'extern', 'false', 'fn', 'impl', 'in', 38 | 'let', 'mod', 'move', 'mut', 'pub', 'ref', 'return', 'self', 'Self', 'static', 39 | 'struct', 'super', 'trait', 'true', 'type', 'unsafe', 'use', 'where', 40 | 'macro_rules', 41 | ], 42 | 43 | controlFlowKeywords: [ 44 | 'continue', 'else', 'for', 'if', 'while', 'loop', 'match', 45 | ], 46 | 47 | typeKeywords: [ 48 | 'Self', 'm32', 'm64', 'm128', 'f80', 'f16', 'f128', 'int', 'uint', 'float', 'char', 49 | 'bool', 'u8', 'u16', 'u32', 'u64', 'f32', 'f64', 'i8', 'i16', 'i32', 'i64', 'str', 50 | 'Option', 'Either', 'c_float', 'c_double', 'c_void', 'FILE', 'fpos_t', 'DIR', 'dirent', 51 | 'c_char', 'c_schar', 'c_uchar', 'c_short', 'c_ushort', 'c_int', 'c_uint', 'c_long', 'c_ulong', 52 | 'size_t', 'ptrdiff_t', 'clock_t', 'time_t', 'c_longlong', 'c_ulonglong', 'intptr_t', 53 | 'uintptr_t', 'off_t', 'dev_t', 'ino_t', 'pid_t', 'mode_t', 'ssize_t', 54 | ], 55 | 56 | operators: [ 57 | '=', '>', '<', '!', '~', '?', ':', '==', '<=', '>=', '!=', 58 | '&&', '||', '++', '--', '+', '-', '*', '/', '&', '|', '^', '%', 59 | '<<', '>>', '>>>', '+=', '-=', '*=', '/=', '&=', '|=', '^=', 60 | '%=', '<<=', '>>=', '>>>=' 61 | ], 62 | 63 | // we include these common regular expressions 64 | symbols: /[=>](?!@symbols)/, '@brackets'], 90 | [/@symbols/, { cases: { '@operators': 'operator', 91 | '@default' : '' } } ], 92 | 93 | // @ annotations. 94 | // As an example, we emit a debugging log message on these tokens. 95 | // Note: message are supressed during the first load -- change some lines to see them. 96 | [/@\s*[a-zA-Z_\$][\w\$]*/, { token: 'annotation', log: 'annotation token: $0' }], 97 | 98 | // numbers 99 | [/\d*\.\d+([eE][\-+]?\d+)?/, 'number.float'], 100 | [/0[xX][0-9a-fA-F]+/, 'number.hex'], 101 | [/\d+/, 'number'], 102 | 103 | // delimiter: after number because of .\d floats 104 | [/[;,.]/, 'delimiter'], 105 | 106 | // strings 107 | [/"([^"\\]|\\.)*$/, 'string.invalid' ], // non-teminated string 108 | [/"/, { token: 'string.quote', bracket: '@open', next: '@string' } ], 109 | 110 | // characters 111 | [/'[^\\']'/, 'string'], 112 | [/(')(@escapes)(')/, ['string','string.escape','string']], 113 | [/'/, 'string.invalid'] 114 | ], 115 | 116 | comment: [ 117 | [/[^\/*]+/, 'comment' ], 118 | [/\/\*/, 'comment', '@push' ], // nested comment 119 | ["\\*/", 'comment', '@pop' ], 120 | [/[\/*]/, 'comment' ] 121 | ], 122 | 123 | string: [ 124 | [/[^\\"]+/, 'string'], 125 | [/@escapes/, 'string.escape'], 126 | [/\\./, 'string.escape.invalid'], 127 | [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' } ] 128 | ], 129 | 130 | whitespace: [ 131 | [/[ \t\r\n]+/, 'white'], 132 | [/\/\*/, 'comment', '@comment' ], 133 | [/\/\/.*$/, 'comment'], 134 | ], 135 | 136 | func_decl: [ 137 | [ 138 | /[a-z_$][\w$]*/, 'support.function', '@pop', 139 | ], 140 | ], 141 | }, 142 | }; 143 | -------------------------------------------------------------------------------- /www/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const HtmlWebPackPlugin = require("html-webpack-plugin"); 3 | 4 | module.exports = { 5 | mode: "development", 6 | entry: { 7 | app: "./index.js", 8 | ra: "./ra-worker.js", 9 | "editor.worker": "monaco-editor/esm/vs/editor/editor.worker.js", 10 | }, 11 | output: { 12 | globalObject: "self", 13 | filename: "[name].bundle.js", 14 | path: path.resolve(__dirname, "dist"), 15 | }, 16 | module: { 17 | rules: [ 18 | { 19 | test: /\.css$/, 20 | use: ["style-loader", "css-loader"], 21 | }, 22 | { 23 | test: /\.rs$/, 24 | use: ['raw-loader'], 25 | }, 26 | { 27 | test: /\.ttf$/, 28 | use: ['file-loader'] 29 | } 30 | ], 31 | }, 32 | plugins: [ 33 | new HtmlWebPackPlugin({ 34 | title: "Rust Analyzer Playground", 35 | chunks: ["app"], 36 | }), 37 | ], 38 | // It is needed for firefox works 39 | devServer: { 40 | headers: { 41 | 'Cross-Origin-Embedder-Policy': 'require-corp', 42 | 'Cross-Origin-Opener-Policy': 'same-origin' 43 | }, 44 | }, 45 | }; 46 | --------------------------------------------------------------------------------