1 | # swc architecture
|
2 |
|
3 | This document gives a high level overview of swc internals. You may find it useful if you want to contribute to swc or if you are interested in the inner workings of swc.
|
4 |
|
5 | ## Macros
|
6 |
|
7 | See [blog post about swc macros](https://swc-project.github.io/blog/2020/01/04/pmutil#macros-built-with-pmutil).
|
8 |
|
9 | swc uses proc macro extensively to reduce work. Please see links below to know what each macro do.
|
10 |
|
11 | - [enum_kind][]
|
12 | - [string_enum][]
|
13 | - [ast_node][]
|
14 |
|
15 | And some adhoc-macros are used.
|
16 |
|
17 | - [parser_macros][]
|
18 | - [codegen_macros][]
|
19 |
|
20 | These macro breaks macro hygiene.
|
21 |
|
22 | ## Structure
|
23 |
|
24 | ### `/atoms`
|
25 |
|
26 | Handle string interning for the swc project. The crate depends on [string_cache](https://github.com/servo/string-cache) from servo.
|
27 |
|
28 | ### `/common`
|
29 |
|
30 | Contains code related to span, hygiene and error reporting.
|
31 |
|
32 | Also, it contains / re-exports codes for visitor pattern. `Visit<T>` is non-mutating visitor, while `Fold<T>` is a mutating visitor.
|
33 |
|
34 | ### `/ecmascript/ast`
|
35 |
|
36 | Contains ast nodes for javascript and script.
|
37 |
|
38 | ### `/ecmascript/codegen`
|
39 |
|
40 | Converts javascript ast into javascript code.
|
41 |
|
42 | ### `/ecmascript/parser`
|
43 |
|
44 | Parses javascript and typescript
|
45 |
|
46 | ### `/ecmascript/transforms`
|
47 |
|
48 | Theres are three core transforms named `resolver`, `hygiene`, `fixer`. Other transforms depends on them.
|
49 |
|
50 | #### `/ecmascript/transforms/src/resolver`
|
51 |
|
52 | This pass resolves and marks all identifiers in the file.
|
53 |
|
54 | e.g.
|
55 |
|
56 | ```js
|
57 | let a = 1;
|
58 | {
|
59 | let a = 1;
|
60 | }
|
61 | ```
|
62 |
|
63 | becomes
|
64 |
|
65 | ```js
|
66 | let a#0 = 1;
|
67 | {
|
68 | let a#1 = 1;
|
69 | }
|
70 | ```
|
71 |
|
72 | where number after `#` denotes the hygiene id. If two identifiers have same symbol but different hygiene id, it's different.
|
73 |
|
74 | #### `/ecmascript/transforms/src/hygiene`
|
75 |
|
76 | Hygiene pass actually changes symbol of identifiers with same symbol but different hygiene id.
|
77 |
|
78 | ```js
|
79 | let a#0 = 1;
|
80 | {
|
81 | let a#1 = 2;
|
82 | }
|
83 | ```
|
84 |
|
85 | becomes
|
86 |
|
87 | ```js
|
88 | let a = 1;
|
89 | {
|
90 | let a1 = 2;
|
91 | }
|
92 | ```
|
93 |
|
94 | #### `/ecmascript/transforms/src/fixer`
|
95 |
|
96 | Fixes borken ast. This allow us to simply fold types like `BinExpr` without caring about operator precedence.
|
97 |
|
98 | It means,
|
99 |
|
100 | ```rust
|
101 | let v = BinExpr {
|
102 | left: "1 + 2",
|
103 | op: "*",
|
104 | right: "3",
|
105 | };
|
106 | ```
|
107 |
|
108 | (other passes generates ast like this)
|
109 |
|
110 | is converted into
|
111 |
|
112 | ```rust
|
113 | let v = BinExpr {
|
114 | left: "(1 + 2)",
|
115 | op: "*",
|
116 | right: "3",
|
117 | };
|
118 | ```
|
119 |
|
120 | and printed as
|
121 |
|
122 | ```js
|
123 | (1 + 2) * 3;
|
124 | ```
|
125 |
|
126 | #### `/ecmascript/transforms/src/compat`
|
127 |
|
128 | Contains codes related to converting new generation javascript codes for old browsers.
|
129 |
|
130 | #### `/ecmascript/transforms/src/modules`
|
131 |
|
132 | Contains code related to transforming es6 modules to other modules.
|
133 |
|
134 | #### `/ecmascript/transforms/src/optimization`
|
135 |
|
136 | Contains code related to making code faster on runtime. Currently only small set of optimization is implemented.
|
137 |
|
138 | ## Tests
|
139 |
|
140 | swc uses [official ecmascript conformance test suite called test262][test262] for testing.
|
141 |
|
142 | Parser tests ensures that parsed result of test262/pass is identical with test262/pass-explicit.
|
143 |
|
144 | Codegen tests ensures that generated code is equivalent to goldened reference files located at [tests/references](ecmascript/codegen/tests/references).
|
145 |
|
146 | [enum_kind]: https://swc-project.github.io/rustdoc/enum_kind/derive.Kind.html
|
147 | [string_enum]: https://swc-project.github.io/rustdoc/string_enum/derive.StringEnum.html
|
148 | [ast_node]: https://swc-project.github.io/rustdoc/ast_node/index.html
|
149 | [parser_macros]: https://swc-project.github.io/rustdoc/swc_ecma_parser_macros/index.html
|
150 | [codegen_macros]: https://swc-project.github.io/rustdoc/swc_ecma_codegen_macros/index.html
|
151 | [test262]: https://github.com/tc39/test262
|