Render one symbol: details + (optional) body/outline + its caller/callee trail.
(cg: CodeGraph, node: Node, includeCode: boolean)
| 6254 | |
| 6255 | /** Render one symbol: details + (optional) body/outline + its caller/callee trail. */ |
| 6256 | private async renderNodeSection(cg: CodeGraph, node: Node, includeCode: boolean): Promise<string> { |
| 6257 | // Disk-drift gate (issue #1474): the body below is CURRENT bytes sliced at |
| 6258 | // INDEXED line ranges. If the file changed since its last index sync, that |
| 6259 | // slice can be a DIFFERENT symbol's code served under this node's name — |
| 6260 | // confidently wrong, with no watcher banner to catch it on a `projectPath` |
| 6261 | // (cross-project) target. Never emit a slice from a drifted file. |
| 6262 | if (this.isFileStaleOnDisk(cg, node.filePath)) { |
| 6263 | return this.renderStaleNodeSection(cg, node, includeCode); |
| 6264 | } |
| 6265 | let code: string | null = null; |
| 6266 | let outline: string | null = null; |
| 6267 | if (includeCode) { |
| 6268 | // For container symbols (class/interface/struct/…), the full body is the |
| 6269 | // sum of every method body — a wall of source. Return a structural outline |
| 6270 | // (members + signatures + line numbers) instead; leaf symbols return their |
| 6271 | // full body. |
| 6272 | if (CONTAINER_NODE_KINDS.has(node.kind)) { |
| 6273 | outline = this.buildContainerOutline(cg, node); |
| 6274 | } |
| 6275 | if (!outline) { |
| 6276 | code = await cg.getCode(node.id); |
| 6277 | } |
| 6278 | } |
| 6279 | return this.formatNodeDetails(node, code, outline) + this.formatTrail(cg, node); |
| 6280 | } |
| 6281 | |
| 6282 | // Whole-file fallback caps for a drifted file (#1474): small enough to fit |
| 6283 | // codegraph_node's output cap (MAX_OUTPUT_LENGTH) with headroom for the |
no test coverage detected