Render one symbol: details + (optional) body/outline + its caller/callee trail.
(cg: CodeGraph, node: Node, includeCode: boolean)
| 4163 | |
| 4164 | /** Render one symbol: details + (optional) body/outline + its caller/callee trail. */ |
| 4165 | private async renderNodeSection(cg: CodeGraph, node: Node, includeCode: boolean): Promise<string> { |
| 4166 | // Disk-drift gate (issue #1474): the body below is CURRENT bytes sliced at |
| 4167 | // INDEXED line ranges. If the file changed since its last index sync, that |
| 4168 | // slice can be a DIFFERENT symbol's code served under this node's name — |
| 4169 | // confidently wrong, with no watcher banner to catch it on a `projectPath` |
| 4170 | // (cross-project) target. Never emit a slice from a drifted file. |
| 4171 | if (this.isFileStaleOnDisk(cg, node.filePath)) { |
| 4172 | return this.renderStaleNodeSection(cg, node, includeCode); |
| 4173 | } |
| 4174 | let code: string | null = null; |
| 4175 | let outline: string | null = null; |
| 4176 | if (includeCode) { |
| 4177 | // For container symbols (class/interface/struct/…), the full body is the |
| 4178 | // sum of every method body — a wall of source. Return a structural outline |
| 4179 | // (members + signatures + line numbers) instead; leaf symbols return their |
| 4180 | // full body. |
| 4181 | if (CONTAINER_NODE_KINDS.has(node.kind)) { |
| 4182 | outline = this.buildContainerOutline(cg, node); |
| 4183 | } |
| 4184 | if (!outline) { |
| 4185 | code = await cg.getCode(node.id); |
| 4186 | } |
| 4187 | } |
| 4188 | return this.formatNodeDetails(node, code, outline) + this.formatTrail(cg, node); |
| 4189 | } |
| 4190 | |
| 4191 | // Whole-file fallback caps for a drifted file (#1474): small enough to fit |
| 4192 | // codegraph_node's output cap (MAX_OUTPUT_LENGTH) with headroom for the |
no test coverage detected