Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

feat(rome_analyze): implement the validTypeof rule #2649

Merged
merged 4 commits into from
Jun 9, 2022
Merged

Conversation

leops
Copy link
Contributor

@leops leops commented Jun 3, 2022

Summary

This PR implements the valid-typeof rule from ESLint verifying the result of typeof unary expressions is being compared to a valid expression (either a string literal that's a valid type name or another typeof expression)

Test Plan

I added test cases for the rule based on the examples found in the ESLint docs

@leops leops temporarily deployed to aws June 3, 2022 15:20 Inactive
@github-actions
Copy link

github-actions bot commented Jun 3, 2022

Parser conformance results on ubuntu-latest

js/262

Test result main count This PR count Difference
Total 45878 45878 0
Passed 44938 44938 0
Failed 940 940 0
Panics 0 0 0
Coverage 97.95% 97.95% 0.00%

jsx/babel

Test result main count This PR count Difference
Total 39 39 0
Passed 36 36 0
Failed 3 3 0
Panics 0 0 0
Coverage 92.31% 92.31% 0.00%

symbols/microsoft

Test result main count This PR count Difference
Total 5946 5946 0
Passed 350 350 0
Failed 5595 5596 ❌ ⏫ +1
Panics 1 0 ✅ ⏬ -1
Coverage 5.89% 5.89% 0.00%
⁉️ Panic To Failed (1):
typeGuardsAsAssertions.symbols

ts/babel

Test result main count This PR count Difference
Total 588 588 0
Passed 519 519 0
Failed 69 69 0
Panics 0 0 0
Coverage 88.27% 88.27% 0.00%

ts/microsoft

Test result main count This PR count Difference
Total 16257 16257 0
Passed 12391 12391 0
Failed 3866 3866 0
Panics 0 0 0
Coverage 76.22% 76.22% 0.00%

@cloudflare-pages
Copy link

cloudflare-pages bot commented Jun 3, 2022

Deploying with  Cloudflare Pages  Cloudflare Pages

Latest commit: 3e67e81
Status: ✅  Deploy successful!
Preview URL: https://97a83fe8.tools-8rn.pages.dev
Branch Preview URL: https://feature-valid-typeof.tools-8rn.pages.dev

View logs

@github-actions
Copy link

github-actions bot commented Jun 3, 2022


pub(crate) enum ValidTypeof {}

impl Rule for ValidTypeof {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add some documentation of what the rule is testing for.

ActionCategory, RuleCategory,
};

pub(crate) enum ValidTypeof {}
Copy link
Contributor

Choose a reason for hiding this comment

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

An empty enum... that's interesting. What's the reason behind using an empty enum over struct ValidTypeof;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It doesn't make a huge difference, we just need a type to implement the Rule trait on but that type will never be instantiated and this is made clear by using a type that actually can't be instantiated at all (while an empty struct can be instantiated, but will be zero-sized)

Comment on lines 62 to 63
.trim_start_matches(['"', '\''])
.trim_end_matches(['"', '\''])
Copy link
Contributor

Choose a reason for hiding this comment

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

You can do literal.inner_string_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.

inner_string_text returns a SyntaxNodeText, which I found less practical in this case as it needs to be collected into an allocated String in order to be matched-on, while text_trimmed returns an &str directly

Copy link
Contributor

Choose a reason for hiding this comment

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

There are no current usages of it. Should we change the implementation to return a string slice instead? Sounds like it's the more practical.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes that would make sense, the only downside I see to that is that a &str slice doesn't have any associated range information but it shouldn't be too much of a problem

return None;
}

if let JsAnyLiteralExpression::JsStringLiteralExpression(literal) = literal {
Copy link
Contributor

Choose a reason for hiding this comment

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

what if the right-hand side is a template literal?

>> typeof "a" ===  `string`
true

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is currently unsupported, I could probably add some code to handle the simple case with a single chunk / no interpolation, but it may not be needed eventually depending on how this rule interacts with the noUnusedTemplateLiteral rule

Copy link
Contributor

@ematipico ematipico left a comment

Choose a reason for hiding this comment

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

This rule should follow the naming convention: https://github.com/rome/tools/blob/main/CONTRIBUTING.md#naming-patterns

Hence, it should be called useValidTypeof or noInvalidTypeof

crates/rome_analyze/src/analyzers/valid_typeof.rs Outdated Show resolved Hide resolved
Some(RuleDiagnostic {
severity: Severity::Error,
message: markup! {
"Invalid typeof comparison value"
Copy link
Contributor

Choose a reason for hiding this comment

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

We should tell why the comparison is invalid.

Suggested change
"Invalid typeof comparison value"
"Invalid `typeof` comparison value"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To make a note on diagnostics here, in the context of a Rust-like diagnostic with rich codespan information it would be possible to attach context-specific messages to the actual label:

error[useValidTypeof]: Invalid typeof comparison value
   ┌─ useValidTypeof.js:10:1
   │
10 │ typeof bar !== "fucntion"
   │                ^^^^^^^^^^ not a valid type name
   
error[useValidTypeof]: Invalid `typeof` comparison value
   ┌─ useValidTypeof.js:14:1
   │
14 │ typeof bar == Object
   │               ^^^^^^ not a string literal

However I'm not entirely certain how to represent this information in the context of the LSP where we have a lot less control on how these diagnostics are rendered

Copy link
Contributor

Choose a reason for hiding this comment

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

Probably we should provide two messages/diagnostics: one for the CLI/CI and one for the LSP

@leops leops temporarily deployed to aws June 8, 2022 08:48 Inactive
@leops leops temporarily deployed to aws June 9, 2022 15:59 Inactive
@leops leops temporarily deployed to aws June 9, 2022 16:07 Inactive
@leops leops merged commit 0dd0bde into main Jun 9, 2022
@leops leops deleted the feature/valid-typeof branch June 9, 2022 16:22
@leops leops mentioned this pull request Jun 9, 2022
21 tasks
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants