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

Function resolve

src/resolution/frameworks/drupal.ts:352–401  ·  view source on GitHub ↗
(ref: UnresolvedRef, context: ResolutionContext)

Source from the content-addressed store, hash-verified

350 },
351
352 resolve(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null {
353 const name = ref.referenceName;
354
355 // _controller: '\Drupal\module\...\ClassName::methodName' (double colon) or the
356 // single-colon controller-service form '\Drupal\...\ClassName:methodName'.
357 const controllerMatch = name.match(/^\\?(?:Drupal\\[^:]+\\)?([^\\:]+):{1,2}(\w+)$/);
358 if (controllerMatch) {
359 const [, className, methodName] = controllerMatch;
360 const classNodes = context.getNodesByName(className!);
361 for (const cls of classNodes) {
362 if (cls.kind !== 'class') continue;
363 const fileNodes = context.getNodesInFile(cls.filePath);
364 const method = fileNodes.find((n) => n.kind === 'method' && n.name === methodName);
365 if (method) {
366 return { original: ref, targetNodeId: method.id, confidence: 0.9, resolvedBy: 'framework' };
367 }
368 return { original: ref, targetNodeId: cls.id, confidence: 0.7, resolvedBy: 'framework' };
369 }
370 }
371
372 // _form / _entity_form: '\Drupal\module\...\ClassName' (bare FQCN, no method)
373 if (name.includes('\\') && !name.includes(':')) {
374 const className = lastSegment(name);
375 if (className) {
376 const classNodes = context.getNodesByName(className);
377 const cls = classNodes.find((n) => n.kind === 'class');
378 if (cls) {
379 return { original: ref, targetNodeId: cls.id, confidence: 0.85, resolvedBy: 'framework' };
380 }
381 }
382 }
383
384 // hook_X — find any function whose name ends in _{hookSuffix} in a hook file
385 if (name.startsWith('hook_')) {
386 const hookSuffix = name.slice(5); // strip 'hook_'
387 const candidates = context.getNodesByKind('function').filter(
388 (n) => n.name.endsWith(`_${hookSuffix}`) && isDrupalHookFile(n.filePath)
389 );
390 if (candidates.length > 0) {
391 return {
392 original: ref,
393 targetNodeId: candidates[0]!.id,
394 confidence: 0.75,
395 resolvedBy: 'framework',
396 };
397 }
398 }
399
400 return null;
401 },
402
403 extract(filePath: string, content: string): { nodes: Node[]; references: UnresolvedRef[] } {
404 if (filePath.endsWith('.routing.yml')) {

Callers

nothing calls this directly

Calls 5

lastSegmentFunction · 0.85
isDrupalHookFileFunction · 0.85
getNodesByNameMethod · 0.65
getNodesInFileMethod · 0.65
getNodesByKindMethod · 0.65

Tested by

no test coverage detected