Skip to content
This repository was archived by the owner on Sep 9, 2025. It is now read-only.

Commit 7621ac2

Browse files
committed
feat: add root path and pass file path explicitely
1 parent 558d1da commit 7621ac2

File tree

10 files changed

+140
-21
lines changed

10 files changed

+140
-21
lines changed

languages/tree-sitter-stack-graphs-python/src/stack-graphs.tsg

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
;; ^^^^^^^^^^^^^^^^
1414

1515
global FILE_PATH
16+
global ROOT_PATH
1617
global ROOT_NODE
1718
global JUMP_TO_SCOPE_NODE
1819

@@ -272,7 +273,9 @@ inherit .parent_module
272273
node grandparent_module_ref_node
273274
var grandparent_module_ref = grandparent_module_ref_node
274275

275-
scan FILE_PATH {
276+
; get the file path relative to the root path
277+
let rel_path = (replace FILE_PATH ROOT_PATH "")
278+
scan rel_path {
276279
"([^/]+)/"
277280
{
278281
node def_dot
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# ------ path: foo/bar/module.py -----------#
2+
# ------ global: ROOT_PATH=foo/bar -----------#
3+
4+
foo = 42
5+
6+
# ------ path: foo/bar/baz/module.py -----------#
7+
# ------ global: ROOT_PATH=foo/bar -----------#
8+
9+
bar = "hello"
10+
11+
# ------ path: foo/bar/main.py -------------#
12+
# ------ global: ROOT_PATH=foo/bar -----------#
13+
14+
from module import foo
15+
from baz.module import bar
16+
17+
print(foo)
18+
# ^ defined: 4, 14
19+
20+
print(bar)
21+
# ^ defined: 9, 15

tree-sitter-stack-graphs/src/cli/index.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,10 +428,19 @@ impl<'a> Indexer<'a> {
428428
cancellation_flag: &dyn CancellationFlag,
429429
) -> std::result::Result<(), BuildErrorWithSource<'b>> {
430430
let relative_source_path = source_path.strip_prefix(source_root).unwrap();
431+
// here the file should also have stripped the source_root from its path
431432
if let Some(lc) = lcs.primary {
432433
let globals = Variables::new();
433434
lc.sgl
434-
.build_stack_graph_into(graph, file, source, &globals, cancellation_flag)
435+
.build_stack_graph_into(
436+
graph,
437+
file,
438+
source,
439+
source_path,
440+
source_root,
441+
&globals,
442+
cancellation_flag,
443+
)
435444
.map_err(|inner| BuildErrorWithSource {
436445
inner,
437446
source_path: source_path.to_path_buf(),

tree-sitter-stack-graphs/src/cli/test.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,8 @@ impl TestArgs {
321321
&mut test.graph,
322322
test_fragment.file,
323323
&test_fragment.source,
324+
&test_fragment.path,
325+
&test_fragment.root_path,
324326
&globals,
325327
cancellation_flag.as_ref(),
326328
)

tree-sitter-stack-graphs/src/lib.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ static PRECEDENCE_ATTR: &'static str = "precedence";
438438
static ROOT_NODE_VAR: &'static str = "ROOT_NODE";
439439
static JUMP_TO_SCOPE_NODE_VAR: &'static str = "JUMP_TO_SCOPE_NODE";
440440
static FILE_PATH_VAR: &'static str = "FILE_PATH";
441+
static ROOT_PATH_VAR: &'static str = "ROOT_PATH";
441442

442443
/// Holds information about how to construct stack graphs for a particular language.
443444
pub struct StackGraphLanguage {
@@ -557,10 +558,12 @@ impl StackGraphLanguage {
557558
stack_graph: &'a mut StackGraph,
558559
file: Handle<File>,
559560
source: &'a str,
561+
source_path: &Path,
562+
source_root: &Path,
560563
globals: &'a Variables<'a>,
561564
cancellation_flag: &'a dyn CancellationFlag,
562565
) -> Result<(), BuildError> {
563-
self.builder_into_stack_graph(stack_graph, file, source)
566+
self.builder_into_stack_graph(stack_graph, file, source, source_path, source_root)
564567
.build(globals, cancellation_flag)
565568
}
566569

@@ -573,8 +576,10 @@ impl StackGraphLanguage {
573576
stack_graph: &'a mut StackGraph,
574577
file: Handle<File>,
575578
source: &'a str,
579+
source_path: &'a Path,
580+
source_root: &'a Path,
576581
) -> Builder<'a> {
577-
Builder::new(self, stack_graph, file, source)
582+
Builder::new(self, stack_graph, file, source, source_path, source_root)
578583
}
579584
}
580585

@@ -583,6 +588,8 @@ pub struct Builder<'a> {
583588
stack_graph: &'a mut StackGraph,
584589
file: Handle<File>,
585590
source: &'a str,
591+
source_path: &'a Path,
592+
source_root: &'a Path,
586593
graph: Graph<'a>,
587594
remapped_nodes: HashMap<usize, NodeID>,
588595
injected_node_count: usize,
@@ -595,13 +602,17 @@ impl<'a> Builder<'a> {
595602
stack_graph: &'a mut StackGraph,
596603
file: Handle<File>,
597604
source: &'a str,
605+
source_path: &'a Path,
606+
source_root: &'a Path,
598607
) -> Self {
599608
let span_calculator = SpanCalculator::new(source);
600609
Builder {
601610
sgl,
602611
stack_graph,
603612
file,
604613
source,
614+
source_path,
615+
source_root,
605616
graph: Graph::new(),
606617
remapped_nodes: HashMap::new(),
607618
injected_node_count: 0,
@@ -635,23 +646,33 @@ impl<'a> Builder<'a> {
635646
let tree = parse_errors.into_tree();
636647

637648
let mut globals = Variables::nested(globals);
649+
638650
if globals.get(&ROOT_NODE_VAR.into()).is_none() {
639651
let root_node = self.inject_node(NodeID::root());
640652
globals
641653
.add(ROOT_NODE_VAR.into(), root_node.into())
642654
.expect("Failed to set ROOT_NODE");
643655
}
656+
644657
let jump_to_scope_node = self.inject_node(NodeID::jump_to());
645658
globals
646659
.add(JUMP_TO_SCOPE_NODE_VAR.into(), jump_to_scope_node.into())
647660
.expect("Failed to set JUMP_TO_SCOPE_NODE");
661+
648662
if globals.get(&FILE_PATH_VAR.into()).is_none() {
649-
let file_name = self.stack_graph[self.file].to_string();
663+
let file_name = self.source_path.to_str().unwrap().to_string();
650664
globals
651665
.add(FILE_PATH_VAR.into(), file_name.into())
652666
.expect("Failed to set FILE_PATH");
653667
}
654668

669+
if globals.get(&ROOT_PATH_VAR.into()).is_none() {
670+
let root_path = self.source_root.to_str().unwrap().to_string();
671+
globals
672+
.add(ROOT_PATH_VAR.into(), root_path.into())
673+
.expect("Failed to set ROOT_PATH");
674+
}
675+
655676
let mut config = ExecutionConfig::new(&self.sgl.functions, &globals)
656677
.lazy(true)
657678
.debug_attributes(

tree-sitter-stack-graphs/src/loader.rs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,14 @@ impl LanguageConfiguration {
7979
Loader::load_globals_from_config_str(builtins_config, &mut builtins_globals)?;
8080
}
8181
let file = builtins.add_file("<builtins>").unwrap();
82+
let builtins_path_var = Path::new("<builtins>");
83+
let builtins_root = Path::new("");
8284
sgl.build_stack_graph_into(
8385
&mut builtins,
8486
file,
8587
builtins_source,
88+
builtins_path_var,
89+
builtins_root,
8690
&builtins_globals,
8791
cancellation_flag,
8892
)
@@ -325,17 +329,28 @@ impl Loader {
325329
graph: &mut StackGraph,
326330
cancellation_flag: &dyn CancellationFlag,
327331
) -> Result<(), LoadError<'a>> {
328-
let file = graph.add_file(&path.to_string_lossy()).unwrap();
332+
let file_name = path.to_string_lossy();
333+
let file: stack_graphs::arena::Handle<stack_graphs::graph::File> =
334+
graph.add_file(&file_name).unwrap();
335+
let builtins_root = Path::new("");
329336
let mut globals = Variables::new();
330337
Self::load_globals_from_config_str(&config, &mut globals)?;
331-
sgl.build_stack_graph_into(graph, file, &source, &globals, cancellation_flag)
332-
.map_err(|err| LoadError::Builtins {
333-
inner: err,
334-
source_path: path.to_path_buf(),
335-
source,
336-
tsg_path: sgl.tsg_path.to_path_buf(),
337-
tsg: sgl.tsg_source.clone(),
338-
})?;
338+
sgl.build_stack_graph_into(
339+
graph,
340+
file,
341+
&source,
342+
path,
343+
builtins_root,
344+
&globals,
345+
cancellation_flag,
346+
)
347+
.map_err(|err| LoadError::Builtins {
348+
inner: err,
349+
source_path: path.to_path_buf(),
350+
source,
351+
tsg_path: sgl.tsg_path.to_path_buf(),
352+
tsg: sgl.tsg_source.clone(),
353+
})?;
339354
return Ok(());
340355
}
341356

tree-sitter-stack-graphs/src/test.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ pub struct Test {
157157
pub struct TestFragment {
158158
pub file: Handle<File>,
159159
pub path: PathBuf,
160+
pub root_path: PathBuf,
160161
pub source: String,
161162
pub assertions: Vec<Assertion>,
162163
pub globals: HashMap<String, String>,
@@ -180,6 +181,7 @@ impl Test {
180181
let mut prev_source = String::new();
181182
let mut line_files = Vec::new();
182183
let mut line_count = 0;
184+
let default_root_path = PathBuf::from("");
183185
for (current_line_number, current_line) in
184186
PositionedSubstring::lines_iter(source).enumerate()
185187
{
@@ -202,6 +204,7 @@ impl Test {
202204
fragments.push(TestFragment {
203205
file,
204206
path: current_path,
207+
root_path: default_root_path.clone(),
205208
source: current_source,
206209
assertions: Vec::new(),
207210
globals: current_globals,
@@ -254,6 +257,7 @@ impl Test {
254257
fragments.push(TestFragment {
255258
file,
256259
path: current_path,
260+
root_path: default_root_path.clone(),
257261
source: current_source,
258262
assertions: Vec::new(),
259263
globals: current_globals,

tree-sitter-stack-graphs/tests/it/builder.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
// Please see the LICENSE-APACHE or LICENSE-MIT files in this distribution for license details.
66
// ------------------------------------------------------------------------------------------------
77

8+
use std::path::Path;
9+
810
use stack_graphs::graph::StackGraph;
911
use tree_sitter_graph::Variables;
1012
use tree_sitter_stack_graphs::NoCancellation;
@@ -22,15 +24,27 @@ fn can_support_preexisting_nodes() {
2224
"#;
2325
let python = "pass";
2426

27+
let file_name = "test.py";
28+
let source_path = Path::new(file_name);
29+
let source_root = Path::new("");
30+
2531
let mut graph = StackGraph::new();
26-
let file = graph.get_or_create_file("test.py");
32+
let file = graph.get_or_create_file(file_name);
2733
let node_id = graph.new_node_id(file);
2834
let _preexisting_node = graph.add_scope_node(node_id, true).unwrap();
2935

3036
let globals = Variables::new();
3137
let language = StackGraphLanguage::from_str(tree_sitter_python::language(), tsg).unwrap();
3238
language
33-
.build_stack_graph_into(&mut graph, file, python, &globals, &NoCancellation)
39+
.build_stack_graph_into(
40+
&mut graph,
41+
file,
42+
python,
43+
source_path,
44+
source_root,
45+
&globals,
46+
&NoCancellation,
47+
)
3448
.expect("Failed to build graph");
3549
}
3650

@@ -45,13 +59,18 @@ fn can_support_injected_nodes() {
4559
"#;
4660
let python = "pass";
4761

62+
let file_name = "test.py";
63+
let source_path = Path::new(file_name);
64+
let source_root = Path::new("");
65+
4866
let mut graph = StackGraph::new();
49-
let file = graph.get_or_create_file("test.py");
67+
let file = graph.get_or_create_file(file_name);
5068
let node_id = graph.new_node_id(file);
5169
let _preexisting_node = graph.add_scope_node(node_id, true).unwrap();
5270

5371
let language = StackGraphLanguage::from_str(tree_sitter_python::language(), tsg).unwrap();
54-
let mut builder = language.builder_into_stack_graph(&mut graph, file, python);
72+
let mut builder =
73+
language.builder_into_stack_graph(&mut graph, file, python, source_path, source_root);
5574

5675
let mut globals = Variables::new();
5776
globals

tree-sitter-stack-graphs/tests/it/main.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
// Please see the LICENSE-APACHE or LICENSE-MIT files in this distribution for license details.
66
// ------------------------------------------------------------------------------------------------
77

8+
use std::path::Path;
9+
810
use stack_graphs::arena::Handle;
911
use stack_graphs::graph::File;
1012
use stack_graphs::graph::StackGraph;
@@ -23,11 +25,22 @@ pub(self) fn build_stack_graph(
2325
python_source: &str,
2426
tsg_source: &str,
2527
) -> Result<(StackGraph, Handle<File>), BuildError> {
28+
let file_name = "test.py";
29+
let source_path = Path::new(file_name);
30+
let source_root = Path::new("");
2631
let language =
2732
StackGraphLanguage::from_str(tree_sitter_python::language(), tsg_source).unwrap();
2833
let mut graph = StackGraph::new();
29-
let file = graph.get_or_create_file("test.py");
34+
let file = graph.get_or_create_file(file_name);
3035
let globals = Variables::new();
31-
language.build_stack_graph_into(&mut graph, file, python_source, &globals, &NoCancellation)?;
36+
language.build_stack_graph_into(
37+
&mut graph,
38+
file,
39+
python_source,
40+
source_path,
41+
source_root,
42+
&globals,
43+
&NoCancellation,
44+
)?;
3245
Ok((graph, file))
3346
}

tree-sitter-stack-graphs/tests/it/test.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,22 @@ fn build_stack_graph_into(
6868
graph: &mut StackGraph,
6969
file: Handle<File>,
7070
python_source: &str,
71+
source_path: &Path,
72+
source_root: &Path,
7173
tsg_source: &str,
7274
globals: &Variables,
7375
) -> Result<(), BuildError> {
7476
let language =
7577
StackGraphLanguage::from_str(tree_sitter_python::language(), tsg_source).unwrap();
76-
language.build_stack_graph_into(graph, file, python_source, globals, &NoCancellation)?;
78+
language.build_stack_graph_into(
79+
graph,
80+
file,
81+
python_source,
82+
source_path,
83+
source_root,
84+
globals,
85+
&NoCancellation,
86+
)?;
7787
Ok(())
7888
}
7989

@@ -102,6 +112,8 @@ fn check_test(
102112
&mut test.graph,
103113
fragments.file,
104114
&fragments.source,
115+
&fragments.path,
116+
&fragments.root_path,
105117
tsg_source,
106118
&globals,
107119
)

0 commit comments

Comments
 (0)