fix(lint): restore canonical prevent-abbreviations semantics#545
Open
samchon wants to merge 16 commits into
Open
fix(lint): restore canonical prevent-abbreviations semantics#545samchon wants to merge 16 commits into
samchon wants to merge 16 commits into
Conversation
Replace occurrence-based abbreviation reports with binding-aware, collision-safe renames and the complete final upstream option contract. Preserve the legacy public rule ID across the upstream name-replacements rename. Constraint: Keep unicorn/prevent-abbreviations configuration compatibility. Rejected: Retain a handpicked abbreviation subset | it cannot satisfy upstream replacement and extension semantics. Confidence: medium Scope-risk: broad Directive: Keep binding/reference edits atomic and preserve shorthand external names. Tested: Not run before the required review rounds. Not-tested: Focused Go, corpus, command, and type-contract tests await the three exact-HEAD reviews.
Model declaration and reference occupancy separately, respect function-scoped var bindings, preserve disabled lookup keys, and inspect every merged declaration before offering edits. Apply import modes to static require and named-default syntax. Constraint: Every offered rename must preserve lexical and external binding semantics. Rejected: File-global name blocking | unnecessarily changes safe sibling-scope replacements. Confidence: high Scope-risk: moderate Directive: Collision checks must include unresolved and external references visible from the renamed binding. Tested: Not run before the required clean review rounds. Not-tested: Focused validation remains gated on three clean exact-HEAD reviews.
Use checker resolution, precise binding/reference scopes, parser-aware JSDoc attachment, and TypeScript signature scopes so fixes preserve every visible name while retaining upstream replacement behavior. Constraint: The rule must remain safe for TypeScript, JSX, Vue, exports, parameter properties, and compiler-provided globals without hardcoded environment name lists. Rejected: Hardcode DOM and built-in globals | would miss project and library declarations. Rejected: Reserve generated names across all ancestor scopes | rejects legal shadowing and diverges from lexical semantics. Confidence: high Scope-risk: moderate Directive: Keep collision decisions checker- and scope-derived; do not replace them with text-only name scans. Tested: Static diff integrity only; focused local tests are intentionally deferred until three clean exact-HEAD reviews. Not-tested: Go rule suite and TypeScript public-surface test have not yet run.
Exhaustive review found that nested parameters, exported destructuring, ambient declarations, type-only lexical scopes, and Unicode modifier letters could bypass safety or uniqueness rules. Align those boundaries with the TypeScript AST and the upstream Unicode category contract, and retain schema-valid empty replacement spellings. Constraint: Exact upstream semantics must coexist with source-only rename safety. Rejected: Suppress all destructuring or all exported-container bindings | would discard safe local fixes and diverge from lexical identity. Confidence: high Scope-risk: moderate Directive: Keep generated-name scopes tied to the smallest semantic TypeScript scope and preserve diagnostic-only external bindings. Tested: git diff --check; exhaustive static review of source, tests, types, docs, and upstream pinned sources. Not-tested: Focused local tests intentionally deferred until three clean exact-HEAD review rounds.
Exhaustive review found over-broad generated scopes, false collisions from JSX and type labels, unsafe property classification in destructuring assignments, default-export over-suppression, dotfile extension drift, and null replacement acceptance. Model each boundary from the TypeScript AST and align the documentation with the checker-backed implementation. Constraint: Fixes must remain source-local, collision-free, and compatible with the pinned upstream contract. Rejected: Treat every identifier-shaped token as lexical | property labels, intrinsic JSX tags, and external qualifiers do not participate in lexical lookup. Confidence: high Scope-risk: moderate Directive: Keep unresolved-reference occupancy limited to syntax that a new lexical declaration can actually capture. Tested: git diff --check; static comparison with TypeScript-Go scope/JSX APIs and Node path.extname behavior. Not-tested: Focused local tests intentionally deferred until three clean exact-HEAD review rounds.
A BindingElement does not carry its root declaration-list flags, so block-based scope lookup misclassified destructured var bindings as lexical. Resolve the root declaration before choosing var scope and pin two independently named destructured vars that target the same canonical replacement. Constraint: Generated names must follow JavaScript var hoisting, including nested binding patterns. Rejected: Special-case the regression's property names | declaration-root traversal covers every destructuring depth and loop form. Confidence: high Scope-risk: narrow Directive: Determine declaration semantics from the root declaration before assigning a BindingElement scope. Tested: git diff --check and static TypeScript AST parent-chain verification. Not-tested: Focused local tests intentionally deferred until three clean exact-HEAD review rounds.
Generated var names must respect lexical early-error restrictions in every containing block, loop, switch, and catch scope. Catch parameters and direct catch-body lexical declarations likewise share a collision boundary even though their AST containers differ. Constraint: ECMAScript early errors reject var/lexical and catch-parameter/body collisions before runtime. Rejected: Reserve every generated name function-wide | would unnecessarily prevent legal shadowing. Confidence: high Scope-risk: narrow Directive: Keep generated-name scope tracking aligned with ECMAScript declaration early errors. Tested: Static diff validation only; focused tests intentionally deferred until three clean exhaustive reviews. Not-tested: Local Go tests pending the mandated review sequence.
Generated names now retain binding identity so nested shadowing is accepted only when neither renamed declaration changes another generated binding's reference resolution. Constraint: Multiple fixes are computed against one original source tree and may introduce names that the checker cannot resolve yet. Rejected: Reserve names throughout every descendant scope | would reject legal shadowing without cross-scope reads. Confidence: high Scope-risk: narrow Directive: Generated-name collision checks must consider both declaration ancestry and reference scopes. Tested: Static diff validation only; focused tests intentionally remain after three clean exhaustive reviews. Not-tested: Local Go tests pending the mandated review sequence.
Only ESLint's exact virtual placeholders are excluded so valid platform filenames containing angle brackets still receive canonical abbreviation diagnostics. Constraint: The compatibility target excludes only <input> and <text> as virtual filenames. Rejected: Treat every angle-bracket filename as virtual | suppresses real Unix filenames. Confidence: high Scope-risk: narrow Tested: Static diff validation only; focused tests remain after three clean exhaustive reviews. Not-tested: Local Go tests pending the mandated review sequence.
The guide now distinguishes directly named-exported declarations from export-list aliases whose external spelling the fixer preserves. Constraint: Documentation must match the implemented export-specifier rewrite contract. Rejected: Describe every named export as diagnostic-only | contradicts the safe export-list fix and its regression test. Confidence: high Scope-risk: narrow Tested: Static diff validation only. Not-tested: Documentation build pending the mandated post-review validation phase.
Import-mode filtering now applies only to a non-optional bare require call with exactly one ordinary string literal, leaving other calls subject to normal binding checks. Constraint: Upstream static-require recognition excludes extra arguments, optional calls, and template literals. Rejected: Reuse the broader shared require extractor | it intentionally accepts shapes needed by security rules but changes this rule's option semantics. Confidence: high Scope-risk: narrow Tested: Static diff validation only; focused tests remain after three clean exhaustive reviews. Not-tested: Local Go tests pending the mandated review sequence.
Raw option keys are checked against the case-sensitive canonical schema before Go's case-insensitive struct-field matching can accept a typo. Constraint: Upstream additionalProperties false treats option names as case-sensitive. Rejected: Rely only on DisallowUnknownFields | encoding/json still accepts case-insensitive tag matches. Confidence: high Scope-risk: narrow Tested: Static diff validation only; focused tests remain after three clean exhaustive reviews. Not-tested: Local Go tests pending the mandated review sequence.
Duplicate ignore entries are rejected during validation to match the canonical option schema instead of silently compiling the same expression twice. Constraint: The upstream ignore array declares uniqueItems true. Rejected: Deduplicate silently | would accept a configuration the canonical schema rejects. Confidence: high Scope-risk: narrow Tested: Static diff validation only; focused tests remain after three clean exhaustive reviews. Not-tested: Local Go tests pending the mandated review sequence.
Attached-comment discovery now crosses transparent parentheses and TypeScript assertion wrappers before deciding whether a parameter rename can be offered. Constraint: A source-only rename must not leave an attached @param spelling stale. Rejected: Inspect only the immediate function parent chain | misses common as, satisfies, non-null, and type-assertion assignments. Confidence: high Scope-risk: narrow Directive: New transparent expression wrappers must participate in attached-JSDoc discovery. Tested: Static diff validation only; focused tests remain after three clean exhaustive reviews. Not-tested: Local Go tests pending the mandated review sequence.
Virtual-placeholder recognition is isolated behind a pure helper so exact boundaries can be tested without creating Windows-invalid fixture paths. Constraint: The focused suite must run on Windows and Unix. Rejected: Materialize angle-bracket filenames | Windows rejects them before the rule executes. Confidence: high Scope-risk: narrow Tested: Static diff validation only; focused tests remain after three clean exhaustive reviews. Not-tested: Local Go tests pending the mandated review sequence.
The canonical custom replacement contract accepts arbitrary replacement spellings, so generated variable names must suffix reserved words. Complete the reserved-word guard for break and lock the behavior with a focused regression. Constraint: Preserve upstream getAvailableVariableName semantics without adding dependencies. Confidence: high Scope-risk: narrow Tested: Static diff inspection and git diff --check. Not-tested: Local tests are intentionally deferred until three exact-HEAD exhaustive reviews complete.
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
Compatibility and safety
The established
unicorn/prevent-abbreviationsID retains the final upstream semantics from before the June 2026 rename toname-replacements. Fixes are withheld for declarations carrying a namedexportmodifier, ambient and cross-file-merged bindings, JSX tags,.vuefiles, parameter properties, and attached-JSDoc parameters when a source-only rename cannot preserve external meaning. Export-list aliases and default-export local names remain fixable because their external spellings are preserved.Validation
Three sequential exact-HEAD exhaustive reviews and focused local validation follow the repository workflow. No formatter was run.
Fixes #495