Repository navigation
fix(scripts): the where-matcher lift reads identifiers from code, never from template-literal text - #30472
Merged
Conversation
…rom template-literal text identifiersIn was a word regex over source text, so a refusal message naming a sibling binding pulled it into the lift and a conforming matcher read unjudged. It now walks the parsed tree; self-test pins both directions. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Utp6CYZ6tmbWZDWzLW4Yzg
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Utp6CYZ6tmbWZDWzLW4Yzg
This was referenced Nov 5, 2026
Contributor
Author
|
domain:server#4 · os-bill · session_01Utp6CZMkHvuDeVYgTD73qF 席位意见:ACCEPT(#29860)。where-matcher 一致性检查现在只从代码里收标识符(语法树上的 Identifier,含 席位核对Head-sha:
|
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.
Requested by Bill · project thread
domain:server#4 · os-bill · session_01Utp6CZMkHvuDeVYgTD73qF
Fixes #29860
Clause-②: no — an internal instrument; no product surface moves
Metadata-protocol: none
维护者速读
${…}里的表达式仍算代码照收。driver对象一起拉进来,运行时报name is not defined,一个本来合规的替身被判"无法判定",挡住了 PR fix(objectql): a write answers every stored declared column the driver did not echo as null, as the next read does (#29538) #29858,作者只好改文案绕过去。门禁结论不该取决于报错文案用了哪个英文单词。scripts/check-where-matcher-conformance.mjs的identifiersIn(改为遍历语法树)与buildCallable里读sourceIdentifiers的三行;self-test 新电池#29860。pnpm check:where-matcher,预期 self-test 打印 OK,全树一行0 silently-wrong and 0 unjudged(合 main 后共 685 个 matcher)。What changes
identifiersInwas a word regex over source TEXT (/\b([A-Za-z_$][A-Za-z0-9_$]*)\b/g), so every word in a string literal, a template literal's text, a regular expression or a comment counted as a name the lift should follow. It now walks the parsed tree and collectsIdentifiernodes only: a${…}hole is code and is collected, the text around it is not. Discovery computes the sets off the nodes it already holds (the candidate'ssourceIdentifiers, and each visible declaration'sidentifiersbeside itstext), so nothing is re-parsed and no fragment goes through a second parse door.buildCallablefollows those sets instead of re-scanning text. The header's "Extraction" paragraph says what "names" now means.Over-inclusion stays in one direction only, as before: a property name (
row.name) is still an identifier node, and a name that resolves to no same-file declaration is skipped by the lift.Premise note. The card says ordinary string literals already behaved this way. Measured on
main, they did not: the same regex read them too. This PR covers both spellings, and the self-test pins both.Tests
New self-test battery
#29860: the lift reads identifiers from code, never from text(floor 7; roster floor 4 → 5):FIXTURE_TEXT_NAMES_SIBLING, the card's shape: a refusing matcher inside a factory whose messages say "sparse driver" (one template literal with a${k}hole, one plain string), besideconst driver = { name, … }that closes over the factory parameter. Pinned: discovered;driverandimplementednot collected; lifts and judges CONFORMING (refusing).FIXTURE_HOLE_NAMES_HELPER, the other direction: a same-file helperlabelnamed only inside a${…}hole on the matcher's answering path. Pinned:labelcollected; the matcher lifts with it and judges CONFORMING.Mutation replay (one-off, restored by blob hash == HEAD)
template-literal TEXT names no identifier: "driver" in the message is not collected,a matcher beside text naming a sibling binding lifts and is CONFORMING, not UNJUDGED.if (ts.isTemplateExpression(n)) return;): self-test exit 1 —the helper named only inside the hole is collected,so the hole-reading matcher lifts with its helper and is CONFORMING.Real producer replay
packages/objectql/src/write-answer-declared-columns.test.tsread in memory with its messages put back tosparse driver:(the wording PR #29858 had to rename away), thendiscoverInSource+judge:main(989ae42):46 matches UNJUDGED could not lift: ReferenceError: name is not defined46 matches CONFORMINGAcceptance notes
684 matcher(s) discovered … 0 silently-wrong and 0 unjudged. Wall time about 15.6 s before, 14.9 s after. After mergingorigin/main(head da5a909):685 matcher(s) discovered … 0 silently-wrong and 0 unjudged.scripts/check-objectql-double-limit.mjscarries a near-identical lifter (identifiersInat line 400 is the same word regex). Same defect class, no real producer measured there; not touched (outside this card's file surface), reported to the seat.Verification
Gate list derived by
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(31 commands), each run with its exit code recorded before any pipe and reconciled with--ran;pnpm lintrun. Readings are in the os-dev-report on #29860.No changeset: the diff is one repo-root script that no released package ships (
skip-changeset).Generated by Claude Code