Skip to content

fix(lint): honor configured no-restricted-syntax selectors#542

Merged
samchon merged 3 commits into
masterfrom
fix/lint-no-restricted-syntax-options
Jul 14, 2026
Merged

fix(lint): honor configured no-restricted-syntax selectors#542
samchon merged 3 commits into
masterfrom
fix/lint-no-restricted-syntax-options

Conversation

@samchon

@samchon samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Summary

  • remove the built-in with/label denylist so an optionless rule is silent
  • add a validated esquery-compatible selector parser and matcher over the native TypeScript-Go AST
  • expose the official variadic selector/message types and document native TypeScript selector semantics
  • add exact-range, combinator, attribute, subject, TypeScript-node, invalid-config, and real-command regression shields

Validation

  • not run yet: per the required delivery sequence, focused local tests follow three clean exhaustive whole-PR reviews of one exact HEAD
  • formatter was not run

Closes #499

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from 3683bfb to 5ae1436 Compare July 14, 2026 05:15
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exhaustive whole-PR review found substantive correctness gaps before any clean round: duplicate selector listener semantics, computed/value paths, literal runtime types, indexed array paths, boolean attribute applicability, class and ESTree alias behavior, canonical token spelling, and a misplaced regression test. The fixes and shield coverage were rebased onto current master and pushed at exact HEAD 5ae1436. Review evidence is reset to 0/3; no local tests have run. Starting a fresh exhaustive whole-PR review of this exact HEAD now.

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from 5ae1436 to c0ff5fd Compare July 14, 2026 05:41
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exact-head review reset to 0/3 at \c0ff5fd3e458fdc6931d4a17dcbaceb599755d82\ after rebasing onto current master. Independent review found and fixed additional contract gaps: structured null/non-string options were accepted, RestElement/SpreadElement/Property aliases were conflated, numeric literal coercion and UTF-16 string length diverged from esquery, malformed unquoted values were accepted, and sibling/nth selectors flattened scalar and array fields. The new implementation preserves array-field boundaries, extends documented native structural lists, and adds regression shields for every finding. No formatter or tests have run; three fresh exhaustive whole-PR reviews start now on this immutable HEAD.

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from c0ff5fd to 4a7e76a Compare July 14, 2026 05:44
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Review finding before round 1 could be counted: the documented raw-literal and UTF-16 string-length behavior lacked a direct shield. Added an emoji/raw-source regression and adjusted the Program body assertion. Exact HEAD is now \4a7e76a5; counter remains 0/3 and round 1 restarts on this HEAD.

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from 4a7e76a to 64efcb2 Compare July 14, 2026 05:45
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

The new raw-literal shield itself exposed an invalid JSON-wrapper construction during review. It now marshals the selector string canonically. Exact HEAD is \64efcb25d3b2480e573580d20fb8d95e83470879; still 0/3, restarting full review 1.

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from 64efcb2 to 57372a9 Compare July 14, 2026 05:47
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Round-1 review found one more value-coercion gap before a clean round: non-decimal BigInt literals retained their source radix even though esquery literal equality observes canonical BigInt string values. Production now normalizes with the standard arbitrary-precision integer parser and the shield covers \

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from 57372a9 to 2432e26 Compare July 14, 2026 05:49
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Round-1 review also found that matching the whole tree once per configured selector grouped diagnostics by option order, unlike source traversal. Matches are now stably ordered by AST position while preserving duplicate reports and same-node selector order; a reversed-option regression proves it. Exact HEAD \2432e2665a0f746df76082bbdac3b6c7437393b5; still 0/3, restarting full review 1.

samchon added 2 commits July 14, 2026 14:51
Replace the fixed with/label denylist with a validated esquery-compatible selector parser and matcher over the native TypeScript-Go tree. The public tuple type, rule guide, exact-range regression shield, and real command cases preserve the variadic ESLint contract while documenting native tree semantics.

Constraint: No new dependencies, monkeypatching, formatting pass, or ESTree shadow tree.

Rejected: A node-kind switch | cannot express attributes, combinators, subjects, or TypeScript-specific syntax.

