node_mutation 1.21.4 → 1.21.5
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 +4 -0
- data/Gemfile.lock +1 -1
- data/lib/node_mutation/version.rb +1 -1
- data/lib/node_mutation.rb +67 -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: f1148a4464a8b1f52500b09be2581a61c0add079b55052ced0e92297885f7082
|
4
|
+
data.tar.gz: c8e779f8ab34b515c7c991a0b16c3a4aa85c280841fa65d021a1d4fd6a49ec25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 662faf8ca577ab83503429153c5af550a4a3134a8138e4f36400aa6fcfb40b27de367c5a837af6dd6a139fe63627f3343d11d5573e2ae0501d0cfaf25fb8adb3
|
7
|
+
data.tar.gz: deda4075371317fd3c5decfda04bb8752b38f37679c21e1d940f1ebb2ef775f945ee38956ebea0e78717eb386e3dccaf5ff3b76fb50f550e616a246a880e43d6
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/lib/node_mutation.rb
CHANGED
@@ -262,20 +262,22 @@ 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
|
-
new_source = rewrite_source(source,
|
280
|
+
new_source = rewrite_source(source, sort_actions(get_filter_actions(conflict_actions)))
|
279
281
|
result = NodeMutation::Result.new(affected: true, conflicted: !conflict_actions.empty?)
|
280
282
|
result.new_source = new_source
|
281
283
|
result
|
@@ -289,63 +291,79 @@ class NodeMutation
|
|
289
291
|
# if strategy is set to KEEP_RUNNING.
|
290
292
|
# @return {NodeMutation::Result}
|
291
293
|
def test
|
292
|
-
@actions =
|
293
|
-
|
294
|
+
@actions = optimize_group_actions(@actions)
|
295
|
+
|
296
|
+
flatten_actions = flat_actions(@actions)
|
297
|
+
if flatten_actions.length == 0
|
294
298
|
return NodeMutation::Result.new(affected: false, conflicted: false)
|
295
299
|
end
|
296
300
|
|
297
301
|
@transform_proc.call(@actions) if @transform_proc
|
298
|
-
|
299
|
-
conflict_actions = get_conflict_actions(
|
302
|
+
sorted_actions = sort_flatten_actions(flatten_actions)
|
303
|
+
conflict_actions = get_conflict_actions(sorted_actions)
|
300
304
|
if conflict_actions.size > 0 && strategy?(Strategy::THROW_ERROR)
|
301
305
|
raise ConflictActionError, "mutation actions are conflicted"
|
302
306
|
end
|
303
307
|
|
304
308
|
result = NodeMutation::Result.new(affected: true, conflicted: !conflict_actions.empty?)
|
305
|
-
|
309
|
+
actions = sort_actions(get_filter_actions(conflict_actions))
|
310
|
+
result.actions = actions.map(&:to_struct)
|
306
311
|
result
|
307
312
|
end
|
308
313
|
|
309
314
|
private
|
310
315
|
|
311
|
-
#
|
316
|
+
# Optimizes a list of actions, recursively optimizing any nested group actions.
|
317
|
+
# @param actions [Array<NodeMutation::Action>]
|
318
|
+
# @return [Array<NodeMutation::Action>] optimized actions
|
319
|
+
def optimize_group_actions(actions)
|
320
|
+
actions.map do |action|
|
321
|
+
if action.is_a?(GroupAction)
|
322
|
+
# If the group action contains only one action, replace the group action with that action
|
323
|
+
if action.actions.length === 1
|
324
|
+
return optimize_group_actions(action.actions)
|
325
|
+
end
|
326
|
+
|
327
|
+
# If the group action contains more than one action, optimize its sub-actions
|
328
|
+
action.actions = optimize_group_actions(action.actions)
|
329
|
+
end
|
330
|
+
action
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
# It flats a series of actions by removing any GroupAction
|
312
335
|
# objects that contain only a single action. This is done recursively.
|
313
|
-
|
314
|
-
|
336
|
+
# @param actions [Array<NodeMutation::Action>]
|
337
|
+
# @return [Array<NodeMutation::Action>] flatten actions
|
338
|
+
def flat_actions(actions)
|
339
|
+
flatten_actions = []
|
315
340
|
actions.each do |action|
|
316
341
|
if action.is_a?(GroupAction)
|
317
|
-
|
342
|
+
flatten_actions += flat_actions(action.actions)
|
318
343
|
else
|
319
|
-
|
344
|
+
flatten_actions << action
|
320
345
|
end
|
321
346
|
end
|
322
|
-
|
347
|
+
flatten_actions
|
323
348
|
end
|
324
349
|
|
325
|
-
#
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
if action.
|
331
|
-
|
332
|
-
else
|
333
|
-
action.actions.first
|
350
|
+
# Recusively sort actions by start position and end position.
|
351
|
+
# @param actions [Array<NodeMutation::Action>]
|
352
|
+
# @return [Array<NodeMutation::Action>] sorted actions
|
353
|
+
def sort_actions(actions)
|
354
|
+
actions.each do |action|
|
355
|
+
if action.is_a?(GroupAction)
|
356
|
+
action.actions = sort_actions(action.actions)
|
334
357
|
end
|
335
|
-
else
|
336
|
-
action.actions = flatten_actions(action.actions)
|
337
|
-
action
|
338
358
|
end
|
359
|
+
actions.sort_by { |action| [action.start, action.end] }
|
339
360
|
end
|
340
361
|
|
341
362
|
# Sort actions by start position and end position.
|
342
363
|
# @param actions [Array<NodeMutation::Action>]
|
343
364
|
# @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
|
365
|
+
def sort_flatten_actions(flatten_actions)
|
366
|
+
flatten_actions.sort_by { |action| [action.start, action.end] }
|
349
367
|
end
|
350
368
|
|
351
369
|
# Rewrite source code with actions.
|
@@ -365,6 +383,8 @@ class NodeMutation
|
|
365
383
|
|
366
384
|
# It changes source code from bottom to top, and it can change source code twice at the same time,
|
367
385
|
# So if there is an overlap between two actions, it removes the conflict actions and operate them in the next loop.
|
386
|
+
# @param actions [Array<NodeMutation::Action>]
|
387
|
+
# @return [Array<NodeMutation::Action>] conflict actions
|
368
388
|
def get_conflict_actions(actions)
|
369
389
|
i = actions.length - 1
|
370
390
|
j = i - 1
|
@@ -376,7 +396,7 @@ class NodeMutation
|
|
376
396
|
while j > -1
|
377
397
|
# if we have two actions with overlapped range.
|
378
398
|
if begin_pos < actions[j].end
|
379
|
-
conflict_actions << actions
|
399
|
+
conflict_actions << actions[j]
|
380
400
|
else
|
381
401
|
i = j
|
382
402
|
begin_pos = actions[i].start
|
@@ -384,12 +404,22 @@ class NodeMutation
|
|
384
404
|
end
|
385
405
|
j -= 1
|
386
406
|
end
|
387
|
-
actions.each do |action|
|
388
|
-
conflict_actions.concat(get_conflict_actions(action.actions)) if action.is_a?(GroupAction)
|
389
|
-
end
|
390
407
|
conflict_actions
|
391
408
|
end
|
392
409
|
|
410
|
+
# It filters conflict actions from actions.
|
411
|
+
# @param actions [Array<NodeMutation::Action>]
|
412
|
+
# @return [Array<NodeMutation::Action>] filtered actions
|
413
|
+
def get_filter_actions(conflict_actions)
|
414
|
+
@actions.select do |action|
|
415
|
+
if action.is_a?(GroupAction)
|
416
|
+
action.actions.all? { |child_action| !conflict_actions.include?(child_action) }
|
417
|
+
else
|
418
|
+
!conflict_actions.include?(action)
|
419
|
+
end
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
393
423
|
def strategy?(strategy)
|
394
424
|
NodeMutation.strategy & strategy == strategy
|
395
425
|
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.5
|
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-19 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: ast node mutation apis
|
14
14
|
email:
|