synvert-core 0.57.1 → 0.58.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d308267b7dc3f8561869a44ab25b6ffb329f4dfbc04ae66e960de167faa1ee4a
4
- data.tar.gz: c6863adae12f49e7d8c0eb79c336f11b5dfaead8b7679a32c32a2131a0cd2ccf
3
+ metadata.gz: 991e04b61994a2fd44aaaa4cb35564a56d359ffd2b9277fb805f6fb684a2f3ce
4
+ data.tar.gz: 0d969850a6915e9861937fa2a4e77ee36d93954b0aa764ffa3a56396d83becba
5
5
  SHA512:
6
- metadata.gz: ce3db59d4d4d047c4abafbe3130252615bf601fc980c601d93552777105c646eb76174e04ae5e7af16004570f4d091c7549c40c5b5b0e803ab8eb916607ae34a
7
- data.tar.gz: 2095af835a69d267a8d78112752aa553c002cb0699f3ca082b2ef0600e95b772eba9aae76cbd863ae3e8d7a7101c92942e03ae89e34d0c3abd6a636a5b65ac29
6
+ metadata.gz: 4d7a0dfe005762899d89eaede4db3219b1d6d03c94d640b1b2168234402747e658f9e19a537f6f129b8cc1e8741ca45cddfa32ed354d8e8361a08a544b41e99f
7
+ data.tar.gz: fe58dedc331361f6cfbf1627e55f677e61073271a40ad7ea62bb57233ab9350f8c99750f5346360511d64e3ba0f35d112683029b377e866f3591a9a3f7ea575c
data/CHANGELOG.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # CHANGELOG
2
2
 
3
- ## 0.57.1 (2021-10-18)
3
+ ## 0.58.0 (2021-10-23)
4
4
 
5
5
  * Support `left_value` and `right_value` for `and` and `or` node
6
+ * Rewrite `within_node` and `within_direct_node`, `WithinScope` accepts `recursive` and `direct` options
6
7
 
7
8
  ## 0.57.0 (2021-10-02)
8
9
 
@@ -432,8 +432,8 @@ module Parser::AST
432
432
  def recursive_children(&block)
433
433
  children.each do |child|
434
434
  if child.is_a?(Parser::AST::Node)
435
- yield child
436
- child.recursive_children(&block)
435
+ result = yield child
436
+ child.recursive_children(&block) unless result == :stop
437
437
  end
438
438
  end
439
439
  end
@@ -161,9 +161,11 @@ module Synvert::Core
161
161
  # then continue operating on each matching ast node.
162
162
  #
163
163
  # @param rules [Hash] rules to find mathing ast nodes.
164
+ # @param options [Hash] optional, set if recursive or not.
164
165
  # @param block [Block] block code to continue operating on the matching nodes.
165
- def within_node(rules, &block)
166
- Rewriter::WithinScope.new(self, rules, { recursive: true }, &block).process
166
+ def within_node(rules, options = nil, &block)
167
+ options ||= { recursive: true }
168
+ Rewriter::WithinScope.new(self, rules, options, &block).process
167
169
  end
168
170
 
169
171
  alias with_node within_node
@@ -174,7 +176,7 @@ module Synvert::Core
174
176
  # @param rules [Hash] rules to find mathing ast nodes.
175
177
  # @param block [Block] block code to continue operating on the matching nodes.
176
178
  def within_direct_node(rules, &block)
177
- Rewriter::WithinScope.new(self, rules, { recursive: false }, &block).process
179
+ Rewriter::WithinScope.new(self, rules, { direct: true }, &block).process
178
180
  end
179
181
 
180
182
  alias with_direct_node within_direct_node
@@ -9,7 +9,7 @@ module Synvert::Core
9
9
  # @param rules [Hash]
10
10
  # @param options [Hash]
11
11
  # @param block [Block]
12
- def initialize(instance, rules, options = { recursive: true }, &block)
12
+ def initialize(instance, rules, options = {}, &block)
13
13
  @instance = instance
14
14
  @rules = rules
15
15
  @options = options
@@ -23,7 +23,14 @@ module Synvert::Core
23
23
  current_node = @instance.current_node
24
24
  return unless current_node
25
25
 
26
- matching_nodes = find_matching_nodes(current_node)
26
+ matching_nodes =
27
+ if @options[:direct]
28
+ find_direct_matching_nodes(current_node)
29
+ elsif @options[:recursive]
30
+ find_recursive_matching_nodes(current_node)
31
+ else
32
+ find_matching_nodes(current_node)
33
+ end
27
34
  @instance.process_with_node current_node do
28
35
  matching_nodes.each do |matching_node|
29
36
  @instance.process_with_node matching_node do
@@ -35,36 +42,73 @@ module Synvert::Core
35
42
 
36
43
  private
37
44
 
38
- def find_matching_nodes(current_node)
45
+ # Find the matching nodes only in current or direct children.
46
+ def find_direct_matching_nodes(current_node)
39
47
  matching_nodes = []
40
- if @options[:recursive]
41
- if current_node.is_a?(Parser::AST::Node)
42
- matching_nodes << current_node if current_node.match? @rules
43
- current_node.recursive_children do |child_node|
44
- matching_nodes << child_node if child_node.match? @rules
45
- end
46
- else
47
- current_node.each do |node|
48
- matching_nodes << node if node.match? @rules
49
- node.recursive_children do |child_node|
50
- matching_nodes << child_node if child_node.match? @rules
51
- end
52
- end
53
- end
54
- elsif current_node.is_a?(Parser::AST::Node)
48
+ if current_node.is_a?(Parser::AST::Node)
55
49
  if current_node.type == :begin
