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

Function goframeRouteEdges

src/resolution/goframe-synthesizer.ts:77–148  ·  view source on GitHub ↗
(ctx: ResolutionContext, onYield: MaybeYield)

Source from the content-addressed store, hash-verified

75}
76
77export async function goframeRouteEdges(ctx: ResolutionContext, onYield: MaybeYield): Promise<Edge[]> {
78 let scanned255 = 0;
79 // Route nodes the goframe extractor created, keyed by their package-qualified
80 // request type (`cash.ListReq`). `wanted` holds every key a handler signature
81 // could match — the qualified form plus its bare type fallback.
82 const routesByReqType = new Map<string, Node[]>();
83 const wanted = new Set<string>();
84 for (const route of (ctx.iterateNodesByKind?.('route') ?? ctx.getNodesByKind('route'))) {
85 if ((++scanned255 & 63) === 0) await onYield();
86 if (route.language !== 'go') continue;
87 const marker = route.qualifiedName.indexOf(GOFRAME_ROUTE_MARKER);
88 if (marker < 0) continue;
89 const joinKey = route.qualifiedName.slice(marker + GOFRAME_ROUTE_MARKER.length);
90 if (!joinKey) continue;
91 let arr = routesByReqType.get(joinKey);
92 if (!arr) { arr = []; routesByReqType.set(joinKey, arr); }
93 arr.push(route);
94 wanted.add(joinKey);
95 const dot = joinKey.lastIndexOf('.');
96 if (dot >= 0) wanted.add(joinKey.slice(dot + 1)); // bare fallback
97 }
98 if (routesByReqType.size === 0) return [];
99
100 // Handler candidates: Go methods whose signature takes a wanted request type by
101 // pointer, indexed by every matching (qualified + bare) form so a route can
102 // match precisely on `pkg.Type` and fall back to the bare `Type`.
103 const handlersByKey = new Map<string, Node[]>();
104 for (const method of (ctx.iterateNodesByKind?.('method') ?? ctx.getNodesByKind('method'))) {
105 if ((++scanned255 & 63) === 0) await onYield();
106 if (method.language !== 'go' || !method.signature) continue;
107 for (const t of pointerParamTypes(method.signature)) {
108 if (!wanted.has(t)) continue;
109 let arr = handlersByKey.get(t);
110 if (!arr) { arr = []; handlersByKey.set(t, arr); }
111 arr.push(method);
112 }
113 }
114
115 const edges: Edge[] = [];
116 const seen = new Set<string>();
117 let added = 0;
118 for (const [joinKey, routes] of routesByReqType) {
119 const bare = joinKey.includes('.') ? joinKey.slice(joinKey.lastIndexOf('.') + 1) : joinKey;
120 // Precise package-qualified match first; bare type only as a fallback (covers
121 // a same-package handler or an aliased import where the bare name is unique).
122 const candidates = handlersByKey.get(joinKey) ?? handlersByKey.get(bare);
123 if (!candidates || candidates.length === 0) continue;
124 const requestType = bare;
125 for (const route of routes) {
126 const handler = selectHandler(candidates, route.filePath);
127 if (!handler || route.id === handler.id) continue;
128 const key = `${route.id}>${handler.id}`;
129 if (seen.has(key) || added >= FANOUT_CAP) continue;
130 seen.add(key);
131 edges.push({
132 source: route.id,
133 target: handler.id,
134 kind: 'calls',

Callers 1

Calls 7

pointerParamTypesFunction · 0.85
selectHandlerFunction · 0.85
hasMethod · 0.80
iterateNodesByKindMethod · 0.65
getNodesByKindMethod · 0.65
getMethod · 0.65
setMethod · 0.45

Tested by

no test coverage detected