File: 00004-add-ast-path-info-to-visitor.md

package info (click to toggle)
rust-swc-core 35.0.0~ds-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 62,816 kB
  • sloc: javascript: 873; xml: 538; sh: 358; makefile: 35; python: 5
file content (51 lines) | stat: -rw-r--r-- 2,116 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# Provide more information to visitor methods

-   Status: accepted <!-- optional -->
-   Deciders: @kdy1, @kwonoj <!-- optional -->
-   Date: 2022-06-30 <!-- optional -->

## Context and Problem Statement

Currently one can't get any information about parent node.
This is due to ownership restriction of rust.
We can't pass a reference to the parent to a visitor method.
Let's say we have a `CallExpr`, and we are now going to call `visit_mut_callee` from `visit_mut_call_expr`.
We want `&mut callee`, because it's the signature of `visit_mut_callee`.
So we **borrow it from CallExpr**.
As we mutabily borrowed something from `CallExpr`, we cannot pass `&CallExpr` to `visit_mut_callee`.

We can workaround this by

-   taking `CallExpr.callee`
-   call `visit_mut_callee(&mut self, callee: &mut Callee, parent: &CallExpr)`, with dummy callee in `parent.callee`.
-   restore the original callee from `visit_mut_call`.

But doing this by hand is error-prone and doing this automatically by codegen is costly.
This is explicit `memmove`, and `memmove` is quite costly.
SWC moved from `Fold` to `VisitMut` because of `mmemove`.

## Decision Drivers

-   Help plugin authors writing plugins.

## Considered Options

-   [option 1] Stay with as-is.

-   [option 2] Provide full information using `unsafe`.

-   **[option 3] Provide small amount of information .**

We will expose the spans and kinds of the parent ast nodes for `VisitMut` and `Fold`, while passing an enum with parent data for `Visit`.
This difference is related to the restriction above.
This is the exact problem rust is trying to solve, and we don't want to violate the rules of rust.

## Decision Outcome

Chosen option: **[option 3] Provide small amount of information .**

This decision is taken because

-   It's too hard to **port** plugins, because a plugin author has to recreate logic instead of porting, if the original babel plugin uses parent node information.
-   Using `unsafe` in public API requires more discussion.
-   We don't have good debugging api for plugins at the moment, so using `unsafe` in plugins is strongly discourages.