46 lines
1.6 KiB
TypeScript
46 lines
1.6 KiB
TypeScript
import type { BlockKind, CodeBlock, LanguageAdapter } from './contract'
|
|
import { readFileSync } from 'node:fs'
|
|
import * as path from 'node:path'
|
|
import { TreeSitterRuntime } from './runtime'
|
|
|
|
/** 单元测试直接用依赖包里的 wasm,不走打包产物。 */
|
|
export const WASM_DIR = path.resolve(__dirname, '../../node_modules/@vscode/tree-sitter-wasm/wasm')
|
|
|
|
export const runtime = new TreeSitterRuntime(WASM_DIR)
|
|
|
|
export function readFixture(name: string): string {
|
|
return readFileSync(path.join(__dirname, 'fixtures', name), 'utf8')
|
|
}
|
|
|
|
/** 解析 source,把代码块树交给 use;语法树随后释放。 */
|
|
export async function withBlocks<T>(adapter: LanguageAdapter, languageId: string, source: string, use: (blocks: CodeBlock[]) => T): Promise<T> {
|
|
const tree = await runtime.parse(adapter, languageId, source)
|
|
try {
|
|
return use(adapter.toBlocks(tree.rootNode, source))
|
|
}
|
|
finally {
|
|
tree.delete()
|
|
}
|
|
}
|
|
|
|
/** 和原型 CODE_TREE 同样的写法:at 是 1 起的行号(单行,或 [起, 止])。 */
|
|
export interface Outline { at: number | [number, number], kind: BlockKind, kids?: Outline[] }
|
|
|
|
export function outline(blocks: CodeBlock[]): Outline[] {
|
|
return blocks.map((block) => {
|
|
const from = block.header.startRow + 1
|
|
const to = block.header.endRow + 1
|
|
const item: Outline = { at: from === to ? from : [from, to], kind: block.kind }
|
|
if (block.children.length > 0)
|
|
item.kids = outline(block.children)
|
|
return item
|
|
})
|
|
}
|
|
|
|
export function walk(blocks: CodeBlock[], visit: (block: CodeBlock) => void): void {
|
|
for (const block of blocks) {
|
|
visit(block)
|
|
walk(block.children, visit)
|
|
}
|
|
}
|