cleanup: native (#887)

This commit is contained in:
Divy Srivastava 2020-07-22 15:15:12 +05:30 committed by GitHub
parent 053f81c761
commit 68799d74ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 502 additions and 472 deletions

View File

@ -9,24 +9,19 @@ extern crate path_clean;
extern crate serde; extern crate serde;
extern crate swc; extern crate swc;
use anyhow::{Context as _, Error}; use anyhow::Error;
use backtrace::Backtrace; use backtrace::Backtrace;
use neon::prelude::*; use neon::prelude::*;
use path_clean::clean; use std::{env, panic::set_hook, sync::Arc};
use std::{
env,
panic::set_hook,
path::{Path, PathBuf},
sync::Arc,
};
use swc::{ use swc::{
common::{self, errors::Handler, FileName, FilePathMapping, SourceFile, SourceMap}, common::{self, errors::Handler, FilePathMapping, SourceMap},
config::{Options, ParseOptions, SourceMapsConfig},
ecmascript::ast::Program,
Compiler, TransformOutput, Compiler, TransformOutput,
}; };
mod bundle; mod bundle;
mod parse;
mod print;
mod transform;
fn init(_cx: MethodContext<JsUndefined>) -> NeonResult<ArcCompiler> { fn init(_cx: MethodContext<JsUndefined>) -> NeonResult<ArcCompiler> {
if cfg!(debug_assertions) || env::var("SWC_DEBUG").unwrap_or_else(|_| String::new()) == "1" { if cfg!(debug_assertions) || env::var("SWC_DEBUG").unwrap_or_else(|_| String::new()) == "1" {
@ -50,24 +45,7 @@ fn init(_cx: MethodContext<JsUndefined>) -> NeonResult<ArcCompiler> {
Ok(Arc::new(c)) Ok(Arc::new(c))
} }
/// Input to transform pub fn complete_output<'a>(
#[derive(Debug)]
enum Input {
/// json string
Program(String),
/// Raw source code.
Source(Arc<SourceFile>),
/// File
File(PathBuf),
}
struct TransformTask {
c: Arc<Compiler>,
input: Input,
options: Options,
}
fn complete_output<'a>(
mut cx: impl Context<'a>, mut cx: impl Context<'a>,
result: Result<TransformOutput, Error>, result: Result<TransformOutput, Error>,
) -> JsResult<'a, JsValue> { ) -> JsResult<'a, JsValue> {
@ -77,439 +55,6 @@ fn complete_output<'a>(
} }
} }
impl Task for TransformTask {
type Output = TransformOutput;
type Error = Error;
type JsEvent = JsValue;
fn perform(&self) -> Result<Self::Output, Self::Error> {
self.c.run(|| match self.input {
Input::Program(ref s) => {
let program: Program =
serde_json::from_str(&s).expect("failed to deserialize Program");
// TODO: Source map
self.c.process_js(program, &self.options)
}
Input::File(ref path) => {
let fm = self.c.cm.load_file(path).context("failed to read module")?;
self.c.process_js_file(fm, &self.options)
}
Input::Source(ref s) => self.c.process_js_file(s.clone(), &self.options),
})
}
fn complete(
self,
cx: TaskContext,
result: Result<Self::Output, Self::Error>,
) -> JsResult<Self::JsEvent> {
complete_output(cx, result)
}
}
/// returns `compiler, (src / path), options, plugin, callback`
fn schedule_transform<F>(mut cx: MethodContext<JsCompiler>, op: F) -> JsResult<JsValue>
where
F: FnOnce(&Arc<Compiler>, String, bool, Options) -> TransformTask,
{
let c;
let this = cx.this();
{
let guard = cx.lock();
c = this.borrow(&guard).clone();
};
let s = cx.argument::<JsString>(0)?.value();
let is_module = cx.argument::<JsBoolean>(1)?;
let options_arg = cx.argument::<JsValue>(2)?;
let options: Options = neon_serde::from_value(&mut cx, options_arg)?;
let callback = cx.argument::<JsFunction>(3)?;
let task = op(&c, s, is_module.value(), options);
task.schedule(callback);
Ok(cx.undefined().upcast())
}
fn exec_transform<F>(mut cx: MethodContext<JsCompiler>, op: F) -> JsResult<JsValue>
where
F: FnOnce(&Compiler, String, &Options) -> Result<Arc<SourceFile>, Error>,
{
let s = cx.argument::<JsString>(0)?;
let is_module = cx.argument::<JsBoolean>(1)?;
let options: Options = match cx.argument_opt(2) {
Some(v) => neon_serde::from_value(&mut cx, v)?,
None => {
let obj = cx.empty_object().upcast();
neon_serde::from_value(&mut cx, obj)?
}
};
let this = cx.this();
let output = {
let guard = cx.lock();
let c = this.borrow(&guard);
c.run(|| {
if is_module.value() {
let program: Program =
serde_json::from_str(&s.value()).expect("failed to deserialize Program");
c.process_js(program, &options)
} else {
let fm = op(&c, s.value(), &options).expect("failed to create fm");
c.process_js_file(fm, &options)
}
})
};
complete_output(cx, output)
}
fn transform(cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
schedule_transform(cx, |c, src, is_module, options| {
let input = if is_module {
Input::Program(src)
} else {
Input::Source(c.cm.new_source_file(
if options.filename.is_empty() {
FileName::Anon
} else {
FileName::Real(options.filename.clone().into())
},
src,
))
};
TransformTask {
c: c.clone(),
input,
options,
}
})
}
fn transform_sync(cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
exec_transform(cx, |c, src, options| {
Ok(c.cm.new_source_file(
if options.filename.is_empty() {
FileName::Anon
} else {
FileName::Real(options.filename.clone().into())
},
src,
))
})
}
fn transform_file(cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
schedule_transform(cx, |c, path, _, options| {
let path = clean(&path);
TransformTask {
c: c.clone(),
input: Input::File(path.into()),
options,
}
})
}
fn transform_file_sync(cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
exec_transform(cx, |c, path, _| {
Ok(c.cm
.load_file(Path::new(&path))
.expect("failed to load file"))
})
}
// ----- Parsing -----
struct ParseTask {
c: Arc<Compiler>,
fm: Arc<SourceFile>,
options: ParseOptions,
}
struct ParseFileTask {
c: Arc<Compiler>,
path: PathBuf,
options: ParseOptions,
}
fn complete_parse<'a>(
mut cx: impl Context<'a>,
result: Result<Program, Error>,
c: &Compiler,
) -> JsResult<'a, JsValue> {
c.run(|| match result {
Ok(program) => Ok(cx
.string(serde_json::to_string(&program).expect("failed to serialize Program"))
.upcast()),
Err(err) => cx.throw_error(format!("{:?}", err)),
})
}
impl Task for ParseTask {
type Output = Program;
type Error = Error;
type JsEvent = JsValue;
fn perform(&self) -> Result<Self::Output, Self::Error> {
self.c.run(|| {
self.c.parse_js(
self.fm.clone(),
self.options.target,
self.options.syntax,
self.options.is_module,
self.options.comments,
)
})
}
fn complete(
self,
cx: TaskContext,
result: Result<Self::Output, Self::Error>,
) -> JsResult<Self::JsEvent> {
complete_parse(cx, result, &self.c)
}
}
impl Task for ParseFileTask {
type Output = Program;
type Error = Error;
type JsEvent = JsValue;
fn perform(&self) -> Result<Self::Output, Self::Error> {
self.c.run(|| {
let fm = self
.c
.cm
.load_file(&self.path)
.context("failed to read module")?;
self.c.parse_js(
fm,
self.options.target,
self.options.syntax,
self.options.is_module,
self.options.comments,
)
})
}
fn complete(
self,
cx: TaskContext,
result: Result<Self::Output, Self::Error>,
) -> JsResult<Self::JsEvent> {
complete_parse(cx, result, &self.c)
}
}
fn parse(mut cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
let src = cx.argument::<JsString>(0)?;
let options_arg = cx.argument::<JsValue>(1)?;
let options: ParseOptions = neon_serde::from_value(&mut cx, options_arg)?;
let callback = cx.argument::<JsFunction>(2)?;
let this = cx.this();
{
let guard = cx.lock();
let c = this.borrow(&guard);
let fm = c.cm.new_source_file(FileName::Anon, src.value());
ParseTask {
c: c.clone(),
fm,
options,
}
.schedule(callback);
};
Ok(cx.undefined().upcast())
}
fn parse_sync(mut cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
let c;
let this = cx.this();
{
let guard = cx.lock();
let compiler = this.borrow(&guard);
c = compiler.clone();
}
c.run(|| {
let src = cx.argument::<JsString>(0)?;
let options_arg = cx.argument::<JsValue>(1)?;
let options: ParseOptions = neon_serde::from_value(&mut cx, options_arg)?;
let program = {
let fm = c.cm.new_source_file(FileName::Anon, src.value());
c.parse_js(
fm,
options.target,
options.syntax,
options.is_module,
options.comments,
)
};
complete_parse(cx, program, &c)
})
}
fn parse_file_sync(mut cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
let c;
let this = cx.this();
{
let guard = cx.lock();
let compiler = this.borrow(&guard);
c = compiler.clone();
}
c.run(|| {
let path = cx.argument::<JsString>(0)?;
let options_arg = cx.argument::<JsValue>(1)?;
let options: ParseOptions = neon_serde::from_value(&mut cx, options_arg)?;
let program = {
let fm =
c.cm.load_file(Path::new(&path.value()))
.expect("failed to read program file");
c.parse_js(
fm,
options.target,
options.syntax,
options.is_module,
options.comments,
)
};
complete_parse(cx, program, &c)
})
}
fn parse_file(mut cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
let path = cx.argument::<JsString>(0)?;
let options_arg = cx.argument::<JsValue>(1)?;
let options: ParseOptions = neon_serde::from_value(&mut cx, options_arg)?;
let callback = cx.argument::<JsFunction>(2)?;
let this = cx.this();
{
let guard = cx.lock();
let c = this.borrow(&guard);
ParseFileTask {
c: c.clone(),
path: path.value().into(),
options,
}
.schedule(callback);
};
Ok(cx.undefined().upcast())
}
// ----- Printing -----
struct PrintTask {
c: Arc<Compiler>,
program: Program,
options: Options,
}
impl Task for PrintTask {
type Output = TransformOutput;
type Error = Error;
type JsEvent = JsValue;
fn perform(&self) -> Result<Self::Output, Self::Error> {
self.c.run(|| {
self.c.print(
&self.program,
self.options
.source_maps
.clone()
.unwrap_or(SourceMapsConfig::Bool(false)),
None,
self.options
.config
.clone()
.unwrap_or_default()
.minify
.unwrap_or(false),
)
})
}
fn complete(
self,
cx: TaskContext,
result: Result<Self::Output, Self::Error>,
) -> JsResult<Self::JsEvent> {
complete_output(cx, result)
}
}
fn print(mut cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
let program = cx.argument::<JsString>(0)?;
let program: Program =
serde_json::from_str(&program.value()).expect("failed to deserialize Program");
let options = cx.argument::<JsValue>(1)?;
let options: Options = neon_serde::from_value(&mut cx, options)?;
let callback = cx.argument::<JsFunction>(2)?;
let this = cx.this();
{
let guard = cx.lock();
let c = this.borrow(&guard);
PrintTask {
c: c.clone(),
program,
options,
}
.schedule(callback)
}
Ok(cx.undefined().upcast())
}
fn print_sync(mut cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
let c;
let this = cx.this();
{
let guard = cx.lock();
let compiler = this.borrow(&guard);
c = compiler.clone();
}
c.run(|| {
let program = cx.argument::<JsString>(0)?;
let program: Program =
serde_json::from_str(&program.value()).expect("failed to deserialize Program");
let options = cx.argument::<JsValue>(1)?;
let options: Options = neon_serde::from_value(&mut cx, options)?;
let result = {
c.print(
&program,
options
.source_maps
.clone()
.unwrap_or(SourceMapsConfig::Bool(false)),
None,
options.config.unwrap_or_default().minify.unwrap_or(false),
)
};
complete_output(cx, result)
})
}
pub type ArcCompiler = Arc<Compiler>; pub type ArcCompiler = Arc<Compiler>;
declare_types! { declare_types! {
@ -519,43 +64,43 @@ declare_types! {
} }
method transform(cx) { method transform(cx) {
transform(cx) transform::transform(cx)
} }
method transformSync(cx) { method transformSync(cx) {
transform_sync(cx) transform::transform_sync(cx)
} }
method transformFile(cx) { method transformFile(cx) {
transform_file(cx) transform::transform_file(cx)
} }
method transformFileSync(cx) { method transformFileSync(cx) {
transform_file_sync(cx) transform::transform_file_sync(cx)
} }
method parse(cx) { method parse(cx) {
parse(cx) parse::parse(cx)
} }
method parseSync(cx) { method parseSync(cx) {
parse_sync(cx) parse::parse_sync(cx)
} }
method parseFile(cx) { method parseFile(cx) {
parse_file(cx) parse::parse_file(cx)
} }
method parseFileSync(cx) { method parseFileSync(cx) {
parse_file_sync(cx) parse::parse_file_sync(cx)
} }
method print(cx) { method print(cx) {
print(cx) print::print(cx)
} }
method printSync(cx) { method printSync(cx) {
print_sync(cx) print::print_sync(cx)
} }
method bundle(cx) { method bundle(cx) {

203
native/src/parse.rs Normal file
View File

@ -0,0 +1,203 @@
use crate::JsCompiler;
use anyhow::{Context as _, Error};
use neon::prelude::*;
use std::{
path::{Path, PathBuf},
sync::Arc,
};
use swc::{
common::{FileName, SourceFile},
config::ParseOptions,
ecmascript::ast::Program,
Compiler,
};
// ----- Parsing -----
pub struct ParseTask {
pub c: Arc<Compiler>,
pub fm: Arc<SourceFile>,
pub options: ParseOptions,
}
pub struct ParseFileTask {
pub c: Arc<Compiler>,
pub path: PathBuf,
pub options: ParseOptions,
}
pub fn complete_parse<'a>(
mut cx: impl Context<'a>,
result: Result<Program, Error>,
c: &Compiler,
) -> JsResult<'a, JsValue> {
c.run(|| match result {
Ok(program) => Ok(cx
.string(serde_json::to_string(&program).expect("failed to serialize Program"))
.upcast()),
Err(err) => cx.throw_error(format!("{:?}", err)),
})
}
impl Task for ParseTask {
type Output = Program;
type Error = Error;
type JsEvent = JsValue;
fn perform(&self) -> Result<Self::Output, Self::Error> {
self.c.run(|| {
self.c.parse_js(
self.fm.clone(),
self.options.target,
self.options.syntax,
self.options.is_module,
self.options.comments,
)
})
}
fn complete(
self,
cx: TaskContext,
result: Result<Self::Output, Self::Error>,
) -> JsResult<Self::JsEvent> {
complete_parse(cx, result, &self.c)
}
}
impl Task for ParseFileTask {
type Output = Program;
type Error = Error;
type JsEvent = JsValue;
fn perform(&self) -> Result<Self::Output, Self::Error> {
self.c.run(|| {
let fm = self
.c
.cm
.load_file(&self.path)
.context("failed to read module")?;
self.c.parse_js(
fm,
self.options.target,
self.options.syntax,
self.options.is_module,
self.options.comments,
)
})
}
fn complete(
self,
cx: TaskContext,
result: Result<Self::Output, Self::Error>,
) -> JsResult<Self::JsEvent> {
complete_parse(cx, result, &self.c)
}
}
pub fn parse(mut cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
let src = cx.argument::<JsString>(0)?;
let options_arg = cx.argument::<JsValue>(1)?;
let options: ParseOptions = neon_serde::from_value(&mut cx, options_arg)?;
let callback = cx.argument::<JsFunction>(2)?;
let this = cx.this();
{
let guard = cx.lock();
let c = this.borrow(&guard);
let fm = c.cm.new_source_file(FileName::Anon, src.value());
ParseTask {
c: c.clone(),
fm,
options,
}
.schedule(callback);
};
Ok(cx.undefined().upcast())
}
pub fn parse_sync(mut cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
let c;
let this = cx.this();
{
let guard = cx.lock();
let compiler = this.borrow(&guard);
c = compiler.clone();
}
c.run(|| {
let src = cx.argument::<JsString>(0)?;
let options_arg = cx.argument::<JsValue>(1)?;
let options: ParseOptions = neon_serde::from_value(&mut cx, options_arg)?;
let program = {
let fm = c.cm.new_source_file(FileName::Anon, src.value());
c.parse_js(
fm,
options.target,
options.syntax,
options.is_module,
options.comments,
)
};
complete_parse(cx, program, &c)
})
}
pub fn parse_file_sync(mut cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
let c;
let this = cx.this();
{
let guard = cx.lock();
let compiler = this.borrow(&guard);
c = compiler.clone();
}
c.run(|| {
let path = cx.argument::<JsString>(0)?;
let options_arg = cx.argument::<JsValue>(1)?;
let options: ParseOptions = neon_serde::from_value(&mut cx, options_arg)?;
let program = {
let fm =
c.cm.load_file(Path::new(&path.value()))
.expect("failed to read program file");
c.parse_js(
fm,
options.target,
options.syntax,
options.is_module,
options.comments,
)
};
complete_parse(cx, program, &c)
})
}
pub fn parse_file(mut cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
let path = cx.argument::<JsString>(0)?;
let options_arg = cx.argument::<JsValue>(1)?;
let options: ParseOptions = neon_serde::from_value(&mut cx, options_arg)?;
let callback = cx.argument::<JsFunction>(2)?;
let this = cx.this();
{
let guard = cx.lock();
let c = this.borrow(&guard);
ParseFileTask {
c: c.clone(),
path: path.value().into(),
options,
}
.schedule(callback);
};
Ok(cx.undefined().upcast())
}

106
native/src/print.rs Normal file
View File

@ -0,0 +1,106 @@
use crate::{complete_output, JsCompiler};
use anyhow::Error;
use neon::prelude::*;
use std::sync::Arc;
use swc::{
config::{Options, SourceMapsConfig},
ecmascript::ast::Program,
Compiler, TransformOutput,
};
// ----- Printing -----
pub struct PrintTask {
pub c: Arc<Compiler>,
pub program: Program,
pub options: Options,
}
impl Task for PrintTask {
type Output = TransformOutput;
type Error = Error;
type JsEvent = JsValue;
fn perform(&self) -> Result<Self::Output, Self::Error> {
self.c.run(|| {
self.c.print(
&self.program,
self.options
.source_maps
.clone()
.unwrap_or(SourceMapsConfig::Bool(false)),
None,
self.options
.config
.clone()
.unwrap_or_default()
.minify
.unwrap_or(false),
)
})
}
fn complete(
self,
cx: TaskContext,
result: Result<Self::Output, Self::Error>,
) -> JsResult<Self::JsEvent> {
complete_output(cx, result)
}
}
pub fn print(mut cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
let program = cx.argument::<JsString>(0)?;
let program: Program =
serde_json::from_str(&program.value()).expect("failed to deserialize Program");
let options = cx.argument::<JsValue>(1)?;
let options: Options = neon_serde::from_value(&mut cx, options)?;
let callback = cx.argument::<JsFunction>(2)?;
let this = cx.this();
{
let guard = cx.lock();
let c = this.borrow(&guard);
PrintTask {
c: c.clone(),
program,
options,
}
.schedule(callback)
}
Ok(cx.undefined().upcast())
}
pub fn print_sync(mut cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
let c;
let this = cx.this();
{
let guard = cx.lock();
let compiler = this.borrow(&guard);
c = compiler.clone();
}
c.run(|| {
let program = cx.argument::<JsString>(0)?;
let program: Program =
serde_json::from_str(&program.value()).expect("failed to deserialize Program");
let options = cx.argument::<JsValue>(1)?;
let options: Options = neon_serde::from_value(&mut cx, options)?;
let result = {
c.print(
&program,
options
.source_maps
.clone()
.unwrap_or(SourceMapsConfig::Bool(false)),
None,
options.config.unwrap_or_default().minify.unwrap_or(false),
)
};
complete_output(cx, result)
})
}

176
native/src/transform.rs Normal file
View File

@ -0,0 +1,176 @@
use crate::{complete_output, JsCompiler};
use anyhow::{Context as _, Error};
use neon::prelude::*;
use path_clean::clean;
use std::{
path::{Path, PathBuf},
sync::Arc,
};
use swc::{
common::{FileName, SourceFile},
config::Options,
ecmascript::ast::Program,
Compiler, TransformOutput,
};
/// Input to transform
#[derive(Debug)]
pub enum Input {
/// json string
Program(String),
/// Raw source code.
Source(Arc<SourceFile>),
/// File
File(PathBuf),
}
pub struct TransformTask {
pub c: Arc<Compiler>,
pub input: Input,
pub options: Options,
}
impl Task for TransformTask {
type Output = TransformOutput;
type Error = Error;
type JsEvent = JsValue;
fn perform(&self) -> Result<Self::Output, Self::Error> {
self.c.run(|| match self.input {
Input::Program(ref s) => {
let program: Program =
serde_json::from_str(&s).expect("failed to deserialize Program");
// TODO: Source map
self.c.process_js(program, &self.options)
}
Input::File(ref path) => {
let fm = self.c.cm.load_file(path).context("failed to read module")?;
self.c.process_js_file(fm, &self.options)
}
Input::Source(ref s) => self.c.process_js_file(s.clone(), &self.options),
})
}
fn complete(
self,
cx: TaskContext,
result: Result<Self::Output, Self::Error>,
) -> JsResult<Self::JsEvent> {
complete_output(cx, result)
}
}
/// returns `compiler, (src / path), options, plugin, callback`
pub fn schedule_transform<F>(mut cx: MethodContext<JsCompiler>, op: F) -> JsResult<JsValue>
where
F: FnOnce(&Arc<Compiler>, String, bool, Options) -> TransformTask,
{
let c;
let this = cx.this();
{
let guard = cx.lock();
c = this.borrow(&guard).clone();
};
let s = cx.argument::<JsString>(0)?.value();
let is_module = cx.argument::<JsBoolean>(1)?;
let options_arg = cx.argument::<JsValue>(2)?;
let options: Options = neon_serde::from_value(&mut cx, options_arg)?;
let callback = cx.argument::<JsFunction>(3)?;
let task = op(&c, s, is_module.value(), options);
task.schedule(callback);
Ok(cx.undefined().upcast())
}
pub fn exec_transform<F>(mut cx: MethodContext<JsCompiler>, op: F) -> JsResult<JsValue>
where
F: FnOnce(&Compiler, String, &Options) -> Result<Arc<SourceFile>, Error>,
{
let s = cx.argument::<JsString>(0)?;
let is_module = cx.argument::<JsBoolean>(1)?;
let options: Options = match cx.argument_opt(2) {
Some(v) => neon_serde::from_value(&mut cx, v)?,
None => {
let obj = cx.empty_object().upcast();
neon_serde::from_value(&mut cx, obj)?
}
};
let this = cx.this();
let output = {
let guard = cx.lock();
let c = this.borrow(&guard);
c.run(|| {
if is_module.value() {
let program: Program =
serde_json::from_str(&s.value()).expect("failed to deserialize Program");
c.process_js(program, &options)
} else {
let fm = op(&c, s.value(), &options).expect("failed to create fm");
c.process_js_file(fm, &options)
}
})
};
complete_output(cx, output)
}
pub fn transform(cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
schedule_transform(cx, |c, src, is_module, options| {
let input = if is_module {
Input::Program(src)
} else {
Input::Source(c.cm.new_source_file(
if options.filename.is_empty() {
FileName::Anon
} else {
FileName::Real(options.filename.clone().into())
},
src,
))
};
TransformTask {
c: c.clone(),
input,
options,
}
})
}
pub fn transform_sync(cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
exec_transform(cx, |c, src, options| {
Ok(c.cm.new_source_file(
if options.filename.is_empty() {
FileName::Anon
} else {
FileName::Real(options.filename.clone().into())
},
src,
))
})
}
pub fn transform_file(cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
schedule_transform(cx, |c, path, _, options| {
let path = clean(&path);
TransformTask {
c: c.clone(),
input: Input::File(path.into()),
options,
}
})
}
pub fn transform_file_sync(cx: MethodContext<JsCompiler>) -> JsResult<JsValue> {
exec_transform(cx, |c, path, _| {
Ok(c.cm
.load_file(Path::new(&path))
.expect("failed to load file"))
})
}