56
50
  current_node.children.each do |child_node|
57
- matching_nodes << child_node if child_node.match? @rules
51
+ matching_nodes << child_node if child_node.match?(@rules)
58
52
  end
59
- elsif current_node.match? @rules
53
+ elsif current_node.match?(@rules)
60
54
  matching_nodes << current_node
61
55
  end
62
56
  else
63
57
  current_node.each do |child_node|
64
- matching_nodes << child_node if child_node.match? @rules
58
+ matching_nodes << child_node if child_node.match?(@rules)
59
+ end
60
+ end
61
+ matching_nodes
62
+ end
63
+
64
+ # Find matching nodes in all recursive children.
65
+ def find_recursive_matching_nodes(current_node)
66
+ matching_nodes = []
67
+ if current_node.is_a?(Parser::AST::Node)
68
+ matching_nodes << current_node if current_node.match?(@rules)
69
+ current_node.recursive_children do |child_node|
70
+ matching_nodes << child_node if child_node.match?(@rules)
71
+ end
72
+ else
73
+ current_node.each do |node|
74
+ matching_nodes << node if node.match?(@rules)
75
+ node.recursive_children do |child_node|
76
+ matching_nodes << child_node if child_node.match?(@rules)
77
+ end
78
+ end
79
+ end
80
+ matching_nodes
81
+ end
82
+
83
+ # Find matching nodes in recursive children but do not continue on matching nodes.
84
+ def find_matching_nodes(current_node)
85
+ matching_nodes = []
86
+ if current_node.is_a?(Parser::AST::Node)
87
+ if current_node.match?(@rules)
88
+ matching_nodes << current_node
89
+ return matching_nodes
90
+ end
91
+ current_node.recursive_children do |child_node|
92
+ if child_node.match?(@rules)
93
+ matching_nodes << child_node
94
+ break :stop
95
+ end
96
+ end
97
+ else
98
+ current_node.each do |node|
99
+ if node.match?(@rules)
100
+ matching_nodes << node
101
+ next
102
+ end
103
+ node.recursive_children do |child_node|
104
+ if child_node.match?(@rules)
105
+ matching_nodes << child_node
106
+ break :stop
107
+ end
108
+ end
65
109
  end
66
110
  end
67
111
  matching_nodes
68
112
  end
69
113
  end
70
- end
114
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Synvert
4
4
  module Core
5
- VERSION = '0.57.1'
5
+ VERSION = '0.58.0'
6
6
  end
7
7
  end
@@ -31,13 +31,23 @@ module Synvert::Core
31
31
  instance.with_node(type: 'send', message: 'create', &block)
32
32
  end
33
33
 
34
- it 'parses within_direct_node' do
34
+ it 'parses within_node with recursive false' do
35
35
  scope = double
36
36
  block = proc {}
37
37
  expect(Rewriter::WithinScope).to receive(:new)
38
38
  .with(instance, { type: 'send', message: 'create' }, { recursive: false }, &block)
39
39
  .and_return(scope)
40
40
  expect(scope).to receive(:process)
41
+ instance.within_node({ type: 'send', message: 'create' }, { recursive: false }, &block)
42
+ end
43
+
44
+ it 'parses within_direct_node' do
45
+ scope = double
46
+ block = proc {}
47
+ expect(Rewriter::WithinScope).to receive(:new)
48
+ .with(instance, { type: 'send', message: 'create' }, { direct: true }, &block)
49
+ .and_return(scope)
50
+ expect(scope).to receive(:process)
41
51
  instance.within_direct_node(type: 'send', message: 'create', &block)
42
52
  end
43
53
 
@@ -45,7 +55,7 @@ module Synvert::Core
45
55
  scope = double
46
56
  block = proc {}
47
57
  expect(Rewriter::WithinScope).to receive(:new)
48
- .with(instance, { type: 'send', message: 'create' }, { recursive: false }, &block)
58
+ .with(instance, { type: 'send', message: 'create' }, { direct: true }, &block)
49
59
  .and_return(scope)
50
60
  expect(scope).to receive(:process)
51
61
  instance.with_direct_node(type: 'send', message: 'create', &block)
@@ -51,6 +51,33 @@ module Synvert::Core
51
51
  expect(type_in_scope).to eq :send
52
52
  expect(instance.current_node.type).to eq :block
53
53
  end
54
+
55
+ it 'matches multiple block nodes' do
56
+ block_nodes = []
57
+ scope = Rewriter::WithinScope.new(instance, { type: 'block' }, { recursive: true }) do
58
+ block_nodes << node
59
+ end
60
+ scope.process
61
+ expect(block_nodes.size).to eq 2
62
+ end
63
+
64
+ it 'matches only one block node if no recursive' do
65
+ block_nodes = []
66
+ scope = Rewriter::WithinScope.new(instance, { type: 'block' } , { recursive: false }) do
67
+ block_nodes << node
68
+ end
69
+ scope.process
70
+ expect(block_nodes.size).to eq 1
71
+ end
72
+
73
+ it 'matches only one direct node' do
74
+ block_nodes = []
75
+ scope = Rewriter::WithinScope.new(instance, { type: 'block' } , { direct: true }) do
76
+ block_nodes << node
77
+ end
78
+ scope.process
79
+ expect(block_nodes.size).to eq 1
80
+ end
54
81
  end
55
82
  end
56
83
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: synvert-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.57.1
4
+ version: 0.58.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Huang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-18 00:00:00.000000000 Z
11
+ date: 2021-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport