aboutsummaryrefslogtreecommitdiffstats
path: root/app/tree_sitter.c
blob: 4a5615fe36f2b38fddbeccb410c7b57a6892adc2 (plain)
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
#include "string.h"
#include "tree_sitter/api.h"

typedef struct Node {
  TSPoint start_point;
  TSPoint end_point;
  uint32_t start_byte;
  uint32_t end_byte;
} Node;

void extract_comments(
  TSLanguage* language,
  char* input,
  Node** out,
  uint32_t* out_len
) {
  TSParser* parser = ts_parser_new();
  ts_parser_set_language(parser, language);
  TSTree* tree = ts_parser_parse_string(parser, NULL, input, strlen(input));
  TSNode root_node = ts_tree_root_node(tree);
  TSTreeCursor tree_cursor = ts_tree_cursor_new(root_node);

  uint32_t n_max = 1024;
  uint32_t n = 0;
  *out = malloc(sizeof(Node) * n_max);

  Node* current_out = *out;
  TSNode current_node;
  bool process = true;
  while (true) {
    current_node = ts_tree_cursor_current_node(&tree_cursor);
    if (process && (0 == strcmp("comment", ts_node_type(current_node)))) {
      if (n >= n_max) {
        n_max *= 2;
        *out = realloc(*out, sizeof(Node) * n_max);
        current_out = *out + n;
      }
      current_out->start_byte = ts_node_start_byte(current_node);
      current_out->end_byte = ts_node_end_byte(current_node);
      current_out->start_point = ts_node_start_point(current_node);
      current_out->end_point = ts_node_end_point(current_node);
      n++;
      current_out++;
    }
    if (process && ts_tree_cursor_goto_first_child(&tree_cursor)) {
      process = true;
    } else if (ts_tree_cursor_goto_next_sibling(&tree_cursor)) {
      process = true;
    } else {
      if (!ts_tree_cursor_goto_parent(&tree_cursor)) break;
      process = false;
    }
  }

  *out_len = n;

  ts_tree_cursor_delete(&tree_cursor);
  ts_tree_delete(tree);
  ts_parser_delete(parser);
}