mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
perf(rust): use cow_utils instead (#5664)
Related to #5586 and #5662 --------- Co-authored-by: Boshen <boshenc@gmail.com>
This commit is contained in:
parent
a729b64380
commit
d18c896a2c
40 changed files with 146 additions and 78 deletions
|
|
@ -1,6 +1,10 @@
|
|||
ignore-interior-mutability = ["oxc_linter::rule::RuleWithSeverity"]
|
||||
|
||||
disallowed-methods = [
|
||||
{ path = "str::to_ascii_lowercase", reason = "Avoid memory allocation. Use `cow_utils::CowUtils::cow_to_ascii_lowercase` instead." },
|
||||
{ path = "str::to_ascii_uppercase", reason = "Avoid memory allocation. Use `cow_utils::CowUtils::cow_to_ascii_uppercase` instead." },
|
||||
{ path = "str::to_ascii_lowercase", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_to_ascii_lowercase` instead." },
|
||||
{ path = "str::to_ascii_uppercase", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_to_ascii_uppercase` instead." },
|
||||
{ path = "str::to_lowercase", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_to_lowercase` instead." },
|
||||
{ path = "str::to_uppercase", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_to_uppercase` instead." },
|
||||
{ path = "str::replace", reason = "To avoid memory allocation, use `cow_utils::CowUtils::replace` instead." },
|
||||
{ path = "str::replacen", reason = "To avoid memory allocation, use `cow_utils::CowUtils::replacen` instead." },
|
||||
]
|
||||
|
|
|
|||
5
Cargo.lock
generated
5
Cargo.lock
generated
|
|
@ -1525,6 +1525,7 @@ version = "0.28.0"
|
|||
dependencies = [
|
||||
"base64",
|
||||
"bitflags 2.6.0",
|
||||
"cow-utils",
|
||||
"daachorse",
|
||||
"insta",
|
||||
"nonmax",
|
||||
|
|
@ -1692,6 +1693,7 @@ dependencies = [
|
|||
name = "oxc_minifier"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"cow-utils",
|
||||
"insta",
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
|
|
@ -1738,6 +1740,7 @@ version = "0.28.0"
|
|||
dependencies = [
|
||||
"assert-unchecked",
|
||||
"bitflags 2.6.0",
|
||||
"cow-utils",
|
||||
"memchr",
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
|
|
@ -1871,6 +1874,7 @@ version = "0.28.0"
|
|||
dependencies = [
|
||||
"base64-simd",
|
||||
"cfg-if",
|
||||
"cow-utils",
|
||||
"rayon",
|
||||
"rustc-hash",
|
||||
"serde",
|
||||
|
|
@ -1927,6 +1931,7 @@ dependencies = [
|
|||
name = "oxc_transform_conformance"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"cow-utils",
|
||||
"indexmap",
|
||||
"oxc",
|
||||
"oxc_tasks_common",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ workspace = true
|
|||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
cow-utils = { workspace = true }
|
||||
oxc_allocator = { workspace = true }
|
||||
oxc_ast = { workspace = true }
|
||||
oxc_index = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::{borrow::Cow, ops::Not};
|
||||
|
||||
use cow_utils::CowUtils;
|
||||
use oxc_allocator::{Box, Vec};
|
||||
#[allow(clippy::wildcard_imports)]
|
||||
use oxc_ast::ast::*;
|
||||
|
|
@ -1232,7 +1233,7 @@ impl<'a> Gen for RegExpLiteral<'a> {
|
|||
);
|
||||
// Avoid forming a single-line comment or "</script" sequence
|
||||
if Some('/') == last
|
||||
|| (Some('<') == last && pattern_text.to_lowercase().starts_with("script"))
|
||||
|| (Some('<') == last && pattern_text.cow_to_lowercase().starts_with("script"))
|
||||
{
|
||||
p.print_hard_space();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -318,6 +318,7 @@ impl<'a> Fixer<'a> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use cow_utils::CowUtils;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use oxc_diagnostics::OxcDiagnostic;
|
||||
|
|
@ -417,7 +418,7 @@ mod test {
|
|||
get_fix_result(vec![create_message(insert_at_middle(), Some(INSERT_AT_MIDDLE))]);
|
||||
assert_eq!(
|
||||
result.fixed_code,
|
||||
TEST_CODE.replace("6 *", &format!("{}{}", INSERT_AT_MIDDLE.content, "6 *"))
|
||||
TEST_CODE.cow_replace("6 *", &format!("{}{}", INSERT_AT_MIDDLE.content, "6 *"))
|
||||
);
|
||||
assert_eq!(result.messages.len(), 0);
|
||||
}
|
||||
|
|
@ -435,7 +436,7 @@ mod test {
|
|||
format!(
|
||||
"{}{}{}",
|
||||
INSERT_AT_START.content,
|
||||
TEST_CODE.replace("6 *", &format!("{}{}", INSERT_AT_MIDDLE.content, "6 *")),
|
||||
TEST_CODE.cow_replace("6 *", &format!("{}{}", INSERT_AT_MIDDLE.content, "6 *")),
|
||||
INSERT_AT_END.content
|
||||
)
|
||||
);
|
||||
|
|
@ -452,7 +453,7 @@ mod test {
|
|||
#[test]
|
||||
fn replace_at_the_start() {
|
||||
let result = get_fix_result(vec![create_message(replace_var(), Some(REPLACE_VAR))]);
|
||||
assert_eq!(result.fixed_code, TEST_CODE.replace("var", "let"));
|
||||
assert_eq!(result.fixed_code, TEST_CODE.cow_replace("var", "let"));
|
||||
assert_eq!(result.messages.len(), 0);
|
||||
assert!(result.fixed);
|
||||
}
|
||||
|
|
@ -460,7 +461,7 @@ mod test {
|
|||
#[test]
|
||||
fn replace_at_the_middle() {
|
||||
let result = get_fix_result(vec![create_message(replace_id(), Some(REPLACE_ID))]);
|
||||
assert_eq!(result.fixed_code, TEST_CODE.replace("answer", "foo"));
|
||||
assert_eq!(result.fixed_code, TEST_CODE.cow_replace("answer", "foo"));
|
||||
assert_eq!(result.messages.len(), 0);
|
||||
assert!(result.fixed);
|
||||
}
|
||||
|
|
@ -468,7 +469,7 @@ mod test {
|
|||
#[test]
|
||||
fn replace_at_the_end() {
|
||||
let result = get_fix_result(vec![create_message(replace_num(), Some(REPLACE_NUM))]);
|
||||
assert_eq!(result.fixed_code, TEST_CODE.replace('6', "5"));
|
||||
assert_eq!(result.fixed_code, TEST_CODE.cow_replace('6', "5"));
|
||||
assert_eq!(result.messages.len(), 0);
|
||||
assert!(result.fixed);
|
||||
}
|
||||
|
|
@ -489,7 +490,7 @@ mod test {
|
|||
#[test]
|
||||
fn remove_at_the_start() {
|
||||
let result = get_fix_result(vec![create_message(remove_start(), Some(REMOVE_START))]);
|
||||
assert_eq!(result.fixed_code, TEST_CODE.replace("var ", ""));
|
||||
assert_eq!(result.fixed_code, TEST_CODE.cow_replace("var ", ""));
|
||||
assert_eq!(result.messages.len(), 0);
|
||||
assert!(result.fixed);
|
||||
}
|
||||
|
|
@ -500,7 +501,7 @@ mod test {
|
|||
remove_middle(Span::default()),
|
||||
Some(REMOVE_MIDDLE),
|
||||
)]);
|
||||
assert_eq!(result.fixed_code, TEST_CODE.replace("answer", "a"));
|
||||
assert_eq!(result.fixed_code, TEST_CODE.cow_replace("answer", "a"));
|
||||
assert_eq!(result.messages.len(), 0);
|
||||
assert!(result.fixed);
|
||||
}
|
||||
|
|
@ -508,7 +509,7 @@ mod test {
|
|||
#[test]
|
||||
fn remove_at_the_end() {
|
||||
let result = get_fix_result(vec![create_message(remove_end(), Some(REMOVE_END))]);
|
||||
assert_eq!(result.fixed_code, TEST_CODE.replace(" * 7", ""));
|
||||
assert_eq!(result.fixed_code, TEST_CODE.cow_replace(" * 7", ""));
|
||||
assert_eq!(result.messages.len(), 0);
|
||||
assert!(result.fixed);
|
||||
}
|
||||
|
|
@ -531,7 +532,7 @@ mod test {
|
|||
create_message(remove_middle(Span::default()), Some(REMOVE_MIDDLE)),
|
||||
create_message(replace_id(), Some(REPLACE_ID)),
|
||||
]);
|
||||
assert_eq!(result.fixed_code, TEST_CODE.replace("answer", "foo"));
|
||||
assert_eq!(result.fixed_code, TEST_CODE.cow_replace("answer", "foo"));
|
||||
assert_eq!(result.messages.len(), 1);
|
||||
assert_eq!(result.messages[0].error.to_string(), "removemiddle");
|
||||
assert!(result.fixed);
|
||||
|
|
@ -543,7 +544,7 @@ mod test {
|
|||
create_message(remove_start(), Some(REMOVE_START)),
|
||||
create_message(replace_id(), Some(REPLACE_ID)),
|
||||
]);
|
||||
assert_eq!(result.fixed_code, TEST_CODE.replace("var answer", "foo"));
|
||||
assert_eq!(result.fixed_code, TEST_CODE.cow_replace("var answer", "foo"));
|
||||
assert_eq!(result.messages.len(), 0);
|
||||
assert!(result.fixed);
|
||||
}
|
||||
|
|
@ -555,7 +556,7 @@ mod test {
|
|||
create_message(replace_id(), Some(REPLACE_ID)),
|
||||
create_message(no_fix(Span::default()), None),
|
||||
]);
|
||||
assert_eq!(result.fixed_code, TEST_CODE.replace("answer", "foo"));
|
||||
assert_eq!(result.fixed_code, TEST_CODE.cow_replace("answer", "foo"));
|
||||
assert_eq!(result.messages.len(), 2);
|
||||
assert_eq!(result.messages[0].error.to_string(), "nofix");
|
||||
assert_eq!(result.messages[1].error.to_string(), "removemiddle");
|
||||
|
|
@ -591,7 +592,7 @@ mod test {
|
|||
Message::new(no_fix_2(Span::new(1, 7)), None),
|
||||
Message::new(no_fix_1(Span::new(1, 3)), None),
|
||||
]);
|
||||
assert_eq!(result.fixed_code, TEST_CODE.replace("answer", "foo"));
|
||||
assert_eq!(result.fixed_code, TEST_CODE.cow_replace("answer", "foo"));
|
||||
assert_eq!(result.messages.len(), 2);
|
||||
assert_eq!(result.messages[0].error.to_string(), "nofix1");
|
||||
assert_eq!(result.messages[1].error.to_string(), "nofix2");
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ impl NoLossOfPrecision {
|
|||
} else {
|
||||
format!("{value:o}")
|
||||
};
|
||||
!raw.ends_with(&suffix.to_uppercase())
|
||||
!raw.ends_with(&suffix.cow_to_uppercase().as_ref())
|
||||
}
|
||||
|
||||
fn base_ten_loses_precision(node: &'_ NumericLiteral) -> bool {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use cow_utils::CowUtils;
|
||||
use oxc_diagnostics::OxcDiagnostic;
|
||||
use oxc_semantic::SymbolFlags;
|
||||
use oxc_span::{GetSpan, Span};
|
||||
|
|
@ -32,7 +33,7 @@ pub fn used_ignored(symbol: &Symbol<'_, '_>) -> OxcDiagnostic {
|
|||
|
||||
OxcDiagnostic::warn(format!("{pronoun} '{name}' is marked as ignored but is used."))
|
||||
.with_label(symbol.span().label(format!("'{name}' is declared here")))
|
||||
.with_help(format!("Consider renaming this {}.", pronoun.to_lowercase()))
|
||||
.with_help(format!("Consider renaming this {}.", pronoun.cow_to_lowercase()))
|
||||
}
|
||||
/// Variable 'x' is declared but never used.
|
||||
pub fn declared(symbol: &Symbol<'_, '_>) -> OxcDiagnostic {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use std::{
|
|||
str::FromStr,
|
||||
};
|
||||
|
||||
use cow_utils::CowUtils;
|
||||
use itertools::Itertools;
|
||||
use oxc_ast::{
|
||||
ast::{ImportDeclaration, ImportDeclarationSpecifier, Statement},
|
||||
|
|
@ -210,10 +211,10 @@ impl SortImports {
|
|||
let mut previous_local_member_name = get_first_local_member_name(previous);
|
||||
|
||||
if self.ignore_case {
|
||||
current_local_member_name =
|
||||
current_local_member_name.map(|name| name.to_lowercase().into());
|
||||
previous_local_member_name =
|
||||
previous_local_member_name.map(|name| name.to_lowercase().into());
|
||||
current_local_member_name = current_local_member_name
|
||||
.map(|name| Cow::Owned(name.cow_to_lowercase().into_owned()));
|
||||
previous_local_member_name = previous_local_member_name
|
||||
.map(|name| Cow::Owned(name.cow_to_lowercase().into_owned()));
|
||||
}
|
||||
|
||||
// "memberSyntaxSortOrder": ["none", "all", "multiple", "single"]
|
||||
|
|
@ -283,7 +284,7 @@ impl SortImports {
|
|||
let b = window[1].local.name.as_str();
|
||||
|
||||
if self.ignore_case {
|
||||
a.to_lowercase() > b.to_lowercase()
|
||||
a.cow_to_lowercase() > b.cow_to_lowercase()
|
||||
} else {
|
||||
a > b
|
||||
}
|
||||
|
|
@ -330,7 +331,7 @@ impl SortImports {
|
|||
let b = b.local.name.as_str();
|
||||
|
||||
if self.ignore_case {
|
||||
a.to_lowercase().cmp(&b.to_lowercase())
|
||||
a.cow_to_lowercase().cmp(&b.cow_to_lowercase())
|
||||
} else {
|
||||
a.cmp(b)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::{borrow::Cow, cmp::Ordering};
|
||||
|
||||
use cow_utils::CowUtils;
|
||||
use oxc_ast::{
|
||||
ast::{BindingPatternKind, VariableDeclarator},
|
||||
AstKind,
|
||||
|
|
@ -93,7 +94,7 @@ impl SortVars {
|
|||
};
|
||||
|
||||
if self.ignore_case {
|
||||
return Cow::Owned(ident.name.to_lowercase());
|
||||
return ident.name.as_str().cow_to_lowercase();
|
||||
}
|
||||
|
||||
Cow::Borrowed(ident.name.as_str()) // avoid string allocs in the default case
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#![allow(clippy::cast_possible_truncation)]
|
||||
use std::{ffi::OsStr, path::Component, sync::Arc};
|
||||
|
||||
use cow_utils::CowUtils;
|
||||
use oxc_diagnostics::OxcDiagnostic;
|
||||
use oxc_macros::declare_oxc_lint;
|
||||
use oxc_span::{CompactStr, Span};
|
||||
|
|
@ -142,12 +143,13 @@ impl Rule for NoCycle {
|
|||
let help = stack
|
||||
.iter()
|
||||
.map(|(specifier, path)| {
|
||||
let path = path
|
||||
.strip_prefix(&cwd)
|
||||
.unwrap_or(path)
|
||||
.to_string_lossy()
|
||||
.replace('\\', "/");
|
||||
format!("-> {specifier} - {path}")
|
||||
format!(
|
||||
"-> {specifier} - {}",
|
||||
path.strip_prefix(&cwd)
|
||||
.unwrap_or(path)
|
||||
.to_string_lossy()
|
||||
.cow_replace('\\', "/")
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use cow_utils::CowUtils;
|
||||
use oxc_ast::{
|
||||
ast::{CallExpression, Expression, Statement},
|
||||
AstKind,
|
||||
|
|
@ -273,7 +274,13 @@ fn convert_pattern(pattern: &str) -> String {
|
|||
// request.**.expect* -> request.[a-z\\d\\.]*.expect[a-z\\d]*
|
||||
let pattern = pattern
|
||||
.split('.')
|
||||
.map(|p| if p == "**" { String::from("[a-z\\d\\.]*") } else { p.replace('*', "[a-z\\d]*") })
|
||||
.map(|p| {
|
||||
if p == "**" {
|
||||
String::from("[a-z\\d\\.]*")
|
||||
} else {
|
||||
p.cow_replace('*', "[a-z\\d]*").into_owned()
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\\.");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::{collections::HashMap, hash::Hash};
|
||||
|
||||
use cow_utils::CowUtils;
|
||||
use oxc_ast::{
|
||||
ast::{Argument, BinaryExpression, Expression},
|
||||
AstKind,
|
||||
|
|
@ -281,7 +282,7 @@ fn validate_title(
|
|||
if !valid_title.disallowed_words.is_empty() {
|
||||
let Ok(disallowed_words_reg) = regex::Regex::new(&format!(
|
||||
r#"(?iu)\b(?:{})\b"#,
|
||||
valid_title.disallowed_words.join("|").replace('.', r"\.")
|
||||
valid_title.disallowed_words.join("|").cow_replace('.', r"\.")
|
||||
)) else {
|
||||
return;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use cow_utils::CowUtils;
|
||||
use oxc_ast::{ast::JSXAttributeItem, AstKind};
|
||||
use oxc_diagnostics::OxcDiagnostic;
|
||||
use oxc_macros::declare_oxc_lint;
|
||||
|
|
@ -52,7 +53,8 @@ declare_oxc_lint!(
|
|||
impl Rule for AriaProps {
|
||||
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
||||
if let AstKind::JSXAttributeItem(JSXAttributeItem::Attribute(attr)) = node.kind() {
|
||||
let name = get_jsx_attribute_name(&attr.name).to_lowercase();
|
||||
let name = get_jsx_attribute_name(&attr.name);
|
||||
let name = name.cow_to_lowercase();
|
||||
if name.starts_with("aria-") && !VALID_ARIA_PROPS.contains(&name) {
|
||||
let suggestion = COMMON_TYPOS.get(&name).copied();
|
||||
let diagnostic = aria_props_diagnostic(attr.span, &name, suggestion);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use cow_utils::CowUtils;
|
||||
use oxc_ast::{ast::JSXAttributeItem, AstKind};
|
||||
use oxc_diagnostics::OxcDiagnostic;
|
||||
use oxc_macros::declare_oxc_lint;
|
||||
|
|
@ -57,7 +58,8 @@ impl Rule for AriaUnsupportedElements {
|
|||
JSXAttributeItem::Attribute(attr) => attr,
|
||||
JSXAttributeItem::SpreadAttribute(_) => continue,
|
||||
};
|
||||
let attr_name = get_jsx_attribute_name(&attr.name).to_lowercase();
|
||||
let attr_name = get_jsx_attribute_name(&attr.name);
|
||||
let attr_name = attr_name.cow_to_lowercase();
|
||||
if INVALID_ATTRIBUTES.contains(&attr_name) {
|
||||
ctx.diagnostic_with_fix(
|
||||
aria_unsupported_elements_diagnostic(attr.span, &attr_name),
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use cow_utils::CowUtils;
|
||||
use oxc_ast::{
|
||||
ast::{JSXAttributeItem, JSXOpeningElement},
|
||||
AstKind,
|
||||
|
|
@ -84,8 +85,9 @@ impl Rule for RoleSupportsAriaProps {
|
|||
let invalid_props = get_invalid_aria_props_for_role(role_value);
|
||||
for attr in &jsx_el.attributes {
|
||||
if let JSXAttributeItem::Attribute(attr) = attr {
|
||||
let name = get_jsx_attribute_name(&attr.name).to_lowercase();
|
||||
if invalid_props.contains(&&name.as_str()) {
|
||||
let name = get_jsx_attribute_name(&attr.name);
|
||||
let name = name.cow_to_lowercase();
|
||||
if invalid_props.contains(&&name.as_ref()) {
|
||||
ctx.diagnostic(if is_implicit {
|
||||
is_implicit_diagnostic(attr.span, &name, role_value, &el_type)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use cow_utils::CowUtils;
|
||||
use oxc_ast::{
|
||||
ast::{Expression, JSXAttributeItem, JSXAttributeName, JSXElement, JSXFragment, Statement},
|
||||
AstKind,
|
||||
|
|
@ -91,7 +92,7 @@ pub fn import_matcher<'a>(
|
|||
actual_local_name: &'a str,
|
||||
expected_module_name: &'a str,
|
||||
) -> bool {
|
||||
let expected_module_name = expected_module_name.to_lowercase();
|
||||
let expected_module_name = expected_module_name.cow_to_lowercase();
|
||||
ctx.semantic().module_record().import_entries.iter().any(|import| {
|
||||
import.module_request.name().as_str() == expected_module_name
|
||||
&& import.local_name.name().as_str() == actual_local_name
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::{borrow::Cow, collections::hash_map::HashMap};
|
||||
|
||||
use cow_utils::CowUtils;
|
||||
use itertools::Itertools;
|
||||
use once_cell::sync::Lazy;
|
||||
use oxc_ast::{
|
||||
|
|
@ -421,7 +422,10 @@ const DOM_PROPERTIES_IGNORE_CASE: [&str; 5] = [
|
|||
];
|
||||
|
||||
static DOM_PROPERTIES_LOWER_MAP: Lazy<HashMap<String, &'static str>> = Lazy::new(|| {
|
||||
DOM_PROPERTIES_NAMES.iter().map(|it| (it.to_lowercase(), *it)).collect::<HashMap<_, _>>()
|
||||
DOM_PROPERTIES_NAMES
|
||||
.iter()
|
||||
.map(|it| (it.cow_to_lowercase().into_owned(), *it))
|
||||
.collect::<HashMap<_, _>>()
|
||||
});
|
||||
|
||||
///
|
||||
|
|
@ -433,7 +437,7 @@ static DOM_PROPERTIES_LOWER_MAP: Lazy<HashMap<String, &'static str>> = Lazy::new
|
|||
fn is_valid_data_attr(name: &str) -> bool {
|
||||
static DATA_ATTR_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"^data(-?[^:]*)$").unwrap());
|
||||
|
||||
!name.to_lowercase().starts_with("data-xml") && DATA_ATTR_REGEX.is_match(name)
|
||||
!name.cow_to_lowercase().starts_with("data-xml") && DATA_ATTR_REGEX.is_match(name)
|
||||
}
|
||||
|
||||
fn normalize_attribute_case(name: &str) -> &str {
|
||||
|
|
@ -496,7 +500,10 @@ impl Rule for NoUnknownProperty {
|
|||
};
|
||||
if is_valid_data_attr(&actual_name) {
|
||||
if self.0.require_data_lowercase && has_uppercase(&actual_name) {
|
||||
ctx.diagnostic(data_lowercase_required(span, &actual_name.to_lowercase()));
|
||||
ctx.diagnostic(data_lowercase_required(
|
||||
span,
|
||||
&actual_name.cow_to_lowercase(),
|
||||
));
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
|
@ -520,7 +527,7 @@ impl Rule for NoUnknownProperty {
|
|||
}
|
||||
|
||||
DOM_PROPERTIES_LOWER_MAP
|
||||
.get(&name.to_lowercase())
|
||||
.get(&name.cow_to_lowercase().into_owned())
|
||||
.or_else(|| DOM_ATTRIBUTES_TO_CAMEL.get(name))
|
||||
.map_or_else(
|
||||
|| {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use cow_utils::CowUtils;
|
||||
use oxc_ast::CommentKind;
|
||||
use oxc_diagnostics::OxcDiagnostic;
|
||||
use oxc_macros::declare_oxc_lint;
|
||||
|
|
@ -178,7 +179,7 @@ impl Rule for BanTsComment {
|
|||
|fixer| {
|
||||
fixer.replace(
|
||||
comm.span,
|
||||
raw.replace("@ts-ignore", "@ts-expect-error"),
|
||||
raw.cow_replace("@ts-ignore", "@ts-expect-error"),
|
||||
)
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use cow_utils::CowUtils;
|
||||
use oxc_ast::AstKind;
|
||||
use oxc_diagnostics::OxcDiagnostic;
|
||||
use oxc_macros::declare_oxc_lint;
|
||||
|
|
@ -65,7 +66,7 @@ impl Rule for BanTypes {
|
|||
"String" | "Boolean" | "Number" | "Symbol" | "BigInt" => {
|
||||
ctx.diagnostic(type_diagnostic(
|
||||
name.as_str(),
|
||||
&name.to_lowercase(),
|
||||
&name.as_str().cow_to_lowercase(),
|
||||
typ.span,
|
||||
));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use cow_utils::CowUtils;
|
||||
use oxc_ast::{
|
||||
ast::{Expression, TSTypeName},
|
||||
AstKind,
|
||||
|
|
@ -91,7 +92,7 @@ impl Rule for NoWrapperObjectTypes {
|
|||
|
||||
if can_fix {
|
||||
ctx.diagnostic_with_fix(no_wrapper_object_types(ident_span), |fixer| {
|
||||
fixer.replace(ident_span, ident_name.to_lowercase())
|
||||
fixer.replace(ident_span, ident_name.cow_to_lowercase())
|
||||
});
|
||||
} else {
|
||||
ctx.diagnostic(no_wrapper_object_types(ident_span));
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use cow_utils::CowUtils;
|
||||
use oxc_ast::CommentKind;
|
||||
use oxc_diagnostics::OxcDiagnostic;
|
||||
use oxc_macros::declare_oxc_lint;
|
||||
|
|
@ -58,7 +59,7 @@ impl Rule for PreferTsExpectError {
|
|||
ctx.diagnostic_with_fix(prefer_ts_expect_error_diagnostic(comment_span), |fixer| {
|
||||
fixer.replace(
|
||||
comment_span,
|
||||
format!("//{}", raw.replace("@ts-ignore", "@ts-expect-error")),
|
||||
format!("//{}", raw.cow_replace("@ts-ignore", "@ts-expect-error")),
|
||||
)
|
||||
});
|
||||
} else {
|
||||
|
|
@ -66,7 +67,7 @@ impl Rule for PreferTsExpectError {
|
|||
ctx.diagnostic_with_fix(prefer_ts_expect_error_diagnostic(comment_span), |fixer| {
|
||||
fixer.replace(
|
||||
comment_span,
|
||||
format!("/*{}*/", raw.replace("@ts-ignore", "@ts-expect-error")),
|
||||
format!("/*{}*/", raw.cow_replace("@ts-ignore", "@ts-expect-error")),
|
||||
)
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use cow_utils::CowUtils;
|
||||
use oxc_ast::AstKind;
|
||||
use oxc_diagnostics::OxcDiagnostic;
|
||||
use oxc_macros::declare_oxc_lint;
|
||||
|
|
@ -101,7 +102,7 @@ fn check_number_literal(number_literal: &str, raw_span: Span) -> Option<(OxcDiag
|
|||
Span::new(raw_span.start + 1, raw_span.start + 2),
|
||||
if number_literal.starts_with("0B") { "0b" } else { "0o" },
|
||||
),
|
||||
number_literal.to_lowercase(),
|
||||
number_literal.cow_to_lowercase().into_owned(),
|
||||
));
|
||||
}
|
||||
if number_literal.starts_with("0X") || number_literal.starts_with("0x") {
|
||||
|
|
@ -131,14 +132,14 @@ fn check_number_literal(number_literal: &str, raw_span: Span) -> Option<(OxcDiag
|
|||
let char_position = raw_span.start + index as u32;
|
||||
return Some((
|
||||
uppercase_exponential_notation(Span::new(char_position, char_position + 1)),
|
||||
number_literal.to_lowercase(),
|
||||
number_literal.cow_to_lowercase().into_owned(),
|
||||
));
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn digits_to_uppercase(digits: &str) -> String {
|
||||
let mut result = digits.to_uppercase();
|
||||
let mut result = digits.cow_to_uppercase().into_owned();
|
||||
if result.ends_with('N') {
|
||||
result.truncate(result.len() - 1);
|
||||
result.push('n');
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use cow_utils::CowUtils;
|
||||
use lazy_static::lazy_static;
|
||||
use oxc_ast::{
|
||||
ast::{BigIntLiteral, NumericLiteral},
|
||||
|
|
@ -177,7 +178,7 @@ impl NumericSeparatorsStyle {
|
|||
fn format_binary(&self, raw_number: &str) -> String {
|
||||
let prefix = &raw_number[0..2];
|
||||
|
||||
let mut to_format = raw_number[2..].replace('_', "");
|
||||
let mut to_format = raw_number[2..].cow_replace('_', "").into_owned();
|
||||
|
||||
add_separators(&mut to_format, &SeparatorDir::Right, &self.binary);
|
||||
to_format.insert_str(0, prefix);
|
||||
|
|
@ -187,7 +188,7 @@ impl NumericSeparatorsStyle {
|
|||
fn format_hex(&self, number_raw: &str) -> String {
|
||||
let prefix = &number_raw[0..2];
|
||||
|
||||
let mut to_format = number_raw[2..].replace('_', "");
|
||||
let mut to_format = number_raw[2..].cow_replace('_', "").into_owned();
|
||||
|
||||
add_separators(&mut to_format, &SeparatorDir::Right, &self.hexadecimal);
|
||||
to_format.insert_str(0, prefix);
|
||||
|
|
@ -204,7 +205,7 @@ impl NumericSeparatorsStyle {
|
|||
|
||||
let prefix = &number_raw[0..2];
|
||||
|
||||
let mut to_format = number_raw[2..].replace('_', "");
|
||||
let mut to_format = number_raw[2..].cow_replace('_', "").into_owned();
|
||||
|
||||
add_separators(&mut to_format, &SeparatorDir::Right, &self.octal);
|
||||
to_format.insert_str(0, prefix);
|
||||
|
|
@ -222,7 +223,7 @@ impl NumericSeparatorsStyle {
|
|||
let mut out = String::new();
|
||||
|
||||
{
|
||||
let number = caps.get(1).unwrap().as_str().replace('_', "");
|
||||
let number = caps.get(1).unwrap().as_str().cow_replace('_', "").into_owned();
|
||||
|
||||
if let Some((whole, decimal)) = number.split_once('.') {
|
||||
if !whole.is_empty() {
|
||||
|
|
@ -251,7 +252,7 @@ impl NumericSeparatorsStyle {
|
|||
out.push_str(sign.as_str());
|
||||
}
|
||||
if let Some(power) = caps.get(4) {
|
||||
let mut s = power.as_str().replace('_', "");
|
||||
let mut s = power.as_str().cow_replace('_', "").into_owned();
|
||||
add_separators(&mut s, &SeparatorDir::Right, &self.number);
|
||||
out.push_str(&s);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use cow_utils::CowUtils;
|
||||
use oxc_allocator::Allocator;
|
||||
use oxc_diagnostics::{DiagnosticService, GraphicalReportHandler, GraphicalTheme, NamedSource};
|
||||
use serde::Deserialize;
|
||||
|
|
@ -185,7 +186,8 @@ impl Tester {
|
|||
expect_pass: Vec<T>,
|
||||
expect_fail: Vec<T>,
|
||||
) -> Self {
|
||||
let rule_path = PathBuf::from(rule_name.replace('-', "_")).with_extension("tsx");
|
||||
let rule_path =
|
||||
PathBuf::from(rule_name.cow_replace('-', "_").into_owned()).with_extension("tsx");
|
||||
let expect_pass = expect_pass.into_iter().map(Into::into).collect::<Vec<_>>();
|
||||
let expect_fail = expect_fail.into_iter().map(Into::into).collect::<Vec<_>>();
|
||||
let current_working_directory =
|
||||
|
|
@ -294,7 +296,7 @@ impl Tester {
|
|||
}
|
||||
|
||||
fn snapshot(&self) {
|
||||
let name = self.rule_name.replace('-', "_");
|
||||
let name = self.rule_name.cow_replace('-', "_");
|
||||
let mut settings = insta::Settings::clone_current();
|
||||
|
||||
settings.set_prepend_module_to_snapshot(false);
|
||||
|
|
@ -304,7 +306,7 @@ impl Tester {
|
|||
}
|
||||
|
||||
settings.bind(|| {
|
||||
insta::assert_snapshot!(name, self.snapshot);
|
||||
insta::assert_snapshot!(name.as_ref(), self.snapshot);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ test = false
|
|||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
cow-utils = { workspace = true }
|
||||
oxc_allocator = { workspace = true }
|
||||
oxc_ast = { workspace = true }
|
||||
oxc_codegen = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use cow_utils::CowUtils;
|
||||
use oxc_allocator::Allocator;
|
||||
use oxc_ast::{ast::*, visit::walk_mut, AstBuilder, VisitMut};
|
||||
use oxc_semantic::{ScopeTree, SymbolTable};
|
||||
use oxc_span::{CompactStr, SPAN};
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::replace_global_defines::{DotDefine, ReplaceGlobalDefines};
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ impl InjectImport {
|
|||
fn replace_name(local: &str) -> Option<CompactStr> {
|
||||
local
|
||||
.contains('.')
|
||||
.then(|| CompactStr::from(format!("$inject_{}", local.replace('.', "_"))))
|
||||
.then(|| CompactStr::from(format!("$inject_{}", local.cow_replace('.', "_"))))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ oxc_syntax = { workspace = true }
|
|||
|
||||
assert-unchecked = { workspace = true }
|
||||
bitflags = { workspace = true }
|
||||
cow-utils = { workspace = true }
|
||||
num-bigint = { workspace = true }
|
||||
num-traits = { workspace = true }
|
||||
rustc-hash = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use cow_utils::CowUtils;
|
||||
use oxc_allocator::Box;
|
||||
use oxc_ast::ast::*;
|
||||
use oxc_diagnostics::Result;
|
||||
|
|
@ -517,7 +518,7 @@ impl<'a> ParserImpl<'a> {
|
|||
let cur_src = self.cur_src();
|
||||
let raw = &cur_src[1..cur_src.len() - end_offset as usize];
|
||||
let raw = Atom::from(if cooked.is_some() && raw.contains('\r') {
|
||||
self.ast.str(raw.replace("\r\n", "\n").replace('\r', "\n").as_str())
|
||||
self.ast.str(&raw.cow_replace("\r\n", "\n").cow_replace('\r', "\n"))
|
||||
} else {
|
||||
raw
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
use std::borrow::Cow;
|
||||
|
||||
use cow_utils::CowUtils;
|
||||
use num_bigint::BigInt;
|
||||
use num_traits::Num;
|
||||
|
||||
|
|
@ -40,7 +41,7 @@ pub fn parse_int(s: &str, kind: Kind, has_sep: bool) -> Result<f64, &'static str
|
|||
}
|
||||
|
||||
pub fn parse_float(s: &str, has_sep: bool) -> Result<f64, &'static str> {
|
||||
let s = if has_sep { Cow::Owned(s.replace('_', "")) } else { Cow::Borrowed(s) };
|
||||
let s = if has_sep { s.cow_replace('_', "") } else { Cow::Borrowed(s) };
|
||||
debug_assert!(!s.contains('_'));
|
||||
s.parse::<f64>().map_err(|_| "invalid float")
|
||||
}
|
||||
|
|
@ -93,7 +94,7 @@ fn parse_decimal_with_underscores(s: &str) -> f64 {
|
|||
|
||||
debug_assert!(!s.is_empty());
|
||||
if s.len() > MAX_FAST_DECIMAL_LEN {
|
||||
return parse_decimal_slow(&s.replace('_', ""));
|
||||
return parse_decimal_slow(&s.cow_replace('_', ""));
|
||||
}
|
||||
|
||||
let mut result = 0_u64;
|
||||
|
|
@ -391,7 +392,7 @@ fn parse_hex_with_underscores_slow(s: &str) -> f64 {
|
|||
// ==================================== BIGINT ====================================
|
||||
|
||||
pub fn parse_big_int(s: &str, kind: Kind, has_sep: bool) -> Result<BigInt, &'static str> {
|
||||
let s = if has_sep { Cow::Owned(s.replace('_', "")) } else { Cow::Borrowed(s) };
|
||||
let s = if has_sep { s.cow_replace('_', "") } else { Cow::Borrowed(s) };
|
||||
debug_assert!(!s.contains('_'));
|
||||
parse_big_int_without_underscores(&s, kind)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ doctest = false
|
|||
[dependencies]
|
||||
base64-simd = { workspace = true }
|
||||
cfg-if = { workspace = true }
|
||||
cow-utils = { workspace = true }
|
||||
rustc-hash = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use crate::SourceMap;
|
||||
use cow_utils::CowUtils;
|
||||
|
||||
/// The `SourcemapVisualizer` is a helper for sourcemap testing.
|
||||
/// It print the mapping of original content and final content tokens.
|
||||
|
|
@ -151,16 +154,18 @@ impl<'a> SourcemapVisualizer<'a> {
|
|||
tables
|
||||
}
|
||||
|
||||
fn str_slice_by_token(buff: &[Vec<u16>], start: (u32, u32), end: (u32, u32)) -> String {
|
||||
fn str_slice_by_token(buff: &[Vec<u16>], start: (u32, u32), end: (u32, u32)) -> Cow<'_, str> {
|
||||
if start.0 == end.0 {
|
||||
if start.1 <= end.1 {
|
||||
return String::from_utf16(
|
||||
&buff[start.0 as usize][start.1 as usize..end.1 as usize],
|
||||
)
|
||||
.unwrap();
|
||||
return Cow::Owned(
|
||||
String::from_utf16(&buff[start.0 as usize][start.1 as usize..end.1 as usize])
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
return String::from_utf16(&buff[start.0 as usize][end.1 as usize..start.1 as usize])
|
||||
.unwrap();
|
||||
return Cow::Owned(
|
||||
String::from_utf16(&buff[start.0 as usize][end.1 as usize..start.1 as usize])
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
let mut s = String::new();
|
||||
|
|
@ -175,8 +180,10 @@ impl<'a> SourcemapVisualizer<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
let replaced: Cow<str> = s.cow_replace("\r", "");
|
||||
|
||||
// Windows: Replace "\r\n" and replace with "\n"
|
||||
s.replace('\r', "")
|
||||
Cow::Owned(replaced.into_owned())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#![allow(clippy::disallowed_methods)]
|
||||
use std::{cell::RefCell, io::Read, path::PathBuf, rc::Rc};
|
||||
|
||||
use bpaf::{Bpaf, Parser};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#![allow(clippy::disallowed_methods)]
|
||||
use oxc_allocator::Allocator;
|
||||
use oxc_benchmark::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
||||
use oxc_parser::lexer::{Kind, Lexer};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#![allow(clippy::print_stdout)]
|
||||
#![allow(clippy::print_stdout, clippy::disallowed_methods)]
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
mod diff;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#![allow(clippy::print_stdout, clippy::print_stderr)]
|
||||
#![allow(clippy::print_stdout, clippy::print_stderr, clippy::disallowed_methods)]
|
||||
// Core
|
||||
mod runtime;
|
||||
mod suite;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#![allow(clippy::print_stdout, clippy::print_stderr)]
|
||||
#![allow(clippy::print_stdout, clippy::print_stderr, clippy::disallowed_methods)]
|
||||
mod ignore_list;
|
||||
mod spec;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#![allow(clippy::print_stdout, clippy::print_stderr)]
|
||||
#![allow(clippy::print_stdout, clippy::print_stderr, clippy::disallowed_methods)]
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
collections::HashMap,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ doctest = false
|
|||
oxc = { workspace = true, features = ["full"] }
|
||||
oxc_tasks_common = { workspace = true }
|
||||
|
||||
cow-utils = { workspace = true }
|
||||
indexmap = { workspace = true }
|
||||
pico-args = { workspace = true }
|
||||
walkdir = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use cow_utils::CowUtils;
|
||||
use oxc::{
|
||||
allocator::Allocator,
|
||||
codegen::CodeGenerator,
|
||||
|
|
@ -288,7 +289,7 @@ impl TestCase for ConformanceTestCase {
|
|||
|
||||
let output;
|
||||
let passed = if let Some(throws) = &babel_options.throws {
|
||||
output = throws.to_string().replace(" (1:6)", "");
|
||||
output = throws.cow_replace(" (1:6)", "").into_owned();
|
||||
!output.is_empty()
|
||||
&& actual_errors.as_ref().is_some_and(|errors| errors.contains(&output))
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
#![allow(clippy::print_stdout, clippy::print_stderr, clippy::missing_panics_doc)]
|
||||
#![allow(
|
||||
clippy::print_stdout,
|
||||
clippy::print_stderr,
|
||||
clippy::missing_panics_doc,
|
||||
clippy::disallowed_methods
|
||||
)]
|
||||
|
||||
pub mod linter;
|
||||
|
|
|
|||
Loading…
Reference in a new issue