use vize_croquis::macros::BUILTIN_MACROS;
pub fn is_macro_call_line(line: &str) -> bool {
let trimmed = line.trim();
if trimmed.starts_with("import") {
return false;
}
for macro_name in BUILTIN_MACROS {
if let Some(pos) = line.find(macro_name) {
let after = &line[pos + macro_name.len()..];
let after_trimmed = after.trim_start();
let is_call = after_trimmed.starts_with('(') || after_trimmed.starts_with('<');
if !is_call {
continue;
}
let before = &line[..pos];
let single_quotes = count_unescaped_quotes(before, '\'');
let double_quotes = count_unescaped_quotes(before, '"');
let backticks = count_unescaped_quotes(before, '`');
if single_quotes % 2 == 1 || double_quotes % 2 == 1 || backticks % 2 == 1 {
continue;
}
return true;
}
}
false
}
fn count_unescaped_quotes(s: &str, quote_char: char) -> usize {
let mut count = 0;
let mut escaped = false;
for c in s.chars() {
if escaped {
escaped = false;
} else if c == '\\' {
escaped = true;
} else if c == quote_char {
count += 1;
}
}
count
}
pub fn is_paren_macro_start(line: &str) -> bool {
let trimmed = line.trim();
if trimmed.starts_with("import") {
return false;
}
for macro_name in BUILTIN_MACROS {
if let Some(pos) = line.find(macro_name) {
let after = &line[pos + macro_name.len()..];
let after_trimmed = after.trim_start();
let is_call = after_trimmed.starts_with('(') || after_trimmed.starts_with('<');
if !is_call {
continue;
}
let before = &line[..pos];
let single_quotes = count_unescaped_quotes(before, '\'');
let double_quotes = count_unescaped_quotes(before, '"');
let backticks = count_unescaped_quotes(before, '`');
if single_quotes % 2 == 1 || double_quotes % 2 == 1 || backticks % 2 == 1 {
continue;
}
if line.contains('(') {
let open_count = line.matches('(').count();
let close_count = line.matches(')').count();
if open_count > close_count {
return true;
}
}
}
}
false
}
pub fn is_multiline_macro_start(line: &str) -> bool {
let trimmed = line.trim();
if trimmed.starts_with("import") {
return false;
}
for macro_name in BUILTIN_MACROS {
if let Some(pos) = line.find(macro_name) {
let after = &line[pos + macro_name.len()..];
let after_trimmed = after.trim_start();
let is_call = after_trimmed.starts_with('(') || after_trimmed.starts_with('<');
if !is_call {
continue;
}
let before = &line[..pos];
let single_quotes = count_unescaped_quotes(before, '\'');
let double_quotes = count_unescaped_quotes(before, '"');
let backticks = count_unescaped_quotes(before, '`');
if single_quotes % 2 == 1 || double_quotes % 2 == 1 || backticks % 2 == 1 {
continue;
}
if line.contains('<') {
let open_count = line.matches('<').count();
let close_count = line.matches('>').count();
if open_count > close_count {
return true;
}
if open_count == close_count && !line.contains("()") && !line.ends_with(')') {
if !trimmed.ends_with("()") && !trimmed.ends_with(')') {
return true;
}
}
}
}
}
false
}
pub fn is_props_destructure_line(line: &str) -> bool {
let trimmed = line.trim();
(trimmed.starts_with("const {") || trimmed.starts_with("let {") || trimmed.starts_with("var {"))
&& (trimmed.contains("defineProps") || trimmed.contains("withDefaults"))
}