Skip to content

Commit dacf99f

Browse files
committed
refactor to less brittle tree sitter points
1 parent d0620a5 commit dacf99f

File tree

1 file changed

+34
-15
lines changed

1 file changed

+34
-15
lines changed

src/parse/tree_sitter_parser.rs

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,7 @@ pub(crate) fn parse_subtrees(
12161216
src: &str,
12171217
config: &TreeSitterConfig,
12181218
tree: &tree_sitter::Tree,
1219+
nl_pos: &LinePositions,
12191220
) -> DftHashMap<usize, (tree_sitter::Tree, TreeSitterConfig, HighlightedNodeIds)> {
12201221
let mut subtrees = DftHashMap::default();
12211222

@@ -1249,9 +1250,20 @@ pub(crate) fn parse_subtrees(
12491250
range.end_byte -= 1;
12501251

12511252
// We also need to update start_point and end_point for Tree-sitter to be happy.
1252-
// Since we know a backtick is 1 column wide and doesn't span lines:
1253-
range.start_point.column += 1;
1254-
range.end_point.column -= 1;
1253+
// Use line positions to calculate the exact row/col for the new byte offsets.
1254+
// this handles cases where the backtick is followed by a newline or
1255+
// other complex formatting.
1256+
let start_span = nl_pos.from_region(range.start_byte, range.start_byte)[0];
1257+
let end_span = nl_pos.from_region(range.end_byte, range.end_byte)[0];
1258+
1259+
range.start_point = ts::Point {
1260+
row: start_span.line.0 as usize,
1261+
column: start_span.start_col as usize,
1262+
};
1263+
range.end_point = ts::Point {
1264+
row: end_span.line.0 as usize,
1265+
column: end_span.start_col as usize,
1266+
};
12551267
}
12561268
}
12571269
_ => {}
@@ -1482,11 +1494,13 @@ pub(crate) fn to_syntax<'a>(
14821494

14831495
let highlights = tree_highlights(tree, src, config);
14841496

1497+
// Use line numbers to handle sub-language ranges correctly.
1498+
let nl_pos = LinePositions::from(src);
1499+
14851500
// Parse sub-languages, if any, which will be used both for
14861501
// highlighting and for more precise Syntax nodes where applicable.
1487-
let subtrees = parse_subtrees(src, config, tree);
1502+
let subtrees = parse_subtrees(src, config, tree, &nl_pos);
14881503

1489-
let nl_pos = LinePositions::from(src);
14901504
let mut cursor = tree.walk();
14911505

14921506
let mut error_count: usize = 0;
@@ -1941,11 +1955,10 @@ mod tests {
19411955

19421956
fn assert_contains_atoms<'a>(nodes: &[&'a Syntax<'a>], expected_sequence: Vec<Vec<&str>>) {
19431957
let mut to_search = VecDeque::from(nodes.to_vec());
1944-
let mut expected_iter = expected_sequence.into_iter();
1945-
let mut current_expected = expected_iter.next();
1958+
let mut to_check = VecDeque::from(expected_sequence);
19461959

19471960
while let Some(node) = to_search.pop_front() {
1948-
if let Some(expected) = &current_expected {
1961+
if let Some(expected) = to_check.front() {
19491962
match node {
19501963
Syntax::List { children, .. } => {
19511964
// Extract just the normal atoms from this list to see if they match the line
@@ -1959,9 +1972,10 @@ mod tests {
19591972

19601973
// If this list matches the current expected line, advance expectation
19611974
if !atom_texts.is_empty() && atom_texts == *expected {
1962-
current_expected = expected_iter.next();
1975+
to_check.pop_front();
19631976
}
19641977

1978+
// Continue searching children in order (DFS)
19651979
for child in children.iter().rev() {
19661980
to_search.push_front(child);
19671981
}
@@ -1974,14 +1988,15 @@ mod tests {
19741988
}
19751989
}
19761990

1977-
if let Some(remaining) = current_expected {
1991+
if !to_check.is_empty() {
19781992
panic!(
1979-
"Could not find all atom sequences. \nMissing: {:?}\nDebug Tree:\n{:?}",
1980-
remaining,
1993+
"Could not find all atom sequences. \nMissing: {:?}\nDebug Tree:\n{}",
1994+
to_check,
19811995
nodes
1996+
.to_vec()
19821997
.iter()
19831998
.map(|node| node.dbg_content())
1984-
.collect::<Vec<_>>()
1999+
.collect::<Vec<String>>()
19852000
.join("\n")
19862001
);
19872002
}
@@ -2052,8 +2067,12 @@ mod tests {
20522067
),
20532068
// Case 6: Multiline Edge Case
20542069
(
2055-
"\nconst X = styled.div`\ncolor: white;\n`",
2056-
vec![vec!["color", ":", "white", ";"]],
2070+
r#"
2071+
const Button = styled.button`
2072+
color: green;
2073+
`;
2074+
"#,
2075+
vec![vec!["color", ":", "green", ";"]],
20572076
),
20582077
];
20592078

0 commit comments

Comments
 (0)