Rejected: A translated ESTree copy | duplicates traversal identity and loses native TypeScript nodes.

Confidence: medium

Scope-risk: moderate

Directive: Keep selector validation on the generic ruleOptionsValidator path and preserve native Parent/ForEachChild semantics.

Tested: Not run yet; required three exhaustive whole-PR reviews precede focused local tests.

Not-tested: Go selector/rule tests, lint build, and TypeScript config typecheck pending review completion.
The first exhaustive review exposed missing array paths, literal runtime types, boolean-property applicability, class aliases, duplicate-listener semantics, and a misplaced regression test. Model those concerns through native AST capabilities and the shared scanner instead of selector-specific branches.

Constraint: Preserve esquery grammar semantics while documenting TypeScript-Go tree differences.

Rejected: Synthetic false attributes on every node | presence selectors would match unrelated syntax.

Rejected: Per-call operator tables | the scanner already owns canonical token spelling.

Confidence: medium

Scope-risk: moderate

Directive: Any later selector change must reset exhaustive review evidence and retain native-tree semantics.

Tested: Not run; focused tests follow three clean exhaustive reviews at one exact HEAD.

Not-tested: Go and TypeScript validation remain intentionally deferred.

Related: #499
@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from 2432e26 to 977c0d2 Compare July 14, 2026 05:52
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Rebased onto master after #544 merged. The conflicts in shared rule types, autocomplete shields, README, and website docs were resolved by retaining both no-restricted-imports and no-restricted-syntax contracts; no side was dropped. Exact HEAD is now \977c0d2ad3b5e7ccaad1e4750012129e3bc6dbb8; counter is 0/3 and the first formal exhaustive whole-PR review starts on this head.

@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exhaustive whole-PR review 1/3 CLEAN at exact HEAD \977c0d2ad3b5e7ccaad1e4750012129e3bc6dbb8. Rechecked the full option schema and config boundary, selector grammar against esquery, TypeScript-Go traversal/field/list semantics, aliases, coercion and range behavior, diagnostic ordering, public types, command path, docs, conflict integration with #544, and every regression shield. No files changed. Starting independent full review 2 on the identical head; no tests or formatter run.

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from 977c0d2 to 800babb Compare July 14, 2026 05:53
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Review 2 found a semantic omission after the prior clean round: TypeScript-Go represents boolean and null literals as keyword kinds, so :expression/:pattern\ excluded them even though esquery's Literal nodes are expressions. The classifier now delegates to the complete literal predicate, with a \Literal:expression\ shield for \ rue\ and
ull. Exact HEAD \800babb0ecacb65434bd4c053301845b600f020d; all prior clean counts are invalidated and the counter resets to 0/3.

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from 800babb to b042f21 Compare July 14, 2026 05:58
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Review found that relational selectors on BigInt literals were falling through the Number-only coercion path, losing JavaScript's exact BigInt comparison semantics. The matcher now compares BigInt values exactly against both numeric selector literals and StringToBigInt-compatible string literals, with a regression above 2^53. Pushed as b042f21; the three exhaustive review rounds restart at 0/3 on this exact head.

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from b042f21 to be6a63a Compare July 14, 2026 06:07
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exhaustive review found that TypeScript-Go represents destructuring-assignment patterns as object/array literals and their rests as spread nodes. The ESTree aliases therefore overlapped incorrectly: assignment targets matched ObjectExpression/ArrayExpression/SpreadElement instead of ObjectPattern/ArrayPattern/RestElement. The matcher now uses the shared write-target classifier to distinguish those contexts, with array and object regression shields. Pushed as be6a63a; clean review count resets to 0/3 on this exact head.

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from be6a63a to 4a28e9d Compare July 14, 2026 06:08
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

