vitest-pool-assemblyscript 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +110 -36
  2. package/binding.gyp +6 -6
  3. package/dist/{compiler-CscxCJw3.mjs → addon-interface-7FPjYh7J.mjs} +12 -141
  4. package/dist/addon-interface-7FPjYh7J.mjs.map +1 -0
  5. package/dist/{ast-visitor-DJLJd5dt.mjs → ast-visitor-C5gQqWD2.mjs} +1 -1
  6. package/dist/{ast-visitor-DJLJd5dt.mjs.map → ast-visitor-C5gQqWD2.mjs.map} +1 -1
  7. package/dist/{compile-runner-BJ_ZF3Ma.mjs → compile-runner-C-05LdGX.mjs} +7 -6
  8. package/dist/compile-runner-C-05LdGX.mjs.map +1 -0
  9. package/dist/compiler/transforms/strip-inline.mjs +2 -3
  10. package/dist/compiler/transforms/strip-inline.mjs.map +1 -1
  11. package/dist/compiler-YMrl5MY_.mjs +147 -0
  12. package/dist/compiler-YMrl5MY_.mjs.map +1 -0
  13. package/dist/config/index-v3.d.mts +2 -2
  14. package/dist/config/index.d.mts +3 -3
  15. package/dist/config/index.mjs +4 -4
  16. package/dist/{coverage-merge-DCEwyjMy.mjs → coverage-merge-CBXkpM1O.mjs} +1 -1
  17. package/dist/{coverage-merge-DCEwyjMy.mjs.map → coverage-merge-CBXkpM1O.mjs.map} +1 -1
  18. package/dist/coverage-provider/index.mjs +11 -11
  19. package/dist/coverage-provider/index.mjs.map +1 -1
  20. package/dist/{custom-provider-options-i_O0OSTV.d.mts → custom-provider-options-YTk1m7At.d.mts} +2 -2
  21. package/dist/{custom-provider-options-i_O0OSTV.d.mts.map → custom-provider-options-YTk1m7At.d.mts.map} +1 -1
  22. package/dist/feature-check-CNyjFX9M.mjs +82 -0
  23. package/dist/feature-check-CNyjFX9M.mjs.map +1 -0
  24. package/dist/index-internal.d.mts +1 -1
  25. package/dist/index-internal.d.mts.map +1 -1
  26. package/dist/index-internal.mjs +2 -1
  27. package/dist/index-v3.mjs +3 -3
  28. package/dist/index.d.mts +2 -2
  29. package/dist/index.mjs +4 -4
  30. package/dist/{load-user-imports-CYTTU22Q.mjs → load-user-imports-B3Iy_K8k.mjs} +4 -5
  31. package/dist/{load-user-imports-CYTTU22Q.mjs.map → load-user-imports-B3Iy_K8k.mjs.map} +1 -1
  32. package/dist/path-utils-t9OzjXYF.mjs +24 -0
  33. package/dist/path-utils-t9OzjXYF.mjs.map +1 -0
  34. package/dist/{pool-runner-init-D56aVMMD.d.mts → pool-runner-init-CvnB0-iN.d.mts} +2 -2
  35. package/dist/pool-runner-init-CvnB0-iN.d.mts.map +1 -0
  36. package/dist/{pool-runner-init-D1QamWkS.mjs → pool-runner-init-D8Ei957C.mjs} +6 -5
  37. package/dist/pool-runner-init-D8Ei957C.mjs.map +1 -0
  38. package/dist/pool-thread/compile-worker-thread.d.mts +1 -1
  39. package/dist/pool-thread/compile-worker-thread.mjs +7 -7
  40. package/dist/pool-thread/compile-worker-thread.mjs.map +1 -1
  41. package/dist/pool-thread/test-worker-thread.d.mts +1 -1
  42. package/dist/pool-thread/test-worker-thread.mjs +5 -5
  43. package/dist/pool-thread/test-worker-thread.mjs.map +1 -1
  44. package/dist/pool-thread/v3-tinypool-thread.d.mts +1 -1
  45. package/dist/pool-thread/v3-tinypool-thread.mjs +8 -8
  46. package/dist/pool-thread/v3-tinypool-thread.mjs.map +1 -1
  47. package/dist/resolve-config-BFNr7LW7.mjs.map +1 -1
  48. package/dist/{test-runner-CfhzcYNS.mjs → test-runner-WF857_Bk.mjs} +4 -4
  49. package/dist/{test-runner-CfhzcYNS.mjs.map → test-runner-WF857_Bk.mjs.map} +1 -1
  50. package/dist/{types-DmyeERkL.d.mts → types-D0nprJo1.d.mts} +1 -1
  51. package/dist/types-D0nprJo1.d.mts.map +1 -0
  52. package/dist/{vitest-file-tasks-BUwzh375.mjs → vitest-file-tasks-Bn9CrWt_.mjs} +1 -1
  53. package/dist/{vitest-file-tasks-BUwzh375.mjs.map → vitest-file-tasks-Bn9CrWt_.mjs.map} +1 -1
  54. package/dist/{vitest-tasks-ByPK8DvF.mjs → vitest-tasks--ow4pacR.mjs} +1 -1
  55. package/dist/{vitest-tasks-ByPK8DvF.mjs.map → vitest-tasks--ow4pacR.mjs.map} +1 -1
  56. package/dist/{wasm-names-CydfYzQK.mjs → wasm-names-BFtzQCH4.mjs} +1 -1
  57. package/dist/{wasm-names-CydfYzQK.mjs.map → wasm-names-BFtzQCH4.mjs.map} +1 -1
  58. package/dist/{worker-rpc-channel-lbhK7Qz8.mjs → worker-rpc-channel-CZZIxtv5.mjs} +1 -1
  59. package/dist/{worker-rpc-channel-lbhK7Qz8.mjs.map → worker-rpc-channel-CZZIxtv5.mjs.map} +1 -1
  60. package/package.json +17 -16
  61. package/prebuilds/darwin-arm64/vitest-pool-assemblyscript.glibc.node +0 -0
  62. package/prebuilds/darwin-x64/vitest-pool-assemblyscript.glibc.node +0 -0
  63. package/prebuilds/linux-arm64/vitest-pool-assemblyscript.glibc.node +0 -0
  64. package/prebuilds/linux-x64/vitest-pool-assemblyscript.glibc.node +0 -0
  65. package/prebuilds/linux-x64/vitest-pool-assemblyscript.musl.node +0 -0
  66. package/prebuilds/win32-arm64/vitest-pool-assemblyscript.glibc.node +0 -0
  67. package/prebuilds/win32-x64/vitest-pool-assemblyscript.glibc.node +0 -0
  68. package/scripts/install.js +53 -16
  69. package/src/{native-instrumentation → instrumentation/native}/addon.cpp +8 -8
  70. package/dist/compile-runner-BJ_ZF3Ma.mjs.map +0 -1
  71. package/dist/compiler-CscxCJw3.mjs.map +0 -1
  72. package/dist/node-check-CooGQMLH.mjs +0 -16
  73. package/dist/node-check-CooGQMLH.mjs.map +0 -1
  74. package/dist/pool-runner-init-D1QamWkS.mjs.map +0 -1
  75. package/dist/pool-runner-init-D56aVMMD.d.mts.map +0 -1
  76. package/dist/types-DmyeERkL.d.mts.map +0 -1
package/README.md CHANGED
@@ -2,8 +2,12 @@
2
2
 
3
3
  <p align="center">
4
4
  <img src="docs/images/as-icon.svg" height="50" align="middle">
5
- &nbsp;&nbsp;&#10133;&nbsp;&nbsp;
6
- <img src="docs/images/vitest-dark.svg" height="30" align="middle">
5
+ &nbsp;&nbsp;&nbsp;&nbsp;&#10133;&nbsp;&nbsp;&nbsp;&nbsp;
6
+ <picture>
7
+ <source media="(prefers-color-scheme: dark)" srcset="docs/images/vitest-light.svg">
8
+ <source media="(prefers-color-scheme: light)" srcset="docs/images/vitest-dark.svg">
9
+ <img alt="Vitest logo" src="docs/images/vitest-dark.svg" height="30" align="middle">
10
+ </picture>
7
11
  </p>
8
12
 
9
13
  <p align="center">
@@ -24,29 +28,51 @@
24
28
  </p>
25
29
 
26
30
  <p align="center">
27
- <a href="#status">Status</a> | <a href="#quick-start">Quick Start</a> | <a href="#features">Features</a> | <a href="#compatibility">Compatibility</a> | <a href="#performance">Performance</a> | <a href="#prior-work">Prior Work</a> | <a href="#license">License</a>
31
+ Check it out:
28
32
  <br/>
29
- <a href="#writing-tests">Writing Tests</a> | <a href="docs/matchers-api.md">Matchers API</a> | <a href="docs/configuration-guide.md">Configuration Guide</a> | <a href="docs/providing-wasm-imports.md">Providing WASM Imports</a>
33
+ <a href="#status">Status</a> |
34
+ <a href="#quick-start">Quick Start</a> |
35
+ <a href="#features">Features</a> |
36
+ <a href="#frequently-asked-questions">Frequently Asked Questions</a>
37
+ <br/>
38
+ <a href="#compatibility">Compatibility</a> |
39
+ <a href="#performance">Performance</a> |
40
+ <a href="#prior-work">Prior Work</a> |
41
+ <a href="#license">License</a>
42
+ </p>
43
+ <p align="center">
44
+ Dig in:
45
+ <br/>
46
+ <a href="#writing-tests">Writing Tests</a> |
47
+ <a href="docs/matchers-api.md">Matchers API</a> |
48
+ <a href="docs/configuration-guide.md">Configuration Guide</a> |
49
+ <a href="docs/providing-wasm-imports.md">Providing WASM Imports</a>
30
50
  </p>
