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

Method createEdges

src/resolution/index.ts:1052–1114  ·  view source on GitHub ↗

* Create edges from resolved references

(resolved: ResolvedRef[])

Source from the content-addressed store, hash-verified

1050 * Create edges from resolved references
1051 */
1052 createEdges(resolved: ResolvedRef[]): Edge[] {
1053 return resolved.map((ref) => {
1054 // `function_ref` (#756) is internal-only: it persists as a `references`
1055 // edge (the registration site depends on the callback), distinguishable
1056 // by metadata.resolvedBy === 'function-ref'. callers/impact already
1057 // traverse `references`, so registration sites surface with no
1058 // graph-layer changes.
1059 let kind: Edge['kind'] =
1060 ref.original.referenceKind === 'function_ref' ? 'references' : ref.original.referenceKind;
1061
1062 // Promote "extends" to "implements" when a class/struct targets an interface
1063 if (kind === 'extends') {
1064 const targetNode = this.queries.getNodeById(ref.targetNodeId);
1065 if (targetNode && (targetNode.kind === 'interface' || targetNode.kind === 'protocol')) {
1066 const sourceNode = this.queries.getNodeById(ref.original.fromNodeId);
1067 if (sourceNode && sourceNode.kind !== 'interface' && sourceNode.kind !== 'protocol') {
1068 kind = 'implements';
1069 }
1070 }
1071 }
1072
1073 // Promote "calls" to "instantiates" when the resolved target is a
1074 // class/struct. Languages without a `new` keyword (Python, Ruby)
1075 // express instantiation as `Foo()` — extraction can't tell that
1076 // apart from a function call without symbol info, but resolution
1077 // can: if `Foo` resolves to a class, the call IS an instantiation.
1078 if (kind === 'calls') {
1079 const targetNode = this.queries.getNodeById(ref.targetNodeId);
1080 if (targetNode && (targetNode.kind === 'class' || targetNode.kind === 'struct')) {
1081 kind = 'instantiates';
1082 }
1083 }
1084
1085 return {
1086 source: ref.original.fromNodeId,
1087 target: ref.targetNodeId,
1088 kind,
1089 line: ref.original.line,
1090 column: ref.original.column,
1091 metadata: {
1092 confidence: ref.confidence,
1093 resolvedBy: ref.resolvedBy,
1094 // The ORIGINAL reference text (and kind, when edge-kind promotion
1095 // rewrote it — calls→instantiates, extends→implements,
1096 // function_ref→references). If this edge's target is later removed
1097 // by a re-index, the edge is resurrected as exactly this ref and
1098 // re-resolved (#1240 removal case) — a faithful resurrection, so
1099 // re-resolution can never bind anywhere a full re-index wouldn't.
1100 // Reconstruction from the target node's name instead would strip
1101 // receiver/qualifier context (`h.greet` → `greet`) and risk a
1102 // wrong rebind; edges without refName (pre-#1240, synthesized) are
1103 // deliberately NOT resurrected for the same reason.
1104 refName: ref.original.referenceName,
1105 ...(ref.original.referenceKind !== kind ? { refKind: ref.original.referenceKind } : {}),
1106 // Uniform marker for function-as-value edges (#756), regardless of
1107 // which strategy resolved them (import vs matchFunctionRef) — lets
1108 // tooling label "callback registration" and lets validation diff
1109 // exactly the edges this feature added.

Calls 1

getNodeByIdMethod · 0.65

Tested by

no test coverage detected