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',
);