The same whole-PR review also found that TypeScript-Go encodes an array destructuring default as an inner assignment-shaped BinaryExpression. That node is ESTree AssignmentPattern semantics, not AssignmentExpression semantics. AssignmentExpression aliasing now excludes nodes inside destructuring targets while retaining the outer assignment, with positive and negative regression coverage. Pushed as 4a28e9d; review count remains 0/3 on the new exact head.

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from 4a28e9d to abfaa86 Compare July 14, 2026 06:09
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Review found one more alias overlap: TypeScript-Go's no-substitution template kind was classified as both ESTree Literal and TemplateLiteral. ESTree keeps those categories distinct. Literal aliasing now excludes template literals while native template value/raw access and :expression behavior remain intact; the regression shield proves TemplateLiteral matches and Literal does not. Pushed as abfaa86; review count resets to 0/3.

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from abfaa86 to 9438f77 Compare July 14, 2026 06:10
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Whole-change review found a documented structural-field gap: switch CaseClause nodes exposed consequent but not their test expression, so native selectors such as CaseClause[test.value=1] could never match. The shared test path now covers case expressions, with a combined test/consequent regression. Pushed as 9438f77; the exact-head review count restarts at 0/3.

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from 9438f77 to 03a498c Compare July 14, 2026 06:11
@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from 017bdc0 to e0ddbb9 Compare July 14, 2026 06:30
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exhaustive review found that uniqueItems validation encoded structured option fields with NUL separators. Because JSON strings can contain NUL, two distinct selector/message tuples could collide and be rejected. Uniqueness now uses a typed comparable struct, preserving bare-vs-structured and missing-vs-empty-message identity without serialization ambiguity; a collision regression is included. Pushed as e0ddbb9; review count resets to 0/3.

@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exhaustive whole-PR review 1/3 is clean on exact HEAD e0ddbb9. Rechecked every production/test/type/documentation/corpus change, official schema/listener behavior, full grammar, AST identity/parent/list fields, aliases/classes, JavaScript primitive conversion, source-order diagnostics, range fidelity, and command dispatch. No changes were made.

@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exhaustive whole-PR review 2/3 is clean on exact HEAD e0ddbb9. This independent pass again covered the entire diff, emphasizing malformed/deep option inputs, duplicate listener identity, parser termination/recursion, regex safety, subject/:has boundaries, scalar-versus-list sibling semantics, native TypeScript contexts, concurrency/state isolation, public type soundness, documentation accuracy, and regression-test failure strength. No changes were made.

@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exhaustive whole-PR review 3/3 is clean on exact HEAD e0ddbb9. The third complete pass independently revalidated issue acceptance criteria, every changed file and public claim, AST traversal/identity and TypeScript-only cases, all selector/value/operator semantics, configuration failure isolation, diagnostic determinism, test oracle independence and coverage, compatibility, maintainability, and prohibited-pattern absence. No changes were made. Proceeding only now to focused local verification.

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from e0ddbb9 to 3f5a8e1 Compare July 14, 2026 06:37
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Focused execution reached the selector shield and exposed two stale test oracles, not production defects: the rest/spread fixture reused the same token text, and ReturnStatement was queried through the non-ESTree field name expression instead of argument. I made the fixture unambiguous and corrected the field selector in HEAD 3f5a8e1. Because the exact HEAD changed, the mandatory exhaustive review count is reset to 0/3 before any test rerun.

@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exhaustive whole-PR review 1/3 is CLEAN on exact HEAD 3f5a8e1. I independently re-read all ten changed files and compared the complete parser grammar, matcher traversal, subjects, combinators, list boundaries, native and ESTree aliases, JavaScript coercion, strict option validation, diagnostic ordering and ranges, public types, docs, command-path shields, commit metadata, and prohibited-pattern absence against the issue and primary esquery/ESLint sources. The two corrected test oracles now assert distinct rest/spread tokens and the canonical ReturnStatement argument field. No files changed. Starting full review 2 on the identical head; no test rerun or formatter has occurred.

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from 3f5a8e1 to 0bf03d1 Compare July 14, 2026 06:51
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exhaustive review 2 found a real alias-composition gap: TypeScript-Go represents ordinary members of a declared object binding pattern as BindingElement nodes, so ObjectPattern > Property missed them while object rest was already mapped to RestElement. The Property alias now includes only non-rest BindingElement children of ObjectBindingPattern, preserving the disjoint rest role. Positive key/value coverage and a negative rest-as-Property shield were added at exact HEAD 0bf03d1. All prior clean evidence is invalidated; the counter resets to 0/3 and no test rerun or formatter has occurred.

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from 0bf03d1 to d874666 Compare July 14, 2026 06:57
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

