feat(linter): implement eslint/no-implicit-coercion rule#16735
feat(linter): implement eslint/no-implicit-coercion rule#16735camc314 merged 7 commits intooxc-project:mainfrom
Conversation
CodSpeed Performance ReportMerging #16735 will not alter performanceComparing Summary
Footnotes
|
camc314
left a comment
There was a problem hiding this comment.
This looks good - thanks for working on this!
|
Thanks for the review! I've addressed all your suggestions:
Really appreciate you pointing these out, learned some useful patterns here. |
camc314
left a comment
There was a problem hiding this comment.
Thank you! I pushed two more commits, one
The first adding support for lastIndexOf. Annoying I couldn't see any eslint test cases for this scenario. So i added some
And the second is refactoring the allow config property into bitflags (see the commit message for more detail/why)
This rule disallows shorthand type conversions using operators like
`!!`, `+`, `""+ `, `*1`, etc.
Detected patterns:
- `!!foo` → boolean coercion (suggest: Boolean(foo))
- `+foo` → number coercion (suggest: Number(foo))
- `1 * foo` / `foo * 1` → number coercion
- `foo - 0` → number coercion
- `- -foo` → number coercion via double negation
- `"" + foo` / `foo + ""` → string coercion (suggest: String(foo))
- `~foo.indexOf()` → boolean coercion
- \`\${foo}\` → string coercion (when disallowTemplateShorthand is true)
Configuration options:
- boolean: warn on boolean coercion (default: true)
- number: warn on number coercion (default: true)
- string: warn on string coercion (default: true)
- disallowTemplateShorthand: warn on template literal coercion (default: false)
- allow: list of operators to allow (e.g., ["!!", "+"])
- Rename is_number_call to is_already_numeric for clarity - Extract repeated diagnostic logic into report_coercion helper - Add CoercionKind enum for type-safe coercion classification - Improve comments explaining template literal whitespace check
- Use DefaultRuleConfig for simpler configuration parsing - Replace is_number_one helper with existing Expression::is_number_value
eslint doesnt have test cases for these, but it does flag `lastIndexOf`, this commit adds some test cases, and adds support for `lastIndexof`
Replace `Vec<CompactStr>` with `AllowedOperators` bitflags for checking allowed operators. Since the set of valid operators is fixed and small (6 values), bitflags provide O(1) lookup via bit operations instead of O(n) iteration, and avoid heap allocation for the Vec. The custom `Deserialize` impl uses a `Visitor` to parse directly from the JSON array without intermediate allocation, and now reports an error for unrecognized operator strings instead of silently ignoring them.
a92a268 to
18ab8db
Compare
|
Thanks for the enhancements! The lastIndexOf addition and bitflags refactor look great 👍 |
Summary
Implements the ESLint
no-implicit-coercionrule which disallows shorthand type conversions.Detected patterns
!!fooBoolean(foo)+fooNumber(foo)1 * foo/foo * 1Number(foo)foo - 0Number(foo)- -fooNumber(foo)"" + foo/foo + ""String(foo)~foo.indexOf()`${foo}`String(foo)Configuration options
{ "boolean": true, "number": true, "string": true, "disallowTemplateShorthand": false, "allow": ["!!", "+"] }References
Test plan