2021-11-15 07:26:04 +03:00
# SWC architecture
2018-12-04 09:11:50 +03:00
2021-11-15 07:26:04 +03:00
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.
2018-12-04 09:11:50 +03:00
## Macros
2021-11-15 07:26:04 +03:00
<!-- TODO: fix link -->
<!-- See [blog post about SWC macros ](https://swc.rs/blog/2020/01/04/pmutil#macros-built-with-pmutil ). -->
2020-01-23 12:39:04 +03:00
2021-11-15 07:26:04 +03:00
SWC uses proc macro extensively to reduce work. Please see links below to know what each macro do.
2018-12-04 09:11:50 +03:00
2021-11-15 07:26:04 +03:00
- [enum_kind][]
- [string_enum][]
- [ast_node][]
2018-12-04 09:11:50 +03:00
And some adhoc-macros are used.
2021-11-15 07:26:04 +03:00
- [parser_macros][]
- [codegen_macros][]
2018-12-04 09:11:50 +03:00
These macro breaks macro hygiene.
2020-01-23 12:39:04 +03:00
## Structure
2021-11-15 07:26:04 +03:00
### [`/crates/swc_atoms`](crates/swc_atoms)
2020-01-23 12:39:04 +03:00
2021-11-15 07:26:04 +03:00
Handle string interning for the SWC project. The crate depends on [string_cache ](https://github.com/servo/string-cache ) from servo.
2020-01-23 12:39:04 +03:00
2021-11-15 07:26:04 +03:00
### [`/crates/swc_common`](crates/swc_common)
2020-01-23 12:39:04 +03:00
Contains code related to span, hygiene and error reporting.
Also, it contains / re-exports codes for visitor pattern. `Visit<T>` is non-mutating visitor, while `Fold<T>` is a mutating visitor.
2021-11-15 07:26:04 +03:00
### [`/crates/swc_ecma_ast`](crates/swc_ecma_ast)
2020-01-23 12:39:04 +03:00
2021-11-15 07:26:04 +03:00
Contains AST nodes for javascript and typescript.
2020-01-23 12:39:04 +03:00
2021-11-15 07:26:04 +03:00
### [`/crates/swc_ecma_codegen`](crates/swc_ecma_codegen)
2020-01-23 12:39:04 +03:00
2021-11-15 07:26:04 +03:00
Converts javascript AST into javascript code.
2020-01-23 12:39:04 +03:00
2021-11-15 07:26:04 +03:00
### [`/crates/swc_ecma_parser`](crates/swc_ecma_parser)
2020-01-23 12:39:04 +03:00
2020-05-05 14:08:50 +03:00
Parses javascript and typescript
2020-01-23 12:39:04 +03:00
2021-11-15 07:26:04 +03:00
### [`/crates/swc_ecma_transforms_base`](crates/swc_ecma_transforms_base)
2020-01-23 12:39:04 +03:00
2021-11-16 13:31:02 +03:00
There are three core transforms named `resolver` , `hygiene` , `fixer` . Other transforms depend on them.
2020-01-23 12:39:04 +03:00
2021-11-15 07:26:04 +03:00
#### [`/crates/swc_ecma_transforms_base/src/resolver`](crates/swc_ecma_transforms_base/src/resolver)
2020-01-23 12:39:04 +03:00
This pass resolves and marks all identifiers in the file.
e.g.
```js
let a = 1;
{
2021-11-15 07:26:04 +03:00
let a = 1;
2020-01-23 12:39:04 +03:00
}
```
becomes
```js
let a#0 = 1;
{
let a#1 = 1;
}
```
2021-11-16 13:31:02 +03:00
where the number after the hash (`#`) denotes the hygiene id. If two identifiers have the same symbol but different hygiene ids, they are considered different.
2020-01-23 12:39:04 +03:00
2021-11-15 07:26:04 +03:00
#### [`/crates/swc_ecma_transforms_base/src/hygiene`](crates/swc_ecma_transforms_base/src/hygiene)
2020-01-23 12:39:04 +03:00
2021-11-16 13:31:02 +03:00
The hygiene pass actually changes symbols of identifiers with the same symbol but different hygiene ids to different symbols.
2020-01-23 12:39:04 +03:00
```js
let a#0 = 1;
{
let a#1 = 2;
}
```
becomes
```js
let a = 1;
{
2021-11-15 07:26:04 +03:00
let a1 = 2;
2020-01-23 12:39:04 +03:00
}
```
2021-11-15 07:26:04 +03:00
#### [`/crates/swc_ecma_transforms_base/src/fixer`](crates/swc_ecma_transforms_base/src/fixer)
2020-01-23 12:39:04 +03:00
2021-11-15 07:26:04 +03:00
Fixes broken AST. This allow us to simply fold types like `BinExpr` without caring about operator precedence.
2020-01-23 12:39:04 +03:00
It means,
```rust
let v = BinExpr {
left: "1 + 2",
op: "*",
right: "3",
};
```
2021-11-16 13:31:02 +03:00
(other passes generate AST like this)
2020-01-23 12:39:04 +03:00
is converted into
```rust
let v = BinExpr {
left: "(1 + 2)",
op: "*",
right: "3",
};
```
and printed as
```js
(1 + 2) * 3;
```
2021-11-15 07:26:04 +03:00
<!-- TODO: add correct references to files -->
<!-- #### `/ecmascript/transforms/src/compat`
2020-01-23 12:39:04 +03:00
2021-11-16 13:31:02 +03:00
Contains code related to converting new generation javascript code into code understood by old browsers.
2020-01-23 12:39:04 +03:00
#### `/ecmascript/transforms/src/modules`
Contains code related to transforming es6 modules to other modules.
#### `/ecmascript/transforms/src/optimization`
2021-11-16 13:31:02 +03:00
Contains code related to making code faster on runtime. Currently only a small set of optimizations is implemented. -->
2018-12-04 09:11:50 +03:00
## Tests
2021-11-15 07:26:04 +03:00
SWC uses the [official ecmascript conformance test suite called test262][test262] for testing.
2018-12-04 09:11:50 +03:00
2021-11-16 13:31:02 +03:00
Parser tests ensure that the parsed results of `test262/pass` are identical with `test262/pass-explicit` .
2018-12-04 09:11:50 +03:00
2021-11-16 13:31:02 +03:00
Codegen tests ensure that the generated code is equivalent to the golden fixture files located at [tests/references ](crates/swc_ecma_codegen/tests ).
2018-12-04 09:11:50 +03:00
2021-03-31 07:09:10 +03:00
[enum_kind]: https://rustdoc.swc.rs/enum_kind/derive.Kind.html
[string_enum]: https://rustdoc.swc.rs/string_enum/derive.StringEnum.html
[ast_node]: https://rustdoc.swc.rs/ast_node/index.html
[parser_macros]: https://rustdoc.swc.rs/swc_ecma_parser_macros/index.html
[codegen_macros]: https://rustdoc.swc.rs/swc_ecma_codegen_macros/index.html
2020-01-23 12:39:04 +03:00
[test262]: https://github.com/tc39/test262