Skip to content
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

Merged
merged 13 commits into from
Nov 24, 2023

Conversation

Yuiki
Copy link
Contributor

@Yuiki Yuiki commented Nov 23, 2023

Summary

Implement a useRegexLiterals lint rule.
fixes #353

Test Plan

  • Snapshot tests

@github-actions github-actions bot added A-Project Area: project A-Linter Area: linter A-Website Area: website L-JavaScript Language: JavaScript and super languages A-Diagnostic Area: diagnostocis labels Nov 23, 2023
@Yuiki Yuiki marked this pull request as ready for review November 23, 2023 11:13
Copy link
Member

@Conaclos Conaclos left a 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?

@Yuiki
Copy link
Contributor Author

Yuiki commented Nov 24, 2023

@Conaclos
Thank you for your comment!
I refactored some codes using global_identifier .

@Yuiki Yuiki requested a review from Conaclos November 24, 2023 11:15
Copy link
Member

@Conaclos Conaclos left a 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

Comment on lines 208 to 209
let expr = from.as_any_js_expression()?;
match expr.clone().omit_parentheses() {
Copy link
Member

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:

Suggested change
let expr = from.as_any_js_expression()?;
match expr.clone().omit_parentheses() {
let AnyJsCallArgument::AnyJsExpression(expr) = from else { return None };
match expr..omit_parentheses() {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix at 67e5e07

Comment on lines 210 to 235
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)
Copy link
Member

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.

Copy link
Contributor Author

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.

Comment on lines 241 to 251
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)
}
Copy link
Member

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:

Suggested change
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()
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix at 53c62e8

Copy link
Contributor Author

@Yuiki Yuiki left a 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."

Comment on lines 241 to 251
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)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix at 53c62e8

Comment on lines 210 to 235
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)
Copy link
Contributor Author

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.

Comment on lines 208 to 209
let expr = from.as_any_js_expression()?;
match expr.clone().omit_parentheses() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix at 67e5e07

@Yuiki Yuiki requested a review from Conaclos November 24, 2023 16:09
Copy link
Member

@Conaclos Conaclos left a 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 :)

@Conaclos Conaclos merged commit a3e14da into biomejs:main Nov 24, 2023
14 checks passed
@Yuiki Yuiki deleted the lint/useRegexLiterals branch November 25, 2023 01:17
@Conaclos Conaclos added the A-Changelog Area: changelog label Nov 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Changelog Area: changelog A-Diagnostic Area: diagnostocis A-Linter Area: linter A-Project Area: project A-Website Area: website L-JavaScript Language: JavaScript and super languages
Projects
None yet
Development

Successfully merging this pull request may close these issues.

📎 Implement lint/useRegexLiterals - eslint/prefer-regex-literals
2 participants