From ea04c5ee52c14adf8333b9dae185ae1f849f729c Mon Sep 17 00:00:00 2001 From: Gergo Magyar Date: Tue, 12 May 2026 12:39:02 +0100 Subject: [PATCH] docs(php): document '...' vs 'params' variadic-marker asymmetry (U5) The shared narrowOverloadCandidates pass in scope-resolution/passes/ overload-narrowing.ts checks for 'params'/'params ' as the variadic marker - the C# 'params' keyword convention. PHP uses '...' instead, matching its source-language syntax. The discrepancy is harmless in practice because PHP variadic methods set parameterCount=undefined, which skips the 'max !== undefined && argCount > max' gate that hosts the 'params' check entirely - so the C# branch is dead code for PHP. Document the asymmetry at both sites with cross-references so a future contributor reading either file lands on the full picture: - overload-narrowing.ts:48 area: explains the 'params' branch is C#- specific and warns that adding new markers requires auditing each adapter's arity-metadata.ts. - languages/php/arity-metadata.ts:46 area: explains PHP uses '...' intentionally and that the shared pass's 'params' branch is dead code for PHP because of the parameterCount=undefined setting. No behavior change. Existing PHP variadic-resolution tests already exercise the live '...' path. --- .../core/ingestion/languages/php/arity-metadata.ts | 11 +++++++++++ .../scope-resolution/passes/overload-narrowing.ts | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/gitnexus/src/core/ingestion/languages/php/arity-metadata.ts b/gitnexus/src/core/ingestion/languages/php/arity-metadata.ts index 6b80a057d..40662bd61 100644 --- a/gitnexus/src/core/ingestion/languages/php/arity-metadata.ts +++ b/gitnexus/src/core/ingestion/languages/php/arity-metadata.ts @@ -43,6 +43,17 @@ export function computePhpArityMetadata(fnNode: SyntaxNode): PhpArityMetadata { } if (p.type !== null) types.push(p.type); } + // PHP variadic marker convention: append the literal '...' string to + // `parameterTypes`. This is intentionally DIFFERENT from C#, which uses + // the literal 'params' (its source-language keyword). The shared + // `narrowOverloadCandidates` pass in `scope-resolution/passes/overload- + // narrowing.ts` checks for the C# 'params' marker — that branch is + // dead code for PHP because PHP variadic methods set `parameterCount + // = undefined` (see line below), which skips the `max !== undefined` + // gate that hosts the 'params' check. PHP's actual variadic-aware + // arity logic lives in `phpArityCompatibility` (arity.ts) and now + // also in `phpEmitUnresolvedReceiverEdges` (scope-resolver.ts), both + // of which check `'...'`. Finding 9 of PR #1497 adversarial review. if (hasVariadic) types.push('...'); const total = params.length; diff --git a/gitnexus/src/core/ingestion/scope-resolution/passes/overload-narrowing.ts b/gitnexus/src/core/ingestion/scope-resolution/passes/overload-narrowing.ts index ae448e326..f36287052 100644 --- a/gitnexus/src/core/ingestion/scope-resolution/passes/overload-narrowing.ts +++ b/gitnexus/src/core/ingestion/scope-resolution/passes/overload-narrowing.ts @@ -43,6 +43,16 @@ export function narrowOverloadCandidates( const max = d.parameterCount; const min = d.requiredParameterCount; if (max !== undefined && argCount > max) { + // Variadic marker check is C#-specific (the 'params' keyword). + // Other languages use their own marker — PHP uses '...' (see + // `languages/php/arity-metadata.ts:46`), Python uses '*args'- + // shaped metadata that lives outside `parameterTypes` entirely. + // This branch is dead code for those languages because they + // set `parameterCount = undefined` for variadic functions, + // which keeps `max` undefined and skips this check entirely. + // Adding new variadic markers here changes behavior for those + // other languages too — don't extend without auditing each + // adapter's `arity-metadata.ts`. Finding 9 of PR #1497. const variadic = d.parameterTypes !== undefined && d.parameterTypes.some((t) => t === 'params' || t.startsWith('params '));