mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
refactor(linter): use cow_to_ascii_lowercase instead cow_to_lowercase (#8678)
`cow_to_lowercase` is slow as it deals with unicode. closes #8659
This commit is contained in:
parent
883d25b27d
commit
23b49a665f
16 changed files with 30 additions and 29 deletions
|
|
@ -1346,7 +1346,7 @@ impl Gen for RegExpLiteral<'_> {
|
||||||
let pattern_text = self.regex.pattern.source_text(p.source_text);
|
let pattern_text = self.regex.pattern.source_text(p.source_text);
|
||||||
// Avoid forming a single-line comment or "</script" sequence
|
// Avoid forming a single-line comment or "</script" sequence
|
||||||
if last == Some(b'/')
|
if last == Some(b'/')
|
||||||
|| (last == Some(b'<') && pattern_text.cow_to_lowercase().starts_with("script"))
|
|| (last == Some(b'<') && pattern_text.cow_to_ascii_lowercase().starts_with("script"))
|
||||||
{
|
{
|
||||||
p.print_hard_space();
|
p.print_hard_space();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,7 @@ impl<'a> RawNum<'a> {
|
||||||
impl NoLossOfPrecision {
|
impl NoLossOfPrecision {
|
||||||
fn not_base_ten_loses_precision(node: &'_ NumericLiteral) -> bool {
|
fn not_base_ten_loses_precision(node: &'_ NumericLiteral) -> bool {
|
||||||
let raw = node.raw.as_ref().unwrap().as_str().cow_replace('_', "");
|
let raw = node.raw.as_ref().unwrap().as_str().cow_replace('_', "");
|
||||||
let raw = raw.cow_to_uppercase();
|
let raw = raw.cow_to_ascii_uppercase();
|
||||||
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
|
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
|
||||||
// AST always store number as f64, need a cast to format in bin/oct/hex
|
// AST always store number as f64, need a cast to format in bin/oct/hex
|
||||||
let value = node.value as u64;
|
let value = node.value as u64;
|
||||||
|
|
@ -197,7 +197,7 @@ impl NoLossOfPrecision {
|
||||||
} else {
|
} else {
|
||||||
format!("{value:o}")
|
format!("{value:o}")
|
||||||
};
|
};
|
||||||
!raw.ends_with(&suffix.cow_to_uppercase().as_ref())
|
!raw.ends_with(&suffix.cow_to_ascii_uppercase().as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn base_ten_loses_precision(node: &'_ NumericLiteral) -> bool {
|
fn base_ten_loses_precision(node: &'_ NumericLiteral) -> bool {
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ impl Rule for NoScriptUrl {
|
||||||
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
||||||
match node.kind() {
|
match node.kind() {
|
||||||
AstKind::StringLiteral(literal)
|
AstKind::StringLiteral(literal)
|
||||||
if literal.value.cow_to_lowercase().starts_with("javascript:") =>
|
if literal.value.cow_to_ascii_lowercase().starts_with("javascript:") =>
|
||||||
{
|
{
|
||||||
emit_diagnostic(ctx, literal.span);
|
emit_diagnostic(ctx, literal.span);
|
||||||
}
|
}
|
||||||
|
|
@ -58,7 +58,7 @@ impl Rule for NoScriptUrl {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.value
|
.value
|
||||||
.raw
|
.raw
|
||||||
.cow_to_lowercase()
|
.cow_to_ascii_lowercase()
|
||||||
.starts_with("javascript:")
|
.starts_with("javascript:")
|
||||||
{
|
{
|
||||||
emit_diagnostic(ctx, literal.span);
|
emit_diagnostic(ctx, literal.span);
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ where
|
||||||
.with_label(symbol.span().label(format!("'{name}' is declared here")))
|
.with_label(symbol.span().label(format!("'{name}' is declared here")))
|
||||||
.with_help(format!(
|
.with_help(format!(
|
||||||
"Consider renaming this {}{help_suffix}",
|
"Consider renaming this {}{help_suffix}",
|
||||||
pronoun_singular.cow_to_lowercase()
|
pronoun_singular.cow_to_ascii_lowercase()
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
/// Variable 'x' is declared but never used.
|
/// Variable 'x' is declared but never used.
|
||||||
|
|
|
||||||
|
|
@ -213,9 +213,9 @@ impl SortImports {
|
||||||
|
|
||||||
if self.ignore_case {
|
if self.ignore_case {
|
||||||
current_local_member_name = current_local_member_name
|
current_local_member_name = current_local_member_name
|
||||||
.map(|name| Cow::Owned(name.cow_to_lowercase().into_owned()));
|
.map(|name| Cow::Owned(name.cow_to_ascii_lowercase().into_owned()));
|
||||||
previous_local_member_name = previous_local_member_name
|
previous_local_member_name = previous_local_member_name
|
||||||
.map(|name| Cow::Owned(name.cow_to_lowercase().into_owned()));
|
.map(|name| Cow::Owned(name.cow_to_ascii_lowercase().into_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// "memberSyntaxSortOrder": ["none", "all", "multiple", "single"]
|
// "memberSyntaxSortOrder": ["none", "all", "multiple", "single"]
|
||||||
|
|
@ -285,7 +285,7 @@ impl SortImports {
|
||||||
let b = window[1].local.name.as_str();
|
let b = window[1].local.name.as_str();
|
||||||
|
|
||||||
if self.ignore_case {
|
if self.ignore_case {
|
||||||
a.cow_to_lowercase() > b.cow_to_lowercase()
|
a.cow_to_ascii_lowercase() > b.cow_to_ascii_lowercase()
|
||||||
} else {
|
} else {
|
||||||
a > b
|
a > b
|
||||||
}
|
}
|
||||||
|
|
@ -332,7 +332,7 @@ impl SortImports {
|
||||||
let b = b.local.name.as_str();
|
let b = b.local.name.as_str();
|
||||||
|
|
||||||
if self.ignore_case {
|
if self.ignore_case {
|
||||||
a.cow_to_lowercase().cmp(&b.cow_to_lowercase())
|
a.cow_to_ascii_lowercase().cmp(&b.cow_to_ascii_lowercase())
|
||||||
} else {
|
} else {
|
||||||
a.cmp(b)
|
a.cmp(b)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,7 @@ impl Rule for SortKeys {
|
||||||
for group in &mut property_groups {
|
for group in &mut property_groups {
|
||||||
*group = group
|
*group = group
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| s.cow_to_lowercase().to_string())
|
.map(|s| s.cow_to_ascii_lowercase().to_string())
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ impl SortVars {
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.ignore_case {
|
if self.ignore_case {
|
||||||
return ident.name.as_str().cow_to_lowercase();
|
return ident.name.as_str().cow_to_ascii_lowercase();
|
||||||
}
|
}
|
||||||
|
|
||||||
Cow::Borrowed(ident.name.as_str()) // avoid string allocs in the default case
|
Cow::Borrowed(ident.name.as_str()) // avoid string allocs in the default case
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ impl Rule for AriaProps {
|
||||||
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
||||||
if let AstKind::JSXAttributeItem(JSXAttributeItem::Attribute(attr)) = node.kind() {
|
if let AstKind::JSXAttributeItem(JSXAttributeItem::Attribute(attr)) = node.kind() {
|
||||||
let name = get_jsx_attribute_name(&attr.name);
|
let name = get_jsx_attribute_name(&attr.name);
|
||||||
let name = name.cow_to_lowercase();
|
let name = name.cow_to_ascii_lowercase();
|
||||||
if name.starts_with("aria-") && !VALID_ARIA_PROPS.contains(&name) {
|
if name.starts_with("aria-") && !VALID_ARIA_PROPS.contains(&name) {
|
||||||
let suggestion = COMMON_TYPOS.get(&name).copied();
|
let suggestion = COMMON_TYPOS.get(&name).copied();
|
||||||
let diagnostic = aria_props_diagnostic(attr.span, &name, suggestion);
|
let diagnostic = aria_props_diagnostic(attr.span, &name, suggestion);
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ impl Rule for AriaUnsupportedElements {
|
||||||
JSXAttributeItem::SpreadAttribute(_) => continue,
|
JSXAttributeItem::SpreadAttribute(_) => continue,
|
||||||
};
|
};
|
||||||
let attr_name = get_jsx_attribute_name(&attr.name);
|
let attr_name = get_jsx_attribute_name(&attr.name);
|
||||||
let attr_name = attr_name.cow_to_lowercase();
|
let attr_name = attr_name.cow_to_ascii_lowercase();
|
||||||
if INVALID_ATTRIBUTES.contains(&attr_name) {
|
if INVALID_ATTRIBUTES.contains(&attr_name) {
|
||||||
ctx.diagnostic_with_fix(
|
ctx.diagnostic_with_fix(
|
||||||
aria_unsupported_elements_diagnostic(attr.span, &attr_name),
|
aria_unsupported_elements_diagnostic(attr.span, &attr_name),
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ impl Rule for RoleSupportsAriaProps {
|
||||||
for attr in &jsx_el.attributes {
|
for attr in &jsx_el.attributes {
|
||||||
if let JSXAttributeItem::Attribute(attr) = attr {
|
if let JSXAttributeItem::Attribute(attr) = attr {
|
||||||
let name = get_jsx_attribute_name(&attr.name);
|
let name = get_jsx_attribute_name(&attr.name);
|
||||||
let name = name.cow_to_lowercase();
|
let name = name.cow_to_ascii_lowercase();
|
||||||
if invalid_props.contains(&&name.as_ref()) {
|
if invalid_props.contains(&&name.as_ref()) {
|
||||||
ctx.diagnostic(if is_implicit {
|
ctx.diagnostic(if is_implicit {
|
||||||
is_implicit_diagnostic(attr.span, &name, role_value, &el_type)
|
is_implicit_diagnostic(attr.span, &name, role_value, &el_type)
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ pub fn import_matcher<'a>(
|
||||||
actual_local_name: &'a str,
|
actual_local_name: &'a str,
|
||||||
expected_module_name: &'a str,
|
expected_module_name: &'a str,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let expected_module_name = expected_module_name.cow_to_lowercase();
|
let expected_module_name = expected_module_name.cow_to_ascii_lowercase();
|
||||||
ctx.module_record().import_entries.iter().any(|import| {
|
ctx.module_record().import_entries.iter().any(|import| {
|
||||||
import.module_request.name() == expected_module_name
|
import.module_request.name() == expected_module_name
|
||||||
&& import.local_name.name() == actual_local_name
|
&& import.local_name.name() == actual_local_name
|
||||||
|
|
|
||||||
|
|
@ -427,9 +427,10 @@ const DOM_PROPERTIES_IGNORE_CASE: [&str; 5] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref DOM_PROPERTIES_LOWER_MAP: FxHashMap<String, &'static str> = DOM_PROPERTIES_NAMES
|
static ref DOM_PROPERTIES_LOWER_MAP: FxHashMap<Cow<'static, str>, &'static str> =
|
||||||
|
DOM_PROPERTIES_NAMES
|
||||||
.iter()
|
.iter()
|
||||||
.map(|it| (it.cow_to_lowercase().into_owned(), *it))
|
.map(|it| (it.cow_to_ascii_lowercase(), *it))
|
||||||
.collect::<FxHashMap<_, _>>();
|
.collect::<FxHashMap<_, _>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -442,7 +443,7 @@ fn is_valid_data_attr(name: &str) -> bool {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if name.cow_to_lowercase().starts_with("data-xml") {
|
if name.cow_to_ascii_lowercase().starts_with("data-xml") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -519,7 +520,7 @@ impl Rule for NoUnknownProperty {
|
||||||
if self.0.require_data_lowercase && has_uppercase(&actual_name) {
|
if self.0.require_data_lowercase && has_uppercase(&actual_name) {
|
||||||
ctx.diagnostic(data_lowercase_required(
|
ctx.diagnostic(data_lowercase_required(
|
||||||
span,
|
span,
|
||||||
&actual_name.cow_to_lowercase(),
|
&actual_name.cow_to_ascii_lowercase(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
@ -544,7 +545,7 @@ impl Rule for NoUnknownProperty {
|
||||||
}
|
}
|
||||||
|
|
||||||
DOM_PROPERTIES_LOWER_MAP
|
DOM_PROPERTIES_LOWER_MAP
|
||||||
.get(&name.cow_to_lowercase().into_owned())
|
.get(&name.cow_to_ascii_lowercase())
|
||||||
.or_else(|| DOM_ATTRIBUTES_TO_CAMEL.get(name))
|
.or_else(|| DOM_ATTRIBUTES_TO_CAMEL.get(name))
|
||||||
.map_or_else(
|
.map_or_else(
|
||||||
|| {
|
|| {
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ impl Rule for BanTypes {
|
||||||
"String" | "Boolean" | "Number" | "Symbol" | "BigInt" => {
|
"String" | "Boolean" | "Number" | "Symbol" | "BigInt" => {
|
||||||
ctx.diagnostic(type_diagnostic(
|
ctx.diagnostic(type_diagnostic(
|
||||||
name.as_str(),
|
name.as_str(),
|
||||||
&name.as_str().cow_to_lowercase(),
|
&name.as_str().cow_to_ascii_lowercase(),
|
||||||
typ.span,
|
typ.span,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ impl Rule for NoWrapperObjectTypes {
|
||||||
|
|
||||||
if can_fix {
|
if can_fix {
|
||||||
ctx.diagnostic_with_fix(no_wrapper_object_types(ident_span), |fixer| {
|
ctx.diagnostic_with_fix(no_wrapper_object_types(ident_span), |fixer| {
|
||||||
fixer.replace(ident_span, ident_name.cow_to_lowercase())
|
fixer.replace(ident_span, ident_name.cow_to_ascii_lowercase())
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
ctx.diagnostic(no_wrapper_object_types(ident_span));
|
ctx.diagnostic(no_wrapper_object_types(ident_span));
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ fn check_number_literal(number_literal: &str, raw_span: Span) -> Option<(OxcDiag
|
||||||
Span::new(raw_span.start + 1, raw_span.start + 2),
|
Span::new(raw_span.start + 1, raw_span.start + 2),
|
||||||
if number_literal.starts_with("0B") { "0b" } else { "0o" },
|
if number_literal.starts_with("0B") { "0b" } else { "0o" },
|
||||||
),
|
),
|
||||||
number_literal.cow_to_lowercase().into_owned(),
|
number_literal.cow_to_ascii_lowercase().into_owned(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if number_literal.starts_with("0X") || number_literal.starts_with("0x") {
|
if number_literal.starts_with("0X") || number_literal.starts_with("0x") {
|
||||||
|
|
@ -133,14 +133,14 @@ fn check_number_literal(number_literal: &str, raw_span: Span) -> Option<(OxcDiag
|
||||||
let char_position = raw_span.start + index as u32;
|
let char_position = raw_span.start + index as u32;
|
||||||
return Some((
|
return Some((
|
||||||
uppercase_exponential_notation(Span::new(char_position, char_position + 1)),
|
uppercase_exponential_notation(Span::new(char_position, char_position + 1)),
|
||||||
number_literal.cow_to_lowercase().into_owned(),
|
number_literal.cow_to_ascii_lowercase().into_owned(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn digits_to_uppercase(digits: &str) -> String {
|
fn digits_to_uppercase(digits: &str) -> String {
|
||||||
let mut result = digits.cow_to_uppercase().into_owned();
|
let mut result = digits.cow_to_ascii_uppercase().into_owned();
|
||||||
if result.ends_with('N') {
|
if result.ends_with('N') {
|
||||||
result.truncate(result.len() - 1);
|
result.truncate(result.len() - 1);
|
||||||
result.push('n');
|
result.push('n');
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ impl FromStr for ESTarget {
|
||||||
type Err = String;
|
type Err = String;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
match s.cow_to_lowercase().as_ref() {
|
match s.cow_to_ascii_lowercase().as_ref() {
|
||||||
"es5" => Ok(Self::ES5),
|
"es5" => Ok(Self::ES5),
|
||||||
"es6" | "es2015" => Ok(Self::ES2015),
|
"es6" | "es2015" => Ok(Self::ES2015),
|
||||||
"es2016" => Ok(Self::ES2016),
|
"es2016" => Ok(Self::ES2016),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue