Skip to content

Commit

Permalink
feat(swc_core): Introduce package (#5364)
Browse files Browse the repository at this point in the history
  • Loading branch information
kwonoj authored Aug 2, 2022
1 parent 366020b commit 27b464d
Show file tree
Hide file tree
Showing 17 changed files with 290 additions and 499 deletions.
22 changes: 16 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[workspace]
members = [
"crates/swc_core",
"crates/dbg-swc",
"crates/jsdoc",
"crates/binding_core_node",
Expand Down
87 changes: 87 additions & 0 deletions crates/swc_core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
[package]
authors = ["강동윤 <kdy1997.dev@gmail.com>", "OJ Kwon <kwon.ohjoong@gmail.com>"]
description = "TBD"
name = "swc_core"
license = "Apache-2.0"
edition = "2021"
repository = "https://github.com/swc-project/swc.git"
version = "0.0.1"

[features]
### Public features
### Users should opt in necessary features explicitly

## General
# Enable `quote!` macro support.
quote = ["swc_ecma_quote"]

## Plugins
# Top level features should be enabled to write plugins for the custom transform.
plugin_transform = [
# Dependent features
"__plugin_transform",
"__common",
"__ast",
"__visit",
"__plugin_transform_schema_v1",
# Enable optional packages
"swc_common/plugin-mode",
"swc_plugin_proxy/plugin-mode",
"swc_plugin_macro",
"swc_plugin",
"once_cell",
]

### Internal features that public features are relying on.
### This is not supposed to be used directly, and does not gaurantee
### stability across each versions.

# Specify version of AST schema will be used.
# This'll be automatically selected via transform_plugin features,
# SWC upstream decides which version to be used for specific version of
# swc_core.
__plugin_transform_schema_v1 = ["swc_common/plugin_transform_schema_v1"]

# Do not use: testing purpose only
__plugin_transform_schema_vtest = ["swc_common/plugin_transform_schema_vtest"]

## Plugins

# Internal flags for any transform plugin feature
__plugin_transform = []

# Do not use: testing purpose only
# Force enable different version of AST schema
__plugin_transform_schema_test = [
# Dependent features
"__plugin_transform",
"__common",
"__ast",
"__visit",
"__plugin_transform_schema_vtest",
# Enable optional packages
"swc_common/plugin-mode",
"swc_plugin_proxy/plugin-mode",
"swc_plugin_macro",
"swc_plugin",
"once_cell",
]

## Common
__common = ["swc_common"]

## TODO: Should this be public?
## AST
__ast = ["swc_ecma_ast/rkyv-impl", "swc_atoms"]
__visit = ["swc_ecma_visit"]

[dependencies]
once_cell = { optional = true, version = "1.13.0" }
swc_atoms = { optional = true, version = "0.3.1", path = "../swc_atoms" }
swc_common = { optional = true, version = "0.26.0", path = "../swc_common" }
swc_ecma_ast = { optional = true, version = "0.89.1", path = "../swc_ecma_ast" }
swc_ecma_quote = { optional = true, version = "0.30.0", path = "../swc_ecma_quote" }
swc_ecma_visit = { optional = true, version = "0.75.0", path = "../swc_ecma_visit" }
swc_plugin = { optional = true, version = "0.88.2", path = "../swc_plugin" }
swc_plugin_macro = { optional = true, version = "0.8.1", path = "../swc_plugin_macro" }
swc_plugin_proxy = { optional = true, version = "0.17.0", path = "../swc_plugin_proxy" }
37 changes: 37 additions & 0 deletions crates/swc_core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#![cfg_attr(docsrs, feature(doc_cfg))]

// Quote
#[cfg(any(docsrs, feature = "quote"))]
#[cfg_attr(docsrs, doc(cfg(feature = "quote")))]
pub mod quote {
pub use swc_ecma_quote::*;
}

// Plugins
#[cfg(any(docsrs, feature = "__plugin_transform"))]
#[cfg_attr(docsrs, doc(cfg(feature = "__plugin_transform")))]
pub mod plugin;

// ast exposed via swc_ecma_ast
// TODO: Can dependency tree simplified
// by swc_ecma_ast reexports swc_atoms?
#[cfg(any(docsrs, feature = "__ast"))]
#[cfg_attr(docsrs, doc(cfg(feature = "__ast")))]
pub mod ast {
pub use swc_atoms::*;
pub use swc_ecma_ast::*;
}

// visit* interfaces
#[cfg(any(docsrs, feature = "__visit"))]
#[cfg_attr(docsrs, doc(cfg(feature = "__visit")))]
pub mod visit {
pub use swc_ecma_visit::*;
}

// swc_common features
#[cfg(any(docsrs, feature = "__common"))]
#[cfg_attr(docsrs, doc(cfg(feature = "__common")))]
pub mod common {
pub use swc_common::*;
}
40 changes: 40 additions & 0 deletions crates/swc_core/src/plugin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// #[plugin_transform] macro
#[cfg(any(docsrs, feature = "__plugin_transform"))]
#[cfg_attr(docsrs, doc(cfg(feature = "__plugin_transform")))]
pub use swc_plugin_macro::plugin_transform;

/// exported __alloc / __free fn for the guest (plugin)
/// allows to allocate memory from the host side.
/// This should not be directly referenced.
#[cfg(all(feature = "__plugin_transform", target_arch = "wasm32"))]
pub mod memory {
pub use swc_plugin::allocation::*;
}

/// Global HANDLER implementation for the plugin
/// for error reporting.
#[cfg(any(docsrs, feature = "__plugin_transform"))]
#[cfg_attr(docsrs, doc(cfg(feature = "__plugin_transform")))]
pub mod errors {
/// global context HANDLER in plugin's transform function.
pub static HANDLER: swc_plugin::pseudo_scoped_key::PseudoScopedKey<
swc_common::errors::Handler,
> = swc_plugin::pseudo_scoped_key::PseudoScopedKey {
inner: once_cell::sync::OnceCell::new(),
};
}

/// Plugin's environment metadata context.
#[cfg(any(docsrs, feature = "__plugin_transform"))]
#[cfg_attr(docsrs, doc(cfg(feature = "__plugin_transform")))]
pub mod metadata {
pub use swc_common::plugin::metadata::TransformPluginMetadataContextKind;
pub use swc_plugin_proxy::TransformPluginProgramMetadata;
}

/// Proxy to the host's data not attached to the AST, like sourcemap / comments.
#[cfg(any(docsrs, feature = "__plugin_transform"))]
#[cfg_attr(docsrs, doc(cfg(feature = "__plugin_transform")))]
pub mod proxies {
pub use swc_plugin_proxy::*;
}
21 changes: 1 addition & 20 deletions crates/swc_plugin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,5 @@ rustdoc-args = ["--cfg", "docsrs"]
[lib]
bench = false

[features]
default = ["plugin_transform_schema_v1"]
quote = ["swc_ecma_quote"]
plugin_transform_schema_v1 = [
"swc_common/plugin_transform_schema_v1"
]
plugin_transform_schema_vtest = [
"swc_common/plugin_transform_schema_vtest",
]

[dependencies]
swc_atoms = { version = "0.3.1", path = "../swc_atoms" }
swc_common = { version = "0.26.0", path = "../swc_common", features = [
"plugin-mode",
] }
swc_ecma_quote = { version = "0.30.0", path = "../swc_ecma_quote", optional = true }
swc_ecmascript = { version = "0.186.0", path = "../swc_ecmascript", features = ["utils", "visit", "rkyv-impl"] }
swc_plugin_proxy = { version = "0.17.0", path = "../swc_plugin_proxy", features = [
"plugin-mode",
] }
swc_plugin_macro = { version = "0.8.1", path = "../swc_plugin_macro" }
once_cell = "1.13.0"
25 changes: 3 additions & 22 deletions crates/swc_plugin/README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,5 @@
# SWC Plugin
## swc_plugin (PUBLIC INTERFACE DEPRECATED)

This crate provides necessary types and macros for creating a custom plugin for SWC (https://swc.rs/), which are WebAssembly modules that may be used to modify behavior of SWC. Currently only `transform` (https://swc.rs/docs/usage/core#transform) is supported.
Provides internal implementation detail to communicate between `@swc/core` to the plugin.

**Disclaimer: currently SWC plugin support is experimental, there may be possible breaking changes or unexpected behaviors. Please provide issues, feedbacks to https://github.com/swc-project/swc/discussions .**

## Writing a plugin

All plugin require adding crate-type = ['cdylib'] to the Cargo.toml. For a quick setup, SWC provides a simple commandline to create project for the plugin.

```
// if you haven't, add build targets for webassembly
rustup target add wasm32-wasi wasm32-unknown-unknown
cargo install swc_cli
swc plugin new ${plugin_name} --target-type wasm32-wasi
```

When create a new project cli require to specify target type between `wasm32-wasi` or `wasm32-unknown-unknown`. `wasm32-unknown-unknown` will generate slighly smaller binary, but it doesn't support system interfaces as well as macros like `printn!()`.

Generated project will contain a fn with macro `#[plugin_transform]` which internally does necessary interop for communication between host to the plugin.

There are few references like SWC's [jest transform](https://github.com/swc-project/swc/blob/90d080c16b41b73f34151c1f5ecbcbf0b5d8e236/crates/swc_ecma_ext_transforms/src/jest.rs) for writing actual `VisitMut`.
NOTE: This was previously entrypoint sdk to authoring a plugin, but `swc_core` becomes a meta entrypoint to any features SWC provides (https://github.com/swc-project/swc/discussions/5244).
39 changes: 0 additions & 39 deletions crates/swc_plugin/src/handler.rs

This file was deleted.

73 changes: 2 additions & 71 deletions crates/swc_plugin/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,73 +1,4 @@
#![cfg_attr(docsrs, feature(doc_cfg))]

// Reexports
pub use swc_common::{
chain,
plugin::serialized::{
deserialize_from_ptr, PluginError, PluginSerializedBytes, VersionedSerializable,
PLUGIN_TRANSFORM_AST_SCHEMA_VERSION,
},
};

pub mod collections {
pub use swc_common::collections::AHashMap;
}

pub mod comments {
pub use swc_common::comments::{Comment, CommentKind, Comments};
pub use swc_plugin_proxy::PluginCommentsProxy;
}

pub mod source_map {
pub use swc_common::{
source_map::{
BytePos, CharPos, FileLinesResult, FileName, Loc, MultiByteChar, NonNarrowChar, Pos,
SourceFile,
},
SourceMapper,
};
pub use swc_plugin_proxy::PluginSourceMapProxy;
}

pub mod metadata {
pub use swc_common::plugin::metadata::TransformPluginMetadataContextKind;
pub use swc_plugin_proxy::TransformPluginProgramMetadata;
}

pub mod utils {
pub use swc_common::util::take;
#[cfg(feature = "swc_ecma_quote")]
#[cfg_attr(docsrs, doc(cfg(feature = "quote")))]
pub use swc_ecma_quote::*;
pub use swc_ecmascript::utils::*;
}

pub mod ast {
pub use swc_atoms::*;
pub use swc_ecmascript::{ast::*, visit::*};
}

pub mod syntax_pos {
pub use swc_common::{Mark, Span, DUMMY_SP};
}

mod handler;
pub mod errors {
pub use swc_common::errors::{Diagnostic, Handler, Level};

pub use crate::handler::HANDLER;
}

pub mod environment {
pub use crate::handler::*;
}
// We don't set target cfg as it'll block macro expansions
// in ide (i.e rust-analyzer) or non-wasm target `cargo check`
pub use swc_plugin_macro::plugin_transform;
#[cfg(target_arch = "wasm32")]
mod allocation;
#[cfg(target_arch = "wasm32")]
pub mod memory {
pub use crate::allocation::*;
}
mod pseudo_scoped_key;
pub mod allocation;
pub mod pseudo_scoped_key;
Loading

1 comment on commit 27b464d

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 27b464d Previous: daaa8b5 Ratio
es/full/minify/libraries/antd 1745833165 ns/iter (± 62065907) 1813581502 ns/iter (± 106750103) 0.96
es/full/minify/libraries/d3 410871011 ns/iter (± 27884111) 396120999 ns/iter (± 8316479) 1.04
es/full/minify/libraries/echarts 1518196306 ns/iter (± 74475302) 1535258765 ns/iter (± 164903332) 0.99
es/full/minify/libraries/jquery 113491192 ns/iter (± 24391088) 96940477 ns/iter (± 1635609) 1.17
es/full/minify/libraries/lodash 139043479 ns/iter (± 10363174) 123456291 ns/iter (± 3565693) 1.13
es/full/minify/libraries/moment 60881593 ns/iter (± 2637813) 62036012 ns/iter (± 6982853) 0.98
es/full/minify/libraries/react 20285733 ns/iter (± 957940) 20086452 ns/iter (± 1925103) 1.01
es/full/minify/libraries/terser 324772194 ns/iter (± 11440453) 334480838 ns/iter (± 22119047) 0.97
es/full/minify/libraries/three 571965654 ns/iter (± 14832627) 578036380 ns/iter (± 81714498) 0.99
es/full/minify/libraries/typescript 3666523974 ns/iter (± 151946524) 3641071016 ns/iter (± 129452488) 1.01
es/full/minify/libraries/victory 789342720 ns/iter (± 20323425) 792759241 ns/iter (± 28919613) 1.00
es/full/minify/libraries/vue 155003121 ns/iter (± 9039006) 141214183 ns/iter (± 20560684) 1.10
es/full/codegen/es3 33607 ns/iter (± 2928) 33266 ns/iter (± 933) 1.01
es/full/codegen/es5 33701 ns/iter (± 3163) 33359 ns/iter (± 880) 1.01
es/full/codegen/es2015 34179 ns/iter (± 3355) 33336 ns/iter (± 796) 1.03
es/full/codegen/es2016 33597 ns/iter (± 2342) 33464 ns/iter (± 895) 1.00
es/full/codegen/es2017 33386 ns/iter (± 1688) 33560 ns/iter (± 2168) 0.99
es/full/codegen/es2018 33411 ns/iter (± 1648) 33511 ns/iter (± 755) 1.00
es/full/codegen/es2019 33174 ns/iter (± 1856) 34022 ns/iter (± 1770) 0.98
es/full/codegen/es2020 33383 ns/iter (± 3193) 33383 ns/iter (± 1822) 1
es/full/all/es3 190958868 ns/iter (± 11081621) 233462438 ns/iter (± 27365764) 0.82
es/full/all/es5 178849753 ns/iter (± 8784592) 181918852 ns/iter (± 11462971) 0.98
es/full/all/es2015 152018213 ns/iter (± 10610750) 147907908 ns/iter (± 12241199) 1.03
es/full/all/es2016 161040571 ns/iter (± 16408600) 147519675 ns/iter (± 12409387) 1.09
es/full/all/es2017 161538716 ns/iter (± 16293025) 146666008 ns/iter (± 11285355) 1.10
es/full/all/es2018 155981811 ns/iter (± 16670009) 144447304 ns/iter (± 11351566) 1.08
es/full/all/es2019 153120599 ns/iter (± 24602453) 146779751 ns/iter (± 10019883) 1.04
es/full/all/es2020 138345438 ns/iter (± 10217647) 139987877 ns/iter (± 11257626) 0.99
es/full/parser 759847 ns/iter (± 28786) 779159 ns/iter (± 59933) 0.98
es/full/base/fixer 29255 ns/iter (± 2028) 29391 ns/iter (± 1918) 1.00
es/full/base/resolver_and_hygiene 89797 ns/iter (± 12935) 87616 ns/iter (± 6785) 1.02
serialization of ast node 217 ns/iter (± 8) 212 ns/iter (± 3) 1.02
serialization of serde 244 ns/iter (± 10) 237 ns/iter (± 6) 1.03

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.