synvert-core 1.10.1 → 1.12.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: 966c0db8262c57bb94be47d44c5638c9c9607728da335b4bde9d39c49f7bc665
4
- data.tar.gz: e2be9da04e58da3b236d03006883778f6e202d9bbb5a8fa922dd6339117a6a2a
3
+ metadata.gz: e526dbe6f12418da40df7cb5b945f7ed957820573455b575f2a609c334b58e72
4
+ data.tar.gz: 1f22528b636b548c9ddb05466d366e62dce813794d173c11b8de11ef522b97a8
5
5
  SHA512:
6
- metadata.gz: 1e1f6a8a25817ebe46c03bdbf6e7982f559c426bf5537c2ae28549215ad77a03c45768af6b3f74ba84e34105c6d1e8c9cbb365cb1f431220b59028678c373dcd
7
- data.tar.gz: 44f57f854c537825acb57217b216294f226df391b1eb185fd1558f463084a91ad9fcc296f54eba05c5b66e1d995a40c897d267fff662ff5bf85472d83d993be1
6
+ metadata.gz: 46f29de95717e764a33c0303c20086fb3fc3dcc43c7548c174b4eb46f368e2b0cec6b1ea6ff88eed04654f58cf9dad3066aa679ece8d7a6cfb2a7676095fe4aa
7
+ data.tar.gz: 7622e84c396751bd49b57464424efee84ba3f45d727c5653528fb11a5da7d26e856c0008ea1dc5967e7ee3afe8f238a8dbb6c67bc5071970312523a426a98dd3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.12.0 (2022-10-14)
4
+
5
+ * Condition accepts both nql and rules
6
+ * Make `find_node` as an alias to `within_node`
7
+ * Remove skip files only once
8
+
9
+ ## 1.11.0 (2022-10-11)
10
+
11
+ * Add `Configuration.number_of_workers`
12
+ * Test rewriter in parallel
13
+
3
14
  ## 1.10.1 (2022-10-09)
4
15
 
5
16
  * Do not reset `@options`
data/Gemfile.lock CHANGED
@@ -1,11 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- synvert-core (1.10.1)
4
+ synvert-core (1.12.0)
5
5
  activesupport (< 7.0.0)
6
6
  erubis
7
7
  node_mutation
8
8
  node_query
9
+ parallel
9
10
  parser
10
11
  parser_node_ext
11
12
 
@@ -57,6 +58,7 @@ GEM
57
58
  notiffany (0.1.3)
58
59
  nenv (~> 0.1)
59
60
  shellany (~> 0.0)
61
+ parallel (1.22.1)
60
62
  parser (3.1.2.1)
61
63
  ast (~> 2.4.1)
62
64
  parser_node_ext (0.4.0)
data/README.md CHANGED
@@ -73,16 +73,16 @@ DSLs are as follows
73
73
 
74
74
  Scopes:
75
75
 
