fix(tools): count kinds of code point, not code points, and cover a hostile tool name

"the two code points CPython refuses" counted classes: NUL is one code
point, unpaired surrogates are the whole 2,048-wide D800-DFFF block. Say
kinds, in both the docstring and the test comment that mirrors it, and
restore the "odd" qualifier the test comment dropped -- an even trailing
backslash run does not eat the closing quote.

The soft-keyword test title still said "only special in statement
position", which the previous commit's own three-way split contradicts
for `case`: `case_block` is a clause head inside a `match` statement, not
a statement.

Add the case the subscript tool-name path lacked. A lone surrogate is
reachable in a name through JSON.parse of MCP wire JSON, and that path
has no UNPRINTABLE / LONE_SURROGATE fallback -- only the same ES2019
well-formed stringification the Literal path leans on.
This commit is contained in:
Chinesezjc
2026-08-05 19:17:34 +08:00
parent f3c8695fd6
commit 72991bbcdb
2 changed files with 31 additions and 11 deletions
+5 -4
View File
@@ -263,10 +263,11 @@ function childClassName(base: string, segment: string): string {
* by a JS parser back into the same double.
*
* `JSON.stringify` is also what keeps this path's output parseable, and it is
* the only thing that does. It covers both classes of hazard: the two code
* points CPython refuses anywhere in source — NUL among the C0 controls, and
* unpaired surrogates under ES2019 well-formed stringification, which the
* engines range guarantees — and the ones that break this line in particular,
* the only thing that does. It covers both classes of hazard: the two kinds of
* code point CPython refuses anywhere in source — NUL among the C0 controls,
* and the whole D800DFFF unpaired-surrogate block, escaped under ES2019
* well-formed stringification, which the engines range guarantees — and the
* ones that break this line in particular,
* a bare `"` closing the literal early, a trailing odd backslash eating the
* closing quote, and a bare LF/CR ending it before its terminator. The
* `description` path carries {@link UNPRINTABLE} and {@link LONE_SURROGATE}