Skip to content

Commit 191ff03

Browse files
committed
Find Rust items and print location with codespan-reporting
1 parent e985a22 commit 191ff03

File tree

4 files changed

+389
-92
lines changed

4 files changed

+389
-92
lines changed

language-tool/Cargo.lock

Lines changed: 118 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

language-tool/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ edition = "2024"
55
publish = false
66

77
[dependencies]
8+
codespan-reporting = "0.12.0"
89
libloading = "0.8.6"
910
tree-sitter = "=0.25.6"
1011
tree-sitter-language = "=0.1.5"

language-tool/src/lib.rs

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

0 commit comments

Comments
 (0)