31
51
 
32
52
  ---
33
53
 
34
54
  <br/>
35
55
  <p align="center">
36
- <img src="docs/images/example-small.gif" alt="vitest-pool-assemblyscript demo">
56
+ <img src="docs/images/example-small.gif" alt="vitest-pool-assemblyscript quick demo">
37
57
  </p>
38
58
 
39
59
  ## Status
40
60
 
41
61
  This project is relatively new to the scene, but is being improved every day. Please give it a try!
42
62
 
43
- - All [listed features](#features) are working and assumed to be bug-free ([report](https://github.com/themattspiral/vitest-pool-assemblyscript/issues/new))
44
- - [`describe()` and `test()` definition APIs](#writing-tests) are stable and not expected to change
45
- - [`expect()` matchers API](docs/matchers-api.md) is stable and not expected to change. More are coming soon
46
- - Native instrumentation prebuilds are available [across many platforms](#compatibility)
47
- - See [Current Limitations & Roadmap](#current-limitations--roadmap) for important limitations to be aware of, and to see what's still planned.
63
+ All [listed features](#features) are working and assumed to be bug-free ([please report any](https://github.com/themattspiral/vitest-pool-assemblyscript/issues/new))
48
64
 
49
- Please [report a bug or request a feature](https://github.com/themattspiral/vitest-pool-assemblyscript/issues/new) if you have something you'd like to share.
65
+ | Function | Status |
66
+ |---|---|
67
+ | [`describe()` and `test()` APIs](#writing-tests) | - stable<br/>- no breaking changes expected |
68
+ | [`expect()` API](docs/matchers-api.md) | - stable<br/>- no breaking changes expected<br/>- more coming soon |
69
+ | Code Coverage / Instrumentation | - function coverage stable [across platforms](#compatibility)<br/>- branch & line coverage coming soon |
70
+ | Hybrid Coverage Provider | - stable<br/>- v8 delegation, side-by-side JS coverage<br/>- istanbul delegation coming soon
71
+
72
+ See Also:
73
+ - [Current Limitations & Roadmap](#current-limitations--roadmap)
74
+ - [Frequently Asked Questions](#frequently-asked-questions)
75
+ - [Report a Bug / Request a Feature](https://github.com/themattspiral/vitest-pool-assemblyscript/issues/new)
50
76
 
51
77
  ---
52
78
 
@@ -162,17 +188,47 @@ npx vitest run
162
188
 
163
189
  ---
164
190
 
191
+ ## Frequently Asked Questions
192
+
193
+ **Q: How does this work?**
194
+ <br/>
195
+ **A:** Vitest has a [custom pool API](https://vitest.dev/guide/advanced/pool.html) that lets you define the execution environment for the tests it runs (internally, vitest uses its own pools to run JavaScript and TypeScript tests). This custom pool uses the [AssemblyScript compiler](https://www.assemblyscript.org/compiler.html) to compile each test file to WASM, instruments the WASM binary for code coverage, then runs each test in an isolated WASM instance and reports results back to vitest through its standard RPC reporting mechanism.
196
+
197
+ **Q: So it is really using vitest?**
198
+ <br/>
199
+ **A:** Yes! It's a real vitest pool, not a clone of vitest - it hooks directly into the framework, receiving tests to run from vitest and reporting results back. The pool implements its own compilation, test execution, and [matchers in AS](docs/matchers-api.md), designed to mirror the [vitest expect() API](https://vitest.dev/api/expect.html). We don't use vite build integration, but that's the tradeoff of a custom pool - you can bring any execution environment to vitest.
200
+
201
+ The overall goal is tight vitest experience integration - most CLI commands, reporters, UI, and project configurations should work as you'd expect, and test runner behavior should match vitest's JS pool runner for features we've implemented (retries, timeouts, skip, only, fails, etc.). Some features aren't implemented yet due to effort and prioritization, and others necessarily differ given AssemblyScript's static typing and execution model. See the [configuration guide](docs/configuration-guide.md) and [limitations / roadmap](#current-limitations--roadmap) for specifics.
202
+
203
+ **Q: Will this work on my machine?**
204
+ <br/>
205
+ **A:** Probably! WASM coverage instrumentation requires native binaries, and we ship [prebuilt binaries for most common platforms](#compatibility). If your platform isn't listed, the npm package installation will fallback to trying to build the native code using a local C++ toolchain.
206
+
207
+ **Q: Do you support older versions of AssemblyScript?**
208
+ <br/>
209
+ **A:** It's tested against 0.28.9 currently, and that's the version I have any real experience with. Older versions might work but aren't actively tested. If you're stuck on an older version and run into issues, you're welcome to [open an issue](https://github.com/themattspiral/vitest-pool-assemblyscript/issues/new).
210
+
211
+ **Q: Is this an official vitest project?**
212
+ <br/>
213
+ **A:** No, this is a third-party community project. It's not affiliated with or endorsed by the vitest team, though we're grateful for their extensible architecture that makes projects like this possible, and the [other open-source projects](#prior-work) that provide vital functionality and reference architecture.
214
+
215
+ **Q: Are you a company? A bot?**
216
+ <br/>
217
+ **A:** Just [a person](https://github.com/themattspiral)! This started as a hobby project to improve my own AssemblyScript testing workflow and learn something about WASM internals, and it's grown from there. I use Claude Code for initial scaffolding and to help dig into the native instrumentation side in particular, but everything goes through me, and my intention is to contribute something useful and high-quality to the community. Feedback and contributions are welcome.
218
+
219
+ ---
220
+
165
221
  ## Compatibility
166
222
 
167
223
  | Dependency | Supported Versions |
168
224
  |---|---|
169
225
  | Node.js | (20*), 22, 24+ |
170
- | Vitest | 3.2.x, 4.x |
171
- | AssemblyScript | 0.28+ |
226
+ | Vitest | 3.2.x, 4.x.x |
227
+ | AssemblyScript | 0.28.9+ ([more?](#frequently-asked-questions)) |
172
228
 
173
229
  >ℹ️ ***Node 20 Support:** If you don't need code coverage, Node 20 should continue to work for test execution.
174
230
  >
175
- >WASM coverage instrumentation is implemented using WebAssembly [multi-memory](https://github.com/WebAssembly/multi-memory) to isolate coverage counters from user test memory. This feature shipped in V8 12.0 / Node 22.
231
+ >WASM coverage instrumentation is implemented using [WebAssembly multi-memory](https://github.com/WebAssembly/multi-memory) to isolate coverage counters from user test memory. This feature shipped in V8 12.0 / Node 22.
176
232
 
177
233
  **Platforms with prebuilt native binaries for coverage instrumentation & debug info:**
178
234
 
@@ -190,8 +246,8 @@ npx vitest run
190
246
  Import `test`, `describe`, `expect` from `vitest-pool-assemblyscript/assembly`. These functions are designed to follow the vitest API as closely as possible, so that everything is familiar and easy to reason about.
191
247
 
192
248
  - `it` is available as an alias for `test`
193
- - `describe` and `test` have inline modifiers to quickly change their status (see below)
194
- - `TestOptions` allows per-test inline configuration of additional options
249
+ - `describe` and `test` have inline modifiers to quickly change their run mode (see below)
250
+ - `TestOptions` allows per-test inline configuration of additional options (aligned with vitest behavior)
195
251
 
196
252
  ```typescript
197
253
  import { test, it, describe, expect, TestOptions } from "vitest-pool-assemblyscript/assembly";
@@ -215,17 +271,29 @@ describe("a suite of math operations", () => {
215
271
  });
216
272
  ```
217
273
 
218
- ### Inline Modifiers: `.skip`, `.only`, `.fails`
274
+ ### Inline Run Mode Modifiers: `.skip`, `.only`, `.fails`
275
+
276
+ These modify the way in which tests run in relation to each other, and/or how they report results.
277
+
278
+ They follow vitest JS-pool behavior.
219
279
 
220
280
  ```typescript
221
- test.skip("not ready yet", () => { /* ... */ });
281
+ test.skip("not ready yet", () => {
282
+ // test will register it exists, show as skipped
283
+ });
222
284
 
223
- test.only("run only this test", () => { /* ... */ });
285
+ test.only("debugging this test", () => {
286
+ // test will run by itself in this file
287
+ });
224
288
 
225
- test.fails("expected to fail, so will actually pass", () => {
289
+ test.fails("conditions are expected to fail, so test will actually pass", () => {
226
290
  expect(false).toBeTruthy();
227
291
  });
228
292
 
293
+ test.fails("conditions are expected to fail but do not, so test will actually fail", () => {
294
+ expect(true).toBeTruthy();
295
+ });
296
+
229
297
  describe.skip("entire suite skipped", () => { /* ... */ });
230
298
 
231
299
  describe.only("only this suite runs", () => { /* ... */ });
@@ -233,9 +301,10 @@ describe.only("only this suite runs", () => { /* ... */ });
233
301
 
234
302
  ### Inline Test Options
235
303
 
236
- `TestOptions` provides chainable configuration for `timeout`, `retry`, `skip`, `only`, and `fails`.
304
+ `TestOptions` provides chainable configuration for the vitest behavioral options: `timeout`, `retry`, `skip`, `only`, and `fails`
305
+ - While you define them slightly differently in AssemblyScript than JavaScript, their behavior matches the same options in vitest
237
306
  - Options can be placed before or after the callback
238
- - Suite options are inherited by nested tests and suites
307
+ - Suite options (in `describe`) are inherited by nested tests and nested suites
239
308
 
240
309
  ```typescript
241
310
  // options before callback
@@ -261,12 +330,16 @@ test.fails("expected failure with retry", TestOptions.retry(3), () => {
261
330
  });
262
331
  ```
263
332
 
264
- See the [Matchers API documentation](docs/matchers-api.md) for details on the available `expect()` methods you can use within your tests.
265
-
266
333
  ### Lifecycle Hooks (Setup & Teardown)
267
334
 
268
335
  Coming Soon!
269
336
 
337
+ ### Test Matchers
338
+
339
+ We aim to follow the [vitest/jest `expect()` API](https://vitest.dev/api/expect.html) as closely as possible, with some necessary differences given AssemblyScript's static-typing.
340
+
341
+ See the AssemblyScript Pool [Matchers API documentation](docs/matchers-api.md) for details on the available `expect()` methods you can use within your tests.
342
+
270
343
  ---
271
344
 
272
345
  ## Current Limitations & Roadmap
@@ -314,16 +387,16 @@ These are known limitations which are currently being worked on.
314
387
 
315
388
  ## Performance
316
389
 
317
- Efforts have been made to compile and run tests as quickly as possible:
318
- - Separate compile and test execution thread pools, workers, and runners for quicker startup and respawn
319
- - Compile threads tuned to take advantage of significant Node V8 engine warmup time savings on consecutive AssemblyScript compilations
390
+ Many efforts have been made to compile and run tests as quickly as possible. Some optimizations that have been most useful:
391
+ - Separate compile and test execution thread pools, worker thread entry points, and runners for quicker startup and thread respawn after test timeouts
392
+ - Compile threads tuned to take advantage of significant Node V8 engine warmup time savings on consecutive AssemblyScript compilations (this is an ongoing investigation as I want to see how it behaves when scaled up significantly)
320
393
  - In-memory compiled files and source maps to eliminate intermediate disk I/O
321
394
  - Enforced hard timeouts for long-running WASM tests via thread termination, with intelligent resume
322
395
 
323
- As such, it is capable of compiling dozens of test files comprising hundreds of tests in a few seconds.
396
+ As such, it is capable of compiling dozens of test files comprising hundreds of tests in a few seconds, and is likely faster on your machine than mine:
324
397
 
325
398
  <p align="center">
326
- <img src="docs/images/example-fixtures-suite.gif" alt="vitest-pool-assemblyscript demo">
399
+ <img src="docs/images/example-fixtures-suite.gif" alt="vitest-pool-assemblyscript large suite performance demo">
327
400
  </p>
328
401
 
329
402
  ---
@@ -332,15 +405,16 @@ As such, it is capable of compiling dozens of test files comprising hundreds of
332
405
 
333
406
  There are several core pieces of software without which this project would not be possible.
334
407
 
335
- - This project makes direct use of the [AssemblyScript language](https://www.assemblyscript.org) and its fantastic [compiler](https://www.assemblyscript.org/compiler.html)
336
- - Thanks to the [Vitest team](https://github.com/vitest-dev) for creating the framework in the first place and making it pluggable for different runtimes. Their internal pools were used as extensive reference in early phase development.
337
- - The key component that allows us to perform WASM instrumentation is [Binaryen](https://github.com/WebAssembly/binaryen), a C++ toolchain infrastructure library for WebAssembly.
338
- - Particular gratitude is owed to [assemblyscript-unittest-framework](https://github.com/wasm-ecosystem/assemblyscript-unittest-framework) for inspiring parts of our test discovery and instrumentation walking approaches.
408
+ - This project makes direct use of the [AssemblyScript language](https://www.assemblyscript.org) and its fantastic [compiler](https://www.assemblyscript.org/compiler.html). AS is a joy to work with when it comes to WASM because it's so familiar to everyday TypeScript usage.
409
+ - The key component that allows us to perform WASM instrumentation is [Binaryen](https://github.com/WebAssembly/binaryen), a C++ toolchain infrastructure library for WebAssembly. We started by using the fantastic [binaryen.js](https://github.com/AssemblyScript/binaryen.js/) - a JS port also from the folks behind AssemblyScript, and eventually migrated to the native library for some advanced source-map regeneration features.
410
+ - Thanks to the [Vitest team](https://github.com/vitest-dev) for creating the framework in the first place and making it extensible for different runtimes. Their internal pools were used as reference throughout development.
411
+ - Thanks to [`@cloudflare/vitest-pool-workers`](https://github.com/cloudflare/workers-sdk/tree/main/packages/vitest-pool-workers) for providing the leading example of a 3rd party vitest custom pool out in the wild.
412
+ - Particular gratitude is also owed to [assemblyscript-unittest-framework](https://github.com/wasm-ecosystem/assemblyscript-unittest-framework) for inspiring our test discovery and instrumentation expression-walking approaches.
339
413
 
340
414
  ---
341
415
 
342
416
  ## License
343
417
 
344
- [MIT](LICENSE)
345
- - Portions of this software have been derived from third-party works which are licenced under different terms. Individual code contributions have been noted where applicable and are accompanied by their respective licenses.
346
- - See the license file and source code for details
418
+ Licensed under the [MIT](LICENSE)
419
+
420
+ Portions of this software have been derived from third-party works which are licenced under different terms. These uses have been noted and are accompanied by their respective licenses in the [project license](LICENSE) and/or in applicable source code.
package/binding.gyp CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "targets": [
3
3
  {
4
- "target_name": "wasm_binaryen_debug",
4
+ "target_name": "wasm_binaryen_debug_instrumenter",
5
5
  "sources": [
6
- "src/native-instrumentation/addon.cpp"
6
+ "src/instrumentation/native/addon.cpp"
7
7
  ],
8
8
  "include_dirs": [
9
9
  # node-addon-api C++ headers (N-API wrapper)
@@ -27,7 +27,7 @@
27
27
  "-lpthread"
28
28
  ],
29
29
  # Enable C++ exceptions (node-gyp disables them by default)
30
- "cflags_cc": ["-std=c++20", "-fexceptions", "-O3"],
30
+ "cflags_cc": ["-std=c++17", "-fexceptions", "-O3"],
31
31
  "cflags!": ["-fno-exceptions"],
32
32
  "cflags_cc!": ["-fno-exceptions"]
33
33
  }],
@@ -38,9 +38,9 @@
38
38
  "xcode_settings": {
39
39
  "GCC_ENABLE_CPP_EXCEPTIONS": "YES",
40
40
  "CLANG_CXX_LIBRARY": "libc++",
41
- # Minimum macOS deployment target for C++20 support
41
+ # Minimum macOS deployment target for C++17 support
42
42
  "MACOSX_DEPLOYMENT_TARGET": "10.15",
43
- "OTHER_CPLUSPLUSFLAGS": ["-std=c++20", "-fexceptions", "-O3"]
43
+ "OTHER_CPLUSPLUSFLAGS": ["-std=c++17", "-fexceptions", "-O3"]
44
44
  }
45
45
  }],
46
46
  ["OS=='win'", {
@@ -52,7 +52,7 @@
52
52
  "VCCLCompilerTool": {
53
53
  # Enable C++ exception handling (/EHsc)
54
54
  "ExceptionHandling": 1,
55
- "AdditionalOptions": ["/std:c++20"]
55
+ "AdditionalOptions": ["/std:c++17", "/permissive"]
56
56
  }
57
57
  }
58
58
  }]
@@ -1,13 +1,12 @@
1
1
  import { INTERNAL_PATH_LIB_PREFIX, POOL_ERROR_NAMES } from "./constants-DuBLuMjt.mjs";
2
- import { createPoolError, debug, throwPoolErrorIfAborted } from "./debug-Cm1VFmaz.mjs";
3
- import { getShortFunctionName } from "./wasm-names-CydfYzQK.mjs";
2
+ import { createPoolError, debug } from "./debug-Cm1VFmaz.mjs";
3
+ import { toForwardSlash } from "./path-utils-t9OzjXYF.mjs";
4
+ import { getShortFunctionName } from "./wasm-names-BFtzQCH4.mjs";
4
5
  import { createRequire } from "node:module";
5
- import { basename, dirname, resolve } from "node:path";
6
- import { access, readFile } from "node:fs/promises";
7
- import { main } from "assemblyscript/asc";
6
+ import { dirname, resolve } from "node:path";
8
7
  import { fileURLToPath } from "node:url";
9
8
 
10
- //#region src/native-instrumentation/addon-interface.ts
9
+ //#region src/instrumentation/addon-interface.ts
11
10
  /**
12
11
  * Native addon interface for extracting debug information from WebAssembly binaries
13
12
  *
@@ -29,7 +28,7 @@ try {
29
28
  try {
30
29
  addon = nodeGypBuild(rootFromSrc);
31
30
  } catch (err) {
32
- throw createPoolError(`Native addon not found. Searched from ${rootFromDist} and ${rootFromSrc}. Ensure prebuilds are available or run 'npm run build:native' to compile from source. Original error: ${err instanceof Error ? err.message : String(err)}`, POOL_ERROR_NAMES.WASMInstrumentationError);
31
+ throw createPoolError(`vitest-pool-assemblyscript native instrumentation addon not found. Searched from ${rootFromDist} and ${rootFromSrc}. Ensure prebuilds are available or run 'node node_modules/vitest-pool-assemblyscript/scripts/install.js' to compile from source. Original error: ${err instanceof Error ? err.message : String(err)}`, POOL_ERROR_NAMES.WASMInstrumentationError);
33
32
  }
34
33
  }
35
34
  /**
@@ -46,8 +45,8 @@ try {
46
45
  function convertLocation(rawLocation, debugSourceFiles, projectRoot) {
47
46
  let filePath = debugSourceFiles[rawLocation.fileIndex];
48
47
  if (!filePath) throw createPoolError(`No debug source file with index: ${rawLocation.fileIndex}}`, POOL_ERROR_NAMES.WASMInstrumentationError);
49
- if (filePath.startsWith(INTERNAL_PATH_LIB_PREFIX)) filePath = resolve(projectRoot, "assembly", filePath.slice(INTERNAL_PATH_LIB_PREFIX.length));
50
- else filePath = resolve(projectRoot, filePath);
48
+ if (filePath.startsWith(INTERNAL_PATH_LIB_PREFIX)) filePath = toForwardSlash(resolve(projectRoot, "assembly", filePath.slice(INTERNAL_PATH_LIB_PREFIX.length)));
49
+ else filePath = toForwardSlash(resolve(projectRoot, filePath));
51
50
  return {
52
51
  filePath,
53
52
  line: rawLocation.line,
@@ -172,7 +171,7 @@ function transformDebugInfo(raw, logPrefix, projectRoot) {
172
171
  * @throws {TypeError} If wasmBuffer or sourceMapBuffer are not Buffers
173
172
  * @throws {Error} If WASM binary or source map is invalid
174
173
  */
175
- function instrumentForCoverage(wasmBuffer, sourceMapBuffer, instrumentationOptions, logModule, logLabel) {
174
+ const instrumentForCoverage = (wasmBuffer, sourceMapBuffer, instrumentationOptions, logModule, logLabel) => {
176
175
  if (!Buffer.isBuffer(wasmBuffer)) throw createPoolError("instrumentForCoverage - wasmBuffer must be a Buffer", POOL_ERROR_NAMES.WASMInstrumentationError);
177
176
  if (!Buffer.isBuffer(sourceMapBuffer)) throw createPoolError("instrumentForCoverage - sourceMapBuffer must be a Buffer", POOL_ERROR_NAMES.WASMInstrumentationError);
178
177
  const interfaceLogPrefix = `[${logModule} Inst] ${logLabel}`;
@@ -200,136 +199,8 @@ function instrumentForCoverage(wasmBuffer, sourceMapBuffer, instrumentationOptio
200
199
  sourceMap: nativeResult.sourceMap,
201
200
  debugInfo
202
201
  };
203
- }
204
-
205
- //#endregion
206
- //#region src/compiler/index.ts
207
- /**
208
- * AssemblyScript Compiler
209
- *
210
- * Handles compilation of AssemblyScript source code to WASM binaries.
211
- * Manages compiler options, transforms, and in-memory compilation.
212
- */
213
- const POOL_ASSEMBLY_NODE_MODULES_PREFIX = "node_modules/vitest-pool-assemblyscript/assembly/";
214
- const STRIP_INLINE_TRANSFORM = resolve(import.meta.dirname, "./compiler/transforms/strip-inline.mjs");
215
- setImmediate(async () => {
216
- try {
217
- await access(STRIP_INLINE_TRANSFORM);
218
- } catch {
219
- throw createPoolError(`AS Compiler strip inline transform file not found at "${STRIP_INLINE_TRANSFORM}"`, POOL_ERROR_NAMES.CompilationError);
220
- }
221
- });
222
- /**
223
- * Compile AssemblyScript source code to WASM binary
224
- */
225
- async function compileAssemblyScript(filename, options, logModule, logLabel, signal) {
226
- throwPoolErrorIfAborted(signal);
227
- const compileStart = performance.now();
228
- const logPrefix = `[${logModule} ASC] ${logLabel}`;
229
- const { shouldInstrument, instrumentationOptions, extraFlags } = options;
230
- if (shouldInstrument && !instrumentationOptions) throw createPoolError("Instrumentation options are required for coverage instrumentation", POOL_ERROR_NAMES.CompilationError);
231
- const stdoutLines = [];
232
- const stderrLines = [];
233
- let binary;
234
- let sourceMap;
235
- const entryFile = filename;
236
- const outputFile = "output.wasm";
237
- debug(`${logPrefix} - Compiling: "${filename}"`);
238
- const stdout = { write: (text) => {
239
- stdoutLines.push(text);
240
- return true;
241
- } };
242
- const stderr = { write: (text) => {
243
- stderrLines.push(text);
244
- return true;
245
- } };
246
- const compilerFlags = [
247
- entryFile,
248
- "--optimizeLevel",
249
- "0",
250
- "--shrinkLevel",
251
- "0",
252
- "--runtime",
253
- "stub",
254
- ...extraFlags || [],
255
- "--outFile",
256
- outputFile,
257
- "--importMemory",
258
- "--debug",
259
- "--sourceMap",
260
- "--exportStart",
261
- "_start",
262
- "--exportTable"
263
- ];
264
- if (options.stripInline === true) {
265
- compilerFlags.push("--transform", STRIP_INLINE_TRANSFORM);
266
- debug(`${logPrefix} - Added Transform - Stripping @inline decorators`);
267
- }
268
- const ascStart = performance.now();
269
- const result = await main(compilerFlags, {
270
- stdout,
271
- stderr,
272
- writeFile: (name, contents, _baseDir) => {
273
- throwPoolErrorIfAborted(signal);
274
- if (name.endsWith(".wasm") && contents instanceof Uint8Array) {
275
- binary = contents;
276
- debug(`${logPrefix} - Captured binary in memory: "${name}"`);
277
- } else if (name.endsWith(".wasm.map") && typeof contents === "string") {
278
- debug(`${logPrefix} - Captured source map in memory: "${name}"`);
279
- sourceMap = contents;
280
- } else debug(`${logPrefix} - WARNING - Captured Unexpected File: "${name}" at baseDir: "${_baseDir}"`);
281
- },
282
- readFile: async (filename, baseDir) => {
283
- const filePath = resolve(baseDir, filename);
284
- try {
285
- return await readFile(filePath, { encoding: "utf-8" });
286
- } catch {
287
- if (filename.startsWith(POOL_ASSEMBLY_NODE_MODULES_PREFIX)) {
288
- const localPath = resolve(baseDir, "assembly", filename.substring(49));
289
- try {
290
- return await readFile(localPath, { encoding: "utf-8" });
291
- } catch {
292
- return null;
293
- }
294
- }
295
- return null;
296
- }
297
- }
298
- });
299
- debug(`${logPrefix} - TIMING asc.main: ${(performance.now() - ascStart).toFixed(2)} ms`);
300
- if (result.error) {
301
- const errorMessage = stderrLines.length > 0 ? `${result.error.message}\n\n${stderrLines.join("")}` : result.error.message;
302
- throw createPoolError(errorMessage, POOL_ERROR_NAMES.CompilationError, errorMessage);
303
- }
304
- if (!binary) throw createPoolError(stderrLines.length > 0 ? `No WASM binary was generated\n\nAS Compiler output:\n${stderrLines.join("")}` : "No WASM binary was generated", POOL_ERROR_NAMES.CompilationError);
305
- if (!sourceMap) throw createPoolError("Source map not captured from AssemblyScript Compiler", POOL_ERROR_NAMES.CompilationError);
306
- const cleanBinary = binary;
307
- const wasmSourceMap = sourceMap;
308
- debug(`${logPrefix} - Compilation successful, clean binary size: ${cleanBinary.length} bytes`);
309
- debug(`${logPrefix} - Source map generated, size: ${wasmSourceMap.length * 2} bytes`);
310
- if (options.shouldInstrument) {
311
- throwPoolErrorIfAborted(signal);
312
- const instrumentStart = performance.now();
313
- const instrumentResult = instrumentForCoverage(Buffer.from(cleanBinary), Buffer.from(wasmSourceMap), options.instrumentationOptions, logModule, logLabel);
314
- const instCount = instrumentResult.debugInfo.instrumentedFunctionCount;
315
- const instrumentEnd = performance.now();
316
- debug(`${logPrefix} - TIMING Instrumented ${instCount} functions: ${(performance.now() - instrumentStart).toFixed(2)} ms`);
317
- return {
318
- binary: instrumentResult.instrumentedWasm,
319
- sourceMap: instrumentResult.sourceMap,
320
- debugInfo: instrumentResult.debugInfo,
321
- isInstrumented: true,
322
- compileTiming: instrumentEnd - compileStart
323
- };
324
- }
325
- return {
326
- binary: cleanBinary,
327
- sourceMap: wasmSourceMap,
328
- isInstrumented: false,
329
- compileTiming: performance.now() - compileStart
330
- };
331
- }
202
+ };
332
203
 
333
204
  //#endregion
334
- export { compileAssemblyScript };
335
- //# sourceMappingURL=compiler-CscxCJw3.mjs.map
205
+ export { instrumentForCoverage };
206
+ //# sourceMappingURL=addon-interface-7FPjYh7J.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addon-interface-7FPjYh7J.mjs","names":[],"sources":["../src/instrumentation/addon-interface.ts"],"sourcesContent":["/**\n * Native addon interface for extracting debug information from WebAssembly binaries\n *\n * This module wraps Binaryen's C++ API to provide expression-level debug locations\n * and basic block information that the JavaScript API doesn't expose.\n *\n * The native addon outputs raw data (0-based columns, relative paths) which this\n * wrapper transforms into the final BinaryDebugInfo format (1-based columns,\n * absolute paths, grouped by file and position).\n */\n\nimport { createRequire } from 'node:module';\nimport { resolve, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport type {\n NativeAddon,\n NativeInstrumentationResult,\n NativeDebugInfoOutput,\n NativeFunctionDebugInfo,\n NativeExpressionDebugInfo,\n NativeSourceLocation,\n BinaryDebugInfo,\n FunctionDebugInfo,\n SourceLocation,\n ExpressionDebugInfo,\n InstrumentationResult,\n NativeInstrumentationOptions,\n InstrumentationOptions,\n InstrumentForCoverageFunc,\n} from '../types/types.js';\nimport { POOL_ERROR_NAMES, INTERNAL_PATH_LIB_PREFIX } from '../types/constants.js';\nimport { debug } from '../util/debug.js';\nimport { toForwardSlash } from '../util/path-utils.js';\nimport { createPoolError } from '../util/pool-errors.js';\nimport { getShortFunctionName } from '../wasm-executor/wasm-names.js';\n\n// Load the native addon via node-gyp-build\n// node-gyp-build checks: prebuilds/ first, then build/Release/\n// It searches from the given directory for a package.json to find the package root.\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst rootFromDist = resolve(__dirname, '..');\n// TODO: Verify if this src fallback is still needed — pool always runs from dist/ even locally.\n// If confirmed dead code, remove this and simplify to a single nodeGypBuild call.\nconst rootFromSrc = resolve(__dirname, '../..');\n\nconst require = createRequire(import.meta.url);\nconst nodeGypBuild: (dir: string) => NativeAddon = require('node-gyp-build');\n\nlet addon: NativeAddon;\ntry {\n addon = nodeGypBuild(rootFromDist);\n} catch {\n try {\n addon = nodeGypBuild(rootFromSrc);\n } catch (err) {\n throw createPoolError(\n `vitest-pool-assemblyscript native instrumentation addon not found. Searched from ${rootFromDist} and ${rootFromSrc}. `\n + `Ensure prebuilds are available or run 'node node_modules/vitest-pool-assemblyscript/scripts/install.js'`\n + ` to compile from source. Original error: ${err instanceof Error ? err.message : String(err)}`,\n POOL_ERROR_NAMES.WASMInstrumentationError\n );\n }\n}\n\n/**\n * Convert a raw location (0-indexed columns, path indexes) to\n * processed location (1-indexed columns, absolute path strings)\n *\n * Source map paths vary by import style and project structure:\n * - Relative imports: \"assembly/compare.ts\"\n * - Bare package imports: \"~lib/vitest-pool-assemblyscript/assembly/compare.ts\"\n * - Source outside project root: \"../assembly/compare.ts\" (e.g. test-external importing parent sources)\n *\n * All are normalized to absolute filesystem paths for consistent coverage key matching.\n */\nfunction convertLocation(\n rawLocation: NativeSourceLocation,\n debugSourceFiles: string[],\n projectRoot: string\n): SourceLocation {\n let filePath = debugSourceFiles[rawLocation.fileIndex];\n\n if (!filePath) {\n throw createPoolError(\n `No debug source file with index: ${rawLocation.fileIndex}}`,\n POOL_ERROR_NAMES.WASMInstrumentationError\n );\n }\n\n // Normalize to absolute path for consistent coverage key matching\n if (filePath.startsWith(INTERNAL_PATH_LIB_PREFIX)) {\n // ~lib/vitest-pool-assemblyscript/assembly/X.ts -> projectRoot/assembly/X.ts\n const relativePart = filePath.slice(INTERNAL_PATH_LIB_PREFIX.length);\n filePath = toForwardSlash(resolve(projectRoot, 'assembly', relativePart));\n } else {\n // Resolve relative path (handles both 'assembly/X.ts' and '../assembly/X.ts')\n filePath = toForwardSlash(resolve(projectRoot, filePath));\n }\n\n return {\n filePath,\n line: rawLocation.line,\n column: rawLocation.column + 1, // convert from 0-indexed to 1-indexed\n };\n}\n\n/**\n * Convert a raw expression to processed format\n */\nfunction convertExpression(\n rawExpr: NativeExpressionDebugInfo,\n debugSourceFiles: string[],\n projectRoot: string\n): ExpressionDebugInfo {\n const converted: ExpressionDebugInfo = {\n type: rawExpr.type,\n isBranch: rawExpr.isBranch,\n };\n\n if (rawExpr.branchPaths !== undefined) {\n converted.branchPaths = rawExpr.branchPaths;\n }\n\n if (rawExpr.location) {\n const convertedLocation = convertLocation(rawExpr.location, debugSourceFiles, projectRoot);\n if (convertedLocation) {\n converted.location = convertedLocation;\n }\n }\n\n return converted;\n}\n\n/**\n * Generate a position key to identify the SourceLocation uniquely\n * within a file. Does NOT include the file identifier.\n */\nfunction getPositionKey(location: SourceLocation) {\n return `${location.line}:${location.column}`;\n}\n\n/**\n * Convert a raw function to processed format and compute position key\n * Returns undefined if function has no valid representative location\n */\nfunction convertFunction(\n rawFunc: NativeFunctionDebugInfo,\n debugSourceFiles: string[],\n projectRoot: string\n): { func: FunctionDebugInfo; filePath: string; positionKey: string } | undefined {\n const representativeLocation = convertLocation(rawFunc.representativeLocation, debugSourceFiles, projectRoot);\n\n // Convert expressions\n const expressions: ExpressionDebugInfo[] = [];\n if (rawFunc.expressions) {\n for (const expr of rawFunc.expressions) {\n expressions.push(convertExpression(expr, debugSourceFiles, projectRoot));\n }\n }\n\n const converted: FunctionDebugInfo = {\n wasmIndex: rawFunc.wasmIndex,\n name: rawFunc.name,\n representativeLocation,\n coverageMemoryIndex: rawFunc.coverageMemoryIndex,\n expressions,\n basicBlocks: rawFunc.basicBlocks,\n };\n\n const filePath = representativeLocation.filePath;\n const positionKey = getPositionKey(representativeLocation);\n\n return { func: converted, filePath, positionKey };\n}\n\n/**\n * Check if two WASM function names are monomorphizations of the same generic function.\n * Generic monomorphizations share the same base name and suffix, differing only in\n * the type parameters inside angle brackets.\n *\n * e.g. \"assembly/compare/closeTo<bool\\2cbool>\" and \"assembly/compare/closeTo<bool\\2cu8>\"\n * e.g. \"assembly/expect/BaseExpectMatcher<bool>#constructor\" and \"assembly/expect/BaseExpectMatcher<i8>#constructor\"\n */\nfunction isGenericMonomorphizationMatch(nameA: string, nameB: string): boolean {\n const openA = nameA.indexOf('<');\n const openB = nameB.indexOf('<');\n\n // Both must contain generic type parameters\n if (openA === -1 || openB === -1) return false;\n\n const lastCloseA = nameA.lastIndexOf('>');\n const lastCloseB = nameB.lastIndexOf('>');\n\n if (lastCloseA === -1 || lastCloseB === -1) return false;\n\n // Prefix before '<' must match (includes module path, class, function name)\n const prefixA = nameA.substring(0, openA);\n const prefixB = nameB.substring(0, openB);\n if (prefixA !== prefixB) return false;\n\n // Suffix after last '>' must match (e.g. \"#constructor\", or empty)\n const suffixA = nameA.substring(lastCloseA + 1);\n const suffixB = nameB.substring(lastCloseB + 1);\n if (suffixA !== suffixB) return false;\n\n return true;\n}\n\n/**\n * Transform raw native addon output to processed BinaryDebugInfo\n */\nfunction transformDebugInfo(\n raw: NativeDebugInfoOutput,\n logPrefix: string,\n projectRoot: string,\n): BinaryDebugInfo {\n const functionsByFileAndPosition: Record<string, Record<string, FunctionDebugInfo[]>> = {};\n\n debug(`${logPrefix} - Converting ${raw.functions.length} functions`);\n\n let genericCollisionCount = 0;\n let skippedCount = 0;\n let instrumentedFunctionCount = 0;\n\n for (const rawFunc of raw.functions) {\n const result = convertFunction(rawFunc, raw.debugSourceFiles, projectRoot);\n if (!result) {\n debug(`${logPrefix} - WARNING: Skipped function (bad conversion): \"${rawFunc.name}\"`);\n skippedCount++;\n continue;\n }\n\n const { func, filePath, positionKey } = result;\n\n // Check for position collisions\n const existingAtPosition = functionsByFileAndPosition[filePath]?.[positionKey];\n if (existingAtPosition) {\n const existingName = existingAtPosition[0]!.name;\n\n // Only allow collision if both are monomorphizations of the same generic\n if (isGenericMonomorphizationMatch(existingName, func.name)) {\n existingAtPosition.push(func);\n genericCollisionCount++;\n instrumentedFunctionCount++;\n debug(\n `${logPrefix} - Generic monomorphization at ${filePath}:${positionKey}:`\n + ` \"${getShortFunctionName(func.name)}\" grouped with \"${getShortFunctionName(existingName)}\"`\n );\n continue;\n }\n\n throw createPoolError(\n `ERROR - Function Debug Position Collision at ${filePath}:${positionKey}: \"${getShortFunctionName(existingName)}\"`\n + ` will be replaced by \"${getShortFunctionName(func.name)}\". This is a bug. Please report it at:`\n + ` https://github.com/themattspiral/vitest-pool-assemblyscript/issues/new`,\n POOL_ERROR_NAMES.WASMInstrumentationError\n );\n }\n\n instrumentedFunctionCount++;\n\n // Group by file and position\n if (!functionsByFileAndPosition[filePath]) {\n functionsByFileAndPosition[filePath] = {};\n }\n\n functionsByFileAndPosition[filePath][positionKey] = [func];\n }\n\n debug(\n `${logPrefix} - BinaryDebugInfo transform complete: ${instrumentedFunctionCount} instrumented functions`\n + ` (${genericCollisionCount} generic collisions, ${skippedCount} skipped)`\n );\n\n return {\n debugSourceFiles: raw.debugSourceFiles,\n functionsByFileAndPosition,\n instrumentedFunctionCount,\n };\n}\n\n/**\n * Instrument a WASM binary for coverage collection and regenerate source map\n *\n * This function:\n * 1. Adds __coverage_memory import (multi-memory for coverage counters)\n * 2. Injects coverage counter increments at each function entry\n * 3. Regenerates source map with correct offsets after instrumentation\n * 4. Extracts debug info with coverageMemoryIndex assigned\n *\n * @param wasmBuffer - Buffer containing the clean WASM binary\n * @param sourceMapBuffer - Buffer containing the source map JSON\n * @returns Instrumented binary, regenerated source map, and debug info\n *\n * @throws {TypeError} If wasmBuffer or sourceMapBuffer are not Buffers\n * @throws {Error} If WASM binary or source map is invalid\n */\nexport const instrumentForCoverage: InstrumentForCoverageFunc = (\n wasmBuffer: Buffer,\n sourceMapBuffer: Buffer,\n instrumentationOptions: InstrumentationOptions,\n logModule: string,\n logLabel: string,\n): InstrumentationResult => {\n if (!Buffer.isBuffer(wasmBuffer)) {\n throw createPoolError(\n 'instrumentForCoverage - wasmBuffer must be a Buffer',\n POOL_ERROR_NAMES.WASMInstrumentationError\n );\n }\n if (!Buffer.isBuffer(sourceMapBuffer)) {\n throw createPoolError(\n 'instrumentForCoverage - sourceMapBuffer must be a Buffer',\n POOL_ERROR_NAMES.WASMInstrumentationError\n );\n }\n\n const interfaceLogPrefix = `[${logModule} Inst] ${logLabel}`;\n const nativeLogPrefix = `[${logModule} InstNative] ${logLabel}`;\n\n debug(`${interfaceLogPrefix} - Calling native instrumentForCoverage`);\n const startTime = performance.now();\n\n const options: NativeInstrumentationOptions = {\n coverageMemoryPagesMin: instrumentationOptions.coverageMemoryPagesMin,\n coverageMemoryPagesMax: instrumentationOptions.coverageMemoryPagesMax,\n excludedFiles: instrumentationOptions.relativeExcludedFiles,\n excludedLibraryFilePrefix: instrumentationOptions.excludedLibraryFilePrefix,\n excludedLibraryFileOverridePrefix: instrumentationOptions.excludedLibraryFileOverridePrefix,\n debug: instrumentationOptions.debug,\n logPrefix: nativeLogPrefix\n };\n const nativeResult: NativeInstrumentationResult = addon.instrumentForCoverage(wasmBuffer, sourceMapBuffer, options);\n const addonTime = performance.now();\n debug(`${interfaceLogPrefix} - TIMING Native addon: ${(addonTime - startTime).toFixed(2)} ms`);\n\n if (nativeResult.errors?.length) {\n throw createPoolError(\n `Errors encountered duriing native instrumentation: ${nativeResult.errors.join('\\n')}`,\n POOL_ERROR_NAMES.WASMInstrumentationError,\n );\n }\n\n const debugInfo = transformDebugInfo(nativeResult.debugInfo, interfaceLogPrefix, instrumentationOptions.projectRoot);\n \n const transformTime = performance.now();\n debug(`${interfaceLogPrefix} - TIMING DebugInfo Transform: ${(transformTime - addonTime).toFixed(2)} ms`);\n debug(`${interfaceLogPrefix} - Binary size: ${nativeResult.instrumentedWasm.length} bytes | Source map size: ${nativeResult.sourceMap.length * 2} bytes`);\n\n return {\n instrumentedWasm: nativeResult.instrumentedWasm,\n sourceMap: nativeResult.sourceMap,\n debugInfo,\n };\n}\n"],"mappings":"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"}
@@ -307,4 +307,4 @@ var ASTVisitor = class {
307
307
 
308
308
  //#endregion
309
309
  export { ASTVisitor };
310
- //# sourceMappingURL=ast-visitor-DJLJd5dt.mjs.map
310
+ //# sourceMappingURL=ast-visitor-C5gQqWD2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ast-visitor-DJLJd5dt.mjs","names":[],"sources":["../src/util/ast-visitor.ts"],"sourcesContent":["/**\n * Base AST Visitor for AssemblyScript\n *\n * Provides reusable walking logic for traversing AS AST nodes.\n * Subclasses override hook methods to perform specific tasks.\n *\n * Used by:\n * - ast-parser.ts: Extract function metadata for coverage\n * - strip-inline.mts: Strip @inline decorators\n */\n\nimport {\n Node,\n Source,\n BlockStatement,\n FunctionDeclaration,\n MethodDeclaration,\n ClassDeclaration,\n NamespaceDeclaration,\n VariableStatement,\n VariableDeclaration,\n FunctionExpression,\n ExpressionStatement,\n BinaryExpression,\n PropertyAccessExpression,\n IfStatement,\n WhileStatement,\n DoStatement,\n ForStatement,\n ForOfStatement,\n SwitchStatement,\n SwitchCase,\n TryStatement,\n ThrowStatement,\n ReturnStatement,\n CallExpression,\n NewExpression,\n ParenthesizedExpression,\n TernaryExpression,\n CommaExpression,\n AssertionExpression,\n InstanceOfExpression,\n ElementAccessExpression,\n UnaryPostfixExpression,\n UnaryPrefixExpression,\n ClassExpression,\n ParameterNode,\n EnumDeclaration,\n EnumValueDeclaration,\n FieldDeclaration,\n InterfaceDeclaration,\n VoidStatement,\n} from 'assemblyscript';\n\nimport { ASNodeKind } from '../types/constants.js';\n\n/**\n * Abstract base class for AST visitors.\n *\n * Subclasses override hook methods to perform tasks during traversal:\n * - beforeVisit: Called before visiting each node (e.g., strip decorators)\n * - onFunctionDeclaration: Called when visiting a function declaration\n * - onMethodDeclaration: Called when visiting a method declaration\n * - onVariableDeclaration: Called when visiting a variable declaration\n * - onClassEnter/onClassExit: Called when entering/exiting a class\n */\nexport abstract class ASTVisitor {\n /**\n * Visit all statements in a source file\n */\n visitSource(source: Source): void {\n for (const stmt of source.statements) {\n this.visitNode(stmt);\n }\n }\n\n /**\n * Hook called before visiting each node.\n * Override to perform pre-visit tasks (e.g., stripping decorators).\n */\n protected beforeVisit(_node: Node): void {}\n\n /**\n * Hook called when entering a class declaration.\n * Override to track class context.\n */\n protected onClassEnter(_node: ClassDeclaration): void {}\n\n /**\n * Hook called when exiting a class declaration.\n * Override to restore class context.\n */\n protected onClassExit(_node: ClassDeclaration): void {}\n\n /**\n * Hook called when visiting a function declaration.\n * Override to extract function info or perform other tasks.\n * Return false to skip recursing into the function body.\n */\n protected onFunctionDeclaration(_node: FunctionDeclaration): boolean {\n return true; // Continue recursion by default\n }\n\n /**\n * Hook called when visiting a method declaration.\n * Override to extract method info or perform other tasks.\n * Return false to skip recursing into the method body.\n */\n protected onMethodDeclaration(_node: MethodDeclaration): boolean {\n return true; // Continue recursion by default\n }\n\n /**\n * Hook called when visiting a variable declaration.\n * Override to handle variable declarations (e.g., arrow functions).\n * Return false to skip recursing into the initializer.\n */\n protected onVariableDeclaration(_node: VariableDeclaration): boolean {\n return true; // Continue recursion by default\n }\n\n /**\n * Main visitor dispatch - routes to specific handler based on node kind\n */\n visitNode(node: Node): void {\n // Call pre-visit hook\n this.beforeVisit(node);\n\n // Recurse into children based on node kind\n switch (node.kind) {\n // Type nodes - no children to visit\n case ASNodeKind.NamedType:\n case ASNodeKind.FunctionType:\n case ASNodeKind.TypeName:\n case ASNodeKind.TypeParameter:\n break;\n\n // Parameter - may have default value\n case ASNodeKind.Parameter: {\n const param = node as ParameterNode;\n if (param.initializer) this.visitNode(param.initializer);\n break;\n }\n\n // Simple expressions - no children\n case ASNodeKind.Identifier:\n case ASNodeKind.False:\n case ASNodeKind.Literal:\n case ASNodeKind.Null:\n case ASNodeKind.Omitted:\n case ASNodeKind.Super:\n case ASNodeKind.This:\n case ASNodeKind.True:\n case ASNodeKind.Constructor:\n case ASNodeKind.Compiled:\n break;\n\n // Expressions with children\n case ASNodeKind.Assertion: {\n const expr = node as AssertionExpression;\n this.visitNode(expr.expression);\n break;\n }\n case ASNodeKind.Binary: {\n const expr = node as BinaryExpression;\n this.visitNode(expr.left);\n this.visitNode(expr.right);\n break;\n }\n case ASNodeKind.Call: {\n const expr = node as CallExpression;\n this.visitNode(expr.expression);\n for (const arg of expr.args) this.visitNode(arg);\n break;\n }\n case ASNodeKind.Class: {\n const expr = node as ClassExpression;\n this.visitNode(expr.declaration);\n break;\n }\n case ASNodeKind.Comma: {\n const expr = node as CommaExpression;\n for (const e of expr.expressions) this.visitNode(e);\n break;\n }\n case ASNodeKind.ElementAccess: {\n const expr = node as ElementAccessExpression;\n this.visitNode(expr.expression);\n this.visitNode(expr.elementExpression);\n break;\n }\n case ASNodeKind.Function: {\n const expr = node as FunctionExpression;\n this.visitNode(expr.declaration);\n break;\n }\n case ASNodeKind.InstanceOf: {\n const expr = node as InstanceOfExpression;\n this.visitNode(expr.expression);\n break;\n }\n case ASNodeKind.New: {\n const expr = node as NewExpression;\n for (const arg of expr.args) this.visitNode(arg);\n break;\n }\n case ASNodeKind.Parenthesized: {\n const expr = node as ParenthesizedExpression;\n this.visitNode(expr.expression);\n break;\n }\n case ASNodeKind.PropertyAccess: {\n const expr = node as PropertyAccessExpression;\n this.visitNode(expr.expression);\n break;\n }\n case ASNodeKind.Ternary: {\n const expr = node as TernaryExpression;\n this.visitNode(expr.condition);\n this.visitNode(expr.ifThen);\n this.visitNode(expr.ifElse);\n break;\n }\n case ASNodeKind.UnaryPostfix: {\n const expr = node as UnaryPostfixExpression;\n this.visitNode(expr.operand);\n break;\n }\n case ASNodeKind.UnaryPrefix: {\n const expr = node as UnaryPrefixExpression;\n this.visitNode(expr.operand);\n break;\n }\n\n // Statements with no interesting children\n case ASNodeKind.Break:\n case ASNodeKind.Continue:\n case ASNodeKind.Empty:\n case ASNodeKind.Export:\n case ASNodeKind.ExportDefault:\n case ASNodeKind.ExportImport:\n case ASNodeKind.Import:\n case ASNodeKind.Module:\n break;\n\n // Statements with children\n case ASNodeKind.Block: {\n const stmt = node as BlockStatement;\n for (const s of stmt.statements) this.visitNode(s);\n break;\n }\n case ASNodeKind.Do: {\n const stmt = node as DoStatement;\n this.visitNode(stmt.body);\n this.visitNode(stmt.condition);\n break;\n }\n case ASNodeKind.Expression: {\n const stmt = node as ExpressionStatement;\n this.visitNode(stmt.expression);\n break;\n }\n case ASNodeKind.For: {\n const stmt = node as ForStatement;\n if (stmt.initializer) this.visitNode(stmt.initializer);\n if (stmt.condition) this.visitNode(stmt.condition);\n if (stmt.incrementor) this.visitNode(stmt.incrementor);\n this.visitNode(stmt.body);\n break;\n }\n case ASNodeKind.ForOf: {\n const stmt = node as ForOfStatement;\n this.visitNode(stmt.variable);\n this.visitNode(stmt.iterable);\n this.visitNode(stmt.body);\n break;\n }\n case ASNodeKind.If: {\n const stmt = node as IfStatement;\n this.visitNode(stmt.condition);\n this.visitNode(stmt.ifTrue);\n if (stmt.ifFalse) this.visitNode(stmt.ifFalse);\n break;\n }\n case ASNodeKind.Return: {\n const stmt = node as ReturnStatement;\n if (stmt.value) this.visitNode(stmt.value);\n break;\n }\n case ASNodeKind.Switch: {\n const stmt = node as SwitchStatement;\n this.visitNode(stmt.condition);\n for (const switchCase of stmt.cases) this.visitNode(switchCase);\n break;\n }\n case ASNodeKind.Throw: {\n const stmt = node as ThrowStatement;\n this.visitNode(stmt.value);\n break;\n }\n case ASNodeKind.Try: {\n const stmt = node as TryStatement;\n for (const s of stmt.bodyStatements) this.visitNode(s);\n if (stmt.catchStatements) {\n for (const s of stmt.catchStatements) this.visitNode(s);\n }\n if (stmt.finallyStatements) {\n for (const s of stmt.finallyStatements) this.visitNode(s);\n }\n break;\n }\n case ASNodeKind.Variable: {\n const stmt = node as VariableStatement;\n for (const decl of stmt.declarations) this.visitNode(decl);\n break;\n }\n case ASNodeKind.Void: {\n const stmt = node as VoidStatement;\n this.visitNode(stmt.expression);\n break;\n }\n case ASNodeKind.While: {\n const stmt = node as WhileStatement;\n this.visitNode(stmt.condition);\n this.visitNode(stmt.body);\n break;\n }\n case ASNodeKind.SwitchCase: {\n const stmt = node as SwitchCase;\n if (stmt.label) this.visitNode(stmt.label);\n for (const s of stmt.statements) this.visitNode(s);\n break;\n }\n\n // Declaration statements\n case ASNodeKind.ImportDeclaration:\n case ASNodeKind.TypeDeclaration:\n break;\n\n case ASNodeKind.ClassDeclaration: {\n const decl = node as ClassDeclaration;\n this.onClassEnter(decl);\n for (const member of decl.members) this.visitNode(member);\n this.onClassExit(decl);\n break;\n }\n case ASNodeKind.EnumDeclaration: {\n const decl = node as EnumDeclaration;\n for (const value of decl.values) this.visitNode(value);\n break;\n }\n case ASNodeKind.EnumValueDeclaration: {\n const decl = node as EnumValueDeclaration;\n if (decl.initializer) this.visitNode(decl.initializer);\n break;\n }\n case ASNodeKind.FieldDeclaration: {\n const decl = node as FieldDeclaration;\n if (decl.initializer) this.visitNode(decl.initializer);\n break;\n }\n case ASNodeKind.FunctionDeclaration: {\n const decl = node as FunctionDeclaration;\n const shouldRecurse = this.onFunctionDeclaration(decl);\n if (shouldRecurse && decl.body) this.visitNode(decl.body);\n break;\n }\n case ASNodeKind.InterfaceDeclaration: {\n const decl = node as InterfaceDeclaration;\n for (const member of decl.members) this.visitNode(member);\n break;\n }\n case ASNodeKind.MethodDeclaration: {\n const decl = node as MethodDeclaration;\n const shouldRecurse = this.onMethodDeclaration(decl);\n if (shouldRecurse && decl.body) this.visitNode(decl.body);\n break;\n }\n case ASNodeKind.NamespaceDeclaration: {\n const decl = node as NamespaceDeclaration;\n for (const member of decl.members) this.visitNode(member);\n break;\n }\n case ASNodeKind.VariableDeclaration: {\n const decl = node as VariableDeclaration;\n const shouldRecurse = this.onVariableDeclaration(decl);\n if (shouldRecurse && decl.initializer) this.visitNode(decl.initializer);\n break;\n }\n\n // Special nodes - no action needed\n case ASNodeKind.ExportMember:\n case ASNodeKind.IndexSignature:\n case ASNodeKind.Comment:\n case ASNodeKind.Decorator:\n break;\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ast-visitor-C5gQqWD2.mjs","names":[],"sources":["../src/util/ast-visitor.ts"],"sourcesContent":["/**\n * Base AST Visitor for AssemblyScript\n *\n * Provides reusable walking logic for traversing AS AST nodes.\n * Subclasses override hook methods to perform specific tasks.\n *\n * Used by:\n * - ast-parser.ts: Extract function metadata for coverage\n * - strip-inline.mts: Strip @inline decorators\n */\n\nimport {\n Node,\n Source,\n BlockStatement,\n FunctionDeclaration,\n MethodDeclaration,\n ClassDeclaration,\n NamespaceDeclaration,\n VariableStatement,\n VariableDeclaration,\n FunctionExpression,\n ExpressionStatement,\n BinaryExpression,\n PropertyAccessExpression,\n IfStatement,\n WhileStatement,\n DoStatement,\n ForStatement,\n ForOfStatement,\n SwitchStatement,\n SwitchCase,\n TryStatement,\n ThrowStatement,\n ReturnStatement,\n CallExpression,\n NewExpression,\n ParenthesizedExpression,\n TernaryExpression,\n CommaExpression,\n AssertionExpression,\n InstanceOfExpression,\n ElementAccessExpression,\n UnaryPostfixExpression,\n UnaryPrefixExpression,\n ClassExpression,\n ParameterNode,\n EnumDeclaration,\n EnumValueDeclaration,\n FieldDeclaration,\n InterfaceDeclaration,\n VoidStatement,\n} from 'assemblyscript';\n\nimport { ASNodeKind } from '../types/constants.js';\n\n/**\n * Abstract base class for AST visitors.\n *\n * Subclasses override hook methods to perform tasks during traversal:\n * - beforeVisit: Called before visiting each node (e.g., strip decorators)\n * - onFunctionDeclaration: Called when visiting a function declaration\n * - onMethodDeclaration: Called when visiting a method declaration\n * - onVariableDeclaration: Called when visiting a variable declaration\n * - onClassEnter/onClassExit: Called when entering/exiting a class\n */\nexport abstract class ASTVisitor {\n /**\n * Visit all statements in a source file\n */\n visitSource(source: Source): void {\n for (const stmt of source.statements) {\n this.visitNode(stmt);\n }\n }\n\n /**\n * Hook called before visiting each node.\n * Override to perform pre-visit tasks (e.g., stripping decorators).\n */\n protected beforeVisit(_node: Node): void {}\n\n /**\n * Hook called when entering a class declaration.\n * Override to track class context.\n */\n protected onClassEnter(_node: ClassDeclaration): void {}\n\n /**\n * Hook called when exiting a class declaration.\n * Override to restore class context.\n */\n protected onClassExit(_node: ClassDeclaration): void {}\n\n /**\n * Hook called when visiting a function declaration.\n * Override to extract function info or perform other tasks.\n * Return false to skip recursing into the function body.\n */\n protected onFunctionDeclaration(_node: FunctionDeclaration): boolean {\n return true; // Continue recursion by default\n }\n\n /**\n * Hook called when visiting a method declaration.\n * Override to extract method info or perform other tasks.\n * Return false to skip recursing into the method body.\n */\n protected onMethodDeclaration(_node: MethodDeclaration): boolean {\n return true; // Continue recursion by default\n }\n\n /**\n * Hook called when visiting a variable declaration.\n * Override to handle variable declarations (e.g., arrow functions).\n * Return false to skip recursing into the initializer.\n */\n protected onVariableDeclaration(_node: VariableDeclaration): boolean {\n return true; // Continue recursion by default\n }\n\n /**\n * Main visitor dispatch - routes to specific handler based on node kind\n */\n visitNode(node: Node): void {\n // Call pre-visit hook\n this.beforeVisit(node);\n\n // Recurse into children based on node kind\n switch (node.kind) {\n // Type nodes - no children to visit\n case ASNodeKind.NamedType:\n case ASNodeKind.FunctionType:\n case ASNodeKind.TypeName:\n case ASNodeKind.TypeParameter:\n break;\n\n // Parameter - may have default value\n case ASNodeKind.Parameter: {\n const param = node as ParameterNode;\n if (param.initializer) this.visitNode(param.initializer);\n break;\n }\n\n // Simple expressions - no children\n case ASNodeKind.Identifier:\n case ASNodeKind.False:\n case ASNodeKind.Literal:\n case ASNodeKind.Null:\n case ASNodeKind.Omitted:\n case ASNodeKind.Super:\n case ASNodeKind.This:\n case ASNodeKind.True:\n case ASNodeKind.Constructor:\n case ASNodeKind.Compiled:\n break;\n\n // Expressions with children\n case ASNodeKind.Assertion: {\n const expr = node as AssertionExpression;\n this.visitNode(expr.expression);\n break;\n }\n case ASNodeKind.Binary: {\n const expr = node as BinaryExpression;\n this.visitNode(expr.left);\n this.visitNode(expr.right);\n break;\n }\n case ASNodeKind.Call: {\n const expr = node as CallExpression;\n this.visitNode(expr.expression);\n for (const arg of expr.args) this.visitNode(arg);\n break;\n }\n case ASNodeKind.Class: {\n const expr = node as ClassExpression;\n this.visitNode(expr.declaration);\n break;\n }\n case ASNodeKind.Comma: {\n const expr = node as CommaExpression;\n for (const e of expr.expressions) this.visitNode(e);\n break;\n }\n case ASNodeKind.ElementAccess: {\n const expr = node as ElementAccessExpression;\n this.visitNode(expr.expression);\n this.visitNode(expr.elementExpression);\n break;\n }\n case ASNodeKind.Function: {\n const expr = node as FunctionExpression;\n this.visitNode(expr.declaration);\n break;\n }\n case ASNodeKind.InstanceOf: {\n const expr = node as InstanceOfExpression;\n this.visitNode(expr.expression);\n break;\n }\n case ASNodeKind.New: {\n const expr = node as NewExpression;\n for (const arg of expr.args) this.visitNode(arg);\n break;\n }\n case ASNodeKind.Parenthesized: {\n const expr = node as ParenthesizedExpression;\n this.visitNode(expr.expression);\n break;\n }\n case ASNodeKind.PropertyAccess: {\n const expr = node as PropertyAccessExpression;\n this.visitNode(expr.expression);\n break;\n }\n case ASNodeKind.Ternary: {\n const expr = node as TernaryExpression;\n this.visitNode(expr.condition);\n this.visitNode(expr.ifThen);\n this.visitNode(expr.ifElse);\n break;\n }\n case ASNodeKind.UnaryPostfix: {\n const expr = node as UnaryPostfixExpression;\n this.visitNode(expr.operand);\n break;\n }\n case ASNodeKind.UnaryPrefix: {\n const expr = node as UnaryPrefixExpression;\n this.visitNode(expr.operand);\n break;\n }\n\n // Statements with no interesting children\n case ASNodeKind.Break:\n case ASNodeKind.Continue:\n case ASNodeKind.Empty:\n case ASNodeKind.Export:\n case ASNodeKind.ExportDefault:\n case ASNodeKind.ExportImport:\n case ASNodeKind.Import:\n case ASNodeKind.Module:\n break;\n\n // Statements with children\n case ASNodeKind.Block: {\n const stmt = node as BlockStatement;\n for (const s of stmt.statements) this.visitNode(s);\n break;\n }\n case ASNodeKind.Do: {\n const stmt = node as DoStatement;\n this.visitNode(stmt.body);\n this.visitNode(stmt.condition);\n break;\n }\n case ASNodeKind.Expression: {\n const stmt = node as ExpressionStatement;\n this.visitNode(stmt.expression);\n break;\n }\n case ASNodeKind.For: {\n const stmt = node as ForStatement;\n if (stmt.initializer) this.visitNode(stmt.initializer);\n if (stmt.condition) this.visitNode(stmt.condition);\n if (stmt.incrementor) this.visitNode(stmt.incrementor);\n this.visitNode(stmt.body);\n break;\n }\n case ASNodeKind.ForOf: {\n const stmt = node as ForOfStatement;\n this.visitNode(stmt.variable);\n this.visitNode(stmt.iterable);\n this.visitNode(stmt.body);\n break;\n }\n case ASNodeKind.If: {\n const stmt = node as IfStatement;\n this.visitNode(stmt.condition);\n this.visitNode(stmt.ifTrue);\n if (stmt.ifFalse) this.visitNode(stmt.ifFalse);\n break;\n }\n case ASNodeKind.Return: {\n const stmt = node as ReturnStatement;\n if (stmt.value) this.visitNode(stmt.value);\n break;\n }\n case ASNodeKind.Switch: {\n const stmt = node as SwitchStatement;\n this.visitNode(stmt.condition);\n for (const switchCase of stmt.cases) this.visitNode(switchCase);\n break;\n }\n case ASNodeKind.Throw: {\n const stmt = node as ThrowStatement;\n this.visitNode(stmt.value);\n break;\n }\n case ASNodeKind.Try: {\n const stmt = node as TryStatement;\n for (const s of stmt.bodyStatements) this.visitNode(s);\n if (stmt.catchStatements) {\n for (const s of stmt.catchStatements) this.visitNode(s);\n }\n if (stmt.finallyStatements) {\n for (const s of stmt.finallyStatements) this.visitNode(s);\n }\n break;\n }\n case ASNodeKind.Variable: {\n const stmt = node as VariableStatement;\n for (const decl of stmt.declarations) this.visitNode(decl);\n break;\n }\n case ASNodeKind.Void: {\n const stmt = node as VoidStatement;\n this.visitNode(stmt.expression);\n break;\n }\n case ASNodeKind.While: {\n const stmt = node as WhileStatement;\n this.visitNode(stmt.condition);\n this.visitNode(stmt.body);\n break;\n }\n case ASNodeKind.SwitchCase: {\n const stmt = node as SwitchCase;\n if (stmt.label) this.visitNode(stmt.label);\n for (const s of stmt.statements) this.visitNode(s);\n break;\n }\n\n // Declaration statements\n case ASNodeKind.ImportDeclaration:\n case ASNodeKind.TypeDeclaration:\n break;\n\n case ASNodeKind.ClassDeclaration: {\n const decl = node as ClassDeclaration;\n this.onClassEnter(decl);\n for (const member of decl.members) this.visitNode(member);\n this.onClassExit(decl);\n break;\n }\n case ASNodeKind.EnumDeclaration: {\n const decl = node as EnumDeclaration;\n for (const value of decl.values) this.visitNode(value);\n break;\n }\n case ASNodeKind.EnumValueDeclaration: {\n const decl = node as EnumValueDeclaration;\n if (decl.initializer) this.visitNode(decl.initializer);\n break;\n }\n case ASNodeKind.FieldDeclaration: {\n const decl = node as FieldDeclaration;\n if (decl.initializer) this.visitNode(decl.initializer);\n break;\n }\n case ASNodeKind.FunctionDeclaration: {\n const decl = node as FunctionDeclaration;\n const shouldRecurse = this.onFunctionDeclaration(decl);\n if (shouldRecurse && decl.body) this.visitNode(decl.body);\n break;\n }\n case ASNodeKind.InterfaceDeclaration: {\n const decl = node as InterfaceDeclaration;\n for (const member of decl.members) this.visitNode(member);\n break;\n }\n case ASNodeKind.MethodDeclaration: {\n const decl = node as MethodDeclaration;\n const shouldRecurse = this.onMethodDeclaration(decl);\n if (shouldRecurse && decl.body) this.visitNode(decl.body);\n break;\n }\n case ASNodeKind.NamespaceDeclaration: {\n const decl = node as NamespaceDeclaration;\n for (const member of decl.members) this.visitNode(member);\n break;\n }\n case ASNodeKind.VariableDeclaration: {\n const decl = node as VariableDeclaration;\n const shouldRecurse = this.onVariableDeclaration(decl);\n if (shouldRecurse && decl.initializer) this.visitNode(decl.initializer);\n break;\n }\n\n // Special nodes - no action needed\n case ASNodeKind.ExportMember:\n case ASNodeKind.IndexSignature:\n case ASNodeKind.Comment:\n case ASNodeKind.Decorator:\n break;\n }\n }\n}\n"],"mappings":"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"}