|
1 | | -// use libloading::{Library, Symbol, library_filename}; |
2 | 1 | use std::ops::Range; |
3 | | -use tree_sitter::{Node, Parser}; // use tree_sitter::{Language, Node, Parser}; |
4 | | -// use tree_sitter_language::LanguageFn; |
| 2 | +use std::path::{Path, PathBuf}; |
| 3 | +use tree_sitter::Parser; |
| 4 | + |
| 5 | +pub use tree_sitter::Node; |
| 6 | + |
| 7 | +pub mod loader; |
| 8 | +pub mod tools; |
5 | 9 |
|
6 | 10 | pub type GrammarName = &'static str; |
| 11 | +pub type SliceRange = Range<usize>; |
7 | 12 |
|
8 | | -#[derive(Debug)] |
9 | | -pub struct Item<'s, 'a> { |
10 | | - pub total_source: &'s str, |
11 | | - pub raw_node: Node<'a>, |
| 13 | +pub struct File { |
| 14 | + path: PathBuf, |
| 15 | + source: String, |
12 | 16 | } |
13 | 17 |
|
14 | | -impl<'s, 'a> Item<'s, 'a> { |
15 | | - pub fn source(&self) -> &'s str { |
16 | | - &self.total_source[self.range()] |
| 18 | +impl File { |
| 19 | + pub fn new(path: PathBuf, source: String) -> Self { |
| 20 | + Self { path, source } |
| 21 | + } |
| 22 | + |
| 23 | + pub fn path(&self) -> &Path { |
| 24 | + &self.path |
17 | 25 | } |
18 | 26 |
|
19 | | - pub fn range(&self) -> Range<usize> { |
20 | | - self.raw_node.start_byte()..self.raw_node.end_byte() |
| 27 | + pub fn source(&self) -> &str { |
| 28 | + &self.source |
21 | 29 | } |
22 | 30 |
|
23 | | - pub fn grammar_name(&self) -> &'static str { |
24 | | - self.raw_node.grammar_name() |
| 31 | + pub fn node_text(&self, item: Node<'_>) -> &str { |
| 32 | + item.utf8_text(self.source.as_bytes()).unwrap() |
25 | 33 | } |
26 | 34 | } |
27 | 35 |
|
28 | 36 | pub type Chain = Vec<(GrammarName, Range<usize>)>; |
29 | 37 |
|
30 | | -pub trait Scanner<'s> { |
| 38 | +pub trait Scanner { |
31 | 39 | /// returning `false` skip descendents |
32 | 40 | /// chain gives information about location |
33 | | - fn scan_tree<'a>(&mut self, _item: Item<'s, 'a>, _chain: &Chain) -> bool { |
| 41 | + fn scan_tree<'a>(&mut self, _file: &'a File, _item: Node<'a>, _chain: &Chain) -> bool { |
34 | 42 | false |
35 | 43 | } |
36 | 44 |
|
37 | 45 | /// chain gives information about location |
38 | | - fn scan_leaf<'a>(&mut self, item: Item<'s, 'a>, chain: &Chain); |
| 46 | + fn scan_leaf<'a>(&mut self, file: &'a File, item: Node<'a>, chain: &Chain); |
39 | 47 | } |
40 | 48 |
|
41 | | -pub fn scan<'a>(source_code: &'a str, parser: &mut Parser, scanner: &mut impl Scanner<'a>) { |
42 | | - fn flat_walk<'a, 's>( |
43 | | - source_code: &'s str, |
| 49 | +pub fn scan(file: &File, parser: &mut Parser, scanner: &mut impl Scanner) { |
| 50 | + fn flat_walk<'a>( |
| 51 | + file: &File, |
44 | 52 | node: tree_sitter::Node<'a>, |
45 | | - scanner: &mut impl Scanner<'s>, |
| 53 | + scanner: &mut impl Scanner, |
46 | 54 | chain: &mut Chain, |
47 | 55 | ) { |
48 | 56 | if node.child_count() > 0 { |
49 | | - let item = Item { |
50 | | - total_source: source_code, |
51 | | - raw_node: node, |
52 | | - }; |
53 | | - let result = scanner.scan_tree(item, chain); |
| 57 | + let result = scanner.scan_tree(file, node, chain); |
54 | 58 | if !result { |
55 | 59 | let range = node.start_byte()..node.end_byte(); |
56 | 60 | chain.push((node.grammar_name(), range)); |
57 | 61 |
|
58 | 62 | let mut walker = node.walk(); |
59 | 63 | for child in node.children(&mut walker) { |
60 | | - flat_walk(source_code, child, scanner, chain); |
| 64 | + flat_walk(file, child, scanner, chain); |
61 | 65 | } |
62 | 66 | chain.pop(); |
63 | 67 | } |
64 | 68 | } else { |
65 | | - let item = Item { |
66 | | - total_source: source_code, |
67 | | - raw_node: node, |
68 | | - }; |
69 | | - scanner.scan_leaf(item, chain); |
| 69 | + scanner.scan_leaf(file, node, chain); |
70 | 70 | } |
71 | 71 | } |
72 | 72 |
|
73 | | - let tree = parser.parse(source_code, None).unwrap(); |
| 73 | + let tree = parser.parse(&file.source, None).unwrap(); |
74 | 74 | let root = tree.root_node(); |
75 | | - flat_walk(source_code, root, scanner, &mut Vec::new()); |
| 75 | + flat_walk(file, root, scanner, &mut Vec::new()); |
76 | 76 | } |
0 commit comments