fix(cpp): strip template args from out-of-line method receiver qualifiers (#1309)

template<typename T> T Box<T>::get() stored qualified_name Box<T>::get —
the <T> qualifier never matched the class node indexed as Box, so the
method didn't link to its class, while the inline form of the same
method produced Box::get. ICU-shaped multi-line template parameter
lists leaked whole <…> blocks (newlines included) into qualified_name,
exceeding NAME_MAX for downstream consumers.

extractCppReceiverType now applies stripCppTemplateArgs (the #1043
normalization for base-class refs) to the receiver qualifier.

fmt re-index: template-arg-in-qualifier names 25 -> 4 (remaining are a
FMT_BEGIN_EXPORT misparse artifact and gmock conversion-operator names,
both distinct pre-existing shapes), node count byte-stable at 7,536.

Fixes #1286

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Colby Mchenry
2026-07-16 15:04:38 -05:00
committed by GitHub
co-authored by Claude Fable 5
parent e1f339f732
commit 4dd29ea5c1
3 changed files with 70 additions and 1 deletions
+9 -1
View File
@@ -89,7 +89,15 @@ function extractCppReceiverType(node: SyntaxNode, source: string): string | unde
const qid = findDeclaratorQualifiedId(declarator);
if (!qid) return undefined;
const parts = getNodeText(qid, source).trim().split('::').filter(Boolean);
return parts.length > 1 ? parts.slice(0, -1).join('::') : undefined;
if (parts.length <= 1) return undefined;
// An out-of-line template method definition carries the class's template
// parameter list in the qualifier (`template<typename T> T Box<T>::get()`),
// but the class node is indexed as bare `Box` — strip `<…>` so the receiver
// matches it, the same normalization #1043 applies to base-class refs.
// Multi-line parameter lists otherwise leak whole `<…>` blocks (newlines
// included) into qualified_name, which can exceed NAME_MAX (#1286).
const receiver = stripCppTemplateArgs(parts.slice(0, -1).join('::'));
return receiver || undefined;
}
/**