synvert-core 0.64.0 → 1.0.1

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +1 -1
  3. data/.gitignore +4 -0
  4. data/CHANGELOG.md +5 -0
  5. data/Guardfile +11 -2
  6. data/README.md +2 -2
  7. data/Rakefile +15 -1
  8. data/lib/synvert/core/array_ext.rb +41 -0
  9. data/lib/synvert/core/engine/erb.rb +9 -8
  10. data/lib/synvert/core/node_ext.rb +47 -44
  11. data/lib/synvert/core/node_query/compiler/array.rb +34 -0
  12. data/lib/synvert/core/node_query/compiler/attribute.rb +51 -0
  13. data/lib/synvert/core/node_query/compiler/attribute_list.rb +24 -0
  14. data/lib/synvert/core/node_query/compiler/boolean.rb +23 -0
  15. data/lib/synvert/core/node_query/compiler/comparable.rb +79 -0
  16. data/lib/synvert/core/node_query/compiler/dynamic_attribute.rb +51 -0
  17. data/lib/synvert/core/node_query/compiler/expression.rb +88 -0
  18. data/lib/synvert/core/node_query/compiler/float.rb +23 -0
  19. data/lib/synvert/core/node_query/compiler/identifier.rb +41 -0
  20. data/lib/synvert/core/node_query/compiler/integer.rb +23 -0
  21. data/lib/synvert/core/node_query/compiler/invalid_operator_error.rb +7 -0
  22. data/lib/synvert/core/node_query/compiler/nil.rb +23 -0
  23. data/lib/synvert/core/node_query/compiler/parse_error.rb +7 -0
  24. data/lib/synvert/core/node_query/compiler/regexp.rb +37 -0
  25. data/lib/synvert/core/node_query/compiler/selector.rb +51 -0
  26. data/lib/synvert/core/node_query/compiler/string.rb +34 -0
  27. data/lib/synvert/core/node_query/compiler/symbol.rb +23 -0
  28. data/lib/synvert/core/node_query/compiler.rb +24 -0
  29. data/lib/synvert/core/node_query/lexer.rex +96 -0
  30. data/lib/synvert/core/node_query/lexer.rex.rb +293 -0
  31. data/lib/synvert/core/node_query/parser.racc.rb +518 -0
  32. data/lib/synvert/core/node_query/parser.y +84 -0
  33. data/lib/synvert/core/node_query.rb +36 -0
  34. data/lib/synvert/core/rewriter/action/delete_action.rb +4 -2
  35. data/lib/synvert/core/rewriter/action/replace_action.rb +4 -2
  36. data/lib/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action.rb +2 -2
  37. data/lib/synvert/core/rewriter/action/wrap_action.rb +3 -2
  38. data/lib/synvert/core/rewriter/action.rb +2 -1
  39. data/lib/synvert/core/rewriter/helper.rb +5 -2
  40. data/lib/synvert/core/rewriter/instance.rb +25 -13
  41. data/lib/synvert/core/rewriter/scope/query_scope.rb +36 -0
  42. data/lib/synvert/core/rewriter/scope/within_scope.rb +1 -1
  43. data/lib/synvert/core/rewriter.rb +1 -0
  44. data/lib/synvert/core/version.rb +1 -1
  45. data/lib/synvert/core.rb +22 -5
  46. data/spec/synvert/core/engine/erb_spec.rb +2 -2
  47. data/spec/synvert/core/node_ext_spec.rb +36 -5
  48. data/spec/synvert/core/node_query/lexer_spec.rb +512 -0
  49. data/spec/synvert/core/node_query/parser_spec.rb +270 -0
  50. data/spec/synvert/core/rewriter/condition/if_only_exist_condition_spec.rb +1 -6
  51. data/spec/synvert/core/rewriter/helper_spec.rb +4 -1
  52. data/spec/synvert/core/rewriter/instance_spec.rb +24 -3
  53. data/spec/synvert/core/rewriter/scope/query_scope_spec.rb +74 -0
  54. data/spec/synvert/core/rewriter/scope/within_scope_spec.rb +12 -9
  55. data/spec/synvert/core/rewriter_spec.rb +4 -2
  56. data/synvert-core-ruby.gemspec +5 -1
  57. metadata +75 -2
