-
-
Notifications
You must be signed in to change notification settings - Fork 477
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(linter): add eslint/no-unused-vars (⭐ attempt 3.2) #4445
Conversation
CodSpeed Performance ReportMerging #4445 will not alter performanceComparing Summary
|
Nice performance! I'll review this PR this weekend. |
Part of #4445, broken into a separate PR.
this is great! i get a false positive with: function test() {
return function Baz() {
return 'Baz';
};
}
test()(); output: × eslint(no-unused-vars): Function 'Baz' is declared but never used.
╭─[./test.ts:2:21]
1 │ function test() {
2 │ return function Baz() {
· ─┬─
· ╰── 'Baz' is declared here
3 │ return 'Baz';
╰────
help: Consider removing this declaration.
Finished in 7ms on 1 file with 1 rules using 12 threads.
Found 0 warnings and 1 error. also: input: import type { mySchema } from './my-schema';
function test(arg: ReturnType<typeof mySchema>) {
arg;
}
test(''); output: × eslint(no-unused-vars): Type 'mySchema' is imported but never used.
╭─[./test.tsx:1:15]
1 │ import type { mySchema } from './my-schema';
· ────┬───
· ╰── 'mySchema' is imported here
2 │
╰────
help: Consider removing this import.
Finished in 7ms on 1 file with 1 rules using 12 threads.
Found 0 warnings and 1 error. |
> Part of #4445 Fixes a bug where non-exported functions and variables inside of exported TS namespaces were being flagged with `SymbolFlags::Export` ```ts export namespace Foo { // incorrectly flagged as exported function foo() { } } ```
@camc314 thank you so much for the feedback! I'll add those cases and fix it up. |
Part of #4445, broken into a separate PR.
This is impressive work!! Found several cases should fail: // SS is unused
export abstract class PureComponent<P = {}, S = {}, SS = any> extends preact.Component<P, S> {
isPureReactComponent: boolean;
} import * as angular from "angular";
|
@mysteryven those examples are located in |
You are right. The semantic doesn't handle |
crates/oxc_linter/src/rules/eslint/no_unused_vars/binding_pattern.rs
Outdated
Show resolved
Hide resolved
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.
Awesome! Let's merge it after all requested changes are resolved!
> Part of #4445 Improve `debug_name` to show identifier names for more AST kinds.
> Part of #4445 Improve `debug_name` to show identifier names for more AST kinds.
> Part of #4445 Improve `debug_name` to show identifier names for more AST kinds.
NOTE: I'm pretty confident this will cause failures in Preact's lint CI job. Lemme make a PR into their codebase first. EDIT: PRs have been made into offending codebases. Depending on how much time we have between merging this PR and our next release, we should be ok to merge. |
Oxlint's [no-unused-vars](oxc-project/oxc#4445) PR will be merged soon. This PR updates `oxlint.json` to support some limitations of its implementation. - `@jsx` pragmas are not currently recognized as a usage, so `createElement` has been added to `varsIgnorePattern` - `Fragment` imports used via `<></>` syntax is not recognized as a usage, so `Fragment` has been added to `varsIgnorePattern` Note that there are still some unused variables and catch parameters that, when `no-unused-vars` gets merged, will cause lint CI to fail.
> Part of #4445 Improve `debug_name` to show identifier names for more AST kinds.
### Description Oxlint will be adding [no-unused-vars](oxc-project/oxc#4445) soon, which will add warnings to all unused variables. This PR updates Rolldown's `.oxlintrc.json` and cleans up some code to prevent your CI from failing. --------- Co-authored-by: Yunfei <i.heyunfei@gmail.com>
Merge activity
|
> Re-creation of #4427 due to rebasing issues. Original attempt: #642 ----- Third time's the charm? Each time I attempt this rule, I find a bunch of bugs in `Semantic`, and I expect this attempt to be no different. Expect sidecar issues+PRs stemming from this PR here. ## Not Supported These are cases supported in the original eslint rule, but that I'm intentionally deciding not to support - export comments in scripts ```js /* exported a */ var a; ``` - global comments ```js /* global a */ var a; ``` ## Behavior Changes These are intentional deviations from the original rule's behavior: - logical re-assignments are not considered usages ```js // passes in eslint/no-unused-vars, fails in this implementation let a = 0; a ||= 1; let b = 0; b &&= 2; let c = undefined; c ??= [] ``` ## Known Limitations - Lint rules do not have babel or tsconfig information, meaning we can't determine if `React` imports are being used or not. The relevant tsconfig settings here are `jsx`, `jsxPragma`, and `jsxFragmentName`. To accommodate this, all imports to symbols named `React` or `h` are ignored in JSX files. - References to symbols used in JSDoc `{@link}` tags are not created, so symbols that are only used in doc comments will be reported as unused. See: #4443 - `.vue` files are skipped completely, since variables can be used in templates in ways we cannot detect > note: `.d.ts` files are skipped as well. ## Todo - [x] Skip unused TS enum members on used enums - [x] Skip unused parameters followed by used variables in object/array spreads - [x] Re-assignments to array/object spreads do not respect `destructuredArrayIgnorePattern` (related to: #4435) - [x] #4493 - [x] References inside a nested scope are not considered usages (#4447) - [x] Port over typescript-eslint test cases _(wip, they've been copied and I'm slowly enabling them)_ - [x] Handle constructor properties ```ts class Foo { constructor(public a) {} // `a` should be allowed } ``` - [x] Read references in sequence expressions (that are not in the last position) should not count as a usage ```js let a = 0; let b = (a++, 0); console.log(b) ``` > Honestly, is anyone even writing code like this? - [x] function overload signatures should not be reported - [x] Named functions returned from other functions get incorrectly reported as unused (found by @camc314) ```js function foo() { return function bar() { } } Foo()() ``` - [x] false positive for TS modules within ambient modules ```ts declare global { // incorrectly marked as unused namespace jest { } } ``` ## Blockers - #4436 - #4437 - #4446 - #4447 - #4494 - #4495 ## Non-Blocking Issues - #4443 - #4475 (prevents checks on exported symbols from namespaces)
e97aa72
to
b952942
Compare
@DonIsaac Can you take a look at https://github.com/oxc-project/oxlint-ecosystem-ci/actions/runs/10173564561/job/28137965651. This case seems a false positive x eslint(no-unused-vars): Function 'onMessage' is declared but never used.
,-[wasm-runtime/fs-proxy.cjs:78:51]
77 | */
78 | module.exports.createOnMessage = (fs) => function onMessage(e) {
: ^^^^|^^^^
: `-- 'onMessage' is declared here
79 | if (e.data.__fs__) {
`----
help: Consider removing this declaration. |
Congrats! |
## [0.23.0] - 2024-08-01 - 27fd062 sourcemap: [**BREAKING**] Avoid passing `Result`s (#4541) (overlookmotel) ### Features - a558492 codegen: Implement `BinaryExpressionVisitor` (#4548) (Boshen) - 7446e98 codegen: Align more esbuild implementations (#4510) (Boshen) - 35654e6 codegen: Align operator precedence with esbuild (#4509) (Boshen) - b952942 linter: Add eslint/no-unused-vars (⭐ attempt 3.2) (#4445) (DonIsaac) - 85e8418 linter: Add react/jsx-curly-brace-presence (#3949) (Don Isaac) - cf1854b semantic: Remove `ReferenceFlags::Value` from non-type-only exports that referenced type binding (#4511) (Dunqing) ### Bug Fixes - b58ed80 codegen: Enable more test cases (#4585) (Boshen) - 6a94e3f codegen: Fixes for esbuild test cases (#4503) (Boshen) - d5c4b19 parser: Fix enum member parsing (#4543) (DonIsaac) ### Performance - 4c6d19d allocator: Use capacity hint (#4584) (Luca Bruno) - 7585e16 linter: Remove allocations for string comparisons (#4570) (DonIsaac) - 55a8763 parser: Faster decoding unicode escapes in identifiers (#4579) (overlookmotel) - ae1d38f parser: Fast path for ASCII when checking char after numeric literal (#4577) (overlookmotel) - 56ae615 parser: Make not at EOF the hot path in `Source` methods (#4576) (overlookmotel) - 25679e6 parser: Optimize `Lexer::hex_digit` (#4572) (overlookmotel) - bb33bcc parser: Speed up lexing non-decimal numbers (#4571) (overlookmotel) - ab8509e parser: Use `-` not `saturating_sub` (#4561) (overlookmotel) - c9c38a1 parser: Support peeking over bytes (#4304) (lucab) - 0870ee1 parser: Get and check lookahead token (#4534) (lucab) - d00014e sourcemap: Elide bounds checks in VLQ encoding (#4583) (overlookmotel) - 1fd9dd0 sourcemap: Use simd to escape JSON string (#4487) (Brooooooklyn) ### Documentation - 0914e47 ast: Add doc comments to literal nodes (#4551) (DonIsaac) - c6a11be ast: Auto-generate doc comments for AstBuilder methods (#4471) (DonIsaac) ### Refactor - e68ed62 parser: Convert lexer byte handler for `|` to a single match (#4575) (overlookmotel) - bba824b parser: Convert `Lexer::read_minus` to a single match (#4574) (overlookmotel) - ef5418a parser: Convert `Lexer::read_left_angle` to a single match (#4573) (overlookmotel) - 9e5be78 parser: Add `Lexer::consume_2_chars` (#4569) (overlookmotel) - 649913e parser: Extract `u8` not `&u8` when iterating over bytes (#4568) (overlookmotel) - 59f00c0 parser: Rename function (#4566) (overlookmotel) - 8e3e910 parser: Rename vars (#4565) (overlookmotel) - 0c0601f parser: Rename function (#4564) (overlookmotel) - 0acc4a7 parser: Fetch 2 bytes in `?` byte handler (#4563) (overlookmotel) - 565eccf parser: Shorten lexer code (#4562) (overlookmotel) - 148bdb5 parser: Adjust function inlining (#4530) (overlookmotel) - 16c7b98 semantic: Move CatchClause scope binding logic to visit_block_statement (#4505) (Dunqing) - d6974d4 semantic: `AstNodeParentIter` fetch nodes lazily (#4533) (overlookmotel) - d914b14 semantic: Reusing the same reference (#4529) (Dunqing) - 7b5e1f5 semantic: Use `is_empty()` instead of `len() == 0` (#4532) (overlookmotel) - 9db4259 semantic: Inline trivial methods (#4531) (overlookmotel) - 7c42ffc sourcemap: Align Base64 chars lookup table to cache line (#4535) (overlookmotel) - 96602bf transformer/typescript: Determine whether to remove `ExportSpeicifer` by `ReferenceFlags` (#4513) (Dunqing) - e6a8af6 traverse: Speed up tests (#4538) (overlookmotel) Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
> Part of #4445 Improve `debug_name` to show identifier names for more AST kinds.
> Part of #4445 Improve `debug_name` to show identifier names for more AST kinds.
## [0.7.0] - 2024-08-05 - 85a7cea semantic: [**BREAKING**] Remove name from `reference` (#4329) (Dunqing) ### Features - aaee07e ast: Add `AstKind::AssignmentTargetPattern`, `AstKind::ArrayAssignmentTarget` and `AstKind::ObjectAssignmentTarget` (#4456) (Dunqing) - 9df7b56 jsx-a11y/no-autofocus: Implement fixer support (#4171) (Jelle van der Waa) - b87bf70 linter: Add fix capabilties to existing lint rules (#4560) (DonIsaac) - ddd8b27 linter: Support conditional fix capabilities (#4559) (DonIsaac) - b952942 linter: Add eslint/no-unused-vars (⭐ attempt 3.2) (#4445) (DonIsaac) - 6543958 linter: Add auto-fix metadata to RuleMeta (#4557) (Don Isaac) - 85e8418 linter: Add react/jsx-curly-brace-presence (#3949) (Don Isaac) - 4c4da56 linter: Add typescript-eslint/prefer-keyword-namespce (#4438) (Aza Walker) - d8c2a83 linter: Eslint-plugin-vitest/no-import-node-test (#4440) (cinchen) - e3b0c40 linter: Eslint-plugin-vitest/no-identical-title (#4422) (cinchen) - c936782 linter: Eslint-plugin-vitest/no-conditional-expect (#4425) (cinchen) - 27fdd69 linter: Eslint-plugin-vitest/no-commented-out-tests (#4424) (cinchen) - 51f5025 linter: Add fixer for unicorn/prefer-string-starts-ends-with (#4378) (DonIsaac) - 3c0c709 linter: Add typescript-eslint/no-extraneous-class (#4357) (Jaden Rodriguez) - 7afa1f0 linter: Support suggestions and dangerous fixes (#4223) (DonIsaac) - acc5729 linter: Eslint-plugin-vitest/expect-expect (#4299) (cinchen) - 2213f93 linter: Eslint-plugin-vitest/no-alias-methods (#4301) (cinchen) - c296bc3 linter/eslint: Implement func-names (#4618) (Alexander S.) - e116ae0 linter/eslint: Implement fixer for prefer-numeric-literals (#4591) (Jelle van der Waa) - eaf834f linter/eslint: Implement prefer-numeric-literals (#4109) (Jelle van der Waa) - db2fd70 linter/eslint-plugin-promise: Implement no-webpack-loader-syntax (#4331) (Jelle van der Waa) - 5f1e070 linter/eslint-plugin-unicorn: Add fixer for prefer-code-point (#4353) (Jelle van der Waa) - ed49e16 linter/eslint-plugin-unicorn: Implement fixer for prefer-dom-node-append (#4306) (Jelle van der Waa) - e2b15ac linter/react: Implement react-jsx-boolean-value (#4613) (Jelle van der Waa) - 68efcd4 linter/react-perf: Handle new objects and arrays in prop assignment patterns (#4396) (DonIsaac) ### Bug Fixes - 368112c ast: Remove `#[visit(ignore)]` from `ExportDefaultDeclarationKind`'s `TSInterfaceDeclaration` (#4497) (Dunqing) - d384f60 ci: Remove unused(?) .html file (#4545) (Yuji Sugiura) - 06aec77 linter: Invalid binary expression with overflow (#4647) (DonIsaac) - b2da22b linter: Invalid tags in rule docs (#4646) (DonIsaac) - 94440ad linter: Panic on invalid lang in `a11y/lang`. (#4630) (rzvxa) - e0b03f8 linter: Improve the boundary for eslint/for-direction (#4590) (heygsc) - 70b8cfa linter: Missing return in no-obj-calls recursion (#4594) (DonIsaac) - fe1356d linter: Change no-unused-vars to nursery (#4588) (DonIsaac) - 72337b1 linter: Change typescript-eslint/no-namespace to restriction (#4539) (Don Isaac) - 732f4e2 linter: Fix `oxlint` allocator cfg (#4527) (overlookmotel) - 289dc39 linter: Overflow in no-obj-calls (#4397) (DonIsaac) - a664715 linter/eslint: Fix invalid regexp in no_regex_spaces test (#4605) (Yuji Sugiura) - 74fa75a linter/eslint: Drop quotes around max-params lint warning (#4608) (Jelle van der Waa) - 9fcd9ae linter/eslint: Fix invalid regexp in no_control_regex test (#4544) (leaysgur) - ac08de8 linter/react_perf: Allow new objects, array, fns, etc in top scope (#4395) (DonIsaac) - 0fba738 npm: SyntaxError caused by optional chaining in low version node (#4650) (heygsc) - 73d2558 oxlint: Fix oxlint failed to build due to missing feature (Boshen) ### Performance - 6ff200d linter: Change react rules and utils to use `Cow` and `CompactStr` instead of `String` (#4603) (DonIsaac) - f259df0 linter: Make img-redundant-alt only build a regex once (#4604) (DonIsaac) - 7585e16 linter: Remove allocations for string comparisons (#4570) (DonIsaac) - b60bdf1 linter: `no_shadow_restricted_names` only look up name in hashmap once (#4472) (overlookmotel) - 81384f5 linter: Avoid unnecessary work in `nextjs:no_duplicate_head` rule (#4465) (overlookmotel) - f7da22d linter: Disable lint rules by file type (#4380) (DonIsaac) - 348c1ad semantic: Remove `span` field from `Reference` (#4464) (overlookmotel) - 6a9f4db semantic: Reduce storage size for symbol redeclarations (#4463) (overlookmotel)- a207923 Replace some CompactStr usages with Cows (#4377) (DonIsaac) ### Refactor - 7a75e0f linter: Use diagnostic codes in lint rules (#4349) (DonIsaac) - ccb1835 semantic: Methods take `Span` as param, not `&Span` (#4470) (overlookmotel) - 7cd53f3 semantic: Var hoisting (#4379) (Dunqing) - c99b3eb syntax: Give `ScopeId` a niche (#4468) (overlookmotel) Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
Third time's the charm?
Each time I attempt this rule, I find a bunch of bugs in
Semantic
, and I expect this attempt to be no different. Expect sidecar issues+PRs stemming from this PR here.Not Supported
These are cases supported in the original eslint rule, but that I'm intentionally deciding not to support
Behavior Changes
These are intentional deviations from the original rule's behavior:
Known Limitations
React
imports are being used or not. The relevant tsconfig settings here arejsx
,jsxPragma
, andjsxFragmentName
. To accommodate this, all imports to symbols namedReact
orh
are ignored in JSX files.{@link}
tags are not created, so symbols that are only used in doc comments will be reported as unused. See: (proposal) feat(semantic): addReferenceFlag::JSDoc
#4443.vue
files are skipped completely, since variables can be used in templates in ways we cannot detectTodo
destructuredArrayIgnorePattern
(related to: bug(semantic): incorrect parents forArrayAssignmentTarget
#4435)Reference
has incorrect span, node_id, and symbol_id #4447)Blockers
AstNode
has incorrectScopeId
#4436MemberExpression
not recorded #4446Reference
has incorrect span, node_id, and symbol_id #4447typeof
operator on type imports not counted as a reference #4494typeof
not counted as a reference #4495Non-Blocking Issues
ReferenceFlag::JSDoc
#4443export default (function() {})
flagged asSymbolFlags::Export
#4475 (prevents checks on exported symbols from namespaces)