Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(swc/core): introduce swc_core package #5364

Merged
merged 12 commits into from
Aug 2, 2022
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"]
kdy1 marked this conversation as resolved.
Show resolved Hide resolved

## 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"))]
kdy1 marked this conversation as resolved.
Show resolved Hide resolved
#[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;
Copy link
Member

Choose a reason for hiding this comment

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

Same here


/// 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