@@ -0,0 +1,270 @@
1
+ require 'spec_helper'
2
+
3
+ module Synvert::Core::NodeQuery
4
+ RSpec.describe Parser do
5
+ let(:parser) { described_class.new }
6
+
7
+ def assert_parser(source)
8
+ expect(parser.parse(source).to_s).to eq source
9
+ end
10
+
11
+ it 'parses one selector' do
12
+ source = '.send[message=:create]'
13
+ assert_parser(source)
14
+ end
15
+
16
+ it 'parses two selectors' do
17
+ source = '.class[name=Synvert] .def[name="foobar"]'
18
+ assert_parser(source)
19
+ end
20
+
21
+ it 'parses three selectors' do
22
+ source = '.class[name=Synvert] .def[name="foobar"] .send[message=create]'
23
+ assert_parser(source)
24
+ end
25
+
26
+ it 'parses child selector' do
27
+ source = '.class[name=Synvert] > .def[name="foobar"]'
28
+ assert_parser(source)
29
+ end
30
+
31
+ it 'parses :first-child' do
32
+ source = '.class .def:first-child'
33
+ assert_parser(source)
34
+ end
35
+
36
+ it 'parses :last-child' do
37
+ source = '.class .def:last-child'
38
+ assert_parser(source)
39
+ end
40
+
41
+ it 'parses :nth-child(n)' do
42
+ source = '.class .def:nth-child(2)'
43
+ assert_parser(source)
44
+ end
45
+
46
+ it 'parses :nth-last-child(n)' do
47
+ source = '.class .def:nth-last-child(2)'
48
+ assert_parser(source)
49
+ end
50
+
51
+ it 'parses :has selector' do
52
+ source = '.class:has(> .def)'
53
+ assert_parser(source)
54
+ end
55
+
56
+ it 'parses multiple attributes' do
57
+ source = '.send[receiver=nil][message=:create]'
58
+ assert_parser(source)
59
+ end
60
+
61
+ it 'parses nested attributes' do
62
+ source = '.send[receiver.message=:create]'
63
+ assert_parser(source)
64
+ end
65
+
66
+ it 'parses selector value' do
67
+ source = '.send[receiver=.send[message=:create]]'
68
+ assert_parser(source)
69
+ end
70
+
71
+ it 'parses not equal operator' do
72
+ source = '.send[receiver=.send[message!=:create]]'
73
+ assert_parser(source)
74
+ end
75
+
76
+ it 'parses greater than operator' do
77
+ source = '.send[receiver=.send[arguments.size>1]]'
78
+ assert_parser(source)
79
+ end
80
+
81
+ it 'parses greater than or equal operator' do
82
+ source = '.send[receiver=.send[arguments.size>=1]]'
83
+ assert_parser(source)
84
+ end
85
+
86
+ it 'parses less than operator' do
87
+ source = '.send[receiver=.send[arguments.size<1]]'
88
+ assert_parser(source)
89
+ end
90
+
91
+ it 'parses less than or equal operator' do
92
+ source = '.send[receiver=.send[arguments.size<=1]]'
93
+ assert_parser(source)
94
+ end
95
+
96
+ it 'parses in operator' do
97
+ source = '.def[name in (foo, bar)]'
98
+ assert_parser(source)
99
+ end
100
+
101
+ it 'parses not_in operator' do
102
+ source = '.def[name not in (foo, bar)]'
103
+ assert_parser(source)
104
+ end
105
+
106
+ it 'parses includes operator' do
107
+ source = '.def[arguments includes &block]'
108
+ assert_parser(source)
109
+ end
110
+
111
+ describe '#query_nodes' do
112
+ let(:node) {
113
+ parse(<<~EOS)
114
+ class Synvert
115
+ def foo
116
+ FactoryBot.create(:user, name: 'foo')
117
+ end
118
+
119
+ def bar
120
+ FactoryBot.create(:user, name: 'bar')
121
+ end
122
+
123
+ def foobar(a, b)
124
+ { a: a, b: b }
125
+ foo.merge(bar)
126
+ arr[index]
127
+ end
128
+ end
129
+ EOS
130
+ }
131
+
132
+ it 'matches class node' do
133
+ expression = parser.parse('.class[name=Synvert]')
134
+ expect(expression.query_nodes(node)).to eq [node]
135
+ end
136
+
137
+ it 'matches def node' do
138
+ expression = parser.parse('.def')
139
+ expect(expression.query_nodes(node)).to eq node.body
140
+ end
141
+
142
+ it 'matches first def node' do
143
+ expression = parser.parse('.def:first-child')
144
+ expect(expression.query_nodes(node)).to eq [node.body.first]
145
+ end
146
+
147
+ it 'matches nested first node' do
148
+ expression = parser.parse('.def[arguments.size=0] .send:first-child')
149
+ expect(expression.query_nodes(node)).to eq [node.body.first.body.first, node.body.second.body.first]
150
+ end
151
+
152
+ it 'matches last def node' do
153
+ expression = parser.parse('.def:last-child')
154
+ expect(expression.query_nodes(node)).to eq [node.body.last]
155
+ end
156
+
157
+ it 'matches nth-child node' do
158
+ expression = parser.parse('.def:nth-child(2)')
159
+ expect(expression.query_nodes(node)).to eq [node.body.second]
160
+ end
161
+
162
+ it 'matches nth-last-child node' do
163
+ expression = parser.parse('.def:nth-last-child(2)')
164
+ expect(expression.query_nodes(node)).to eq [node.body[-2]]
165
+ end
166
+
167
+ it 'matches not equal' do
168
+ expression = parser.parse('.def[name!=foobar]')
169
+ expect(expression.query_nodes(node)).to eq [node.body.first, node.body.second]
170
+ end
171
+
172
+ it 'matches in' do
173
+ expression = parser.parse('.def[name IN (foo, bar)]')
174
+ expect(expression.query_nodes(node)).to eq [node.body.first, node.body.second]
175
+ end
176
+
177
+ it 'matches not in' do
178
+ expression = parser.parse('.def[name NOT IN (foo, bar)]')
179
+ expect(expression.query_nodes(node)).to eq [node.body.last]
180
+ end
181
+
182
+ it 'matches includes' do
183
+ expression = parser.parse('.def[arguments INCLUDES a]')
184
+ expect(expression.query_nodes(node)).to eq [node.body.last]
185
+ end
186
+
187
+ it 'matches equal array' do
188
+ expression = parser.parse('.def[arguments=(a, b)]')
189
+ expect(expression.query_nodes(node)).to eq [node.body.last]
190
+
191
+ expression = parser.parse('.def[arguments=(b, a)]')
192
+ expect(expression.query_nodes(node)).to eq []
193
+ end
194
+
195
+ it 'matches not equal array' do
196
+ expression = parser.parse('.def[arguments!=(a, b)]')
197
+ expect(expression.query_nodes(node)).to eq [node.body.first, node.body.second]
198
+
199
+ expression = parser.parse('.def[arguments!=(b, a)]')
200
+ expect(expression.query_nodes(node)).to eq [node.body.first, node.body.second, node.body.last]
201
+ end
202
+
203
+ it 'matches descendant node' do
204
+ expression = parser.parse('.class .send[message=:create]')
205
+ expect(expression.query_nodes(node)).to eq [node.body.first.children.last, node.body.second.children.last]
206
+ end
207
+
208
+ it 'matches three level descendant node' do
209
+ expression = parser.parse('.class .def .send[message=:create]')
210
+ expect(expression.query_nodes(node)).to eq [node.body.first.children.last, node.body.second.children.last]
211
+ end
212
+
213
+ it 'matches child node' do
214
+ expression = parser.parse('.def > .send[message=:create]')
215
+ expect(expression.query_nodes(node)).to eq [node.body.first.children.last, node.body.second.children.last]
216
+ end
217
+
218
+ it 'matches next sibling node' do
219
+ expression = parser.parse('.def[name=foo] + .def[name=bar]')
220
+ expect(expression.query_nodes(node)).to eq [node.body.second]
221
+ end
222
+
223
+ it 'matches sebsequent sibling node' do
224
+ expression = parser.parse('.def[name=foo] ~ .def[name=foobar]')
225
+ expect(expression.query_nodes(node)).to eq [node.body.last]
226
+ end
227
+
228
+ it 'matches has selector' do
229
+ expression = parser.parse('.def:has(> .send[receiver=FactoryBot])')
230
+ expect(expression.query_nodes(node)).to eq [node.body.first, node.body.second]
231
+ end
232
+
233
+ it 'matches arguments.size' do
234
+ expression = parser.parse('.send[arguments.size=2]')
235
+ expect(expression.query_nodes(node)).to eq [node.body.first.children.last, node.body.second.children.last]
236
+ expression = parser.parse('.send[arguments.size>2]')
237
+ expect(expression.query_nodes(node)).to eq []
238
+ expression = parser.parse('.send[arguments.size>=2]')
239
+ expect(expression.query_nodes(node)).to eq [node.body.first.children.last, node.body.second.children.last]
240
+ end
241
+
242
+ it 'matches arguments' do
243
+ expression = parser.parse('.send[arguments=[size=2][first=.sym][last=.hash]]')
244
+ expect(expression.query_nodes(node)).to eq [node.body.first.children.last, node.body.second.children.last]
245
+ end
246
+
247
+ it 'matches regexp value' do
248
+ expression = parser.parse('.def[name=~/foo/]')
249
+ expect(expression.query_nodes(node)).to eq [node.body.first, node.body.last]
250
+ expression = parser.parse('.def[name!~/bar/]')
251
+ expect(expression.query_nodes(node)).to eq [node.body.first]
252
+ end
253
+
254
+ it 'matches attribute value' do
255
+ expression = parser.parse('.pair[key={{value}}]')
256
+ expect(expression.query_nodes(node)).to eq node.body.last.body.first.children
257
+ end
258
+
259
+ it 'matches identifier' do
260
+ expression = parser.parse('.send[receiver=foo][message=merge]')
261
+ expect(expression.query_nodes(node)).to eq [node.body.last.body.second]
262
+ end
263
+
264
+ it 'matches []' do
265
+ expression = parser.parse('.send[message="[]"]')
266
+ expect(expression.query_nodes(node)).to eq [node.body.last.body.third]
267
+ end
268
+ end
269
+ end
270
+ end
@@ -17,12 +17,7 @@ module Synvert::Core
17
17
 
