@@ -4,8 +4,8 @@ use rowan::TextRange;
4
4
use rustc_hash:: { FxHashMap , FxHashSet } ;
5
5
6
6
use crate :: {
7
- syntax_editor:: { mapping:: MissingMapping , Change , ChangeKind } ,
8
- ted , SyntaxElement , SyntaxNode , SyntaxNodePtr ,
7
+ syntax_editor:: { mapping:: MissingMapping , Change , ChangeKind , Position , PositionRepr } ,
8
+ SyntaxElement , SyntaxNode , SyntaxNodePtr ,
9
9
} ;
10
10
11
11
use super :: { SyntaxEdit , SyntaxEditor } ;
@@ -94,6 +94,7 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit {
94
94
95
95
// Add to changed ancestors, if applicable
96
96
match change {
97
+ Change :: Insert ( _, _) | Change :: InsertAll ( _, _) => { }
97
98
Change :: Replace ( target, _) => {
98
99
changed_ancestors. push_back ( ChangedAncestor :: single ( target, change_index) )
99
100
}
@@ -106,23 +107,46 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit {
106
107
107
108
for index in independent_changes {
108
109
match & mut changes[ index as usize ] {
109
- Change :: Replace ( target, new_node) => {
110
+ Change :: Insert ( target, _) | Change :: InsertAll ( target, _) => {
111
+ match & mut target. repr {
112
+ PositionRepr :: FirstChild ( parent) => {
113
+ * parent = tree_mutator. make_syntax_mut ( parent) ;
114
+ }
115
+ PositionRepr :: After ( child) => {
116
+ * child = tree_mutator. make_element_mut ( child) ;
117
+ }
118
+ } ;
119
+ }
120
+ Change :: Replace ( target, _) => {
110
121
* target = tree_mutator. make_element_mut ( target) ;
111
-
112
- if let Some ( new_node) = new_node {
113
- changed_elements. push ( new_node. clone ( ) ) ;
114
- }
115
122
}
116
123
}
124
+
125
+ // Collect changed elements
126
+ match & changes[ index as usize ] {
127
+ Change :: Insert ( _, element) => changed_elements. push ( element. clone ( ) ) ,
128
+ Change :: InsertAll ( _, elements) => changed_elements. extend ( elements. iter ( ) . cloned ( ) ) ,
129
+ Change :: Replace ( _, Some ( element) ) => changed_elements. push ( element. clone ( ) ) ,
130
+ Change :: Replace ( _, None ) => { }
131
+ }
117
132
}
118
133
119
134
for DependentChange { parent, child } in dependent_changes. into_iter ( ) {
120
135
let ( input_ancestor, output_ancestor) = match & changes[ parent as usize ] {
121
- // insert? unreachable
136
+ // No change will depend on an insert since changes can only depend on nodes in the root tree
137
+ Change :: Insert ( _, _) | Change :: InsertAll ( _, _) => unreachable ! ( ) ,
122
138
Change :: Replace ( target, Some ( new_target) ) => {
123
139
( to_owning_node ( target) , to_owning_node ( new_target) )
124
140
}
125
- Change :: Replace ( _, None ) => continue , // silently drop outdated change
141
+ // Silently drop outdated change
142
+ Change :: Replace ( _, None ) => continue ,
143
+ } ;
144
+
145
+ let upmap_target_node = |target : & SyntaxNode | {
146
+ match mappings. upmap_child ( target, & input_ancestor, & output_ancestor) {
147
+ Ok ( it) => it,
148
+ Err ( MissingMapping ( current) ) => unreachable ! ( "no mappings exist between {current:?} (ancestor of {input_ancestor:?}) and {output_ancestor:?}" ) ,
149
+ }
126
150
} ;
127
151
128
152
let upmap_target = |target : & SyntaxElement | {
@@ -133,6 +157,14 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit {
133
157
} ;
134
158
135
159
match & mut changes[ child as usize ] {
160
+ Change :: Insert ( target, _) | Change :: InsertAll ( target, _) => match & mut target. repr {
161
+ PositionRepr :: FirstChild ( parent) => {
162
+ * parent = upmap_target_node ( parent) ;
163
+ }
164
+ PositionRepr :: After ( child) => {
165
+ * child = upmap_target ( child) ;
166
+ }
167
+ } ,
136
168
Change :: Replace ( target, _) => {
137
169
* target = upmap_target ( & target) ;
138
170
}
@@ -142,8 +174,21 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit {
142
174
// Apply changes
143
175
for change in changes {
144
176
match change {
145
- Change :: Replace ( target, None ) => ted:: remove ( target) ,
146
- Change :: Replace ( target, Some ( new_target) ) => ted:: replace ( target, new_target) ,
177
+ Change :: Insert ( position, element) => {
178
+ let ( parent, index) = position. place ( ) ;
179
+ parent. splice_children ( index..index, vec ! [ element] ) ;
180
+ }
181
+ Change :: InsertAll ( position, elements) => {
182
+ let ( parent, index) = position. place ( ) ;
183
+ parent. splice_children ( index..index, elements) ;
184
+ }
185
+ Change :: Replace ( target, None ) => {
186
+ target. detach ( ) ;
187
+ }
188
+ Change :: Replace ( target, Some ( new_target) ) => {
189
+ let parent = target. parent ( ) . unwrap ( ) ;
190
+ parent. splice_children ( target. index ( ) ..target. index ( ) + 1 , vec ! [ new_target] ) ;
191
+ }
147
192
}
148
193
}
149
194
0 commit comments