Add customizable api (#1006)

This commit is contained in:
강동윤 2020-08-27 20:35:28 +09:00 committed by GitHub
parent d641c0216b
commit 99981f70c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 7 deletions

View File

@ -1,13 +1,24 @@
use swc_common::pass::CompilerPass; use swc_common::pass::CompilerPass;
pub use swc_common::pass::{Optional, Repeated}; pub use swc_common::pass::{Optional, Repeated};
use swc_ecma_ast::{Module, Script};
use swc_ecma_visit::Fold; use swc_ecma_visit::Fold;
pub fn noop() -> impl Fold { pub fn noop() -> impl Fold {
struct Noop;
impl Fold for Noop {}
Noop Noop
} }
struct Noop;
impl Fold for Noop {
#[inline(always)]
fn fold_module(&mut self, m: Module) -> Module {
m
}
#[inline(always)]
fn fold_script(&mut self, s: Script) -> Script {
s
}
}
pub trait JsPass: CompilerPass + Fold {} pub trait JsPass: CompilerPass + Fold {}
impl<T: ?Sized> JsPass for T where T: CompilerPass + Fold {} impl<T: ?Sized> JsPass for T where T: CompilerPass + Fold {}

View File

@ -112,7 +112,6 @@ impl<'a, 'b, P: swc_ecma_visit::Fold> PassBuilder<'a, 'b, P> {
/// - fixer if enabled /// - fixer if enabled
pub fn finalize<'cmt>( pub fn finalize<'cmt>(
self, self,
root_mark: Mark,
syntax: Syntax, syntax: Syntax,
module: Option<ModuleConfig>, module: Option<ModuleConfig>,
comments: Option<&'cmt dyn Comments>, comments: Option<&'cmt dyn Comments>,
@ -183,7 +182,7 @@ impl<'a, 'b, P: swc_ecma_visit::Fold> PassBuilder<'a, 'b, P> {
need_interop_analysis need_interop_analysis
), ),
helpers::inject_helpers(), helpers::inject_helpers(),
ModuleConfig::build(self.cm.clone(), root_mark, module), ModuleConfig::build(self.cm.clone(), self.global_mark, module),
Optional::new(hygiene(), self.hygiene), Optional::new(hygiene(), self.hygiene),
Optional::new(fixer(comments), self.fixer), Optional::new(fixer(comments), self.fixer),
) )

View File

@ -250,7 +250,7 @@ impl Options {
.hygiene(!self.disable_hygiene) .hygiene(!self.disable_hygiene)
.fixer(!self.disable_fixer) .fixer(!self.disable_fixer)
.preset_env(config.env) .preset_env(config.env)
.finalize(root_mark, syntax, config.module, comments); .finalize(syntax, config.module, comments);
BuiltConfig { BuiltConfig {
minify: config.minify.unwrap_or(false), minify: config.minify.unwrap_or(false),

View File

@ -17,6 +17,7 @@ use std::{
sync::Arc, sync::Arc,
}; };
use swc_common::{ use swc_common::{
chain,
comments::{Comment, Comments}, comments::{Comment, Comments},
errors::Handler, errors::Handler,
input::StringInput, input::StringInput,
@ -27,6 +28,7 @@ use swc_ecma_codegen::{self, Emitter, Node};
use swc_ecma_parser::{lexer::Lexer, Parser, Syntax}; use swc_ecma_parser::{lexer::Lexer, Parser, Syntax};
use swc_ecma_transforms::{ use swc_ecma_transforms::{
helpers::{self, Helpers}, helpers::{self, Helpers},
pass::noop,
util, util,
}; };
use swc_ecma_visit::FoldWith; use swc_ecma_visit::FoldWith;
@ -386,13 +388,28 @@ impl Compiler {
}) })
} }
pub fn process_js_file( /// `custom_after_pass` is applied after swc transforms are applied.
pub fn process_js_with_custom_pass<P>(
&self, &self,
fm: Arc<SourceFile>, fm: Arc<SourceFile>,
opts: &Options, opts: &Options,
) -> Result<TransformOutput, Error> { custom_after_pass: P,
) -> Result<TransformOutput, Error>
where
P: swc_ecma_visit::Fold,
{
self.run(|| -> Result<_, Error> { self.run(|| -> Result<_, Error> {
let config = self.run(|| self.config_for_file(opts, &fm.name))?; let config = self.run(|| self.config_for_file(opts, &fm.name))?;
let config = BuiltConfig {
pass: chain!(config.pass, custom_after_pass),
syntax: config.syntax,
target: config.target,
minify: config.minify,
external_helpers: config.external_helpers,
source_maps: config.source_maps,
input_source_map: config.input_source_map,
is_module: config.is_module,
};
let orig = self.get_orig_src_map(&fm, &opts.input_source_map)?; let orig = self.get_orig_src_map(&fm, &opts.input_source_map)?;
let program = self.parse_js( let program = self.parse_js(
fm.clone(), fm.clone(),
@ -407,6 +424,14 @@ impl Compiler {
.context("failed to process js file") .context("failed to process js file")
} }
pub fn process_js_file(
&self,
fm: Arc<SourceFile>,
opts: &Options,
) -> Result<TransformOutput, Error> {
self.process_js_with_custom_pass(fm, opts, noop())
}
/// You can use custom pass with this method. /// You can use custom pass with this method.
/// ///
/// There exists a [PassBuilder] to help building custom passes. /// There exists a [PassBuilder] to help building custom passes.