18
18
  describe '#process' do
19
19
  it 'gets matching nodes' do
20
- source =
21
- '
22
- RSpec.configure do |config|
23
- config.include EmailSpec::Helpers
24
- end
25
- '
20
+ source = ' RSpec.configure do |config| config.include EmailSpec::Helpers end '
26
21
  node = Parser::CurrentRuby.parse(source)
27
22
  instance = double(current_node: node)
28
23
  run = false
@@ -4,7 +4,10 @@ require 'spec_helper'
4
4
 
5
5
  module Synvert::Core
6
6
  describe Rewriter::Helper do
7
- let(:dummy_instance) { Class.new { include Rewriter::Helper }.new }
7
+ let(:dummy_instance) {
8
+ Class.new { include Rewriter::Helper }
9
+ .new
10
+ }
8
11
  let(:instance) do
9
12
  rewriter = Rewriter.new('foo', 'bar')
10
13
  Rewriter::Instance.new rewriter, 'spec/**/*_spec.rb' do
@@ -11,6 +11,14 @@ module Synvert::Core
11
11
  Rewriter::Instance.new(rewriter, ['file pattern'])
12
12
  }
13
13
 
14
+ it 'parses find_node' do
15
+ scope = double
16
+ block = proc {}
17
+ expect(Rewriter::QueryScope).to receive(:new).with(instance, '.send[message=create]', &block).and_return(scope)
18
+ expect(scope).to receive(:process)
19
+ instance.find_node('.send[message=create]', &block)
20
+ end
21
+
14
22
  it 'parses within_node' do
