Skip to content

Commit c075321

Browse files
committed
Rework library and add some tools
1 parent 191ff03 commit c075321

File tree

7 files changed

+216
-216
lines changed

7 files changed

+216
-216
lines changed

language-tool/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Tools for operating on code
2+
3+
Currently focused on Rust, but more languages supported in the future...

language-tool/src/lib.rs

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,76 @@
1-
// use libloading::{Library, Symbol, library_filename};
21
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;
59

610
pub type GrammarName = &'static str;
11+
pub type SliceRange = Range<usize>;
712

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,
1216
}
1317

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
1725
}
1826

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
2129
}
2230

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()
2533
}
2634
}
2735

2836
pub type Chain = Vec<(GrammarName, Range<usize>)>;
2937

30-
pub trait Scanner<'s> {
38+
pub trait Scanner {
3139
/// returning `false` skip descendents
3240
/// 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 {
3442
false
3543
}
3644

3745
/// 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);
3947
}
4048

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,
4452
node: tree_sitter::Node<'a>,
45-
scanner: &mut impl Scanner<'s>,
53+
scanner: &mut impl Scanner,
4654
chain: &mut Chain,
4755
) {
4856
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);
5458
if !result {
5559
let range = node.start_byte()..node.end_byte();
5660
chain.push((node.grammar_name(), range));
5761

5862
let mut walker = node.walk();
5963
for child in node.children(&mut walker) {
60-
flat_walk(source_code, child, scanner, chain);
64+
flat_walk(file, child, scanner, chain);
6165
}
6266
chain.pop();
6367
}
6468
} 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);
7070
}
7171
}
7272

73-
let tree = parser.parse(source_code, None).unwrap();
73+
let tree = parser.parse(&file.source, None).unwrap();
7474
let root = tree.root_node();
75-
flat_walk(source_code, root, scanner, &mut Vec::new());
75+
flat_walk(file, root, scanner, &mut Vec::new());
7676
}

language-tool/src/loader.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use libloading::{Library, Symbol, library_filename};
2+
use tree_sitter::{Language, Parser as TreeSitterParser};
3+
use tree_sitter_language::LanguageFn;
4+
5+
// unsafe extern "C" {
6+
// fn tree_sitter_rust() -> *const ();
7+
// }
8+
9+
pub struct Parser {
10+
#[allow(unused)]
11+
library: Library,
12+
pub parser: TreeSitterParser,
13+
}
14+
15+
pub fn get_rust_parser() -> Parser {
16+
let language = "rust";
17+
eprintln!("loading {language}");
18+
let module = std::path::Path::new("languages").join(library_filename(language));
19+
let function_name = format!("tree_sitter_{language}");
20+
let library = unsafe { Library::new(&module).unwrap() };
21+
let function = unsafe {
22+
library
23+
.get::<Symbol<extern "C" fn() -> *const ()>>(function_name.as_bytes())
24+
.unwrap()
25+
};
26+
let language_fn = unsafe { LanguageFn::from_raw(**function) };
27+
eprintln!(
28+
"loaded {function_name} from {module}",
29+
module = module.display()
30+
);
31+
32+
// let language_fn = unsafe { LanguageFn::from_raw(tree_sitter_rust) };
33+
34+
let mut parser = TreeSitterParser::new();
35+
parser
36+
.set_language(&Language::from(language_fn))
37+
.unwrap_or_else(|_| panic!("Error loading {language:?} grammar"));
38+
39+
Parser { library, parser }
40+
}

0 commit comments

Comments
 (0)