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

Method createEdges

src/resolution/index.ts:1060–1122  ·  view source on GitHub ↗

* Create edges from resolved references

(resolved: ResolvedRef[])

Source from the content-addressed store, hash-verified

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

Calls 1

getNodeByIdMethod · 0.65

Tested by

no test coverage detected