15
23
  scope = double
16
24
  block = proc {}
@@ -91,7 +99,10 @@ module Synvert::Core
91
99
 
92
100
  it 'parses append' do
93
101
  action = double
94
- expect(Rewriter::AppendAction).to receive(:new).with(instance, 'include FactoryGirl::Syntax::Methods').and_return(action)
102
+ expect(Rewriter::AppendAction).to receive(:new).with(
103
+ instance,
104
+ 'include FactoryGirl::Syntax::Methods'
105
+ ).and_return(action)
95
106
  expect(action).to receive(:process)
96
107
  instance.append 'include FactoryGirl::Syntax::Methods'
97
108
  end
@@ -108,14 +119,24 @@ module Synvert::Core
108
119
 
109
120
  it 'parses insert at end' do
110
121
  action = double
111
- expect(Rewriter::InsertAction).to receive(:new).with(instance, '.first', at: 'end', to: 'receiver').and_return(action)
122
+ expect(Rewriter::InsertAction).to receive(:new).with(
123
+ instance,
124
+ '.first',
125
+ at: 'end',
126
+ to: 'receiver'
127
+ ).and_return(action)
112
128
  expect(action).to receive(:process)
113
129
  instance.insert '.first', to: 'receiver'
114
130
  end
115
131
 
