node_query 1.7.0 → 1.8.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 061470a9033fb08485c03c44c3c41ca6ff0daf6a7db2fbe474d82384f9dd731b
4
- data.tar.gz: 915e29f0a09147d3b7d06b0e81770b197cd743f4d44cd3da7b7f5ddee8a50a8c
3
+ metadata.gz: 3dec6cb33f976a8d4eab33d781441941dad502fe794ced0b22ee37e2ef15afd0
4
+ data.tar.gz: 50b703ba607c8efe543fa4a019d84959416795d6fe199b7320eb6f2c0fe454dd
5
5
  SHA512:
6
- metadata.gz: b2184539cae7f69fdc3c53d993394fe4a5cb78bf2fb2e92a7183d61c6de4cab4e9117891859ddbd3c09d54f7905de2ea9c3059279e56d7b28c4f3a286f7247a6
7
- data.tar.gz: e040f8691f7d51c07b6f9a7f7c03de42488a4f02815c683fd1a763eff6f985e4899a91c620d0bc37a4c9942e1c7e294c1e7220e9499a4ee573734cddeeb39acc
6
+ metadata.gz: 9b7232c12af438ecbc69dfd24ee62c6f3c60be26760047afa95154d862da50a098c9079f4c744d15f31ab34e319a2bc8a874fb4d4fb396143f2a6e5e802f7d2f
7
+ data.tar.gz: 60afc766f3d6e4b3cf44efc3e7bf6fac3b7256b8ce47831311ac3fef6a23768bb40ec5d0c5ae6bdf6193dbba6bf40f6349aa71f9d7726a1c9ecf1841ed565fe3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.8.1 (2022-10-15)
4
+
5
+ * Fix `filter_by_position` with empty nodes
6
+
7
+ ## 1.8.0 (2022-10-14)
8
+
9
+ * Support `:first-child` and `:last-child`
10
+
3
11
  ## 1.7.0 (2022-10-01)
4
12
 
