( buffers: KernelBuffers, filePath: string, language: Language )
| 61 | } |
| 62 | |
| 63 | export function decodeExtractBuffers( |
| 64 | buffers: KernelBuffers, |
| 65 | filePath: string, |
| 66 | language: Language |
| 67 | ): ExtractionResult { |
| 68 | const { meta, arena } = buffers; |
| 69 | if (meta.length < META_SIZE) throw new Error(`kernel meta too short: ${meta.length}`); |
| 70 | const version = meta.readUInt8(META.version); |
| 71 | if (version !== KERNEL_ABI_VERSION) { |
| 72 | throw new Error(`kernel buffer ABI ${version} != expected ${KERNEL_ABI_VERSION}`); |
| 73 | } |
| 74 | const nodeCount = meta.readUInt32LE(META.nodeCount); |
| 75 | const edgeCount = meta.readUInt32LE(META.edgeCount); |
| 76 | const refCount = meta.readUInt32LE(META.refCount); |
| 77 | |
| 78 | const now = Date.now(); |
| 79 | const nodes: Node[] = new Array(nodeCount); |
| 80 | // Node-table row index → node id, for edge/ref endpoint resolution. |
| 81 | const idByRow: string[] = new Array(nodeCount); |
| 82 | |
| 83 | for (let i = 0; i < nodeCount; i++) { |
| 84 | const row = buffers.nodes.subarray(i * NODE_ROW_SIZE, (i + 1) * NODE_ROW_SIZE); |
| 85 | const id = str(arena, row, NODE.id)!; |
| 86 | idByRow[i] = id; |
| 87 | const flags = row.readUInt16LE(NODE.flags); |
| 88 | const node: Node = { |
| 89 | id, |
| 90 | kind: NODE_KINDS[row.readUInt8(NODE.kind)] as NodeKind, |
| 91 | name: str(arena, row, NODE.name)!, |
| 92 | qualifiedName: str(arena, row, NODE.qualifiedName)!, |
| 93 | filePath, |
| 94 | language, |
| 95 | startLine: row.readUInt32LE(NODE.startLine), |
| 96 | endLine: row.readUInt32LE(NODE.endLine), |
| 97 | startColumn: row.readUInt32LE(NODE.startColumn), |
| 98 | endColumn: row.readUInt32LE(NODE.endColumn), |
| 99 | updatedAt: now, |
| 100 | }; |
| 101 | const docstring = str(arena, row, NODE.docstring); |
| 102 | if (docstring !== undefined) node.docstring = docstring; |
| 103 | const signature = str(arena, row, NODE.signature); |
| 104 | if (signature !== undefined) node.signature = signature; |
| 105 | const visibility = VISIBILITIES[row.readUInt8(NODE.visibility)]; |
| 106 | if (visibility !== undefined) node.visibility = visibility; |
| 107 | const isExported = flag(flags, FLAG.isExported); |
| 108 | if (isExported !== undefined) node.isExported = isExported; |
| 109 | const isAsync = flag(flags, FLAG.isAsync); |
| 110 | if (isAsync !== undefined) node.isAsync = isAsync; |
| 111 | const isStatic = flag(flags, FLAG.isStatic); |
| 112 | if (isStatic !== undefined) node.isStatic = isStatic; |
| 113 | const isAbstract = flag(flags, FLAG.isAbstract); |
| 114 | if (isAbstract !== undefined) node.isAbstract = isAbstract; |
| 115 | const decorators = strList(arena, row, NODE.decorators); |
| 116 | if (decorators !== undefined) node.decorators = decorators; |
| 117 | const typeParameters = strList(arena, row, NODE.typeParameters); |
| 118 | if (typeParameters !== undefined) node.typeParameters = typeParameters; |
| 119 | const returnType = str(arena, row, NODE.returnType); |
| 120 | if (returnType !== undefined) node.returnType = returnType; |
no test coverage detected