diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
index 83af2ccb..0b9e59ad 100644
--- a/.github/workflows/build-and-test.yml
+++ b/.github/workflows/build-and-test.yml
@@ -19,11 +19,20 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
- - name: Use Rust stable
+ - name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- - name: Build with Cargo
+ - name: Setup npm
+ uses: actions/setup-node@v4
+
+ - name: Build Rust code
run: cargo build --release --workspace
- - name: Run tests
- run: cargo test --verbose
\ No newline at end of file
+ - name: Run Rust tests
+ run: cargo test --verbose
+
+ - name: Check VSCode client
+ working-directory: 'editors/vscode'
+ run: |
+ npm ci
+ npm run check
\ No newline at end of file
diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml
index 734abff5..c33d89f9 100644
--- a/.github/workflows/draft-release.yml
+++ b/.github/workflows/draft-release.yml
@@ -8,6 +8,9 @@ env:
CARGO_TERM_COLOR: always
IS_PRE_RELEASE: ${{ contains(github.ref_name, 'dev') }}
+permissions:
+ issues: write
+
jobs:
build:
strategy:
@@ -37,8 +40,10 @@ jobs:
- name: Build xtask
run: cargo build --package xtask --release
- - name: Prepare the server executable
+ - name: Prepare the LSP server executable
run: cargo xtask prep-server --target ${{ matrix.target }} --release
+ - name: Download rw3d_cli
+ run: cargo xtask prep-rw3d
- name: Package the extension (pre-release)
if: ${{ env.IS_PRE_RELEASE == 'true' }}
@@ -75,6 +80,17 @@ jobs:
generateReleaseNotes: true
prerelease: ${{ env.IS_PRE_RELEASE }}
+
+ - name: Require manual approval to upload the extension to marketplaces
+ if: ${{ env.IS_PRE_RELEASE == 'false' }}
+ uses: trstringer/manual-approval@v1
+ with:
+ secret: ${{ github.TOKEN }}
+ approvers: SpontanCombust
+ minimum-approvals: 1
+ issue-title: "Deploying ${{ github.ref_name }} to marketplaces from staging"
+ issue-body: "Please approve or deny the deployment of version ${{ github.ref_name }}."
+
# The VS Marketplace doesn't yet support pre-release semver versions, sigh....
# https://code.visualstudio.com/api/working-with-extensions/publishing-extension#prerelease-extensions
# - name: Upload extension to VSCode Marketplace (pre-release)
diff --git a/.gitignore b/.gitignore
index a7a8ad8f..27aa5bb1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,7 +4,7 @@
/editors/vscode/node_modules
/editors/vscode/out
-/editors/vscode/server
+/editors/vscode/deps/**
*.vsix
/site
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 686dfb7d..9ecb0f69 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -21,10 +21,10 @@
"type": "lldb",
"request": "attach",
"windows": {
- "program": "${workspaceFolder}/server/bin/witcherscript-lsp.exe",
+ "program": "${workspaceFolder}/deps/lsp_server/bin/witcherscript-lsp.exe",
},
"linux": {
- "program": "${workspaceFolder}/server/bin/witcherscript-lsp"
+ "program": "${workspaceFolder}/deps/lsp_server/bin/witcherscript-lsp"
}
}
]
diff --git a/Cargo.lock b/Cargo.lock
index 4413cb2c..6c643178 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4,7 +4,7 @@ version = 3
[[package]]
name = "abs-path"
-version = "0.3.2"
+version = "0.4.0"
dependencies = [
"lsp-types",
"serde",
@@ -27,6 +27,17 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+[[package]]
+name = "aes"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
+dependencies = [
+ "cfg-if",
+ "cipher",
+ "cpufeatures",
+]
+
[[package]]
name = "aho-corasick"
version = "1.1.2"
@@ -90,6 +101,15 @@ version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
+[[package]]
+name = "arbitrary"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"
+dependencies = [
+ "derive_arbitrary",
+]
+
[[package]]
name = "async-trait"
version = "0.1.76"
@@ -149,17 +169,63 @@ dependencies = [
"syn 2.0.48",
]
+[[package]]
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+
+[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
[[package]]
name = "bytes"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
+[[package]]
+name = "bzip2"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8"
+dependencies = [
+ "bzip2-sys",
+ "libc",
+]
+
+[[package]]
+name = "bzip2-sys"
+version = "0.1.11+1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+]
+
[[package]]
name = "cc"
version = "1.0.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
+dependencies = [
+ "jobserver",
+ "libc",
+]
[[package]]
name = "cfg-if"
@@ -167,6 +233,16 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+[[package]]
+name = "cipher"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
+dependencies = [
+ "crypto-common",
+ "inout",
+]
+
[[package]]
name = "clap"
version = "4.4.18"
@@ -213,6 +289,45 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
+[[package]]
+name = "constant_time_eq"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2"
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crc"
+version = "3.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636"
+dependencies = [
+ "crc-catalog",
+]
+
+[[package]]
+name = "crc-catalog"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
+
+[[package]]
+name = "crc32fast"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
+dependencies = [
+ "cfg-if",
+]
+
[[package]]
name = "crossbeam-deque"
version = "0.8.5"
@@ -234,9 +349,19 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
-version = "0.8.19"
+version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
+checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
[[package]]
name = "dashmap"
@@ -251,6 +376,54 @@ dependencies = [
"parking_lot_core",
]
+[[package]]
+name = "deflate64"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b"
+
+[[package]]
+name = "deranged"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
+dependencies = [
+ "powerfmt",
+]
+
+[[package]]
+name = "derive_arbitrary"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.48",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer",
+ "crypto-common",
+ "subtle",
+]
+
+[[package]]
+name = "displaydoc"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.48",
+]
+
[[package]]
name = "dyn-clone"
version = "1.0.16"
@@ -299,6 +472,16 @@ dependencies = [
"windows-sys",
]
+[[package]]
+name = "flate2"
+version = "1.0.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
[[package]]
name = "form_urlencoded"
version = "1.2.1"
@@ -385,6 +568,27 @@ dependencies = [
"slab",
]
+[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
[[package]]
name = "gimli"
version = "0.28.1"
@@ -409,6 +613,15 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
+[[package]]
+name = "hmac"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
+dependencies = [
+ "digest",
+]
+
[[package]]
name = "httparse"
version = "1.8.0"
@@ -435,6 +648,15 @@ dependencies = [
"hashbrown",
]
+[[package]]
+name = "inout"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
+dependencies = [
+ "generic-array",
+]
+
[[package]]
name = "itertools"
version = "0.8.2"
@@ -450,6 +672,15 @@ version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
+[[package]]
+name = "jobserver"
+version = "0.1.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "libc"
version = "0.2.153"
@@ -466,6 +697,18 @@ dependencies = [
"scopeguard",
]
+[[package]]
+name = "lockfree-object-pool"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e"
+
+[[package]]
+name = "log"
+version = "0.4.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+
[[package]]
name = "lsp-types"
version = "0.94.1"
@@ -479,11 +722,21 @@ dependencies = [
"url",
]
+[[package]]
+name = "lzma-rs"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e"
+dependencies = [
+ "byteorder",
+ "crc",
+]
+
[[package]]
name = "memchr"
-version = "2.6.4"
+version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "miniz_oxide"
@@ -494,6 +747,12 @@ dependencies = [
"adler",
]
+[[package]]
+name = "num-conv"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
+
[[package]]
name = "num_cpus"
version = "1.16.0"
@@ -532,6 +791,16 @@ dependencies = [
"windows-targets 0.48.5",
]
+[[package]]
+name = "pbkdf2"
+version = "0.12.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2"
+dependencies = [
+ "digest",
+ "hmac",
+]
+
[[package]]
name = "percent-encoding"
version = "2.3.1"
@@ -570,6 +839,24 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+[[package]]
+name = "pkg-config"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
+
+[[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+
[[package]]
name = "proc-macro2"
version = "1.0.78"
@@ -594,6 +881,36 @@ dependencies = [
"proc-macro2",
]
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom",
+]
+
[[package]]
name = "rayon"
version = "1.9.0"
@@ -746,6 +1063,17 @@ dependencies = [
"serde",
]
+[[package]]
+name = "sha1"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
[[package]]
name = "shrinkwraprs"
version = "0.3.0"
@@ -759,6 +1087,12 @@ dependencies = [
"syn 1.0.109",
]
+[[package]]
+name = "simd-adler32"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
+
[[package]]
name = "slab"
version = "0.4.9"
@@ -805,6 +1139,12 @@ dependencies = [
"syn 2.0.48",
]
+[[package]]
+name = "subtle"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
+
[[package]]
name = "syn"
version = "1.0.109"
@@ -829,24 +1169,43 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "1.0.50"
+version = "1.0.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
+checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.50"
+version = "1.0.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
+checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
]
+[[package]]
+name = "time"
+version = "0.3.36"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
+dependencies = [
+ "deranged",
+ "num-conv",
+ "powerfmt",
+ "serde",
+ "time-core",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
+
[[package]]
name = "tinyvec"
version = "1.6.0"
@@ -864,9 +1223,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.35.1"
+version = "1.38.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104"
+checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a"
dependencies = [
"backtrace",
"num_cpus",
@@ -876,9 +1235,9 @@ dependencies = [
[[package]]
name = "tokio-macros"
-version = "2.2.0"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
+checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
dependencies = [
"proc-macro2",
"quote",
@@ -1043,6 +1402,12 @@ dependencies = [
"tree-sitter",
]
+[[package]]
+name = "typenum"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
+
[[package]]
name = "unicode-bidi"
version = "0.3.14"
@@ -1082,6 +1447,18 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
[[package]]
name = "windows-sys"
version = "0.52.0"
@@ -1216,7 +1593,7 @@ dependencies = [
[[package]]
name = "witcherscript"
-version = "0.3.2"
+version = "0.4.0"
dependencies = [
"abs-path",
"encoding_rs_io",
@@ -1232,7 +1609,7 @@ dependencies = [
[[package]]
name = "witcherscript-analysis"
-version = "0.3.2"
+version = "0.4.0"
dependencies = [
"abs-path",
"lsp-types",
@@ -1249,7 +1626,7 @@ dependencies = [
[[package]]
name = "witcherscript-diagnostics"
-version = "0.3.2"
+version = "0.4.0"
dependencies = [
"abs-path",
"lsp-types",
@@ -1259,7 +1636,7 @@ dependencies = [
[[package]]
name = "witcherscript-lsp"
-version = "0.3.2"
+version = "0.4.0"
dependencies = [
"abs-path",
"bitmask-enum",
@@ -1268,6 +1645,7 @@ dependencies = [
"rayon",
"serde",
"serde_json",
+ "serde_repr",
"shrinkwraprs",
"thiserror",
"tokio",
@@ -1280,7 +1658,7 @@ dependencies = [
[[package]]
name = "witcherscript-project"
-version = "0.3.2"
+version = "0.4.0"
dependencies = [
"abs-path",
"dyn-clone",
@@ -1313,10 +1691,102 @@ checksum = "7e2c411759b501fb9501aac2b1b2d287a6e93e5bdcf13c25306b23e1b716dd0e"
[[package]]
name = "xtask"
-version = "0.3.2"
+version = "0.4.0"
dependencies = [
"anyhow",
"clap",
"project-root",
"xshell",
+ "zip",
+]
+
+[[package]]
+name = "zeroize"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
+dependencies = [
+ "zeroize_derive",
+]
+
+[[package]]
+name = "zeroize_derive"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.48",
+]
+
+[[package]]
+name = "zip"
+version = "2.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "775a2b471036342aa69bc5a602bc889cb0a06cda00477d0c69566757d5553d39"
+dependencies = [
+ "aes",
+ "arbitrary",
+ "bzip2",
+ "constant_time_eq",
+ "crc32fast",
+ "crossbeam-utils",
+ "deflate64",
+ "displaydoc",
+ "flate2",
+ "hmac",
+ "indexmap",
+ "lzma-rs",
+ "memchr",
+ "pbkdf2",
+ "rand",
+ "sha1",
+ "thiserror",
+ "time",
+ "zeroize",
+ "zopfli",
+ "zstd",
+]
+
+[[package]]
+name = "zopfli"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946"
+dependencies = [
+ "bumpalo",
+ "crc32fast",
+ "lockfree-object-pool",
+ "log",
+ "once_cell",
+ "simd-adler32",
+]
+
+[[package]]
+name = "zstd"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9"
+dependencies = [
+ "zstd-safe",
+]
+
+[[package]]
+name = "zstd-safe"
+version = "7.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa556e971e7b568dc775c136fc9de8c779b1c2fc3a63defaafadffdbd3181afa"
+dependencies = [
+ "zstd-sys",
+]
+
+[[package]]
+name = "zstd-sys"
+version = "2.0.12+zstd.1.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a4e40c320c3cb459d9a9ff6de98cff88f4751ee9275d140e2be94a2b74e4c13"
+dependencies = [
+ "cc",
+ "pkg-config",
]
diff --git a/Cargo.toml b/Cargo.toml
index 57b09cb9..44a64013 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,7 +3,7 @@ members = ["crates/*", "xtask"]
resolver = "2"
[workspace.package]
-version = "0.3.2"
+version = "0.4.0"
edition = "2021"
authors = ["SpontanCombust"]
@@ -21,6 +21,7 @@ clap = {version = "4.4", features = ["derive"]}
anyhow = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
+serde_repr = "0.1"
toml = "0.8"
semver = { version = "1.0", features = ["serde"] }
dyn-clone = "1.0"
diff --git a/README.md b/README.md
index 616b9420..4f5b544c 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,8 @@

-
+
+
***WIDE*** (**W**itcherScript **I**ntegrated **D**evelopment **E**nvironment) is unofficial Witcher 3 modding tooling aimed at improving developer experience by supplying them with powerful code analysis tools in the form of an editor extension making use of a Language Server.
diff --git a/crates/abs-path/src/lib.rs b/crates/abs-path/src/lib.rs
index a963bbd8..cb506424 100644
--- a/crates/abs-path/src/lib.rs
+++ b/crates/abs-path/src/lib.rs
@@ -145,7 +145,14 @@ impl TryFrom for AbsPath {
let path = value.to_file_path()?;
Ok(Self::resolve(path, None).unwrap())
}
-
+}
+
+impl TryFrom for AbsPath {
+ type Error = self::Error;
+
+ fn try_from(value: PathBuf) -> Result {
+ Self::resolve(value, None)
+ }
}
impl Into for AbsPath {
diff --git a/crates/analysis/src/jobs/scan_symbols.rs b/crates/analysis/src/jobs/scan_symbols.rs
index 4693d4ff..3345a75b 100644
--- a/crates/analysis/src/jobs/scan_symbols.rs
+++ b/crates/analysis/src/jobs/scan_symbols.rs
@@ -594,7 +594,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> {
}
}
- fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, _: DeclarationTraversalContext) -> FunctionDeclarationTraversalPolicy {
+ fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, _: &TraversalContextStack) -> FunctionDeclarationTraversalPolicy {
let mut traverse = false;
let name_node = n.name();
@@ -615,7 +615,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> {
}
}
- fn exit_member_func_decl(&mut self, _: &FunctionDeclarationNode, _: DeclarationTraversalContext) {
+ fn exit_member_func_decl(&mut self, _: &FunctionDeclarationNode, _: &TraversalContextStack) {
// pop only if visit managed to create the symbol
if self.current_path.components().last().map(|comp| comp.category == SymbolCategory::Callable).unwrap_or(false) {
self.current_path.pop();
@@ -623,7 +623,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> {
}
}
- fn visit_event_decl(&mut self, n: &EventDeclarationNode, _: DeclarationTraversalContext) -> EventDeclarationTraversalPolicy {
+ fn visit_event_decl(&mut self, n: &EventDeclarationNode, _: &TraversalContextStack) -> EventDeclarationTraversalPolicy {
let mut traverse = false;
let name_node = n.name();
@@ -649,14 +649,14 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> {
}
}
- fn exit_event_decl(&mut self, _: &EventDeclarationNode, _: DeclarationTraversalContext) {
+ fn exit_event_decl(&mut self, _: &EventDeclarationNode, _: &TraversalContextStack) {
if self.current_path.components().last().map(|comp| comp.category == SymbolCategory::Callable).unwrap_or(false) {
self.current_path.pop();
self.current_param_ordinal = 0;
}
}
- fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, _: FunctionTraversalContext) {
+ fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, _: &TraversalContextStack) {
let specifiers: SymbolSpecifiers<_> = n.specifiers()
.map(|sn| sn.value())
.filter_map(|s| FunctionParameterSpecifier::try_from(s).ok())
@@ -686,7 +686,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> {
}
}
- fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, _: DeclarationTraversalContext) {
+ fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, _: &TraversalContextStack) {
let specifiers: SymbolSpecifiers<_> = n.specifiers()
.map(|sn| sn.value())
.filter_map(|s| MemberVarSpecifier::try_from(s).ok())
@@ -730,7 +730,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> {
}
}
- fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, _: DeclarationTraversalContext) {
+ fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, _: &TraversalContextStack) {
let name_node = n.name();
let autobind_name = name_node.value(&self.doc);
let path = MemberDataSymbolPath::new(&self.current_path, &autobind_name);
@@ -755,7 +755,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> {
- fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, _: StatementTraversalContext) -> VarDeclarationTraversalPolicy {
+ fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, _: &TraversalContextStack) -> VarDeclarationTraversalPolicy {
let type_path = self.check_type_from_type_annot(n.var_type());
for name_node in n.names() {
@@ -779,27 +779,27 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> {
}
}
- fn visit_compound_stmt(&mut self, _: &CompoundStatementNode, _: StatementTraversalContext) -> CompoundStatementTraversalPolicy {
+ fn visit_compound_stmt(&mut self, _: &CompoundStatementNode, _: &TraversalContextStack) -> CompoundStatementTraversalPolicy {
CompoundStatementTraversalPolicy { traverse: true }
}
- fn visit_while_stmt(&mut self, _: &WhileLoopNode, _: StatementTraversalContext) -> WhileLoopTraversalPolicy {
+ fn visit_while_stmt(&mut self, _: &WhileLoopNode, _: &TraversalContextStack) -> WhileLoopTraversalPolicy {
WhileLoopTraversalPolicy { traverse_cond: false, traverse_body: true }
}
- fn visit_do_while_stmt(&mut self, _: &DoWhileLoopNode, _: StatementTraversalContext) -> DoWhileLoopTraversalPolicy {
+ fn visit_do_while_stmt(&mut self, _: &DoWhileLoopNode, _: &TraversalContextStack) -> DoWhileLoopTraversalPolicy {
DoWhileLoopTraversalPolicy { traverse_cond: false, traverse_body: true }
}
- fn visit_for_stmt(&mut self, _: &ForLoopNode, _: StatementTraversalContext) -> ForLoopTraversalPolicy {
+ fn visit_for_stmt(&mut self, _: &ForLoopNode, _: &TraversalContextStack) -> ForLoopTraversalPolicy {
ForLoopTraversalPolicy { traverse_init: false, traverse_cond: false, traverse_iter: false, traverse_body: true }
}
- fn visit_if_stmt(&mut self, _: &IfConditionalNode, _: StatementTraversalContext) -> IfConditionalTraversalPolicy {
+ fn visit_if_stmt(&mut self, _: &IfConditionalNode, _: &TraversalContextStack) -> IfConditionalTraversalPolicy {
IfConditionalTraversalPolicy { traverse_cond: false, traverse_body: true, traverse_else_body: true }
}
- fn visit_switch_stmt(&mut self, _: &SwitchConditionalNode, _: StatementTraversalContext) -> SwitchConditionalTraversalPolicy {
+ fn visit_switch_stmt(&mut self, _: &SwitchConditionalNode, _: &TraversalContextStack) -> SwitchConditionalTraversalPolicy {
SwitchConditionalTraversalPolicy { traverse_cond: false, traverse_body: true }
}
}
\ No newline at end of file
diff --git a/crates/analysis/src/jobs/syntax_analysis/contextual_analysis.rs b/crates/analysis/src/jobs/syntax_analysis/contextual_analysis.rs
index 85ec90c3..7e3715f2 100644
--- a/crates/analysis/src/jobs/syntax_analysis/contextual_analysis.rs
+++ b/crates/analysis/src/jobs/syntax_analysis/contextual_analysis.rs
@@ -10,7 +10,8 @@ use witcherscript_diagnostics::{Diagnostic, DiagnosticKind};
pub fn contextual_syntax_analysis(script: &Script, doc: &ScriptDocument, diagnostics: &mut Vec) {
let mut visitor = ContextualSyntaxAnalysis {
doc,
- diagnostics
+ diagnostics,
+ visited_non_var_stmt_before: false
};
script.visit_nodes(&mut visitor);
@@ -18,7 +19,8 @@ pub fn contextual_syntax_analysis(script: &Script, doc: &ScriptDocument, diagnos
struct ContextualSyntaxAnalysis<'a> {
doc: &'a ScriptDocument,
- diagnostics: &'a mut Vec
+ diagnostics: &'a mut Vec,
+ visited_non_var_stmt_before: bool
}
impl ContextualSyntaxAnalysis<'_> {
@@ -256,10 +258,11 @@ impl SyntaxNodeVisitor for ContextualSyntaxAnalysis<'_> {
self.check_function_specifiers(n, true);
}
- FunctionDeclarationTraversalPolicy {
- traverse_params: true,
- traverse_definition: false
- }
+ TraversalPolicy::default_to(true)
+ }
+
+ fn exit_global_func_decl(&mut self, _: &FunctionDeclarationNode) {
+ self.visited_non_var_stmt_before = false;
}
fn visit_global_var_decl(&mut self, n: &MemberVarDeclarationNode) {
@@ -305,7 +308,7 @@ impl SyntaxNodeVisitor for ContextualSyntaxAnalysis<'_> {
}
}
- fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, ctx: DeclarationTraversalContext) {
+ fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, ctx: &TraversalContextStack) {
if let Some(range) = n.annotation().map(|ann| ann.range()) {
self.diagnostics.push(Diagnostic {
range,
@@ -319,7 +322,7 @@ impl SyntaxNodeVisitor for ContextualSyntaxAnalysis<'_> {
for (spec, range) in n.specifiers().map(|specn| (specn.value(), specn.range())) {
if let Ok(var_spec) = MemberVarSpecifier::try_from(spec) {
if matches!(var_spec, MemberVarSpecifier::AccessModifier(_)) {
- if ctx == DeclarationTraversalContext::StructDefinition {
+ if ctx.contains(TraversalContext::Struct) {
let spec_name = Keyword::from(spec).to_string();
self.diagnostics.push(Diagnostic {
range,
@@ -353,7 +356,7 @@ impl SyntaxNodeVisitor for ContextualSyntaxAnalysis<'_> {
}
}
- fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, _: DeclarationTraversalContext) -> FunctionDeclarationTraversalPolicy {
+ fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, _: &TraversalContextStack) -> FunctionDeclarationTraversalPolicy {
if let Some(range) = n.annotation().map(|ann| ann.range()) {
self.diagnostics.push(Diagnostic {
range,
@@ -363,13 +366,22 @@ impl SyntaxNodeVisitor for ContextualSyntaxAnalysis<'_> {
self.check_function_specifiers(n, false);
- FunctionDeclarationTraversalPolicy {
- traverse_params: true,
- traverse_definition: false
- }
+ TraversalPolicy::default_to(true)
+ }
+
+ fn exit_member_func_decl(&mut self, _: &FunctionDeclarationNode, _: &TraversalContextStack) {
+ self.visited_non_var_stmt_before = false;
}
- fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, _: DeclarationTraversalContext) {
+ fn visit_event_decl(&mut self, _: &EventDeclarationNode, _: &TraversalContextStack) -> EventDeclarationTraversalPolicy {
+ TraversalPolicy::default_to(true)
+ }
+
+ fn exit_event_decl(&mut self, _: &EventDeclarationNode, _: &TraversalContextStack) {
+ self.visited_non_var_stmt_before = false;
+ }
+
+ fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, _: &TraversalContextStack) {
let mut specifiers = SmallVec::<[AutobindSpecifier; 2]>::new();
let mut found_access_modif_before = false;
@@ -403,7 +415,7 @@ impl SyntaxNodeVisitor for ContextualSyntaxAnalysis<'_> {
}
}
- fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, _: FunctionTraversalContext) {
+ fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, _: &TraversalContextStack) {
let mut specifiers = SmallVec::<[FunctionParameterSpecifier; 2]>::new();
for (spec, range) in n.specifiers().map(|specn| (specn.value(), specn.range())) {
@@ -425,4 +437,97 @@ impl SyntaxNodeVisitor for ContextualSyntaxAnalysis<'_> {
}
}
}
+
+ fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, _: &TraversalContextStack) -> VarDeclarationTraversalPolicy {
+ if self.visited_non_var_stmt_before {
+ self.diagnostics.push(Diagnostic {
+ range: n.range(),
+ kind: DiagnosticKind::InvalidLocalVarPlacement
+ });
+ }
+
+ VarDeclarationTraversalPolicy {
+ traverse_init_value: false
+ }
+ }
+
+ fn visit_expr_stmt(&mut self, _: &ExpressionStatementNode, _: &TraversalContextStack) -> ExpressionStatementTraversalPolicy {
+ self.visited_non_var_stmt_before = true;
+
+ ExpressionStatementTraversalPolicy {
+ traverse_expr: false
+ }
+ }
+
+ fn visit_if_stmt(&mut self, _: &IfConditionalNode, _: &TraversalContextStack) -> IfConditionalTraversalPolicy {
+ self.visited_non_var_stmt_before = true;
+
+ IfConditionalTraversalPolicy {
+ traverse_cond: false,
+ traverse_body: true,
+ traverse_else_body: true
+ }
+ }
+
+ fn visit_switch_stmt(&mut self, _: &SwitchConditionalNode, _: &TraversalContextStack) -> SwitchConditionalTraversalPolicy {
+ self.visited_non_var_stmt_before = true;
+
+ SwitchConditionalTraversalPolicy {
+ traverse_cond: false,
+ traverse_body: true
+ }
+ }
+
+ fn visit_for_stmt(&mut self, _: &ForLoopNode, _: &TraversalContextStack) -> ForLoopTraversalPolicy {
+ self.visited_non_var_stmt_before = true;
+
+ ForLoopTraversalPolicy {
+ traverse_init: false,
+ traverse_cond: false,
+ traverse_iter: false,
+ traverse_body: true
+ }
+ }
+
+ fn visit_while_stmt(&mut self, _: &WhileLoopNode, _: &TraversalContextStack) -> WhileLoopTraversalPolicy {
+ self.visited_non_var_stmt_before = true;
+
+ WhileLoopTraversalPolicy {
+ traverse_cond: false,
+ traverse_body: true
+ }
+ }
+
+ fn visit_do_while_stmt(&mut self, _: &DoWhileLoopNode, _: &TraversalContextStack) -> DoWhileLoopTraversalPolicy {
+ self.visited_non_var_stmt_before = true;
+
+ DoWhileLoopTraversalPolicy {
+ traverse_cond: false,
+ traverse_body: true
+ }
+ }
+
+ fn visit_delete_stmt(&mut self, _: &DeleteStatementNode, _: &TraversalContextStack) -> DeleteStatementTraversalPolicy {
+ self.visited_non_var_stmt_before = true;
+
+ DeleteStatementTraversalPolicy {
+ traverse_value: false
+ }
+ }
+
+ fn visit_compound_stmt(&mut self, _: &CompoundStatementNode, _: &TraversalContextStack) -> CompoundStatementTraversalPolicy {
+ self.visited_non_var_stmt_before = true;
+
+ CompoundStatementTraversalPolicy {
+ traverse: true
+ }
+ }
+
+ fn visit_return_stmt(&mut self, _: &ReturnStatementNode, _: &TraversalContextStack) -> ReturnStatementTraversalPolicy {
+ self.visited_non_var_stmt_before = true;
+
+ ReturnStatementTraversalPolicy {
+ traverse_value: false
+ }
+ }
}
\ No newline at end of file
diff --git a/crates/analysis/src/jobs/syntax_analysis/syntax_error_visitor.rs b/crates/analysis/src/jobs/syntax_analysis/syntax_error_visitor.rs
index a661c31e..74eb243c 100644
--- a/crates/analysis/src/jobs/syntax_analysis/syntax_error_visitor.rs
+++ b/crates/analysis/src/jobs/syntax_analysis/syntax_error_visitor.rs
@@ -252,7 +252,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, _: DeclarationTraversalContext) {
+ fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, _: &TraversalContextStack) {
if n.has_errors() {
if let Some(annot) = n.annotation() {
self.check_annotation(&annot);
@@ -265,7 +265,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode, _: DeclarationTraversalContext) -> MemberDefaultValueTraversalPolicy {
+ fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode, _: &TraversalContextStack) -> MemberDefaultValueTraversalPolicy {
let mut traverse_value = false;
if n.has_errors() {
self.check_identifier(&n.member());
@@ -281,7 +281,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_member_hint(&mut self, n: &MemberHintNode, _: DeclarationTraversalContext) {
+ fn visit_member_hint(&mut self, n: &MemberHintNode, _: &TraversalContextStack) {
if n.has_errors() {
self.check_identifier(&n.member());
self.check_missing(&n.value(), "hint string");
@@ -290,7 +290,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, _: DeclarationTraversalContext) {
+ fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, _: &TraversalContextStack) {
if n.has_errors() {
self.check_identifier(&n.name());
self.check_type_annot(&n.autobind_type());
@@ -299,7 +299,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, _: FunctionTraversalContext) {
+ fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, _: &TraversalContextStack) {
if n.has_errors() {
n.names().for_each(|name| { self.check_identifier(&name); } );
self.check_type_annot(&n.param_type());
@@ -342,7 +342,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, _: DeclarationTraversalContext) -> FunctionDeclarationTraversalPolicy {
+ fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, _: &TraversalContextStack) -> FunctionDeclarationTraversalPolicy {
let mut traverse_params = false;
let mut traverse_definition = false;
if n.has_errors() {
@@ -379,7 +379,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_event_decl(&mut self, n: &EventDeclarationNode, _: DeclarationTraversalContext) -> EventDeclarationTraversalPolicy {
+ fn visit_event_decl(&mut self, n: &EventDeclarationNode, _: &TraversalContextStack) -> EventDeclarationTraversalPolicy {
let mut traverse_params = false;
let mut traverse_definition = false;
if n.has_errors() {
@@ -412,7 +412,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode, _: DeclarationTraversalContext) -> MemberDefaultsBlockTraversalPolicy {
+ fn visit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode, _: &TraversalContextStack) -> MemberDefaultsBlockTraversalPolicy {
let traverse = if n.has_errors() {
self.check_errors(n);
true
@@ -425,7 +425,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode) -> MemberDefaultValueTraversalPolicy {
+ fn visit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode, _: &TraversalContextStack) -> MemberDefaultValueTraversalPolicy {
let mut traverse_value = false;
if n.has_errors() {
self.check_identifier(&n.member());
@@ -442,7 +442,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
- fn visit_compound_stmt(&mut self, n: &CompoundStatementNode, _: StatementTraversalContext) -> CompoundStatementTraversalPolicy {
+ fn visit_compound_stmt(&mut self, n: &CompoundStatementNode, _: &TraversalContextStack) -> CompoundStatementTraversalPolicy {
let traverse = if n.has_errors() {
self.check_errors(n);
true
@@ -455,7 +455,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, _: StatementTraversalContext) -> VarDeclarationTraversalPolicy {
+ fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, _: &TraversalContextStack) -> VarDeclarationTraversalPolicy {
let mut traverse_init_value = false;
if n.has_errors() {
n.names().for_each(|name| { self.check_identifier(&name); } );
@@ -470,7 +470,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_expr_stmt(&mut self, n: &ExpressionStatementNode, _: StatementTraversalContext) -> ExpressionStatementTraversalPolicy {
+ fn visit_expr_stmt(&mut self, n: &ExpressionStatementNode, _: &TraversalContextStack) -> ExpressionStatementTraversalPolicy {
let mut traverse_expr = false;
if n.has_errors() {
traverse_expr = !self.check_expression(&n.expr());
@@ -483,7 +483,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_return_stmt(&mut self, n: &ReturnStatementNode, _: StatementTraversalContext) -> ReturnStatementTraversalPolicy {
+ fn visit_return_stmt(&mut self, n: &ReturnStatementNode, _: &TraversalContextStack) -> ReturnStatementTraversalPolicy {
let mut traverse_value = false;
if n.has_errors() {
traverse_value = n.value().map(|value| !self.check_expression(&value)).unwrap_or(false);
@@ -496,19 +496,19 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_break_stmt(&mut self, n: &BreakStatementNode, _: StatementTraversalContext) {
+ fn visit_break_stmt(&mut self, n: &BreakStatementNode, _: &TraversalContextStack) {
if n.has_errors() {
self.check_errors(n);
}
}
- fn visit_continue_stmt(&mut self, n: &ContinueStatementNode, _: StatementTraversalContext) {
+ fn visit_continue_stmt(&mut self, n: &ContinueStatementNode, _: &TraversalContextStack) {
if n.has_errors() {
self.check_errors(n);
}
}
- fn visit_delete_stmt(&mut self, n: &DeleteStatementNode, _: StatementTraversalContext) -> DeleteStatementTraversalPolicy {
+ fn visit_delete_stmt(&mut self, n: &DeleteStatementNode, _: &TraversalContextStack) -> DeleteStatementTraversalPolicy {
let mut traverse_value = false;
if n.has_errors() {
traverse_value = !self.check_expression(&n.value());
@@ -521,7 +521,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_for_stmt(&mut self, n: &ForLoopNode, _: StatementTraversalContext) -> ForLoopTraversalPolicy {
+ fn visit_for_stmt(&mut self, n: &ForLoopNode, _: &TraversalContextStack) -> ForLoopTraversalPolicy {
let mut traverse_init = false;
let mut traverse_cond = false;
let mut traverse_iter = false;
@@ -543,7 +543,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_while_stmt(&mut self, n: &WhileLoopNode, _: StatementTraversalContext) -> WhileLoopTraversalPolicy {
+ fn visit_while_stmt(&mut self, n: &WhileLoopNode, _: &TraversalContextStack) -> WhileLoopTraversalPolicy {
let mut traverse_cond = false;
let mut traverse_body = false;
if n.has_errors() {
@@ -559,7 +559,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_do_while_stmt(&mut self, n: &DoWhileLoopNode, _: StatementTraversalContext) -> DoWhileLoopTraversalPolicy {
+ fn visit_do_while_stmt(&mut self, n: &DoWhileLoopNode, _: &TraversalContextStack) -> DoWhileLoopTraversalPolicy {
let mut traverse_cond = false;
let mut traverse_body = false;
if n.has_errors() {
@@ -575,7 +575,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_if_stmt(&mut self, n: &IfConditionalNode, _: StatementTraversalContext) -> IfConditionalTraversalPolicy {
+ fn visit_if_stmt(&mut self, n: &IfConditionalNode, _: &TraversalContextStack) -> IfConditionalTraversalPolicy {
let mut traverse_cond = false;
let mut traverse_body = false;
let mut traverse_else_body = false;
@@ -594,7 +594,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_switch_stmt(&mut self, n: &SwitchConditionalNode, _: StatementTraversalContext) -> SwitchConditionalTraversalPolicy {
+ fn visit_switch_stmt(&mut self, n: &SwitchConditionalNode, _: &TraversalContextStack) -> SwitchConditionalTraversalPolicy {
let mut traverse_cond = false;
let mut traverse_body = false;
if n.has_errors() {
@@ -615,7 +615,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_switch_stmt_case(&mut self, n: &SwitchConditionalCaseLabelNode) -> SwitchConditionalCaseLabelTraversalPolicy {
+ fn visit_switch_stmt_case(&mut self, n: &SwitchConditionalCaseLabelNode, _: &TraversalContextStack) -> SwitchConditionalCaseLabelTraversalPolicy {
let mut traverse_value = false;
if n.has_errors() {
traverse_value = !self.check_expression(&n.value());
@@ -628,7 +628,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_switch_stmt_default(&mut self, n: &SwitchConditionalDefaultLabelNode) {
+ fn visit_switch_stmt_default(&mut self, n: &SwitchConditionalDefaultLabelNode, _: &TraversalContextStack) {
if n.has_errors() {
self.check_errors(n);
}
@@ -637,7 +637,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
- fn visit_array_expr(&mut self, n: &ArrayExpressionNode, _: ExpressionTraversalContext) -> ArrayExpressionTraversalPolicy {
+ fn visit_array_expr(&mut self, n: &ArrayExpressionNode, _: &TraversalContextStack) -> ArrayExpressionTraversalPolicy {
let traverse_accessor = !self.check_expression(&n.accessor());
let traverse_index = !self.check_expression(&n.index());
@@ -649,7 +649,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode, _: ExpressionTraversalContext) -> AssignmentOperationExpressionTraversalPolicy {
+ fn visit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode, _: &TraversalContextStack) -> AssignmentOperationExpressionTraversalPolicy {
let traverse_left = !self.check_expression(&n.left());
let traverse_right = !self.check_expression(&n.right());
@@ -661,7 +661,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, _: ExpressionTraversalContext) -> BinaryOperationExpressionTraversalPolicy {
+ fn visit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, _: &TraversalContextStack) -> BinaryOperationExpressionTraversalPolicy {
let traverse_left = !self.check_expression(&n.left());
let traverse_right = !self.check_expression(&n.right());
@@ -673,7 +673,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode, _: ExpressionTraversalContext) -> UnaryOperationExpressionTraversalPolicy {
+ fn visit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode, _: &TraversalContextStack) -> UnaryOperationExpressionTraversalPolicy {
let traverse_right = !self.check_expression(&n.right());
self.check_errors(n);
@@ -683,7 +683,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_func_call_expr(&mut self, n: &FunctionCallExpressionNode, _: ExpressionTraversalContext) -> FunctionCallExpressionTraversalPolicy {
+ fn visit_func_call_expr(&mut self, n: &FunctionCallExpressionNode, _: &TraversalContextStack) -> FunctionCallExpressionTraversalPolicy {
let func = n.func();
let traverse_func = !self.check_missing(&func, "function") || func.has_errors();
@@ -703,7 +703,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_new_expr(&mut self, n: &NewExpressionNode, _: ExpressionTraversalContext) -> NewExpressionTraversalPolicy {
+ fn visit_new_expr(&mut self, n: &NewExpressionNode, _: &TraversalContextStack) -> NewExpressionTraversalPolicy {
self.check_identifier(&n.class());
let mut traverse_lifetime_obj = false;
@@ -718,7 +718,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, _: ExpressionTraversalContext) -> MemberFieldExpressionTraversalPolicy {
+ fn visit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, _: &TraversalContextStack) -> MemberFieldExpressionTraversalPolicy {
let traverse_accessor = !self.check_expression(&n.accessor());
self.check_identifier(&n.member());
@@ -729,7 +729,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_nested_expr(&mut self, n: &NestedExpressionNode, _: ExpressionTraversalContext) -> NestedExpressionTraversalPolicy {
+ fn visit_nested_expr(&mut self, n: &NestedExpressionNode, _: &TraversalContextStack) -> NestedExpressionTraversalPolicy {
let traverse_inner = !self.check_expression(&n.inner());
self.check_errors(n);
@@ -739,7 +739,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode, _: ExpressionTraversalContext) -> TernaryConditionalExpressionTraversalPolicy {
+ fn visit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode, _: &TraversalContextStack) -> TernaryConditionalExpressionTraversalPolicy {
let traverse_cond = !self.check_expression(&n.cond());
let traverse_conseq = !self.check_expression(&n.conseq());
let traverse_alt = !self.check_expression(&n.alt());
@@ -753,7 +753,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, _: ExpressionTraversalContext) -> TypeCastExpressionTraversalPolicy {
+ fn visit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, _: &TraversalContextStack) -> TypeCastExpressionTraversalPolicy {
self.check_identifier(&n.target_type());
let traverse_value = !self.check_expression(&n.value());
@@ -764,7 +764,7 @@ impl SyntaxNodeVisitor for SyntaxErrorVisitor<'_> {
}
}
- fn visit_func_call_arg(&mut self, _: &FunctionCallArgument) -> FunctionCallArgumentTraversalPolicy {
+ fn visit_func_call_arg(&mut self, _: &FunctionCallArgument, _: &TraversalContextStack) -> FunctionCallArgumentTraversalPolicy {
FunctionCallArgumentTraversalPolicy {
traverse_expr: true
}
diff --git a/crates/analysis/src/symbol_analysis/unqualified_name_lookup.rs b/crates/analysis/src/symbol_analysis/unqualified_name_lookup.rs
index 0c66bb60..e1b23d0c 100644
--- a/crates/analysis/src/symbol_analysis/unqualified_name_lookup.rs
+++ b/crates/analysis/src/symbol_analysis/unqualified_name_lookup.rs
@@ -428,7 +428,7 @@ impl SyntaxNodeVisitor for UnqualifiedNameLookupBuilder<'_> {
self.payload.borrow_mut().pop_scope();
}
- fn visit_member_func_decl(&mut self, _: &FunctionDeclarationNode, _: DeclarationTraversalContext) -> FunctionDeclarationTraversalPolicy {
+ fn visit_member_func_decl(&mut self, _: &FunctionDeclarationNode, _: &TraversalContextStack) -> FunctionDeclarationTraversalPolicy {
let mut unl = self.payload.borrow_mut();
let sympath_ctx = self.sympath_ctx.borrow();
@@ -448,11 +448,11 @@ impl SyntaxNodeVisitor for UnqualifiedNameLookupBuilder<'_> {
TraversalPolicy::default_to(true)
}
- fn exit_member_func_decl(&mut self, _: &FunctionDeclarationNode, _: DeclarationTraversalContext) {
+ fn exit_member_func_decl(&mut self, _: &FunctionDeclarationNode, _: &TraversalContextStack) {
self.payload.borrow_mut().pop_scope();
}
- fn visit_event_decl(&mut self, _: &EventDeclarationNode, _: DeclarationTraversalContext) -> EventDeclarationTraversalPolicy {
+ fn visit_event_decl(&mut self, _: &EventDeclarationNode, _: &TraversalContextStack) -> EventDeclarationTraversalPolicy {
let mut unl = self.payload.borrow_mut();
let sympath_ctx = self.sympath_ctx.borrow();
@@ -472,11 +472,11 @@ impl SyntaxNodeVisitor for UnqualifiedNameLookupBuilder<'_> {
TraversalPolicy::default_to(true)
}
- fn exit_event_decl(&mut self, _: &EventDeclarationNode, _: DeclarationTraversalContext) {
+ fn exit_event_decl(&mut self, _: &EventDeclarationNode, _: &TraversalContextStack) {
self.payload.borrow_mut().pop_scope();
}
- fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, _: StatementTraversalContext) -> VarDeclarationTraversalPolicy {
+ fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, _: &TraversalContextStack) -> VarDeclarationTraversalPolicy {
let mut unl = self.payload.borrow_mut();
let sympath_ctx = self.sympath_ctx.borrow();
diff --git a/crates/analysis/src/utils/visitors/expr_evaluator.rs b/crates/analysis/src/utils/visitors/expr_evaluator.rs
index efbf07c0..c612d5ff 100644
--- a/crates/analysis/src/utils/visitors/expr_evaluator.rs
+++ b/crates/analysis/src/utils/visitors/expr_evaluator.rs
@@ -8,14 +8,19 @@ use super::SymbolPathBuilderPayload;
/// Requires valid for the given context `SymbolPathBuilderPayload` and `UnqualifiedNameLookup` to work.
pub fn evaluate_expression<'a>(
n: ExpressionNode,
- ctx: Option,
+ ctx: TraversalContext,
doc: &'a ScriptDocument,
symtab_marcher: SymbolTableMarcher<'a>,
sympath_payload: Rc>,
unl_payload: Rc>
) -> SymbolPathBuf {
let mut evaluator = ExpressionEvaluator::new(doc, symtab_marcher, sympath_payload, unl_payload);
- n.accept(&mut evaluator, ctx.unwrap_or(ExpressionTraversalContext::ExpressionStatement)); // by default it should think it is operating on an izolated statement
+
+ // we don't need information about the exact whereabouts of the expression
+ let mut ctx_stack = TraversalContextStack::new();
+ ctx_stack.push(ctx);
+
+ n.accept(&mut evaluator, &mut ctx_stack);
evaluator.finish()
}
@@ -35,7 +40,7 @@ pub struct ExpressionEvaluator<'a> {
#[derive(Clone)]
struct TypeStackElement {
path: SymbolPathBuf,
- ctx: ExpressionTraversalContext
+ ctx: TraversalContext
}
impl<'a> ExpressionEvaluator<'a> {
@@ -64,7 +69,7 @@ impl<'a> ExpressionEvaluator<'a> {
#[inline]
- fn push(&mut self, path: SymbolPathBuf, ctx: ExpressionTraversalContext) {
+ fn push(&mut self, path: SymbolPathBuf, ctx: TraversalContext) {
self.type_stack.push(TypeStackElement { path, ctx })
}
@@ -140,61 +145,61 @@ impl<'a> ExpressionEvaluator<'a> {
}
impl SyntaxNodeVisitor for ExpressionEvaluator<'_> {
- fn exit_nested_expr(&mut self, _: &NestedExpressionNode, ctx: ExpressionTraversalContext) {
- self.top_mut().map(|e| e.ctx = ctx );
+ fn exit_nested_expr(&mut self, _: &NestedExpressionNode, ctx: &TraversalContextStack) {
+ self.top_mut().map(|e| e.ctx = ctx.top() );
}
- fn visit_literal_expr(&mut self, n: &LiteralNode, ctx: ExpressionTraversalContext) {
+ fn visit_literal_expr(&mut self, n: &LiteralNode, ctx: &TraversalContextStack) {
match n.clone().value() {
- Literal::Int(_) => self.push(BasicTypeSymbolPath::new("int").into(), ctx),
- Literal::Hex(_) => self.push(BasicTypeSymbolPath::new("int").into(), ctx),
- Literal::Float(_) => self.push(BasicTypeSymbolPath::new("float").into(), ctx),
- Literal::Bool(_) => self.push(BasicTypeSymbolPath::new("bool").into(), ctx),
- Literal::String(_) => self.push(BasicTypeSymbolPath::new("string").into(), ctx),
- Literal::Name(_) => self.push(BasicTypeSymbolPath::new("name").into(), ctx),
- Literal::Null(_) => self.push(BasicTypeSymbolPath::new("NULL").into(), ctx),
+ Literal::Int(_) => self.push(BasicTypeSymbolPath::new("int").into(), ctx.top()),
+ Literal::Hex(_) => self.push(BasicTypeSymbolPath::new("int").into(), ctx.top()),
+ Literal::Float(_) => self.push(BasicTypeSymbolPath::new("float").into(), ctx.top()),
+ Literal::Bool(_) => self.push(BasicTypeSymbolPath::new("bool").into(), ctx.top()),
+ Literal::String(_) => self.push(BasicTypeSymbolPath::new("string").into(), ctx.top()),
+ Literal::Name(_) => self.push(BasicTypeSymbolPath::new("name").into(), ctx.top()),
+ Literal::Null(_) => self.push(BasicTypeSymbolPath::new("NULL").into(), ctx.top()),
}
}
- fn visit_this_expr(&mut self, _: &ThisExpressionNode, ctx: ExpressionTraversalContext) {
+ fn visit_this_expr(&mut self, _: &ThisExpressionNode, ctx: &TraversalContextStack) {
let sympath_payload = self.sympath_payload.borrow();
let type_path = sympath_payload.current_sympath.root().unwrap_or_default();
let this_path = ThisVarSymbolPath::new(type_path);
drop(sympath_payload);
- self.push(this_path.into(), ctx);
+ self.push(this_path.into(), ctx.top());
}
- fn visit_super_expr(&mut self, _: &SuperExpressionNode, ctx: ExpressionTraversalContext) {
+ fn visit_super_expr(&mut self, _: &SuperExpressionNode, ctx: &TraversalContextStack) {
let sympath_payload = self.sympath_payload.borrow();
let type_path = sympath_payload.current_sympath.root().unwrap_or_default();
let super_path = SuperVarSymbolPath::new(type_path);
drop(sympath_payload);
- self.push(super_path.into(), ctx);
+ self.push(super_path.into(), ctx.top());
}
- fn visit_parent_expr(&mut self, _: &ParentExpressionNode, ctx: ExpressionTraversalContext) {
+ fn visit_parent_expr(&mut self, _: &ParentExpressionNode, ctx: &TraversalContextStack) {
let sympath_payload = self.sympath_payload.borrow();
let type_path = sympath_payload.current_sympath.root().unwrap_or_default();
let parent_path = ParentVarSymbolPath::new(type_path);
drop(sympath_payload);
- self.push(parent_path.into(), ctx);
+ self.push(parent_path.into(), ctx.top());
}
- fn visit_virtual_parent_expr(&mut self, _: &VirtualParentExpressionNode, ctx: ExpressionTraversalContext) {
+ fn visit_virtual_parent_expr(&mut self, _: &VirtualParentExpressionNode, ctx: &TraversalContextStack) {
let sympath_payload = self.sympath_payload.borrow();
let type_path = sympath_payload.current_sympath.root().unwrap_or_default();
let virtual_parent_path = VirtualParentVarSymbolPath::new(type_path);
drop(sympath_payload);
- self.push(virtual_parent_path.into(), ctx);
+ self.push(virtual_parent_path.into(), ctx.top());
}
- fn visit_identifier_expr(&mut self, n: &IdentifierNode, ctx: ExpressionTraversalContext) {
+ fn visit_identifier_expr(&mut self, n: &IdentifierNode, ctx: &TraversalContextStack) {
let name = n.value(self.doc);
- let ident_category = if ctx == ExpressionTraversalContext::FunctionCallExpressionFunc {
+ let ident_category = if ctx.top() == TraversalContext::FunctionCallExpressionFunc {
SymbolCategory::Callable
} else {
SymbolCategory::Data
@@ -205,46 +210,46 @@ impl SyntaxNodeVisitor for ExpressionEvaluator<'_> {
.map(|p| p.to_owned())
.unwrap_or(SymbolPathBuf::new(&name, ident_category));
- self.push(ident_path, ctx);
+ self.push(ident_path, ctx.top());
}
- fn exit_func_call_expr(&mut self, _: &FunctionCallExpressionNode, ctx: ExpressionTraversalContext) {
+ fn exit_func_call_expr(&mut self, _: &FunctionCallExpressionNode, ctx: &TraversalContextStack) {
// this is a completely explicit language in terms of typeing and there is no function overloading
// so we don't need argument types to get the return type of a function
- while self.top().map(|e| e.ctx == ExpressionTraversalContext::FunctionCallArg).unwrap_or(false) {
+ while self.top().map(|e| e.ctx == TraversalContext::FunctionCallArg).unwrap_or(false) {
self.pop();
}
- if self.top().map(|e| e.ctx == ExpressionTraversalContext::FunctionCallExpressionFunc).unwrap_or(false) {
+ if self.top().map(|e| e.ctx == TraversalContext::FunctionCallExpressionFunc).unwrap_or(false) {
let func_path = self.pop().unwrap().path;
- self.push(self.produce_type(&func_path), ctx);
+ self.push(self.produce_type(&func_path), ctx.top());
} else {
- self.push(SymbolPathBuf::unknown(SymbolCategory::Type), ctx);
+ self.push(SymbolPathBuf::unknown(SymbolCategory::Type), ctx.top());
}
}
- fn exit_array_expr(&mut self, _: &ArrayExpressionNode, ctx: ExpressionTraversalContext) {
+ fn exit_array_expr(&mut self, _: &ArrayExpressionNode, ctx: &TraversalContextStack) {
// type of the index doesn't matter in this case
- if self.top().map(|e| e.ctx == ExpressionTraversalContext::ArrayExpressionIndex).unwrap_or(false) {
+ if self.top().map(|e| e.ctx == TraversalContext::ArrayExpressionIndex).unwrap_or(false) {
self.pop();
}
- if self.top().map(|e| e.ctx == ExpressionTraversalContext::ArrayExpressionAccessor).unwrap_or(false) {
+ if self.top().map(|e| e.ctx == TraversalContext::ArrayExpressionAccessor).unwrap_or(false) {
let accessor_path = self.pop().unwrap().path;
let accessor_type = self.produce_type(&accessor_path);
let op_path = MemberCallableSymbolPath::new(&accessor_type, ArrayTypeSymbol::INDEX_OPERATOR_NAME);
- self.push(self.produce_type(&op_path), ctx);
+ self.push(self.produce_type(&op_path), ctx.top());
} else {
- self.push(SymbolPathBuf::unknown(SymbolCategory::Type), ctx);
+ self.push(SymbolPathBuf::unknown(SymbolCategory::Type), ctx.top());
}
}
- fn exit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, ctx: ExpressionTraversalContext) {
- if self.top().map(|e| e.ctx == ExpressionTraversalContext::MemberAccessExpressionAccessor).unwrap_or(false) {
+ fn exit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, ctx: &TraversalContextStack) {
+ if self.top().map(|e| e.ctx == TraversalContext::MemberAccessExpressionAccessor).unwrap_or(false) {
let accessor_path = self.pop().unwrap().path;
let member = n.member().value(self.doc);
- let member_category = if ctx == ExpressionTraversalContext::FunctionCallExpressionFunc {
+ let member_category = if ctx.top() == TraversalContext::FunctionCallExpressionFunc {
SymbolCategory::Callable
} else {
SymbolCategory::Data
@@ -299,48 +304,48 @@ impl SyntaxNodeVisitor for ExpressionEvaluator<'_> {
_ => SymbolPathBuf::unknown(SymbolCategory::Type)
};
- self.push(member_path, ctx);
+ self.push(member_path, ctx.top());
} else {
- self.push(SymbolPathBuf::unknown(SymbolCategory::Type), ctx);
+ self.push(SymbolPathBuf::unknown(SymbolCategory::Type), ctx.top());
}
} else {
- self.push(SymbolPathBuf::unknown(SymbolCategory::Type), ctx);
+ self.push(SymbolPathBuf::unknown(SymbolCategory::Type), ctx.top());
}
}
- fn exit_new_expr(&mut self, n: &NewExpressionNode, ctx: ExpressionTraversalContext) {
+ fn exit_new_expr(&mut self, n: &NewExpressionNode, ctx: &TraversalContextStack) {
// lifetime object has no bearing on the type of the expression
- if self.top().map(|e| e.ctx == ExpressionTraversalContext::NewExpressionLifetimeObj).unwrap_or(false) {
+ if self.top().map(|e| e.ctx == TraversalContext::NewExpressionLifetimeObj).unwrap_or(false) {
self.pop();
}
- self.push(BasicTypeSymbolPath::new(&n.class().value(self.doc)).into(), ctx);
+ self.push(BasicTypeSymbolPath::new(&n.class().value(self.doc)).into(), ctx.top());
}
- fn exit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, ctx: ExpressionTraversalContext) {
- if self.top().map(|e| e.ctx == ExpressionTraversalContext::TypeCastExpressionValue).unwrap_or(false) {
+ fn exit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, ctx: &TraversalContextStack) {
+ if self.top().map(|e| e.ctx == TraversalContext::TypeCastExpressionValue).unwrap_or(false) {
self.pop();
}
let target_type = n.target_type().value(self.doc);
- self.push(BasicTypeSymbolPath::new(&target_type).into(), ctx);
+ self.push(BasicTypeSymbolPath::new(&target_type).into(), ctx.top());
}
- fn exit_unary_op_expr(&mut self, _: &UnaryOperationExpressionNode, ctx: ExpressionTraversalContext) {
- if self.top().map(|e| e.ctx == ExpressionTraversalContext::UnaryOperationExpressionRight).unwrap_or(false) {
+ fn exit_unary_op_expr(&mut self, _: &UnaryOperationExpressionNode, ctx: &TraversalContextStack) {
+ if self.top().map(|e| e.ctx == TraversalContext::UnaryOperationExpressionRight).unwrap_or(false) {
// there is no operator overloading as far as I'm aware, so this propagation is probably ok
- self.top_mut().map(|e| e.ctx = ctx );
+ self.top_mut().map(|e| e.ctx = ctx.top());
} else {
- self.push(SymbolPathBuf::unknown(SymbolCategory::Type), ctx);
+ self.push(SymbolPathBuf::unknown(SymbolCategory::Type), ctx.top());
}
}
- fn exit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, ctx: ExpressionTraversalContext) {
- if self.top().map(|e| e.ctx == ExpressionTraversalContext::BinaryOperationExpressionRight).unwrap_or(false) {
+ fn exit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, ctx: &TraversalContextStack) {
+ if self.top().map(|e| e.ctx == TraversalContext::BinaryOperationExpressionRight).unwrap_or(false) {
self.pop();
}
- let left_path = if self.top().map(|e| e.ctx == ExpressionTraversalContext::BinaryOperationExpressionLeft).unwrap_or(false) {
+ let left_path = if self.top().map(|e| e.ctx == TraversalContext::BinaryOperationExpressionLeft).unwrap_or(false) {
self.pop().unwrap().path
} else {
SymbolPathBuf::unknown(SymbolCategory::Type)
@@ -366,36 +371,36 @@ impl SyntaxNodeVisitor for ExpressionEvaluator<'_> {
| BinaryOperator::GreaterOrEqual => BasicTypeSymbolPath::new("bool").into(),
};
- self.push(op_path, ctx);
+ self.push(op_path, ctx.top());
}
- fn exit_assign_op_expr(&mut self, _: &AssignmentOperationExpressionNode, ctx: ExpressionTraversalContext) {
- if self.top().map(|e| e.ctx == ExpressionTraversalContext::AssignmentOperationExpressionRight).unwrap_or(false) {
+ fn exit_assign_op_expr(&mut self, _: &AssignmentOperationExpressionNode, ctx: &TraversalContextStack) {
+ if self.top().map(|e| e.ctx == TraversalContext::AssignmentOperationExpressionRight).unwrap_or(false) {
self.pop();
}
- if self.top().map(|e| e.ctx == ExpressionTraversalContext::AssignmentOperationExpressionLeft).unwrap_or(false) {
- self.top_mut().map(|e| e.ctx = ctx );
+ if self.top().map(|e| e.ctx == TraversalContext::AssignmentOperationExpressionLeft).unwrap_or(false) {
+ self.top_mut().map(|e| e.ctx = ctx.top() );
} else {
- self.push(SymbolPathBuf::unknown(SymbolCategory::Type), ctx);
+ self.push(SymbolPathBuf::unknown(SymbolCategory::Type), ctx.top());
}
}
- fn exit_ternary_cond_expr(&mut self, _: &TernaryConditionalExpressionNode, ctx: ExpressionTraversalContext) {
- if self.top().map(|e| e.ctx == ExpressionTraversalContext::TernaryConditionalExpressionAlt).unwrap_or(false) {
+ fn exit_ternary_cond_expr(&mut self, _: &TernaryConditionalExpressionNode, ctx: &TraversalContextStack) {
+ if self.top().map(|e| e.ctx == TraversalContext::TernaryConditionalExpressionAlt).unwrap_or(false) {
self.pop();
}
- let conseq_path = if self.top().map(|e| e.ctx == ExpressionTraversalContext::TernaryConditionalExpressionConseq).unwrap_or(false) {
+ let conseq_path = if self.top().map(|e| e.ctx == TraversalContext::TernaryConditionalExpressionConseq).unwrap_or(false) {
self.pop().unwrap().path
} else {
SymbolPathBuf::unknown(SymbolCategory::Type)
};
- if self.top().map(|e| e.ctx == ExpressionTraversalContext::TernaryConditionalExpressionCond).unwrap_or(false) {
+ if self.top().map(|e| e.ctx == TraversalContext::TernaryConditionalExpressionCond).unwrap_or(false) {
self.pop();
}
- self.push(conseq_path, ctx);
+ self.push(conseq_path, ctx.top());
}
}
diff --git a/crates/analysis/src/utils/visitors/position_filter.rs b/crates/analysis/src/utils/visitors/position_filter.rs
index d13f8028..44c4ad9c 100644
--- a/crates/analysis/src/utils/visitors/position_filter.rs
+++ b/crates/analysis/src/utils/visitors/position_filter.rs
@@ -180,7 +180,7 @@ impl SyntaxNodeVisitor for PositionFilter {
- fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, _: DeclarationTraversalContext) -> FunctionDeclarationTraversalPolicy {
+ fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, _: &TraversalContextStack) -> FunctionDeclarationTraversalPolicy {
let mut tp = FunctionDeclarationTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -200,11 +200,11 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn exit_member_func_decl(&mut self, _: &FunctionDeclarationNode, _: DeclarationTraversalContext) {
+ fn exit_member_func_decl(&mut self, _: &FunctionDeclarationNode, _: &TraversalContextStack) {
self.currently_in_callable_range = false;
}
- fn visit_event_decl(&mut self, n: &EventDeclarationNode, _: DeclarationTraversalContext) -> EventDeclarationTraversalPolicy {
+ fn visit_event_decl(&mut self, n: &EventDeclarationNode, _: &TraversalContextStack) -> EventDeclarationTraversalPolicy {
let mut tp = EventDeclarationTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -224,39 +224,39 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn exit_event_decl(&mut self, _: &EventDeclarationNode, _: DeclarationTraversalContext) {
+ fn exit_event_decl(&mut self, _: &EventDeclarationNode, _: &TraversalContextStack) {
self.currently_in_callable_range = false;
}
- fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, _: FunctionTraversalContext) {
+ fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, _: &TraversalContextStack) {
self.currently_in_range = n.spans_position(self.pos);
if self.currently_in_range {
self.payload.borrow_mut().done = true;
}
}
- fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, _: DeclarationTraversalContext) {
+ fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, _: &TraversalContextStack) {
self.currently_in_range = n.spans_position(self.pos);
if self.currently_in_range {
self.payload.borrow_mut().done = true;
}
}
- fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, _: DeclarationTraversalContext) {
+ fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, _: &TraversalContextStack) {
self.currently_in_range = n.spans_position(self.pos);
if self.currently_in_range {
self.payload.borrow_mut().done = true;
}
}
- fn visit_member_hint(&mut self, n: &MemberHintNode, _: DeclarationTraversalContext) {
+ fn visit_member_hint(&mut self, n: &MemberHintNode, _: &TraversalContextStack) {
self.currently_in_range = n.spans_position(self.pos);
if self.currently_in_range {
self.payload.borrow_mut().done = true;
}
}
- fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode, _: DeclarationTraversalContext) -> MemberDefaultValueTraversalPolicy {
+ fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode, _: &TraversalContextStack) -> MemberDefaultValueTraversalPolicy {
let mut tp = MemberDefaultValueTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -272,7 +272,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode, _: DeclarationTraversalContext) -> MemberDefaultsBlockTraversalPolicy {
+ fn visit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode, _: &TraversalContextStack) -> MemberDefaultsBlockTraversalPolicy {
let mut tp = MemberDefaultsBlockTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -283,7 +283,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode) -> MemberDefaultValueTraversalPolicy {
+ fn visit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode, _: &TraversalContextStack) -> MemberDefaultValueTraversalPolicy {
let mut tp = MemberDefaultValueTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -302,7 +302,7 @@ impl SyntaxNodeVisitor for PositionFilter {
- fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, _: StatementTraversalContext) -> VarDeclarationTraversalPolicy {
+ fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, _: &TraversalContextStack) -> VarDeclarationTraversalPolicy {
let mut tp = VarDeclarationTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -318,7 +318,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_compound_stmt(&mut self, n: &CompoundStatementNode, _: StatementTraversalContext) -> CompoundStatementTraversalPolicy {
+ fn visit_compound_stmt(&mut self, n: &CompoundStatementNode, _: &TraversalContextStack) -> CompoundStatementTraversalPolicy {
let mut tp = CompoundStatementTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -329,7 +329,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_for_stmt(&mut self, n: &ForLoopNode, _: StatementTraversalContext) -> ForLoopTraversalPolicy {
+ fn visit_for_stmt(&mut self, n: &ForLoopNode, _: &TraversalContextStack) -> ForLoopTraversalPolicy {
let mut tp = ForLoopTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -354,7 +354,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_while_stmt(&mut self, n: &WhileLoopNode, _: StatementTraversalContext) -> WhileLoopTraversalPolicy {
+ fn visit_while_stmt(&mut self, n: &WhileLoopNode, _: &TraversalContextStack) -> WhileLoopTraversalPolicy {
let mut tp = WhileLoopTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -373,7 +373,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_do_while_stmt(&mut self, n: &DoWhileLoopNode, _: StatementTraversalContext) -> DoWhileLoopTraversalPolicy {
+ fn visit_do_while_stmt(&mut self, n: &DoWhileLoopNode, _: &TraversalContextStack) -> DoWhileLoopTraversalPolicy {
let mut tp = DoWhileLoopTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -392,7 +392,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_if_stmt(&mut self, n: &IfConditionalNode, _: StatementTraversalContext) -> IfConditionalTraversalPolicy {
+ fn visit_if_stmt(&mut self, n: &IfConditionalNode, _: &TraversalContextStack) -> IfConditionalTraversalPolicy {
let mut tp = IfConditionalTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -414,7 +414,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_switch_stmt(&mut self, n: &SwitchConditionalNode, _: StatementTraversalContext) -> SwitchConditionalTraversalPolicy {
+ fn visit_switch_stmt(&mut self, n: &SwitchConditionalNode, _: &TraversalContextStack) -> SwitchConditionalTraversalPolicy {
let mut tp = SwitchConditionalTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -433,7 +433,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_switch_stmt_case(&mut self, n: &SwitchConditionalCaseLabelNode) -> SwitchConditionalCaseLabelTraversalPolicy {
+ fn visit_switch_stmt_case(&mut self, n: &SwitchConditionalCaseLabelNode, _: &TraversalContextStack) -> SwitchConditionalCaseLabelTraversalPolicy {
let mut tp = SwitchConditionalCaseLabelTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -449,28 +449,28 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_switch_stmt_default(&mut self, n: &SwitchConditionalDefaultLabelNode) {
+ fn visit_switch_stmt_default(&mut self, n: &SwitchConditionalDefaultLabelNode, _: &TraversalContextStack) {
self.currently_in_range = n.spans_position(self.pos);
if self.currently_in_range {
self.payload.borrow_mut().done = true;
}
}
- fn visit_break_stmt(&mut self, n: &BreakStatementNode, _: StatementTraversalContext) {
+ fn visit_break_stmt(&mut self, n: &BreakStatementNode, _: &TraversalContextStack) {
self.currently_in_range = n.spans_position(self.pos);
if self.currently_in_range {
self.payload.borrow_mut().done = true;
}
}
- fn visit_continue_stmt(&mut self, n: &ContinueStatementNode, _: StatementTraversalContext) {
+ fn visit_continue_stmt(&mut self, n: &ContinueStatementNode, _: &TraversalContextStack) {
self.currently_in_range = n.spans_position(self.pos);
if self.currently_in_range {
self.payload.borrow_mut().done = true;
}
}
- fn visit_delete_stmt(&mut self, n: &DeleteStatementNode, _: StatementTraversalContext) -> DeleteStatementTraversalPolicy {
+ fn visit_delete_stmt(&mut self, n: &DeleteStatementNode, _: &TraversalContextStack) -> DeleteStatementTraversalPolicy {
let mut tp = DeleteStatementTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -486,7 +486,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_return_stmt(&mut self, n: &ReturnStatementNode, _: StatementTraversalContext) -> ReturnStatementTraversalPolicy {
+ fn visit_return_stmt(&mut self, n: &ReturnStatementNode, _: &TraversalContextStack) -> ReturnStatementTraversalPolicy {
let mut tp = ReturnStatementTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -502,7 +502,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_expr_stmt(&mut self, n: &ExpressionStatementNode, _: StatementTraversalContext) -> ExpressionStatementTraversalPolicy {
+ fn visit_expr_stmt(&mut self, n: &ExpressionStatementNode, _: &TraversalContextStack) -> ExpressionStatementTraversalPolicy {
let mut tp = ExpressionStatementTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -518,7 +518,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_nop_stmt(&mut self, n: &NopNode, _: StatementTraversalContext) {
+ fn visit_nop_stmt(&mut self, n: &NopNode, _: &TraversalContextStack) {
self.currently_in_range = n.spans_position(self.pos);
if self.currently_in_range {
self.payload.borrow_mut().done = true;
@@ -528,7 +528,7 @@ impl SyntaxNodeVisitor for PositionFilter {
- fn visit_nested_expr(&mut self, n: &NestedExpressionNode, _: ExpressionTraversalContext) -> NestedExpressionTraversalPolicy {
+ fn visit_nested_expr(&mut self, n: &NestedExpressionNode, _: &TraversalContextStack) -> NestedExpressionTraversalPolicy {
let mut tp = NestedExpressionTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -544,7 +544,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode, _: ExpressionTraversalContext) -> AssignmentOperationExpressionTraversalPolicy {
+ fn visit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode, _: &TraversalContextStack) -> AssignmentOperationExpressionTraversalPolicy {
let mut tp = AssignmentOperationExpressionTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -563,7 +563,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, _: ExpressionTraversalContext) -> BinaryOperationExpressionTraversalPolicy {
+ fn visit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, _: &TraversalContextStack) -> BinaryOperationExpressionTraversalPolicy {
let mut tp = BinaryOperationExpressionTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -582,7 +582,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode, _: ExpressionTraversalContext) -> UnaryOperationExpressionTraversalPolicy {
+ fn visit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode, _: &TraversalContextStack) -> UnaryOperationExpressionTraversalPolicy {
let mut tp = UnaryOperationExpressionTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -598,7 +598,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_new_expr(&mut self, n: &NewExpressionNode, _: ExpressionTraversalContext) -> NewExpressionTraversalPolicy {
+ fn visit_new_expr(&mut self, n: &NewExpressionNode, _: &TraversalContextStack) -> NewExpressionTraversalPolicy {
let mut tp = NewExpressionTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -614,7 +614,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, _: ExpressionTraversalContext) -> TypeCastExpressionTraversalPolicy {
+ fn visit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, _: &TraversalContextStack) -> TypeCastExpressionTraversalPolicy {
let mut tp = TypeCastExpressionTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -630,7 +630,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode, _: ExpressionTraversalContext) -> TernaryConditionalExpressionTraversalPolicy {
+ fn visit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode, _: &TraversalContextStack) -> TernaryConditionalExpressionTraversalPolicy {
let mut tp = TernaryConditionalExpressionTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -652,7 +652,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, _: ExpressionTraversalContext) -> MemberFieldExpressionTraversalPolicy {
+ fn visit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, _: &TraversalContextStack) -> MemberFieldExpressionTraversalPolicy {
let mut tp = MemberFieldExpressionTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -668,7 +668,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_array_expr(&mut self, n: &ArrayExpressionNode, _: ExpressionTraversalContext) -> ArrayExpressionTraversalPolicy {
+ fn visit_array_expr(&mut self, n: &ArrayExpressionNode, _: &TraversalContextStack) -> ArrayExpressionTraversalPolicy {
let mut tp = ArrayExpressionTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -687,7 +687,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_func_call_expr(&mut self, n: &FunctionCallExpressionNode, _: ExpressionTraversalContext) -> FunctionCallExpressionTraversalPolicy {
+ fn visit_func_call_expr(&mut self, n: &FunctionCallExpressionNode, _: &TraversalContextStack) -> FunctionCallExpressionTraversalPolicy {
let mut tp = FunctionCallExpressionTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -706,7 +706,7 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_func_call_arg(&mut self, n: &FunctionCallArgument) -> FunctionCallArgumentTraversalPolicy {
+ fn visit_func_call_arg(&mut self, n: &FunctionCallArgument, _: &TraversalContextStack) -> FunctionCallArgumentTraversalPolicy {
let mut tp = FunctionCallArgumentTraversalPolicy::default_to(false);
self.currently_in_range = n.spans_position(self.pos);
@@ -724,42 +724,42 @@ impl SyntaxNodeVisitor for PositionFilter {
tp
}
- fn visit_identifier_expr(&mut self, n: &IdentifierNode, _: ExpressionTraversalContext) {
+ fn visit_identifier_expr(&mut self, n: &IdentifierNode, _: &TraversalContextStack) {
self.currently_in_range = n.spans_position(self.pos);
if self.currently_in_range {
self.payload.borrow_mut().done = true;
}
}
- fn visit_literal_expr(&mut self, n: &LiteralNode, _: ExpressionTraversalContext) {
+ fn visit_literal_expr(&mut self, n: &LiteralNode, _: &TraversalContextStack) {
self.currently_in_range = n.spans_position(self.pos);
if self.currently_in_range {
self.payload.borrow_mut().done = true;
}
}
- fn visit_this_expr(&mut self, n: &ThisExpressionNode, _: ExpressionTraversalContext) {
+ fn visit_this_expr(&mut self, n: &ThisExpressionNode, _: &TraversalContextStack) {
self.currently_in_range = n.spans_position(self.pos);
if self.currently_in_range {
self.payload.borrow_mut().done = true;
}
}
- fn visit_super_expr(&mut self, n: &SuperExpressionNode, _: ExpressionTraversalContext) {
+ fn visit_super_expr(&mut self, n: &SuperExpressionNode, _: &TraversalContextStack) {
self.currently_in_range = n.spans_position(self.pos);
if self.currently_in_range {
self.payload.borrow_mut().done = true;
}
}
- fn visit_parent_expr(&mut self, n: &ParentExpressionNode, _: ExpressionTraversalContext) {
+ fn visit_parent_expr(&mut self, n: &ParentExpressionNode, _: &TraversalContextStack) {
self.currently_in_range = n.spans_position(self.pos);
if self.currently_in_range {
self.payload.borrow_mut().done = true;
}
}
- fn visit_virtual_parent_expr(&mut self, n: &VirtualParentExpressionNode, _: ExpressionTraversalContext) {
+ fn visit_virtual_parent_expr(&mut self, n: &VirtualParentExpressionNode, _: &TraversalContextStack) {
self.currently_in_range = n.spans_position(self.pos);
if self.currently_in_range {
self.payload.borrow_mut().done = true;
diff --git a/crates/analysis/src/utils/visitors/sympath_builder.rs b/crates/analysis/src/utils/visitors/sympath_builder.rs
index 062e9f87..764430c5 100644
--- a/crates/analysis/src/utils/visitors/sympath_builder.rs
+++ b/crates/analysis/src/utils/visitors/sympath_builder.rs
@@ -113,23 +113,23 @@ impl SyntaxNodeVisitor for SymbolPathBuilder<'_> {
self.payload.borrow_mut().current_sympath.pop();
}
- fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, _: DeclarationTraversalContext) -> FunctionDeclarationTraversalPolicy {
+ fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, _: &TraversalContextStack) -> FunctionDeclarationTraversalPolicy {
let name = n.name().value(self.doc);
self.payload.borrow_mut().current_sympath.push(&name, SymbolCategory::Callable);
TraversalPolicy::default_to(true)
}
- fn exit_member_func_decl(&mut self, _: &FunctionDeclarationNode, _: DeclarationTraversalContext) {
+ fn exit_member_func_decl(&mut self, _: &FunctionDeclarationNode, _: &TraversalContextStack) {
self.payload.borrow_mut().current_sympath.pop();
}
- fn visit_event_decl(&mut self, n: &EventDeclarationNode, _: DeclarationTraversalContext) -> EventDeclarationTraversalPolicy {
+ fn visit_event_decl(&mut self, n: &EventDeclarationNode, _: &TraversalContextStack) -> EventDeclarationTraversalPolicy {
let name = n.name().value(self.doc);
self.payload.borrow_mut().current_sympath.push(&name, SymbolCategory::Callable);
TraversalPolicy::default_to(true)
}
- fn exit_event_decl(&mut self, _: &EventDeclarationNode, _: DeclarationTraversalContext) {
+ fn exit_event_decl(&mut self, _: &EventDeclarationNode, _: &TraversalContextStack) {
self.payload.borrow_mut().current_sympath.pop();
}
}
diff --git a/crates/core/src/ast/classes.rs b/crates/core/src/ast/classes.rs
index cc0353f1..4fbbe3d2 100644
--- a/crates/core/src/ast/classes.rs
+++ b/crates/core/src/ast/classes.rs
@@ -59,12 +59,12 @@ impl<'script> TryFrom> for ClassDeclarationNode<'script> {
}
impl SyntaxNodeTraversal for ClassDeclarationNode<'_> {
- type TraversalCtx = ();
-
- fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_class_decl(self);
if tp.traverse_definition {
- self.definition().accept(visitor, ());
+ ctx.push(TraversalContext::Class);
+ self.definition().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_class_decl(self);
}
@@ -106,10 +106,8 @@ impl<'script> TryFrom> for ClassBlockNode<'script> {
}
impl SyntaxNodeTraversal for ClassBlockNode<'_> {
- type TraversalCtx = ();
-
- fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) {
- self.iter().for_each(|s| s.accept(visitor, DeclarationTraversalContext::ClassDefinition));
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
+ self.iter().for_each(|s| s.accept(visitor, ctx));
}
}
@@ -184,9 +182,7 @@ impl<'script> TryFrom> for ClassPropertyNode<'script> {
}
impl SyntaxNodeTraversal for ClassPropertyNode<'_> {
- type TraversalCtx = DeclarationTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
match self.clone().value() {
ClassProperty::Var(s) => s.accept(visitor, ctx),
ClassProperty::Default(s) => s.accept(visitor, ctx),
@@ -256,9 +252,7 @@ impl<'script> TryFrom> for AutobindDeclarationNode<'script> {
}
impl SyntaxNodeTraversal for AutobindDeclarationNode<'_> {
- type TraversalCtx = DeclarationTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
visitor.visit_autobind_decl(self, ctx);
}
}
diff --git a/crates/core/src/ast/conditionals.rs b/crates/core/src/ast/conditionals.rs
index 35680eeb..50567429 100644
--- a/crates/core/src/ast/conditionals.rs
+++ b/crates/core/src/ast/conditionals.rs
@@ -55,18 +55,22 @@ impl<'script> TryFrom> for IfConditionalNode<'script> {
}
impl SyntaxNodeTraversal for IfConditionalNode<'_> {
- type TraversalCtx = StatementTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_if_stmt(self, ctx);
if tp.traverse_cond {
- self.cond().accept(visitor, ExpressionTraversalContext::IfConditionalCond);
+ ctx.push(TraversalContext::IfConditionalCond);
+ self.cond().accept(visitor, ctx);
+ ctx.pop();
}
if tp.traverse_body {
- self.body().accept(visitor, StatementTraversalContext::IfConditionalBody);
+ ctx.push(TraversalContext::IfConditionalBody);
+ self.body().accept(visitor, ctx);
+ ctx.pop();
}
if tp.traverse_else_body {
- self.else_body().map(|s| s.accept(visitor, StatementTraversalContext::IfConditionalElseBody));
+ ctx.push(TraversalContext::IfConditionalElseBody);
+ self.else_body().map(|s| s.accept(visitor, ctx));
+ ctx.pop();
}
visitor.exit_if_stmt(self, ctx);
}
@@ -112,15 +116,17 @@ impl<'script> TryFrom> for SwitchConditionalNode<'script> {
}
impl SyntaxNodeTraversal for SwitchConditionalNode<'_> {
- type TraversalCtx = StatementTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_switch_stmt(self, ctx);
if tp.traverse_cond {
- self.cond().accept(visitor, ExpressionTraversalContext::SwitchConditionalCond);
+ ctx.push(TraversalContext::SwitchConditionalCond);
+ self.cond().accept(visitor, ctx);
+ ctx.pop();
}
if tp.traverse_body {
- self.body().accept(visitor, ());
+ ctx.push(TraversalContext::SwitchConditionalBody);
+ self.body().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_switch_stmt(self, ctx);
}
@@ -162,10 +168,8 @@ impl<'script> TryFrom> for SwitchConditionalBlockNode<'script>
}
impl SyntaxNodeTraversal for SwitchConditionalBlockNode<'_> {
- type TraversalCtx = ();
-
- fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) {
- self.sections().for_each(|s| s.accept(visitor, ()));
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
+ self.sections().for_each(|s| s.accept(visitor, ctx));
}
}
@@ -233,13 +237,11 @@ impl<'script> TryFrom> for SwitchConditionalSectionNode<'script
}
impl SyntaxNodeTraversal for SwitchConditionalSectionNode<'_> {
- type TraversalCtx = ();
-
- fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
match self.clone().value() {
- SwitchConditionalSection::Statement(n) => n.accept(visitor, StatementTraversalContext::SwitchConditionalBody),
- SwitchConditionalSection::Case(n) => n.accept(visitor, ()),
- SwitchConditionalSection::Default(n) => n.accept(visitor, ()),
+ SwitchConditionalSection::Statement(n) => n.accept(visitor, ctx),
+ SwitchConditionalSection::Case(n) => n.accept(visitor, ctx),
+ SwitchConditionalSection::Default(n) => n.accept(visitor, ctx),
}
}
}
@@ -279,14 +281,14 @@ impl<'script> TryFrom> for SwitchConditionalCaseLabelNode<'scri
}
impl SyntaxNodeTraversal for SwitchConditionalCaseLabelNode<'_> {
- type TraversalCtx = ();
-
- fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) {
- let tp = visitor.visit_switch_stmt_case(self);
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
+ let tp = visitor.visit_switch_stmt_case(self, ctx);
if tp.traverse_value {
- self.value().accept(visitor, ExpressionTraversalContext::SwitchConditionalCaseLabel);
+ ctx.push(TraversalContext::SwitchConditionalCaseLabel);
+ self.value().accept(visitor, ctx);
+ ctx.pop();
}
- visitor.exit_switch_stmt_case(self);
+ visitor.exit_switch_stmt_case(self, ctx);
}
}
@@ -317,9 +319,7 @@ impl<'script> TryFrom> for SwitchConditionalDefaultLabelNode<'s
}
impl SyntaxNodeTraversal for SwitchConditionalDefaultLabelNode<'_> {
- type TraversalCtx = ();
-
- fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) {
- visitor.visit_switch_stmt_default(self);
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
+ visitor.visit_switch_stmt_default(self, ctx);
}
}
\ No newline at end of file
diff --git a/crates/core/src/ast/enums.rs b/crates/core/src/ast/enums.rs
index 0738c91e..1c93e44c 100644
--- a/crates/core/src/ast/enums.rs
+++ b/crates/core/src/ast/enums.rs
@@ -48,12 +48,12 @@ impl<'script> TryFrom> for EnumDeclarationNode<'script> {
}
impl SyntaxNodeTraversal for EnumDeclarationNode<'_> {
- type TraversalCtx = ();
-
- fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_enum_decl(self);
if tp.traverse_definition {
- self.definition().accept(visitor, ());
+ ctx.push(TraversalContext::Enum);
+ self.definition().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_enum_decl(self);
}
@@ -95,10 +95,8 @@ impl<'script> TryFrom> for EnumBlockNode<'script> {
}
impl SyntaxNodeTraversal for EnumBlockNode<'_> {
- type TraversalCtx = ();
-
- fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) {
- self.iter().for_each(|s| s.accept(visitor, ()));
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
+ self.iter().for_each(|s| s.accept(visitor, ctx));
}
}
@@ -148,9 +146,7 @@ impl<'script> TryFrom> for EnumVariantDeclarationNode<'script>
}
impl SyntaxNodeTraversal for EnumVariantDeclarationNode<'_> {
- type TraversalCtx = ();
-
- fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, _: &mut TraversalContextStack) {
visitor.visit_enum_variant_decl(self);
}
}
diff --git a/crates/core/src/ast/expressions.rs b/crates/core/src/ast/expressions.rs
index 073e12bc..92ce90c7 100644
--- a/crates/core/src/ast/expressions.rs
+++ b/crates/core/src/ast/expressions.rs
@@ -57,12 +57,12 @@ impl<'script> TryFrom> for NestedExpressionNode<'script> {
}
impl SyntaxNodeTraversal for NestedExpressionNode<'_> {
- type TraversalCtx = ExpressionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_nested_expr(self, ctx);
if tp.traverse_inner {
- self.inner().accept(visitor, ExpressionTraversalContext::NestedExpressionInner);
+ ctx.push(TraversalContext::NestedExpressionInner);
+ self.inner().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_nested_expr(self, ctx);
}
@@ -97,9 +97,7 @@ impl<'script> TryFrom> for ThisExpressionNode<'script> {
}
impl SyntaxNodeTraversal for ThisExpressionNode<'_> {
- type TraversalCtx = ExpressionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
visitor.visit_this_expr(self, ctx);
}
}
@@ -133,9 +131,7 @@ impl<'script> TryFrom> for SuperExpressionNode<'script> {
}
impl SyntaxNodeTraversal for SuperExpressionNode<'_> {
- type TraversalCtx = ExpressionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
visitor.visit_super_expr(self, ctx);
}
}
@@ -169,9 +165,7 @@ impl<'script> TryFrom> for ParentExpressionNode<'script> {
}
impl SyntaxNodeTraversal for ParentExpressionNode<'_> {
- type TraversalCtx = ExpressionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
visitor.visit_parent_expr(self, ctx);
}
}
@@ -205,9 +199,7 @@ impl<'script> TryFrom> for VirtualParentExpressionNode<'script>
}
impl SyntaxNodeTraversal for VirtualParentExpressionNode<'_> {
- type TraversalCtx = ExpressionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
visitor.visit_virtual_parent_expr(self, ctx);
}
}
@@ -252,15 +244,15 @@ impl<'script> TryFrom> for FunctionCallExpressionNode<'script>
}
impl SyntaxNodeTraversal for FunctionCallExpressionNode<'_> {
- type TraversalCtx = ExpressionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_func_call_expr(self, ctx);
if tp.traverse_func {
- self.func().accept(visitor, ExpressionTraversalContext::FunctionCallExpressionFunc);
+ ctx.push(TraversalContext::FunctionCallExpressionFunc);
+ self.func().accept(visitor, ctx);
+ ctx.pop();
}
if tp.traverse_args {
- self.args().map(|n| n.accept(visitor, ()));
+ self.args().map(|n| n.accept(visitor, ctx));
}
visitor.exit_func_call_expr(self, ctx);
}
@@ -318,10 +310,8 @@ impl<'script> TryFrom> for FunctionCallArgumentsNode<'script> {
}
impl SyntaxNodeTraversal for FunctionCallArgumentsNode<'_> {
- type TraversalCtx = ();
-
- fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) {
- self.iter().for_each(|n| n.accept(visitor, ()))
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
+ self.iter().for_each(|n| n.accept(visitor, ctx))
}
}
@@ -364,16 +354,16 @@ impl Debug for FunctionCallArgument<'_> {
}
impl SyntaxNodeTraversal for FunctionCallArgument<'_> {
- type TraversalCtx = ();
-
- fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) {
- let tp = visitor.visit_func_call_arg(self);
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
+ let tp = visitor.visit_func_call_arg(self, ctx);
if tp.traverse_expr {
if let FunctionCallArgument::Some(n) = self {
- n.accept(visitor, ExpressionTraversalContext::FunctionCallArg);
+ ctx.push(TraversalContext::FunctionCallArg);
+ n.accept(visitor, ctx);
+ ctx.pop();
}
}
- visitor.exit_func_call_arg(self);
+ visitor.exit_func_call_arg(self, ctx);
}
}
@@ -417,15 +407,17 @@ impl<'script> TryFrom> for ArrayExpressionNode<'script> {
}
impl SyntaxNodeTraversal for ArrayExpressionNode<'_> {
- type TraversalCtx = ExpressionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_array_expr(self, ctx);
if tp.traverse_accessor {
- self.accessor().accept(visitor, ExpressionTraversalContext::ArrayExpressionAccessor);
+ ctx.push(TraversalContext::ArrayExpressionAccessor);
+ self.accessor().accept(visitor, ctx);
+ ctx.pop();
}
if tp.traverse_index {
- self.index().accept(visitor, ExpressionTraversalContext::ArrayExpressionIndex);
+ ctx.push(TraversalContext::ArrayExpressionIndex);
+ self.index().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_array_expr(self, ctx);
}
@@ -471,12 +463,12 @@ impl<'script> TryFrom> for MemberAccessExpressionNode<'script>
}
impl SyntaxNodeTraversal for MemberAccessExpressionNode<'_> {
- type TraversalCtx = ExpressionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_member_access_expr(self, ctx);
if tp.traverse_accessor {
- self.accessor().accept(visitor, ExpressionTraversalContext::MemberAccessExpressionAccessor);
+ ctx.push(TraversalContext::MemberAccessExpressionAccessor);
+ self.accessor().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_member_access_expr(self, ctx);
}
@@ -522,12 +514,12 @@ impl<'script> TryFrom> for NewExpressionNode<'script> {
}
impl SyntaxNodeTraversal for NewExpressionNode<'_> {
- type TraversalCtx = ExpressionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_new_expr(self, ctx);
if tp.traverse_lifetime_obj {
- self.lifetime_obj().map(|n| n.accept(visitor, ExpressionTraversalContext::NewExpressionLifetimeObj));
+ ctx.push(TraversalContext::NewExpressionLifetimeObj);
+ self.lifetime_obj().map(|n| n.accept(visitor, ctx));
+ ctx.pop();
}
visitor.exit_new_expr(self, ctx);
}
@@ -573,12 +565,12 @@ impl<'script> TryFrom> for TypeCastExpressionNode<'script> {
}
impl SyntaxNodeTraversal for TypeCastExpressionNode<'_> {
- type TraversalCtx = ExpressionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_type_cast_expr(self, ctx);
if tp.traverse_value {
- self.value().accept(visitor, ExpressionTraversalContext::TypeCastExpressionValue);
+ ctx.push(TraversalContext::TypeCastExpressionValue);
+ self.value().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_type_cast_expr(self, ctx);
}
@@ -624,12 +616,12 @@ impl<'script> TryFrom> for UnaryOperationExpressionNode<'script
}
impl SyntaxNodeTraversal for UnaryOperationExpressionNode<'_> {
- type TraversalCtx = ExpressionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_unary_op_expr(self, ctx);
if tp.traverse_right {
- self.right().accept(visitor, ExpressionTraversalContext::UnaryOperationExpressionRight);
+ ctx.push(TraversalContext::UnaryOperationExpressionRight);
+ self.right().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_unary_op_expr(self, ctx);
}
@@ -680,15 +672,17 @@ impl<'script> TryFrom> for BinaryOperationExpressionNode<'scrip
}
impl SyntaxNodeTraversal for BinaryOperationExpressionNode<'_> {
- type TraversalCtx = ExpressionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_binary_op_expr(self, ctx);
if tp.traverse_left {
- self.left().accept(visitor, ExpressionTraversalContext::BinaryOperationExpressionLeft);
+ ctx.push(TraversalContext::BinaryOperationExpressionLeft);
+ self.left().accept(visitor, ctx);
+ ctx.pop();
}
if tp.traverse_right {
- self.right().accept(visitor, ExpressionTraversalContext::BinaryOperationExpressionRight);
+ ctx.push(TraversalContext::BinaryOperationExpressionRight);
+ self.right().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_binary_op_expr(self, ctx);
}
@@ -739,15 +733,17 @@ impl<'script> TryFrom> for AssignmentOperationExpressionNode<'s
}
impl SyntaxNodeTraversal for AssignmentOperationExpressionNode<'_> {
- type TraversalCtx = ExpressionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_assign_op_expr(self, ctx);
if tp.traverse_left {
- self.left().accept(visitor, ExpressionTraversalContext::AssignmentOperationExpressionLeft);
+ ctx.push(TraversalContext::AssignmentOperationExpressionLeft);
+ self.left().accept(visitor, ctx);
+ ctx.pop();
}
if tp.traverse_right {
- self.right().accept(visitor, ExpressionTraversalContext::AssignmentOperationExpressionRight);
+ ctx.push(TraversalContext::AssignmentOperationExpressionRight);
+ self.right().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_assign_op_expr(self, ctx);
}
@@ -798,18 +794,22 @@ impl<'script> TryFrom> for TernaryConditionalExpressionNode<'sc
}
impl SyntaxNodeTraversal for TernaryConditionalExpressionNode<'_> {
- type TraversalCtx = ExpressionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_ternary_cond_expr(self, ctx);
if tp.traverse_cond {
- self.cond().accept(visitor, ExpressionTraversalContext::TernaryConditionalExpressionCond);
+ ctx.push(TraversalContext::TernaryConditionalExpressionCond);
+ self.cond().accept(visitor, ctx);
+ ctx.pop();
}
if tp.traverse_conseq {
- self.conseq().accept(visitor, ExpressionTraversalContext::TernaryConditionalExpressionConseq);
+ ctx.push(TraversalContext::TernaryConditionalExpressionConseq);
+ self.conseq().accept(visitor, ctx);
+ ctx.pop();
}
if tp.traverse_alt {
- self.alt().accept(visitor, ExpressionTraversalContext::TernaryConditionalExpressionAlt);
+ ctx.push(TraversalContext::TernaryConditionalExpressionAlt);
+ self.alt().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_ternary_cond_expr(self, ctx);
}
@@ -1032,9 +1032,7 @@ impl<'script> From> for ExpressionNode
}
impl SyntaxNodeTraversal for ExpressionNode<'_> {
- type TraversalCtx = ExpressionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
match self.clone().value() {
Expression::Nested(n) => n.accept(visitor, ctx),
Expression::Literal(n) => n.accept(visitor, ctx),
@@ -1091,12 +1089,12 @@ impl<'script> TryFrom> for ExpressionStatementNode<'script> {
}
impl SyntaxNodeTraversal for ExpressionStatementNode<'_> {
- type TraversalCtx = StatementTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_expr_stmt(self, ctx);
if tp.traverse_expr {
- self.expr().accept(visitor, ExpressionTraversalContext::ExpressionStatement);
+ ctx.push(TraversalContext::ExpressionStatement);
+ self.expr().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_expr_stmt(self, ctx);
}
diff --git a/crates/core/src/ast/functions.rs b/crates/core/src/ast/functions.rs
index f8626164..d49501c7 100644
--- a/crates/core/src/ast/functions.rs
+++ b/crates/core/src/ast/functions.rs
@@ -65,16 +65,18 @@ impl<'script> TryFrom> for EventDeclarationNode<'script> {
}
impl SyntaxNodeTraversal for EventDeclarationNode<'_> {
- type TraversalCtx = DeclarationTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_event_decl(self, ctx);
+
+ ctx.push(TraversalContext::Event);
if tp.traverse_params {
- self.params().accept(visitor, FunctionTraversalContext::Event);
+ self.params().accept(visitor, ctx);
}
if tp.traverse_definition {
- self.definition().accept(visitor, FunctionTraversalContext::Event);
+ self.definition().accept(visitor, ctx);
}
+ ctx.pop();
+
visitor.exit_event_decl(self, ctx);
}
}
@@ -144,29 +146,31 @@ impl<'script> TryFrom> for FunctionDeclarationNode<'script> {
}
impl SyntaxNodeTraversal for FunctionDeclarationNode<'_> {
- type TraversalCtx = DeclarationTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
- if ctx == DeclarationTraversalContext::Global {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
+ if ctx.top() == TraversalContext::Global {
let tp = visitor.visit_global_func_decl(self);
+ ctx.push(TraversalContext::GlobalFunction);
if tp.traverse_params {
- self.params().accept(visitor, FunctionTraversalContext::GlobalFunction);
+ self.params().accept(visitor, ctx);
}
if tp.traverse_definition {
- self.definition().accept(visitor, FunctionTraversalContext::GlobalFunction);
+ self.definition().accept(visitor, ctx);
}
+ ctx.pop();
visitor.exit_global_func_decl(self);
} else {
let tp = visitor.visit_member_func_decl(self, ctx);
+ ctx.push(TraversalContext::MemberFunction);
if tp.traverse_params {
- self.params().accept(visitor, FunctionTraversalContext::MemberFunction);
+ self.params().accept(visitor, ctx);
}
if tp.traverse_definition {
- self.definition().accept(visitor, FunctionTraversalContext::MemberFunction);
+ self.definition().accept(visitor, ctx);
}
+ ctx.pop();
visitor.exit_member_func_decl(self, ctx);
}
@@ -225,9 +229,7 @@ impl<'script> TryFrom> for FunctionDefinitionNode<'script> {
}
impl SyntaxNodeTraversal for FunctionDefinitionNode<'_> {
- type TraversalCtx = FunctionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
if let FunctionDefinition::Some(block) = self.clone().value() {
block.accept(visitor, ctx);
}
@@ -270,16 +272,8 @@ impl<'script> TryFrom> for FunctionBlockNode<'script> {
}
impl SyntaxNodeTraversal for FunctionBlockNode<'_> {
- type TraversalCtx = FunctionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
- let iter_ctx = match ctx {
- FunctionTraversalContext::GlobalFunction => StatementTraversalContext::GlobalFunctionDefinition,
- FunctionTraversalContext::MemberFunction => StatementTraversalContext::MemberFunctionDefinition,
- FunctionTraversalContext::Event => StatementTraversalContext::EventDefinition,
- };
-
- self.iter().for_each(|s| s.accept(visitor, iter_ctx));
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
+ self.iter().for_each(|s| s.accept(visitor, ctx));
}
}
@@ -319,9 +313,7 @@ impl<'script> TryFrom> for FunctionParametersNode<'script> {
}
impl SyntaxNodeTraversal for FunctionParametersNode<'_> {
- type TraversalCtx = FunctionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
self.iter().for_each(|s| s.accept(visitor, ctx));
}
}
@@ -371,9 +363,7 @@ impl<'script> TryFrom> for FunctionParameterGroupNode<'script>
}
impl SyntaxNodeTraversal for FunctionParameterGroupNode<'_> {
- type TraversalCtx = FunctionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
visitor.visit_func_param_group(self, ctx);
}
}
@@ -474,9 +464,7 @@ impl<'script> TryFrom> for FunctionStatementNode<'script> {
}
impl SyntaxNodeTraversal for FunctionStatementNode<'_> {
- type TraversalCtx = StatementTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
match self.clone().value() {
FunctionStatement::Var(s) => s.accept(visitor, ctx),
FunctionStatement::Expr(s) => s.accept(visitor, ctx),
@@ -524,9 +512,7 @@ impl<'script> TryFrom> for BreakStatementNode<'script> {
}
impl SyntaxNodeTraversal for BreakStatementNode<'_> {
- type TraversalCtx = StatementTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
visitor.visit_break_stmt(self, ctx);
}
}
@@ -560,9 +546,7 @@ impl<'script> TryFrom> for ContinueStatementNode<'script> {
}
impl SyntaxNodeTraversal for ContinueStatementNode<'_> {
- type TraversalCtx = StatementTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
visitor.visit_continue_stmt(self, ctx);
}
}
@@ -602,12 +586,12 @@ impl<'script> TryFrom> for ReturnStatementNode<'script> {
}
impl SyntaxNodeTraversal for ReturnStatementNode<'_> {
- type TraversalCtx = StatementTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_return_stmt(self, ctx);
if tp.traverse_value {
- self.value().map(|expr| expr.accept(visitor, ExpressionTraversalContext::ReturnStatement));
+ ctx.push(TraversalContext::ReturnStatement);
+ self.value().map(|expr| expr.accept(visitor, ctx));
+ ctx.pop();
}
visitor.exit_return_stmt(self, ctx);
}
@@ -648,12 +632,12 @@ impl<'script> TryFrom> for DeleteStatementNode<'script> {
}
impl SyntaxNodeTraversal for DeleteStatementNode<'_> {
- type TraversalCtx = StatementTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_delete_stmt(self, ctx);
if tp.traverse_value {
- self.value().accept(visitor, ExpressionTraversalContext::DeleteStatement);
+ ctx.push(TraversalContext::DeleteStatement);
+ self.value().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_delete_stmt(self, ctx);
}
@@ -695,12 +679,12 @@ impl<'script> TryFrom> for CompoundStatementNode<'script> {
}
impl SyntaxNodeTraversal for CompoundStatementNode<'_> {
- type TraversalCtx = StatementTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_compound_stmt(self, ctx);
if tp.traverse {
- self.iter().for_each(|s| s.accept(visitor, StatementTraversalContext::InCompoundStatement));
+ ctx.push(TraversalContext::CompoundStatement);
+ self.iter().for_each(|s| s.accept(visitor, ctx));
+ ctx.pop();
}
visitor.exit_compound_stmt(self, ctx);
}
diff --git a/crates/core/src/ast/loops.rs b/crates/core/src/ast/loops.rs
index 7e804535..e850a256 100644
--- a/crates/core/src/ast/loops.rs
+++ b/crates/core/src/ast/loops.rs
@@ -58,21 +58,27 @@ impl<'script> TryFrom> for ForLoopNode<'script> {
}
impl SyntaxNodeTraversal for ForLoopNode<'_> {
- type TraversalCtx = StatementTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_for_stmt(self, ctx);
if tp.traverse_init {
- self.init().map(|init| init.accept(visitor, ExpressionTraversalContext::ForLoopInit));
+ ctx.push(TraversalContext::ForLoopInit);
+ self.init().map(|init| init.accept(visitor, ctx));
+ ctx.pop();
}
if tp.traverse_cond {
- self.cond().map(|cond| cond.accept(visitor, ExpressionTraversalContext::ForLoopCond));
+ ctx.push(TraversalContext::ForLoopCond);
+ self.cond().map(|cond| cond.accept(visitor, ctx));
+ ctx.pop();
}
if tp.traverse_iter {
- self.iter().map(|iter| iter.accept(visitor, ExpressionTraversalContext::ForLoopIter));
+ ctx.push(TraversalContext::ForLoopIter);
+ self.iter().map(|iter| iter.accept(visitor, ctx));
+ ctx.pop();
}
if tp.traverse_body {
- self.body().accept(visitor, StatementTraversalContext::ForLoopBody);
+ ctx.push(TraversalContext::ForLoopBody);
+ self.body().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_for_stmt(self, ctx);
}
@@ -118,15 +124,17 @@ impl<'script> TryFrom> for WhileLoopNode<'script> {
}
impl SyntaxNodeTraversal for WhileLoopNode<'_> {
- type TraversalCtx = StatementTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_while_stmt(self, ctx);
if tp.traverse_cond {
- self.cond().accept(visitor, ExpressionTraversalContext::WhileLoopCond);
+ ctx.push(TraversalContext::WhileLoopCond);
+ self.cond().accept(visitor, ctx);
+ ctx.pop();
}
if tp.traverse_body {
- self.body().accept(visitor, StatementTraversalContext::WhileLoopBody);
+ ctx.push(TraversalContext::WhileLoopBody);
+ self.body().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_while_stmt(self, ctx);
}
@@ -172,15 +180,17 @@ impl<'script> TryFrom> for DoWhileLoopNode<'script> {
}
impl SyntaxNodeTraversal for DoWhileLoopNode<'_> {
- type TraversalCtx = StatementTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_do_while_stmt(self, ctx);
if tp.traverse_cond {
- self.cond().accept(visitor, ExpressionTraversalContext::DoWhileLoopCond);
+ ctx.push(TraversalContext::DoWhileLoopCond);
+ self.cond().accept(visitor, ctx);
+ ctx.pop();
}
if tp.traverse_body {
- self.body().accept(visitor, StatementTraversalContext::DoWhileLoopBody);
+ ctx.push(TraversalContext::DoWhileLoopBody);
+ self.body().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_do_while_stmt(self, ctx);
}
diff --git a/crates/core/src/ast/nop.rs b/crates/core/src/ast/nop.rs
index 4cb30ec2..6929aa8c 100644
--- a/crates/core/src/ast/nop.rs
+++ b/crates/core/src/ast/nop.rs
@@ -36,9 +36,7 @@ impl<'script> TryFrom> for NopNode<'script> {
}
impl SyntaxNodeTraversal for NopNode<'_> {
- type TraversalCtx = StatementTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
visitor.visit_nop_stmt(self, ctx);
}
}
\ No newline at end of file
diff --git a/crates/core/src/ast/root.rs b/crates/core/src/ast/root.rs
index 87b76e2c..262e441c 100644
--- a/crates/core/src/ast/root.rs
+++ b/crates/core/src/ast/root.rs
@@ -79,16 +79,14 @@ impl<'script> TryFrom> for RootStatementNode<'script> {
}
impl SyntaxNodeTraversal for RootStatementNode<'_> {
- type TraversalCtx = ();
-
- fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
match self.clone().value() {
- RootStatement::Function(s) => s.accept(visitor, DeclarationTraversalContext::Global),
- RootStatement::Class(s) => s.accept(visitor, ()),
- RootStatement::State(s) => s.accept(visitor, ()),
- RootStatement::Struct(s) => s.accept(visitor, ()),
- RootStatement::Enum(s) => s.accept(visitor, ()),
- RootStatement::Var(s) => s.accept(visitor, DeclarationTraversalContext::Global),
+ RootStatement::Function(s) => s.accept(visitor, ctx),
+ RootStatement::Class(s) => s.accept(visitor, ctx),
+ RootStatement::State(s) => s.accept(visitor, ctx),
+ RootStatement::Struct(s) => s.accept(visitor, ctx),
+ RootStatement::Enum(s) => s.accept(visitor, ctx),
+ RootStatement::Var(s) => s.accept(visitor, ctx),
RootStatement::Nop(_) => {},
}
}
@@ -130,12 +128,12 @@ impl<'script> TryFrom> for RootNode<'script> {
}
impl SyntaxNodeTraversal for RootNode<'_> {
- type TraversalCtx = ();
-
- fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_root(self);
if tp.traverse {
- self.iter().for_each(|s| s.accept(visitor, ()));
+ ctx.push(TraversalContext::Global);
+ self.iter().for_each(|s| s.accept(visitor, ctx));
+ ctx.pop();
}
}
}
\ No newline at end of file
diff --git a/crates/core/src/ast/states.rs b/crates/core/src/ast/states.rs
index ace3641a..78ec5f19 100644
--- a/crates/core/src/ast/states.rs
+++ b/crates/core/src/ast/states.rs
@@ -62,12 +62,12 @@ impl<'script> TryFrom> for StateDeclarationNode<'script> {
}
impl SyntaxNodeTraversal for StateDeclarationNode<'_> {
- type TraversalCtx = ();
-
- fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_state_decl(self);
if tp.traverse_definition {
- self.definition().accept(visitor, ());
+ ctx.push(TraversalContext::State);
+ self.definition().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_state_decl(self);
}
@@ -108,9 +108,7 @@ impl<'script> TryFrom> for StateBlockNode<'script> {
}
impl SyntaxNodeTraversal for StateBlockNode<'_> {
- type TraversalCtx = ();
-
- fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) {
- self.iter().for_each(|s| s.accept(visitor, DeclarationTraversalContext::StateDefinition));
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
+ self.iter().for_each(|s| s.accept(visitor, ctx));
}
}
\ No newline at end of file
diff --git a/crates/core/src/ast/structs.rs b/crates/core/src/ast/structs.rs
index 45b3836c..4bcdac33 100644
--- a/crates/core/src/ast/structs.rs
+++ b/crates/core/src/ast/structs.rs
@@ -56,12 +56,12 @@ impl<'script> TryFrom> for StructDeclarationNode<'script> {
}
impl SyntaxNodeTraversal for StructDeclarationNode<'_> {
- type TraversalCtx = ();
-
- fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_struct_decl(self);
if tp.traverse_definition {
- self.definition().accept(visitor, ());
+ ctx.push(TraversalContext::Struct);
+ self.definition().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_struct_decl(self);
}
@@ -103,10 +103,8 @@ impl<'script> TryFrom> for StructBlockNode<'script> {
}
impl SyntaxNodeTraversal for StructBlockNode<'_> {
- type TraversalCtx = ();
-
- fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) {
- self.iter().for_each(|s| s.accept(visitor, DeclarationTraversalContext::StructDefinition));
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
+ self.iter().for_each(|s| s.accept(visitor, ctx));
}
}
@@ -174,9 +172,7 @@ impl<'script> TryFrom> for StructPropertyNode<'script> {
}
impl SyntaxNodeTraversal for StructPropertyNode<'_> {
- type TraversalCtx = DeclarationTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
match self.clone().value() {
StructProperty::Var(s) => s.accept(visitor, ctx),
StructProperty::Default(s) => s.accept(visitor, ctx),
@@ -223,12 +219,10 @@ impl<'script> TryFrom> for MemberDefaultsBlockNode<'script> {
}
impl SyntaxNodeTraversal for MemberDefaultsBlockNode<'_> {
- type TraversalCtx = DeclarationTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_member_defaults_block(self, ctx);
if tp.traverse {
- self.iter().for_each(|n| n.accept(visitor, ()));
+ self.iter().for_each(|n| n.accept(visitor, ctx));
}
visitor.exit_member_defaults_block(self, ctx);
}
@@ -274,14 +268,14 @@ impl<'script> TryFrom> for MemberDefaultsBlockAssignmentNode<'s
}
impl SyntaxNodeTraversal for MemberDefaultsBlockAssignmentNode<'_> {
- type TraversalCtx = ();
-
- fn accept(&self, visitor: &mut V, _: Self::TraversalCtx) {
- let tp = visitor.visit_member_defaults_block_assignment(self);
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
+ let tp = visitor.visit_member_defaults_block_assignment(self, ctx);
if tp.traverse_value {
- self.value().accept(visitor, ExpressionTraversalContext::MemberDefaultValue);
+ ctx.push(TraversalContext::MemberDefaultValue);
+ self.value().accept(visitor, ctx);
+ ctx.pop();
}
- visitor.exit_member_defaults_block_assignment(self);
+ visitor.exit_member_defaults_block_assignment(self, ctx);
}
}
@@ -325,12 +319,12 @@ impl<'script> TryFrom> for MemberDefaultValueNode<'script> {
}
impl SyntaxNodeTraversal for MemberDefaultValueNode<'_> {
- type TraversalCtx = DeclarationTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_member_default_val(self, ctx);
if tp.traverse_value {
- self.value().accept(visitor, ExpressionTraversalContext::MemberDefaultValue);
+ ctx.push(TraversalContext::MemberDefaultValue);
+ self.value().accept(visitor, ctx);
+ ctx.pop();
}
visitor.exit_member_default_val(self, ctx);
}
@@ -376,9 +370,7 @@ impl<'script> TryFrom> for MemberHintNode<'script> {
}
impl SyntaxNodeTraversal for MemberHintNode<'_> {
- type TraversalCtx = DeclarationTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
visitor.visit_member_hint(self, ctx);
}
}
diff --git a/crates/core/src/ast/traversal/contexts.rs b/crates/core/src/ast/traversal/contexts.rs
index c1f69563..7e670c77 100644
--- a/crates/core/src/ast/traversal/contexts.rs
+++ b/crates/core/src/ast/traversal/contexts.rs
@@ -3,23 +3,45 @@
//! a class, a state or a struct.
-//TODO maybe replace separate enums with just one, but pass around a stack of these contexts
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum ExpressionTraversalContext {
+pub enum TraversalContext {
+ Global,
+
+ Class,
+ State,
+ Struct,
+ Enum,
+ GlobalFunction,
+
+ MemberFunction,
+ Event,
MemberDefaultValue,
-
+
+ LocalVarDeclarationInitValue,
+
ExpressionStatement,
+ CompoundStatement,
ReturnStatement,
DeleteStatement,
+
+ IfConditionalCond,
+ IfConditionalBody,
+ IfConditionalElseBody,
+
+ SwitchConditionalCond,
+ SwitchConditionalBody,
+ SwitchConditionalCaseLabel,
+
ForLoopInit,
ForLoopCond,
ForLoopIter,
+ ForLoopBody,
+
WhileLoopCond,
+ WhileLoopBody,
+
DoWhileLoopCond,
- IfConditionalCond,
- SwitchConditionalCond,
- SwitchConditionalCaseLabel,
- LocalVarDeclarationInitValue,
+ DoWhileLoopBody,
NestedExpressionInner,
FunctionCallExpressionFunc,
@@ -39,33 +61,55 @@ pub enum ExpressionTraversalContext {
TernaryConditionalExpressionAlt,
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum DeclarationTraversalContext {
- Global,
- ClassDefinition,
- StateDefinition,
- StructDefinition
+impl Default for TraversalContext {
+ fn default() -> Self {
+ Self::Global
+ }
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum FunctionTraversalContext {
- GlobalFunction,
- MemberFunction,
- Event
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct TraversalContextStack {
+ stack: Vec
}
+impl TraversalContextStack {
+ #[inline]
+ pub fn new() -> Self {
+ Self {
+ stack: Vec::with_capacity(8)
+ }
+ }
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum StatementTraversalContext {
- GlobalFunctionDefinition,
- MemberFunctionDefinition,
- EventDefinition,
+ #[inline]
+ pub fn push(&mut self, ctx: TraversalContext) {
+ self.stack.push(ctx);
+ }
- IfConditionalBody,
- IfConditionalElseBody,
- SwitchConditionalBody,
- ForLoopBody,
- WhileLoopBody,
- DoWhileLoopBody,
- InCompoundStatement
+ #[inline]
+ pub fn pop(&mut self) {
+ self.stack.pop();
+ }
+
+ #[inline]
+ pub fn top(&self) -> TraversalContext {
+ self.stack.last().map(|ctx| *ctx).unwrap_or_default()
+ }
+
+ #[inline]
+ pub fn contains(&self, ctx: TraversalContext) -> bool {
+ self.stack.contains(&ctx)
+ }
+
+ /// Iterate the stack top-to-bottom
+ #[inline]
+ pub fn iter<'a>(&'a self) -> impl Iterator- + 'a {
+ self.stack.iter().rev().cloned()
+ }
+}
+
+impl Default for TraversalContextStack {
+ fn default() -> Self {
+ Self::new()
+ }
}
diff --git a/crates/core/src/ast/traversal/mod.rs b/crates/core/src/ast/traversal/mod.rs
index 562232f2..b73bc2ab 100644
--- a/crates/core/src/ast/traversal/mod.rs
+++ b/crates/core/src/ast/traversal/mod.rs
@@ -11,7 +11,5 @@ pub use visitor_chain::*;
/// Traverse an syntax node using left-recursion.
pub trait SyntaxNodeTraversal {
- type TraversalCtx;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx);
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack);
}
diff --git a/crates/core/src/ast/traversal/visitor.rs b/crates/core/src/ast/traversal/visitor.rs
index d0c6fa91..04a7ec93 100644
--- a/crates/core/src/ast/traversal/visitor.rs
+++ b/crates/core/src/ast/traversal/visitor.rs
@@ -16,78 +16,78 @@ pub trait SyntaxNodeVisitor {
/// Called when visiting a parenthesized expression node.
- fn visit_nested_expr(&mut self, n: &NestedExpressionNode, ctx: ExpressionTraversalContext) -> NestedExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_nested_expr(&mut self, n: &NestedExpressionNode, ctx: &TraversalContextStack) -> NestedExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting the nested expression node and possibly also children nodes specified in traversal policy.
- fn exit_nested_expr(&mut self, n: &NestedExpressionNode, ctx: ExpressionTraversalContext) {}
+ fn exit_nested_expr(&mut self, n: &NestedExpressionNode, ctx: &TraversalContextStack) {}
/// Called when visiting a node representing any literal.
- fn visit_literal_expr(&mut self, n: &LiteralNode, ctx: ExpressionTraversalContext) {}
+ fn visit_literal_expr(&mut self, n: &LiteralNode, ctx: &TraversalContextStack) {}
/// Called when visiting a node representing a `this` expression.
- fn visit_this_expr(&mut self, n: &ThisExpressionNode, ctx: ExpressionTraversalContext) {}
+ fn visit_this_expr(&mut self, n: &ThisExpressionNode, ctx: &TraversalContextStack) {}
/// Called when visiting a node representing a `super` expression.
- fn visit_super_expr(&mut self, n: &SuperExpressionNode, ctx: ExpressionTraversalContext) {}
+ fn visit_super_expr(&mut self, n: &SuperExpressionNode, ctx: &TraversalContextStack) {}
/// Called when visiting a node representing a `parent` expression.
- fn visit_parent_expr(&mut self, n: &ParentExpressionNode, ctx: ExpressionTraversalContext) {}
+ fn visit_parent_expr(&mut self, n: &ParentExpressionNode, ctx: &TraversalContextStack) {}
/// Called when visiting a node representing a `virtual_parent` expression.
- fn visit_virtual_parent_expr(&mut self, n: &VirtualParentExpressionNode, ctx: ExpressionTraversalContext) {}
+ fn visit_virtual_parent_expr(&mut self, n: &VirtualParentExpressionNode, ctx: &TraversalContextStack) {}
/// Called when visiting a node representing an identifier in code (not a keyword).
- fn visit_identifier_expr(&mut self, n: &IdentifierNode, ctx: ExpressionTraversalContext) {}
+ fn visit_identifier_expr(&mut self, n: &IdentifierNode, ctx: &TraversalContextStack) {}
/// Called when visiting a function call node.
- fn visit_func_call_expr(&mut self, n: &FunctionCallExpressionNode, ctx: ExpressionTraversalContext) -> FunctionCallExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_func_call_expr(&mut self, n: &FunctionCallExpressionNode, ctx: &TraversalContextStack) -> FunctionCallExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting function call expression node and possibly also children nodes specified in traversal policy.
- fn exit_func_call_expr(&mut self, n: &FunctionCallExpressionNode, ctx: ExpressionTraversalContext) {}
+ fn exit_func_call_expr(&mut self, n: &FunctionCallExpressionNode, ctx: &TraversalContextStack) {}
/// Called when visiting a function call argument.
/// Node may be None due to it referring to an optional function parameter.
- fn visit_func_call_arg(&mut self, n: &FunctionCallArgument) -> FunctionCallArgumentTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_func_call_arg(&mut self, n: &FunctionCallArgument, ctx: &TraversalContextStack) -> FunctionCallArgumentTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting function call argument and possibly also children nodes specified in traversal policy.
- fn exit_func_call_arg(&mut self, n: &FunctionCallArgument) {}
+ fn exit_func_call_arg(&mut self, n: &FunctionCallArgument, ctx: &TraversalContextStack) {}
/// Called when visiting an indexing expression.
- fn visit_array_expr(&mut self, n: &ArrayExpressionNode, ctx: ExpressionTraversalContext) -> ArrayExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_array_expr(&mut self, n: &ArrayExpressionNode, ctx: &TraversalContextStack) -> ArrayExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting an indexing expression and possibly also children nodes specified in traversal policy.
- fn exit_array_expr(&mut self, n: &ArrayExpressionNode, ctx: ExpressionTraversalContext) {}
+ fn exit_array_expr(&mut self, n: &ArrayExpressionNode, ctx: &TraversalContextStack) {}
/// Called when visiting an expression of accessing a field in an object.
- fn visit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, ctx: ExpressionTraversalContext) -> MemberFieldExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, ctx: &TraversalContextStack) -> MemberFieldExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting an expression of accessing a field in an object and possibly also children nodes specified in traversal policy.
- fn exit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, ctx: ExpressionTraversalContext) {}
+ fn exit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, ctx: &TraversalContextStack) {}
/// Called when visiting an instantiation expression.
- fn visit_new_expr(&mut self, n: &NewExpressionNode, ctx: ExpressionTraversalContext) -> NewExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_new_expr(&mut self, n: &NewExpressionNode, ctx: &TraversalContextStack) -> NewExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting an instantiation expression and possibly also children nodes specified in traversal policy.
- fn exit_new_expr(&mut self, n: &NewExpressionNode, ctx: ExpressionTraversalContext) {}
+ fn exit_new_expr(&mut self, n: &NewExpressionNode, ctx: &TraversalContextStack) {}
/// Called when visiting a type-casting expression.
- fn visit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, ctx: ExpressionTraversalContext) -> TypeCastExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, ctx: &TraversalContextStack) -> TypeCastExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting a type-casting expression and possibly also child node specified in traversal policy.
- fn exit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, ctx: ExpressionTraversalContext) {}
+ fn exit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, ctx: &TraversalContextStack) {}
/// Called when visiting an unary operation expression.
- fn visit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode, ctx: ExpressionTraversalContext) -> UnaryOperationExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode, ctx: &TraversalContextStack) -> UnaryOperationExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting an unary operation expression and possibly also children nodes specified in traversal policy.
- fn exit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode, ctx: ExpressionTraversalContext) {}
+ fn exit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode, ctx: &TraversalContextStack) {}
/// Called when visiting a binary operation expression.
- fn visit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, ctx: ExpressionTraversalContext) -> BinaryOperationExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, ctx: &TraversalContextStack) -> BinaryOperationExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting a binary operation expression and possibly also children nodes specified in traversal policy.
- fn exit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, ctx: ExpressionTraversalContext) {}
+ fn exit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, ctx: &TraversalContextStack) {}
/// Called when visiting an assignment operation expression.
- fn visit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode, ctx: ExpressionTraversalContext) -> AssignmentOperationExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode, ctx: &TraversalContextStack) -> AssignmentOperationExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting an assignment operation expression and possibly also children nodes specified in traversal policy.
- fn exit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode, ctx: ExpressionTraversalContext) {}
+ fn exit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode, ctx: &TraversalContextStack) {}
/// Called when visiting a ternary conditional expression (expr1 ? expr2 : expr3).
- fn visit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode, ctx: ExpressionTraversalContext) -> TernaryConditionalExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode, ctx: &TraversalContextStack) -> TernaryConditionalExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting a ternary conditional expression and possibly also children nodes specified in traversal policy.
- fn exit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode, ctx: ExpressionTraversalContext) {}
+ fn exit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode, ctx: &TraversalContextStack) {}
@@ -123,31 +123,31 @@ pub trait SyntaxNodeVisitor {
fn visit_global_var_decl(&mut self, n: &MemberVarDeclarationNode) {}
/// Called when visiting member variable (i.e. field) declaration.
- fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, ctx: DeclarationTraversalContext) {}
+ fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, ctx: &TraversalContextStack) {}
/// Called when visiting a statement assigning a default value to a field.
- fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode, ctx: DeclarationTraversalContext) -> MemberDefaultValueTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode, ctx: &TraversalContextStack) -> MemberDefaultValueTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting a statement assigning a default value to a field and possibly also children nodes specified in traversal policy.
- fn exit_member_default_val(&mut self, n: &MemberDefaultValueNode, ctx: DeclarationTraversalContext) {}
+ fn exit_member_default_val(&mut self, n: &MemberDefaultValueNode, ctx: &TraversalContextStack) {}
/// Called when visiting a `defaults` block.
- fn visit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode, ctx: DeclarationTraversalContext) -> MemberDefaultsBlockTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode, ctx: &TraversalContextStack) -> MemberDefaultsBlockTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visitng a `defaults` block and possibly also children nodes specified in traversal policy.
- fn exit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode, ctx: DeclarationTraversalContext) {}
+ fn exit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode, ctx: &TraversalContextStack) {}
/// Called when visiting a default value assignment inside a `defaults` block.
- fn visit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode) -> MemberDefaultValueTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode, ctx: &TraversalContextStack) -> MemberDefaultValueTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting a default value assignment inside a `defaults` block and possibly also children nodes specified in traversal policy.
- fn exit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode) {}
+ fn exit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode, ctx: &TraversalContextStack) {}
/// Called when visiting a statement noting some information about a perticular type field.
- fn visit_member_hint(&mut self, n: &MemberHintNode, ctx: DeclarationTraversalContext) {}
+ fn visit_member_hint(&mut self, n: &MemberHintNode, ctx: &TraversalContextStack) {}
/// Called when visiting an autobind variable declaration.
- fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, ctx: DeclarationTraversalContext) {}
+ fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, ctx: &TraversalContextStack) {}
/// Called when visiting a group of function parameters. This may mean a single parameter or multiple delimited names with common specifiers and a type.
- fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, ctx: FunctionTraversalContext) {}
+ fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, ctx: &TraversalContextStack) {}
/// Called when visiting a global function declaration.
fn visit_global_func_decl(&mut self, n: &FunctionDeclarationNode) -> FunctionDeclarationTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
@@ -155,85 +155,85 @@ pub trait SyntaxNodeVisitor {
fn exit_global_func_decl(&mut self, n: &FunctionDeclarationNode) {}
/// Called when visiting a member function declaration (i.e. a method).
- fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, ctx: DeclarationTraversalContext) -> FunctionDeclarationTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, ctx: &TraversalContextStack) -> FunctionDeclarationTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting member function declaration and possibly also children nodes specified in traversal policy.
- fn exit_member_func_decl(&mut self, n: &FunctionDeclarationNode, ctx: DeclarationTraversalContext) {}
+ fn exit_member_func_decl(&mut self, n: &FunctionDeclarationNode, ctx: &TraversalContextStack) {}
/// Called when visiting an event function declaration.
- fn visit_event_decl(&mut self, n: &EventDeclarationNode, ctx: DeclarationTraversalContext) -> EventDeclarationTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_event_decl(&mut self, n: &EventDeclarationNode, ctx: &TraversalContextStack) -> EventDeclarationTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting member function declaration and possibly also children nodes specified in traversal policy.
- fn exit_event_decl(&mut self, n: &EventDeclarationNode, ctx: DeclarationTraversalContext) {}
+ fn exit_event_decl(&mut self, n: &EventDeclarationNode, ctx: &TraversalContextStack) {}
/// Called when visiting a local variable declaration inside a function.
- fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, ctx: StatementTraversalContext) -> VarDeclarationTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, ctx: &TraversalContextStack) -> VarDeclarationTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting a local variable declaration and possibly also children nodes specified in traversal policy.
- fn exit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, ctx: StatementTraversalContext) {}
+ fn exit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, ctx: &TraversalContextStack) {}
/// Called when visiting an expression statement inside a function.
- fn visit_expr_stmt(&mut self, n: &ExpressionStatementNode, ctx: StatementTraversalContext) -> ExpressionStatementTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_expr_stmt(&mut self, n: &ExpressionStatementNode, ctx: &TraversalContextStack) -> ExpressionStatementTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting an expression statement and possibly also children nodes specified in traversal policy.
- fn exit_expr_stmt(&mut self, n: &ExpressionStatementNode, ctx: StatementTraversalContext) {}
+ fn exit_expr_stmt(&mut self, n: &ExpressionStatementNode, ctx: &TraversalContextStack) {}
/// Called when visiting a `for` loop.
- fn visit_for_stmt(&mut self, n: &ForLoopNode, ctx: StatementTraversalContext) -> ForLoopTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_for_stmt(&mut self, n: &ForLoopNode, ctx: &TraversalContextStack) -> ForLoopTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting a `for` loop and possibly also children nodes specified in traversal policy.
- fn exit_for_stmt(&mut self, n: &ForLoopNode, ctx: StatementTraversalContext) {}
+ fn exit_for_stmt(&mut self, n: &ForLoopNode, ctx: &TraversalContextStack) {}
/// Called when visiting a `while` loop.
- fn visit_while_stmt(&mut self, n: &WhileLoopNode, ctx: StatementTraversalContext) -> WhileLoopTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_while_stmt(&mut self, n: &WhileLoopNode, ctx: &TraversalContextStack) -> WhileLoopTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting a `while` loop and possibly also children nodes specified in traversal policy.
- fn exit_while_stmt(&mut self, n: &WhileLoopNode, ctx: StatementTraversalContext) {}
+ fn exit_while_stmt(&mut self, n: &WhileLoopNode, ctx: &TraversalContextStack) {}
/// Called when visiting a `do-while` loop.
- fn visit_do_while_stmt(&mut self, n: &DoWhileLoopNode, ctx: StatementTraversalContext) -> DoWhileLoopTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_do_while_stmt(&mut self, n: &DoWhileLoopNode, ctx: &TraversalContextStack) -> DoWhileLoopTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting a `do-while` loop and possibly also children nodes specified in traversal policy.
- fn exit_do_while_stmt(&mut self, n: &DoWhileLoopNode, ctx: StatementTraversalContext) {}
+ fn exit_do_while_stmt(&mut self, n: &DoWhileLoopNode, ctx: &TraversalContextStack) {}
/// Called when visiting an `if` condition.
- fn visit_if_stmt(&mut self, n: &IfConditionalNode, ctx: StatementTraversalContext) -> IfConditionalTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_if_stmt(&mut self, n: &IfConditionalNode, ctx: &TraversalContextStack) -> IfConditionalTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting an `if` condition and possibly also children nodes specified in traversal policy.
- fn exit_if_stmt(&mut self, n: &IfConditionalNode, ctx: StatementTraversalContext) {}
+ fn exit_if_stmt(&mut self, n: &IfConditionalNode, ctx: &TraversalContextStack) {}
/// Called when visiting a `switch` statement.
- fn visit_switch_stmt(&mut self, n: &SwitchConditionalNode, ctx: StatementTraversalContext) -> SwitchConditionalTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_switch_stmt(&mut self, n: &SwitchConditionalNode, ctx: &TraversalContextStack) -> SwitchConditionalTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting a `switch` statement and possibly also children nodes specified in traversal policy.
- fn exit_switch_stmt(&mut self, n: &SwitchConditionalNode, ctx: StatementTraversalContext) {}
+ fn exit_switch_stmt(&mut self, n: &SwitchConditionalNode, ctx: &TraversalContextStack) {}
/// Called when visiting a `case` label inside a `switch` statement.
- fn visit_switch_stmt_case(&mut self, n: &SwitchConditionalCaseLabelNode) -> SwitchConditionalCaseLabelTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_switch_stmt_case(&mut self, n: &SwitchConditionalCaseLabelNode, ctx: &TraversalContextStack) -> SwitchConditionalCaseLabelTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting a `case` label inside a `switch` statement and possibly also children nodes specified in traversal policy.
- fn exit_switch_stmt_case(&mut self, n: &SwitchConditionalCaseLabelNode) {}
+ fn exit_switch_stmt_case(&mut self, n: &SwitchConditionalCaseLabelNode, ctx: &TraversalContextStack) {}
/// Called when visiting a `default` label inside a `switch` statement.
- fn visit_switch_stmt_default(&mut self, n: &SwitchConditionalDefaultLabelNode) {}
+ fn visit_switch_stmt_default(&mut self, n: &SwitchConditionalDefaultLabelNode, ctx: &TraversalContextStack) {}
/// Called when visiting a `break` statement.
- fn visit_break_stmt(&mut self, n: &BreakStatementNode, ctx: StatementTraversalContext) {}
+ fn visit_break_stmt(&mut self, n: &BreakStatementNode, ctx: &TraversalContextStack) {}
/// Called when visiting a `continue` statement.
- fn visit_continue_stmt(&mut self, n: &ContinueStatementNode, ctx: StatementTraversalContext) {}
+ fn visit_continue_stmt(&mut self, n: &ContinueStatementNode, ctx: &TraversalContextStack) {}
/// Called when visiting a `return` statement.
- fn visit_return_stmt(&mut self, n: &ReturnStatementNode, ctx: StatementTraversalContext) -> ReturnStatementTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_return_stmt(&mut self, n: &ReturnStatementNode, ctx: &TraversalContextStack) -> ReturnStatementTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting a `return` statement and possibly also children nodes specified in traversal policy.
- fn exit_return_stmt(&mut self, n: &ReturnStatementNode, ctx: StatementTraversalContext) {}
+ fn exit_return_stmt(&mut self, n: &ReturnStatementNode, ctx: &TraversalContextStack) {}
/// Called when visiting a `delete` statement.
- fn visit_delete_stmt(&mut self, n: &DeleteStatementNode, ctx: StatementTraversalContext) -> DeleteStatementTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_delete_stmt(&mut self, n: &DeleteStatementNode, ctx: &TraversalContextStack) -> DeleteStatementTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting a `delete` statement and possibly also children nodes specified in traversal policy.
- fn exit_delete_stmt(&mut self, n: &DeleteStatementNode, ctx: StatementTraversalContext) {}
+ fn exit_delete_stmt(&mut self, n: &DeleteStatementNode, ctx: &TraversalContextStack) {}
/// Called when visiting a scope block statement in a function.
- fn visit_compound_stmt(&mut self, n: &CompoundStatementNode, ctx: StatementTraversalContext) -> CompoundStatementTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
+ fn visit_compound_stmt(&mut self, n: &CompoundStatementNode, ctx: &TraversalContextStack) -> CompoundStatementTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting a scope block statement in a function and possibly also children nodes specified in traversal policy.
- fn exit_compound_stmt(&mut self, n: &CompoundStatementNode, ctx: StatementTraversalContext) {}
+ fn exit_compound_stmt(&mut self, n: &CompoundStatementNode, ctx: &TraversalContextStack) {}
/// Called when visiting a NOP statement.
/// It most notably means:
/// 1. A trailing "orphan" semicolon somewhere in code
/// 2. Indicating absence of action, e.g. `while(!AreWeThereYet());`
- fn visit_nop_stmt(&mut self, n: &NopNode, ctx: StatementTraversalContext) {}
+ fn visit_nop_stmt(&mut self, n: &NopNode, ctx: &TraversalContextStack) {}
}
diff --git a/crates/core/src/ast/traversal/visitor_chain.rs b/crates/core/src/ast/traversal/visitor_chain.rs
index e8f2cafa..d554b9bd 100644
--- a/crates/core/src/ast/traversal/visitor_chain.rs
+++ b/crates/core/src/ast/traversal/visitor_chain.rs
@@ -146,279 +146,279 @@ impl<'a> SyntaxNodeVisitor for SyntaxNodeVisitorChain<'a> {
- fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, ctx: DeclarationTraversalContext) -> FunctionDeclarationTraversalPolicy {
+ fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, ctx: &TraversalContextStack) -> FunctionDeclarationTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_member_func_decl(n, ctx))
}
- fn exit_member_func_decl(&mut self, n: &FunctionDeclarationNode, ctx: DeclarationTraversalContext) {
+ fn exit_member_func_decl(&mut self, n: &FunctionDeclarationNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_member_func_decl(n, ctx))
}
- fn visit_event_decl(&mut self, n: &EventDeclarationNode, ctx: DeclarationTraversalContext) -> EventDeclarationTraversalPolicy {
+ fn visit_event_decl(&mut self, n: &EventDeclarationNode, ctx: &TraversalContextStack) -> EventDeclarationTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_event_decl(n, ctx))
}
- fn exit_event_decl(&mut self, n: &EventDeclarationNode, ctx: DeclarationTraversalContext) {
+ fn exit_event_decl(&mut self, n: &EventDeclarationNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_event_decl(n, ctx))
}
- fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, ctx: FunctionTraversalContext) {
+ fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, ctx: &TraversalContextStack) {
self.chain_visit(move |link| link.visit_func_param_group(n, ctx))
}
- fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, ctx: DeclarationTraversalContext) {
+ fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, ctx: &TraversalContextStack) {
self.chain_visit(move |link| link.visit_member_var_decl(n, ctx))
}
- fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, ctx: DeclarationTraversalContext) {
+ fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, ctx: &TraversalContextStack) {
self.chain_visit(move |link| link.visit_autobind_decl(n, ctx))
}
- fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode, ctx: DeclarationTraversalContext) -> MemberDefaultValueTraversalPolicy {
+ fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode, ctx: &TraversalContextStack) -> MemberDefaultValueTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_member_default_val(n, ctx))
}
- fn exit_member_default_val(&mut self, n: &MemberDefaultValueNode, ctx: DeclarationTraversalContext) {
+ fn exit_member_default_val(&mut self, n: &MemberDefaultValueNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_member_default_val(n, ctx))
}
- fn visit_member_hint(&mut self, n: &MemberHintNode, ctx: DeclarationTraversalContext) {
+ fn visit_member_hint(&mut self, n: &MemberHintNode, ctx: &TraversalContextStack) {
self.chain_visit(move |link| link.visit_member_hint(n, ctx))
}
- fn visit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode, ctx: DeclarationTraversalContext) -> MemberDefaultsBlockTraversalPolicy {
+ fn visit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode, ctx: &TraversalContextStack) -> MemberDefaultsBlockTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_member_defaults_block(n, ctx))
}
- fn exit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode, ctx: DeclarationTraversalContext) {
+ fn exit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_member_defaults_block(n, ctx))
}
- fn visit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode) -> MemberDefaultValueTraversalPolicy {
- self.chain_visit_traversable(move |link| link.visit_member_defaults_block_assignment(n))
+ fn visit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode, ctx: &TraversalContextStack) -> MemberDefaultValueTraversalPolicy {
+ self.chain_visit_traversable(move |link| link.visit_member_defaults_block_assignment(n, ctx))
}
- fn exit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode) {
- self.chain_exit(move |link| link.exit_member_defaults_block_assignment(n))
+ fn exit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode, ctx: &TraversalContextStack) {
+ self.chain_exit(move |link| link.exit_member_defaults_block_assignment(n, ctx))
}
- fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, ctx: StatementTraversalContext) -> VarDeclarationTraversalPolicy {
+ fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, ctx: &TraversalContextStack) -> VarDeclarationTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_local_var_decl_stmt(n, ctx))
}
- fn exit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, ctx: StatementTraversalContext) {
+ fn exit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_local_var_decl_stmt(n, ctx))
}
- fn visit_compound_stmt(&mut self, n: &CompoundStatementNode, ctx: StatementTraversalContext) -> CompoundStatementTraversalPolicy {
+ fn visit_compound_stmt(&mut self, n: &CompoundStatementNode, ctx: &TraversalContextStack) -> CompoundStatementTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_compound_stmt(n, ctx))
}
- fn exit_compound_stmt(&mut self, n: &CompoundStatementNode, ctx: StatementTraversalContext) {
+ fn exit_compound_stmt(&mut self, n: &CompoundStatementNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_compound_stmt(n, ctx))
}
- fn visit_while_stmt(&mut self, n: &WhileLoopNode, ctx: StatementTraversalContext) -> WhileLoopTraversalPolicy {
+ fn visit_while_stmt(&mut self, n: &WhileLoopNode, ctx: &TraversalContextStack) -> WhileLoopTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_while_stmt(n, ctx))
}
- fn exit_while_stmt(&mut self, n: &WhileLoopNode, ctx: StatementTraversalContext) {
+ fn exit_while_stmt(&mut self, n: &WhileLoopNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_while_stmt(n, ctx))
}
- fn visit_do_while_stmt(&mut self, n: &DoWhileLoopNode, ctx: StatementTraversalContext) -> DoWhileLoopTraversalPolicy {
+ fn visit_do_while_stmt(&mut self, n: &DoWhileLoopNode, ctx: &TraversalContextStack) -> DoWhileLoopTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_do_while_stmt(n, ctx))
}
- fn exit_do_while_stmt(&mut self, n: &DoWhileLoopNode, ctx: StatementTraversalContext) {
+ fn exit_do_while_stmt(&mut self, n: &DoWhileLoopNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_do_while_stmt(n, ctx))
}
- fn visit_for_stmt(&mut self, n: &ForLoopNode, ctx: StatementTraversalContext) -> ForLoopTraversalPolicy {
+ fn visit_for_stmt(&mut self, n: &ForLoopNode, ctx: &TraversalContextStack) -> ForLoopTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_for_stmt(n, ctx))
}
- fn exit_for_stmt(&mut self, n: &ForLoopNode, ctx: StatementTraversalContext) {
+ fn exit_for_stmt(&mut self, n: &ForLoopNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_for_stmt(n, ctx))
}
- fn visit_if_stmt(&mut self, n: &IfConditionalNode, ctx: StatementTraversalContext) -> IfConditionalTraversalPolicy {
+ fn visit_if_stmt(&mut self, n: &IfConditionalNode, ctx: &TraversalContextStack) -> IfConditionalTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_if_stmt(n, ctx))
}
- fn exit_if_stmt(&mut self, n: &IfConditionalNode, ctx: StatementTraversalContext) {
+ fn exit_if_stmt(&mut self, n: &IfConditionalNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_if_stmt(n, ctx))
}
- fn visit_switch_stmt(&mut self, n: &SwitchConditionalNode, ctx: StatementTraversalContext) -> SwitchConditionalTraversalPolicy {
+ fn visit_switch_stmt(&mut self, n: &SwitchConditionalNode, ctx: &TraversalContextStack) -> SwitchConditionalTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_switch_stmt(n, ctx))
}
- fn exit_switch_stmt(&mut self, n: &SwitchConditionalNode, ctx: StatementTraversalContext) {
+ fn exit_switch_stmt(&mut self, n: &SwitchConditionalNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_switch_stmt(n, ctx))
}
- fn visit_switch_stmt_case(&mut self, n: &SwitchConditionalCaseLabelNode) -> SwitchConditionalCaseLabelTraversalPolicy {
- self.chain_visit_traversable(move |link| link.visit_switch_stmt_case(n))
+ fn visit_switch_stmt_case(&mut self, n: &SwitchConditionalCaseLabelNode, ctx: &TraversalContextStack) -> SwitchConditionalCaseLabelTraversalPolicy {
+ self.chain_visit_traversable(move |link| link.visit_switch_stmt_case(n, ctx))
}
- fn exit_switch_stmt_case(&mut self, n: &SwitchConditionalCaseLabelNode) {
- self.chain_exit(move |link| link.exit_switch_stmt_case(n))
+ fn exit_switch_stmt_case(&mut self, n: &SwitchConditionalCaseLabelNode, ctx: &TraversalContextStack) {
+ self.chain_exit(move |link| link.exit_switch_stmt_case(n, ctx))
}
- fn visit_switch_stmt_default(&mut self, n: &SwitchConditionalDefaultLabelNode) {
- self.chain_visit(move |link| link.visit_switch_stmt_default(n))
+ fn visit_switch_stmt_default(&mut self, n: &SwitchConditionalDefaultLabelNode, ctx: &TraversalContextStack) {
+ self.chain_visit(move |link| link.visit_switch_stmt_default(n, ctx))
}
- fn visit_expr_stmt(&mut self, n: &ExpressionStatementNode, ctx: StatementTraversalContext) -> ExpressionStatementTraversalPolicy {
+ fn visit_expr_stmt(&mut self, n: &ExpressionStatementNode, ctx: &TraversalContextStack) -> ExpressionStatementTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_expr_stmt(n, ctx))
}
- fn exit_expr_stmt(&mut self, n: &ExpressionStatementNode, ctx: StatementTraversalContext) {
+ fn exit_expr_stmt(&mut self, n: &ExpressionStatementNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_expr_stmt(n, ctx))
}
- fn visit_return_stmt(&mut self, n: &ReturnStatementNode, ctx: StatementTraversalContext) -> ReturnStatementTraversalPolicy {
+ fn visit_return_stmt(&mut self, n: &ReturnStatementNode, ctx: &TraversalContextStack) -> ReturnStatementTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_return_stmt(n, ctx))
}
- fn exit_return_stmt(&mut self, n: &ReturnStatementNode, ctx: StatementTraversalContext) {
+ fn exit_return_stmt(&mut self, n: &ReturnStatementNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_return_stmt(n, ctx))
}
- fn visit_delete_stmt(&mut self, n: &DeleteStatementNode, ctx: StatementTraversalContext) -> DeleteStatementTraversalPolicy {
+ fn visit_delete_stmt(&mut self, n: &DeleteStatementNode, ctx: &TraversalContextStack) -> DeleteStatementTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_delete_stmt(n, ctx))
}
- fn exit_delete_stmt(&mut self, n: &DeleteStatementNode, ctx: StatementTraversalContext) {
+ fn exit_delete_stmt(&mut self, n: &DeleteStatementNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_delete_stmt(n, ctx))
}
- fn visit_break_stmt(&mut self, n: &BreakStatementNode, ctx: StatementTraversalContext) {
+ fn visit_break_stmt(&mut self, n: &BreakStatementNode, ctx: &TraversalContextStack) {
self.chain_visit(move |link| link.visit_break_stmt(n, ctx))
}
- fn visit_continue_stmt(&mut self, n: &ContinueStatementNode, ctx: StatementTraversalContext) {
+ fn visit_continue_stmt(&mut self, n: &ContinueStatementNode, ctx: &TraversalContextStack) {
self.chain_visit(move |link| link.visit_continue_stmt(n, ctx))
}
- fn visit_nop_stmt(&mut self, n: &NopNode, ctx: StatementTraversalContext) {
+ fn visit_nop_stmt(&mut self, n: &NopNode, ctx: &TraversalContextStack) {
self.chain_visit(move |link| link.visit_nop_stmt(n, ctx))
}
- fn visit_nested_expr(&mut self, n: &NestedExpressionNode, ctx: ExpressionTraversalContext) -> NestedExpressionTraversalPolicy {
+ fn visit_nested_expr(&mut self, n: &NestedExpressionNode, ctx: &TraversalContextStack) -> NestedExpressionTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_nested_expr(n, ctx))
}
- fn exit_nested_expr(&mut self, n: &NestedExpressionNode, ctx: ExpressionTraversalContext) {
+ fn exit_nested_expr(&mut self, n: &NestedExpressionNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_nested_expr(n, ctx))
}
- fn visit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode, ctx: ExpressionTraversalContext) -> AssignmentOperationExpressionTraversalPolicy {
+ fn visit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode, ctx: &TraversalContextStack) -> AssignmentOperationExpressionTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_assign_op_expr(n, ctx))
}
- fn exit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode, ctx: ExpressionTraversalContext) {
+ fn exit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_assign_op_expr(n, ctx))
}
- fn visit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, ctx: ExpressionTraversalContext) -> BinaryOperationExpressionTraversalPolicy {
+ fn visit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, ctx: &TraversalContextStack) -> BinaryOperationExpressionTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_binary_op_expr(n, ctx))
}
- fn exit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, ctx: ExpressionTraversalContext) {
+ fn exit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_binary_op_expr(n, ctx))
}
- fn visit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode, ctx: ExpressionTraversalContext) -> UnaryOperationExpressionTraversalPolicy {
+ fn visit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode, ctx: &TraversalContextStack) -> UnaryOperationExpressionTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_unary_op_expr(n, ctx))
}
- fn exit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode, ctx: ExpressionTraversalContext) {
+ fn exit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_unary_op_expr(n, ctx))
}
- fn visit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, ctx: ExpressionTraversalContext) -> MemberFieldExpressionTraversalPolicy {
+ fn visit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, ctx: &TraversalContextStack) -> MemberFieldExpressionTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_member_access_expr(n, ctx))
}
- fn exit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, ctx: ExpressionTraversalContext) {
+ fn exit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_member_access_expr(n, ctx))
}
- fn visit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, ctx: ExpressionTraversalContext) -> TypeCastExpressionTraversalPolicy {
+ fn visit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, ctx: &TraversalContextStack) -> TypeCastExpressionTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_type_cast_expr(n, ctx))
}
- fn exit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, ctx: ExpressionTraversalContext) {
+ fn exit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_type_cast_expr(n, ctx))
}
- fn visit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode, ctx: ExpressionTraversalContext) -> TernaryConditionalExpressionTraversalPolicy {
+ fn visit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode, ctx: &TraversalContextStack) -> TernaryConditionalExpressionTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_ternary_cond_expr(n, ctx))
}
- fn exit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode, ctx: ExpressionTraversalContext) {
+ fn exit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_ternary_cond_expr(n, ctx))
}
- fn visit_new_expr(&mut self, n: &NewExpressionNode, ctx: ExpressionTraversalContext) -> NewExpressionTraversalPolicy {
+ fn visit_new_expr(&mut self, n: &NewExpressionNode, ctx: &TraversalContextStack) -> NewExpressionTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_new_expr(n, ctx))
}
- fn exit_new_expr(&mut self, n: &NewExpressionNode, ctx: ExpressionTraversalContext) {
+ fn exit_new_expr(&mut self, n: &NewExpressionNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_new_expr(n, ctx))
}
- fn visit_array_expr(&mut self, n: &ArrayExpressionNode, ctx: ExpressionTraversalContext) -> ArrayExpressionTraversalPolicy {
+ fn visit_array_expr(&mut self, n: &ArrayExpressionNode, ctx: &TraversalContextStack) -> ArrayExpressionTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_array_expr(n, ctx))
}
- fn exit_array_expr(&mut self, n: &ArrayExpressionNode, ctx: ExpressionTraversalContext) {
+ fn exit_array_expr(&mut self, n: &ArrayExpressionNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_array_expr(n, ctx))
}
- fn visit_func_call_expr(&mut self, n: &FunctionCallExpressionNode, ctx: ExpressionTraversalContext) -> FunctionCallExpressionTraversalPolicy {
+ fn visit_func_call_expr(&mut self, n: &FunctionCallExpressionNode, ctx: &TraversalContextStack) -> FunctionCallExpressionTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_func_call_expr(n, ctx))
}
- fn exit_func_call_expr(&mut self, n: &FunctionCallExpressionNode, ctx: ExpressionTraversalContext) {
+ fn exit_func_call_expr(&mut self, n: &FunctionCallExpressionNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_func_call_expr(n, ctx))
}
- fn visit_func_call_arg(&mut self, n: &FunctionCallArgument) -> FunctionCallArgumentTraversalPolicy {
- self.chain_visit_traversable(move |link| link.visit_func_call_arg(n))
+ fn visit_func_call_arg(&mut self, n: &FunctionCallArgument, ctx: &TraversalContextStack) -> FunctionCallArgumentTraversalPolicy {
+ self.chain_visit_traversable(move |link| link.visit_func_call_arg(n, ctx))
}
- fn exit_func_call_arg(&mut self, n: &FunctionCallArgument) {
- self.chain_exit(move |link| link.exit_func_call_arg(n))
+ fn exit_func_call_arg(&mut self, n: &FunctionCallArgument, ctx: &TraversalContextStack) {
+ self.chain_exit(move |link| link.exit_func_call_arg(n, ctx))
}
- fn visit_identifier_expr(&mut self, n: &IdentifierNode, ctx: ExpressionTraversalContext) {
+ fn visit_identifier_expr(&mut self, n: &IdentifierNode, ctx: &TraversalContextStack) {
self.chain_visit(move |link| link.visit_identifier_expr(n, ctx))
}
- fn visit_literal_expr(&mut self, n: &LiteralNode, ctx: ExpressionTraversalContext) {
+ fn visit_literal_expr(&mut self, n: &LiteralNode, ctx: &TraversalContextStack) {
self.chain_visit(move |link| link.visit_literal_expr(n, ctx))
}
- fn visit_this_expr(&mut self, n: &ThisExpressionNode, ctx: ExpressionTraversalContext) {
+ fn visit_this_expr(&mut self, n: &ThisExpressionNode, ctx: &TraversalContextStack) {
self.chain_visit(move |link| link.visit_this_expr(n, ctx))
}
- fn visit_super_expr(&mut self, n: &SuperExpressionNode, ctx: ExpressionTraversalContext) {
+ fn visit_super_expr(&mut self, n: &SuperExpressionNode, ctx: &TraversalContextStack) {
self.chain_visit(move |link| link.visit_super_expr(n, ctx))
}
- fn visit_parent_expr(&mut self, n: &ParentExpressionNode, ctx: ExpressionTraversalContext) {
+ fn visit_parent_expr(&mut self, n: &ParentExpressionNode, ctx: &TraversalContextStack) {
self.chain_visit(move |link| link.visit_parent_expr(n, ctx))
}
- fn visit_virtual_parent_expr(&mut self, n: &VirtualParentExpressionNode, ctx: ExpressionTraversalContext) {
+ fn visit_virtual_parent_expr(&mut self, n: &VirtualParentExpressionNode, ctx: &TraversalContextStack) {
self.chain_visit(move |link| link.visit_virtual_parent_expr(n, ctx))
}
}
\ No newline at end of file
diff --git a/crates/core/src/ast/vars.rs b/crates/core/src/ast/vars.rs
index c4f4a518..8733bcc1 100644
--- a/crates/core/src/ast/vars.rs
+++ b/crates/core/src/ast/vars.rs
@@ -92,12 +92,12 @@ impl<'script> TryFrom> for LocalVarDeclarationNode<'script> {
}
impl SyntaxNodeTraversal for LocalVarDeclarationNode<'_> {
- type TraversalCtx = StatementTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_local_var_decl_stmt(self, ctx);
if tp.traverse_init_value {
- self.init_value().map(|init_value| init_value.accept(visitor, ExpressionTraversalContext::LocalVarDeclarationInitValue));
+ ctx.push(TraversalContext::LocalVarDeclarationInitValue);
+ self.init_value().map(|init_value| init_value.accept(visitor, ctx));
+ ctx.pop();
}
visitor.exit_local_var_decl_stmt(self, ctx);
}
@@ -153,10 +153,8 @@ impl<'script> TryFrom> for MemberVarDeclarationNode<'script> {
}
impl SyntaxNodeTraversal for MemberVarDeclarationNode<'_> {
- type TraversalCtx = DeclarationTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
- if ctx == DeclarationTraversalContext::Global {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
+ if ctx.top() == TraversalContext::Global {
visitor.visit_global_var_decl(self);
} else {
visitor.visit_member_var_decl(self, ctx);
diff --git a/crates/core/src/script.rs b/crates/core/src/script.rs
index 0eefc93b..55d668d6 100644
--- a/crates/core/src/script.rs
+++ b/crates/core/src/script.rs
@@ -2,7 +2,7 @@ use std::io;
use ropey::Rope;
use thiserror::Error;
use tree_sitter::{Parser, Tree, LanguageError};
-use crate::{ast::{RootNode, SyntaxNodeTraversal, SyntaxNodeVisitor}, script_document::ScriptDocument};
+use crate::{ast::{RootNode, SyntaxNodeTraversal, SyntaxNodeVisitor, TraversalContextStack}, script_document::ScriptDocument};
#[derive(Debug, Clone)]
@@ -80,6 +80,7 @@ impl Script {
}
pub fn visit_nodes(&self, visitor: &mut V) {
- self.root_node().accept(visitor, ());
+ let mut ctx = TraversalContextStack::new();
+ self.root_node().accept(visitor, &mut ctx);
}
}
\ No newline at end of file
diff --git a/crates/core/src/tokens/identifier.rs b/crates/core/src/tokens/identifier.rs
index 06012bf9..7c3c3f16 100644
--- a/crates/core/src/tokens/identifier.rs
+++ b/crates/core/src/tokens/identifier.rs
@@ -2,7 +2,7 @@ use std::borrow::Cow;
use std::fmt::Debug;
use shrinkwraprs::Shrinkwrap;
use crate::{script_document::ScriptDocument, AnyNode, DebugRange, NamedSyntaxNode, SyntaxNode};
-use crate::ast::{SyntaxNodeTraversal, ExpressionTraversalContext, SyntaxNodeVisitor};
+use crate::ast::{SyntaxNodeTraversal, TraversalContextStack, SyntaxNodeVisitor};
#[derive(Shrinkwrap, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
@@ -43,9 +43,7 @@ impl Debug for IdentifierNode<'_> {
}
impl SyntaxNodeTraversal for IdentifierNode<'_> {
- type TraversalCtx = ExpressionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
visitor.visit_identifier_expr(self, ctx);
}
}
diff --git a/crates/core/src/tokens/literals.rs b/crates/core/src/tokens/literals.rs
index babc2e52..50762be0 100644
--- a/crates/core/src/tokens/literals.rs
+++ b/crates/core/src/tokens/literals.rs
@@ -5,7 +5,7 @@ use shrinkwraprs::Shrinkwrap;
use thiserror::Error;
use crate::MISSING_TEXT;
use crate::{AnyNode, NamedSyntaxNode, SyntaxNode, DebugMaybeAlternate, DebugRange, script_document::ScriptDocument};
-use crate::ast::{SyntaxNodeTraversal, SyntaxNodeVisitor, ExpressionTraversalContext};
+use crate::ast::{SyntaxNodeTraversal, SyntaxNodeVisitor, TraversalContextStack};
#[derive(Debug, Clone, Error)]
@@ -377,9 +377,7 @@ impl<'script> TryFrom> for LiteralNode<'script> {
}
impl SyntaxNodeTraversal for LiteralNode<'_> {
- type TraversalCtx = ExpressionTraversalContext;
-
- fn accept(&self, visitor: &mut V, ctx: Self::TraversalCtx) {
+ fn accept(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
visitor.visit_literal_expr(self, ctx);
}
}
\ No newline at end of file
diff --git a/crates/diagnostics/src/lib.rs b/crates/diagnostics/src/lib.rs
index 2f5afcd4..7c47769e 100644
--- a/crates/diagnostics/src/lib.rs
+++ b/crates/diagnostics/src/lib.rs
@@ -91,6 +91,7 @@ pub enum DiagnosticKind {
expected_text: String
},
GlobalScopeVarDecl,
+ InvalidLocalVarPlacement,
// symbol anaysis
SymbolNameTaken {
@@ -143,7 +144,8 @@ impl DiagnosticKind {
| InvalidAnnotationPlacement
| MissingAnnotationArgument { .. }
| IncompatibleAnnotation { .. }
- | GlobalScopeVarDecl => DiagnosticDomain::ContextualSyntaxAnalysis,
+ | GlobalScopeVarDecl
+ | InvalidLocalVarPlacement => DiagnosticDomain::ContextualSyntaxAnalysis,
SymbolNameTaken { .. }
| MissingTypeArg
| UnnecessaryTypeArg
@@ -178,6 +180,7 @@ impl DiagnosticKind {
MissingAnnotationArgument { .. } => lsp::DiagnosticSeverity::ERROR,
IncompatibleAnnotation { .. } => lsp::DiagnosticSeverity::ERROR,
GlobalScopeVarDecl => lsp::DiagnosticSeverity::ERROR,
+ InvalidLocalVarPlacement => lsp::DiagnosticSeverity::ERROR,
SymbolNameTaken { .. } => lsp::DiagnosticSeverity::ERROR,
MissingTypeArg => lsp::DiagnosticSeverity::ERROR,
@@ -213,6 +216,7 @@ impl DiagnosticKind {
MissingAnnotationArgument { missing } => format!("This annotation requires {missing} argument"),
IncompatibleAnnotation { annotation_name, expected_text } => format!("{} may only be used for {}", annotation_name, expected_text),
GlobalScopeVarDecl => "Syntax error: variable declarations in the global scope are not allowed unless you intend to use the @addField annotation.".into(),
+ InvalidLocalVarPlacement => "Local variables can only be declared at the start of the function before all other statements".into(),
SymbolNameTaken { name, .. } => format!("The name \"{}\" is defined multiple times", name),
MissingTypeArg => "Missing type argument".into(),
diff --git a/crates/lsp/Cargo.toml b/crates/lsp/Cargo.toml
index 7180d02c..e3b52e08 100644
--- a/crates/lsp/Cargo.toml
+++ b/crates/lsp/Cargo.toml
@@ -14,10 +14,11 @@ abs-path = { path = "../abs-path" }
dashmap.workspace = true
serde.workspace = true
serde_json.workspace = true
+serde_repr.workspace = true
thiserror.workspace = true
rayon.workspace = true
bitmask-enum.workspace = true
shrinkwraprs.workspace = true
filetime.workspace = true
tower-lsp = "0.20.0"
-tokio = { version = "1", features = ["macros", "rt", "rt-multi-thread", "io-std", "time"] }
\ No newline at end of file
+tokio = { version = "1.38", features = ["macros", "rt", "rt-multi-thread", "io-std", "time"] }
\ No newline at end of file
diff --git a/crates/lsp/src/main.rs b/crates/lsp/src/main.rs
index 3d8437de..7a8a226b 100644
--- a/crates/lsp/src/main.rs
+++ b/crates/lsp/src/main.rs
@@ -13,6 +13,7 @@ mod reporting;
mod tasks;
mod requests;
mod notifications;
+mod model;
#[tower_lsp::async_trait]
@@ -106,6 +107,8 @@ async fn main() {
.custom_method(requests::projects::create::METHOD, Backend::create_project)
.custom_method(requests::projects::list::METHOD, Backend::project_list)
.custom_method(requests::projects::vanilla_dependency_content::METHOD, Backend::vanilla_dependency_content)
+ .custom_method(requests::projects::vanilla_content::METHOD, Backend::vanilla_content)
+ .custom_method(requests::projects::source_tree::METHOD, Backend::source_tree)
.custom_method(requests::scripts::parent_content::METHOD, Backend::parent_content)
.custom_method(requests::debug::script_ast::METHOD, Backend::script_ast)
.custom_method(requests::debug::script_cst::METHOD, Backend::script_cst)
diff --git a/crates/lsp/src/model.rs b/crates/lsp/src/model.rs
new file mode 100644
index 00000000..30734299
--- /dev/null
+++ b/crates/lsp/src/model.rs
@@ -0,0 +1,57 @@
+//! Common types for communication between the server and client
+
+use serde::{Deserialize, Serialize};
+use serde_repr::{Deserialize_repr, Serialize_repr};
+use tower_lsp::lsp_types as lsp;
+use witcherscript_project::{content_graph::GraphNode, content::*};
+
+
+#[derive(Debug, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct ContentInfo {
+ pub content_uri: lsp::Url,
+ pub content_kind: ContentKind,
+ pub content_name: String,
+ pub scripts_root_uri: lsp::Url,
+ pub is_in_workspace: bool,
+ pub is_in_repository: bool,
+ pub is_native: bool
+}
+
+impl From<&GraphNode> for ContentInfo {
+ fn from(n: &GraphNode) -> Self {
+ Self {
+ content_uri: n.content.path().to_uri(),
+ content_kind: n.content.as_ref().into(),
+ content_name: n.content.content_name().to_string(),
+ scripts_root_uri: n.content.source_tree_root().to_uri(),
+ is_in_workspace: n.in_workspace,
+ is_in_repository: n.in_repository,
+ is_native: n.is_native
+ }
+ }
+}
+
+#[derive(Debug, Serialize_repr, Deserialize_repr)]
+#[repr(i32)]
+pub enum ContentKind {
+ Raw = 0,
+ WideProject = 1,
+ RedkitProject = 2
+}
+
+impl From<&dyn Content> for ContentKind {
+ fn from(value: &dyn Content) -> Self {
+ let any = value.as_any();
+
+ if any.is::() {
+ ContentKind::WideProject
+ }
+ else if any.is::() {
+ ContentKind::RedkitProject
+ }
+ else {
+ ContentKind::Raw
+ }
+ }
+}
\ No newline at end of file
diff --git a/crates/lsp/src/notifications.rs b/crates/lsp/src/notifications.rs
index a7e02c93..5b4a67f2 100644
--- a/crates/lsp/src/notifications.rs
+++ b/crates/lsp/src/notifications.rs
@@ -36,4 +36,73 @@ pub mod projects {
pub const METHOD: &'static str = "witcherscript-ide/projects/didImportScripts";
}
+
+ // Sent after making changes to the content graph and performing tasks associated with that
+ pub mod did_change_content_graph {
+ use super::*;
+
+ pub const METHOD: &'static str = "witcherscript-ide/projects/didChangeContentGraph";
+
+ pub struct Type;
+ impl lsp::notification::Notification for Type {
+ type Params = ();
+
+ const METHOD: &'static str = METHOD;
+ }
+ }
+}
+
+pub mod scripts {
+ use super::*;
+
+ pub mod did_finish_initial_indexing {
+ use super::*;
+
+ pub const METHOD: &'static str = "witcherscript-ide/scripts/didFinishInitialIndexing";
+
+ pub struct Type;
+ impl lsp::notification::Notification for Type {
+ type Params = ();
+
+ const METHOD: &'static str = METHOD;
+ }
+ }
+
+ pub mod did_start_script_parsing {
+ use super::*;
+
+ #[derive(Debug, Serialize, Deserialize)]
+ #[serde(rename_all = "camelCase")]
+ pub struct Parameters {
+ pub content_name: String,
+ }
+
+ pub const METHOD: &'static str = "witcherscript-ide/scripts/didStartScriptParsing";
+
+ pub struct Type;
+ impl lsp::notification::Notification for Type {
+ type Params = Parameters;
+
+ const METHOD: &'static str = METHOD;
+ }
+ }
+
+ pub mod did_finish_script_parsing {
+ use super::*;
+
+ #[derive(Debug, Serialize, Deserialize)]
+ #[serde(rename_all = "camelCase")]
+ pub struct Parameters {
+ pub content_name: String,
+ }
+
+ pub const METHOD: &'static str = "witcherscript-ide/scripts/didFinishScriptParsing";
+
+ pub struct Type;
+ impl lsp::notification::Notification for Type {
+ type Params = Parameters;
+
+ const METHOD: &'static str = METHOD;
+ }
+ }
}
\ No newline at end of file
diff --git a/crates/lsp/src/providers/common.rs b/crates/lsp/src/providers/common.rs
index 698a49ac..4ae86186 100644
--- a/crates/lsp/src/providers/common.rs
+++ b/crates/lsp/src/providers/common.rs
@@ -177,7 +177,7 @@ impl<'a> TextDocumentPositionResolver<'a> {
});
}
- fn found_expression_ident(&mut self, n: &IdentifierNode, expr: ExpressionNode, ctx: Option) {
+ fn found_expression_ident(&mut self, n: &IdentifierNode, expr: ExpressionNode, ctx: TraversalContext) {
let expr_typ = evaluate_expression(
expr, ctx,
self.doc,
@@ -345,7 +345,7 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> {
}
}
- fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, _: DeclarationTraversalContext) {
+ fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, _: &TraversalContextStack) {
let var_type = n.var_type();
// not checking the annotation, because it'll be erroneous anyways
@@ -357,7 +357,7 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> {
}
}
- fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, _: DeclarationTraversalContext) {
+ fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, _: &TraversalContextStack) {
let name = n.name();
let autobind_type = n.autobind_type();
@@ -369,35 +369,35 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> {
}
}
- fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode, _: DeclarationTraversalContext) -> MemberDefaultValueTraversalPolicy {
+ fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode, ctx: &TraversalContextStack) -> MemberDefaultValueTraversalPolicy {
if self.pos_filter_payload.borrow().done {
let member = n.member();
if member.spans_position(self.pos) {
- self.found_expression_ident(&member, member.clone().into(), None);
+ self.found_expression_ident(&member, member.clone().into(), ctx.top());
}
}
TraversalPolicy::default_to(true)
}
- fn visit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode) -> MemberDefaultValueTraversalPolicy {
+ fn visit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode, ctx: &TraversalContextStack) -> MemberDefaultValueTraversalPolicy {
if self.pos_filter_payload.borrow().done {
let member = n.member();
if member.spans_position(self.pos) {
- self.found_expression_ident(&member, member.clone().into(), None);
+ self.found_expression_ident(&member, member.clone().into(), ctx.top());
}
}
TraversalPolicy::default_to(true)
}
- fn visit_member_hint(&mut self, n: &MemberHintNode, _: DeclarationTraversalContext) {
+ fn visit_member_hint(&mut self, n: &MemberHintNode, ctx: &TraversalContextStack) {
let member = n.member();
if member.spans_position(self.pos) {
- self.found_expression_ident(&member, member.clone().into(), None);
+ self.found_expression_ident(&member, member.clone().into(), ctx.top());
}
}
@@ -420,7 +420,7 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> {
TraversalPolicy::default_to(true)
}
- fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, _: DeclarationTraversalContext) -> FunctionDeclarationTraversalPolicy {
+ fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, _: &TraversalContextStack) -> FunctionDeclarationTraversalPolicy {
if self.pos_filter_payload.borrow().done {
let name = n.name();
@@ -436,7 +436,7 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> {
TraversalPolicy::default_to(true)
}
- fn visit_event_decl(&mut self, n: &EventDeclarationNode, _: DeclarationTraversalContext) -> EventDeclarationTraversalPolicy {
+ fn visit_event_decl(&mut self, n: &EventDeclarationNode, _: &TraversalContextStack) -> EventDeclarationTraversalPolicy {
if self.pos_filter_payload.borrow().done {
let name = n.name();
@@ -451,7 +451,7 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> {
TraversalPolicy::default_to(true)
}
- fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, _: FunctionTraversalContext) {
+ fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, _: &TraversalContextStack) {
let param_type = n.param_type();
if param_type.spans_position(self.pos) {
@@ -463,7 +463,7 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> {
}
- fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, _: StatementTraversalContext) -> VarDeclarationTraversalPolicy {
+ fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, _: &TraversalContextStack) -> VarDeclarationTraversalPolicy {
if self.pos_filter_payload.borrow().done {
let var_type = n.var_type();
@@ -479,39 +479,39 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> {
}
- fn visit_this_expr(&mut self, n: &ThisExpressionNode, _: ExpressionTraversalContext) {
+ fn visit_this_expr(&mut self, n: &ThisExpressionNode, _: &TraversalContextStack) {
self.found_this_kw(n);
}
- fn visit_super_expr(&mut self, n: &SuperExpressionNode, _: ExpressionTraversalContext) {
+ fn visit_super_expr(&mut self, n: &SuperExpressionNode, _: &TraversalContextStack) {
self.found_super_kw(n);
}
- fn visit_parent_expr(&mut self, n: &ParentExpressionNode, _: ExpressionTraversalContext) {
+ fn visit_parent_expr(&mut self, n: &ParentExpressionNode, _: &TraversalContextStack) {
self.found_parent_kw(n);
}
- fn visit_virtual_parent_expr(&mut self, n: &VirtualParentExpressionNode, _: ExpressionTraversalContext) {
+ fn visit_virtual_parent_expr(&mut self, n: &VirtualParentExpressionNode, _: &TraversalContextStack) {
self.found_virtual_parent_kw(n);
}
- fn visit_identifier_expr(&mut self, n: &IdentifierNode, cx: ExpressionTraversalContext) {
- self.found_expression_ident(n, n.clone().into(), Some(cx));
+ fn visit_identifier_expr(&mut self, n: &IdentifierNode, ctx: &TraversalContextStack) {
+ self.found_expression_ident(n, n.clone().into(), ctx.top());
}
- fn visit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, cx: ExpressionTraversalContext) -> MemberFieldExpressionTraversalPolicy {
+ fn visit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, ctx: &TraversalContextStack) -> MemberFieldExpressionTraversalPolicy {
if self.pos_filter_payload.borrow().done {
let member = n.member();
if member.spans_position(self.pos) {
- self.found_expression_ident(&member, n.clone().into(), Some(cx));
+ self.found_expression_ident(&member, n.clone().into(), ctx.top());
}
}
TraversalPolicy::default_to(true)
}
- fn visit_new_expr(&mut self, n: &NewExpressionNode, _: ExpressionTraversalContext) -> NewExpressionTraversalPolicy {
+ fn visit_new_expr(&mut self, n: &NewExpressionNode, _: &TraversalContextStack) -> NewExpressionTraversalPolicy {
if self.pos_filter_payload.borrow().done {
let class = n.class();
@@ -523,7 +523,7 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> {
TraversalPolicy::default_to(true)
}
- fn visit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, _: ExpressionTraversalContext) -> TypeCastExpressionTraversalPolicy {
+ fn visit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, _: &TraversalContextStack) -> TypeCastExpressionTraversalPolicy {
if self.pos_filter_payload.borrow().done {
let target_type = n.target_type();
diff --git a/crates/lsp/src/providers/custom/projects.rs b/crates/lsp/src/providers/custom/projects.rs
index 4edc9639..aa9704e1 100644
--- a/crates/lsp/src/providers/custom/projects.rs
+++ b/crates/lsp/src/providers/custom/projects.rs
@@ -1,9 +1,8 @@
use std::io::Write;
use abs_path::AbsPath;
-use tower_lsp::lsp_types as lsp;
use tower_lsp::jsonrpc::{self, Result};
use witcherscript_project::{content::VANILLA_CONTENT_NAME, Manifest};
-use crate::{notifications, requests::{self, ContentInfo}, Backend};
+use crate::{notifications, requests, model, Backend};
pub trait LangaugeServerCustomProjects {
@@ -11,9 +10,13 @@ pub trait LangaugeServerCustomProjects {
async fn vanilla_dependency_content(&self, params: requests::projects::vanilla_dependency_content::Parameters) -> Result;
+ async fn vanilla_content(&self, params: requests::projects::vanilla_content::Parameters) -> Result;
+
async fn project_list(&self, params: requests::projects::list::Parameters) -> Result;
async fn did_import_scripts(&self, params: notifications::projects::did_import_scripts::Parameters);
+
+ async fn source_tree(&self, params: requests::projects::source_tree::Parameters) -> Result;
}
@@ -148,13 +151,7 @@ impl LangaugeServerCustomProjects for Backend {
let mut content0_info = None;
for n in graph.walk_dependencies(&project_path) {
if n.content.content_name() == VANILLA_CONTENT_NAME {
- content0_info = Some(ContentInfo {
- content_uri: n.content.path().to_uri(),
- scripts_root_uri: n.content.source_tree_root().to_uri(),
- content_name: n.content.content_name().to_owned(),
- is_in_workspace: n.in_workspace,
- is_in_repository: n.in_repository
- });
+ content0_info = Some(model::ContentInfo::from(n));
}
}
@@ -171,6 +168,21 @@ impl LangaugeServerCustomProjects for Backend {
}
}
+ async fn vanilla_content(&self, _: requests::projects::vanilla_content::Parameters) -> Result {
+ let graph = self.content_graph.read().await;
+
+ let mut content0_info = None;
+ for n in graph.nodes() {
+ if n.content.content_name() == VANILLA_CONTENT_NAME {
+ content0_info = Some(model::ContentInfo::from(n));
+ }
+ }
+
+ Ok(requests::projects::vanilla_content::Response {
+ content0_info
+ })
+ }
+
async fn project_list(&self, params: requests::projects::list::Parameters) -> Result {
let only_from_workspace = params.only_from_workspace.unwrap_or(true);
@@ -182,13 +194,7 @@ impl LangaugeServerCustomProjects for Backend {
continue;
}
- project_infos.push(ContentInfo {
- content_uri: lsp::Url::from_file_path(n.content.path()).unwrap(),
- scripts_root_uri: lsp::Url::from_file_path(n.content.source_tree_root()).unwrap(),
- content_name: n.content.content_name().into(),
- is_in_workspace: n.in_workspace,
- is_in_repository: n.in_repository
- })
+ project_infos.push(model::ContentInfo::from(n));
}
Ok(requests::projects::list::Response {
@@ -213,6 +219,39 @@ impl LangaugeServerCustomProjects for Backend {
self.reporter.log_error("Imported files do no belong to a known content!").await;
}
}
+
+ async fn source_tree(&self, params: requests::projects::source_tree::Parameters) -> Result {
+ let content_path: AbsPath;
+ if let Ok(abs_path) = AbsPath::try_from(params.content_uri) {
+ content_path = abs_path;
+ } else {
+ return Err(jsonrpc::Error::invalid_params("content_uri parameter is not a valid file URI"));
+ }
+
+ let source_tree = self.source_trees.get(&content_path);
+
+ if source_tree.is_none() {
+ return Err(jsonrpc::Error {
+ code: jsonrpc::ErrorCode::ServerError(-1070),
+ message: "The content is absent from the content graph".into(),
+ data: None
+ })
+ }
+
+ let source_tree = source_tree.unwrap();
+ let scripts_root_path = source_tree.script_root().as_path().to_path_buf();
+ let mut local_script_paths: Vec<_> = source_tree.iter().map(|f| f.path.local().to_path_buf()).collect();
+ local_script_paths.sort();
+
+ let res = requests::projects::source_tree::Response {
+ scripts_root_path,
+ local_script_paths
+ };
+
+ drop(source_tree);
+
+ Ok(res)
+ }
}
diff --git a/crates/lsp/src/providers/custom/scripts.rs b/crates/lsp/src/providers/custom/scripts.rs
index d745b23e..989b89d6 100644
--- a/crates/lsp/src/providers/custom/scripts.rs
+++ b/crates/lsp/src/providers/custom/scripts.rs
@@ -1,6 +1,6 @@
use abs_path::AbsPath;
use tower_lsp::jsonrpc::{self, Result};
-use crate::{requests::{self, ContentInfo}, Backend};
+use crate::{requests, model, Backend};
pub trait LangaugeServerCustomScripts {
@@ -41,13 +41,7 @@ impl LangaugeServerCustomScripts for Backend {
if let Some(n) = self.content_graph.read().await.get_node_by_path(&parent_content_path) {
Ok(requests::scripts::parent_content::Response {
- parent_content_info: ContentInfo {
- content_uri: parent_content_path.into(),
- scripts_root_uri: n.content.source_tree_root().to_uri(),
- content_name: n.content.content_name().into(),
- is_in_workspace: n.in_workspace,
- is_in_repository: n.in_repository
- }
+ parent_content_info: model::ContentInfo::from(n)
})
} else {
Err(jsonrpc::Error {
diff --git a/crates/lsp/src/providers/initialization.rs b/crates/lsp/src/providers/initialization.rs
index 574afb06..35e672c7 100644
--- a/crates/lsp/src/providers/initialization.rs
+++ b/crates/lsp/src/providers/initialization.rs
@@ -6,50 +6,53 @@ use tower_lsp::lsp_types as lsp;
use tower_lsp::jsonrpc::Result;
use witcherscript_project::redkit::RedkitManifest;
use witcherscript_project::Manifest;
-use crate::Backend;
+use crate::{notifications, Backend};
-#[derive(Deserialize)]
+#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
struct InitializationOptions {
- native_content_uri: lsp::Url,
+ rayon_threads: i32,
+ native_content_path: PathBuf,
game_directory: PathBuf,
content_repositories: Vec,
enable_syntax_analysis: bool
}
-impl std::fmt::Debug for InitializationOptions {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.debug_struct("InitializationOptions")
- .field("native_content_uri", &self.native_content_uri.to_string())
- .field("game_directory", &self.game_directory)
- .field("content_repositories", &self.content_repositories)
- .field("enable_syntax_analysis", &self.enable_syntax_analysis)
- .finish()
- }
-}
-
impl Backend {
pub async fn initialize_impl(&self, params: lsp::InitializeParams) -> Result {
- if let Some(workspace_folders) = params.workspace_folders {
- let mut workspace_roots = self.workspace_roots.write().await;
- *workspace_roots = workspace_folders.into_iter()
- .map(|f| AbsPath::try_from(f.uri).unwrap())
- .collect();
- }
-
if let Some(init_opts) = params.initialization_options {
match serde_json::from_value::(init_opts) {
Ok(val) => {
self.reporter.log_info(format!("Initializing server with: {:#?}", val)).await;
+
+
+ let rayon_threads = if val.rayon_threads > 0 {
+ val.rayon_threads as usize
+ } else {
+ std::thread::available_parallelism()
+ .expect("Cannot access the number of available threads")
+ .get()
+ .checked_sub(2) // make sure rayon doesn't take up all resources
+ .unwrap_or(1)
+ };
+
+ rayon::ThreadPoolBuilder::new()
+ .num_threads(rayon_threads)
+ .build_global()
+ .expect("rayon::ThreadPoolBuilder panik");
+
+ self.reporter.log_info(format!("Configured tokio worker threads: {}", tokio::runtime::Handle::current().metrics().num_workers())).await;
+ self.reporter.log_info(format!("Configured rayon threads: {}", rayon_threads)).await;
+
- match AbsPath::try_from(val.native_content_uri) {
+ match AbsPath::try_from(val.native_content_path) {
Ok(native_content_path) => {
let mut graph = self.content_graph.write().await;
graph.set_native_content_path(&native_content_path);
},
Err(_) => {
- self.reporter.log_error("Invalid native_content_path URI").await;
+ self.reporter.log_error("Invalid native_content_path").await;
}
}
@@ -65,6 +68,13 @@ impl Backend {
} else {
self.reporter.log_error("Initialization options missing!").await;
}
+
+ if let Some(workspace_folders) = params.workspace_folders {
+ let mut workspace_roots = self.workspace_roots.write().await;
+ *workspace_roots = workspace_folders.into_iter()
+ .map(|f| AbsPath::try_from(f.uri).unwrap())
+ .collect();
+ }
let file_ops_filter_ws = lsp::FileOperationFilter {
@@ -155,7 +165,9 @@ impl Backend {
self.setup_workspace_content_scanners().await;
self.setup_repository_content_scanners().await;
self.build_content_graph(true).await;
-
+
+ self.client.send_notification::(()).await;
+
self.reporter.commit_all_diagnostics().await;
}
}
\ No newline at end of file
diff --git a/crates/lsp/src/providers/selection_range.rs b/crates/lsp/src/providers/selection_range.rs
index 0a817584..6b009f66 100644
--- a/crates/lsp/src/providers/selection_range.rs
+++ b/crates/lsp/src/providers/selection_range.rs
@@ -268,7 +268,7 @@ impl SyntaxNodeVisitor for SelectionRangeResolver {
- fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, _: DeclarationTraversalContext) -> FunctionDeclarationTraversalPolicy {
+ fn visit_member_func_decl(&mut self, n: &FunctionDeclarationNode, _: &TraversalContextStack) -> FunctionDeclarationTraversalPolicy {
self.range_stack.push(n.range());
if self.payload.borrow().done {
@@ -298,7 +298,7 @@ impl SyntaxNodeVisitor for SelectionRangeResolver {
TraversalPolicy::default_to(true)
}
- fn visit_event_decl(&mut self, n: &EventDeclarationNode, _: DeclarationTraversalContext) -> EventDeclarationTraversalPolicy {
+ fn visit_event_decl(&mut self, n: &EventDeclarationNode, _: &TraversalContextStack) -> EventDeclarationTraversalPolicy {
self.range_stack.push(n.range());
if self.payload.borrow().done {
@@ -319,7 +319,7 @@ impl SyntaxNodeVisitor for SelectionRangeResolver {
TraversalPolicy::default_to(true)
}
- fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, _: FunctionTraversalContext) {
+ fn visit_func_param_group(&mut self, n: &FunctionParameterGroupNode, _: &TraversalContextStack) {
self.range_stack.push(n.range());
if n.param_type().spans_position(self.pos) {
@@ -333,7 +333,7 @@ impl SyntaxNodeVisitor for SelectionRangeResolver {
}
}
- fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, _: DeclarationTraversalContext) {
+ fn visit_member_var_decl(&mut self, n: &MemberVarDeclarationNode, _: &TraversalContextStack) {
self.range_stack.push(n.range());
if let Some(annot) = n.annotation().filter(|annot| annot.spans_position(self.pos)) {
@@ -350,7 +350,7 @@ impl SyntaxNodeVisitor for SelectionRangeResolver {
}
}
- fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, _: DeclarationTraversalContext) {
+ fn visit_autobind_decl(&mut self, n: &AutobindDeclarationNode, _: &TraversalContextStack) {
self.range_stack.push(n.range());
if n.name().spans_position(self.pos) {
@@ -378,7 +378,7 @@ impl SyntaxNodeVisitor for SelectionRangeResolver {
}
}
- fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode, _: DeclarationTraversalContext) -> MemberDefaultValueTraversalPolicy {
+ fn visit_member_default_val(&mut self, n: &MemberDefaultValueNode, _: &TraversalContextStack) -> MemberDefaultValueTraversalPolicy {
self.range_stack.push(n.range());
if self.payload.borrow().done {
@@ -390,13 +390,13 @@ impl SyntaxNodeVisitor for SelectionRangeResolver {
TraversalPolicy::default_to(true)
}
- fn visit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode, _: DeclarationTraversalContext) -> MemberDefaultsBlockTraversalPolicy {
+ fn visit_member_defaults_block(&mut self, n: &MemberDefaultsBlockNode, _: &TraversalContextStack) -> MemberDefaultsBlockTraversalPolicy {
self.range_stack.push(n.range());
TraversalPolicy::default_to(true)
}
- fn visit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode) -> MemberDefaultValueTraversalPolicy {
+ fn visit_member_defaults_block_assignment(&mut self, n: &MemberDefaultsBlockAssignmentNode, _: &TraversalContextStack) -> MemberDefaultValueTraversalPolicy {
self.range_stack.push(n.range());
if self.payload.borrow().done {
@@ -408,7 +408,7 @@ impl SyntaxNodeVisitor for SelectionRangeResolver {
TraversalPolicy::default_to(true)
}
- fn visit_member_hint(&mut self, n: &MemberHintNode, _: DeclarationTraversalContext) {
+ fn visit_member_hint(&mut self, n: &MemberHintNode, _: &TraversalContextStack) {
self.range_stack.push(n.range());
if n.member().spans_position(self.pos) {
@@ -422,7 +422,7 @@ impl SyntaxNodeVisitor for SelectionRangeResolver {
- fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, _: StatementTraversalContext) -> VarDeclarationTraversalPolicy {
+ fn visit_local_var_decl_stmt(&mut self, n: &LocalVarDeclarationNode, _: &TraversalContextStack) -> VarDeclarationTraversalPolicy {
self.range_stack.push(n.range());
if self.payload.borrow().done {
@@ -437,13 +437,13 @@ impl SyntaxNodeVisitor for SelectionRangeResolver {
TraversalPolicy::default_to(true)
}
- fn visit_if_stmt(&mut self, n: &IfConditionalNode, _: StatementTraversalContext) -> IfConditionalTraversalPolicy {
+ fn visit_if_stmt(&mut self, n: &IfConditionalNode, _: &TraversalContextStack) -> IfConditionalTraversalPolicy {
self.range_stack.push(n.range());
TraversalPolicy::default_to(true)
}
- fn visit_switch_stmt(&mut self, n: &SwitchConditionalNode, _: StatementTraversalContext) -> SwitchConditionalTraversalPolicy {
+ fn visit_switch_stmt(&mut self, n: &SwitchConditionalNode, _: &TraversalContextStack) -> SwitchConditionalTraversalPolicy {
self.range_stack.push(n.range());
if n.body().spans_position(self.pos) {
@@ -453,104 +453,104 @@ impl SyntaxNodeVisitor for SelectionRangeResolver {
TraversalPolicy::default_to(true)
}
- fn visit_switch_stmt_case(&mut self, n: &SwitchConditionalCaseLabelNode) -> SwitchConditionalCaseLabelTraversalPolicy {
+ fn visit_switch_stmt_case(&mut self, n: &SwitchConditionalCaseLabelNode, _: &TraversalContextStack) -> SwitchConditionalCaseLabelTraversalPolicy {
self.range_stack.push(n.range());
TraversalPolicy::default_to(true)
}
- fn visit_switch_stmt_default(&mut self, n: &SwitchConditionalDefaultLabelNode) {
+ fn visit_switch_stmt_default(&mut self, n: &SwitchConditionalDefaultLabelNode, _: &TraversalContextStack) {
self.range_stack.push(n.range());
}
- fn visit_for_stmt(&mut self, n: &ForLoopNode, _: StatementTraversalContext) -> ForLoopTraversalPolicy {
+ fn visit_for_stmt(&mut self, n: &ForLoopNode, _: &TraversalContextStack) -> ForLoopTraversalPolicy {
self.range_stack.push(n.range());
TraversalPolicy::default_to(true)
}
- fn visit_while_stmt(&mut self, n: &WhileLoopNode, _: StatementTraversalContext) -> WhileLoopTraversalPolicy {
+ fn visit_while_stmt(&mut self, n: &WhileLoopNode, _: &TraversalContextStack) -> WhileLoopTraversalPolicy {
self.range_stack.push(n.range());
TraversalPolicy::default_to(true)
}
- fn visit_do_while_stmt(&mut self, n: &DoWhileLoopNode, _: StatementTraversalContext) -> DoWhileLoopTraversalPolicy {
+ fn visit_do_while_stmt(&mut self, n: &DoWhileLoopNode, _: &TraversalContextStack) -> DoWhileLoopTraversalPolicy {
self.range_stack.push(n.range());
TraversalPolicy::default_to(true)
}
- fn visit_compound_stmt(&mut self, n: &CompoundStatementNode, _: StatementTraversalContext) -> CompoundStatementTraversalPolicy {
+ fn visit_compound_stmt(&mut self, n: &CompoundStatementNode, _: &TraversalContextStack) -> CompoundStatementTraversalPolicy {
self.range_stack.push(n.range());
TraversalPolicy::default_to(true)
}
- fn visit_expr_stmt(&mut self, n: &ExpressionStatementNode, _: StatementTraversalContext) -> ExpressionStatementTraversalPolicy {
+ fn visit_expr_stmt(&mut self, n: &ExpressionStatementNode, _: &TraversalContextStack) -> ExpressionStatementTraversalPolicy {
self.range_stack.push(n.range());
TraversalPolicy::default_to(true)
}
- fn visit_return_stmt(&mut self, n: &ReturnStatementNode, _: StatementTraversalContext) -> ReturnStatementTraversalPolicy {
+ fn visit_return_stmt(&mut self, n: &ReturnStatementNode, _: &TraversalContextStack) -> ReturnStatementTraversalPolicy {
self.range_stack.push(n.range());
TraversalPolicy::default_to(true)
}
- fn visit_delete_stmt(&mut self, n: &DeleteStatementNode, _: StatementTraversalContext) -> DeleteStatementTraversalPolicy {
+ fn visit_delete_stmt(&mut self, n: &DeleteStatementNode, _: &TraversalContextStack) -> DeleteStatementTraversalPolicy {
self.range_stack.push(n.range());
TraversalPolicy::default_to(true)
}
- fn visit_break_stmt(&mut self, n: &BreakStatementNode, _: StatementTraversalContext) {
+ fn visit_break_stmt(&mut self, n: &BreakStatementNode, _: &TraversalContextStack) {
self.range_stack.push(n.range());
}
- fn visit_continue_stmt(&mut self, n: &ContinueStatementNode, _: StatementTraversalContext) {
+ fn visit_continue_stmt(&mut self, n: &ContinueStatementNode, _: &TraversalContextStack) {
self.range_stack.push(n.range());
}
- fn visit_nop_stmt(&mut self, n: &NopNode, _: StatementTraversalContext) {
+ fn visit_nop_stmt(&mut self, n: &NopNode, _: &TraversalContextStack) {
self.range_stack.push(n.range());
}
- fn visit_nested_expr(&mut self, n: &NestedExpressionNode, _: ExpressionTraversalContext) -> NestedExpressionTraversalPolicy {
+ fn visit_nested_expr(&mut self, n: &NestedExpressionNode, _: &TraversalContextStack) -> NestedExpressionTraversalPolicy {
self.range_stack.push(n.range());
TraversalPolicy::default_to(true)
}
- fn visit_array_expr(&mut self, n: &ArrayExpressionNode, _: ExpressionTraversalContext) -> ArrayExpressionTraversalPolicy {
+ fn visit_array_expr(&mut self, n: &ArrayExpressionNode, _: &TraversalContextStack) -> ArrayExpressionTraversalPolicy {
self.range_stack.push(n.range());
TraversalPolicy::default_to(true)
}
- fn visit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode, _: ExpressionTraversalContext) -> AssignmentOperationExpressionTraversalPolicy {
+ fn visit_assign_op_expr(&mut self, n: &AssignmentOperationExpressionNode, _: &TraversalContextStack) -> AssignmentOperationExpressionTraversalPolicy {
self.range_stack.push(n.range());
TraversalPolicy::default_to(true)
}
- fn visit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, _: ExpressionTraversalContext) -> BinaryOperationExpressionTraversalPolicy {
+ fn visit_binary_op_expr(&mut self, n: &BinaryOperationExpressionNode, _: &TraversalContextStack) -> BinaryOperationExpressionTraversalPolicy {
self.range_stack.push(n.range());
TraversalPolicy::default_to(true)
}
- fn visit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode, _: ExpressionTraversalContext) -> UnaryOperationExpressionTraversalPolicy {
+ fn visit_unary_op_expr(&mut self, n: &UnaryOperationExpressionNode, _: &TraversalContextStack) -> UnaryOperationExpressionTraversalPolicy {
self.range_stack.push(n.range());
TraversalPolicy::default_to(true)
}
- fn visit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, _: ExpressionTraversalContext) -> MemberFieldExpressionTraversalPolicy {
+ fn visit_member_access_expr(&mut self, n: &MemberAccessExpressionNode, _: &TraversalContextStack) -> MemberFieldExpressionTraversalPolicy {
self.range_stack.push(n.range());
if self.payload.borrow().done {
@@ -562,7 +562,7 @@ impl SyntaxNodeVisitor for SelectionRangeResolver {
TraversalPolicy::default_to(true)
}
- fn visit_new_expr(&mut self, n: &NewExpressionNode, _: ExpressionTraversalContext) -> NewExpressionTraversalPolicy {
+ fn visit_new_expr(&mut self, n: &NewExpressionNode, _: &TraversalContextStack) -> NewExpressionTraversalPolicy {
self.range_stack.push(n.range());
if self.payload.borrow().done {
@@ -574,7 +574,7 @@ impl SyntaxNodeVisitor for SelectionRangeResolver {
TraversalPolicy::default_to(true)
}
- fn visit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, _: ExpressionTraversalContext) -> TypeCastExpressionTraversalPolicy {
+ fn visit_type_cast_expr(&mut self, n: &TypeCastExpressionNode, _: &TraversalContextStack) -> TypeCastExpressionTraversalPolicy {
self.range_stack.push(n.range());
if self.payload.borrow().done {
@@ -586,13 +586,13 @@ impl SyntaxNodeVisitor for SelectionRangeResolver {
TraversalPolicy::default_to(true)
}
- fn visit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode, _: ExpressionTraversalContext) -> TernaryConditionalExpressionTraversalPolicy {
+ fn visit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode, _: &TraversalContextStack) -> TernaryConditionalExpressionTraversalPolicy {
self.range_stack.push(n.range());
TraversalPolicy::default_to(true)
}
- fn visit_func_call_expr(&mut self, n: &FunctionCallExpressionNode, _: ExpressionTraversalContext) -> FunctionCallExpressionTraversalPolicy {
+ fn visit_func_call_expr(&mut self, n: &FunctionCallExpressionNode, _: &TraversalContextStack) -> FunctionCallExpressionTraversalPolicy {
self.range_stack.push(n.range());
if let Some(args) = n.args() {
@@ -604,27 +604,27 @@ impl SyntaxNodeVisitor for SelectionRangeResolver {
TraversalPolicy::default_to(true)
}
- fn visit_identifier_expr(&mut self, n: &IdentifierNode, _: ExpressionTraversalContext) {
+ fn visit_identifier_expr(&mut self, n: &IdentifierNode, _: &TraversalContextStack) {
self.range_stack.push(n.range());
}
- fn visit_literal_expr(&mut self, n: &LiteralNode, _: ExpressionTraversalContext) {
+ fn visit_literal_expr(&mut self, n: &LiteralNode, _: &TraversalContextStack) {
self.range_stack.push(n.range());
}
- fn visit_this_expr(&mut self, n: &ThisExpressionNode, _: ExpressionTraversalContext) {
+ fn visit_this_expr(&mut self, n: &ThisExpressionNode, _: &TraversalContextStack) {
self.range_stack.push(n.range());
}
- fn visit_super_expr(&mut self, n: &SuperExpressionNode, _: ExpressionTraversalContext) {
+ fn visit_super_expr(&mut self, n: &SuperExpressionNode, _: &TraversalContextStack) {
self.range_stack.push(n.range());
}
- fn visit_parent_expr(&mut self, n: &ParentExpressionNode, _: ExpressionTraversalContext) {
+ fn visit_parent_expr(&mut self, n: &ParentExpressionNode, _: &TraversalContextStack) {
self.range_stack.push(n.range());
}
- fn visit_virtual_parent_expr(&mut self, n: &VirtualParentExpressionNode, _: ExpressionTraversalContext) {
+ fn visit_virtual_parent_expr(&mut self, n: &VirtualParentExpressionNode, _: &TraversalContextStack) {
self.range_stack.push(n.range());
}
}
diff --git a/crates/lsp/src/requests.rs b/crates/lsp/src/requests.rs
index 0e6fa5d9..b2d1f98f 100644
--- a/crates/lsp/src/requests.rs
+++ b/crates/lsp/src/requests.rs
@@ -1,17 +1,7 @@
use serde::Deserialize;
use serde::Serialize;
use tower_lsp::lsp_types as lsp;
-
-
-#[derive(Debug, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct ContentInfo {
- pub content_uri: lsp::Url,
- pub scripts_root_uri: lsp::Url,
- pub content_name: String,
- pub is_in_workspace: bool,
- pub is_in_repository: bool
-}
+use super::model;
pub mod projects {
@@ -52,7 +42,7 @@ pub mod projects {
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Response {
- pub project_infos: Vec
+ pub project_infos: Vec
}
pub const METHOD: &'static str = "witcherscript-ide/projects/list";
@@ -71,11 +61,52 @@ pub mod projects {
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Response {
- pub content0_info: ContentInfo
+ pub content0_info: model::ContentInfo
}
pub const METHOD: &'static str = "witcherscript-ide/projects/vanillaDependencyContent";
}
+
+ /// Returns information about content0 content, doesn't need any source content to check as opposed to [`vanilla_dependency_content`].
+ /// Returns None if doesn't find content0
+ pub mod vanilla_content {
+ use super::*;
+
+ #[derive(Debug, Serialize, Deserialize)]
+ #[serde(rename_all = "camelCase")]
+ pub struct Parameters {
+
+ }
+
+ #[derive(Debug, Serialize, Deserialize)]
+ #[serde(rename_all = "camelCase")]
+ pub struct Response {
+ pub content0_info: Option
+ }
+
+ pub const METHOD: &'static str = "witcherscript-ide/projects/vanillaContent";
+ }
+
+ /// Returns a list of source file paths associated with a given content sorted in alphabetical order
+ pub mod source_tree {
+ use std::path::PathBuf;
+ use super::*;
+
+ #[derive(Debug, Serialize, Deserialize)]
+ #[serde(rename_all = "camelCase")]
+ pub struct Parameters {
+ pub content_uri: lsp::Url
+ }
+
+ #[derive(Debug, Serialize, Deserialize)]
+ #[serde(rename_all = "camelCase")]
+ pub struct Response {
+ pub scripts_root_path: PathBuf,
+ pub local_script_paths: Vec
+ }
+
+ pub const METHOD: &'static str = "witcherscript-ide/projects/sourceTree";
+ }
}
pub mod scripts {
@@ -94,7 +125,7 @@ pub mod scripts {
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Response {
- pub parent_content_info: ContentInfo
+ pub parent_content_info: model::ContentInfo
}
pub const METHOD: &'static str = "witcherscript-ide/scripts/parentContent";
diff --git a/crates/lsp/src/tasks/content_indexing_tasks.rs b/crates/lsp/src/tasks/content_indexing_tasks.rs
index c58a3afc..9a3a2b6b 100644
--- a/crates/lsp/src/tasks/content_indexing_tasks.rs
+++ b/crates/lsp/src/tasks/content_indexing_tasks.rs
@@ -9,7 +9,7 @@ use witcherscript_project::content::{ContentScanError, ProjectDirectory, RedkitP
use witcherscript_project::source_tree::SourceTreeDifference;
use witcherscript_project::{ContentScanner, FileError};
use witcherscript_project::content_graph::{ContentGraphDifference, ContentGraphError, GraphEdgeWithContent, GraphNode, ModifiedGraphNode};
-use crate::Backend;
+use crate::{Backend, notifications};
impl Backend {
@@ -140,6 +140,8 @@ impl Backend {
self.on_graph_edges_removed(diff_edges_removed).await;
}
+ self.client.send_notification::(()).await;
+
let duration = Instant::now() - start;
self.reporter.log_info(format!("Handled content graph related changes in {:.3}s", duration.as_secs_f32())).await;
}
diff --git a/crates/lsp/src/tasks/script_indexing_tasks.rs b/crates/lsp/src/tasks/script_indexing_tasks.rs
index b6895097..3a871e6d 100644
--- a/crates/lsp/src/tasks/script_indexing_tasks.rs
+++ b/crates/lsp/src/tasks/script_indexing_tasks.rs
@@ -3,7 +3,7 @@ use rayon::prelude::*;
use abs_path::AbsPath;
use witcherscript::{script_document::ScriptDocument, Script};
use witcherscript_project::source_tree::{SourceTreeDifference, SourceTreeFile};
-use crate::{Backend, ScriptState, ScriptStateContentInfo};
+use crate::{Backend, ScriptState, ScriptStateContentInfo, notifications};
impl Backend {
@@ -53,6 +53,16 @@ impl Backend {
.map(|f| f.to_owned())
.collect::>();
+ let content_name = self.content_graph
+ .read().await
+ .get_node_by_path(content_path)
+ .map(|n| n.content.content_name().to_string())
+ .unwrap_or_default();
+
+ self.client.send_notification::(notifications::scripts::did_start_script_parsing::Parameters {
+ content_name: content_name.clone()
+ }).await;
+
if !diff_removed.is_empty() {
self.on_source_tree_files_removed(diff_removed, content_path).await;
}
@@ -66,6 +76,10 @@ impl Backend {
self.on_source_tree_files_added_or_modified(diff_added_or_modified, content_path).await;
}
+ self.client.send_notification::(notifications::scripts::did_finish_script_parsing::Parameters {
+ content_name
+ }).await;
+
let duration = Instant::now() - start;
self.reporter.log_info(format!("Handled source tree related changes to {} in {:.3}s", content_path.display(), duration.as_secs_f32())).await;
}
diff --git a/docs/assets/user-manual/editor/contents-view.png b/docs/assets/user-manual/editor/contents-view.png
new file mode 100644
index 00000000..5d4b1ccf
Binary files /dev/null and b/docs/assets/user-manual/editor/contents-view.png differ
diff --git a/docs/assets/user-manual/editor/dashboard-view.png b/docs/assets/user-manual/editor/dashboard-view.png
new file mode 100644
index 00000000..122cde6d
Binary files /dev/null and b/docs/assets/user-manual/editor/dashboard-view.png differ
diff --git a/docs/assets/user-manual/editor/project-creation.mp4 b/docs/assets/user-manual/editor/project-creation.mp4
deleted file mode 100644
index eccfd4d0..00000000
Binary files a/docs/assets/user-manual/editor/project-creation.mp4 and /dev/null differ
diff --git a/docs/assets/user-manual/editor/project-manifest.png b/docs/assets/user-manual/editor/project-manifest.png
new file mode 100644
index 00000000..ee92c2ec
Binary files /dev/null and b/docs/assets/user-manual/editor/project-manifest.png differ
diff --git a/docs/assets/user-manual/editor/script-import.mp4 b/docs/assets/user-manual/editor/script-import.mp4
deleted file mode 100644
index 893fe758..00000000
Binary files a/docs/assets/user-manual/editor/script-import.mp4 and /dev/null differ
diff --git a/docs/assets/user-manual/editor/status-bar.png b/docs/assets/user-manual/editor/status-bar.png
new file mode 100644
index 00000000..cf9451e0
Binary files /dev/null and b/docs/assets/user-manual/editor/status-bar.png differ
diff --git a/docs/assets/user-manual/editor/vanilla-import-diff.mp4 b/docs/assets/user-manual/editor/vanilla-import-diff.mp4
index f0f84888..e72ea9b4 100644
Binary files a/docs/assets/user-manual/editor/vanilla-import-diff.mp4 and b/docs/assets/user-manual/editor/vanilla-import-diff.mp4 differ
diff --git a/docs/assets/user-manual/editor/vanilla-scripts-view.png b/docs/assets/user-manual/editor/vanilla-scripts-view.png
new file mode 100644
index 00000000..93cf565d
Binary files /dev/null and b/docs/assets/user-manual/editor/vanilla-scripts-view.png differ
diff --git a/docs/assets/user-manual/getting-started/getting-started.mp4 b/docs/assets/user-manual/getting-started/getting-started.mp4
index 79371924..7fc6c52c 100644
Binary files a/docs/assets/user-manual/getting-started/getting-started.mp4 and b/docs/assets/user-manual/getting-started/getting-started.mp4 differ
diff --git a/docs/dev-manual.md b/docs/dev-manual.md
index 63fa6fdc..5e9ff507 100644
--- a/docs/dev-manual.md
+++ b/docs/dev-manual.md
@@ -27,12 +27,19 @@ Currently available xtask commands:
- `prep-client` - build VSCode client
- `--watch` - whether client should be continuously watched for changes made to it and rebuilt
- `--fast` - whether client should be built instantly by skipping `npm ci` step
+- `prep-rw3d` - download the [Rusty Witcher 3 Debugger CLI](https://github.com/SpontanCombust/rusty_witcher_debugger) needed by the client
- `package` - build and package VSCode extension into a .vsix file
- `--out` - output path for the .vsix file; default is "./witcherscript-ide.vsix"
- `--target` - VSCode extension target, e.g. win32-x64
- `--pre-release` - mark the package as pre-release
- `install` - build, package and install the VSCode extension locally
+The usual procedure is as follows:
+
+1. Run `prep-server` whenever making changing to the LSP server. The executable cannot be updated during an active extension host session.
+2. Run `prep-client` whenever making changes to the VSCode client code. This can be done during extension host session, but changes can be observed only after extension reload.
+3. Run `prep-rw3d` when building the project for the first time or when the desired version of the tool changes.
+4. Run all the above when building the project for the first time.
## Debugging
Use VSCode to debug the client and server. The project provides launch configurations for both of them:
diff --git a/docs/user-manual/changelog.md b/docs/user-manual/changelog.md
index 78548ea1..48565aac 100644
--- a/docs/user-manual/changelog.md
+++ b/docs/user-manual/changelog.md
@@ -2,6 +2,50 @@
# Changelog
+# v0.4.0
+**UI/UX Improvements and more**
+
+### Features
+
+- Added a welcome message that is shown when using the extension for the first time [#47](https://github.com/SpontanCombust/witcherscript-ide/issues/47)
+- Added a message pointing to the changelog when the extension gets updated
+- Added a short in-editor walkthrough for the extension [#47](https://github.com/SpontanCombust/witcherscript-ide/issues/47)
+- Added a view container that houses all views added by the extension [#45](https://github.com/SpontanCombust/witcherscript-ide/issues/45)
+- Added a "Dashboard" view that shows a list some of the main commands you can execute, so you don't have to look through the command palette [#46](https://github.com/SpontanCombust/witcherscript-ide/issues/46)
+- Integrated the [Rusty Witcher 3 Debugger CLI](https://github.com/SpontanCombust/rusty_witcher_debugger/) tool into the extension client [#4](https://github.com/SpontanCombust/witcherscript-ide/issues/4)
+- Added "Vanilla Scripts" view. It displays the source tree of vanilla scripts (content0) and allows for peeking and importing vanilla scripts from the level of the view. [#42](https://github.com/SpontanCombust/witcherscript-ide/issues/42)
+- Added "Contents" view. It displays script packages known to the content graph - its metadata and files it is associated with. When extension is active, but there are no script projects in the workspace it displays a welcome message with buttons for creating and initializing a project [#22](https://github.com/SpontanCombust/witcherscript-ide/issues/22)
+- Added context menu items for comparing modded script with vanilla to file explorer and editor views
+- Added context status bar item displaying name of the currently worked on script project. Clicking the item shows the command palette of all available WIDE commands [#12](https://github.com/SpontanCombust/witcherscript-ide/issues/12)
+- Added work status bar item displaying the current background work being done on the language server. The item is hidden when there is no work being done currenly [#12](https://github.com/SpontanCombust/witcherscript-ide/issues/12)
+- Added analysis for local var declaration placement
+
+### Fixes
+- Fixed contextual syntax analysis not working for events
+
+### Commands
+- Added "Open extension logs" command
+- Added "Open extension settings" command
+- Added commands to launch the game
+- Added "Recompile game scripts" command
+- Added "Execute console command" command
+
+### Configuration
+- Added a setting to describe a prefered way of launching the game host for testing (standalone with debug args, REDkit, auto)
+- Added a setting for the IP address of the game host
+- Added a setting for the number of threads allocated to Rayon's parallel data processing
+
+### Other changes
+- Error message after failing to import vanilla scripts now points to extension logs
+
+### Documentation
+- Added "UI Elements" section to the "Editor" page
+- Updated some videos on the "Editor" to better reflect modern way of doing things in WIDE
+- Renamed "Editor" page to "Editor Features"
+- Added a disclaimer for using "content0" as the dependency for projects on the "Project System" page
+- Moved the REDkit section closer to the beginning on the "Project System" page
+- Rewrote "Getting started" page to point to and present the new built-in tutorial
+
## v0.3.2
**Hotfix**
diff --git a/docs/user-manual/diagnostic-index.md b/docs/user-manual/diagnostic-index.md
index a0e1d902..6d21e600 100644
--- a/docs/user-manual/diagnostic-index.md
+++ b/docs/user-manual/diagnostic-index.md
@@ -326,6 +326,25 @@ var modsInstalled: int; // (1)
1. Variable declaration not allowed here.
+---
+
+### `invalid-local-var-placement`
+
+The WitcherScript compiler is not very flexible when it comes to local variable declarations. You are forced to declare all of them at the start of a function before doing anything else, even when it comes to such trivial cases like for loop iterator. This is similar to early C language standards, where declarations could only be done at the beginning of a scope.
+
+```ts linenums="1" hl_lines="3"
+function LogHeldSwordInCombat() {
+ if (thePlayer.IsInCombatState()) {
+ var id: SItemUniqueId; // (1)
+ id = thePlayer.inv.GetCurrentlyHeldSword();
+ LogChannel('TEST', "Sword item name: " + thePlayer.inv.GetItemName(id));
+ }
+}
+```
+
+1. Variable must be done before the "if" statement.
+
+
---
diff --git a/docs/user-manual/editor.md b/docs/user-manual/editor.md
index 867dd232..5a324b23 100644
--- a/docs/user-manual/editor.md
+++ b/docs/user-manual/editor.md
@@ -1,36 +1,67 @@
-# Editor
+# Editor Features
+
+
+## UI Elements
+
+### Dashboard View
+
+The primary view is the dashboard, which lets among other things create a script project and recompile game's scripts.
+
+
+
+### Vanilla Scripts View
+
+This view lets you see all available vanilla script files that you can import/checkout into your project.
+
+
+
+### Contents View
+
+Script "contents" or "packages" are seperate units of code that WIDE can recognize. These include custom WIDE projects, REDkit projects and raw Mod directories. You can learn more about the project system that WIDE uses [here](https://spontancombust.github.io/witcherscript-ide/user-manual/project-system/).
+
+
+
+### Status Bar
+
+Status bar displays context information about the last worked on project and any processes that might be going on currently in the background.
+
+
+
+
+
+
+
+---
## Features
-- creating and initializing [script projects](./project-system.md)
+### Creating and initializing [script projects](./project-system.md)
-
+
:material-information-outline: Loading REDkit projects is also natively supported with some prior requirements outlined [here](./project-system.md#redkit-project).
-- syntax highlighting
+### Syntax highlighting

-- basic syntax analysis
+### Basic syntax analysis

-- importing and comparing scripts with their vanilla counterparts
+### Importing and comparing scripts with their vanilla counterparts
-- hover tooltips
+### Hover tooltips
-- go to definition/declaration
+### Go to definition/declaration