76
- * [find_node](./Synvert/Core/Rewriter/Instance.html#find_node-instance_method) - recursively find matching ast nodes by node query language
77
76
  * [within_node](./Synvert/Core/Rewriter/Instance.html#within_node-instance_method) - recursively find matching ast nodes
78
77
  * [with_node](./Synvert/Core/Rewriter/Instance.html#with_node-instance_method) - alias to within_node
78
+ * [find_node](./Synvert/Core/Rewriter/Instance.html#find_node-instance_method) - alias to within_node
79
79
  * [goto_node](./Synvert/Core/Rewriter/Instance.html#goto_node-instance_method) - go to a child node
80
80
 
81
81
  Conditions:
82
82
 
83
83
  * [if_exist_node](./Synvert/Core/Rewriter/Instance.html#if_exist_node-instance_method) - check if matching node exist in the child nodes
84
84
  * [unless_exist_node](./Synvert/Core/Rewriter/Instance.html#unless_exist_node-instance_method) - check if matching node doesn't exist in the child nodes
85
- * [if_only_exist_node](./Synvert/Core/Rewriter/Instance.html#if_only_exist_node-instance_method) - check if current node has only one child node and the child node matches rules
85
+ * [if_only_exist_node](./Synvert/Core/Rewriter/Instance.html#if_only_exist_node-instance_method) - check if current node has only one child node and the child node matches
86
86
 
87
87
  Actions:
88
88
 
@@ -8,7 +8,8 @@ module Synvert::Core
8
8
  # @!attribute [w] skip_paths
9
9
  # @!attribute [w] only_paths
10
10
  # @!attribute [w] show_run_process
11
- attr_writer :root_path, :skip_paths, :only_paths, :show_run_process
11
+ # @!attribute [w] number_of_workers
12
+ attr_writer :root_path, :skip_paths, :only_paths, :show_run_process, :number_of_workers
12
13
 
13
14
  # Get the path.
14
15
  #
@@ -37,6 +38,13 @@ module Synvert::Core
37
38
  def show_run_process
38
39
  @show_run_process || false
39
40
  end
41
+
42
+ # Number of workers
43
+ #
44
+ # @return [Integer] default is 1
45
+ def number_of_workers
46
+ @number_of_workers || 1
47
+ end
40
48
  end
41
49
  end
42
50
  end
@@ -5,7 +5,7 @@ module Synvert::Core
5
5
  class Rewriter::IfExistCondition < Rewriter::Condition
6
6
  private
7
7
 
8
- # check if any child node matches the rules.
8
+ # check if any child node matches.
9
9
  #
10
10
  # @return [Boolean]
11
11
  def match?
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Synvert::Core
4
- # IfOnlyExistCondition checks if node has only one child node and the child node matches rules.
4
+ # IfOnlyExistCondition checks if node has only one child node and the child node matches.
5
5
  class Rewriter::IfOnlyExistCondition < Rewriter::Condition
6
6
  private
7
7
 
8
- # check if only have one child node and the child node matches rules.
8
+ # check if only have one child node and the child node matches.
9
9
  #
10
10
  # @return [Boolean]
11
11
  def match?
@@ -5,7 +5,7 @@ module Synvert::Core
5
5
  class Rewriter::UnlessExistCondition < Rewriter::Condition
6
6
  private
7
7
 
8
- # check if none of child node matches the rules.
8
+ # check if none of child node matches.
9
9
  #
10
10
  # return [Boolean]
11
11
  def match?
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Synvert::Core
4
- # Condition checks if rules matches.
4
+ # Condition checks if nql or rules matches.
5
5
  class Rewriter::Condition
6
6
  # Initialize a Condition.
7
7
  #
8
8
  # @param instance [Synvert::Core::Rewriter::Instance]
9
- # @param rules [Hash]
9
+ # @param nql_or_rules [String|Hash]
10
10
  # @yield run when condition matches
11
- def initialize(instance, rules, &block)
11
+ def initialize(instance, nql_or_rules, &block)
12
12
  @instance = instance
13
- @node_query = NodeQuery.new(rules)
13
+ @node_query = NodeQuery.new(nql_or_rules)
14
14
  @block = block
15
15
  end
16
16
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ require 'parallel'
2
3
 
3
4
  module Synvert::Core
4
5
  # Instance is an execution unit, it finds specified ast nodes,
@@ -41,8 +42,14 @@ module Synvert::Core
41
42
  # It finds specified files, for each file, it executes the block code, tests the original code,
42
43
  # then returns the actions.
43
44
  def test
44
- get_file_paths.map do |file_path|
45
- test_file(file_path)
45
+ if Configuration.number_of_workers > 1
46
+ Parallel.map(get_file_paths, in_processes: Configuration.number_of_workers) do |file_path|
47
+ test_file(file_path)
48
+ end
49
+ else
50
+ get_file_paths.map do |file_path|
51
+ test_file(file_path)
52
+ end
46
53
  end
47
54
  end
48
55
 
@@ -78,38 +85,29 @@ module Synvert::Core
78
85
  # DSL #
79
86
  #######
80
87
 
81
- # Parse +find_node+ dsl, it creates {Synvert::Core::Rewriter::QueryScope} to recursively find matching ast nodes,
82
- # then continue operating on each matching ast node.
83
- # @example
84
- # # matches FactoryBot.create(:user)
85
- # find_node '.send[receiver=FactoryBot][message=create][arguments.size=1]' do
86
- # end
87
- # @param nql [String] node query language to find matching ast nodes.
88
- # @yield run on the matching nodes.
89
- # @raise [Synvert::Core::NodeQuery::Compiler::ParseError] if query string is invalid.
90
- def find_node(nql, options = {}, &block)
91
- Rewriter::QueryScope.new(self, nql, options, &block).process
92
- rescue NodeQueryLexer::ScanError, Racc::ParseError => e
93
- raise NodeQuery::Compiler::ParseError, "Invalid query string: #{nql}"
94
- end
95
-
96
88
  # Parse +within_node+ dsl, it creates a {Synvert::Core::Rewriter::WithinScope} to recursively find matching ast nodes,
97
89
  # then continue operating on each matching ast node.
98
90
  # @example
99
91
  # # matches User.find_by_login('test')
100
92
  # with_node type: 'send', message: /^find_by_/ do
101
93
  # end
102
- # @param rules [Hash] rules to find mathing ast nodes.
94
+ # # matches FactoryBot.create(:user)
95
+ # with_node '.send[receiver=FactoryBot][message=create][arguments.size=1]' do
96
+ # end
97
+ # @param nql_or_rules [String|Hash] nql or rules to find mathing ast nodes.
103
98
  # @param options [Hash] optional
104
99
  # @option including_self [Boolean] set if query the current node, default is true
105
100
  # @option stop_at_first_match [Boolean] set if stop at first match, default is false
106
101
  # @option recursive [Boolean] set if recursively query child nodes, default is true
107
102
  # @yield run on the matching nodes.
108
- def within_node(rules, options = {}, &block)
109
- Rewriter::WithinScope.new(self, rules, options, &block).process
103
+ def within_node(nql_or_rules, options = {}, &block)
104
+ Rewriter::WithinScope.new(self, nql_or_rules, options, &block).process
105
+ rescue NodeQueryLexer::ScanError, Racc::ParseError => e
106
+ raise NodeQuery::Compiler::ParseError, "Invalid query string: #{nql_or_rules}"
110
107
  end
111
108
 
112
109
  alias with_node within_node
110
+ alias find_node within_node
113
111
 
114
112
  # Parse +goto_node+ dsl, it creates a {Synvert::Core::Rewriter::GotoScope} to go to a child node,
115
113
  # then continue operating on the child node.
@@ -133,10 +131,10 @@ module Synvert::Core
133
131
  # if_exist_node type: 'send', message: 'any_instance' do
134
132
  # end
135
133
  # end
136
- # @param rules [Hash] rules to check mathing ast nodes.
134
+ # @param nql_or_rules [String|Hash] nql or rules to check mathing ast nodes.
137
135
  # @param block [Block] block code to continue operating on the matching nodes.
138
- def if_exist_node(rules, &block)
139
- Rewriter::IfExistCondition.new(self, rules, &block).process
136
+ def if_exist_node(nql_or_rules, &block)
137
+ Rewriter::IfExistCondition.new(self, nql_or_rules, &block).process
140
138
  end
141
139
 
142
140
  # Parse +unless_exist_node+ dsl, it creates a {Synvert::Core::Rewriter::UnlessExistCondition} to check
@@ -147,14 +145,14 @@ module Synvert::Core
147
145
  # unless_exist_node type: 'send', message: 'any_instance' do
148
146
  # end
149
147
  # end
150
- # @param rules [Hash] rules to check mathing ast nodes.
148
+ # @param nql_or_rules [String|Hash] nql or rules to check mathing ast nodes.
151
149
  # @param block [Block] block code to continue operating on the matching nodes.
152
- def unless_exist_node(rules, &block)
153
- Rewriter::UnlessExistCondition.new(self, rules, &block).process
150
+ def unless_exist_node(nql_or_rules, &block)
151
+ Rewriter::UnlessExistCondition.new(self, nql_or_rules, &block).process
154
152
  end
155
153
 
156
154
  # Parse +if_only_exist_node+ dsl, it creates a {Synvert::Core::Rewriter::IfOnlyExistCondition} to check
157
- # if current node has only one child node and the child node matches rules,
155
+ # if current node has only one child node and the child node matches,
158
156
  # if so, then continue operating on each matching ast node.
159
157
  # @example
160
158
  # # it { should matcher }
@@ -162,10 +160,10 @@ module Synvert::Core
162
160
  # if_only_exist_node type: 'send', receiver: nil, message: 'should' do
163
161
  # end
164
162
  # end
165
- # @param rules [Hash] rules to check mathing ast nodes.
163
+ # @param nql_or_rules [String|Hash] nql or rules to check mathing ast nodes.
166
164
  # @param block [Block] block code to continue operating on the matching nodes.
167
- def if_only_exist_node(rules, &block)
168
- Rewriter::IfOnlyExistCondition.new(self, rules, &block).process
165
+ def if_only_exist_node(nql_or_rules, &block)
166
+ Rewriter::IfOnlyExistCondition.new(self, nql_or_rules, &block).process
169
167
  end
170
168
 
171
169
  # Parse +append+ dsl, it creates a {Synvert::Core::Rewriter::AppendAction} to
@@ -427,16 +425,16 @@ module Synvert::Core
427
425
  only_paths.flat_map do |only_path|
428
426
  @file_patterns.flat_map do |file_pattern|
429
427
  pattern = only_path == "." ? file_pattern : File.join(only_path, file_pattern)
430
- Dir.glob(pattern) - get_skip_files
428
+ Dir.glob(pattern)
431
429
  end
432
- end
430
+ end - get_skip_files
433
431
  end
434
432
  end
435
433
 
436
434
  # Get skip files.
437
435
  # @return [Array<String>] skip files
438
436
  def get_skip_files
439
- @skip_files ||= Configuration.skip_paths.flat_map do |skip_path|
437
+ Configuration.skip_paths.flat_map do |skip_path|
440
438
  if File.directory?(skip_path)
441
439
  Dir.glob(File.join(skip_path, "**/*"))
442
440
  elsif File.file?(skip_path)
@@ -1,22 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Synvert::Core
4
- # WithinScope finds out nodes which match rules, then changes its scope to matching node.
4
+ # WithinScope finds out nodes which match nql or rules, then changes its scope to matching node.
5
5
  class Rewriter::WithinScope < Rewriter::Scope
6
6
  # Initialize a WithinScope.
7
7
  #
8
8
  # @param instance [Synvert::Core::Rewriter::Instance]
9
- # @param rules [Hash]
9
+ # @param nql_or_rules [String|Hash]
10
10
  # @param options [Hash]
11
11
  # @yield run on all matching nodes
12
- def initialize(instance, rules, options = {}, &block)
12
+ # @raise [Synvert::Core::NodeQuery::Compiler::ParseError] if the query string is invalid.
13
+ def initialize(instance, nql_or_rules, options = {}, &block)
13
14
  super(instance, &block)
14
15
 
15
16
  @options = { including_self: true, stop_at_first_match: false, recursive: true }.merge(options)
16
- @node_query = NodeQuery.new(rules)
17
+ @node_query = NodeQuery.new(nql_or_rules)
17
18
  end
18
19
 
19
20
  # Find out the matching nodes.
21
+ #
20
22
  # It checks the current node and iterates all child nodes,
21
23
  # then run the block code on each matching node.
22
24
  def process
@@ -17,7 +17,6 @@ module Synvert::Core
17
17
  autoload :Instance, 'synvert/core/rewriter/instance'
18
18
 
19
19
  autoload :Scope, 'synvert/core/rewriter/scope'
20
- autoload :QueryScope, 'synvert/core/rewriter/scope/query_scope'
21
20
  autoload :WithinScope, 'synvert/core/rewriter/scope/within_scope'
22
21
  autoload :GotoScope, 'synvert/core/rewriter/scope/goto_scope'
23
22
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Synvert
4
4
  module Core
5
- VERSION = '1.10.1'
5
+ VERSION = '1.12.0'
6
6
  end
7
7
  end
@@ -12,7 +12,7 @@ module Synvert::Core
12
12
  it 'parses find_node' do
13
13
  scope = double
14
14
  block = proc {}
15
- expect(Rewriter::QueryScope).to receive(:new).with(instance, '.send[message=create]', {}, &block).and_return(scope)
15
+ expect(Rewriter::WithinScope).to receive(:new).with(instance, '.send[message=create]', {}, &block).and_return(scope)
16
16
  expect(scope).to receive(:process)
17
17
  instance.find_node('.send[message=create]', &block)
18
18
  end
@@ -23,72 +23,117 @@ module Synvert::Core
23
23
  before { instance.current_node = node }
24
24
 
25
25
  describe '#process' do
26
- it 'not call block if no matching node' do
27
- run = false
28
- scope =
29
- Rewriter::WithinScope.new instance, type: 'send', message: 'missing' do
30
- run = true
31
- end
32
- scope.process
33
- expect(run).to be_falsey
34
- end
26
+ context 'rules' do
27
+ it 'not call block if no matching node' do
28
+ run = false
29
+ scope =
30
+ Rewriter::WithinScope.new instance, type: 'send', message: 'missing' do
31
+ run = true
32
+ end
33
+ scope.process
34
+ expect(run).to be_falsey
35
+ end
35
36
 
36
- it 'call block if there is matching node' do
37
- run = false
38
- type_in_scope = nil
39
- scope =
40
- Rewriter::WithinScope.new instance,
41
- type: 'send',
42
- receiver: 'FactoryGirl',
43
- message: 'create',
44
- arguments: [':user'] do
45
- run = true
46
- type_in_scope = node.type
47
- end
48
- scope.process
49
- expect(run).to be_truthy
50
- expect(type_in_scope).to eq :send
51
- expect(instance.current_node.type).to eq :block
52
- end
37
+ it 'call block if there is matching node' do
38
+ run = false
39
+ type_in_scope = nil
40
+ scope =
41
+ Rewriter::WithinScope.new instance,
42
+ type: 'send',
43
+ receiver: 'FactoryGirl',
44
+ message: 'create',
45
+ arguments: [':user'] do
46
+ run = true
47
+ type_in_scope = node.type
48
+ end
49
+ scope.process
50
+ expect(run).to be_truthy
51
+ expect(type_in_scope).to eq :send
52
+ expect(instance.current_node.type).to eq :block
53
+ end
53
54
 
54
- it 'matches multiple block nodes' do
55
- block_nodes = []
56
- scope =
57
- Rewriter::WithinScope.new(instance, { type: 'block' }) do
58
- block_nodes << node
59
- end
60
- scope.process
61
- expect(block_nodes.size).to eq 3
62
- end
55
+ it 'matches multiple block nodes' do
56
+ block_nodes = []
57
+ scope =
58
+ Rewriter::WithinScope.new(instance, { type: 'block' }) do
59
+ block_nodes << node
60
+ end
61
+ scope.process
62
+ expect(block_nodes.size).to eq 3
63
+ end
63
64
 
64
- it 'matches only 2 block nodes if including_self is false' do
65
- block_nodes = []
66
- scope =
67
- Rewriter::WithinScope.new(instance, { type: 'block' }, { including_self: false }) do
68
- block_nodes << node
69
- end
70
- scope.process
71
- expect(block_nodes.size).to eq 2
72
- end
65
+ it 'matches only 2 block nodes if including_self is false' do
66
+ block_nodes = []
67
+ scope =
68
+ Rewriter::WithinScope.new(instance, { type: 'block' }, { including_self: false }) do
69
+ block_nodes << node
70
+ end
71
+ scope.process
72
+ expect(block_nodes.size).to eq 2
73
+ end
73
74
 
74
- it 'matches only one block node if recursive is false' do
75
- block_nodes = []
76
- scope =
77
- Rewriter::WithinScope.new(instance, { type: 'block' }, { recursive: false }) do
78
- block_nodes << node
79
- end
80
- scope.process
81
- expect(block_nodes.size).to eq 1
75
+ it 'matches only one block node if recursive is false' do
76
+ block_nodes = []
77
+ scope =
78
+ Rewriter::WithinScope.new(instance, { type: 'block' }, { recursive: false }) do
79
+ block_nodes << node
80
+ end
81
+ scope.process
82
+ expect(block_nodes.size).to eq 1
83
+ end
84
+
85
+ it 'matches only one block node if stop_at_first_match is true' do
86
+ block_nodes = []
87
+ scope =
88
+ Rewriter::WithinScope.new(instance, { type: 'block' }, { stop_at_first_match: true }) do
89
+ block_nodes << node
90
+ end
91
+ scope.process
92
+ expect(block_nodes.size).to eq 1
93
+ end
82
94
  end
83
95
 
84
- it 'matches only one block node if stop_at_first_match is true' do
85
- block_nodes = []
86
- scope =
87
- Rewriter::WithinScope.new(instance, { type: 'block' }, { stop_at_first_match: true }) do
88
- block_nodes << node
89
- end
90
- scope.process
91
- expect(block_nodes.size).to eq 1
96
+ context 'nql' do
97
+ it 'not call block if no matching node' do
98
+ run = false
99
+ scope =
100
+ described_class.new instance, '.send[message=missing]' do
101
+ run = true
102
+ end
103
+ scope.process
104
+ expect(run).to be_falsey
105
+ end
106
+
107
+ it 'call block if there is matching node' do
108
+ run = false
109
+ type_in_scope = nil
110
+ scope =
111
+ described_class.new instance, '.send[receiver=FactoryGirl][message=create][arguments=(:user)]' do
112
+ run = true
113
+ type_in_scope = node.type
114
+ end
115
+ scope.process
116
+ expect(run).to be_truthy
117
+ expect(type_in_scope).to eq :send
118
+ expect(instance.current_node.type).to eq :block
119
+ end
120
+
121
+ it 'matches multiple block nodes' do
122
+ block_nodes = []
123
+ scope =
124
+ described_class.new(instance, '.block') do
125
+ block_nodes << node
126
+ end
127
+ scope.process
128
+ expect(block_nodes.size).to eq 3
129
+ end
130
+
131
+ it 'raises InvalidOperatorError' do
132
+ scope = described_class.new(instance, '.send[receiver IN FactoryGirl]') {}
133
+ expect {
134
+ scope.process
135
+ }.to raise_error(NodeQuery::Compiler::InvalidOperatorError)
136
+ end
92
137
  end
93
138
  end
94
139
  end
@@ -25,4 +25,5 @@ Gem::Specification.new do |spec|
25
25
  spec.add_runtime_dependency "node_mutation"
26
26
  spec.add_runtime_dependency "parser"
27
27
  spec.add_runtime_dependency "parser_node_ext"
28
+ spec.add_runtime_dependency "parallel"
28
29
  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: 1.10.1
4
+ version: 1.12.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: 2022-10-09 00:00:00.000000000 Z
11
+ date: 2022-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: parallel
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  description: convert ruby code to better syntax automatically.
98
112
  email:
99
113
  - flyerhzm@gmail.com
@@ -130,7 +144,6 @@ files:
130
144
  - lib/synvert/core/rewriter/ruby_version.rb
131
145
  - lib/synvert/core/rewriter/scope.rb
132
146
  - lib/synvert/core/rewriter/scope/goto_scope.rb
133
- - lib/synvert/core/rewriter/scope/query_scope.rb
134
147
  - lib/synvert/core/rewriter/scope/within_scope.rb
135
148
  - lib/synvert/core/rewriter/warning.rb
136
149
  - lib/synvert/core/utils.rb
@@ -149,7 +162,6 @@ files:
149
162
  - spec/synvert/core/rewriter/instance_spec.rb
150
163
  - spec/synvert/core/rewriter/ruby_version_spec.rb
151
164
  - spec/synvert/core/rewriter/scope/goto_scope_spec.rb
152
- - spec/synvert/core/rewriter/scope/query_scope_spec.rb
153
165
  - spec/synvert/core/rewriter/scope/within_scope_spec.rb
154
166
  - spec/synvert/core/rewriter/scope_spec.rb
155
167
  - spec/synvert/core/rewriter/warning_spec.rb
@@ -194,7 +206,6 @@ test_files:
194
206
  - spec/synvert/core/rewriter/instance_spec.rb
195
207
  - spec/synvert/core/rewriter/ruby_version_spec.rb
196
208
  - spec/synvert/core/rewriter/scope/goto_scope_spec.rb
197
- - spec/synvert/core/rewriter/scope/query_scope_spec.rb
198
209
  - spec/synvert/core/rewriter/scope/within_scope_spec.rb
199
210
  - spec/synvert/core/rewriter/scope_spec.rb
200
211
  - spec/synvert/core/rewriter/warning_spec.rb
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Synvert::Core
4
- # QueryScope finds out nodes by using node query language, then changes its scope to matching node.
5
- class Rewriter::QueryScope < Rewriter::Scope
6
- # Initialize a QueryScope.
7
- #
8
- # @param instance [Synvert::Core::Rewriter::Instance]
9
- # @param nql [String]
10
- # @param options [Hash]
11
- # @yield run on all matching nodes
12
- def initialize(instance, nql, options = {}, &block)
13
- super(instance, &block)
14
-
15
- @options = { including_self: true, stop_at_first_match: false, recursive: true }.merge(options)
16
- @node_query = NodeQuery.new(nql)
17
- end
18
-
19
- # Find out the matching nodes.
20
- #
21
- # It checks the current node and iterates all child nodes,
22
- # then run the block code on each matching node.
23
- # @raise [Synvert::Core::NodeQuery::Compiler::ParseError] if the query string is invalid.
24
- def process
25
- current_node = @instance.current_node
26
- return unless current_node
27
-
28
- matching_nodes = @node_query.query_nodes(current_node, @options)
29
- @instance.process_with_node(current_node) do
30
- matching_nodes.each do |node|
31
- @instance.process_with_node(node) do
32
- @instance.instance_eval(&@block)
33
- end
34
- end
35
- end
36
- end
37
- end
38
- end
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- module Synvert::Core
6
- describe Rewriter::QueryScope do
7
- let(:instance) {
8
- rewriter = Rewriter.new('foo', 'bar')
9
- Rewriter::Instance.new(rewriter, 'file pattern')
10
- }
11
- let(:source) { <<~EOS }
12
- describe Post do
13
- it 'gets post' do
14
- FactoryGirl.create :post
15
- end
16
- end
17
- EOS
18
-
19
- let(:node) { Parser::CurrentRuby.parse(source) }
20
-
21
- before { instance.current_node = node }
22
-
23
- describe '#process' do
24
- it 'not call block if no matching node' do
25
- run = false
26
- scope =
27
- described_class.new instance, '.send[message=missing]' do
28
- run = true
29
- end
30
- scope.process
31
- expect(run).to be_falsey
32
- end
33
-
34
- it 'call block if there is matching node' do
35
- run = false
36
- type_in_scope = nil
37
- scope =
38
- described_class.new instance, '.send[receiver=FactoryGirl][message=create][arguments=(:post)]' do
39
- run = true
40
- type_in_scope = node.type
41
- end
42
- scope.process
43
- expect(run).to be_truthy
44
- expect(type_in_scope).to eq :send
45
- expect(instance.current_node.type).to eq :block
46
- end
47
-
48
- it 'matches multiple block nodes' do
49
- block_nodes = []
50
- scope =
51
- described_class.new(instance, '.block') do
52
- block_nodes << node
53
- end
54
- scope.process
55
- expect(block_nodes.size).to eq 2
56
- end
57
-
58
- it 'raises InvalidOperatorError' do
59
- scope = described_class.new(instance, '.send[receiver IN FactoryGirl]') {}
60
- expect {
61
- scope.process
62
- }.to raise_error(NodeQuery::Compiler::InvalidOperatorError)
63
- end
64
- end
65
- end
66
- end