I found that wrapping an object literal across lines changes the normalized source when a property expression uses division after a keyword-named property such as x.type. This changes content-addressed function keys and can churn document hashes after a formatting-only edit.
From the repository root with Deno 2, run:
deno eval 'import { normalizeFnSource as normalize } from "./shared/compiler/normalize.ts"; const a = normalize("(x) => ({ a: x.type / 2, b: x.total })"); const b = normalize("(x) => ({\n a: x.type / 2,\n b: x.total\n})"); console.log(a); console.log(b); console.log("same normal form:", a === b);'I get:
(x)=>({a:x.type/ 2, b: x.total})
(x)=>({a:x.type/ 2,b:x.total})
same normal form: falseI expect both to normalize to (x)=>({a:x.type/2,b:x.total}), consistent with the layout-independent canonicalization rule in design D18.
In shared/compiler/normalize.ts, the scanner classifies type as a keyword even after property access. It is missing from the division-context set, so the following slash is rescanned as a regex and absorbs whitespace from the rest of that printed line. The AST equality gate accepts the result because the retained whitespace does not change the expression.
I propose treating keyword tokens after . and ?. as property identifiers when deciding whether the next slash is division. The join also needs to preserve a separator between division and a following regex literal so it cannot accidentally create a comment. I reproduced ordinary and optional property access and will cover both layout equality and literal preservation in regression tests.
I searched open and closed issues and PRs for normalization, division, and function hashes. PR #103 optimizes successful source analysis caching; it does not change this slash classification.
Activity
0No activity yet.