-
-
Notifications
You must be signed in to change notification settings - Fork 502
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(lint): implement a useRegexLiterals rule #843
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Preliminary comment:
Do you think you could reuse biome_js_syntax::global_identifier
?
@Conaclos |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, I provided an in-depth review
let expr = from.as_any_js_expression()?; | ||
match expr.clone().omit_parentheses() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid the clone we could write:
let expr = from.as_any_js_expression()?; | |
match expr.clone().omit_parentheses() { | |
let AnyJsCallArgument::AnyJsExpression(expr) = from else { return None }; | |
match expr..omit_parentheses() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix at 67e5e07
AnyJsExpression::AnyJsLiteralExpression(expr) => { | ||
let expr = expr.as_js_string_literal_expression()?; | ||
let text = expr.inner_string_text().ok()?; | ||
Some(text.to_string()) | ||
} | ||
AnyJsExpression::JsTemplateExpression(expr) => { | ||
let elements = expr.elements(); | ||
if !elements | ||
.iter() | ||
.all(|elem| matches!(elem, AnyJsTemplateElement::JsTemplateChunkElement(_))) | ||
{ | ||
return None; | ||
} | ||
|
||
let text = elements | ||
.iter() | ||
.filter_map(|elem| { | ||
elem.as_js_template_chunk_element() | ||
.unwrap() | ||
.template_chunk_token() | ||
.ok() | ||
}) | ||
.map(|elem| elem.text().replace('\n', "\\n")) | ||
.collect::<String>(); | ||
|
||
Some(text) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you could reuse as_static_value()
that is defined in biome_js_syntax/src/expr_ext.rs
. And check that the returned static value is a string ``StaticValue::String. Basically
as_static_value()` returns `SttaicValue::String` for a string literal and a template literal that consists of a single chunk.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I refactored codes using it at e0ec310
Thank you for letting me know.
fn extract_inner_text(expr: &JsComputedMemberExpression) -> Option<String> { | ||
let text = expr | ||
.member() | ||
.ok()? | ||
.as_any_js_literal_expression()? | ||
.as_js_string_literal_expression()? | ||
.inner_string_text() | ||
.ok()? | ||
.to_string(); | ||
Some(text) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid the string allocation you can return a TokenText
:
fn extract_inner_text(expr: &JsComputedMemberExpression) -> Option<String> { | |
let text = expr | |
.member() | |
.ok()? | |
.as_any_js_literal_expression()? | |
.as_js_string_literal_expression()? | |
.inner_string_text() | |
.ok()? | |
.to_string(); | |
Some(text) | |
} | |
fn extract_inner_text(expr: &JsComputedMemberExpression) -> Option<TokenText> { | |
expr | |
.member() | |
.ok()? | |
.as_any_js_literal_expression()? | |
.as_js_string_literal_expression()? | |
.inner_string_text() | |
.ok() | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix at 53c62e8
crates/biome_js_analyze/src/analyzers/nursery/use_regex_literals.rs
Outdated
Show resolved
Hide resolved
crates/biome_js_analyze/src/analyzers/nursery/use_regex_literals.rs
Outdated
Show resolved
Hide resolved
crates/biome_js_analyze/src/analyzers/nursery/use_regex_literals.rs
Outdated
Show resolved
Hide resolved
of use_regex_literals
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Conaclos
Thank you for the review. It was very insightful and I learned a lot."
crates/biome_js_analyze/src/analyzers/nursery/use_regex_literals.rs
Outdated
Show resolved
Hide resolved
crates/biome_js_analyze/src/analyzers/nursery/use_regex_literals.rs
Outdated
Show resolved
Hide resolved
fn extract_inner_text(expr: &JsComputedMemberExpression) -> Option<String> { | ||
let text = expr | ||
.member() | ||
.ok()? | ||
.as_any_js_literal_expression()? | ||
.as_js_string_literal_expression()? | ||
.inner_string_text() | ||
.ok()? | ||
.to_string(); | ||
Some(text) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix at 53c62e8
crates/biome_js_analyze/src/analyzers/nursery/use_regex_literals.rs
Outdated
Show resolved
Hide resolved
AnyJsExpression::AnyJsLiteralExpression(expr) => { | ||
let expr = expr.as_js_string_literal_expression()?; | ||
let text = expr.inner_string_text().ok()?; | ||
Some(text.to_string()) | ||
} | ||
AnyJsExpression::JsTemplateExpression(expr) => { | ||
let elements = expr.elements(); | ||
if !elements | ||
.iter() | ||
.all(|elem| matches!(elem, AnyJsTemplateElement::JsTemplateChunkElement(_))) | ||
{ | ||
return None; | ||
} | ||
|
||
let text = elements | ||
.iter() | ||
.filter_map(|elem| { | ||
elem.as_js_template_chunk_element() | ||
.unwrap() | ||
.template_chunk_token() | ||
.ok() | ||
}) | ||
.map(|elem| elem.text().replace('\n', "\\n")) | ||
.collect::<String>(); | ||
|
||
Some(text) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I refactored codes using it at e0ec310
Thank you for letting me know.
let expr = from.as_any_js_expression()?; | ||
match expr.clone().omit_parentheses() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix at 67e5e07
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! This is a great addition :)
Summary
Implement a useRegexLiterals lint rule.
fixes #353
Test Plan