node_mutation 1.21.4 → 1.21.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/Gemfile.lock +1 -1
- data/lib/node_mutation/version.rb +1 -1
- data/lib/node_mutation.rb +68 -37
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ae5572567e82e089eefff7f7f696230a17e77fbf0af051dd3a4a46ad21bf9a8
|
4
|
+
data.tar.gz: 8448ddd41dadbee697ee58a2d506bd7832fe9792d601e3a969cdc5b8869651fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 603b93346813a1e4a0e6a2fed2c3fb5a0569f592b69de6d3f580b055ad1cae301c03c1984c50e567612f9b9f32b6fe706cd1c8276691b895d387044349c9fb93
|
7
|
+
data.tar.gz: 7c2ac5164feb10bbb01d0f355c831032dbccbdb6a80eb341884dc350f33dc95409cec2ced8ead61862fadde4ae71f2244414a43b4cd42ea23b70dc62f1082566
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/lib/node_mutation.rb
CHANGED
@@ -262,20 +262,23 @@ class NodeMutation
|
|
262
262
|
# if strategy is set to KEEP_RUNNING.
|
263
263
|
# @return {NodeMutation::Result}
|
264
264
|
def process
|
265
|
-
@actions =
|
266
|
-
|
265
|
+
@actions = optimize_group_actions(@actions)
|
266
|
+
|
267
|
+
flatten_actions = flat_actions(@actions)
|
268
|
+
if flatten_actions.length == 0
|
267
269
|
return NodeMutation::Result.new(affected: false, conflicted: false)
|
268
270
|
end
|
269
271
|
|
270
272
|
source = +@source
|
271
273
|
@transform_proc.call(@actions) if @transform_proc
|
272
|
-
|
273
|
-
conflict_actions = get_conflict_actions(
|
274
|
+
sorted_actions = sort_flatten_actions(flatten_actions)
|
275
|
+
conflict_actions = get_conflict_actions(sorted_actions)
|
274
276
|
if conflict_actions.size > 0 && strategy?(Strategy::THROW_ERROR)
|
275
277
|
raise ConflictActionError, "mutation actions are conflicted"
|
276
278
|
end
|
277
279
|
|
278
|
-
|
280
|
+
actions = sort_flatten_actions(flat_actions(get_filter_actions(conflict_actions)))
|
281
|
+
new_source = rewrite_source(source, actions)
|
279
282
|
result = NodeMutation::Result.new(affected: true, conflicted: !conflict_actions.empty?)
|
280
283
|
result.new_source = new_source
|
281
284
|
result
|
@@ -289,63 +292,79 @@ class NodeMutation
|
|
289
292
|
# if strategy is set to KEEP_RUNNING.
|
290
293
|
# @return {NodeMutation::Result}
|
291
294
|
def test
|
292
|
-
@actions =
|
293
|
-
|
295
|
+
@actions = optimize_group_actions(@actions)
|
296
|
+
|
297
|
+
flatten_actions = flat_actions(@actions)
|
298
|
+
if flatten_actions.length == 0
|
294
299
|
return NodeMutation::Result.new(affected: false, conflicted: false)
|
295
300
|
end
|
296
301
|
|
297
302
|
@transform_proc.call(@actions) if @transform_proc
|
298
|
-
|
299
|
-
conflict_actions = get_conflict_actions(
|
303
|
+
sorted_actions = sort_flatten_actions(flatten_actions)
|
304
|
+
conflict_actions = get_conflict_actions(sorted_actions)
|
300
305
|
if conflict_actions.size > 0 && strategy?(Strategy::THROW_ERROR)
|
301
306
|
raise ConflictActionError, "mutation actions are conflicted"
|
302
307
|
end
|
303
308
|
|
304
309
|
result = NodeMutation::Result.new(affected: true, conflicted: !conflict_actions.empty?)
|
305
|
-
|
310
|
+
actions = sort_actions(get_filter_actions(conflict_actions))
|
311
|
+
result.actions = actions.map(&:to_struct)
|
306
312
|
result
|
307
313
|
end
|
308
314
|
|
309
315
|
private
|
310
316
|
|
311
|
-
#
|
317
|
+
# Optimizes a list of actions, recursively optimizing any nested group actions.
|
318
|
+
# @param actions [Array<NodeMutation::Action>]
|
319
|
+
# @return [Array<NodeMutation::Action>] optimized actions
|
320
|
+
def optimize_group_actions(actions)
|
321
|
+
actions.map do |action|
|
322
|
+
if action.is_a?(GroupAction)
|
323
|
+
# If the group action contains only one action, replace the group action with that action
|
324
|
+
if action.actions.length === 1
|
325
|
+
return optimize_group_actions(action.actions)
|
326
|
+
end
|
327
|
+
|
328
|
+
# If the group action contains more than one action, optimize its sub-actions
|
329
|
+
action.actions = optimize_group_actions(action.actions)
|
330
|
+
end
|
331
|
+
action
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
# It flats a series of actions by removing any GroupAction
|
312
336
|
# objects that contain only a single action. This is done recursively.
|
313
|
-
|
314
|
-
|
337
|
+
# @param actions [Array<NodeMutation::Action>]
|
338
|
+
# @return [Array<NodeMutation::Action>] flatten actions
|
339
|
+
def flat_actions(actions)
|
340
|
+
flatten_actions = []
|
315
341
|
actions.each do |action|
|
316
342
|
if action.is_a?(GroupAction)
|
317
|
-
|
343
|
+
flatten_actions += flat_actions(action.actions)
|
318
344
|
else
|
319
|
-
|
345
|
+
flatten_actions << action
|
320
346
|
end
|
321
347
|
end
|
322
|
-
|
348
|
+
flatten_actions
|
323
349
|
end
|
324
350
|
|
325
|
-
#
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
if action.
|
331
|
-
|
332
|
-
else
|
333
|
-
action.actions.first
|
351
|
+
# Recusively sort actions by start position and end position.
|
352
|
+
# @param actions [Array<NodeMutation::Action>]
|
353
|
+
# @return [Array<NodeMutation::Action>] sorted actions
|
354
|
+
def sort_actions(actions)
|
355
|
+
actions.each do |action|
|
356
|
+
if action.is_a?(GroupAction)
|
357
|
+
action.actions = sort_actions(action.actions)
|
334
358
|
end
|
335
|
-
else
|
336
|
-
action.actions = flatten_actions(action.actions)
|
337
|
-
action
|
338
359
|
end
|
360
|
+
actions.sort_by { |action| [action.start, action.end] }
|
339
361
|
end
|
340
362
|
|
341
363
|
# Sort actions by start position and end position.
|
342
364
|
# @param actions [Array<NodeMutation::Action>]
|
343
365
|
# @return [Array<NodeMutation::Action>] sorted actions
|
344
|
-
def
|
345
|
-
|
346
|
-
actions.each do |action|
|
347
|
-
sort_actions!(action.actions) if action.is_a?(GroupAction)
|
348
|
-
end
|
366
|
+
def sort_flatten_actions(flatten_actions)
|
367
|
+
flatten_actions.sort_by { |action| [action.start, action.end] }
|
349
368
|
end
|
350
369
|
|
351
370
|
# Rewrite source code with actions.
|
@@ -365,6 +384,8 @@ class NodeMutation
|
|
365
384
|
|
366
385
|
# It changes source code from bottom to top, and it can change source code twice at the same time,
|
367
386
|
# So if there is an overlap between two actions, it removes the conflict actions and operate them in the next loop.
|
387
|
+
# @param actions [Array<NodeMutation::Action>]
|
388
|
+
# @return [Array<NodeMutation::Action>] conflict actions
|
368
389
|
def get_conflict_actions(actions)
|
369
390
|
i = actions.length - 1
|
370
391
|
j = i - 1
|
@@ -376,7 +397,7 @@ class NodeMutation
|
|
376
397
|
while j > -1
|
377
398
|
# if we have two actions with overlapped range.
|
378
399
|
if begin_pos < actions[j].end
|
379
|
-
conflict_actions << actions
|
400
|
+
conflict_actions << actions[j]
|
380
401
|
else
|
381
402
|
i = j
|
382
403
|
begin_pos = actions[i].start
|
@@ -384,12 +405,22 @@ class NodeMutation
|
|
384
405
|
end
|
385
406
|
j -= 1
|
386
407
|
end
|
387
|
-
actions.each do |action|
|
388
|
-
conflict_actions.concat(get_conflict_actions(action.actions)) if action.is_a?(GroupAction)
|
389
|
-
end
|
390
408
|
conflict_actions
|
391
409
|
end
|
392
410
|
|
411
|
+
# It filters conflict actions from actions.
|
412
|
+
# @param actions [Array<NodeMutation::Action>]
|
413
|
+
# @return [Array<NodeMutation::Action>] filtered actions
|
414
|
+
def get_filter_actions(conflict_actions)
|
415
|
+
@actions.select do |action|
|
416
|
+
if action.is_a?(GroupAction)
|
417
|
+
action.actions.all? { |child_action| !conflict_actions.include?(child_action) }
|
418
|
+
else
|
419
|
+
!conflict_actions.include?(action)
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
393
424
|
def strategy?(strategy)
|
394
425
|
NodeMutation.strategy & strategy == strategy
|
395
426
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: node_mutation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.21.
|
4
|
+
version: 1.21.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Huang
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-11-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: ast node mutation apis
|
14
14
|
email:
|