116
132
  it 'parses insert at beginning' do
117
133
  action = double
118
- expect(Rewriter::InsertAction).to receive(:new).with(instance, 'URI.', at: 'beginning', to: nil).and_return(action)
134
+ expect(Rewriter::InsertAction).to receive(:new).with(
135
+ instance,
136
+ 'URI.',
137
+ at: 'beginning',
138
+ to: nil
139
+ ).and_return(action)
119
140
  expect(action).to receive(:process)
120
141
  instance.insert 'URI.', at: 'beginning'
121
142
  end
@@ -0,0 +1,74 @@
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 do
22
+ Rewriter::Instance.reset
23
+ instance.current_node = node
24
+ end
25
+
26
+ describe '#process' do
27
+ it 'not call block if no matching node' do
28
+ run = false
29
+ scope =
30
+ described_class.new instance, '.send[message=missing]' do
31
+ run = true
32
+ end
33
+ scope.process
34
+ expect(run).to be_falsey
35
+ end
36
+
37
+ it 'call block if there is matching node' do
38
+ run = false
39
+ type_in_scope = nil
40
+ scope =
41
+ described_class.new instance, '.send[receiver=FactoryGirl][message=create][arguments=(:post)]' do
42
+ run = true
43
+ type_in_scope = node.type
44
+ end
45
+ scope.process
46
+ expect(run).to be_truthy
47
+ expect(type_in_scope).to eq :send
48
+ expect(instance.current_node.type).to eq :block
49
+ end
50
+
51
+ it 'matches multiple block nodes' do
52
+ block_nodes = []
53
+ scope =
54
+ described_class.new(instance, '.block') do
55
+ block_nodes << node
56
+ end
57
+ scope.process
58
+ expect(block_nodes.size).to eq 2
59
+ end
60
+
61
+ it 'raises ParseError' do
62
+ scope = described_class.new(instance, 'hello world') {}
63
+ expect {
64
+ scope.process
65
+ }.to raise_error(NodeQuery::Compiler::ParseError)
66
+
67
+ scope = described_class.new(instance, '.type[key IN value]') {}
68
+ expect {
69
+ scope.process
70
+ }.to raise_error(NodeQuery::Compiler::ParseError)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -54,27 +54,30 @@ module Synvert::Core
54
54
 
55
55
  it 'matches multiple block nodes' do
56
56
  block_nodes = []
57
- scope = Rewriter::WithinScope.new(instance, { type: 'block' }, { stop_when_match: false }) do
58
- block_nodes << node
59
- end
57
+ scope =
58
+ Rewriter::WithinScope.new(instance, { type: 'block' }, { stop_when_match: false }) do
59
+ block_nodes << node
60
+ end
60
61
  scope.process
61
62
  expect(block_nodes.size).to eq 2
62
63
  end
63
64
 
64
65
  it 'matches only one block node if no recursive' do
65
66
  block_nodes = []
66
- scope = Rewriter::WithinScope.new(instance, { type: 'block' } , { stop_when_match: true }) do
67
- block_nodes << node
68
- end
67
+ scope =
68
+ Rewriter::WithinScope.new(instance, { type: 'block' }, { stop_when_match: true }) do
69
+ block_nodes << node
70
+ end
69
71
  scope.process
