File size: 1,803 Bytes
68d7816 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | import { parse } from '@moonshot-ai/tree-sitter-bash';
import type { SyntaxNode } from '@moonshot-ai/tree-sitter-bash';
import { LifecycleScope } from '#/app/scopes';
import { registerScopedService, ScopeActivation } from '#/_base/di/scope';
import type { BashParseOptions, BashParseResult, BashSyntaxNode } from './bashParser';
import { IBashParserService } from './bashParser';
interface MutableBashSyntaxNode {
type: string;
text: string;
startIndex: number;
endIndex: number;
isNamed: boolean;
children: BashSyntaxNode[];
}
function snapshot(root: SyntaxNode): BashSyntaxNode {
const order: SyntaxNode[] = [];
const stack: SyntaxNode[] = [root];
while (stack.length > 0) {
const node = stack.pop()!;
order.push(node);
for (const child of node.children) stack.push(child);
}
const dtos = new Map<SyntaxNode, MutableBashSyntaxNode>();
for (const node of order) {
dtos.set(node, {
type: node.type,
text: node.text,
startIndex: node.startIndex,
endIndex: node.endIndex,
isNamed: node.isNamed,
children: [],
});
}
for (const node of order) {
const dto = dtos.get(node)!;
for (const child of node.children) dto.children.push(dtos.get(child)!);
}
return dtos.get(root)!;
}
export class BashParserService implements IBashParserService {
declare readonly _serviceBrand: undefined;
parse(source: string, options: BashParseOptions = {}): BashParseResult {
const result = parse(source, options);
if (!result.ok) {
return { ok: false, reason: result.reason };
}
return { ok: true, hasError: result.hasError, root: snapshot(result.rootNode) };
}
}
registerScopedService(
LifecycleScope.App,
IBashParserService,
BashParserService,
ScopeActivation.OnDemand,
'bashParser',
);
|