1use std::{
4 cmp::Ordering,
5 collections::VecDeque,
6 ops::{Range, RangeInclusive},
7};
8
9use rowan::TextRange;
10use rustc_hash::FxHashMap;
11use stdx::format_to;
12
13use crate::{
14 SyntaxElement, SyntaxNode, SyntaxNodePtr,
15 syntax_editor::{Change, ChangeKind, PositionRepr, mapping::MissingMapping},
16};
17
18use super::{SyntaxEdit, SyntaxEditor};
19
20pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit {
21 let SyntaxEditor { root, mut changes, mappings, annotations } = editor;
39
40 let mut node_depths = FxHashMap::<SyntaxNode, usize>::default();
41 let mut get_node_depth = |node: SyntaxNode| {
42 *node_depths.entry(node).or_insert_with_key(|node| node.ancestors().count())
43 };
44
45 changes.sort_by(|a, b| {
50 a.target_range()
51 .start()
52 .cmp(&b.target_range().start())
53 .then_with(|| {
54 let a_target = a.target_parent();
55 let b_target = b.target_parent();
56
57 if a_target == b_target {
58 return Ordering::Equal;
59 }
60
61 get_node_depth(a_target).cmp(&get_node_depth(b_target))
62 })
63 .then(a.change_kind().cmp(&b.change_kind()))
64 });
65
66 let disjoint_replaces_ranges = changes
67 .iter()
68 .zip(changes.iter().skip(1))
69 .filter(|(l, r)| {
70 matches!(
72 (l.change_kind(), r.change_kind()),
73 (
74 ChangeKind::Replace | ChangeKind::ReplaceRange,
75 ChangeKind::Replace | ChangeKind::ReplaceRange
76 )
77 )
78 })
79 .all(|(l, r)| {
80 get_node_depth(l.target_parent()) != get_node_depth(r.target_parent())
81 || (l.target_range().end() <= r.target_range().start())
82 });
83
84 if !disjoint_replaces_ranges {
85 report_intersecting_changes(&changes, get_node_depth, &root);
86
87 return SyntaxEdit {
88 old_root: root.clone(),
89 new_root: root,
90 annotations: Default::default(),
91 changed_elements: vec![],
92 };
93 }
94
95 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
96 struct DependentChange {
97 parent: u32,
98 child: u32,
99 }
100
101 let mut changed_ancestors: VecDeque<ChangedAncestor> = VecDeque::new();
103 let mut dependent_changes = vec![];
104 let mut independent_changes = vec![];
105 let mut outdated_changes = vec![];
106
107 for (change_index, change) in changes.iter().enumerate() {
108 if let Some(index) = changed_ancestors
110 .iter()
111 .rev()
112 .position(|ancestor| ancestor.affected_range().contains_range(change.target_range()))
113 {
114 changed_ancestors.drain((index + 1)..);
116
117 let ancestor = &changed_ancestors[index];
119
120 if let Change::Replace(_, None) = changes[ancestor.change_index] {
121 outdated_changes.push(change_index as u32);
122 } else {
123 dependent_changes.push(DependentChange {
124 parent: ancestor.change_index as u32,
125 child: change_index as u32,
126 });
127 }
128 } else {
129 changed_ancestors.drain(..);
133
134 independent_changes.push(change_index as u32);
135 }
136
137 match change {
139 Change::Replace(SyntaxElement::Node(target), _)
140 | Change::ReplaceWithMany(SyntaxElement::Node(target), _) => {
141 changed_ancestors.push_back(ChangedAncestor::single(target, change_index))
142 }
143 Change::ReplaceAll(range, _) => {
144 changed_ancestors.push_back(ChangedAncestor::multiple(range, change_index))
145 }
146 _ => (),
147 }
148 }
149
150 let tree_mutator = TreeMutator::new(&root);
152 let mut changed_elements = vec![];
153 let mut changed_elements_set = rustc_hash::FxHashSet::default();
154 let mut deduplicate_node = |node_or_token: &mut SyntaxElement| {
155 let node;
156 let node = match node_or_token {
157 SyntaxElement::Token(token) => match token.parent() {
158 None => return,
159 Some(parent) => {
160 node = parent;
161 &node
162 }
163 },
164 SyntaxElement::Node(node) => node,
165 };
166 if changed_elements_set.contains(node) {
167 let new_node = node.clone_subtree().clone_for_update();
168 match node_or_token {
169 SyntaxElement::Node(node) => *node = new_node,
170 SyntaxElement::Token(token) => {
171 *token = new_node
172 .children_with_tokens()
173 .filter_map(SyntaxElement::into_token)
174 .find(|it| it.kind() == token.kind() && it.text() == token.text())
175 .unwrap();
176 }
177 }
178 } else {
179 changed_elements_set.insert(node.clone());
180 }
181 };
182
183 for index in independent_changes {
184 match &mut changes[index as usize] {
185 Change::Insert(target, _) | Change::InsertAll(target, _) => {
186 match &mut target.repr {
187 PositionRepr::FirstChild(parent) => {
188 *parent = tree_mutator.make_syntax_mut(parent);
189 }
190 PositionRepr::After(child) => {
191 *child = tree_mutator.make_element_mut(child);
192 }
193 };
194 }
195 Change::Replace(SyntaxElement::Node(target), Some(SyntaxElement::Node(new_target))) => {
196 *target = tree_mutator.make_syntax_mut(target);
197 if new_target.ancestors().any(|node| node == tree_mutator.immutable) {
198 *new_target = new_target.clone_for_update();
199 }
200 }
201 Change::Replace(target, _) | Change::ReplaceWithMany(target, _) => {
202 *target = tree_mutator.make_element_mut(target);
203 }
204 Change::ReplaceAll(range, _) => {
205 let start = tree_mutator.make_element_mut(range.start());
206 let end = tree_mutator.make_element_mut(range.end());
207
208 *range = start..=end;
209 }
210 }
211
212 match &mut changes[index as usize] {
213 Change::Insert(_, element) | Change::Replace(_, Some(element)) => {
214 deduplicate_node(element);
215 }
216 Change::InsertAll(_, elements)
217 | Change::ReplaceWithMany(_, elements)
218 | Change::ReplaceAll(_, elements) => {
219 elements.iter_mut().for_each(&mut deduplicate_node);
220 }
221 Change::Replace(_, None) => (),
222 }
223
224 match &changes[index as usize] {
226 Change::Insert(_, element) => changed_elements.push(element.clone()),
227 Change::InsertAll(_, elements) => changed_elements.extend(elements.iter().cloned()),
228 Change::Replace(_, Some(element)) => changed_elements.push(element.clone()),
229 Change::Replace(_, None) => {}
230 Change::ReplaceWithMany(_, elements) => {
231 changed_elements.extend(elements.iter().cloned())
232 }
233 Change::ReplaceAll(_, elements) => changed_elements.extend(elements.iter().cloned()),
234 }
235 }
236
237 for DependentChange { parent, child } in dependent_changes.into_iter() {
238 let (input_ancestor, output_ancestor) = match &changes[parent as usize] {
239 Change::Insert(_, _) | Change::InsertAll(_, _) => unreachable!(),
241 Change::Replace(target, Some(new_target)) => {
242 (to_owning_node(target), to_owning_node(new_target))
243 }
244 Change::Replace(_, None) => {
245 unreachable!("deletions should not generate dependent changes")
246 }
247 Change::ReplaceAll(_, _) | Change::ReplaceWithMany(_, _) => {
248 unimplemented!("cannot resolve changes that depend on replacing many elements")
249 }
250 };
251
252 let upmap_target_node = |target: &SyntaxNode| match mappings.upmap_child(
253 target,
254 &input_ancestor,
255 &output_ancestor,
256 ) {
257 Ok(it) => it,
258 Err(MissingMapping(current)) => unreachable!(
259 "no mappings exist between {current:?} (ancestor of {input_ancestor:?}) and {output_ancestor:?}"
260 ),
261 };
262
263 let upmap_target = |target: &SyntaxElement| match mappings.upmap_child_element(
264 target,
265 &input_ancestor,
266 &output_ancestor,
267 ) {
268 Ok(it) => it,
269 Err(MissingMapping(current)) => unreachable!(
270 "no mappings exist between {current:?} (ancestor of {input_ancestor:?}) and {output_ancestor:?}"
271 ),
272 };
273
274 match &mut changes[child as usize] {
275 Change::Insert(target, _) | Change::InsertAll(target, _) => match &mut target.repr {
276 PositionRepr::FirstChild(parent) => {
277 *parent = upmap_target_node(parent);
278 }
279 PositionRepr::After(child) => {
280 *child = upmap_target(child);
281 }
282 },
283 Change::Replace(target, _) | Change::ReplaceWithMany(target, _) => {
284 *target = upmap_target(target);
285 }
286 Change::ReplaceAll(range, _) => {
287 *range = upmap_target(range.start())..=upmap_target(range.end());
288 }
289 }
290 }
291
292 for idx in outdated_changes.into_iter().rev() {
295 changes.remove(idx as usize);
296 }
297
298 let mut root = tree_mutator.mutable_clone;
300
301 for change in changes {
302 match change {
303 Change::Insert(position, element) => {
304 let (parent, index) = position.place();
305 parent.splice_children(index..index, vec![element]);
306 }
307 Change::InsertAll(position, elements) => {
308 let (parent, index) = position.place();
309 parent.splice_children(index..index, elements);
310 }
311 Change::Replace(target, None) => {
312 target.detach();
313 }
314 Change::Replace(SyntaxElement::Node(target), Some(new_target)) if target == root => {
315 root = new_target.into_node().expect("root node replacement should be a node");
316 }
317 Change::Replace(target, Some(new_target)) => {
318 let parent = target.parent().unwrap();
319 parent.splice_children(target.index()..target.index() + 1, vec![new_target]);
320 }
321 Change::ReplaceWithMany(target, elements) => {
322 let parent = target.parent().unwrap();
323 parent.splice_children(target.index()..target.index() + 1, elements);
324 }
325 Change::ReplaceAll(range, elements) => {
326 let start = range.start().index();
327 let end = range.end().index();
328 let parent = range.start().parent().unwrap();
329 parent.splice_children(start..end + 1, elements);
330 }
331 }
332 }
333
334 let annotations = annotations.into_iter().filter_map(|(element, annotation)| {
336 match mappings.upmap_element(&element, &root) {
337 Some(Ok(mapped)) => Some((mapped, annotation)),
339 None => Some((element, annotation)),
341 Some(Err(_)) => None,
343 }
344 });
345
346 let mut annotation_groups = FxHashMap::default();
347
348 for (element, annotation) in annotations {
349 annotation_groups.entry(annotation).or_insert(vec![]).push(element);
350 }
351
352 SyntaxEdit {
353 old_root: tree_mutator.immutable,
354 new_root: root,
355 changed_elements,
356 annotations: annotation_groups,
357 }
358}
359
360fn report_intersecting_changes(
361 changes: &[Change],
362 mut get_node_depth: impl FnMut(rowan::SyntaxNode<crate::RustLanguage>) -> usize,
363 root: &rowan::SyntaxNode<crate::RustLanguage>,
364) {
365 let intersecting_changes = changes
366 .iter()
367 .zip(changes.iter().skip(1))
368 .filter(|(l, r)| {
369 matches!(
371 (l.change_kind(), r.change_kind()),
372 (
373 ChangeKind::Replace | ChangeKind::ReplaceRange,
374 ChangeKind::Replace | ChangeKind::ReplaceRange
375 )
376 )
377 })
378 .filter(|(l, r)| {
379 get_node_depth(l.target_parent()) == get_node_depth(r.target_parent())
380 && (l.target_range().end() > r.target_range().start())
381 });
382
383 let mut error_msg = String::from("some replace change ranges intersect!\n");
384
385 let parent_str = root.to_string();
386
387 for (l, r) in intersecting_changes {
388 let mut highlighted_str = parent_str.clone();
389 let l_range = l.target_range();
390 let r_range = r.target_range();
391
392 let i_range = l_range.intersect(r_range).unwrap();
393 let i_str = format!("\x1b[46m{}", &parent_str[i_range]);
394
395 let pre_range: Range<usize> = l_range.start().into()..i_range.start().into();
396 let pre_str = format!("\x1b[44m{}", &parent_str[pre_range]);
397
398 let (highlight_range, highlight_str) = if l_range == r_range {
399 format_to!(error_msg, "\x1b[46mleft change:\x1b[0m {l:?} {l}\n");
400 format_to!(error_msg, "\x1b[46mequals\x1b[0m\n");
401 format_to!(error_msg, "\x1b[46mright change:\x1b[0m {r:?} {r}\n");
402 let i_highlighted = format!("{i_str}\x1b[0m\x1b[K");
403 let total_range: Range<usize> = i_range.into();
404 (total_range, i_highlighted)
405 } else {
406 format_to!(error_msg, "\x1b[44mleft change:\x1b[0m {l:?} {l}\n");
407 let range_end = if l_range.contains_range(r_range) {
408 format_to!(error_msg, "\x1b[46mcovers\x1b[0m\n");
409 format_to!(error_msg, "\x1b[46mright change:\x1b[0m {r:?} {r}\n");
410 l_range.end()
411 } else {
412 format_to!(error_msg, "\x1b[46mintersects\x1b[0m\n");
413 format_to!(error_msg, "\x1b[42mright change:\x1b[0m {r:?} {r}\n");
414 r_range.end()
415 };
416
417 let post_range: Range<usize> = i_range.end().into()..range_end.into();
418
419 let post_str = format!("\x1b[42m{}", &parent_str[post_range]);
420 let result = format!("{pre_str}{i_str}{post_str}\x1b[0m\x1b[K");
421 let total_range: Range<usize> = l_range.start().into()..range_end.into();
422 (total_range, result)
423 };
424 highlighted_str.replace_range(highlight_range, &highlight_str);
425
426 format_to!(error_msg, "{highlighted_str}\n");
427 }
428
429 stdx::always!(false, "{}", error_msg);
430}
431
432fn to_owning_node(element: &SyntaxElement) -> SyntaxNode {
433 match element {
434 SyntaxElement::Node(node) => node.clone(),
435 SyntaxElement::Token(token) => token.parent().unwrap(),
436 }
437}
438
439struct ChangedAncestor {
440 kind: ChangedAncestorKind,
441 change_index: usize,
442}
443
444enum ChangedAncestorKind {
445 Single { node: SyntaxNode },
446 Range { _changed_elements: RangeInclusive<SyntaxElement>, _in_parent: SyntaxNode },
447}
448
449impl ChangedAncestor {
450 fn single(node: &SyntaxNode, change_index: usize) -> Self {
451 let kind = ChangedAncestorKind::Single { node: node.clone() };
452
453 Self { kind, change_index }
454 }
455
456 fn multiple(range: &RangeInclusive<SyntaxElement>, change_index: usize) -> Self {
457 Self {
458 kind: ChangedAncestorKind::Range {
459 _changed_elements: range.clone(),
460 _in_parent: range.start().parent().unwrap(),
461 },
462 change_index,
463 }
464 }
465
466 fn affected_range(&self) -> TextRange {
467 match &self.kind {
468 ChangedAncestorKind::Single { node } => node.text_range(),
469 ChangedAncestorKind::Range { _changed_elements: changed_nodes, _in_parent: _ } => {
470 TextRange::new(
471 changed_nodes.start().text_range().start(),
472 changed_nodes.end().text_range().end(),
473 )
474 }
475 }
476 }
477}
478
479struct TreeMutator {
480 immutable: SyntaxNode,
481 mutable_clone: SyntaxNode,
482}
483
484impl TreeMutator {
485 fn new(immutable: &SyntaxNode) -> TreeMutator {
486 let immutable = immutable.clone();
487 let mutable_clone = immutable.clone_for_update();
488 TreeMutator { immutable, mutable_clone }
489 }
490
491 fn make_element_mut(&self, element: &SyntaxElement) -> SyntaxElement {
492 match element {
493 SyntaxElement::Node(node) => SyntaxElement::Node(self.make_syntax_mut(node)),
494 SyntaxElement::Token(token) => {
495 let parent = self.make_syntax_mut(&token.parent().unwrap());
496 parent.children_with_tokens().nth(token.index()).unwrap()
497 }
498 }
499 }
500
501 fn make_syntax_mut(&self, node: &SyntaxNode) -> SyntaxNode {
502 let ptr = SyntaxNodePtr::new(node);
503 ptr.to_node(&self.mutable_clone)
504 }
505}