Skip to content

Commit 24cccf1

Browse files
committed
Normalize the expression-position shape-detectors (#51)
Reading each expression detector myself (the audit agent's output was malformed): five matched a construct on the raw r.body, so an equivalent factoring slips them. Route them through expandAlts, same pattern as detectTernary/detectCallExpression: - detectBareArrowParam — `ref '=>'`; an opt-tail arrow (`[x, opt('=>', body)]`) was dropped (verified: variable.parameter now emitted for that factoring). - detectPropertyAccess — `'.'`/`'?.'` before a token ref. - detectParenArrowParams + detectArrowParamDelims — the deliberate pair that read the same arrow param-list production; routed identically so they still cannot disagree. - detectDirectParamKeywords — keyword directly before `(`; also recurse `sep`. detectConstructorKeywords already expands (no change). Byte-identical on all six shipped grammars. Twelve detectors are now shape-robust. The YAML region detectors are deferred to a semantics-aware pass: their fixed shapes encode DELIBERATE YAML semantics (detectFold stops at a leaf token and does NOT follow a rule-ref by design — an Indent+rule-ref is a SIBLING node, not a fold), so the audit's heuristic "follow the ref" fix would break the fold-vs-sibling meaning. Not every fixed shape is fragility — some are intent.
1 parent f6a9990 commit 24cccf1

1 file changed

Lines changed: 14 additions & 13 deletions

File tree

src/gen-tm.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2049,10 +2049,10 @@ function detectPropertyAccess(
20492049
}
20502050

20512051
function walk(expr: RuleExpr): void {
2052-
if (expr.type === 'seq') { checkSeq(expr.items); expr.items.forEach(walk); }
2053-
if (expr.type === 'alt') expr.items.forEach(walk);
2054-
if (expr.type === 'quantifier' || expr.type === 'group') walk(expr.body);
2055-
if (expr.type === 'sep') walk(expr.element);
2052+
for (const items of expandAlts(expr)) checkSeq(items); // normalized factorings
2053+
if (expr.type === 'seq' || expr.type === 'alt') expr.items.forEach(walk);
2054+
else if (expr.type === 'quantifier' || expr.type === 'group') walk(expr.body);
2055+
else if (expr.type === 'sep') walk(expr.element);
20562056
}
20572057

20582058
for (const rule of grammar.rules) walk(rule.body);
@@ -2079,8 +2079,8 @@ function detectBareArrowParam(grammar: CstGrammar, tokenNames: Set<string>): boo
20792079
}
20802080

20812081
function walk(expr: RuleExpr): boolean {
2082-
if (expr.type === 'seq') return checkSeq(expr.items) || expr.items.some(walk);
2083-
if (expr.type === 'alt') return expr.items.some(walk);
2082+
if (expandAlts(expr).some(checkSeq)) return true; // normalized factorings (opt-tail / alt / group)
2083+
if (expr.type === 'seq' || expr.type === 'alt') return expr.items.some(walk);
20842084
if (expr.type === 'quantifier' || expr.type === 'group') return walk(expr.body);
20852085
if (expr.type === 'sep') return walk(expr.element);
20862086
return false;
@@ -2112,8 +2112,8 @@ function detectParenArrowParams(grammar: CstGrammar): boolean {
21122112
}
21132113

21142114
function walk(expr: RuleExpr): boolean {
2115-
if (expr.type === 'seq') return checkSeq(expr.items) || expr.items.some(walk);
2116-
if (expr.type === 'alt') return expr.items.some(walk);
2115+
if (expandAlts(expr).some(checkSeq)) return true; // normalized factorings (opt-tail / alt / group)
2116+
if (expr.type === 'seq' || expr.type === 'alt') return expr.items.some(walk);
21172117
if (expr.type === 'quantifier' || expr.type === 'group') return walk(expr.body);
21182118
if (expr.type === 'sep') return walk(expr.element);
21192119
return false;
@@ -2159,8 +2159,8 @@ function detectArrowParamDelims(grammar: CstGrammar): { open: string; close: str
21592159
return false;
21602160
}
21612161
function walk(expr: RuleExpr): boolean {
2162-
if (expr.type === 'seq') return checkSeq(expr.items) || expr.items.some(walk);
2163-
if (expr.type === 'alt') return expr.items.some(walk);
2162+
if (expandAlts(expr).some(checkSeq)) return true; // normalized factorings (opt-tail / alt / group)
2163+
if (expr.type === 'seq' || expr.type === 'alt') return expr.items.some(walk);
21642164
if (expr.type === 'quantifier' || expr.type === 'group') return walk(expr.body);
21652165
if (expr.type === 'sep') return walk(expr.element);
21662166
return false;
@@ -2289,9 +2289,10 @@ function detectDirectParamKeywords(
22892289
}
22902290

22912291
function walk(expr: RuleExpr): void {
2292-
if (expr.type === 'seq') { checkSeq(expr.items); expr.items.forEach(walk); }
2293-
if (expr.type === 'alt') expr.items.forEach(walk);
2294-
if (expr.type === 'quantifier' || expr.type === 'group') walk(expr.body);
2292+
for (const items of expandAlts(expr)) checkSeq(items); // normalized factorings
2293+
if (expr.type === 'seq' || expr.type === 'alt') expr.items.forEach(walk);
2294+
else if (expr.type === 'quantifier' || expr.type === 'group') walk(expr.body);
2295+
else if (expr.type === 'sep') walk(expr.element);
22952296
}
22962297

22972298
for (const rule of grammar.rules) walk(rule.body);

0 commit comments

Comments
 (0)