70
72
  expect(block_nodes.size).to eq 1
71
73
  end
72
74
 
73
75
  it 'matches only one direct node' do
74
76
  block_nodes = []
75
- scope = Rewriter::WithinScope.new(instance, { type: 'block' } , { direct: true }) do
76
- block_nodes << node
77
- end
77
+ scope =
78
+ Rewriter::WithinScope.new(instance, { type: 'block' }, { direct: true }) do
79
+ block_nodes << node
80
+ end
78
81
  scope.process
79
82
  expect(block_nodes.size).to eq 1
80
83
  end
@@ -191,7 +191,8 @@ module Synvert::Core
191
191
  Rewriter.new 'group', 'name' do
192
192
  add_snippet :group, :not_exist
193
193
  end
194
- expect { rewriter.process }.to raise_error(RewriterNotFound)
194
+ expect { rewriter.process }
195
+ .to raise_error(RewriterNotFound)
195
196
  end
196
197
  end
197
198
 
@@ -248,7 +249,8 @@ module Synvert::Core
248
249
  end
249
250
 
250
251
  it 'raises RewriterNotFound if rewriter not found' do
251
- expect { Rewriter.call 'group', 'rewriter' }.to raise_error(RewriterNotFound)
252
+ expect { Rewriter.call 'group', 'rewriter' }
253
+ .to raise_error(RewriterNotFound)
252
254
  end
253
255
 
254
256
  context 'available' do
@@ -14,7 +14,8 @@ Gem::Specification.new do |spec|
14
14
  spec.homepage = "https://github.com/xinminlabs/synvert-core-ruby"
15
15
  spec.license = "MIT"
16
16
 
17
- spec.files = `git ls-files -z`.split("\x0")
17
+ spec.files = `git ls-files -z`.split("\x0") +
18
+ %w[lib/synvert/core/node_query/lexer.rex.rb lib/synvert/core/node_query/parser.racc.rb]
18
19
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
20
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
21
  spec.require_paths = ["lib"]
@@ -26,6 +27,9 @@ Gem::Specification.new do |spec|
26
27
  spec.add_development_dependency "bundler"
27
28
  spec.add_development_dependency "guard"
28
29
  spec.add_development_dependency "guard-rspec"
30
+ spec.add_development_dependency "guard-rake"
31
+ spec.add_development_dependency "oedipus_lex"
32
+ spec.add_development_dependency "racc"
29
33
  spec.add_development_dependency "rake"
30
34
  spec.add_development_dependency "rspec", "3.10.0"
31
35
  spec.add_development_dependency "rspec-mocks", "3.10.2" # rspec-mocks 3.10.3 breaks tests
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.64.0
4
+ version: 1.0.1
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-04-02 00:00:00.000000000 Z
11
+ date: 2022-04-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -94,6 +94,48 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: guard-rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: oedipus_lex
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: racc
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
97
139
  - !ruby/object:Gem::Dependency
98
140
  name: rake
99
141
  requirement: !ruby/object:Gem::Requirement
@@ -153,11 +195,35 @@ files:
153
195
  - README.md
154
196
  - Rakefile
155
197
  - lib/synvert/core.rb
198
+ - lib/synvert/core/array_ext.rb
156
199
  - lib/synvert/core/configuration.rb
157
200
  - lib/synvert/core/engine.rb
158
201
  - lib/synvert/core/engine/erb.rb
159
202
  - lib/synvert/core/exceptions.rb
160
203
  - lib/synvert/core/node_ext.rb