5
13
  * Better regexp to match evaluated value
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- node_query (1.7.0)
4
+ node_query (1.8.1)
5
5
  activesupport (< 7.0.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # NodeQuery
2
2
 
3
- NodeQuery defines an AST node query language, which is a css like syntax for matching nodes,
4
- it supports other ast parser if it implements `NodeQuery::Adapter`.
3
+ NodeQuery defines a NQL (node query language) and node rules to query AST nodes.
5
4
 
6
5
  ## Table of Contents
7
6
 
@@ -25,7 +24,8 @@ it supports other ast parser if it implements `NodeQuery::Adapter`.
25
24
  - [Adjacent sibling combinator](#adjacent-sibling-combinator)
26
25
  - [General sibling combinator](#general-sibling-combinator)
27
26
  - [nql matches goto scope](#nql-matches-goto-scope)
28
- - [nql matches pseudo selector](#nql-matches-pseudo-selector)
27
+ - [nql matches :has and :not_has pseudo selector](#nql-matches-has-and-not_has-pseudo-selector)
28
+ - [nql matches :first-child and :last-child pseudo selector](#nql-matches-first-child-and-last-child-pseudo-selector)
29
29
  - [nql matches multiple expressions](#nql-matches-multiple-expressions)
30
30
  - [Node Rules](#node-rules)
31
31
  - [rules matches node type](#rules-matches-node-type)
@@ -61,7 +61,7 @@ Or install it yourself as:
61
61
  It provides two apis: `query_nodes` and `match_node?`
62
62
 
63
63
  ```ruby
64
- node_query = NodeQuery.new(nqlOrRules: String | Hash) # Initialize NodeQuery
64
+ node_query = NodeQuery.new(nql_or_rules: String | Hash) # Initialize NodeQuery
65
65
  node_query.query_nodes(node: Node, options = { including_self: true, stop_at_first_match: false, recursive: true }): Node[] # Get the matching nodes.
66
66
  node_query.match_node?(node: Node): boolean # Check if the node matches nql or rules.
67
67
  ```
@@ -286,7 +286,7 @@ It matches send node only if it is follows the send node whose left value is @id
286
286
 
287
287
  It matches send node who is in the body of def node.
288
288
 
289
- ### nql matches pseudo selector
289
+ ### nql matches :has and :not_has pseudo selector
290
290
 
291
291
  ```
292
292
  .class:has(.def[name=initialize])
@@ -300,6 +300,20 @@ It matches class node who has an initialize def node.
300
300
 
301
301
  It matches class node who does not have an initialize def node.
302
302
 
303
+ ### nql matches :first-child and :last-child pseudo selector
304
+
305
+ ```
306
+ .def:first-child
307
+ ```
308
+
309
+ It matches the first def node.
310
+
311
+ ```
312
+ .def:last-child
313
+ ```
314
+
315
+ It matches the last def node.
316
+
303
317
  ### nql matches multiple expressions
304
318
 
305
319
  ```
@@ -8,14 +8,16 @@ module NodeQuery::Compiler
8
8
  # @param relationship [String] the relationship between the selectors, it can be descendant <code>nil</code>, child <code>></code>, next sibling <code>+</code> or subsequent sibing <code>~</code>.
9
9
  # @param rest [NodeQuery::Compiler::Selector] the rest selector
10
10
  # @param basic_selector [NodeQuery::Compiler::BasicSelector] the simple selector
11
+ # @param position [String] the position of the node
11
12
  # @param attribute_list [NodeQuery::Compiler::AttributeList] the attribute list
12
13
  # @param pseudo_class [String] the pseudo class, can be <code>has</code> or <code>not_has</code>
13
14
  # @param pseudo_selector [NodeQuery::Compiler::Expression] the pseudo selector
14
- def initialize(goto_scope: nil, relationship: nil, rest: nil, basic_selector: nil, pseudo_class: nil, pseudo_selector: nil)
15
+ def initialize(goto_scope: nil, relationship: nil, rest: nil, basic_selector: nil, position: nil, pseudo_class: nil, pseudo_selector: nil)
15
16
  @goto_scope = goto_scope
16
17
  @relationship = relationship
17
18
  @rest = rest
18
19
  @basic_selector = basic_selector
20
+ @position = position
19
21
  @pseudo_class = pseudo_class
20
22
  @pseudo_selector = pseudo_selector
21
23
  end
@@ -75,7 +77,7 @@ module NodeQuery::Compiler
75
77
  end
76
78
  end
77
79
  end
78
- nodes
80
+ filter_by_position(nodes)
79
81
  end
80
82
 
81
83
  def to_s
@@ -84,10 +86,30 @@ module NodeQuery::Compiler
84
86
  result << "#{@relationship} " if @relationship
85
87
  result << @rest.to_s if @rest
86
88
  result << @basic_selector.to_s if @basic_selector
89
+ result << ":#{@position}" if @position
87
90
  result << ":#{@pseudo_class}(#{@pseudo_selector})" if @pseudo_class
88
91
  result.join('')
89
92
  end
90
93
 
94
+ protected
95
+
96
+ # Filter nodes by position.
97
+ # @param nodes [Array<Node>] nodes to filter
98
+ # @return [Array<Node>|Node] first node or last node or nodes
99
+ def filter_by_position(nodes)
100
+ return nodes unless @position
101
+ return nodes if nodes.empty?
102
+
103
+ case @position
104
+ when 'first-child'
105
+ [nodes.first]
106
+ when 'last-child'
107
+ [nodes.last]
108
+ else
109
+ nodes
110
+ end
111
+ end
112
+
91
113
  private
92
114
 
93
115
  # Find nodes by @goto_scope
@@ -128,7 +150,7 @@ module NodeQuery::Compiler
128
150
  nodes << sibling_node if @rest.match?(sibling_node, sibling_node)
129
151
  end
130
152
  end
131
- nodes
153
+ @rest.filter_by_position(nodes)
132
154
  end
133
155
 
134
156
  # Check if it matches pseudo class.
@@ -144,8 +144,8 @@ class NodeQuery::NodeRules
144
144
  # Convert a hash to flat one.
145
145
  #
146
146
  # @example
147
- # flat_hash(type: 'block', caller: {type: 'send', receiver: 'RSpec'})
148
- # # {[:type] => 'block', [:caller, :type] => 'send', [:caller, :receiver] => 'RSpec'}
147
+ # flat_hash(node_type: 'block', caller: { node_type: 'send', receiver: 'RSpec' })
148
+ # # {[:node_type] => 'block', [:caller, :node_type] => 'send', [:caller, :receiver] => 'RSpec'}
149
149
  # @param h [Hash] original hash.
150
150
  # @return flatten hash.
151
151
  def flat_hash(h, k = [])
@@ -190,4 +190,4 @@ class NodeQuery::NodeRules
190
190
  string
191
191
  end
192
192
  end
193
- end
193
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class NodeQuery
4
- VERSION = "1.7.0"
4
+ VERSION = "1.8.1"
5
5
  end
data/lib/node_query.rb CHANGED
@@ -27,12 +27,12 @@ class NodeQuery
27
27
  end
28
28
 
29
29
  # Initialize a NodeQuery.
30
- # @param nqlOrRules [String | Hash] node query language or node rules
31
- def initialize(nqlOrRules)
32
- if nqlOrRules.is_a?(String)
33
- @expression = NodeQueryParser.new.parse(nqlOrRules)
30
+ # @param nql_or_ruls [String | Hash] node query language or node rules
31
+ def initialize(nql_or_ruls)
32
+ if nql_or_ruls.is_a?(String)
33
+ @expression = NodeQueryParser.new.parse(nql_or_ruls)
34
34
  else
35
- @rules = NodeRules.new(nqlOrRules)
35
+ @rules = NodeRules.new(nql_or_ruls)
36
36
  end
37
37
  end
38
38
 
@@ -26,6 +26,8 @@ rules
26
26
  # [:state] pattern [actions]
27
27
  /\s+/
28
28
  /,/ { [:tCOMMA, text] }
29
+ /:first-child/ { [:tPOSITION, text[1..-1]] }
30
+ /:last-child/ { [:tPOSITION, text[1..-1]] }
29
31
  /:has/ { [:tPSEUDO_CLASS, text[1..-1]] }
30
32
  /:not_has/ { [:tPSEUDO_CLASS, text[1..-1]] }
31
33
  /#{NODE_TYPE}/ { [:tNODE_TYPE, text[1..]] }
@@ -125,6 +125,10 @@ class NodeQueryLexer
125
125
  # do nothing
126
126
  when text = ss.scan(/,/) then
127
127
  action { [:tCOMMA, text] }
128
+ when text = ss.scan(/:first-child/) then
129
+ action { [:tPOSITION, text[1..-1]] }
130
+ when text = ss.scan(/:last-child/) then
131
+ action { [:tPOSITION, text[1..-1]] }
128
132
  when text = ss.scan(/:has/) then
129
133
  action { [:tPSEUDO_CLASS, text[1..-1]] }
130
134
  when text = ss.scan(/:not_has/) then
@@ -22,85 +22,86 @@ class NodeQueryParser < Racc::Parser
22
22
  ##### State transition tables begin ###
23
23
 
24
24
  racc_action_table = [
25
- 8, 8, 7, 9, 10, 36, 12, 5, 6, 16,
26
- 27, 17, 21, 22, 23, 24, 29, 30, 31, 32,
27
- 33, 34, 35, 8, 16, 8, 7, 40, 36, nil,
28
- 8, 5, 6, nil, 37, 36, nil, nil, nil, 29,
29
- 30, 31, 32, 33, 34, 35, 29, 30, 31, 32,
30
- 33, 34, 35, 8, 7, 8, 7, 8, 7, 5,
31
- 6, 5, 6, 5, 6, 8, 7, nil, nil, nil,
32
- nil, 5, 6 ]
25
+ 8, 8, 7, 9, 10, 37, 12, 5, 6, 13,
26
+ 28, 17, 18, 22, 23, 24, 25, 30, 31, 32,
27
+ 33, 34, 35, 36, 8, 17, 8, 7, 41, 37,
28
+ nil, 8, 5, 6, nil, 38, 37, nil, nil, nil,
29
+ nil, 30, 31, 32, 33, 34, 35, 36, 30, 31,
30
+ 32, 33, 34, 35, 36, 8, 7, 8, 7, 8,
31
+ 7, 5, 6, 5, 6, 5, 6, 8, 7, nil,
32
+ nil, nil, nil, 5, 6 ]
33
33
 
34
34
  racc_action_check = [
35
- 24, 0, 0, 1, 2, 24, 5, 0, 0, 8,
36
- 24, 9, 16, 19, 20, 21, 24, 24, 24, 24,
37
- 24, 24, 24, 27, 23, 3, 3, 38, 27, nil,
38
- 39, 3, 3, nil, 27, 39, nil, nil, nil, 27,
39
- 27, 27, 27, 27, 27, 27, 39, 39, 39, 39,
40
- 39, 39, 39, 6, 6, 7, 7, 10, 10, 6,
41
- 6, 7, 7, 10, 10, 12, 12, nil, nil, nil,
42
- nil, 12, 12 ]
35
+ 25, 0, 0, 1, 2, 25, 4, 0, 0, 5,
36
+ 25, 8, 9, 17, 20, 21, 22, 25, 25, 25,
37
+ 25, 25, 25, 25, 28, 24, 3, 3, 39, 28,
38
+ nil, 40, 3, 3, nil, 28, 40, nil, nil, nil,
39
+ nil, 28, 28, 28, 28, 28, 28, 28, 40, 40,
40
+ 40, 40, 40, 40, 40, 6, 6, 7, 7, 10,
41
+ 10, 6, 6, 7, 7, 10, 10, 13, 13, nil,
42
+ nil, nil, nil, 13, 13 ]
43
43
 
44
44
  racc_action_pointer = [
45
- -2, 3, 2, 22, nil, -9, 50, 52, -2, 11,
46
- 54, nil, 62, nil, nil, nil, 6, nil, nil, -3,
47
- 2, -2, nil, 13, -3, nil, nil, 20, nil, nil,
48
- nil, nil, nil, nil, nil, nil, nil, nil, 13, 27,
49
- nil, nil ]
45
+ -2, 3, 2, 23, -11, -6, 52, 54, 0, 12,
46
+ 56, nil, nil, 64, nil, nil, nil, 7, nil, nil,
47
+ -2, 3, -2, nil, 14, -3, nil, nil, 21, nil,
48
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, 14,
49
+ 28, nil, nil ]
50
50
 
51
51
  racc_action_default = [
52
- -27, -27, -2, -4, -5, -27, -27, -27, -9, -27,
53
- -27, -3, -27, -7, -8, -10, -27, 42, -1, -27,
54
- -27, -27, -6, -12, -27, -11, -13, -27, -18, -19,
55
- -20, -21, -22, -23, -24, -25, -26, -14, -27, -17,
56
- -15, -16 ]
52
+ -28, -28, -2, -4, -6, -28, -28, -28, -10, -28,
53
+ -28, -3, -5, -28, -8, -9, -11, -28, 43, -1,
54
+ -28, -28, -28, -7, -13, -28, -12, -14, -28, -19,
55
+ -20, -21, -22, -23, -24, -25, -26, -27, -15, -28,
56
+ -18, -16, -17 ]
57
57
 
58
58
  racc_goto_table = [
59
- 28, 15, 38, 28, 13, 14, 11, 1, 20, 26,
60
- 19, nil, nil, nil, 41, 28, 25, 18 ]
59
+ 16, 39, 29, 11, 1, 29, 21, 27, 14, 15,
60
+ nil, nil, nil, 42, 19, 20, 26, 29 ]
61
61
 
62
62
  racc_goto_check = [
63
- 4, 5, 8, 4, 3, 3, 2, 1, 6, 7,
64
- 3, nil, nil, nil, 8, 4, 5, 1 ]
63
+ 5, 8, 4, 2, 1, 4, 6, 7, 3, 3,
64
+ nil, nil, nil, 8, 1, 3, 5, 4 ]
65
65
 
66
66
  racc_goto_pointer = [
67
- nil, 7, 3, -2, -24, -7, -8, -15, -25 ]
67
+ nil, 4, 0, 2, -23, -8, -11, -18, -27 ]
68
68
 
69
69
  racc_goto_default = [
70
- nil, nil, 2, 3, 4, nil, nil, 39, nil ]
70
+ nil, nil, 2, 3, 4, nil, nil, 40, nil ]
71
71
 
72
72
  racc_reduce_table = [
73
73
  0, 0, :racc_error,
74
- 3, 27, :_reduce_1,
75
- 1, 27, :_reduce_2,
76
- 2, 28, :_reduce_3,
77
- 1, 28, :_reduce_4,
78
- 1, 29, :_reduce_5,
79
- 4, 29, :_reduce_6,
80
- 2, 29, :_reduce_7,
81
- 2, 29, :_reduce_8,
82
- 1, 30, :_reduce_9,
83
- 2, 30, :_reduce_10,
84
- 4, 31, :_reduce_11,
85
- 3, 31, :_reduce_12,
74
+ 3, 28, :_reduce_1,
75
+ 1, 28, :_reduce_2,
76
+ 2, 29, :_reduce_3,
77
+ 1, 29, :_reduce_4,
78
+ 2, 30, :_reduce_5,
79
+ 1, 30, :_reduce_6,
80
+ 4, 30, :_reduce_7,
81
+ 2, 30, :_reduce_8,
82
+ 2, 30, :_reduce_9,
83
+ 1, 31, :_reduce_10,
84
+ 2, 31, :_reduce_11,
85
+ 4, 32, :_reduce_12,
86
86
  3, 32, :_reduce_13,
87
- 4, 32, :_reduce_14,
88
- 5, 32, :_reduce_15,
89
- 2, 34, :_reduce_16,
90
- 1, 34, :_reduce_17,
91
- 1, 33, :_reduce_none,
92
- 1, 33, :_reduce_19,
93
- 1, 33, :_reduce_20,
94
- 1, 33, :_reduce_21,
95
- 1, 33, :_reduce_22,
96
- 1, 33, :_reduce_23,
97
- 1, 33, :_reduce_24,
98
- 1, 33, :_reduce_25,
99
- 1, 33, :_reduce_26 ]
100
-
101
- racc_reduce_n = 27
102
-
103
- racc_shift_n = 42
87
+ 3, 33, :_reduce_14,
88
+ 4, 33, :_reduce_15,
89
+ 5, 33, :_reduce_16,
90
+ 2, 35, :_reduce_17,
91
+ 1, 35, :_reduce_18,
92
+ 1, 34, :_reduce_none,
93
+ 1, 34, :_reduce_20,
94
+ 1, 34, :_reduce_21,
95
+ 1, 34, :_reduce_22,
96
+ 1, 34, :_reduce_23,
97
+ 1, 34, :_reduce_24,
98
+ 1, 34, :_reduce_25,
99
+ 1, 34, :_reduce_26,
100
+ 1, 34, :_reduce_27 ]
101
+
102
+ racc_reduce_n = 28
103
+
104
+ racc_shift_n = 43
104
105
 
105
106
  racc_token_table = {
106
107
  false => 0,
@@ -120,17 +121,18 @@ racc_token_table = {
120
121
  :tCLOSE_ARRAY => 14,
121
122
  :tOPEN_SELECTOR => 15,
122
123
  :tCLOSE_SELECTOR => 16,
123
- :tOPERATOR => 17,
124
- :tARRAY_VALUE => 18,
125
- :tBOOLEAN => 19,
126
- :tFLOAT => 20,
127
- :tINTEGER => 21,
128
- :tNIL => 22,
129
- :tREGEXP => 23,
130
- :tSTRING => 24,
131
- :tSYMBOL => 25 }
132
-
133
- racc_nt_base = 26
124
+ :tPOSITION => 17,
125
+ :tOPERATOR => 18,
126
+ :tARRAY_VALUE => 19,
127
+ :tBOOLEAN => 20,
128
+ :tFLOAT => 21,
129
+ :tINTEGER => 22,
130
+ :tNIL => 23,
131
+ :tREGEXP => 24,
132
+ :tSTRING => 25,
133
+ :tSYMBOL => 26 }
134
+
135
+ racc_nt_base = 27
134
136
 
135
137
  racc_use_result_var = false
136
138
 
@@ -168,6 +170,7 @@ Racc_token_to_s_table = [
168
170
  "tCLOSE_ARRAY",
169
171
  "tOPEN_SELECTOR",
170
172
  "tCLOSE_SELECTOR",
173
+ "tPOSITION",
171
174
  "tOPERATOR",
172
175
  "tARRAY_VALUE",
173
176
  "tBOOLEAN",
@@ -210,88 +213,92 @@ def _reduce_4(val, _values)
210
213
  end
211
214
 
212
215
  def _reduce_5(val, _values)
213
- NodeQuery::Compiler::Selector.new(basic_selector: val[0])
216
+ NodeQuery::Compiler::Selector.new(basic_selector: val[0], position: val[1] )
214
217
  end
215
218
 
216
219
  def _reduce_6(val, _values)
217
- NodeQuery::Compiler::Selector.new(pseudo_class: val[0], pseudo_selector: val[2])
220
+ NodeQuery::Compiler::Selector.new(basic_selector: val[0])
218
221
  end
219
222
 
220
223
  def _reduce_7(val, _values)
221
- NodeQuery::Compiler::Selector.new(relationship: val[0], rest: val[1])
224
+ NodeQuery::Compiler::Selector.new(pseudo_class: val[0], pseudo_selector: val[2])
222
225
  end
223
226
 
224
227
  def _reduce_8(val, _values)
225
- NodeQuery::Compiler::Selector.new(goto_scope: val[0], rest: val[1])
228
+ NodeQuery::Compiler::Selector.new(relationship: val[0], rest: val[1])
226
229
  end
227
230
 
228
231
  def _reduce_9(val, _values)
229
- NodeQuery::Compiler::BasicSelector.new(node_type: val[0])
232
+ NodeQuery::Compiler::Selector.new(goto_scope: val[0], rest: val[1])
230
233
  end
231
234
 
232
235
  def _reduce_10(val, _values)
233
- NodeQuery::Compiler::BasicSelector.new(node_type: val[0], attribute_list: val[1])
236
+ NodeQuery::Compiler::BasicSelector.new(node_type: val[0])
234
237
  end
235
238
 
236
239
  def _reduce_11(val, _values)
237
- NodeQuery::Compiler::AttributeList.new(attribute: val[1], rest: val[3])
240
+ NodeQuery::Compiler::BasicSelector.new(node_type: val[0], attribute_list: val[1])
238
241
  end
239
242
 
240
243
  def _reduce_12(val, _values)
241
- NodeQuery::Compiler::AttributeList.new(attribute: val[1])
244
+ NodeQuery::Compiler::AttributeList.new(attribute: val[1], rest: val[3])
242
245
  end
243
246
 
244
247
  def _reduce_13(val, _values)
245
- NodeQuery::Compiler::Attribute.new(key: val[0], value: val[2], operator: val[1])
248
+ NodeQuery::Compiler::AttributeList.new(attribute: val[1])
246
249
  end
247
250
 
248
251
  def _reduce_14(val, _values)
249
- NodeQuery::Compiler::Attribute.new(key: val[0], value: NodeQuery::Compiler::ArrayValue.new, operator: val[1])
252
+ NodeQuery::Compiler::Attribute.new(key: val[0], value: val[2], operator: val[1])
250
253
  end
251
254
 
252
255
  def _reduce_15(val, _values)
253
- NodeQuery::Compiler::Attribute.new(key: val[0], value: val[3], operator: val[1])
256
+ NodeQuery::Compiler::Attribute.new(key: val[0], value: NodeQuery::Compiler::ArrayValue.new, operator: val[1])
254
257
  end
255
258
 
256
259
  def _reduce_16(val, _values)
257
- NodeQuery::Compiler::ArrayValue.new(value: val[0], rest: val[1])
260
+ NodeQuery::Compiler::Attribute.new(key: val[0], value: val[3], operator: val[1])
258
261
  end
259
262
 
260
263
  def _reduce_17(val, _values)
264
+ NodeQuery::Compiler::ArrayValue.new(value: val[0], rest: val[1])
265
+ end
266
+
267
+ def _reduce_18(val, _values)
261
268
  NodeQuery::Compiler::ArrayValue.new(value: val[0])
262
269
  end
263
270
 
264
- # reduce 18 omitted
271
+ # reduce 19 omitted
265
272
 
266
- def _reduce_19(val, _values)
273
+ def _reduce_20(val, _values)
267
274
  NodeQuery::Compiler::Boolean.new(value: val[0])
268
275
  end
269
276
 
270
- def _reduce_20(val, _values)
277
+ def _reduce_21(val, _values)
271
278
  NodeQuery::Compiler::Float.new(value: val[0])
272
279
  end
273
280
 
274
- def _reduce_21(val, _values)
281
+ def _reduce_22(val, _values)
275
282
  NodeQuery::Compiler::Integer.new(value: val[0])
276
283
  end
277
284
 
278
- def _reduce_22(val, _values)
285
+ def _reduce_23(val, _values)
279
286
  NodeQuery::Compiler::Nil.new(value: val[0])
280
287
  end
281
288
 
282
- def _reduce_23(val, _values)
289
+ def _reduce_24(val, _values)
283
290
  NodeQuery::Compiler::Regexp.new(value: val[0])
284
291
  end
285
292
 
286
- def _reduce_24(val, _values)
293
+ def _reduce_25(val, _values)
287
294
  NodeQuery::Compiler::String.new(value: val[0])
288
295
  end
289
296
 
290
- def _reduce_25(val, _values)
297
+ def _reduce_26(val, _values)
291
298
  NodeQuery::Compiler::Symbol.new(value: val[0])
292
299
  end
293
300
 
294
- def _reduce_26(val, _values)
301
+ def _reduce_27(val, _values)
295
302
  NodeQuery::Compiler::Identifier.new(value: val[0])
296
303
  end
297
304
 
@@ -1,7 +1,7 @@
1
1
  class NodeQueryParser
2
2
  options no_result_var
3
3
  token tCOMMA tNODE_TYPE tGOTO_SCOPE tATTRIBUTE tKEY tIDENTIFIER tIDENTIFIER_VALUE tPSEUDO_CLASS tRELATIONSHIP
4
- tOPEN_ATTRIBUTE tCLOSE_ATTRIBUTE tOPEN_ARRAY tCLOSE_ARRAY tOPEN_SELECTOR tCLOSE_SELECTOR
4
+ tOPEN_ATTRIBUTE tCLOSE_ATTRIBUTE tOPEN_ARRAY tCLOSE_ARRAY tOPEN_SELECTOR tCLOSE_SELECTOR tPOSITION
5
5
  tOPERATOR tARRAY_VALUE tBOOLEAN tFLOAT tINTEGER tNIL tREGEXP tSTRING tSYMBOL
6
6
  rule
7
7
  expression_list
@@ -13,7 +13,8 @@ rule
13
13
  | selector { NodeQuery::Compiler::Expression.new(selector: val[0]) }
14
14
 
15
15
  selector
16
- : basic_selector { NodeQuery::Compiler::Selector.new(basic_selector: val[0]) }
16
+ : basic_selector tPOSITION { NodeQuery::Compiler::Selector.new(basic_selector: val[0], position: val[1] ) }
17
+ | basic_selector { NodeQuery::Compiler::Selector.new(basic_selector: val[0]) }
17
18
  | tPSEUDO_CLASS tOPEN_SELECTOR selector tCLOSE_SELECTOR { NodeQuery::Compiler::Selector.new(pseudo_class: val[0], pseudo_selector: val[2]) }
18
19
  | tRELATIONSHIP selector { NodeQuery::Compiler::Selector.new(relationship: val[0], rest: val[1]) }
19
20
  | tGOTO_SCOPE selector { NodeQuery::Compiler::Selector.new(goto_scope: val[0], rest: val[1]) }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: node_query
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Huang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-01 00:00:00.000000000 Z
11
+ date: 2022-10-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -91,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
91
  - !ruby/object:Gem::Version
92
92
  version: '0'
93
93
  requirements: []
94
- rubygems_version: 3.3.7
94
+ rubygems_version: 3.3.22
95
95
  signing_key:
96
96
  specification_version: 4
97
97
  summary: ast node query language