mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
refactor(ast): check whether there is a single quasi in TemplateLiteral::quasi (#12265)
As the changes show, `TemplateLiteral::quasi` is always paired with a check to use, that check is whether there is only one single `quasi` in this `TemplateLiteral`. This PR is to put this check into the `TemplateLiteral::quasi` API, so that we can simplify the use of `TemplateLiteral::quasi`
This commit is contained in:
1 parent
2a1e805d55
commit
32c32aff4f
12 files changed
+28
-48
No files matched your search
@@ -544,12 +544,12 @@ impl<'a> TemplateLiteral<'a> {
|
||||
/// - `` `foo` `` => `true`
|
||||
/// - `` `foo${bar}qux` `` => `false`
|
||||
pub fn is_no_substitution_template(&self) -> bool {
|
||||
self.expressions.is_empty() && self.quasis.len() == 1
|
||||
self.quasis.len() == 1
|
||||
}
|
||||
|
||||
/// Get single quasi from `template`
|
||||
pub fn quasi(&self) -> Option<Atom<'a>> {
|
||||
self.quasis.first().and_then(|quasi| quasi.value.cooked)
|
||||
if self.is_no_substitution_template() { self.quasis[0].value.cooked } else { None }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -417,13 +417,9 @@ impl<'a> MayHaveSideEffects<'a> for ComputedMemberExpression<'a> {
|
||||
Expression::StringLiteral(s) => {
|
||||
property_access_may_have_side_effects(&self.object, &s.value, ctx)
|
||||
}
|
||||
Expression::TemplateLiteral(t) if t.is_no_substitution_template() => {
|
||||
property_access_may_have_side_effects(
|
||||
&self.object,
|
||||
&t.quasi().expect("template literal must have at least one quasi"),
|
||||
ctx,
|
||||
)
|
||||
}
|
||||
Expression::TemplateLiteral(t) => t.quasi().is_some_and(|quasi| {
|
||||
property_access_may_have_side_effects(&self.object, &quasi, ctx)
|
||||
}),
|
||||
Expression::NumericLiteral(n) => !n.value.to_integer_index().is_some_and(|n| {
|
||||
!integer_index_property_access_may_have_side_effects(&self.object, n, ctx)
|
||||
}),
|
||||
|
||||
@@ -93,10 +93,7 @@ pub fn maybe_object_with_to_primitive_related_properties_overridden(
|
||||
matches!(str.value.as_str(), "toString" | "valueOf")
|
||||
}
|
||||
PropertyKey::TemplateLiteral(temp) => {
|
||||
!temp.is_no_substitution_template()
|
||||
|| temp
|
||||
.quasi()
|
||||
.is_some_and(|val| matches!(val.as_str(), "toString" | "valueOf"))
|
||||
temp.quasi().is_some_and(|val| matches!(val.as_str(), "toString" | "valueOf"))
|
||||
}
|
||||
_ => true,
|
||||
},
|
||||
|
||||
@@ -308,9 +308,7 @@ pub fn extract_regex_flags<'a>(
|
||||
}
|
||||
let flag_arg = match &args[1] {
|
||||
Argument::StringLiteral(flag_arg) => flag_arg.value,
|
||||
Argument::TemplateLiteral(template) if template.is_no_substitution_template() => {
|
||||
template.quasi().expect("no-substitution templates always have a quasi")
|
||||
}
|
||||
Argument::TemplateLiteral(template) => template.quasi()?,
|
||||
_ => return None,
|
||||
};
|
||||
let mut flags = RegExpFlags::empty();
|
||||
|
||||
@@ -124,8 +124,8 @@ impl Rule for ValidTypeof {
|
||||
}
|
||||
|
||||
if let Expression::TemplateLiteral(template) = sibling {
|
||||
if template.expressions.is_empty() {
|
||||
if template.quasi().is_some_and(|value| !VALID_TYPES.contains(&value.as_str())) {
|
||||
if let Some(quasi) = template.quasi() {
|
||||
if !VALID_TYPES.contains(&quasi.as_str()) {
|
||||
ctx.diagnostic(invalid_value(None, sibling.span()));
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -180,9 +180,6 @@ impl ValidTitle {
|
||||
);
|
||||
}
|
||||
Argument::TemplateLiteral(template_literal) => {
|
||||
if !template_literal.is_no_substitution_template() {
|
||||
return;
|
||||
}
|
||||
if let Some(quasi) = template_literal.quasi() {
|
||||
validate_title(
|
||||
quasi.as_str(),
|
||||
|
||||
@@ -180,15 +180,9 @@ impl ButtonHasType {
|
||||
Expression::StringLiteral(str) => {
|
||||
self.is_valid_button_type_prop_string_literal(str.value.as_str())
|
||||
}
|
||||
Expression::TemplateLiteral(template_literal) => {
|
||||
if !template_literal.is_no_substitution_template() {
|
||||
return false;
|
||||
}
|
||||
if let Some(quasi) = template_literal.quasi() {
|
||||
return self.is_valid_button_type_prop_string_literal(quasi.as_str());
|
||||
}
|
||||
false
|
||||
}
|
||||
Expression::TemplateLiteral(template_literal) => template_literal
|
||||
.quasi()
|
||||
.is_some_and(|quasi| self.is_valid_button_type_prop_string_literal(quasi.as_str())),
|
||||
Expression::ConditionalExpression(conditional_expr) => {
|
||||
self.is_valid_button_type_prop_expression(&conditional_expr.consequent)
|
||||
&& self.is_valid_button_type_prop_expression(&conditional_expr.alternate)
|
||||
|
||||
@@ -462,8 +462,9 @@ impl JsxCurlyBracePresence {
|
||||
}
|
||||
}
|
||||
Expression::TemplateLiteral(template) => {
|
||||
if allowed.is_never() && template.is_no_substitution_template() {
|
||||
let string = template.quasi().unwrap();
|
||||
if allowed.is_never()
|
||||
&& let Some(string) = template.quasi()
|
||||
{
|
||||
if contains_quote_characters(string.as_str())
|
||||
|| is_allowed_string_like(
|
||||
ctx,
|
||||
|
||||
@@ -34,8 +34,8 @@ pub fn as_endpoint_registration<'a, 'n>(
|
||||
Expression::StringLiteral(path) => {
|
||||
Some((Some(path.value), &call.arguments.as_slice()[1..]))
|
||||
}
|
||||
Expression::TemplateLiteral(template) if template.is_no_substitution_template() => {
|
||||
Some((template.quasi(), &call.arguments.as_slice()[1..]))
|
||||
Expression::TemplateLiteral(template) => {
|
||||
template.quasi().map(|quasi| (Some(quasi), &call.arguments.as_slice()[1..]))
|
||||
}
|
||||
_ => Some((None, call.arguments.as_slice())),
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::borrow::Cow;
|
||||
use oxc_ast::{
|
||||
AstKind,
|
||||
ast::{
|
||||
CallExpression, Expression, ImportDeclaration, ImportDeclarationSpecifier, TemplateLiteral,
|
||||
CallExpression, Expression, ImportDeclaration, ImportDeclarationSpecifier,
|
||||
match_member_expression,
|
||||
},
|
||||
};
|
||||
@@ -271,8 +271,10 @@ pub fn get_node_name_vec<'a>(expr: &'a Expression<'a>) -> Vec<Cow<'a, str>> {
|
||||
Expression::StringLiteral(string_literal) => {
|
||||
chain.push(Cow::Borrowed(&string_literal.value));
|
||||
}
|
||||
Expression::TemplateLiteral(template_literal) if is_pure_string(template_literal) => {
|
||||
chain.push(Cow::Borrowed(template_literal.quasi().unwrap().as_str()));
|
||||
Expression::TemplateLiteral(template_literal) => {
|
||||
if let Some(quasi) = template_literal.quasi() {
|
||||
chain.push(Cow::Borrowed(quasi.as_str()));
|
||||
}
|
||||
}
|
||||
Expression::TaggedTemplateExpression(tagged_expr) => {
|
||||
chain.extend(get_node_name_vec(&tagged_expr.tag));
|
||||
@@ -294,10 +296,6 @@ pub fn get_node_name_vec<'a>(expr: &'a Expression<'a>) -> Vec<Cow<'a, str>> {
|
||||
chain
|
||||
}
|
||||
|
||||
fn is_pure_string(template_literal: &TemplateLiteral) -> bool {
|
||||
template_literal.expressions.is_empty() && template_literal.quasis.len() == 1
|
||||
}
|
||||
|
||||
pub fn is_equality_matcher(matcher: &KnownMemberExpressionProperty) -> bool {
|
||||
matcher.is_name_equal("toBe")
|
||||
|| matcher.is_name_equal("toEqual")
|
||||
|
||||
@@ -13,7 +13,7 @@ use oxc_span::Span;
|
||||
|
||||
use crate::{
|
||||
context::LintContext,
|
||||
utils::jest::{JestFnKind, JestGeneralFnKind, PossibleJestNode, is_pure_string},
|
||||
utils::jest::{JestFnKind, JestGeneralFnKind, PossibleJestNode},
|
||||
utils::valid_vitest_fn::is_valid_vitest_call,
|
||||
};
|
||||
|
||||
@@ -554,7 +554,9 @@ fn recurse_extend_node_chain<'a>(
|
||||
span: string_literal.span,
|
||||
});
|
||||
}
|
||||
Expression::TemplateLiteral(template_literal) if is_pure_string(template_literal) => {
|
||||
Expression::TemplateLiteral(template_literal)
|
||||
if template_literal.is_no_substitution_template() =>
|
||||
{
|
||||
chain.push(KnownMemberExpressionProperty {
|
||||
element: MemberExpressionElement::Expression(expr),
|
||||
parent: *parent,
|
||||
|
||||
@@ -181,8 +181,7 @@ pub fn is_same_expression(left: &Expression, right: &Expression, ctx: &LintConte
|
||||
}
|
||||
(Expression::StringLiteral(string_lit), Expression::TemplateLiteral(template_lit))
|
||||
| (Expression::TemplateLiteral(template_lit), Expression::StringLiteral(string_lit)) => {
|
||||
return template_lit.is_no_substitution_template()
|
||||
&& string_lit.value == template_lit.quasi().unwrap();
|
||||
return template_lit.quasi().is_some_and(|val| val.as_str() == string_lit.value);
|
||||
}
|
||||
(Expression::TemplateLiteral(left_str), Expression::TemplateLiteral(right_str)) => {
|
||||
return left_str.quasis.content_eq(&right_str.quasis)
|
||||
@@ -304,9 +303,7 @@ pub fn is_same_member_expression(
|
||||
// ex) x[/regex/] === x[`/regex/`]
|
||||
(Expression::TemplateLiteral(template_lit), Expression::RegExpLiteral(regex_lit))
|
||||
| (Expression::RegExpLiteral(regex_lit), Expression::TemplateLiteral(template_lit)) => {
|
||||
if !(template_lit.is_no_substitution_template()
|
||||
&& template_lit.quasi().unwrap() == regex_lit.raw.as_ref().unwrap())
|
||||
{
|
||||
if !template_lit.quasi().is_some_and(|val| val == regex_lit.raw.as_ref().unwrap()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user