From bdb4392aa3a70837a9a51f39a81a8a8a842a4cf4 Mon Sep 17 00:00:00 2001 From: owjs3901 Date: Mon, 7 Jul 2025 12:26:05 +0900 Subject: [PATCH 1/2] Fix classname --- libs/extractor/src/lib.rs | 94 +++++++++++++++++++ libs/extractor/src/prop_modify_utils.rs | 92 ++++++++++++------ ...ractor__tests__props_multi_expression.snap | 81 ++++++++++++++++ ...ctor__tests__template_literal_props-5.snap | 8 ++ ...ctor__tests__template_literal_props-6.snap | 35 +++++++ 5 files changed, 281 insertions(+), 29 deletions(-) create mode 100644 libs/extractor/src/snapshots/extractor__tests__props_multi_expression.snap create mode 100644 libs/extractor/src/snapshots/extractor__tests__template_literal_props-5.snap create mode 100644 libs/extractor/src/snapshots/extractor__tests__template_literal_props-6.snap diff --git a/libs/extractor/src/lib.rs b/libs/extractor/src/lib.rs index 7dc9233a..4758389b 100644 --- a/libs/extractor/src/lib.rs +++ b/libs/extractor/src/lib.rs @@ -2673,6 +2673,66 @@ e(o, { className: "a", bg: variable, style: { color: "blue" }, ...props }) )); } + // #[test] + // #[serial] + // fn props_multi_expression_1() { + // assert_debug_snapshot!(ToBTreeSet::from( + // extract( + // "test.tsx", + // r#"import {Box as C} from '@devup-ui/core' + // + // "#, + // ExtractOption { + // package: "@devup-ui/core".to_string(), + // css_file: None + // } + // ) + // .unwrap() + // )); + // } + #[test] + #[serial] + fn props_multi_expression() { + reset_class_map(); + assert_debug_snapshot!(ToBTreeSet::from( + extract( + "test.jsx", + r#"import { + Box, + Button as DevupButton, + Center, + css, +} from '@devup-ui/core' + + +"#, + ExtractOption { + package: "@devup-ui/core".to_string(), + css_file: None + } + ) + .unwrap() + )); + } + #[test] #[serial] fn props_direct_object_select() { @@ -3161,6 +3221,40 @@ import {Button} from '@devup/ui' ) .unwrap() )); + + reset_class_map(); + assert_debug_snapshot!(ToBTreeSet::from( + extract( + "test.jsx", + r#"import {Box} from '@devup-ui/core' + + "#, + ExtractOption { + package: "@devup-ui/core".to_string(), + css_file: None + } + ) + .unwrap() + )); + + reset_class_map(); + assert_debug_snapshot!(ToBTreeSet::from( + extract( + "test.jsx", + r#"import {Box} from '@devup-ui/core' + + "#, + ExtractOption { + package: "@devup-ui/core".to_string(), + css_file: None + } + ) + .unwrap() + )); } #[test] diff --git a/libs/extractor/src/prop_modify_utils.rs b/libs/extractor/src/prop_modify_utils.rs index e653403f..16290ea8 100644 --- a/libs/extractor/src/prop_modify_utils.rs +++ b/libs/extractor/src/prop_modify_utils.rs @@ -233,7 +233,12 @@ fn merge_string_expressions<'a>( if expressions.is_empty() { return None; } - if expressions.len() == 1 { + if expressions.len() == 1 + && !matches!( + expressions.first().unwrap(), + Expression::StringLiteral(_) | Expression::TemplateLiteral(_) + ) + { return Some(expressions.first().unwrap().clone_in(ast_builder.allocator)); } @@ -241,41 +246,70 @@ fn merge_string_expressions<'a>( let mut other_expressions = vec![]; let mut prev_str = String::new(); for (idx, ex) in expressions.iter().enumerate() { - if let Expression::StringLiteral(literal) = ex { - if !prev_str.trim().is_empty() { - prev_str.push(' '); + match ex { + Expression::StringLiteral(literal) => { + prev_str.push_str( + format!( + "{}{}", + if prev_str.trim().is_empty() && other_expressions.is_empty() { + "" + } else { + " " + }, + literal.value.trim() + ) + .as_str(), + ); } - prev_str.push_str(literal.value.trim()); - } else if let Expression::TemplateLiteral(template) = ex { - for (idx, q) in template.quasis.iter().enumerate() { - if idx == 0 { - if !prev_str.trim().is_empty() { - prev_str.push(' '); - } - prev_str.push_str(&q.value.raw); - } else { - if !prev_str.trim().is_empty() { - string_literals.push(prev_str.clone()); - } - if q.tail { - prev_str = format!("{} ", q.value.raw); + Expression::TemplateLiteral(template) => { + for (idx, q) in template.quasis.iter().enumerate() { + if !prev_str.is_empty() { + string_literals.push(format!( + "{}{}{}{}", + prev_str.trim(), + if !prev_str.trim().is_empty() { " " } else { "" }, + q.value.raw.trim(), + if idx == template.quasis.len() - 1 { + "" + } else { + " " + } + )); + prev_str = String::new(); + } else if q.tail { + prev_str = q.value.raw.trim().to_string(); } else { - string_literals.push(q.value.raw.into()); + string_literals.push(format!( + "{}{}{}", + if idx == 0 + && other_expressions.is_empty() + && string_literals.is_empty() + { + "" + } else { + " " + }, + q.value.raw.trim(), + if q.value.raw.trim().is_empty() || !q.value.raw.ends_with(' ') { + "" + } else { + " " + } + )); prev_str = String::new(); } } + other_expressions.extend(template.expressions.clone_in(ast_builder.allocator)); } - other_expressions.extend(template.expressions.clone_in(ast_builder.allocator)); - } else { - if !prev_str.ends_with(' ') { - string_literals.push(format!("{}{}", prev_str, if idx > 0 { " " } else { "" })); - } else if idx > 0 { - string_literals.push(" ".to_string()); - } else { - string_literals.push("".to_string()); + ex => { + string_literals.push(format!( + "{}{}", + prev_str.trim(), + if idx > 0 { " " } else { "" } + )); + other_expressions.push(ex.clone_in(ast_builder.allocator)); + prev_str = String::new(); } - other_expressions.push(ex.clone_in(ast_builder.allocator)); - prev_str = " ".to_string(); } } if !prev_str.is_empty() { diff --git a/libs/extractor/src/snapshots/extractor__tests__props_multi_expression.snap b/libs/extractor/src/snapshots/extractor__tests__props_multi_expression.snap new file mode 100644 index 00000000..0fbb58e2 --- /dev/null +++ b/libs/extractor/src/snapshots/extractor__tests__props_multi_expression.snap @@ -0,0 +1,81 @@ +--- +source: libs/extractor/src/lib.rs +expression: "ToBTreeSet::from(extract(\"test.jsx\",\nr#\"import {\n Box,\n Button as DevupButton,\n Center,\n css,\n} from '@devup-ui/core'\n\n\n\"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap())" +--- +ToBTreeSet { + styles: { + Static( + ExtractStaticStyle { + property: "border", + value: "1px solid var(--border,#E4E4E4)", + level: 0, + selector: None, + style_order: None, + }, + ), + Static( + ExtractStaticStyle { + property: "border", + value: "none", + level: 0, + selector: None, + style_order: None, + }, + ), + Static( + ExtractStaticStyle { + property: "px", + value: "12px", + level: 0, + selector: None, + style_order: None, + }, + ), + Static( + ExtractStaticStyle { + property: "px", + value: "16px", + level: 0, + selector: None, + style_order: None, + }, + ), + Static( + ExtractStaticStyle { + property: "px", + value: "20px", + level: 0, + selector: None, + style_order: None, + }, + ), + Static( + ExtractStaticStyle { + property: "px", + value: "24px", + level: 0, + selector: None, + style_order: None, + }, + ), + Static( + ExtractStaticStyle { + property: "px", + value: "28px", + level: 0, + selector: None, + style_order: None, + }, + ), + Static( + ExtractStaticStyle { + property: "px", + value: "32px", + level: 0, + selector: None, + style_order: None, + }, + ), + }, + code: "import \"@devup-ui/core/devup-ui.css\";\n