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

Function inferJavaFieldReceiverType

src/resolution/name-matcher.ts:1060–1107  ·  view source on GitHub ↗

* Java/Kotlin: infer a receiver's declared type by walking field declarations * in the class enclosing the call site. The field's `signature` is already in * the form " " (set by tree-sitter.ts extractField), so we * pull the type from there. Handles Spring `@Resource UserBO

(
  receiverName: string,
  ref: UnresolvedRef,
  context: ResolutionContext,
)

Source from the content-addressed store, hash-verified

1058 * null when no matching field is in the enclosing class.
1059 */
1060function inferJavaFieldReceiverType(
1061 receiverName: string,
1062 ref: UnresolvedRef,
1063 context: ResolutionContext,
1064): string | null {
1065 const inFile = context.getNodesInFile(ref.filePath);
1066 if (inFile.length === 0) return null;
1067
1068 // Find the class enclosing the call line (tightest match by latest start).
1069 let enclosing: Node | null = null;
1070 for (const n of inFile) {
1071 if (n.kind !== 'class' && n.kind !== 'interface') continue;
1072 if (n.language !== ref.language) continue;
1073 const end = n.endLine ?? n.startLine;
1074 if (n.startLine <= ref.line && end >= ref.line) {
1075 if (!enclosing || n.startLine >= enclosing.startLine) enclosing = n;
1076 }
1077 }
1078 if (!enclosing) return null;
1079
1080 const enclosingEnd = enclosing.endLine ?? enclosing.startLine;
1081 const field = inFile.find(
1082 (n) =>
1083 n.kind === 'field' &&
1084 n.name === receiverName &&
1085 n.language === ref.language &&
1086 n.startLine >= enclosing.startLine &&
1087 (n.endLine ?? n.startLine) <= enclosingEnd,
1088 );
1089 if (!field || !field.signature) return null;
1090
1091 // Signature shape: "<TypeName> <fieldName>" (extractField). Pull the type,
1092 // strip generics + dotted package, drop array/varargs markers.
1093 const beforeName = field.signature.slice(
1094 0,
1095 field.signature.lastIndexOf(field.name),
1096 );
1097 const typeRaw = beforeName.trim();
1098 if (!typeRaw) return null;
1099
1100 const typeNoGenerics = typeRaw.replace(/<[^>]*>/g, '').trim();
1101 const typeNoArray = typeNoGenerics.replace(/\[\s*\]/g, '').replace(/\.\.\.$/, '').trim();
1102 const parts = typeNoArray.split(/[.\s]+/).filter(Boolean);
1103 const lastPart = parts[parts.length - 1];
1104 if (!lastPart) return null;
1105 if (!/^[A-Z]/.test(lastPart)) return null; // primitives / lowercase → skip
1106 return lastPart;
1107}
1108
1109// ── Local-variable receiver-type inference (#1108) ──────────────────────────
1110//

Callers 1

matchMethodCallFunction · 0.85

Calls 1

getNodesInFileMethod · 0.65

Tested by

no test coverage detected