Helper functions for computing enclosing line numbers

syntactic_context
Wilfred Hughes 2023-04-30 00:23:36 +07:00
parent 1bed379115
commit a93798f91d
2 changed files with 102 additions and 1 deletions

@ -76,6 +76,7 @@ use std::{env, thread};
use humansize::{format_size, BINARY};
use owo_colors::OwoColorize;
use parse::syntax::enclosing_start_lines;
use rayon::prelude::*;
use strum::IntoEnumIterator;
use typed_arena::Arena;
@ -585,6 +586,10 @@ fn diff_file_content(
let mut lhs_positions = syntax::change_positions(&lhs, &change_map);
let mut rhs_positions = syntax::change_positions(&rhs, &change_map);
let enclosing_starts = enclosing_start_lines(&lhs);
let enclosing_ends = enclosing_start_lines(&rhs);
dbg!(enclosing_starts);
if diff_options.ignore_comments {
let lhs_comments =
tsp::comment_positions(&lhs_tree, lhs_src, &lang_config);
@ -658,7 +663,7 @@ fn diff_file_content(
let opposite_to_rhs = opposite_positions(&rhs_positions);
let hunks = matched_pos_to_hunks(&lhs_positions, &rhs_positions);
let hunks = merge_adjacent(
let _hunks = merge_adjacent(
&hunks,
&opposite_to_lhs,
&opposite_to_rhs,

@ -333,6 +333,102 @@ impl<'a> Syntax<'a> {
}
}
pub fn enclosing_start_lines<'a>(nodes: &[&'a Syntax<'a>]) -> HashMap<LineNumber, Vec<LineNumber>> {
let mut res = HashMap::new();
walk_enclosing_start_lines(nodes, &[], &mut res);
res
}
fn walk_enclosing_start_lines<'a>(
nodes: &[&'a Syntax<'a>],
parent_enclosing: &[LineNumber],
blocks_including: &mut HashMap<LineNumber, Vec<LineNumber>>,
) {
for node in nodes {
match node {
List {
open_position,
children,
..
} => {
if let Some(position) = open_position.first() {
let mut enclosing = parent_enclosing.to_vec();
if let Some(last) = enclosing.last() {
if *last != position.line {
enclosing.push(position.line);
}
} else {
enclosing.push(position.line);
}
if !blocks_including.contains_key(&position.line) {
blocks_including.insert(position.line, enclosing.clone());
}
walk_enclosing_start_lines(children, &enclosing, blocks_including)
}
}
Atom { position, .. } => {
for line_span in position {
if !blocks_including.contains_key(&line_span.line) {
blocks_including.insert(line_span.line, parent_enclosing.into());
}
}
}
}
}
}
pub fn enclosing_end_lines<'a>(nodes: &[&'a Syntax<'a>]) -> HashMap<LineNumber, Vec<LineNumber>> {
let mut res = HashMap::new();
walk_enclosing_end_lines(nodes, &[], &mut res);
res
}
fn walk_enclosing_end_lines<'a>(
nodes: &[&'a Syntax<'a>],
parent_enclosing: &[LineNumber],
blocks_including: &mut HashMap<LineNumber, Vec<LineNumber>>,
) {
for node in nodes {
match node {
List {
close_position,
children,
..
} => {
if let Some(position) = close_position.last() {
let mut enclosing = parent_enclosing.to_vec();
if let Some(last) = enclosing.last() {
if *last != position.line {
enclosing.push(position.line);
}
} else {
enclosing.push(position.line);
}
if !blocks_including.contains_key(&position.line) {
blocks_including.insert(position.line, enclosing.clone());
}
walk_enclosing_end_lines(children, &enclosing, blocks_including)
}
}
Atom { position, .. } => {
for line_span in position.iter().rev() {
if !blocks_including.contains_key(&line_span.line) {
blocks_including.insert(line_span.line, parent_enclosing.into());
}
}
}
}
}
}
pub(crate) fn comment_positions<'a>(nodes: &[&'a Syntax<'a>]) -> Vec<SingleLineSpan> {
fn walk_comment_positions(node: &Syntax<'_>, positions: &mut Vec<SingleLineSpan>) {
match node {