* Get full context for a node * * Returns the focal node along with its ancestors, children, * and both incoming and outgoing references. * * @param nodeId - ID of the focal node * @returns Context object with all related information
(nodeId: string)
| 30 | * @returns Context object with all related information |
| 31 | */ |
| 32 | getContext(nodeId: string): Context { |
| 33 | const focal = this.queries.getNodeById(nodeId); |
| 34 | |
| 35 | if (!focal) { |
| 36 | throw new Error(`Node not found: ${nodeId}`); |
| 37 | } |
| 38 | |
| 39 | // Get ancestors (containment hierarchy) |
| 40 | const ancestors = this.traverser.getAncestors(nodeId); |
| 41 | |
| 42 | // Get children |
| 43 | const children = this.traverser.getChildren(nodeId); |
| 44 | |
| 45 | // Get incoming references (things that reference this node) |
| 46 | const incomingEdges = this.queries.getIncomingEdges(nodeId); |
| 47 | const incomingRefs: Array<{ node: Node; edge: Edge }> = []; |
| 48 | for (const edge of incomingEdges) { |
| 49 | // Skip containment edges (already in ancestors) |
| 50 | if (edge.kind === 'contains') { |
| 51 | continue; |
| 52 | } |
| 53 | const node = this.queries.getNodeById(edge.source); |
| 54 | if (node) { |
| 55 | incomingRefs.push({ node, edge }); |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | // Get outgoing references (things this node references) |
| 60 | const outgoingEdges = this.queries.getOutgoingEdges(nodeId); |
| 61 | const outgoingRefs: Array<{ node: Node; edge: Edge }> = []; |
| 62 | for (const edge of outgoingEdges) { |
| 63 | // Skip containment edges (already in children) |
| 64 | if (edge.kind === 'contains') { |
| 65 | continue; |
| 66 | } |
| 67 | const node = this.queries.getNodeById(edge.target); |
| 68 | if (node) { |
| 69 | outgoingRefs.push({ node, edge }); |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | // Get type information (type_of, returns edges) |
| 74 | const types: Node[] = []; |
| 75 | const typeEdgeKinds: EdgeKind[] = ['type_of', 'returns']; |
| 76 | for (const kind of typeEdgeKinds) { |
| 77 | const typeEdges = this.queries.getOutgoingEdges(nodeId, [kind]); |
| 78 | for (const edge of typeEdges) { |
| 79 | const typeNode = this.queries.getNodeById(edge.target); |
| 80 | if (typeNode && !types.some((t) => t.id === typeNode.id)) { |
| 81 | types.push(typeNode); |
| 82 | } |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | // Get relevant imports |
| 87 | const imports: Node[] = []; |
| 88 | const fileNode = ancestors.find((a) => a.kind === 'file'); |
| 89 | if (fileNode) { |
nothing calls this directly
no test coverage detected