Skip to content

Commit 5767717

Browse files
committed
docs: contextual-operator class (as/keyof/is/infer/satisfies) now FIXED in the ledger
1 parent 8548602 commit 5767717

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

docs/upstream-issues.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ TM-expressible parse/lex disambiguation in Monogram's wheelhouse, still open aft
5858

5959
**Contextual keywords (the `#891` class).** A word that is a keyword in some positions but a valid identifier elsewhere (`from`, `as`, `of`, …) was mis-scoped as a keyword *everywhere* by the flat global keyword match. **Fixed** for the always-before-a-fixed-token case: a scope-keyword the grammar *always* places immediately before the string token (only `from`: `'from' String_`) is emitted with a `(?=\s*["'])` lookahead, so `const from = 1` / `from()` / the `import from from "x"` binding scope as `variable`/`entity.name.function` (matching official) while the import-source `from` stays a keyword.
6060

61-
**Still open — `as` (attempted, reverted, deferred).** Generalizing the `from` guard to `as`/`keyof`/`is`/`infer`/`satisfies` (all "keyword only before a type/value") *failed*: unlike `from`, these are scoped by **four mechanisms at once** — the flat keyword group, a per-keyword `keyword.operator.expression.as` rule, the `type-inner` injection, and the structural type rules. De-keywording from the flat group alone both (a) *didn't* fix `const as = 1` (the per-keyword rule still fired) and (b) regressed `keyof`/`is`/`infer` in type position to `entity.name.type` (coverage 99.3%→99.2%). A correct fix must reconcile all four mechanisms positionally — real work, deferred. `of` as an identifier (`const of = 1`) — **the official grammar mis-scopes it too**, so it's a both-wrong case, not a gap.
61+
**FIXED — `as`/`keyof`/`is`/`infer`/`satisfies`/`asserts` (the contextual-operator class).** These are keywords in operator/type position but valid identifiers elsewhere (`const as = 1`); the flat keyword match over-scoped the identifier uses. Unlike `from` (one mechanism), these were scoped by **four at once** — the flat keyword group, the per-keyword `keyword.operator.expression.as` begin rule, the `type-inner` injection, and the structural type rules — which is why a first naive attempt (de-keywording only the flat group) failed: it didn't fix `const as` AND regressed `keyof`/`is`/`infer` in type position to `entity.name.type`. The landed fix reconciles all four: the keyword.operator.expression group is split into reserved operators (`typeof`/`new`/`void`/`delete`/`instanceof` — unconditional) vs contextual operators (a positional guard `(?=\s+OPERAND|\s*$)` — keyword iff followed by whitespace+an operand, or at EOL for multiline casts), the per-keyword begin rules get the same guard, and type-inner re-injects both so type-position uses keep keyword scope. The contextual set is derived agnostically from the grammar's `not(...)` reserved guards (no hardcoded words). Now `const as/keyof/is = 1` → `variable`, `x as T`/`as (A|B)`/`import * as ns`/`keyof T`/`p is T`/`infer U` → keyword — matching official. `of` as an identifier (`const of = 1`) — **the official grammar mis-scopes it too**, so a both-wrong case, not a gap.
6262

6363
> Action: run each through `test/test-issues.ts` to confirm before claiming. Listing here ≠ "breaks in Monogram" — it means "not yet correct-and-tested."
6464

0 commit comments

Comments
 (0)