diff --git a/crates/swc/Cargo.toml b/crates/swc/Cargo.toml index 32949b68853..77a64eed98c 100644 --- a/crates/swc/Cargo.toml +++ b/crates/swc/Cargo.toml @@ -97,4 +97,4 @@ testing = {version = "0.19.0", path = "../testing"} walkdir = "2" [[example]] -name = "usage" +name = "transform" diff --git a/crates/swc/examples/minify-input.js b/crates/swc/examples/minify-input.js new file mode 100644 index 00000000000..aa09df668d3 --- /dev/null +++ b/crates/swc/examples/minify-input.js @@ -0,0 +1,3 @@ + + +const foo = 1 + 1 + 1 + 1 + 1 + 1 + 1; \ No newline at end of file diff --git a/crates/swc/examples/minify.rs b/crates/swc/examples/minify.rs new file mode 100644 index 00000000000..a822f36a7fb --- /dev/null +++ b/crates/swc/examples/minify.rs @@ -0,0 +1,46 @@ +use std::{path::Path, sync::Arc}; + +use anyhow::Context; +use swc::{self, config::JsMinifyOptions, try_with_handler, HandlerOpts}; +use swc_common::SourceMap; + +fn main() { + let cm = Arc::::default(); + + let c = swc::Compiler::new(cm.clone()); + + let output = try_with_handler( + cm.clone(), + HandlerOpts { + ..Default::default() + }, + |handler| { + let fm = cm + .load_file(Path::new("examples/minify-input.js")) + .expect("failed to load file"); + + c.minify( + fm, + handler, + &JsMinifyOptions { + compress: true.into(), + mangle: true.into(), + format: Default::default(), + ecma: Default::default(), + keep_classnames: Default::default(), + keep_fnames: Default::default(), + module: Default::default(), + safari10: Default::default(), + toplevel: Default::default(), + source_map: Default::default(), + output_path: Default::default(), + inline_sources_content: Default::default(), + }, + ) + .context("failed to minify") + }, + ) + .unwrap(); + + println!("{}", output.code); +} diff --git a/crates/swc/examples/transform-input.js b/crates/swc/examples/transform-input.js new file mode 100644 index 00000000000..3c3ebf1361e --- /dev/null +++ b/crates/swc/examples/transform-input.js @@ -0,0 +1,5 @@ + + +class Foo { } + +class Bar extends Foo { } \ No newline at end of file diff --git a/crates/swc/examples/transform.rs b/crates/swc/examples/transform.rs new file mode 100644 index 00000000000..0e40cccedf3 --- /dev/null +++ b/crates/swc/examples/transform.rs @@ -0,0 +1,35 @@ +use std::{path::Path, sync::Arc}; + +use anyhow::Context; +use swc::{self, config::Options, try_with_handler, HandlerOpts}; +use swc_common::SourceMap; + +fn main() { + let cm = Arc::::default(); + + let c = swc::Compiler::new(cm.clone()); + + let output = try_with_handler( + cm.clone(), + HandlerOpts { + ..Default::default() + }, + |handler| { + let fm = cm + .load_file(Path::new("examples/transform-input.js")) + .expect("failed to load file"); + + c.process_js_file( + fm, + handler, + &Options { + ..Default::default() + }, + ) + .context("failed to process file") + }, + ) + .unwrap(); + + println!("{}", output.code); +} diff --git a/crates/swc/examples/transform_error.rs b/crates/swc/examples/transform_error.rs new file mode 100644 index 00000000000..45ec5b7e2f3 --- /dev/null +++ b/crates/swc/examples/transform_error.rs @@ -0,0 +1,36 @@ +use std::sync::Arc; + +use anyhow::Context; +use swc::{self, config::Options, try_with_handler}; +use swc_common::{errors::ColorConfig, FileName, SourceMap}; + +fn main() { + let cm = Arc::::default(); + + let c = swc::Compiler::new(cm.clone()); + + let output = try_with_handler( + cm.clone(), + swc::HandlerOpts { + // Auto is default, but for it's an example. + // You can use the env var named `NO_COLOR` to control this. + color: ColorConfig::Auto, + skip_filename: false, + }, + |handler| { + let fm = cm.new_source_file(FileName::Custom("foo.js".into()), "this ?= foo".into()); + + c.process_js_file( + fm, + handler, + &Options { + ..Default::default() + }, + ) + .context("failed to process file") + }, + ) + .expect("anyhow will give you good error message"); + + println!("{}", output.code); +} diff --git a/crates/swc/examples/usage.rs b/crates/swc/examples/usage.rs deleted file mode 100644 index a5cb60d687b..00000000000 --- a/crates/swc/examples/usage.rs +++ /dev/null @@ -1,31 +0,0 @@ -use std::{path::Path, sync::Arc}; - -use swc::{self, config::Options}; -use swc_common::{ - errors::{ColorConfig, Handler}, - SourceMap, -}; - -fn main() { - let cm = Arc::::default(); - let handler = Arc::new(Handler::with_tty_emitter( - ColorConfig::Auto, - true, - false, - Some(cm.clone()), - )); - let c = swc::Compiler::new(cm.clone()); - - let fm = cm - .load_file(Path::new("foo.js")) - .expect("failed to load file"); - - c.process_js_file( - fm, - &handler, - &Options { - ..Default::default() - }, - ) - .expect("failed to process file"); -} diff --git a/crates/swc_ecma_lints/examples/all.js b/crates/swc_ecma_lints/examples/all.js new file mode 100644 index 00000000000..7b0430c0cc5 --- /dev/null +++ b/crates/swc_ecma_lints/examples/all.js @@ -0,0 +1,5 @@ + + +const a = 1; + +a = 2; \ No newline at end of file diff --git a/crates/swc_ecma_lints/examples/all.rs b/crates/swc_ecma_lints/examples/all.rs new file mode 100644 index 00000000000..1a82d1214da --- /dev/null +++ b/crates/swc_ecma_lints/examples/all.rs @@ -0,0 +1,53 @@ +use swc_common::{errors::HANDLER, Mark, SyntaxContext}; +use swc_ecma_ast::*; +use swc_ecma_lints::{rule::Rule, rules::LintParams}; +use swc_ecma_parser::Syntax; +use swc_ecma_transforms_base::resolver::resolver_with_mark; +use swc_ecma_visit::VisitMutWith; + +fn main() { + // testing::run_test creates Lrc and `&Handler` for you + // You can refer to source code of it or try_with_handler of the swc crate. + + let msg = testing::run_test(false, |cm, handler| -> Result<(), _> { + HANDLER.set(handler, || { + let fm = cm.load_file("examples/all.js".as_ref()).unwrap(); + + let module = swc_ecma_parser::parse_file_as_module( + &fm, + Syntax::default(), + EsVersion::latest(), + None, + &mut vec![], + ); + let mut program = match module { + Ok(v) => Program::Module(v), + Err(err) => { + err.into_diagnostic(handler).emit(); + return Err(()); + } + }; + + let top_level_mark = Mark::fresh(Mark::root()); + let top_level_ctxt = SyntaxContext::empty().apply_mark(top_level_mark); + + program.visit_mut_with(&mut resolver_with_mark(top_level_mark)); + + let mut rules = swc_ecma_lints::rules::all(LintParams { + program: &program, + lint_config: &Default::default(), + top_level_ctxt, + es_version: EsVersion::latest(), + source_map: cm.clone(), + }); + + let module = program.expect_module(); + rules.lint_module(&module); + + Err(()) + }) + }) + .unwrap_err(); + + println!("{}", msg); +} diff --git a/crates/swc_ecma_transforms_compat/Cargo.toml b/crates/swc_ecma_transforms_compat/Cargo.toml index 00dbbd371fa..a47dc1f074b 100644 --- a/crates/swc_ecma_transforms_compat/Cargo.toml +++ b/crates/swc_ecma_transforms_compat/Cargo.toml @@ -3,6 +3,7 @@ authors = ["강동윤 "] description = "rust port of babel and closure compiler." documentation = "https://rustdoc.swc.rs/swc_ecma_transforms_compat/" edition = "2021" +include = ["Cargo.toml", "src/**/*.rs"] license = "Apache-2.0" name = "swc_ecma_transforms_compat" repository = "https://github.com/swc-project/swc.git" diff --git a/crates/swc_ecma_transforms_module/Cargo.toml b/crates/swc_ecma_transforms_module/Cargo.toml index 29592597a30..bc8e25443af 100644 --- a/crates/swc_ecma_transforms_module/Cargo.toml +++ b/crates/swc_ecma_transforms_module/Cargo.toml @@ -3,6 +3,7 @@ authors = ["강동윤 "] description = "rust port of babel and closure compiler." documentation = "https://rustdoc.swc.rs/swc_ecma_transforms_optimization/" edition = "2021" +include = ["Cargo.toml", "src/**/*.rs"] license = "Apache-2.0" name = "swc_ecma_transforms_module" repository = "https://github.com/swc-project/swc.git" diff --git a/crates/swc_ecma_transforms_optimization/Cargo.toml b/crates/swc_ecma_transforms_optimization/Cargo.toml index 05b03920fc4..c7638bffcf8 100644 --- a/crates/swc_ecma_transforms_optimization/Cargo.toml +++ b/crates/swc_ecma_transforms_optimization/Cargo.toml @@ -3,6 +3,7 @@ authors = ["강동윤 "] description = "rust port of babel and closure compiler." documentation = "https://rustdoc.swc.rs/swc_ecma_transforms_optimization/" edition = "2021" +include = ["Cargo.toml", "src/**/*.rs"] license = "Apache-2.0" name = "swc_ecma_transforms_optimization" repository = "https://github.com/swc-project/swc.git" diff --git a/crates/swc_ecma_transforms_proposal/Cargo.toml b/crates/swc_ecma_transforms_proposal/Cargo.toml index ec4eb97e79b..9e96fa59498 100644 --- a/crates/swc_ecma_transforms_proposal/Cargo.toml +++ b/crates/swc_ecma_transforms_proposal/Cargo.toml @@ -3,6 +3,7 @@ authors = ["강동윤 "] description = "rust port of babel and closure compiler." documentation = "https://rustdoc.swc.rs/swc_ecma_transforms_proposal/" edition = "2021" +include = ["Cargo.toml", "src/**/*.rs"] license = "Apache-2.0" name = "swc_ecma_transforms_proposal" repository = "https://github.com/swc-project/swc.git" diff --git a/crates/swc_ecma_transforms_typescript/Cargo.toml b/crates/swc_ecma_transforms_typescript/Cargo.toml index f9fb4af01e4..e2f5d4f14c3 100644 --- a/crates/swc_ecma_transforms_typescript/Cargo.toml +++ b/crates/swc_ecma_transforms_typescript/Cargo.toml @@ -3,6 +3,7 @@ authors = ["강동윤 "] description = "rust port of babel and closure compiler." documentation = "https://rustdoc.swc.rs/swc_ecma_transforms_typescript/" edition = "2021" +include = ["Cargo.toml", "src/**/*.rs"] license = "Apache-2.0" name = "swc_ecma_transforms_typescript" repository = "https://github.com/swc-project/swc.git" diff --git a/crates/swc_error_reporters/examples/swc_try.rs b/crates/swc_error_reporters/examples/swc_try.rs new file mode 100644 index 00000000000..f3d28d466ea --- /dev/null +++ b/crates/swc_error_reporters/examples/swc_try.rs @@ -0,0 +1,65 @@ +//! This is actual code used by swc. + +use std::{ + fmt, + sync::{Arc, Mutex}, +}; + +use swc_common::{errors::Handler, sync::Lrc, BytePos, FileName, SourceFile, SourceMap, Span}; +use swc_error_reporters::{GraphicalReportHandler, PrettyEmitter, PrettyEmitterConfig}; + +fn main() { + let cm = Lrc::::default(); + + let wr = Box::new(LockedWriter::default()); + + let emitter = PrettyEmitter::new( + cm.clone(), + wr.clone(), + GraphicalReportHandler::new(), + PrettyEmitterConfig { + skip_filename: false, + }, + ); + // let e_wr = EmitterWriter::new(wr.clone(), Some(cm), false, + // true).skip_filename(skip_filename); + let handler = Handler::with_emitter(true, false, Box::new(emitter)); + + let fm1 = cm.new_source_file(FileName::Custom("foo.js".into()), "13579".into()); + let fm2 = cm.new_source_file(FileName::Custom("bar.js".into()), "02468".into()); + + // This is a simple example. + handler + .struct_span_err(span(&fm1, 0, 3), "simple message") + .emit(); + + // We can show other file. + // This can be used to show configurable error with the config. + + handler + .struct_span_err(span(&fm1, 0, 3), "constraint violation") + .span_note(span(&fm2, 0, 1), "this is your config") + .emit(); + + let s = &**wr.0.lock().unwrap(); + + println!("{}", s); +} + +/// Don't do this in your real app. You should use [Span] created by parser +fn span(base: &SourceFile, lo: u32, hi: u32) -> Span { + let lo = base.start_pos.0 + lo; + let hi = base.start_pos.0 + hi; + + Span::new(BytePos(lo), BytePos(hi), Default::default()) +} + +#[derive(Clone, Default)] +struct LockedWriter(Arc>); + +impl fmt::Write for LockedWriter { + fn write_str(&mut self, s: &str) -> fmt::Result { + self.0.lock().unwrap().push_str(s); + Ok(()) + } +}