The same pre-round exhaustive pass found three additional generic adapter gaps and fixed them together at exact HEAD d874666: JavaScript numeric comparison must coerce an empty node list through the empty string to zero; native expression fields should use the canonical TypeScript-Go Node.Expression surface across every applicable kind; and scalar body fields were missing for catch clauses, labeled statements, and class static blocks. Load-bearing positive and negative shields cover empty-list coercion, computed-key expression traversal, and all three body relationships. Review count remains 0/3; no runtime tests or formatter have run.

@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exhaustive whole-PR review 1/3 is CLEAN on exact HEAD d874666, tree cc26f734bded129525b793e5bfe8068f40326c32. I re-read every production, test, type, corpus, README, website, and commit-metadata change and revalidated the issue contract, official selector grammar/listener behavior, native traversal and structural fields, all documented aliases, subjects and combinators, JavaScript value coercion, strict option rejection, source-order diagnostics, exact ranges, public type safety, command dispatch, regression-oracle strength, and prohibited-pattern absence. The new BindingElement, expression, scalar-body, and empty-list paths are role-based and general. No files changed. Starting independent full review 2 on this identical head; no tests or formatter run.

@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exhaustive whole-PR review 2/3 is CLEAN on unchanged HEAD d874666, tree cc26f734bded129525b793e5bfe8068f40326c32. This independent full pass again covered every changed file and acceptance criterion, including parser termination and malformed inputs, regex safety, subject and relative-selector boundaries, native parent identity, scalar versus list siblings, alias disjointness for declarations and assignments, all documented structural paths, primitive and object coercion edge cases, concurrency/state isolation, duplicate-listener behavior, diagnostics, public API compatibility, docs, command execution, and shield failure strength. Remote and local heads match; worktree and diff-check are clean. No changes, tests, or formatter run. Starting complete review 3.

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from d874666 to 92526e0 Compare July 14, 2026 06:59
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exhaustive review 3 found a weakness in the newly added empty-node-list shield before it could count clean: the expected text empty() also occurred in the preceding function declaration signature, so the range oracle was ambiguous. The fixture now declares the callable through an arrow binding, making the later zero-argument call the only target while preserving the production path under test. Exact HEAD is 92526e0. The previous 2/3 clean evidence is invalidated and the counter resets to 0/3; no test rerun or formatter has occurred.

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from 92526e0 to ad0d463 Compare July 14, 2026 07:00
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

The same zero-count test-oracle audit found another ambiguous target before review 1: the ReturnStatement identifier text also appeared earlier as the parameter declaration. The fixture now returns the unique property access arguments.length and the selector proves that complete node through the canonical ReturnStatement argument field. Exact HEAD is ad0d463; review count remains 0/3, with no runtime tests or formatter run.

@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exhaustive whole-PR review 1/3 is CLEAN on exact HEAD ad0d463, tree 12d7b2ac9f7cb84be2998805c4eaaa297c3f1541. I independently re-read all ten changed files, every test target, and the full issue/PR history; compared parser and listener behavior to primary esquery and ESLint sources; and revalidated native traversal, fields and lists, aliases, subjects, pseudos, coercion, option schema, deterministic diagnostics, exact ranges, public types, docs, real command coverage, commit integrity, and prohibited-pattern absence. All expected ranges are now unique and load-bearing. Local and remote heads match, worktree and diff-check are clean. No files changed, tests rerun, or formatter run. Beginning complete review 2.

@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from ad0d463 to 67fcbc0 Compare July 14, 2026 07:03
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exhaustive review 2 found a JavaScript getPath mismatch: when an intermediate property is null, esquery preserves null for the remaining path, while the adapter converted it to undefined. Null now propagates unchanged, with positive type(object) and negative type(undefined) shields through an absent IfStatement alternate. Exact HEAD is 67fcbc0. The prior clean round is invalidated and the review count resets to 0/3; no runtime tests or formatter have run.