204
+ - lib/synvert/core/node_query.rb
205
+ - lib/synvert/core/node_query/compiler.rb
206
+ - lib/synvert/core/node_query/compiler/array.rb
207
+ - lib/synvert/core/node_query/compiler/attribute.rb
208
+ - lib/synvert/core/node_query/compiler/attribute_list.rb
209
+ - lib/synvert/core/node_query/compiler/boolean.rb
210
+ - lib/synvert/core/node_query/compiler/comparable.rb
211
+ - lib/synvert/core/node_query/compiler/dynamic_attribute.rb
212
+ - lib/synvert/core/node_query/compiler/expression.rb
213
+ - lib/synvert/core/node_query/compiler/float.rb
214
+ - lib/synvert/core/node_query/compiler/identifier.rb
215
+ - lib/synvert/core/node_query/compiler/integer.rb
216
+ - lib/synvert/core/node_query/compiler/invalid_operator_error.rb
217
+ - lib/synvert/core/node_query/compiler/nil.rb
218
+ - lib/synvert/core/node_query/compiler/parse_error.rb
219
+ - lib/synvert/core/node_query/compiler/regexp.rb
220
+ - lib/synvert/core/node_query/compiler/selector.rb
221
+ - lib/synvert/core/node_query/compiler/string.rb
222
+ - lib/synvert/core/node_query/compiler/symbol.rb
223
+ - lib/synvert/core/node_query/lexer.rex
224
+ - lib/synvert/core/node_query/lexer.rex.rb
225
+ - lib/synvert/core/node_query/parser.racc.rb
226
+ - lib/synvert/core/node_query/parser.y
161
227
  - lib/synvert/core/rewriter.rb
162
228
  - lib/synvert/core/rewriter/action.rb
163
229
  - lib/synvert/core/rewriter/action/append_action.rb
@@ -181,6 +247,7 @@ files:
181
247
  - lib/synvert/core/rewriter/ruby_version.rb
182
248
  - lib/synvert/core/rewriter/scope.rb
183
249
  - lib/synvert/core/rewriter/scope/goto_scope.rb
250
+ - lib/synvert/core/rewriter/scope/query_scope.rb
184
251
  - lib/synvert/core/rewriter/scope/within_scope.rb
185
252
  - lib/synvert/core/rewriter/warning.rb
186
253
  - lib/synvert/core/version.rb
@@ -188,6 +255,8 @@ files:
188
255
  - spec/support/parser_helper.rb
189
256
  - spec/synvert/core/engine/erb_spec.rb
190
257
  - spec/synvert/core/node_ext_spec.rb
258
+ - spec/synvert/core/node_query/lexer_spec.rb
259
+ - spec/synvert/core/node_query/parser_spec.rb
191
260
  - spec/synvert/core/rewriter/action/append_action_spec.rb
192
261
  - spec/synvert/core/rewriter/action/delete_action_spec.rb
193
262
  - spec/synvert/core/rewriter/action/insert_action_spec.rb
@@ -208,6 +277,7 @@ files:
208
277
  - spec/synvert/core/rewriter/instance_spec.rb
209
278
  - spec/synvert/core/rewriter/ruby_version_spec.rb
210
279
  - spec/synvert/core/rewriter/scope/goto_scope_spec.rb
280
+ - spec/synvert/core/rewriter/scope/query_scope_spec.rb
211
281
  - spec/synvert/core/rewriter/scope/within_scope_spec.rb
212
282
  - spec/synvert/core/rewriter/scope_spec.rb
213
283
  - spec/synvert/core/rewriter/warning_spec.rb
@@ -241,6 +311,8 @@ test_files:
241
311
  - spec/support/parser_helper.rb
242
312
  - spec/synvert/core/engine/erb_spec.rb
243
313
  - spec/synvert/core/node_ext_spec.rb
314
+ - spec/synvert/core/node_query/lexer_spec.rb
315
+ - spec/synvert/core/node_query/parser_spec.rb
244
316
  - spec/synvert/core/rewriter/action/append_action_spec.rb
245
317
  - spec/synvert/core/rewriter/action/delete_action_spec.rb
246
318
  - spec/synvert/core/rewriter/action/insert_action_spec.rb
@@ -261,6 +333,7 @@ test_files:
261
333
  - spec/synvert/core/rewriter/instance_spec.rb
262
334
  - spec/synvert/core/rewriter/ruby_version_spec.rb
263
335
  - spec/synvert/core/rewriter/scope/goto_scope_spec.rb
336
+ - spec/synvert/core/rewriter/scope/query_scope_spec.rb
264
337
  - spec/synvert/core/rewriter/scope/within_scope_spec.rb
265
338
  - spec/synvert/core/rewriter/scope_spec.rb
266
339
  - spec/synvert/core/rewriter/warning_spec.rb