Fixed (hopefully) final merger bug :^)

This commit is contained in:
Noah Santschi-Cooney 2021-01-25 01:29:40 +00:00
parent 5aa7f4dc03
commit a12f61fa4e
No known key found for this signature in database
GPG key ID: 3B22282472C8AE48
2 changed files with 58 additions and 28 deletions

View file

@ -12,7 +12,6 @@ use std::collections::{HashMap, HashSet};
use std::collections::hash_map::RandomState; use std::collections::hash_map::RandomState;
use std::convert::{TryFrom, TryInto}; use std::convert::{TryFrom, TryInto};
use std::fmt::{Display, Formatter, Debug}; use std::fmt::{Display, Formatter, Debug};
use std::cmp::max;
use std::io::{stdin, stdout, BufRead, BufReader}; use std::io::{stdin, stdout, BufRead, BufReader};
use std::ops::Add; use std::ops::Add;
use std::rc::Rc; use std::rc::Rc;
@ -285,8 +284,10 @@ impl MinecraftShaderLanguageServer {
all_sources.extend( self.load_sources(&tree)?); all_sources.extend( self.load_sources(&tree)?);
let view = {
let graph = self.graph.borrow(); let graph = self.graph.borrow();
let views = merge_views::generate_merge_list(&tree, &all_sources, &graph); merge_views::generate_merge_list(&tree, &all_sources, &graph)
};
let root_path = self.graph.borrow().get_node(root).clone(); let root_path = self.graph.borrow().get_node(root).clone();
let tree_type = if root_path.ends_with(".fsh") { let tree_type = if root_path.ends_with(".fsh") {
@ -299,7 +300,7 @@ impl MinecraftShaderLanguageServer {
return Ok(diagnostics) return Ok(diagnostics)
}; };
let stdout = match opengl::validate(tree_type, views) { let stdout = match opengl::validate(tree_type, view) {
Some(s) => s, Some(s) => s,
None => { None => {
back_fill(&all_sources, &mut diagnostics); back_fill(&all_sources, &mut diagnostics);
@ -336,10 +337,12 @@ impl MinecraftShaderLanguageServer {
} }
for tree in all_trees { for tree in all_trees {
let view = {
let graph = self.graph.borrow(); let graph = self.graph.borrow();
let views = merge_views::generate_merge_list(&tree.1, &all_sources, &graph); merge_views::generate_merge_list(&tree.1, &all_sources, &graph)
};
let stdout = match opengl::validate(tree.0, views) { let stdout = match opengl::validate(tree.0, view) {
Some(s) => s, Some(s) => s,
None => continue, None => continue,
}; };
@ -366,17 +369,13 @@ impl MinecraftShaderLanguageServer {
let msg = diagnostic_capture.name("output").unwrap().as_str();//.replace("'' : ", ""); let msg = diagnostic_capture.name("output").unwrap().as_str();//.replace("'' : ", "");
if msg.starts_with("compilation terminated") { let line = match diagnostic_capture.name("linenum") {
continue;
}
let line = max(match diagnostic_capture.name("linenum") {
Some(c) => match c.as_str().parse::<u32>() { Some(c) => match c.as_str().parse::<u32>() {
Ok(i) => i, Ok(i) => i,
Err(_) => 0, Err(_) => 0,
}, },
None => 0, None => 0,
}, 2) - 2; } - 2;
// TODO: line matching maybe // TODO: line matching maybe
/* let line_text = source_lines[line as usize]; /* let line_text = source_lines[line as usize];
@ -449,7 +448,10 @@ impl MinecraftShaderLanguageServer {
continue; continue;
} }
let source = fs::read_to_string(path)?; let source = match fs::read_to_string(path) {
Ok(s) => s,
Err(e) => return Err(anyhow!("error reading {}: {}", path, e))
};
sources.insert(path.clone(), source); sources.insert(path.clone(), source);
} }

View file

@ -1,5 +1,6 @@
use std::collections::{HashMap, LinkedList, VecDeque}; use std::collections::{HashMap, LinkedList, VecDeque};
use std::iter::Peekable; use std::iter::Peekable;
use std::cmp::min;
use core::slice::Iter; use core::slice::Iter;
@ -35,11 +36,12 @@ pub fn generate_merge_list<'a>(
// now we add a view of the remainder of the root file // now we add a view of the remainder of the root file
let offset = *last_offset_set.get(&first_path).unwrap(); let offset = *last_offset_set.get(&first_path).unwrap();
merge_list.push_back(&sources.get(&first_path).unwrap()[offset..]);
let len = sources.get(&first_path).unwrap().len();
merge_list.push_back(&sources.get(&first_path).unwrap()[min(offset, len) ..]);
let total_len = merge_list.iter().fold(0, |a, b| { let total_len = merge_list.iter().fold(0, |a, b| {
let a = a + (*b).len(); a + b.len()
a
}); });
let mut merged = String::with_capacity(total_len); let mut merged = String::with_capacity(total_len);
@ -66,7 +68,6 @@ fn create_merge_views<'a>(
None => return, None => return,
}; };
let parent = n.1.unwrap(); let parent = n.1.unwrap();
let child = n.0; let child = n.0;
let edge = graph.get_edge_meta(parent, child); let edge = graph.get_edge_meta(parent, child);
@ -77,7 +78,6 @@ fn create_merge_views<'a>(
let (char_for_line, char_following_line) = char_offset_for_line(edge.line, parent_source); let (char_for_line, char_following_line) = char_offset_for_line(edge.line, parent_source);
let offset = *last_offset_set.insert(parent_path.clone(), char_following_line).get_or_insert(0); let offset = *last_offset_set.insert(parent_path.clone(), char_following_line).get_or_insert(0);
//eprintln!("offset={} char_for_line={} len={} path={}", offset, char_for_line, parent_source.len(), parent_path);
merge_list.push_back(&parent_source[offset..char_for_line]); merge_list.push_back(&parent_source[offset..char_for_line]);
add_opening_line_directive(&child_path, merge_list, line_directives); add_opening_line_directive(&child_path, merge_list, line_directives);
@ -87,7 +87,15 @@ fn create_merge_views<'a>(
// if the next pair's parent is not a child of the current pair, we dump the rest of this childs source // if the next pair's parent is not a child of the current pair, we dump the rest of this childs source
if next.1.unwrap() != child { if next.1.unwrap() != child {
let child_source = sources.get(&child_path).unwrap(); let child_source = sources.get(&child_path).unwrap();
merge_list.push_back(&child_source[..]); // if ends in \n\n, we want to exclude the last \n for some reason. Ask optilad
let offset = {
match child_source.ends_with("\n") {
true => child_source.len()-1,
false => child_source.len(),
}
};
merge_list.push_back(&child_source[..offset]);
last_offset_set.insert(child_path.clone(), 0);
// +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line // +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line
add_closing_line_directive(edge.line+2, &parent_path, merge_list, line_directives); add_closing_line_directive(edge.line+2, &parent_path, merge_list, line_directives);
// if the next pair's parent is not the current pair's parent, we need to bubble up // if the next pair's parent is not the current pair's parent, we need to bubble up
@ -101,20 +109,40 @@ fn create_merge_views<'a>(
create_merge_views(nodes, merge_list, last_offset_set, graph, sources, line_directives, stack); create_merge_views(nodes, merge_list, last_offset_set, graph, sources, line_directives, stack);
stack.pop_back(); stack.pop_back();
if next.1.unwrap() == child { let offset = *last_offset_set.get(&child_path).unwrap();
let offset = *last_offset_set.get(&child_path).unwrap(); let child_source = sources.get(&child_path).unwrap();
let child_source = sources.get(&child_path).unwrap(); // this evaluates to false once the file contents have been exhausted aka offset = child_source.len() + 1
if offset <= child_source.len() { let end_offset = {
merge_list.push_back(&child_source[offset..]); match child_source.ends_with("\n") {
true => 1/* child_source.len()-1 */,
false => 0/* child_source.len() */,
} }
};
if offset < child_source.len()-end_offset {
// if ends in \n\n, we want to exclude the last \n for some reason. Ask optilad
merge_list.push_back(&child_source[offset../* std::cmp::max( */child_source.len()-end_offset/* , offset) */]);
last_offset_set.insert(child_path.clone(), 0);
}
// +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line // +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line
add_closing_line_directive(edge.line+2, &parent_path, merge_list, line_directives); add_closing_line_directive(edge.line+2, &parent_path, merge_list, line_directives);
// we need to check the next item at the point of original return further down the callstack
if nodes.peek().is_some() && stack.contains(&nodes.peek().unwrap().1.unwrap()) {
return;
} }
}, },
None => { None => {
let child_source = sources.get(&child_path).unwrap(); let child_source = sources.get(&child_path).unwrap();
merge_list.push_back(&child_source[..]); // if ends in \n\n, we want to exclude the last \n for some reason. Ask optilad
let offset = {
match child_source.ends_with("\n") {
true => child_source.len()-1,
false => child_source.len(),
}
};
merge_list.push_back(&child_source[..offset]);
last_offset_set.insert(child_path.clone(), 0);
// +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line // +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line
add_closing_line_directive(edge.line+2, &parent_path, merge_list, line_directives); add_closing_line_directive(edge.line+2, &parent_path, merge_list, line_directives);
} }
@ -147,7 +175,7 @@ fn add_opening_line_directive(path: &str, merge_list: &mut LinkedList<&str>, lin
fn add_closing_line_directive(line: usize, path: &str, merge_list: &mut LinkedList<&str>, line_directives: &mut Vec<String>) { fn add_closing_line_directive(line: usize, path: &str, merge_list: &mut LinkedList<&str>, line_directives: &mut Vec<String>) {
// Optifine doesn't seem to add a leading newline if the previous line was a #line directive // Optifine doesn't seem to add a leading newline if the previous line was a #line directive
let line_directive = if let Some(l) = merge_list.back() { let line_directive = if let Some(l) = merge_list.back() {
if l.starts_with("\n#line") { if l.trim().starts_with("#line") {
format!("#line {} \"{}\"\n", line, path) format!("#line {} \"{}\"\n", line, path)
} else { } else {
format!("\n#line {} \"{}\"\n", line, path) format!("\n#line {} \"{}\"\n", line, path)