@@ -88,84 +88,69 @@ func visit(root: Node, visitor: Visitor, keyMap: [Kind: [String]] = [:]) -> Node
88
88
var keys : [ IndexPathElement ] = [ " root " ]
89
89
var index : Int = - 1
90
90
var edits : [ ( key: IndexPathElement , node: Node ) ] = [ ]
91
+ var node : NodeResult ? = . node( root)
92
+ var key : IndexPathElement ?
91
93
var parent : NodeResult ?
92
94
var path : [ IndexPathElement ] = [ ]
93
95
var ancestors : [ NodeResult ] = [ ]
94
- var newRoot = root
95
96
96
97
repeat {
97
98
index += 1
98
99
let isLeaving = index == keys. count
99
- var key : IndexPathElement ?
100
- var node : NodeResult ?
101
100
let isEdited = isLeaving && !edits. isEmpty
102
101
103
- if !isLeaving {
104
- key = parent != nil ? inArray ? index : keys [ index] : nil
105
-
106
- if let parent = parent {
107
- switch parent {
108
- case let . node( parent) :
109
- node = parent. get ( key: key!. keyValue!)
110
- case let . array( parent) :
111
- node = . node( parent [ key!. indexValue!] )
112
- }
113
- } else {
114
- node = . node( newRoot)
115
- }
116
-
117
- if node == nil {
118
- continue
119
- }
120
-
121
- if parent != nil {
122
- path. append ( key!)
123
- }
124
- } else {
102
+ if isLeaving {
125
103
key = ancestors. isEmpty ? nil : path. popLast ( )
126
104
node = parent
127
105
parent = ancestors. popLast ( )
128
106
129
107
if isEdited {
130
- // if inArray {
131
- // node = node.slice()
132
- // } else {
133
- // let clone = node
134
- // node = clone
135
- // }
136
- //
137
- // var editOffset = 0
138
- //
139
- // for ii in 0..<edits.count {
140
- // var editKey = edits[ii].key
141
- // let editValue = edits[ii].node
142
- //
143
- // if inArray {
144
- // editKey -= editOffset
145
- // }
146
- //
147
- // if inArray && editValue == nil {
148
- // node.splice(editKey, 1)
149
- // editOffset += 1
150
- // } else {
151
- //
152
- // if let node = node, case .node(let n) = node {
153
- // n.set(value: editValue, key: editKey.keyValue!)
154
- // }
155
- // }
156
- // }
108
+ if inArray {
109
+ var editOffset = 0
110
+ for (editKey, editValue) in edits {
111
+ let editKey = editKey. indexValue!
112
+ let arrayKey = editKey - editOffset
113
+
114
+ if case . array( var n) = node {
115
+ n. remove ( at: arrayKey)
116
+ node = . array( n)
117
+ editOffset += 1
118
+ }
119
+ }
120
+ } else {
121
+ let clone = node
122
+ node = clone
123
+ for (editKey, editValue) in edits {
124
+ if case . node( let node) = node {
125
+ node. set ( value: editValue, key: editKey. keyValue!)
126
+ }
127
+ }
128
+ }
157
129
}
158
130
159
131
index = stack!. index
160
132
keys = stack!. keys
161
133
edits = stack!. edits
162
134
inArray = stack!. inArray
163
135
stack = stack!. prev
164
- }
136
+ } else if let parent = parent {
137
+ key = inArray ? index : keys [ index]
138
+
139
+ switch parent {
140
+ case let . node( parent) :
141
+ node = parent. get ( key: key!. keyValue!)
142
+ case let . array( parent) :
143
+ node = . node( parent [ key!. indexValue!] )
144
+ }
165
145
166
- var result : VisitResult
146
+ if node == nil {
147
+ continue
148
+ }
149
+ path. append ( key!)
150
+ }
167
151
168
- if case let . node( n) = node! {
152
+ var result : VisitResult = . break // placeholder
153
+ if case let . node( n) = node {
169
154
if !isLeaving {
170
155
result = visitor. enter (
171
156
node: n,
@@ -188,15 +173,16 @@ func visit(root: Node, visitor: Visitor, keyMap: [Kind: [String]] = [:]) -> Node
188
173
break
189
174
}
190
175
191
- if case . skip = result, !isLeaving {
192
- _ = path. popLast ( )
193
- continue
194
- } else if case let . node( n) = result {
195
- edits. append ( ( key!, n!) )
196
-
176
+ if case . skip = result {
197
177
if !isLeaving {
198
- if let n = n {
199
- node = . node( n)
178
+ _ = path. popLast ( )
179
+ continue
180
+ }
181
+ } else if case let . node( resultNode) = result {
182
+ edits. append ( ( key!, resultNode!) )
183
+ if !isLeaving {
184
+ if let resultNode = resultNode {
185
+ node = . node( resultNode)
200
186
} else {
201
187
_ = path. popLast ( )
202
188
continue
@@ -205,38 +191,36 @@ func visit(root: Node, visitor: Visitor, keyMap: [Kind: [String]] = [:]) -> Node
205
191
}
206
192
}
207
193
208
- // if case .continue = result, isEdited {
209
- // edits.append((key!, node! ))
210
- // }
194
+ if case . continue = result, isEdited, case let . node ( node ) = node! {
195
+ edits. append ( ( key!, node) )
196
+ }
211
197
212
- if !isLeaving {
198
+ if isLeaving {
199
+ _ = path. popLast ( )
200
+ } else {
213
201
stack = Stack ( index: index, keys: keys, edits: edits, inArray: inArray, prev: stack)
214
202
inArray = node!. isArray
215
-
216
203
switch node! {
217
204
case let . node( node) :
218
205
keys = visitorKeys [ node. kind] ?? [ ]
219
206
case let . array( array) :
220
207
keys = array. map { _ in " root " }
221
208
}
222
-
223
209
index = - 1
224
210
edits = [ ]
225
-
226
211
if let parent = parent {
227
212
ancestors. append ( parent)
228
213
}
229
-
230
214
parent = node
231
215
}
232
216
} while
233
217
stack != nil
234
218
235
219
if !edits. isEmpty {
236
- newRoot = edits [ edits. count - 1 ] . node
220
+ return edits [ edits. count - 1 ] . node
237
221
}
238
222
239
- return newRoot
223
+ return root
240
224
}
241
225
242
226
final class Stack {
0 commit comments