mirror of
https://github.com/swc-project/swc.git
synced 2024-11-23 00:32:15 +03:00
feat(swc_core): Introduce package (#5364)
This commit is contained in:
parent
366020b18d
commit
27b464d90a
22
Cargo.lock
generated
22
Cargo.lock
generated
@ -3146,6 +3146,21 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_core"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_quote",
|
||||
"swc_ecma_visit",
|
||||
"swc_plugin",
|
||||
"swc_plugin_macro",
|
||||
"swc_plugin_proxy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_css"
|
||||
version = "0.117.0"
|
||||
@ -4120,12 +4135,7 @@ dependencies = [
|
||||
name = "swc_plugin"
|
||||
version = "0.88.2"
|
||||
dependencies = [
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
"swc_ecma_quote",
|
||||
"swc_ecmascript",
|
||||
"swc_plugin_macro",
|
||||
"swc_plugin_proxy",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1,5 +1,6 @@
|
||||
[workspace]
|
||||
members = [
|
||||
"crates/swc_core",
|
||||
"crates/dbg-swc",
|
||||
"crates/jsdoc",
|
||||
"crates/binding_core_node",
|
||||
|
87
crates/swc_core/Cargo.toml
Normal file
87
crates/swc_core/Cargo.toml
Normal file
@ -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
crates/swc_core/src/lib.rs
Normal file
37
crates/swc_core/src/lib.rs
Normal file
@ -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
crates/swc_core/src/plugin.rs
Normal file
40
crates/swc_core/src/plugin.rs
Normal file
@ -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::*;
|
||||
}
|
@ -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"
|
@ -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).
|
@ -1,39 +0,0 @@
|
||||
use swc_common::{
|
||||
plugin::serialized::{PluginSerializedBytes, VersionedSerializable},
|
||||
sync::OnceCell,
|
||||
};
|
||||
|
||||
use crate::pseudo_scoped_key::PseudoScopedKey;
|
||||
|
||||
#[cfg(target_arch = "wasm32")] // Allow testing
|
||||
extern "C" {
|
||||
fn __emit_diagnostics(bytes_ptr: i32, bytes_ptr_len: i32);
|
||||
fn __free(bytes_ptr: i32, size: i32) -> i32;
|
||||
}
|
||||
|
||||
/// An emitter for the Diagnostic in plugin's context by borrowing host's
|
||||
/// environment context.
|
||||
///
|
||||
/// It is not expected to call this directly inside of plugin transform.
|
||||
/// Instead, it is encouraged to use global HANDLER.
|
||||
pub struct PluginDiagnosticsEmitter;
|
||||
|
||||
impl swc_common::errors::Emitter for PluginDiagnosticsEmitter {
|
||||
#[cfg_attr(not(target_arch = "wasm32"), allow(unused))]
|
||||
fn emit(&mut self, db: &swc_common::errors::DiagnosticBuilder<'_>) {
|
||||
let diagnostic = VersionedSerializable::new((*db.diagnostic).clone());
|
||||
let diag = PluginSerializedBytes::try_serialize(&diagnostic)
|
||||
.expect("Should able to serialize Diagnostic");
|
||||
let (ptr, len) = diag.as_ptr();
|
||||
|
||||
#[cfg(target_arch = "wasm32")] // Allow testing
|
||||
unsafe {
|
||||
__emit_diagnostics(ptr as i32, len as i32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// global context HANDLER in plugin's transform function.
|
||||
pub static HANDLER: PseudoScopedKey = PseudoScopedKey {
|
||||
inner: OnceCell::new(),
|
||||
};
|
@ -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;
|
||||
|
@ -1,19 +1,21 @@
|
||||
use once_cell::sync::OnceCell;
|
||||
|
||||
/// Simple substitution for scoped_thread_local with limited interface parity.
|
||||
/// The only available fn in this struct is `with`, which is being used for the
|
||||
/// consumers when they need to access global scope handler (HANDLER.with()).
|
||||
/// Any other interfaces to support thread local is not available.
|
||||
pub struct PseudoScopedKey {
|
||||
pub struct PseudoScopedKey<T> {
|
||||
// As we can't use scoped_thread_local for the global HANDLER, it is challenging
|
||||
// to set its inner handler for each plugin scope's diagnostic emitter.
|
||||
// Via lazy init OnceCell we keep static HANDLER as immutable, also allows to set
|
||||
// plugin specific values when proc_macro expands plugin's transform helper.
|
||||
pub inner: swc_common::sync::OnceCell<swc_common::errors::Handler>,
|
||||
pub inner: OnceCell<T>,
|
||||
}
|
||||
|
||||
impl PseudoScopedKey {
|
||||
impl<T> PseudoScopedKey<T> {
|
||||
pub fn with<F, R>(&self, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&swc_common::errors::Handler) -> R,
|
||||
F: FnOnce(&T) -> R,
|
||||
{
|
||||
f(self.inner.get().expect("Should set handler before call"))
|
||||
}
|
||||
@ -25,4 +27,4 @@ impl PseudoScopedKey {
|
||||
// NOTE: This only works cause we know each plugin transform doesn't need any
|
||||
// thread safety. However, if wasm gets thread support and if we're going to
|
||||
// support it this should be revisited.
|
||||
unsafe impl std::marker::Sync for PseudoScopedKey {}
|
||||
unsafe impl<T> std::marker::Sync for PseudoScopedKey<T> {}
|
||||
|
@ -32,6 +32,30 @@ fn handle_func(func: ItemFn) -> TokenStream {
|
||||
#[cfg(target_arch = "wasm32")] // Allow testing
|
||||
extern "C" {
|
||||
fn __set_transform_result(bytes_ptr: i32, bytes_ptr_len: i32);
|
||||
fn __emit_diagnostics(bytes_ptr: i32, bytes_ptr_len: i32);
|
||||
fn __free(bytes_ptr: i32, size: i32) -> i32;
|
||||
}
|
||||
|
||||
/// An emitter for the Diagnostic in plugin's context by borrowing host's
|
||||
/// environment context.
|
||||
///
|
||||
/// It is not expected to call this directly inside of plugin transform.
|
||||
/// Instead, it is encouraged to use global HANDLER.
|
||||
pub struct PluginDiagnosticsEmitter;
|
||||
|
||||
impl swc_core::common::errors::Emitter for PluginDiagnosticsEmitter {
|
||||
#[cfg_attr(not(target_arch = "wasm32"), allow(unused))]
|
||||
fn emit(&mut self, db: &swc_core::common::errors::DiagnosticBuilder<'_>) {
|
||||
let diagnostic = swc_core::common::plugin::serialized::VersionedSerializable::new((*db.diagnostic).clone());
|
||||
let diag = swc_core::common::plugin::serialized::PluginSerializedBytes::try_serialize(&diagnostic)
|
||||
.expect("Should able to serialize Diagnostic");
|
||||
let (ptr, len) = diag.as_ptr();
|
||||
|
||||
#[cfg(target_arch = "wasm32")] // Allow testing
|
||||
unsafe {
|
||||
__emit_diagnostics(ptr as i32, len as i32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -45,9 +69,9 @@ fn handle_func(func: ItemFn) -> TokenStream {
|
||||
}
|
||||
|
||||
/// Internal function plugin_macro uses to create ptr to PluginError.
|
||||
fn construct_error_ptr(plugin_error: swc_plugin::PluginError) -> i32 {
|
||||
let plugin_error = swc_plugin::VersionedSerializable::new(plugin_error);
|
||||
let ret = swc_plugin::PluginSerializedBytes::try_serialize(&plugin_error).expect("Should able to serialize PluginError");
|
||||
fn construct_error_ptr(plugin_error: swc_core::common::plugin::serialized::PluginError) -> i32 {
|
||||
let plugin_error = swc_core::common::plugin::serialized::VersionedSerializable::new(plugin_error);
|
||||
let ret = swc_core::common::plugin::serialized::PluginSerializedBytes::try_serialize(&plugin_error).expect("Should able to serialize PluginError");
|
||||
let (ptr, len) = ret.as_ptr();
|
||||
|
||||
send_transform_result_to_host(
|
||||
@ -59,7 +83,7 @@ fn handle_func(func: ItemFn) -> TokenStream {
|
||||
|
||||
#[no_mangle]
|
||||
pub fn #transform_schema_version_ident() -> u32 {
|
||||
swc_plugin::PLUGIN_TRANSFORM_AST_SCHEMA_VERSION
|
||||
swc_core::common::plugin::serialized::PLUGIN_TRANSFORM_AST_SCHEMA_VERSION
|
||||
}
|
||||
|
||||
// Macro to allow compose plugin's transform function without manual pointer operation.
|
||||
@ -72,44 +96,46 @@ fn handle_func(func: ItemFn) -> TokenStream {
|
||||
unresolved_mark: u32, should_enable_comments_proxy: i32) -> i32 {
|
||||
// Reconstruct `Program` & config string from serialized program
|
||||
// Host (SWC) should allocate memory, copy bytes and pass ptr to plugin.
|
||||
let program = unsafe { swc_plugin::deserialize_from_ptr(ast_ptr, ast_ptr_len).map(|v| v.into_inner()) };
|
||||
let program = unsafe { swc_core::common::plugin::serialized::deserialize_from_ptr(ast_ptr, ast_ptr_len).map(|v| v.into_inner()) };
|
||||
if program.is_err() {
|
||||
let err = swc_plugin::PluginError::Deserialize("Failed to deserialize program received from host".to_string());
|
||||
let err = swc_core::common::plugin::serialized::PluginError::Deserialize("Failed to deserialize program received from host".to_string());
|
||||
return construct_error_ptr(err);
|
||||
}
|
||||
let program: Program = program.expect("Should be a program");
|
||||
|
||||
// Create a handler wired with plugin's diagnostic emitter, set it for global context.
|
||||
let handler = swc_plugin::errors::Handler::with_emitter(
|
||||
let handler = swc_core::common::errors::Handler::with_emitter(
|
||||
true,
|
||||
false,
|
||||
Box::new(swc_plugin::environment::PluginDiagnosticsEmitter)
|
||||
Box::new(PluginDiagnosticsEmitter)
|
||||
);
|
||||
let handler_set_result = swc_plugin::errors::HANDLER.inner.set(handler);
|
||||
let handler_set_result = swc_core::plugin::errors::HANDLER.inner.set(handler);
|
||||
|
||||
if handler_set_result.is_err() {
|
||||
let err = swc_plugin::PluginError::Serialize(
|
||||
let err = swc_core::common::plugin::serialized::PluginError::Serialize(
|
||||
"Failed to set handler for plugin".to_string()
|
||||
);
|
||||
return construct_error_ptr(err);
|
||||
}
|
||||
|
||||
// Construct metadata to the `Program` for the transform plugin.
|
||||
let plugin_comments_proxy = if should_enable_comments_proxy == 1 { Some(swc_plugin::comments::PluginCommentsProxy) } else { None };
|
||||
let mut metadata = swc_plugin::metadata::TransformPluginProgramMetadata {
|
||||
let plugin_comments_proxy = if should_enable_comments_proxy == 1 { Some(swc_core::plugin::proxies::PluginCommentsProxy) } else { None };
|
||||
let mut metadata = swc_core::plugin::metadata::TransformPluginProgramMetadata {
|
||||
comments: plugin_comments_proxy,
|
||||
source_map: swc_plugin::source_map::PluginSourceMapProxy,
|
||||
unresolved_mark: swc_plugin::syntax_pos::Mark::from_u32(unresolved_mark),
|
||||
source_map: swc_core::plugin::proxies::PluginSourceMapProxy,
|
||||
unresolved_mark: swc_core::common::Mark::from_u32(unresolved_mark),
|
||||
};
|
||||
|
||||
// Take original plugin fn ident, then call it with interop'ed args
|
||||
let transformed_program = #ident(program, metadata);
|
||||
|
||||
// Serialize transformed result, return back to the host.
|
||||
let serialized_result = swc_plugin::PluginSerializedBytes::try_serialize(&swc_plugin::VersionedSerializable::new(transformed_program));
|
||||
let serialized_result = swc_core::common::plugin::serialized::PluginSerializedBytes::try_serialize(
|
||||
&swc_core::common::plugin::serialized::VersionedSerializable::new(transformed_program)
|
||||
);
|
||||
|
||||
if serialized_result.is_err() {
|
||||
let err = swc_plugin::PluginError::Serialize("Failed to serialize transformed program".to_string());
|
||||
let err = swc_core::common::plugin::serialized::PluginError::Serialize("Failed to serialize transformed program".to_string());
|
||||
return construct_error_ptr(err);
|
||||
}
|
||||
|
||||
|
@ -146,16 +146,6 @@ version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be"
|
||||
|
||||
[[package]]
|
||||
name = "enum_kind"
|
||||
version = "0.2.1"
|
||||
dependencies = [
|
||||
"pmutil",
|
||||
"proc-macro2",
|
||||
"swc_macros_common",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
@ -219,16 +209,6 @@ dependencies = [
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-macro"
|
||||
version = "0.2.1"
|
||||
@ -248,79 +228,6 @@ version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lexical"
|
||||
version = "6.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7aefb36fd43fef7003334742cbf77b243fcd36418a1d1bdd480d613a67968f6"
|
||||
dependencies = [
|
||||
"lexical-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lexical-core"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2cde5de06e8d4c2faabc400238f9ae1c74d5412d03a7bd067645ccbc47070e46"
|
||||
dependencies = [
|
||||
"lexical-parse-float",
|
||||
"lexical-parse-integer",
|
||||
"lexical-util",
|
||||
"lexical-write-float",
|
||||
"lexical-write-integer",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lexical-parse-float"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683b3a5ebd0130b8fb52ba0bdc718cc56815b6a097e28ae5a6997d0ad17dc05f"
|
||||
dependencies = [
|
||||
"lexical-parse-integer",
|
||||
"lexical-util",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lexical-parse-integer"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d0994485ed0c312f6d965766754ea177d07f9c00c9b82a5ee62ed5b47945ee9"
|
||||
dependencies = [
|
||||
"lexical-util",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lexical-util"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5255b9ff16ff898710eb9eb63cb39248ea8a5bb036bea8085b1a767ff6c4e3fc"
|
||||
dependencies = [
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lexical-write-float"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accabaa1c4581f05a3923d1b4cfd124c329352288b7b9da09e766b0668116862"
|
||||
dependencies = [
|
||||
"lexical-util",
|
||||
"lexical-write-integer",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lexical-write-integer"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1b6f3d1f4422866b68192d62f77bc5c700bee84f3069f2469d7bc8c77852446"
|
||||
dependencies = [
|
||||
"lexical-util",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.126"
|
||||
@ -653,12 +560,6 @@ version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "string_cache"
|
||||
version = "0.8.4"
|
||||
@ -704,7 +605,7 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "swc_atoms"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
dependencies = [
|
||||
"bytecheck",
|
||||
"once_cell",
|
||||
@ -717,7 +618,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_common"
|
||||
version = "0.25.0"
|
||||
version = "0.26.0"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
@ -743,9 +644,23 @@ dependencies = [
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_core"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_visit",
|
||||
"swc_plugin",
|
||||
"swc_plugin_macro",
|
||||
"swc_plugin_proxy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_ast"
|
||||
version = "0.88.1"
|
||||
version = "0.89.1"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bytecheck",
|
||||
@ -760,40 +675,9 @@ dependencies = [
|
||||
"unicode-id",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_parser"
|
||||
version = "0.115.1"
|
||||
dependencies = [
|
||||
"either",
|
||||
"enum_kind",
|
||||
"lexical",
|
||||
"num-bigint",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
"swc_ecma_ast",
|
||||
"tracing",
|
||||
"typed-arena",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_utils"
|
||||
version = "0.97.0"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"once_cell",
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_visit",
|
||||
"tracing",
|
||||
"unicode-id",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_visit"
|
||||
version = "0.74.1"
|
||||
version = "0.75.0"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"swc_atoms",
|
||||
@ -803,16 +687,6 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecmascript"
|
||||
version = "0.185.0"
|
||||
dependencies = [
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_parser",
|
||||
"swc_ecma_utils",
|
||||
"swc_ecma_visit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_eq_ignore_macros"
|
||||
version = "0.1.0"
|
||||
@ -828,7 +702,7 @@ name = "swc_internal_plugin"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"swc_plugin",
|
||||
"swc_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -843,18 +717,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_plugin"
|
||||
version = "0.87.0"
|
||||
version = "0.88.2"
|
||||
dependencies = [
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
"swc_ecmascript",
|
||||
"swc_plugin_macro",
|
||||
"swc_plugin_proxy",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_plugin_macro"
|
||||
version = "0.8.0"
|
||||
version = "0.8.1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -863,7 +733,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_plugin_proxy"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
dependencies = [
|
||||
"better_scoped_tls",
|
||||
"bytecheck",
|
||||
@ -950,12 +820,6 @@ dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typed-arena"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0685c84d5d54d1c26f7d3eb96cd41550adb97baed141a761cf335d3d33bcd0ae"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.8"
|
||||
|
@ -11,4 +11,4 @@ crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
serde = "1"
|
||||
swc_plugin = { path = "../../../../swc_plugin" }
|
||||
swc_core = { path = "../../../../swc_core", features = ["plugin_transform"] }
|
||||
|
@ -1,9 +1,12 @@
|
||||
use swc_plugin::{
|
||||
use swc_core::{
|
||||
ast::*,
|
||||
errors::HANDLER,
|
||||
metadata::{TransformPluginMetadataContextKind, TransformPluginProgramMetadata},
|
||||
plugin_transform,
|
||||
syntax_pos::DUMMY_SP,
|
||||
common::DUMMY_SP,
|
||||
plugin::{
|
||||
errors::HANDLER,
|
||||
metadata::{TransformPluginMetadataContextKind, TransformPluginProgramMetadata},
|
||||
plugin_transform,
|
||||
},
|
||||
visit::*,
|
||||
};
|
||||
|
||||
struct ConsoleOutputReplacer;
|
||||
|
@ -146,16 +146,6 @@ version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be"
|
||||
|
||||
[[package]]
|
||||
name = "enum_kind"
|
||||
version = "0.2.1"
|
||||
dependencies = [
|
||||
"pmutil",
|
||||
"proc-macro2",
|
||||
"swc_macros_common",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
@ -219,16 +209,6 @@ dependencies = [
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-macro"
|
||||
version = "0.2.1"
|
||||
@ -248,79 +228,6 @@ version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lexical"
|
||||
version = "6.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7aefb36fd43fef7003334742cbf77b243fcd36418a1d1bdd480d613a67968f6"
|
||||
dependencies = [
|
||||
"lexical-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lexical-core"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2cde5de06e8d4c2faabc400238f9ae1c74d5412d03a7bd067645ccbc47070e46"
|
||||
dependencies = [
|
||||
"lexical-parse-float",
|
||||
"lexical-parse-integer",
|
||||
"lexical-util",
|
||||
"lexical-write-float",
|
||||
"lexical-write-integer",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lexical-parse-float"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683b3a5ebd0130b8fb52ba0bdc718cc56815b6a097e28ae5a6997d0ad17dc05f"
|
||||
dependencies = [
|
||||
"lexical-parse-integer",
|
||||
"lexical-util",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lexical-parse-integer"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d0994485ed0c312f6d965766754ea177d07f9c00c9b82a5ee62ed5b47945ee9"
|
||||
dependencies = [
|
||||
"lexical-util",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lexical-util"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5255b9ff16ff898710eb9eb63cb39248ea8a5bb036bea8085b1a767ff6c4e3fc"
|
||||
dependencies = [
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lexical-write-float"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accabaa1c4581f05a3923d1b4cfd124c329352288b7b9da09e766b0668116862"
|
||||
dependencies = [
|
||||
"lexical-util",
|
||||
"lexical-write-integer",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lexical-write-integer"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1b6f3d1f4422866b68192d62f77bc5c700bee84f3069f2469d7bc8c77852446"
|
||||
dependencies = [
|
||||
"lexical-util",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.126"
|
||||
@ -451,7 +358,7 @@ name = "plugin_transform_schema_vtest"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"swc_plugin",
|
||||
"swc_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -661,12 +568,6 @@ version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "string_cache"
|
||||
version = "0.8.4"
|
||||
@ -751,6 +652,20 @@ dependencies = [
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_core"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_visit",
|
||||
"swc_plugin",
|
||||
"swc_plugin_macro",
|
||||
"swc_plugin_proxy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_ast"
|
||||
version = "0.89.1"
|
||||
@ -768,37 +683,6 @@ dependencies = [
|
||||
"unicode-id",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_parser"
|
||||
version = "0.116.0"
|
||||
dependencies = [
|
||||
"either",
|
||||
"enum_kind",
|
||||
"lexical",
|
||||
"num-bigint",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
"swc_ecma_ast",
|
||||
"tracing",
|
||||
"typed-arena",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_utils"
|
||||
version = "0.98.1"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"once_cell",
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_visit",
|
||||
"tracing",
|
||||
"unicode-id",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_visit"
|
||||
version = "0.75.0"
|
||||
@ -811,16 +695,6 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecmascript"
|
||||
version = "0.186.0"
|
||||
dependencies = [
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_parser",
|
||||
"swc_ecma_utils",
|
||||
"swc_ecma_visit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_eq_ignore_macros"
|
||||
version = "0.1.0"
|
||||
@ -845,11 +719,7 @@ dependencies = [
|
||||
name = "swc_plugin"
|
||||
version = "0.88.2"
|
||||
dependencies = [
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
"swc_ecmascript",
|
||||
"swc_plugin_macro",
|
||||
"swc_plugin_proxy",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -950,12 +820,6 @@ dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typed-arena"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0685c84d5d54d1c26f7d3eb96cd41550adb97baed141a761cf335d3d33bcd0ae"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.8"
|
||||
|
@ -11,4 +11,4 @@ crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
serde = "1.0.140"
|
||||
swc_plugin = { path = "../../../../crates/swc_plugin", default-features = false, features = ["plugin_transform_schema_vtest"] }
|
||||
swc_core = { path = "../../../../crates/swc_core", features = ["__plugin_transform_schema_test"] }
|
||||
|
@ -1,5 +1,8 @@
|
||||
use swc_plugin::{
|
||||
ast::*, metadata::TransformPluginProgramMetadata, plugin_transform, syntax_pos::DUMMY_SP,
|
||||
use swc_core::{
|
||||
ast::*,
|
||||
common::DUMMY_SP,
|
||||
plugin::{metadata::TransformPluginProgramMetadata, plugin_transform},
|
||||
visit::*,
|
||||
};
|
||||
|
||||
struct ConsoleOutputReplacer;
|
||||
|
Loading…
Reference in New Issue
Block a user