+124
src/bin/html.rs
+124
src/bin/html.rs
···
1
+
#![recursion_limit = "512"]
2
+
use stag::StagBuilder;
3
+
4
+
use std::iter::Iterator;
5
+
use tree_sitter::{Node, Parser, TreeCursor};
6
+
7
+
fn main() {
8
+
let scopes = std::fs::read_to_string("src/stag.tsg").unwrap();
9
+
let src = include_str!("html.rs");
10
+
11
+
let sg = StagBuilder::default()
12
+
.with_source(src)
13
+
.with_stag_file(&scopes)
14
+
.with_language(tree_sitter_rust::language())
15
+
.execute()
16
+
.unwrap();
17
+
18
+
let mut parser = Parser::new();
19
+
let _ = parser.set_language(tree_sitter_rust::language());
20
+
21
+
let tree = parser.parse(&src, None).unwrap();
22
+
let root = tree.root_node();
23
+
24
+
let preorder = PreOrder {
25
+
cursor: root.walk(),
26
+
done: false,
27
+
};
28
+
29
+
let mut document = html::root::Html::builder();
30
+
let mut code = html::inline_text::Code::builder();
31
+
32
+
let mut prev_range = 0..0;
33
+
let mut line_number = 1;
34
+
code.span(|s| {
35
+
s.text(format!("{line_number:03} "))
36
+
.id(format!("L{line_number}"))
37
+
.class("line-number")
38
+
});
39
+
line_number += 1;
40
+
41
+
for item in preorder {
42
+
let item_range = item.byte_range();
43
+
if prev_range.end < item_range.start {
44
+
let text = &src[prev_range.end..item_range.start];
45
+
for line in text.split_inclusive('\n') {
46
+
code.span(|s| s.text(format!("{line}")));
47
+
if line.contains('\n') {
48
+
code.span(|s| {
49
+
s.text(format!("{line_number:03} "))
50
+
.id(format!("L{line_number}"))
51
+
.class("line-number")
52
+
});
53
+
line_number += 1;
54
+
}
55
+
}
56
+
}
57
+
if item.child_count() == 0 {
58
+
code.span(|mut s| {
59
+
if let Some(idx) = sg.node_by_range(item_range.start, item_range.end) {
60
+
if sg.is_reference(idx) {
61
+
let definitions = sg.definitions(idx).collect::<Vec<_>>();
62
+
if let [only_def] = definitions.as_slice() {
63
+
let def_range = sg.graph[*only_def].range();
64
+
s = s.anchor(|l| {
65
+
l.href(format!("#L{}", def_range.start.line + 1))
66
+
.text(item.utf8_text(src.as_bytes()).unwrap())
67
+
});
68
+
return s;
69
+
}
70
+
}
71
+
}
72
+
s.text(item.utf8_text(src.as_bytes()).unwrap())
73
+
});
74
+
}
75
+
prev_range = item_range;
76
+
}
77
+
78
+
println!(
79
+
"{}",
80
+
document
81
+
.body(|b| {
82
+
b.title("static goto def")
83
+
.preformatted_text(|pre| pre.push(code.build()))
84
+
})
85
+
.head(|h| h.style(|s| s.text(".line-number:target { background-color: lightBlue; }")))
86
+
.build()
87
+
);
88
+
}
89
+
90
+
// root left right
91
+
struct PreOrder<'a> {
92
+
cursor: TreeCursor<'a>,
93
+
done: bool,
94
+
}
95
+
96
+
impl<'a> Iterator for PreOrder<'a> {
97
+
type Item = Node<'a>;
98
+
fn next(&mut self) -> Option<Self::Item> {
99
+
if self.done {
100
+
return None;
101
+
}
102
+
103
+
let node = self.cursor.node();
104
+
105
+
if self.cursor.goto_first_child() {
106
+
return Some(node);
107
+
} else if self.cursor.goto_next_sibling() {
108
+
return Some(node);
109
+
}
110
+
111
+
loop {
112
+
if !self.cursor.goto_parent() {
113
+
self.done = true;
114
+
break;
115
+
}
116
+
117
+
if self.cursor.goto_next_sibling() {
118
+
break;
119
+
}
120
+
}
121
+
122
+
Some(node)
123
+
}
124
+
}
+1
-1
src/debug.rs
+1
-1
src/debug.rs
+1
-1
src/lib.rs
+1
-1
src/lib.rs
-30
src/main.rs
-30
src/main.rs
···
1
-
use stag::StagBuilder;
2
-
3
-
fn main() {
4
-
let scopes = std::fs::read_to_string("src/stag.tsg").unwrap();
5
-
let src = r#"
6
-
fn main() {
7
-
let x = 2;
8
-
let a = 5;
9
-
if let _ = z {
10
-
a[x];
11
-
}
12
-
}
13
-
"#;
14
-
15
-
let sg = StagBuilder::default()
16
-
.with_source(src)
17
-
.with_stag_file(&scopes)
18
-
.with_language(tree_sitter_rust::language())
19
-
.execute()
20
-
.unwrap();
21
-
22
-
for edge in sg.graph.raw_edges() {
23
-
let s = edge.source();
24
-
let t = edge.target();
25
-
let sn = &sg.graph[s];
26
-
let st = &sg.graph[t];
27
-
println!("{:?} -> {:?}", edge.source(), edge.target());
28
-
println!("{:#?} -> {:#?}", sn, st);
29
-
}
30
-
}