MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / inferCppReceiverType

Function inferCppReceiverType

src/resolution/name-matcher.ts:687–748  ·  view source on GitHub ↗
(
  receiverName: string,
  ref: UnresolvedRef,
  context: ResolutionContext,
  depth = 0,
)

Source from the content-addressed store, hash-verified

685}
686
687function inferCppReceiverType(
688 receiverName: string,
689 ref: UnresolvedRef,
690 context: ResolutionContext,
691 depth = 0,
692): string | null {
693 // Per-file lines cache when available — this runs per `receiver->method()`
694 // ref and re-splitting the file each time is the same quadratic as the
695 // shared inferrer's (#1122).
696 const lines = context.getFileLines
697 ? context.getFileLines(ref.filePath)
698 : (context.readFile(ref.filePath)?.split(/\r?\n/) ?? null);
699 if (!lines || lines.length === 0) return null;
700
701 const callLineIndex = Math.max(0, Math.min(lines.length - 1, ref.line - 1));
702 const escapedReceiver = receiverName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
703 const receiverPattern = new RegExp(`\\b${escapedReceiver}\\b`);
704 const declaratorRegex = buildDeclaratorRegex(escapedReceiver);
705
706 for (let i = callLineIndex; i >= 0; i--) {
707 const line = lines[i];
708 if (!line || !receiverPattern.test(line)) continue;
709
710 const declaratorMatch = line.match(declaratorRegex);
711 if (declaratorMatch) {
712 const normalized = normalizeCppTypeName(declaratorMatch[1] ?? '');
713 if (normalized === 'auto') {
714 // `auto x = Foo::instance();` — the declared type is deduced; recover it
715 // from the initializer (call return type / construction) (#645).
716 const initType = inferCppAutoInitializerType(line, receiverName, ref, context, depth);
717 if (initType) return initType;
718 // No usable initializer on this line — keep scanning earlier ones.
719 } else if (normalized) {
720 return normalized;
721 }
722 }
723 }
724
725 const headerCandidates = [
726 ref.filePath.replace(/\.(?:c|cc|cpp|cxx)$/i, '.h'),
727 ref.filePath.replace(/\.(?:c|cc|cpp|cxx)$/i, '.hpp'),
728 ref.filePath.replace(/\.(?:c|cc|cpp|cxx)$/i, '.hxx'),
729 ].filter((candidate, index, arr) => arr.indexOf(candidate) === index && candidate !== ref.filePath);
730
731 for (const headerPath of headerCandidates) {
732 if (!context.fileExists(headerPath)) continue;
733 const headerLines = context.getFileLines
734 ? context.getFileLines(headerPath)
735 : (context.readFile(headerPath)?.split(/\r?\n/) ?? null);
736 if (!headerLines) continue;
737
738 for (const line of headerLines) {
739 if (!receiverPattern.test(line)) continue;
740 const declaratorMatch = line.match(declaratorRegex);
741 if (!declaratorMatch) continue;
742 const normalized = normalizeCppTypeName(declaratorMatch[1] ?? '');
743 if (normalized && normalized !== 'auto') return normalized;
744 }

Callers 2

resolveCppCallResultTypeFunction · 0.85
matchMethodCallFunction · 0.85

Calls 6

buildDeclaratorRegexFunction · 0.85
normalizeCppTypeNameFunction · 0.85
getFileLinesMethod · 0.80
readFileMethod · 0.80
fileExistsMethod · 0.80

Tested by

no test coverage detected