Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/oxc_ast/src/ast_impl/js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
}
}

Expand Down
10 changes: 3 additions & 7 deletions crates/oxc_ecmascript/src/side_effects/may_have_side_effects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}),
Expand Down
5 changes: 1 addition & 4 deletions crates/oxc_ecmascript/src/to_primitive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
Expand Down
4 changes: 1 addition & 3 deletions crates/oxc_linter/src/ast_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions crates/oxc_linter/src/rules/eslint/valid_typeof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 0 additions & 3 deletions crates/oxc_linter/src/rules/jest/valid_title.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
12 changes: 3 additions & 9 deletions crates/oxc_linter/src/rules/react/button_has_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions crates/oxc_linter/src/utils/express.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())),
}
Expand Down
12 changes: 5 additions & 7 deletions crates/oxc_linter/src/utils/jest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
};
Expand Down Expand Up @@ -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));
Expand All @@ -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")
Expand Down
6 changes: 4 additions & 2 deletions crates/oxc_linter/src/utils/jest/parse_jest_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

Expand Down Expand Up @@ -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,
Expand Down
7 changes: 2 additions & 5 deletions crates/oxc_linter/src/utils/unicorn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
}
Expand Down
Loading