Review exposed malformed option values, collapsed node-list boundaries, ESTree alias ambiguity, numeric coercion, UTF-16 length, and nullable structured options. The matcher now preserves native TypeScript coverage while keeping esquery's array-field and value semantics explicit.

Constraint: TypeScript-Go exposes native AST nodes rather than an ESTree projection
Rejected: Flatten every ForEachChild result into one sibling list | scalar fields are not esquery siblings
Confidence: high
Scope-risk: moderate
Directive: Extend structural selector fields explicitly; do not reintroduce flattened sibling semantics
Tested: Not run before the required three clean exact-HEAD review rounds
Not-tested: Focused Go and TypeScript validation pending review completion
@samchon samchon force-pushed the fix/lint-no-restricted-syntax-options branch from 67fcbc0 to a146b62 Compare July 14, 2026 07:04
@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

The zero-count review also found RegExp object stringification retained source flag order, while JavaScript RegExp.prototype.toString emits canonical flag order. Runtime regex values now canonicalize every valid ECMAScript flag in dgimsuvy order while raw remains exact source text; malformed flag sets are preserved rather than silently rewritten. The shield uses source /danger/mi, value /danger/im, and raw /danger/mi. Exact HEAD is a146b62; review count remains 0/3, with no runtime tests or formatter run.

@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exhaustive whole-PR review 1/3 is CLEAN on exact HEAD a146b62, tree 27b03ddf52e8b8744b19db8a7b91b10fe782d4e3. I re-read the entire ten-file change and every range oracle, rechecked the issue and all primary-source semantics, and covered parser grammar, selector recursion, subjects, native parent and node-list identity, fields, aliases, JS null/primitive/object/RegExp coercion, option uniqueness and listener replacement, report order, public types, docs, command validation, maintainability, and prohibited patterns. Local and remote heads match; worktree and diff-check are clean. No finding, file change, runtime test, or formatter. Starting a second complete review on the same head.

@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exhaustive whole-PR review 2/3 is CLEAN on unchanged HEAD a146b62, tree 27b03ddf52e8b8744b19db8a7b91b10fe782d4e3. This independent full review again covered every changed file and requirement, with adversarial checks of grammar backtracking and termination, malformed regex and options, exact-node and :has scope boundaries, subject collection, every native/alias role, list and scalar field semantics, null propagation, Number/BigInt/string/object comparison, RegExp source versus value, duplicate selector ordering, diagnostics, public config types, docs, command path, and all positive/negative shields. No finding or change; local/remote content and diff-check remain clean. No tests or formatter run. Starting complete review 3.

@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exhaustive whole-PR review 3/3 is CLEAN on exact HEAD a146b62, tree 27b03ddf52e8b8744b19db8a7b91b10fe782d4e3. The third independent complete pass revalidated every changed line, requirement, public claim, malformed-input boundary, AST role and parent/list relationship, alias and coercion case, deterministic range/message oracle, test isolation, compatibility, maintainability, and anti-hardcode/monkeypatch/test-branch rule. I also fetched current master 7716093 and inspected a clean virtual merge tree 9d8cb3860e3d46438c777661f8398574929098ca; the overlapping README, rule type, and website edits preserve both merged no-loop-func work and this no-restricted-syntax contract. No changes. Three clean exact-head reviews are complete; proceeding only now to focused local verification. Formatter remains untouched.

@samchon

samchon commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Exact HEAD a146b6286c644a0ce49f3ae9cc0c8551ee3d32e5 completed three sequential exhaustive whole-PR reviews with no findings.

Focused local verification after the reviews:

  • GOFLAGS=-run=NoRestrictedSyntax node scripts/test-go-lint.cjs ? PASS (ok github.com/samchon/ttsc/packages/lint/linthost)
  • pnpm --filter @ttsc/lint build ? PASS

No formatter was run.

@samchon samchon merged commit b78d51e into master Jul 14, 2026
43 of 48 checks passed
@samchon samchon deleted the fix/lint-no-restricted-syntax-options branch July 14, 2026 07:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(lint): make no-restricted-syntax enforce only configured selectors

1 participant