fix: align prefer-const with ESLint implementation#621
Merged
Conversation
Contributor
There was a problem hiding this comment.
Code Review
This pull request enhances the prefer-const rule by implementing auto-fix capabilities for variable declaration lists and improving the handling of destructuring assignments to align with ESLint semantics. It introduces several utility functions for scope resolution and destructuring traversal. Feedback focuses on optimizing performance by caching block-level variable lookups and ensuring correct symbol resolution in the write-counting logic to properly handle variable shadowing.
0d71863 to
71f39b6
Compare
Fix 8 bugs in the prefer-const rule to fully align detection, reporting location, and auto-fix behavior with ESLint's implementation. Bug fixes: - Fix cross-declaration destructuring in same scope not being reported - Fix `hasTargetNotInSet` missing leaf Identifier nodes in PropertyAssignment - Fix `destructuring: "all"` not checking write-level destructuring grouping - Fix `findEnclosingScope` missing ClassStaticBlockDeclaration - Fix `hasTargetNotInSet` missing SpreadAssignment in object destructuring - Fix shorthand name-based matching false-matching shadowed variables - Fix `countWritesByName` lacking scope awareness for shadowed variables - Fix reporting vs fix suppression for same-scope var/const in destructuring Auto-fix: - Implement `let` → `const` auto-fix when all bindings in VDL are const-eligible - Correctly suppress fix when not all bindings can be const or declarations are uninitialized Public utilities extracted: - `utils.FindEnclosingScope` — reusable scope boundary finder (also adopted by no-var) - `utils.VisitDestructuringIdentifiers` — reusable destructuring assignment pattern walker Refactored to use existing public functions: - Replace custom `collectBindingNames` with `utils.CollectBindingNames` - Replace hardcoded scope boundary list with `ast.IsFunctionLikeOrClassStaticBlockDeclaration` Test coverage: 192 test cases across 8 dimensions (vs ESLint's 125).
71f39b6 to
8b82f03
Compare
simplyme0823
approved these changes
Apr 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
prefer-construle to fully align detection, reporting location, and auto-fix behavior with ESLint's implementation.let→constauto-fix when all bindings in the VariableDeclarationList are const-eligible.FindEnclosingScopeandVisitDestructuringIdentifiersas public utilities ininternal/utils/for reuse by other rules (e.g.,no-var).utils.CollectBindingNames,ast.IsFunctionLikeOrClassStaticBlockDeclaration.Bug fixes
hasUnmergeableTargetchecked same VDL instead of same block scopehasTargetNotInSetmissed leaf Identifier nodes in PropertyAssignment valuesdestructuring: "all"didn't check write-level destructuring groupingfindEnclosingScopemissingClassStaticBlockDeclarationhasTargetNotInSetmissingSpreadAssignmentin object destructuringcountWritesByNamelacked scope awareness for shadowed variablescollectBlockAllVarNamesmissed imports/params/function declarations — used name-set instead of symbol-based scope checkingCode quality improvements
countWritesByName→countWritesBySym: accept symbol from caller instead of fragile re-resolutionhasNonReportableDestructuringTarget: replaced name-set approach with TypeChecker symbol-based scope comparison to handle all declaration types (imports, parameters, function/class declarations)isReadBeforeFirstAssigncall inshouldReportcollectBlockAllVarNamesfunctionVerification
--fixoutput byte-identical to ESLint on same inputRelated Links
Checklist