Skip to content

Commit b4a0636

Browse files
committed
replace (NodeIndex, Option<NodeIndex>) with FilialTuple globally
1 parent 9a499d5 commit b4a0636

File tree

4 files changed

+58
-67
lines changed

4 files changed

+58
-67
lines changed

server/src/commands/merged_includes.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use anyhow::{format_err, Result};
1414
use std::fs;
1515

1616
use crate::dfs;
17+
use crate::merge_views::FilialTuple;
1718
use crate::{graph::CachedStableGraph, merge_views, url_norm::FromJson};
1819

1920
use super::Invokeable;
@@ -36,15 +37,15 @@ impl VirtualMergedDocument {
3637
Ok(Some(roots))
3738
}
3839

39-
pub fn get_dfs_for_node(&self, root: NodeIndex) -> Result<Vec<(NodeIndex, Option<NodeIndex>)>, dfs::error::CycleError> {
40+
pub fn get_dfs_for_node(&self, root: NodeIndex) -> Result<Vec<FilialTuple>, dfs::error::CycleError> {
4041
let graph_ref = self.graph.borrow();
4142

4243
let dfs = dfs::Dfs::new(&graph_ref, root);
4344

4445
dfs.collect::<Result<Vec<_>, _>>()
4546
}
4647

47-
pub fn load_sources(&self, nodes: &[(NodeIndex, Option<NodeIndex>)]) -> Result<HashMap<PathBuf, String>> {
48+
pub fn load_sources(&self, nodes: &[FilialTuple]) -> Result<HashMap<PathBuf, String>> {
4849
let mut sources = HashMap::new();
4950

5051
for node in nodes {

server/src/dfs.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use petgraph::stable_graph::NodeIndex;
22

3-
use crate::graph::CachedStableGraph;
3+
use crate::{graph::CachedStableGraph, merge_views::FilialTuple};
44

55
use anyhow::Result;
66

@@ -51,9 +51,9 @@ impl<'a> Dfs<'a> {
5151
}
5252

5353
impl<'a> Iterator for Dfs<'a> {
54-
type Item = Result<(NodeIndex, Option<NodeIndex>), error::CycleError>;
54+
type Item = Result<FilialTuple, error::CycleError>;
5555

56-
fn next(&mut self) -> Option<Result<(NodeIndex, Option<NodeIndex>), error::CycleError>> {
56+
fn next(&mut self) -> Option<Result<FilialTuple, error::CycleError>> {
5757
let parent = self.cycle.last().map(|p| p.node);
5858

5959
if let Some(node) = self.stack.pop() {

server/src/main.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use merge_views::FilialTuple;
12
use rust_lsp::jsonrpc::{method_types::*, *};
23
use rust_lsp::lsp::*;
34
use rust_lsp::lsp_types::{notification::*, *};
@@ -47,8 +48,8 @@ mod graph;
4748
mod logging;
4849
mod lsp_ext;
4950
mod merge_views;
50-
mod opengl;
5151
mod navigation;
52+
mod opengl;
5253
mod url_norm;
5354

5455
#[cfg(test)]
@@ -419,15 +420,15 @@ impl MinecraftShaderLanguageServer {
419420
Ok(diagnostics)
420421
}
421422

422-
pub fn get_dfs_for_node(&self, root: NodeIndex) -> Result<Vec<(NodeIndex, Option<NodeIndex>)>, dfs::error::CycleError> {
423+
pub fn get_dfs_for_node(&self, root: NodeIndex) -> Result<Vec<FilialTuple>, dfs::error::CycleError> {
423424
let graph_ref = self.graph.borrow();
424425

425426
let dfs = dfs::Dfs::new(&graph_ref, root);
426427

427428
dfs.collect::<Result<_, _>>()
428429
}
429430

430-
pub fn load_sources(&self, nodes: &[(NodeIndex, Option<NodeIndex>)]) -> Result<HashMap<PathBuf, String>> {
431+
pub fn load_sources(&self, nodes: &[FilialTuple]) -> Result<HashMap<PathBuf, String>> {
431432
let mut sources = HashMap::new();
432433

433434
for node in nodes {
@@ -675,13 +676,15 @@ impl LanguageServerHandling for MinecraftShaderLanguageServer {
675676
let parser = &mut self.tree_sitter.borrow_mut();
676677
let parser_ctx = match navigation::ParserContext::new(parser, params.text_document.uri.clone()) {
677678
Ok(ctx) => ctx,
678-
Err(e) => return completable.complete(Err(MethodError{
679-
code: 42069,
680-
message: format!("error building parser context: {}", e),
681-
data: (),
682-
})),
679+
Err(e) => {
680+
return completable.complete(Err(MethodError {
681+
code: 42069,
682+
message: format!("error building parser context: {}", e),
683+
data: (),
684+
}))
685+
}
683686
};
684-
687+
685688
match parser_ctx.find_definitions(params.text_document.uri, params.position) {
686689
Ok(locations) => completable.complete(Ok(locations)),
687690
Err(e) => completable.complete(Err(MethodError {

server/src/merge_views.rs

Lines changed: 40 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,22 @@ use petgraph::stable_graph::NodeIndex;
1111

1212
use crate::graph::CachedStableGraph;
1313

14-
/// FilialTuple represents a tuple with a parent at index 0
15-
/// and a child at index 1. Parent can be nullable in the case of
14+
/// FilialTuple represents a tuple with a child at index 0
15+
/// and a parent at index 1. Parent can be nullable in the case of
1616
/// the child being a top level node in the tree.
17-
#[derive(PartialEq, Eq, Hash)]
18-
struct FilialTuple(Option<NodeIndex>, NodeIndex);
17+
pub type FilialTuple = (NodeIndex, Option<NodeIndex>);
1918

20-
impl From<(Option<&NodeIndex>, NodeIndex)> for FilialTuple {
21-
fn from(tuple: (Option<&NodeIndex>, NodeIndex)) -> Self {
22-
FilialTuple(tuple.0.copied(), tuple.1)
23-
}
24-
}
25-
26-
pub fn generate_merge_list<'a>(
27-
nodes: &'a [(NodeIndex, Option<NodeIndex>)], sources: &'a HashMap<PathBuf, String>, graph: &'a CachedStableGraph,
28-
) -> String {
29-
let mut line_directives: Vec<String> = Vec::new();
19+
pub fn generate_merge_list<'a>(nodes: &'a [FilialTuple], sources: &'a HashMap<PathBuf, String>, graph: &'a CachedStableGraph) -> String {
20+
// contains additionally inserted lines such as #line and other directives, preamble defines etc
21+
let mut extra_lines: Vec<String> = Vec::new();
22+
extra_lines.reserve((nodes.len() * 2) + 2);
3023

3124
// list of source code views onto the below sources
3225
let mut merge_list: LinkedList<&'a str> = LinkedList::new();
3326

34-
line_directives.reserve(nodes.len() * 2);
35-
27+
// holds the offset into the child which has been added to the merge list for a parent.
28+
// A child can have multiple parents for a given tree, hence we have to track it for
29+
// a (child, parent) tuple instead of just the child.
3630
let mut last_offset_set: HashMap<FilialTuple, usize> = HashMap::new();
3731

3832
let mut nodes_iter = nodes.iter().peekable();
@@ -41,7 +35,7 @@ pub fn generate_merge_list<'a>(
4135
let first = nodes_iter.next().unwrap().0;
4236
let first_path = graph.get_node(first);
4337

44-
last_offset_set.insert(FilialTuple(None, first), 0);
38+
last_offset_set.insert((first, None), 0);
4539

4640
// stack to keep track of the depth first traversal
4741
let mut stack = VecDeque::<NodeIndex>::new();
@@ -52,30 +46,27 @@ pub fn generate_merge_list<'a>(
5246
&mut last_offset_set,
5347
graph,
5448
sources,
55-
&mut line_directives,
49+
&mut extra_lines,
5650
&mut stack,
5751
);
5852

5953
// now we add a view of the remainder of the root file
60-
let offset = *last_offset_set.get(&FilialTuple(None, first)).unwrap();
54+
let offset = *last_offset_set.get(&(first, None)).unwrap();
6155

6256
let len = sources.get(&first_path).unwrap().len();
6357
merge_list.push_back(&sources.get(&first_path).unwrap()[min(offset, len)..]);
6458

6559
let total_len = merge_list.iter().fold(0, |a, b| a + b.len());
6660

6761
let mut merged = String::with_capacity(total_len);
68-
for slice in merge_list {
69-
merged.push_str(slice);
70-
}
62+
merged.extend(merge_list);
7163

7264
merged
7365
}
7466

7567
fn create_merge_views<'a>(
76-
nodes: &mut Peekable<Iter<(NodeIndex, Option<NodeIndex>)>>, merge_list: &mut LinkedList<&'a str>,
77-
last_offset_set: &mut HashMap<FilialTuple, usize>, graph: &'a CachedStableGraph, sources: &'a HashMap<PathBuf, String>,
78-
line_directives: &mut Vec<String>, stack: &mut VecDeque<NodeIndex>,
68+
nodes: &mut Peekable<Iter<FilialTuple>>, merge_list: &mut LinkedList<&'a str>, last_offset_set: &mut HashMap<FilialTuple, usize>,
69+
graph: &'a CachedStableGraph, sources: &'a HashMap<PathBuf, String>, extra_lines: &mut Vec<String>, stack: &mut VecDeque<NodeIndex>,
7970
) {
8071
loop {
8172
let n = match nodes.next() {
@@ -94,10 +85,10 @@ fn create_merge_views<'a>(
9485
let (char_for_line, char_following_line) = char_offset_for_line(edge.line, parent_source);
9586

9687
let offset = *last_offset_set
97-
.insert((stack.back(), parent).into(), char_following_line)
88+
.insert((parent, stack.back().copied()), char_following_line)
9889
.get_or_insert(0);
9990
merge_list.push_back(&parent_source[offset..char_for_line]);
100-
add_opening_line_directive(&child_path, merge_list, line_directives);
91+
add_opening_line_directive(&child_path, merge_list, extra_lines);
10192

10293
match nodes.peek() {
10394
Some(next) => {
@@ -113,9 +104,9 @@ fn create_merge_views<'a>(
113104
}
114105
};
115106
merge_list.push_back(&child_source[..offset]);
116-
last_offset_set.insert(FilialTuple(Some(parent), child), 0);
107+
last_offset_set.insert((child, Some(parent)), 0);
117108
// +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line
118-
add_closing_line_directive(edge.line + 2, &parent_path, merge_list, line_directives);
109+
add_closing_line_directive(edge.line + 2, &parent_path, merge_list, extra_lines);
119110
// if the next pair's parent is not the current pair's parent, we need to bubble up
120111
if stack.contains(&next.1.unwrap()) {
121112
return;
@@ -124,26 +115,24 @@ fn create_merge_views<'a>(
124115
}
125116

126117
stack.push_back(parent);
127-
create_merge_views(nodes, merge_list, last_offset_set, graph, sources, line_directives, stack);
118+
create_merge_views(nodes, merge_list, last_offset_set, graph, sources, extra_lines, stack);
128119
stack.pop_back();
129120

130-
let offset = *last_offset_set.get(&FilialTuple(Some(parent), child)).unwrap();
121+
let offset = *last_offset_set.get(&(child, Some(parent))).unwrap();
131122
let child_source = sources.get(&child_path).unwrap();
132123
// this evaluates to false once the file contents have been exhausted aka offset = child_source.len() + 1
133-
let end_offset = {
134-
match child_source.ends_with('\n') {
135-
true => 1, /* child_source.len()-1 */
136-
false => 0, /* child_source.len() */
137-
}
124+
let end_offset = match child_source.ends_with('\n') {
125+
true => 1, /* child_source.len()-1 */
126+
false => 0, /* child_source.len() */
138127
};
139128
if offset < child_source.len() - end_offset {
140129
// if ends in \n\n, we want to exclude the last \n for some reason. Ask optilad
141130
merge_list.push_back(&child_source[offset../* std::cmp::max( */child_source.len()-end_offset/* , offset) */]);
142-
last_offset_set.insert(FilialTuple(Some(parent), child), 0);
131+
last_offset_set.insert((child, Some(parent)), 0);
143132
}
144133

145134
// +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line
146-
add_closing_line_directive(edge.line + 2, &parent_path, merge_list, line_directives);
135+
add_closing_line_directive(edge.line + 2, &parent_path, merge_list, extra_lines);
147136

148137
// we need to check the next item at the point of original return further down the callstack
149138
if nodes.peek().is_some() && stack.contains(&nodes.peek().unwrap().1.unwrap()) {
@@ -153,16 +142,14 @@ fn create_merge_views<'a>(
153142
None => {
154143
let child_source = sources.get(&child_path).unwrap();
155144
// if ends in \n\n, we want to exclude the last \n for some reason. Ask optilad
156-
let offset = {
157-
match child_source.ends_with('\n') {
158-
true => child_source.len() - 1,
159-
false => child_source.len(),
160-
}
145+
let offset = match child_source.ends_with('\n') {
146+
true => child_source.len() - 1,
147+
false => child_source.len(),
161148
};
162149
merge_list.push_back(&child_source[..offset]);
163-
last_offset_set.insert(FilialTuple(Some(parent), child), 0);
150+
last_offset_set.insert((child, Some(parent)), 0);
164151
// +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line
165-
add_closing_line_directive(edge.line + 2, &parent_path, merge_list, line_directives);
152+
add_closing_line_directive(edge.line + 2, &parent_path, merge_list, extra_lines);
166153
}
167154
}
168155
}
@@ -184,13 +171,13 @@ fn char_offset_for_line(line_num: usize, source: &str) -> (usize, usize) {
184171
(char_for_line, char_following_line)
185172
}
186173

187-
fn add_opening_line_directive(path: &Path, merge_list: &mut LinkedList<&str>, line_directives: &mut Vec<String>) {
174+
fn add_opening_line_directive(path: &Path, merge_list: &mut LinkedList<&str>, extra_lines: &mut Vec<String>) {
188175
let line_directive = format!("#line 1 \"{}\"\n", path.to_str().unwrap().replace('\\', "\\\\"));
189-
line_directives.push(line_directive);
190-
unsafe_get_and_insert(merge_list, line_directives);
176+
extra_lines.push(line_directive);
177+
unsafe_get_and_insert(merge_list, extra_lines);
191178
}
192179

193-
fn add_closing_line_directive(line: usize, path: &Path, merge_list: &mut LinkedList<&str>, line_directives: &mut Vec<String>) {
180+
fn add_closing_line_directive(line: usize, path: &Path, merge_list: &mut LinkedList<&str>, extra_lines: &mut Vec<String>) {
194181
// Optifine doesn't seem to add a leading newline if the previous line was a #line directive
195182
let line_directive = if let Some(l) = merge_list.back() {
196183
if l.trim().starts_with("#line") {
@@ -202,14 +189,14 @@ fn add_closing_line_directive(line: usize, path: &Path, merge_list: &mut LinkedL
202189
format!("\n#line {} \"{}\"\n", line, path.to_str().unwrap().replace('\\', "\\\\"))
203190
};
204191

205-
line_directives.push(line_directive);
206-
unsafe_get_and_insert(merge_list, line_directives);
192+
extra_lines.push(line_directive);
193+
unsafe_get_and_insert(merge_list, extra_lines);
207194
}
208195

209-
fn unsafe_get_and_insert(merge_list: &mut LinkedList<&str>, line_directives: &[String]) {
196+
fn unsafe_get_and_insert(merge_list: &mut LinkedList<&str>, extra_lines: &[String]) {
210197
// :^)
211198
unsafe {
212-
let vec_ptr_offset = line_directives.as_ptr().add(line_directives.len() - 1);
199+
let vec_ptr_offset = extra_lines.as_ptr().add(extra_lines.len() - 1);
213200
merge_list.push_back(&vec_ptr_offset.as_ref().unwrap()[..]);
214201
}
215202
}

0 commit comments

Comments
 (0)