diff --git a/Cargo.lock b/Cargo.lock index 809a38375..ef60ff749 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1335,7 +1335,7 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "modularize_imports" -version = "0.70.1" +version = "0.71.0" dependencies = [ "convert_case", "handlebars", @@ -2352,7 +2352,7 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "styled_components" -version = "0.98.2" +version = "0.99.0" dependencies = [ "Inflector", "once_cell", @@ -2373,7 +2373,7 @@ dependencies = [ [[package]] name = "styled_jsx" -version = "0.75.2" +version = "0.76.0" dependencies = [ "anyhow", "lightningcss", @@ -2997,7 +2997,7 @@ dependencies = [ [[package]] name = "swc_emotion" -version = "0.74.2" +version = "0.75.0" dependencies = [ "base64 0.22.1", "byteorder", diff --git a/packages/emotion/CHANGELOG.md b/packages/emotion/CHANGELOG.md index 890445cbb..cdfbd3ea2 100644 --- a/packages/emotion/CHANGELOG.md +++ b/packages/emotion/CHANGELOG.md @@ -1,5 +1,17 @@ # @swc/plugin-emotion +## 8.3.0 + +### Minor Changes + +- 4e7336c: Remove needless allocations + +## 8.2.0 + +### Minor Changes + +- 54b4a1a: Remove needless allocations + ## 8.1.0 ### Minor Changes diff --git a/packages/emotion/README.md b/packages/emotion/README.md index 7bcbde38f..e8087840a 100644 --- a/packages/emotion/README.md +++ b/packages/emotion/README.md @@ -34,6 +34,18 @@ Source code for plugin itself (not transforms) are copied from https://github.co # @swc/plugin-emotion +## 8.3.0 + +### Minor Changes + +- 4e7336c: Remove needless allocations + +## 8.2.0 + +### Minor Changes + +- 54b4a1a: Remove needless allocations + ## 8.1.0 ### Minor Changes diff --git a/packages/emotion/package.json b/packages/emotion/package.json index a182b604d..1f943f9f4 100644 --- a/packages/emotion/package.json +++ b/packages/emotion/package.json @@ -1,6 +1,6 @@ { "name": "@swc/plugin-emotion", - "version": "8.1.0", + "version": "8.3.0", "description": "SWC plugin for emotion css-in-js library", "main": "swc_plugin_emotion.wasm", "scripts": { diff --git a/packages/emotion/src/lib.rs b/packages/emotion/src/lib.rs index 8f4cbcbb2..12e536b4f 100644 --- a/packages/emotion/src/lib.rs +++ b/packages/emotion/src/lib.rs @@ -73,7 +73,7 @@ pub fn process_transform(program: Program, data: TransformPluginProgramMetadata) let pos = source_map.lookup_char_pos(program.span().lo); let hash = pos.file.src_hash as u32; program.apply(swc_emotion::emotion( - config, + &config, path, hash, source_map, diff --git a/packages/emotion/transform/Cargo.toml b/packages/emotion/transform/Cargo.toml index 08a3984ec..850f9975a 100644 --- a/packages/emotion/transform/Cargo.toml +++ b/packages/emotion/transform/Cargo.toml @@ -7,7 +7,7 @@ license = { workspace = true } name = "swc_emotion" repository = { workspace = true } rust-version = { workspace = true } -version = "0.74.2" +version = "0.75.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/emotion/transform/src/lib.rs b/packages/emotion/transform/src/lib.rs index f2f7d677a..87bcb7453 100644 --- a/packages/emotion/transform/src/lib.rs +++ b/packages/emotion/transform/src/lib.rs @@ -1,8 +1,4 @@ -use std::{ - borrow::Cow, - path::{Path, PathBuf}, - sync::Arc, -}; +use std::{borrow::Cow, path::Path, sync::Arc}; use base64::Engine; use once_cell::sync::Lazy; @@ -165,21 +161,24 @@ enum PackageMeta { Namespace(EmotionModuleConfig), } -pub fn emotion( - emotion_options: EmotionOptions, - path: &Path, +pub fn emotion<'a, C>( + emotion_options: &'a EmotionOptions, + path: &'a Path, src_file_hash: u32, cm: Arc, comments: C, -) -> impl Pass { +) -> impl 'a + Pass +where + C: 'a + Comments, +{ EmotionTransformer::new(emotion_options, path, src_file_hash, cm, comments) } -pub struct EmotionTransformer { - pub options: EmotionOptions, +pub struct EmotionTransformer<'a, C: Comments> { + pub options: &'a EmotionOptions, #[allow(unused)] filepath_hash: Option, - filepath: PathBuf, + filepath: &'a Path, dirname: Option, filename: Option, src_file_hash: u32, @@ -196,10 +195,10 @@ pub struct EmotionTransformer { } #[swc_trace] -impl EmotionTransformer { - pub fn new( - options: EmotionOptions, - path: &Path, +impl<'a, C: Comments> EmotionTransformer<'a, C> { + fn new( + options: &'a EmotionOptions, + path: &'a Path, src_file_hash: u32, cm: Arc, comments: C, @@ -212,7 +211,7 @@ impl EmotionTransformer { EmotionTransformer { options, filepath_hash: None, - filepath: path.to_owned(), + filepath: path, src_file_hash, dirname: path .parent() @@ -455,7 +454,7 @@ impl EmotionTransformer { } } -impl Fold for EmotionTransformer { +impl Fold for EmotionTransformer<'_, C> { fn fold_call_expr(&mut self, mut expr: CallExpr) -> CallExpr { // If no package that we care about is imported, skip the following // transformation logic. @@ -987,7 +986,7 @@ fn remove_space_around_colon(input: &str, is_first_item: bool, is_last_item: boo ) } -impl Pass for EmotionTransformer +impl Pass for EmotionTransformer<'_, C> where C: Comments, { diff --git a/packages/emotion/transform/tests/fixture.rs b/packages/emotion/transform/tests/fixture.rs index d82a02104..42e1b859b 100644 --- a/packages/emotion/transform/tests/fixture.rs +++ b/packages/emotion/transform/tests/fixture.rs @@ -18,6 +18,19 @@ fn ts_syntax() -> Syntax { #[fixture("tests/fixture/**/input.tsx")] fn next_emotion_fixture(input: PathBuf) { let output = input.parent().unwrap().join("output.ts"); + + let test_import_map = serde_json::from_str(include_str!("./testImportMap.json")).unwrap(); + + let options = EmotionOptions { + enabled: Some(true), + sourcemap: Some(true), + auto_label: Some(true), + import_map: Some(test_import_map), + ..Default::default() + }; + + let path = PathBuf::from("input.ts"); + test_fixture( ts_syntax(), &|tr| { @@ -37,19 +50,11 @@ fn next_emotion_fixture(input: PathBuf) { unresolved_mark, ); - let test_import_map = - serde_json::from_str(include_str!("./testImportMap.json")).unwrap(); let fm = tr.cm.load_file(&input).unwrap(); ( swc_emotion::emotion( - EmotionOptions { - enabled: Some(true), - sourcemap: Some(true), - auto_label: Some(true), - import_map: Some(test_import_map), - ..Default::default() - }, - &PathBuf::from("input.ts"), + &options, + &path, fm.src_hash as u32, tr.cm.clone(), tr.comments.as_ref().clone(), @@ -96,6 +101,15 @@ fn emotion_label_option_fixture(output: PathBuf) { format!("[{output_folder_name}]").into() }; + let options = EmotionOptions { + enabled: Some(true), + sourcemap: Some(true), + auto_label: Some(true), + label_format: Some(label_option.clone()), + ..Default::default() + }; + let file_name = PathBuf::from(format!("{output_folder_name}/index.tsx")); + test_fixture( ts_syntax(), &|tr| { @@ -117,14 +131,8 @@ fn emotion_label_option_fixture(output: PathBuf) { let fm: std::sync::Arc = tr.cm.load_file(&input).unwrap(); ( swc_emotion::emotion( - EmotionOptions { - enabled: Some(true), - sourcemap: Some(true), - auto_label: Some(true), - label_format: Some(label_option.clone()), - ..Default::default() - }, - &PathBuf::from(format!("{output_folder_name}/index.tsx")), + &options, + &file_name, fm.src_hash as u32, tr.cm.clone(), tr.comments.as_ref().clone(), @@ -161,6 +169,16 @@ fn emotion_label(input: PathBuf, label: String) { let mut output = PathBuf::from(&input); output.set_extension("js"); + let options = EmotionOptions { + enabled: Some(true), + sourcemap: Some(true), + auto_label: Some(true), + label_format: Some(label.clone().into()), + ..Default::default() + }; + + let file_name = PathBuf::from(format!("{output_folder_name}/{input_file_name}")); + test_fixture( ts_syntax(), &|tr| { @@ -182,14 +200,8 @@ fn emotion_label(input: PathBuf, label: String) { let fm = tr.cm.load_file(&input).unwrap(); ( swc_emotion::emotion( - EmotionOptions { - enabled: Some(true), - sourcemap: Some(true), - auto_label: Some(true), - label_format: Some(label.clone().into()), - ..Default::default() - }, - &PathBuf::from(format!("{output_folder_name}/{input_file_name}")), + &options, + &file_name, fm.src_hash as u32, tr.cm.clone(), tr.comments.as_ref().clone(), diff --git a/packages/styled-components/CHANGELOG.md b/packages/styled-components/CHANGELOG.md index 6839c1c36..364469764 100644 --- a/packages/styled-components/CHANGELOG.md +++ b/packages/styled-components/CHANGELOG.md @@ -1,5 +1,17 @@ # @swc/plugin-styled-components +## 6.3.0 + +### Minor Changes + +- 4e7336c: Remove needless allocations + +## 6.2.0 + +### Minor Changes + +- 54b4a1a: Remove needless allocations + ## 6.1.0 ### Minor Changes diff --git a/packages/styled-components/README.md b/packages/styled-components/README.md index 29774492e..755fe33d9 100644 --- a/packages/styled-components/README.md +++ b/packages/styled-components/README.md @@ -28,6 +28,18 @@ Then update your `.swcrc` file like below: # @swc/plugin-styled-components +## 6.3.0 + +### Minor Changes + +- 4e7336c: Remove needless allocations + +## 6.2.0 + +### Minor Changes + +- 54b4a1a: Remove needless allocations + ## 6.1.0 ### Minor Changes diff --git a/packages/styled-components/package.json b/packages/styled-components/package.json index f627a147f..42b5fade1 100644 --- a/packages/styled-components/package.json +++ b/packages/styled-components/package.json @@ -1,6 +1,6 @@ { "name": "@swc/plugin-styled-components", - "version": "6.1.0", + "version": "6.3.0", "description": "SWC plugin for styled-components", "main": "swc_plugin_styled_components.wasm", "scripts": { diff --git a/packages/styled-components/src/lib.rs b/packages/styled-components/src/lib.rs index b99f50e2a..8d4cb74f9 100644 --- a/packages/styled-components/src/lib.rs +++ b/packages/styled-components/src/lib.rs @@ -33,9 +33,12 @@ fn styled_components(mut program: Program, data: TransformPluginProgramMetadata) let pos = data.source_map.lookup_char_pos(program.span().lo); let hash = pos.file.src_hash; - let pass = styled_components::styled_components(file_name, hash, config, PluginCommentsProxy); - - program.mutate(pass); + program.mutate(styled_components::styled_components( + &file_name, + hash, + &config, + PluginCommentsProxy, + )); program } diff --git a/packages/styled-components/transform/Cargo.toml b/packages/styled-components/transform/Cargo.toml index 1ae7697a4..0ed9b7f4f 100644 --- a/packages/styled-components/transform/Cargo.toml +++ b/packages/styled-components/transform/Cargo.toml @@ -12,7 +12,7 @@ homepage = { workspace = true } license = { workspace = true } repository = { workspace = true } rust-version = { workspace = true } -version = "0.98.2" +version = "0.99.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/styled-components/transform/src/lib.rs b/packages/styled-components/transform/src/lib.rs index 6183733ea..b7a1a7a46 100644 --- a/packages/styled-components/transform/src/lib.rs +++ b/packages/styled-components/transform/src/lib.rs @@ -1,6 +1,6 @@ #![deny(unused)] -use std::{cell::RefCell, rc::Rc, sync::Arc}; +use std::{cell::RefCell, rc::Rc}; use serde::Deserialize; use swc_atoms::JsWord; @@ -71,20 +71,19 @@ impl Config { } } -pub fn styled_components( - file_name: Arc, +pub fn styled_components<'a, C>( + file_name: &'a FileName, src_file_hash: u128, - config: Config, + config: &'a Config, comments: C, -) -> impl Pass +) -> impl 'a + Pass where - C: Comments, + C: 'a + Comments, { let state: Rc> = Default::default(); - let config = Rc::new(config); ( - analyzer(config.clone(), state.clone()), + analyzer(config, state.clone()), Optional { enabled: config.css_prop, visitor: transpile_css_prop(state.clone()), @@ -95,7 +94,7 @@ where enabled: config.minify, visitor: minify(state.clone()), }, - display_name_and_id(file_name, src_file_hash, config.clone(), state.clone()), + display_name_and_id(file_name, src_file_hash, config, state.clone()), Optional { enabled: config.transpile_template_literals, visitor: template_literals(state.clone()), diff --git a/packages/styled-components/transform/src/utils/analyzer.rs b/packages/styled-components/transform/src/utils/analyzer.rs index 3aee5b3ce..436ee1ddb 100644 --- a/packages/styled-components/transform/src/utils/analyzer.rs +++ b/packages/styled-components/transform/src/utils/analyzer.rs @@ -8,21 +8,21 @@ use swc_ecma_visit::{ use super::State; use crate::Config; -pub fn analyzer(config: Rc, state: Rc>) -> impl Pass + VisitMut { +pub fn analyzer(config: &Config, state: Rc>) -> impl '_ + Pass { visit_mut_pass(AsAnalyzer { config, state }) } -struct AsAnalyzer { - config: Rc, +struct AsAnalyzer<'a> { + config: &'a Config, state: Rc>, } -impl VisitMut for AsAnalyzer { +impl VisitMut for AsAnalyzer<'_> { noop_visit_mut_type!(); fn visit_mut_module(&mut self, p: &mut Module) { let mut v = Analyzer { - config: &self.config, + config: self.config, state: &mut self.state.borrow_mut(), }; @@ -31,7 +31,7 @@ impl VisitMut for AsAnalyzer { fn visit_mut_script(&mut self, p: &mut Script) { let mut v = Analyzer { - config: &self.config, + config: self.config, state: &mut self.state.borrow_mut(), }; diff --git a/packages/styled-components/transform/src/visitors/display_name_and_id.rs b/packages/styled-components/transform/src/visitors/display_name_and_id.rs index 35e856192..2cf115df4 100644 --- a/packages/styled-components/transform/src/visitors/display_name_and_id.rs +++ b/packages/styled-components/transform/src/visitors/display_name_and_id.rs @@ -1,4 +1,4 @@ -use std::{cell::RefCell, convert::TryInto, path::Path, rc::Rc, sync::Arc}; +use std::{cell::RefCell, convert::TryInto, path::Path, rc::Rc}; use once_cell::sync::Lazy; use regex::Regex; @@ -14,12 +14,12 @@ use crate::{ Config, }; -pub fn display_name_and_id( - file_name: Arc, +pub fn display_name_and_id<'a>( + file_name: &'a FileName, src_file_hash: u128, - config: Rc, + config: &'a Config, state: Rc>, -) -> impl Pass + VisitMut { +) -> impl 'a + Pass { visit_mut_pass(DisplayNameAndId { file_name, src_file_hash, @@ -35,11 +35,11 @@ static DISPLAY_NAME_REGEX: Lazy = Lazy::new(|| Regex::new(r"^[a-zA-Z][a-zA-Z0-9]$").unwrap()); #[derive(Debug)] -struct DisplayNameAndId { - file_name: Arc, +struct DisplayNameAndId<'a> { + file_name: &'a FileName, src_file_hash: u128, - config: Rc, + config: &'a Config, state: Rc>, cur_display_name: Option, @@ -47,7 +47,7 @@ struct DisplayNameAndId { component_id: usize, } -impl DisplayNameAndId { +impl DisplayNameAndId<'_> { fn get_block_name(&self, p: &Path) -> String { match p.file_stem().map(|s| s.to_string_lossy()) { Some(file_stem) @@ -69,7 +69,7 @@ impl DisplayNameAndId { fn get_display_name(&mut self, _: &Expr) -> JsWord { let component_name = self.cur_display_name.clone().unwrap_or(js_word!("")); - match &*self.file_name { + match self.file_name { FileName::Real(f) if self.config.file_name => { let block_name = self.get_block_name(f); @@ -230,7 +230,7 @@ impl DisplayNameAndId { } } -impl VisitMut for DisplayNameAndId { +impl VisitMut for DisplayNameAndId<'_> { noop_visit_mut_type!(); fn visit_mut_assign_expr(&mut self, e: &mut AssignExpr) { diff --git a/packages/styled-components/transform/src/visitors/minify/visitor.rs b/packages/styled-components/transform/src/visitors/minify/visitor.rs index 17a214393..87c811ec0 100644 --- a/packages/styled-components/transform/src/visitors/minify/visitor.rs +++ b/packages/styled-components/transform/src/visitors/minify/visitor.rs @@ -9,7 +9,7 @@ use swc_ecma_visit::{noop_visit_mut_type, visit_mut_pass, VisitMut, VisitMutWith use super::css::{minify_raw_values, MinifyResult}; use crate::utils::State; -pub fn minify(state: Rc>) -> impl Pass + VisitMut { +pub fn minify(state: Rc>) -> impl Pass { visit_mut_pass(Minify { state }) } diff --git a/packages/styled-components/transform/src/visitors/pure_annotation.rs b/packages/styled-components/transform/src/visitors/pure_annotation.rs index 20671aa0b..f226c3b2f 100644 --- a/packages/styled-components/transform/src/visitors/pure_annotation.rs +++ b/packages/styled-components/transform/src/visitors/pure_annotation.rs @@ -8,7 +8,7 @@ use swc_ecma_visit::{noop_visit_mut_type, visit_mut_pass, VisitMut, VisitMutWith use crate::utils::State; -pub fn pure_annotation(comments: C, state: Rc>) -> impl Pass + VisitMut +pub fn pure_annotation(comments: C, state: Rc>) -> impl Pass where C: Comments, { diff --git a/packages/styled-components/transform/src/visitors/template_literals.rs b/packages/styled-components/transform/src/visitors/template_literals.rs index 880d6594f..e119fb5a1 100644 --- a/packages/styled-components/transform/src/visitors/template_literals.rs +++ b/packages/styled-components/transform/src/visitors/template_literals.rs @@ -8,7 +8,7 @@ use swc_ecma_visit::{noop_visit_mut_type, visit_mut_pass, VisitMut, VisitMutWith use crate::utils::State; -pub fn template_literals(state: Rc>) -> impl Pass + VisitMut { +pub fn template_literals(state: Rc>) -> impl Pass { visit_mut_pass(TemplateLiterals { state }) } diff --git a/packages/styled-components/transform/src/visitors/transpile_css_prop/transpile.rs b/packages/styled-components/transform/src/visitors/transpile_css_prop/transpile.rs index 249de73be..65a37d7eb 100644 --- a/packages/styled-components/transform/src/visitors/transpile_css_prop/transpile.rs +++ b/packages/styled-components/transform/src/visitors/transpile_css_prop/transpile.rs @@ -24,7 +24,7 @@ use crate::{ static TAG_NAME_REGEX: Lazy = Lazy::new(|| Regex::new("^[a-z][a-z\\d]*(\\-[a-z][a-z\\d]*)?$").unwrap()); -pub fn transpile_css_prop(state: Rc>) -> impl Pass + VisitMut { +pub fn transpile_css_prop(state: Rc>) -> impl Pass { visit_mut_pass(TranspileCssProp { state, ..Default::default() diff --git a/packages/styled-components/transform/tests/fixture.rs b/packages/styled-components/transform/tests/fixture.rs index b1f279d42..92ae30902 100644 --- a/packages/styled-components/transform/tests/fixture.rs +++ b/packages/styled-components/transform/tests/fixture.rs @@ -3,7 +3,7 @@ use std::{fs::read_to_string, path::PathBuf}; use styled_components::{styled_components, Config}; -use swc_common::Mark; +use swc_common::{FileName, Mark}; use swc_ecma_parser::{EsSyntax, Syntax}; use swc_ecma_transforms::resolver; use swc_ecma_transforms_testing::{test_fixture, FixtureTestConfig}; @@ -15,6 +15,8 @@ fn fixture(input: PathBuf) { println!("---- Config -----\n{}", config); let config: Config = serde_json::from_str(&config).unwrap(); + let file_name = FileName::Real(input.clone()); + test_fixture( Syntax::Es(EsSyntax { jsx: true, @@ -26,12 +28,7 @@ fn fixture(input: PathBuf) { ( resolver(Mark::new(), Mark::new(), false), - styled_components( - fm.name.clone(), - fm.src_hash, - config.clone(), - t.comments.clone(), - ), + styled_components(&file_name, fm.src_hash, &config, t.comments.clone()), ) }, &input, diff --git a/packages/styled-jsx/CHANGELOG.md b/packages/styled-jsx/CHANGELOG.md index 492851840..b64baaa30 100644 --- a/packages/styled-jsx/CHANGELOG.md +++ b/packages/styled-jsx/CHANGELOG.md @@ -1,5 +1,17 @@ # @swc/plugin-styled-jsx +## 6.3.0 + +### Minor Changes + +- 4e7336c: Remove needless allocations + +## 6.2.0 + +### Minor Changes + +- 54b4a1a: Remove needless allocations + ## 6.1.0 ### Minor Changes diff --git a/packages/styled-jsx/README.md b/packages/styled-jsx/README.md index 646a78509..f14ef1c08 100644 --- a/packages/styled-jsx/README.md +++ b/packages/styled-jsx/README.md @@ -2,6 +2,18 @@ # @swc/plugin-styled-jsx +## 6.3.0 + +### Minor Changes + +- 4e7336c: Remove needless allocations + +## 6.2.0 + +### Minor Changes + +- 54b4a1a: Remove needless allocations + ## 6.1.0 ### Minor Changes diff --git a/packages/styled-jsx/package.json b/packages/styled-jsx/package.json index 904d62015..d177609e4 100644 --- a/packages/styled-jsx/package.json +++ b/packages/styled-jsx/package.json @@ -1,6 +1,6 @@ { "name": "@swc/plugin-styled-jsx", - "version": "6.1.0", + "version": "6.3.0", "description": "SWC plugin for styled-jsx", "main": "swc_plugin_styled_jsx.wasm", "scripts": { diff --git a/packages/styled-jsx/src/lib.rs b/packages/styled-jsx/src/lib.rs index c5b1f7fa3..408f0c537 100644 --- a/packages/styled-jsx/src/lib.rs +++ b/packages/styled-jsx/src/lib.rs @@ -4,7 +4,7 @@ use styled_jsx::{visitor, visitor::Config}; use swc_core::{ common::{sync::Lrc, FileName, SourceMap}, - ecma::{ast::Program, visit::FoldWith}, + ecma::ast::Program, plugin::{plugin_transform, proxies::TransformPluginProgramMetadata}, }; @@ -20,10 +20,10 @@ fn styled_jsx_plugin(program: Program, data: TransformPluginProgramMetadata) -> // TODO(kdy1): This is wrong, but it does not use cm let cm = Lrc::new(SourceMap::default()); - program.fold_with(&mut visitor::styled_jsx( + program.apply(visitor::styled_jsx( cm, - FileName::Anon, - config, - Default::default(), + &FileName::Anon, + &config, + &Default::default(), )) } diff --git a/packages/styled-jsx/transform/Cargo.toml b/packages/styled-jsx/transform/Cargo.toml index 4d674da15..dc2224193 100644 --- a/packages/styled-jsx/transform/Cargo.toml +++ b/packages/styled-jsx/transform/Cargo.toml @@ -10,7 +10,7 @@ license = { workspace = true } name = "styled_jsx" repository = { workspace = true } rust-version = { workspace = true } -version = "0.75.2" +version = "0.76.0" [features] diff --git a/packages/styled-jsx/transform/src/visitor.rs b/packages/styled-jsx/transform/src/visitor.rs index 9fd66fb04..6fa0efc68 100644 --- a/packages/styled-jsx/transform/src/visitor.rs +++ b/packages/styled-jsx/transform/src/visitor.rs @@ -62,12 +62,12 @@ impl NativeConfig<'_> { } } -pub fn styled_jsx( +pub fn styled_jsx<'a>( cm: Arc, - file_name: FileName, - config: Config, - native_config: NativeConfig<'_>, -) -> impl '_ + Pass + Fold { + file_name: &'a FileName, + config: &'a Config, + native_config: &'a NativeConfig<'a>, +) -> impl 'a + Pass { let file_name = match file_name { FileName::Real(real_file_name) => real_file_name .to_str() @@ -102,8 +102,8 @@ pub fn styled_jsx( struct StyledJSXTransformer<'a> { cm: Arc, - config: Config, - native_config: NativeConfig<'a>, + config: &'a Config, + native_config: &'a NativeConfig<'a>, file_name: Option, styles: Vec, @@ -617,7 +617,7 @@ impl StyledJSXTransformer<'_> { is_global, &self.static_class_name, &self.config.browsers, - &self.native_config, + self.native_config, )? } else { crate::transform_css_swc::transform_css( @@ -625,7 +625,7 @@ impl StyledJSXTransformer<'_> { style_info, is_global, &self.static_class_name, - &self.native_config, + self.native_config, )? }; @@ -685,7 +685,7 @@ impl StyledJSXTransformer<'_> { tag == "global", &static_class_name, &self.config.browsers, - &self.native_config, + self.native_config, )? } else { crate::transform_css_swc::transform_css( @@ -693,7 +693,7 @@ impl StyledJSXTransformer<'_> { style, tag == "global", &static_class_name, - &self.native_config, + self.native_config, )? }; if tag == "resolve" { diff --git a/packages/styled-jsx/transform/tests/fixture.rs b/packages/styled-jsx/transform/tests/fixture.rs index af4a61eba..c5defaae4 100644 --- a/packages/styled-jsx/transform/tests/fixture.rs +++ b/packages/styled-jsx/transform/tests/fixture.rs @@ -24,65 +24,65 @@ fn run(input: PathBuf, use_lightningcss: bool) { "output.swc.js" }); + let browsers = Versions { + chrome: Some("64".parse().unwrap()), + edge: Some("79".parse().unwrap()), + firefox: Some("67".parse().unwrap()), + opera: Some("51".parse().unwrap()), + safari: Some("12".parse().unwrap()), + + ..Default::default() + }; + + let file_name = FileName::Real(PathBuf::from("/some-project/src/some-file.js")); + let config = styled_jsx::visitor::Config { + use_lightningcss, + browsers, + }; + + let native_config = if use_lightningcss { + Default::default() + } else { + NativeConfig { + process_css: Some(Box::new(move |css| { + let ss = lightningcss::stylesheet::StyleSheet::parse( + css, + ParserOptions { + error_recovery: true, + ..Default::default() + }, + ); + + let ss = match ss { + Ok(v) => v, + Err(err) => { + bail!( + "failed to parse css using lightningcss: {}\nCode: {}", + err, + css + ) + } + }; + + let output = ss.to_css(lightningcss::stylesheet::PrinterOptions { + minify: true, + source_map: None, + project_root: None, + targets: Default::default(), + analyze_dependencies: None, + pseudo_classes: None, + })?; + Ok(output.code) + })), + } + }; + test_fixture( syntax(), &|t| { - let browsers = Versions { - chrome: Some("64".parse().unwrap()), - edge: Some("79".parse().unwrap()), - firefox: Some("67".parse().unwrap()), - opera: Some("51".parse().unwrap()), - safari: Some("12".parse().unwrap()), - - ..Default::default() - }; ( resolver(Mark::new(), Mark::new(), false), - styled_jsx( - t.cm.clone(), - FileName::Real(PathBuf::from("/some-project/src/some-file.js")), - styled_jsx::visitor::Config { - use_lightningcss, - browsers, - }, - if use_lightningcss { - Default::default() - } else { - NativeConfig { - process_css: Some(Box::new(move |css| { - let ss = lightningcss::stylesheet::StyleSheet::parse( - css, - ParserOptions { - error_recovery: true, - ..Default::default() - }, - ); - - let ss = match ss { - Ok(v) => v, - Err(err) => { - bail!( - "failed to parse css using lightningcss: {}\nCode: {}", - err, - css - ) - } - }; - - let output = - ss.to_css(lightningcss::stylesheet::PrinterOptions { - minify: true, - source_map: None, - project_root: None, - targets: Default::default(), - analyze_dependencies: None, - pseudo_classes: None, - })?; - Ok(output.code) - })), - } - }, - ), + styled_jsx(t.cm.clone(), &file_name, &config, &native_config), ) }, &input, @@ -120,20 +120,15 @@ fn styled_jsx_errors(input: PathBuf) { }; { let output = input.parent().unwrap().join("output-swc.js"); + let config = styled_jsx::visitor::Config { + use_lightningcss: false, + ..Default::default() + }; + let native_config = Default::default(); test_fixture( syntax(), - &|t| { - styled_jsx( - t.cm.clone(), - file_name.clone(), - styled_jsx::visitor::Config { - use_lightningcss: false, - ..Default::default() - }, - Default::default(), - ) - }, + &|t| styled_jsx(t.cm.clone(), &file_name, &config, &native_config), &input, &output, FixtureTestConfig { @@ -146,20 +141,15 @@ fn styled_jsx_errors(input: PathBuf) { { let output = input.parent().unwrap().join("output-lightningcss.js"); + let config = styled_jsx::visitor::Config { + use_lightningcss: true, + ..Default::default() + }; + let native_config = Default::default(); test_fixture( syntax(), - &|t| { - styled_jsx( - t.cm.clone(), - file_name.clone(), - styled_jsx::visitor::Config { - use_lightningcss: true, - ..Default::default() - }, - Default::default(), - ) - }, + &|t| styled_jsx(t.cm.clone(), &file_name, &config, &native_config), &input, &output, FixtureTestConfig { diff --git a/packages/transform-imports/CHANGELOG.md b/packages/transform-imports/CHANGELOG.md index 67e297a11..574cb8d9f 100644 --- a/packages/transform-imports/CHANGELOG.md +++ b/packages/transform-imports/CHANGELOG.md @@ -1,5 +1,11 @@ # @swc/plugin-transform-imports +## 6.1.0 + +### Minor Changes + +- 4e7336c: Remove needless allocations + ## 6.0.5 ### Patch Changes diff --git a/packages/transform-imports/README.md b/packages/transform-imports/README.md index 60bb072f2..98ab7112c 100644 --- a/packages/transform-imports/README.md +++ b/packages/transform-imports/README.md @@ -18,6 +18,12 @@ # @swc/plugin-transform-imports +## 6.1.0 + +### Minor Changes + +- 4e7336c: Remove needless allocations + ## 6.0.5 ### Patch Changes diff --git a/packages/transform-imports/package.json b/packages/transform-imports/package.json index 72a63ae0c..033762dbc 100644 --- a/packages/transform-imports/package.json +++ b/packages/transform-imports/package.json @@ -1,6 +1,6 @@ { "name": "@swc/plugin-transform-imports", - "version": "6.0.5", + "version": "6.1.0", "description": "SWC plugin for https://www.npmjs.com/package/babel-plugin-transform-imports", "main": "swc_plugin_transform_imports.wasm", "scripts": { diff --git a/packages/transform-imports/src/lib.rs b/packages/transform-imports/src/lib.rs index b8d2b26b4..334b3d66f 100644 --- a/packages/transform-imports/src/lib.rs +++ b/packages/transform-imports/src/lib.rs @@ -14,6 +14,6 @@ fn transform_imports_plugin(program: Program, data: TransformPluginProgramMetada .expect("invalid packages"); program.apply(modularize_imports::modularize_imports( - modularize_imports::Config { packages }, + &modularize_imports::Config { packages }, )) } diff --git a/packages/transform-imports/transform/Cargo.toml b/packages/transform-imports/transform/Cargo.toml index 921e7046e..38464874b 100644 --- a/packages/transform-imports/transform/Cargo.toml +++ b/packages/transform-imports/transform/Cargo.toml @@ -11,7 +11,7 @@ homepage = { workspace = true } license = { workspace = true } repository = { workspace = true } rust-version = { workspace = true } -version = "0.70.1" +version = "0.71.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/transform-imports/transform/src/lib.rs b/packages/transform-imports/transform/src/lib.rs index 1c64ba313..60f74c4a9 100644 --- a/packages/transform-imports/transform/src/lib.rs +++ b/packages/transform-imports/transform/src/lib.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::{borrow::Cow, collections::HashMap}; use convert_case::{Case, Casing}; use handlebars::{Context, Handlebars, Helper, HelperResult, Output, RenderContext}; @@ -51,13 +51,22 @@ impl From> for Transform { } } -struct FoldImports { - renderer: handlebars::Handlebars<'static>, - packages: Vec<(CachedRegex, PackageConfig)>, +struct FoldImports<'a> { + packages: Vec<(CachedRegex, &'a PackageConfig)>, } +static HANDLEBARS: Lazy = Lazy::new(|| { + let mut renderer = Handlebars::new(); + + renderer.register_helper("lowerCase", Box::new(helper_lower_case)); + renderer.register_helper("upperCase", Box::new(helper_upper_case)); + renderer.register_helper("camelCase", Box::new(helper_camel_case)); + renderer.register_helper("kebabCase", Box::new(helper_kebab_case)); + + renderer +}); + struct Rewriter<'a> { - renderer: &'a handlebars::Handlebars<'static>, key: &'a str, config: &'a PackageConfig, group: Vec<&'a str>, @@ -79,7 +88,7 @@ impl Rewriter<'_> { } let new_path = match &self.config.transform { - Transform::String(s) => self.renderer.render_template(s, &ctx).unwrap_or_else(|e| { + Transform::String(s) => HANDLEBARS.render_template(s, &ctx).unwrap_or_else(|e| { panic!("error rendering template for '{}': {}", self.key, e); }), Transform::Vec(v) => { @@ -114,7 +123,7 @@ impl Rewriter<'_> { .insert("memberMatches", CtxData::Array(&group[..])); result = Some( - self.renderer + HANDLEBARS .render_template(val, &ctx_with_member_matches) .unwrap_or_else(|e| { panic!( @@ -304,7 +313,7 @@ impl Rewriter<'_> { } } -impl FoldImports { +impl FoldImports<'_> { fn should_rewrite<'a>(&'a self, name: &'a str) -> Option> { for (regex, config) in &self.packages { let group = regex.captures(name); @@ -314,7 +323,6 @@ impl FoldImports { .map(|x| x.map(|x| x.as_str()).unwrap_or_default()) .collect::>(); return Some(Rewriter { - renderer: &self.renderer, key: name, config, group, @@ -354,7 +362,7 @@ impl FoldImports { } } -impl Fold for FoldImports { +impl Fold for FoldImports<'_> { noop_fold_type!(); fn fold_call_expr(&mut self, mut call: CallExpr) -> CallExpr { @@ -439,27 +447,14 @@ impl Fold for FoldImports { } } -pub fn modularize_imports(config: Config) -> impl Pass { - let mut folder = FoldImports { - renderer: handlebars::Handlebars::new(), - packages: vec![], - }; - folder - .renderer - .register_helper("lowerCase", Box::new(helper_lower_case)); - folder - .renderer - .register_helper("upperCase", Box::new(helper_upper_case)); - folder - .renderer - .register_helper("camelCase", Box::new(helper_camel_case)); - folder - .renderer - .register_helper("kebabCase", Box::new(helper_kebab_case)); - for (mut k, v) in config.packages { +pub fn modularize_imports(config: &Config) -> impl '_ + Pass { + let mut folder = FoldImports { packages: vec![] }; + + for (k, v) in &config.packages { + let mut k = Cow::Borrowed(k); // XXX: Should we keep this hack? if !k.starts_with('^') && !k.ends_with('$') { - k = format!("^{}$", k); + k = Cow::Owned(format!("^{}$", k)); } folder.packages.push(( CachedRegex::new(&k).expect("transform-imports: invalid regex"), diff --git a/packages/transform-imports/transform/tests/fixture.rs b/packages/transform-imports/transform/tests/fixture.rs index a24999783..cd034300a 100644 --- a/packages/transform-imports/transform/tests/fixture.rs +++ b/packages/transform-imports/transform/tests/fixture.rs @@ -15,104 +15,103 @@ fn syntax() -> Syntax { #[fixture("tests/fixture/**/input.js")] fn modularize_imports_fixture(input: PathBuf) { let output = input.parent().unwrap().join("output.js"); + let config = modularize_imports::Config { + packages: vec![ + ( + "react-bootstrap".to_string(), + PackageConfig { + transform: "react-bootstrap/lib/{{member}}".into(), + prevent_full_import: false, + skip_default_conversion: false, + handle_default_import: true, + handle_namespace_import: true, + }, + ), + ( + "my-library/?(((\\w*)?/?)*)".to_string(), + PackageConfig { + transform: "my-library/{{ matches.[1] }}/{{member}}".into(), + prevent_full_import: false, + skip_default_conversion: false, + handle_default_import: true, + handle_namespace_import: true, + }, + ), + ( + "my-library-2".to_string(), + PackageConfig { + transform: "my-library-2/{{ camelCase member }}".into(), + prevent_full_import: false, + skip_default_conversion: true, + handle_default_import: true, + handle_namespace_import: true, + }, + ), + ( + "my-library-3".to_string(), + PackageConfig { + transform: "my-library-3/{{ kebabCase member }}".into(), + prevent_full_import: false, + skip_default_conversion: true, + handle_default_import: true, + handle_namespace_import: true, + }, + ), + ( + "my-library-4".to_string(), + PackageConfig { + transform: Vec::from([ + ("foo".to_string(), "my-library-4/this_is_foo".to_string()), + ("bar".to_string(), "my-library-4/bar".to_string()), + ( + "use(\\w*)".to_string(), + "my-library-4/{{ kebabCase member }}/{{ kebabCase memberMatches.[1] }}" + .to_string(), + ), + ( + "(\\w*)Icon".to_string(), + "my-library-4/{{ kebabCase memberMatches.[1] }}".to_string(), + ), + ( + "*".to_string(), + "my-library-4/{{ upperCase member }}".to_string(), + ), + ]) + .into(), + prevent_full_import: false, + skip_default_conversion: true, + handle_default_import: true, + handle_namespace_import: true, + }, + ), + ( + "my-(module-namespace|default|mixed-(named|star))".to_string(), + PackageConfig { + transform: "transformed-{{matches.[1]}}".into(), + prevent_full_import: false, + skip_default_conversion: true, + handle_default_import: true, + handle_namespace_import: true, + }, + ), + ( + "^(\\..*)(\\.tsx?)$".to_string(), + PackageConfig { + transform: "{{matches.[1]}}.js".into(), + prevent_full_import: false, + skip_default_conversion: false, + handle_default_import: false, + handle_namespace_import: false, + }, + ), + ] + .into_iter() + .collect(), + }; + test_fixture( syntax(), - &|_tr| { - modularize_imports(modularize_imports::Config { - packages: vec![ - ( - "react-bootstrap".to_string(), - PackageConfig { - transform: "react-bootstrap/lib/{{member}}".into(), - prevent_full_import: false, - skip_default_conversion: false, - handle_default_import: true, - handle_namespace_import: true, - }, - ), - ( - "my-library/?(((\\w*)?/?)*)".to_string(), - PackageConfig { - transform: "my-library/{{ matches.[1] }}/{{member}}".into(), - prevent_full_import: false, - skip_default_conversion: false, - handle_default_import: true, - handle_namespace_import: true, - }, - ), - ( - "my-library-2".to_string(), - PackageConfig { - transform: "my-library-2/{{ camelCase member }}".into(), - prevent_full_import: false, - skip_default_conversion: true, - handle_default_import: true, - handle_namespace_import: true, - }, - ), - ( - "my-library-3".to_string(), - PackageConfig { - transform: "my-library-3/{{ kebabCase member }}".into(), - prevent_full_import: false, - skip_default_conversion: true, - handle_default_import: true, - handle_namespace_import: true, - }, - ), - ( - "my-library-4".to_string(), - PackageConfig { - transform: Vec::from([ - ("foo".to_string(), "my-library-4/this_is_foo".to_string()), - ("bar".to_string(), "my-library-4/bar".to_string()), - ( - "use(\\w*)".to_string(), - "my-library-4/{{ kebabCase member }}/{{ kebabCase \ - memberMatches.[1] }}" - .to_string(), - ), - ( - "(\\w*)Icon".to_string(), - "my-library-4/{{ kebabCase memberMatches.[1] }}".to_string(), - ), - ( - "*".to_string(), - "my-library-4/{{ upperCase member }}".to_string(), - ), - ]) - .into(), - prevent_full_import: false, - skip_default_conversion: true, - handle_default_import: true, - handle_namespace_import: true, - }, - ), - ( - "my-(module-namespace|default|mixed-(named|star))".to_string(), - PackageConfig { - transform: "transformed-{{matches.[1]}}".into(), - prevent_full_import: false, - skip_default_conversion: true, - handle_default_import: true, - handle_namespace_import: true, - }, - ), - ( - "^(\\..*)(\\.tsx?)$".to_string(), - PackageConfig { - transform: "{{matches.[1]}}.js".into(), - prevent_full_import: false, - skip_default_conversion: false, - handle_default_import: false, - handle_namespace_import: false, - }, - ), - ] - .into_iter() - .collect(), - }) - }, + &|_tr| modularize_imports(&config), &input, &output, FixtureTestConfig {