node_query 1.13.12 → 1.14.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: cdd226c05ade3d2dde453af11182b02cabe7111f27ab7eaa5677b5b48d3ac247
4
- data.tar.gz: 06bde0578a6e5e113cd1675207f8bef58a77b07761e13bee0c9fdfc2d00cf8e5
3
+ metadata.gz: 3dfe6e9207a883cc7d7240f46bac3d4628443f9eb40bcd5af36802311ebad8ae
4
+ data.tar.gz: 1d4dbd34cb794d95fc594f020fd07706e5babc85a38ea303a2c9ce4a31ed2f0a
5
5
  SHA512:
6
- metadata.gz: 3f2cd0d797d7c212481a481754aca0a448e6bafbee7a4b93b53c6c17255a40e066df5368cdae8304a9da99f3059042ff5798916519aeb25fea1c06c84282c620
7
- data.tar.gz: 7249a00c56a7d527dee321375d6b3f05115fe3666ea8a126b7994935974e7dd7ec1d767296e2cd43d2987189c8c964eec5b065c42d7c7dd27d92c83f3b5d1b29
6
+ metadata.gz: 70dc0235743a5191905c18633a633f620bdff6ffcd8bd4704b31d84ff724239e2e604e9999be9532022fa4d6b590bf3d2b886f468f0e4add83c4c1594f45ad58
7
+ data.tar.gz: 3831937eb116d7e49812631488cc12bbbcf1c923212e810e35ca98a15590b6241c3659ed24909d36206a28176d2d7a721f1ec9e2d10556c6fea62f2889e0d104
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.14.0 (2023-11-27)
4
+
5
+ * Add `adapter` parameter to `NodeQuery`
6
+ * Do not allow to configure an `adapter` globally
7
+
3
8
  ## 1.13.12 (2023-09-29)
4
9
 
5
10
  * `NODE_TYPE` can contain `_`
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- node_query (1.13.12)
4
+ node_query (1.14.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -38,9 +38,10 @@ GEM
38
38
  nenv (~> 0.1)
39
39
  shellany (~> 0.0)
40
40
  oedipus_lex (2.6.0)
41
- parser (3.2.2.1)
41
+ parser (3.2.2.3)
42
42
  ast (~> 2.4.1)
43
- parser_node_ext (1.1.0)
43
+ racc
44
+ parser_node_ext (1.2.1)
44
45
  parser
45
46
  prettier_print (1.2.1)
46
47
  pry (0.14.1)
data/README.md CHANGED
@@ -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(nql_or_rules: String | Hash) # Initialize NodeQuery
64
+ node_query = NodeQuery.new(nql_or_rules: String | Hash, adapter: Symbol) # 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
  ```
@@ -82,8 +82,8 @@ source = `
82
82
  node = Parser::CurrentRuby.parse(source)
83
83
 
84
84
  # It will get the node of initialize.
85
- NodeQuery.new('.def[name=initialize]').query_nodes(node)
86
- NodeQuery.new({ node_type: 'def', name: 'initialize' }).query_nodes(node)
85
+ NodeQuery.new('.def[name=initialize]', adapter: :parser).query_nodes(node)
86
+ NodeQuery.new({ node_type: 'def', name: 'initialize' }, adapter: :parser).query_nodes(node)
87
87
  ```
88
88
 
89
89
  ## Node Query Language
@@ -483,10 +483,6 @@ It provides 2 adapters
483
483
  1. `ParserAdapter`
484
484
  2. `SyntaxTreeAdapter`
485
485
 
486
- ```ruby
487
- NodeQuery.configure(adapter: SyntaxTreeAdapter.new) # default is ParserAdapter
488
- ```
489
-
490
486
  ## Development
491
487
 
492
488
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -8,9 +8,11 @@ module NodeQuery::Compiler
8
8
  # Initialize an Array.
9
9
  # @param value the first value of the array
10
10
  # @param rest the rest value of the array
11
- def initialize(value: nil, rest: nil)
11
+ # @param adapter [NodeQuery::Adapter]
12
+ def initialize(value: nil, rest: nil, adapter:)
12
13
  @value = value
13
14
  @rest = rest
15
+ @adapter = adapter
14
16
  end
15
17
 
16
18
  # Get the expected value.
@@ -7,10 +7,12 @@ module NodeQuery::Compiler
7
7
  # @param key [String] the key
8
8
  # @param value the value can be any class implement {NodeQuery::Compiler::Comparable}
9
9
  # @param operator [String] the operator
10
- def initialize(key:, value:, operator: '=')
10
+ # @param adapter [NodeQuery::Adapter]
11
+ def initialize(key:, value:, operator: '=', adapter:)
11
12
  @key = key
12
13
  @value = value
13
14
  @operator = operator
15
+ @adapter = adapter
14
16
  end
15
17
 
16
18
  # Check if the node matches the attribute.
@@ -18,7 +20,7 @@ module NodeQuery::Compiler
18
20
  # @param base_node [Node] the bae node for evaluated value
19
21
  # @return [Boolean]
20
22
  def match?(node, base_node)
21
- node && @value.match?(NodeQuery::Helper.get_target_node(node, @key), base_node, @operator)
23
+ node && @value.match?(NodeQuery::Helper.get_target_node(node, @key, @adapter), base_node, @operator)
22
24
  end
23
25
 
24
26
  def to_s
@@ -6,9 +6,11 @@ module NodeQuery::Compiler
6
6
  # Initialize a BasicSelector.
7
7
  # @param node_type [String] the node type
8
8
  # @param attribute_list [NodeQuery::Compiler::AttributeList] the attribute list
9
- def initialize(node_type:, attribute_list: nil)
9
+ # @param adapter [NodeQuery::Adapter]
10
+ def initialize(node_type:, attribute_list: nil, adapter:)
10
11
  @node_type = node_type
11
12
  @attribute_list = attribute_list
13
+ @adapter = adapter
12
14
  end
13
15
 
14
16
  # Check if node matches the selector.
@@ -18,7 +20,7 @@ module NodeQuery::Compiler
18
20
  def match?(node, base_node, _operator = '=')
19
21
  return false unless node
20
22
 
21
- @node_type.to_sym == NodeQuery.adapter.get_node_type(node) && (!@attribute_list || @attribute_list.match?(
23
+ @node_type.to_sym == @adapter.get_node_type(node) && (!@attribute_list || @attribute_list.match?(
22
24
  node,
23
25
  base_node
24
26
  ))
@@ -7,8 +7,10 @@ module NodeQuery::Compiler
7
7
 
8
8
  # Initialize a Boolean.
9
9
  # @param value [Boolean] the boolean value
10
- def initialize(value:)
10
+ # @param adapter [NodeQuery::Adapter]
11
+ def initialize(value:, adapter:)
11
12
  @value = value
13
+ @adapter = adapter
12
14
  end
13
15
 
14
16
  # Get valid operators.
@@ -16,6 +16,7 @@ module NodeQuery::Compiler
16
16
  # @param operator [String] operator to compare with expected value, operator can be <code>'='</code>, <code>'!='</code>, <code>'>'</code>, <code>'>='</code>, <code>'<'</code>, <code>'<='</code>, <code>'includes'</code>, <code>'in'</code>, <code>'not_in'</code>, <code>'=~'</code>, <code>'!~'</code>
17
17
  # @return [Boolean] true if actual value matches the expected value
18
18
  # @raise [NodeQuery::Compiler::InvalidOperatorError] if operator is invalid
19
+ # @param adapter [NodeQuery::Adapter]
19
20
  def match?(node, base_node, operator)
20
21
  raise InvalidOperatorError, "invalid operator #{operator}" unless valid_operator?(operator)
21
22
 
@@ -89,7 +90,7 @@ module NodeQuery::Compiler
89
90
  # @param node [Node] ast node
90
91
  # @return the node value, could be integer, float, string, boolean, nil, range, and etc.
91
92
  def actual_value(node)
92
- if NodeQuery.adapter.is_node?(node)
93
+ if @adapter.is_node?(node)
93
94
  node.to_value
94
95
  else
95
96
  node
@@ -7,8 +7,10 @@ module NodeQuery::Compiler
7
7
 
8
8
  # Initialize a Float.
9
9
  # @param value [Float] the float value
10
- def initialize(value:)
10
+ # @param adapter [NodeQuery::Adapter]
11
+ def initialize(value:, adapter:)
11
12
  @value = value
13
+ @adapter = adapter
12
14
  end
13
15
 
14
16
  # Get valid operators.
@@ -8,8 +8,10 @@ module NodeQuery::Compiler
8
8
 
9
9
  # Initialize an Identifier.
10
10
  # @param value [String] the identifier value
11
- def initialize(value:)
11
+ # @param adapter [NodeQuery::Adapter]
12
+ def initialize(value:, adapter:)
12
13
  @value = value
14
+ @adapter = adapter
13
15
  end
14
16
 
15
17
  # Get the actual value.
@@ -19,8 +21,8 @@ module NodeQuery::Compiler
19
21
  # if the node is an Array, return the array of each element's actual value,
20
22
  # otherwise, return the String value.
21
23
  def actual_value(node)
22
- if NodeQuery.adapter.is_node?(node)
23
- NodeQuery.adapter.get_source(node)
24
+ if @adapter.is_node?(node)
25
+ @adapter.get_source(node)
24
26
  elsif node.is_a?(::Array)
25
27
  node.map { |n| actual_value(n) }
26
28
  else
@@ -7,8 +7,10 @@ module NodeQuery::Compiler
7
7
 
8
8
  # Initialize a Integer.
9
9
  # @param value [Integer] the integer value
10
- def initialize(value:)
10
+ # @param adapter [NodeQuery::Adapter]
11
+ def initialize(value:, adapter:)
11
12
  @value = value
13
+ @adapter = adapter
12
14
  end
13
15
 
14
16
  # Get valid operators.
@@ -7,8 +7,10 @@ module NodeQuery::Compiler
7
7
 
8
8
  # Initialize a Nil.
9
9
  # @param value [nil] the nil value
10
- def initialize(value:)
10
+ # @param adapter [NodeQuery::Adapter]
11
+ def initialize(value:, adapter:)
11
12
  @value = value
13
+ @adapter = adapter
12
14
  end
13
15
 
14
16
  # Get valid operators.
@@ -7,8 +7,10 @@ module NodeQuery::Compiler
7
7
 
8
8
  # Initialize a Regexp.
9
9
  # @param value [Regexp] the regexp value
10
- def initialize(value:)
10
+ # @param adapter [NodeQuery::Adapter]
11
+ def initialize(value:, adapter:)
11
12
  @value = value
13
+ @adapter = adapter
12
14
  end
13
15
 
14
16
  # Check if the regexp value matches the node value.
@@ -18,8 +20,8 @@ module NodeQuery::Compiler
18
20
  # @return [Boolean] true if the regexp value matches the node value, otherwise, false.
19
21
  def match?(node, _base_node, operator = '=~')
20
22
  match =
21
- if NodeQuery.adapter.is_node?(node)
22
- @value.match(NodeQuery.adapter.get_source(node))
23
+ if @adapter.is_node?(node)
24
+ @value.match(@adapter.get_source(node))
23
25
  else
24
26
  @value.match(node.to_s)
25
27
  end
@@ -12,6 +12,7 @@ module NodeQuery::Compiler
12
12
  # @param attribute_list [NodeQuery::Compiler::AttributeList] the attribute list
13
13
  # @param pseudo_class [String] the pseudo class, can be <code>has</code> or <code>not_has</code>
14
14
  # @param pseudo_selector [NodeQuery::Compiler::Expression] the pseudo selector
15
+ # @param adapter [NodeQuery::Adapter]
15
16
  def initialize(
16
17
  goto_scope: nil,
17
18
  relationship: nil,
@@ -19,7 +20,8 @@ module NodeQuery::Compiler
19
20
  basic_selector: nil,
20
21
  position: nil,
21
22
  pseudo_class: nil,
22
- pseudo_selector: nil
23
+ pseudo_selector: nil,
24
+ adapter:
23
25
  )
24
26
  @goto_scope = goto_scope
25
27
  @relationship = relationship
@@ -28,6 +30,7 @@ module NodeQuery::Compiler
28
30
  @position = position
29
31
  @pseudo_class = pseudo_class
30
32
  @pseudo_selector = pseudo_selector
33
+ @adapter = adapter
31
34
  end
32
35
 
33
36
  # Check if node matches the selector.
@@ -44,7 +47,7 @@ module NodeQuery::Compiler
44
47
  return false
45
48
  end
46
49
  end
47
- NodeQuery.adapter.is_node?(node) && (!@basic_selector || (operator == "!=" ? !@basic_selector.match?(
50
+ @adapter.is_node?(node) && (!@basic_selector || (operator == "!=" ? !@basic_selector.match?(
48
51
  node,
49
52
  base_node
50
53
  ) : @basic_selector.match?(node, base_node))) && match_pseudo_class?(node)
@@ -83,7 +86,7 @@ module NodeQuery::Compiler
83
86
  end
84
87
  if @basic_selector
85
88
  if options[:recursive]
86
- NodeQuery::Helper.handle_recursive_child(node) do |child_node|
89
+ NodeQuery::Helper.handle_recursive_child(node, @adapter) do |child_node|
87
90
  if match?(child_node, child_node)
88
91
  nodes << child_node
89
92
  break if options[:stop_at_first_match]
@@ -153,13 +156,13 @@ module NodeQuery::Compiler
153
156
  nodes << child_node if @rest.match?(child_node, child_node)
154
157
  end
155
158
  else
156
- NodeQuery.adapter.get_children(node).each do |child_node|
159
+ @adapter.get_children(node).each do |child_node|
157
160
  if child_node.is_a?(Array) # SyntaxTree may return an array in child node.
158
161
  child_node.each do |child_child_node|
159
162
  nodes << child_child_node if @rest.match?(child_child_node, child_child_node)
160
163
  end
161
- elsif NodeQuery.adapter.is_node?(child_node) && :begin == NodeQuery.adapter.get_node_type(child_node)
162
- NodeQuery.adapter.get_children(child_node).each do |child_child_node|
164
+ elsif @adapter.is_node?(child_node) && :begin == @adapter.get_node_type(child_node)
165
+ @adapter.get_children(child_node).each do |child_child_node|
163
166
  nodes << child_child_node if @rest.match?(child_child_node, child_child_node)
164
167
  end
165
168
  elsif @rest.match?(child_node, child_node)
@@ -7,8 +7,10 @@ module NodeQuery::Compiler
7
7
 
8
8
  # Initialize a String.
9
9
  # @param value [String] the string value
10
- def initialize(value:)
10
+ # @param adapter [NodeQuery::Adapter]
11
+ def initialize(value:, adapter:)
11
12
  @value = value
13
+ @adapter = adapter
12
14
  end
13
15
 
14
16
  # Get the expected value.
@@ -19,7 +21,7 @@ module NodeQuery::Compiler
19
21
  # @param base_node [Node] the base node for evaluated value
20
22
  # @return [String] the expected string, if it contains evaluated value, evaluate the node value.
21
23
  def expected_value(base_node)
22
- NodeQuery::Helper.evaluate_node_value(base_node, @value)
24
+ NodeQuery::Helper.evaluate_node_value(base_node, @value, @adapter)
23
25
  end
24
26
 
25
27
  # Check if the actual value equals the node value.
@@ -27,7 +29,7 @@ module NodeQuery::Compiler
27
29
  # @param base_node [Node] the base node for evaluated value
28
30
  # @return [Boolean] true if the actual value equals the node value.
29
31
  def is_equal?(actual, expected)
30
- NodeQuery::Helper.to_string(actual) == expected
32
+ NodeQuery::Helper.to_string(actual, @adapter) == expected
31
33
  end
32
34
 
33
35
  # Get valid operators.
@@ -7,8 +7,10 @@ module NodeQuery::Compiler
7
7
 
8
8
  # Initliaze a Symobol.
9
9
  # @param value [Symbol] the symbol value
10
- def initialize(value:)
10
+ # @param adapter [NodeQuery::Adapter]
11
+ def initialize(value:, adapter:)
11
12
  @value = value
13
+ @adapter = adapter
12
14
  end
13
15
 
14
16
  # Get valid operators.
@@ -5,13 +5,14 @@ class NodeQuery::Helper
5
5
  # Get target node by the keys.
6
6
  # @param node [Node] ast node
7
7
  # @param keys [String|Array] keys of child node.
8
+ # @param adapter [NodeQuery::Adapter]
8
9
  # @return [Node|] the target node.
9
- def get_target_node(node, keys)
10
+ def get_target_node(node, keys, adapter)
10
11
  return unless node
11
12
 
12
13
  first_key, rest_keys = keys.to_s.split('.', 2)
13
14
  if node.is_a?(Array) && first_key === "*"
14
- return node.map { |child_node| get_target_node(child_node, rest_keys) }
15
+ return node.map { |child_node| get_target_node(child_node, rest_keys, adapter) }
15
16
  end
16
17
 
17
18
  if node.is_a?(Array) && first_key =~ /\d+/
@@ -19,21 +20,22 @@ class NodeQuery::Helper
19
20
  elsif node.respond_to?(first_key)
20
21
  child_node = node.send(first_key)
21
22
  elsif first_key == "node_type"
22
- child_node = NodeQuery.adapter.get_node_type(node)
23
+ child_node = adapter.get_node_type(node)
23
24
  end
24
25
 
25
26
  return child_node unless rest_keys
26
27
 
27
- return get_target_node(child_node, rest_keys)
28
+ return get_target_node(child_node, rest_keys, adapter)
28
29
  end
29
30
 
30
31
  # Recursively handle child nodes.
31
32
  # @param node [Node] ast node
33
+ # @param adapter [NodeQuery::Adapter] adapter
32
34
  # @yield [child] Gives a child node.
33
35
  # @yieldparam child [Node] child node
34
- def handle_recursive_child(node, &block)
35
- NodeQuery.adapter.get_children(node).each do |child|
36
- handle_child(child, &block)
36
+ def handle_recursive_child(node, adapter, &block)
37
+ adapter.get_children(node).each do |child|
38
+ handle_child(child, adapter, &block)
37
39
  end
38
40
  end
39
41
 
@@ -43,18 +45,19 @@ class NodeQuery::Helper
43
45
  # evaluated_node_value(node, "@{{value}}") # => @id
44
46
  # @param node [Node] ast node
45
47
  # @param str [String] string to be evaluated
48
+ # @param adapter [NodeQuery::Adapter] adapter
46
49
  # @return [String] evaluated string
47
- def evaluate_node_value(node, str)
50
+ def evaluate_node_value(node, str, adapter)
48
51
  str.scan(/{{(.+?)}}/).each do |match_data|
49
- target_node = NodeQuery::Helper.get_target_node(node, match_data.first)
50
- str = str.sub("{{#{match_data.first}}}", to_string(target_node))
52
+ target_node = NodeQuery::Helper.get_target_node(node, match_data.first, adapter)
53
+ str = str.sub("{{#{match_data.first}}}", to_string(target_node, adapter))
51
54
  end
52
55
  str
53
56
  end
54
57
 
55
- def to_string(node)
56
- if NodeQuery.adapter.is_node?(node)
57
- return NodeQuery.adapter.get_source(node)
58
+ def to_string(node, adapter)
59
+ if adapter.is_node?(node)
60
+ return adapter.get_source(node)
58
61
  end
59
62
 
60
63
  node.to_s
@@ -62,13 +65,13 @@ class NodeQuery::Helper
62
65
 
63
66
  private
64
67
 
65
- def handle_child(node, &block)
66
- if NodeQuery.adapter.is_node?(node)
68
+ def handle_child(node, adapter, &block)
69
+ if adapter.is_node?(node)
67
70
  block.call(node)
68
- handle_recursive_child(node, &block)
71
+ handle_recursive_child(node, adapter, &block)
69
72
  elsif node.is_a?(Array)
70
73
  node.each do |child_node|
71
- handle_child(child_node, &block) unless child_node.nil?
74
+ handle_child(child_node, adapter, &block) unless child_node.nil?
72
75
  end
73
76
  end
74
77
  end
@@ -5,8 +5,10 @@ class NodeQuery::NodeRules
5
5
 
6
6
  # Initialize a NodeRules.
7
7
  # @param rules [Hash] the nod rules
8
- def initialize(rules)
8
+ # @param adapter [NodeQuery::Adapter]
9
+ def initialize(rules, adapter:)
9
10
  @rules = rules
11
+ @adapter = adapter
10
12
  end
11
13
 
12
14
  # Query nodes by the rules.
@@ -28,14 +30,14 @@ class NodeQuery::NodeRules
28
30
  return matching_nodes if options[:stop_at_first_match]
29
31
  end
30
32
  if options[:recursive]
31
- NodeQuery::Helper.handle_recursive_child(node) do |child_node|
33
+ NodeQuery::Helper.handle_recursive_child(node, @adapter) do |child_node|
32
34
  if match_node?(child_node)
33
35
  matching_nodes.push(child_node)
34
36
  break if options[:stop_at_first_match]
35
37
  end
36
38
  end
37
39
  else
38
- NodeQuery.adapter.get_children(node).each do |child_node|
40
+ @adapter.get_children(node).each do |child_node|
39
41
  if match_node?(child_node)
40
42
  matching_nodes.push(child_node)
41
43
  break if options[:stop_at_first_match]
@@ -53,10 +55,10 @@ class NodeQuery::NodeRules
53
55
  last_key = multi_keys.last
54
56
  actual =
55
57
  KEYWORDS.include?(last_key) ?
56
- NodeQuery::Helper.get_target_node(node, multi_keys[0...-1].join('.')) :
57
- NodeQuery::Helper.get_target_node(node, multi_keys.join('.'))
58
+ NodeQuery::Helper.get_target_node(node, multi_keys[0...-1].join('.'), @adapter) :
59
+ NodeQuery::Helper.get_target_node(node, multi_keys.join('.'), @adapter)
58
60
  expected = expected_value(@rules, multi_keys)
59
- expected = NodeQuery::Helper.evaluate_node_value(node, expected) if expected.is_a?(String)
61
+ expected = NodeQuery::Helper.evaluate_node_value(node, expected, @adapter) if expected.is_a?(String)
60
62
  case last_key
61
63
  when :includes
62
64
  actual.any? { |actual_value| match_value?(actual_value, expected) }
@@ -95,22 +97,22 @@ class NodeQuery::NodeRules
95
97
 
96
98
  case expected
97
99
  when Symbol
98
- if NodeQuery.adapter.is_node?(actual)
99
- actual_source = NodeQuery.adapter.get_source(actual)
100
+ if @adapter.is_node?(actual)
101
+ actual_source = @adapter.get_source(actual)
100
102
  actual_source == ":#{expected}" || actual_source == expected.to_s
101
103
  else
102
104
  actual.to_sym == expected
103
105
  end
104
106
  when String
105
- if NodeQuery.adapter.is_node?(actual)
106
- actual_source = NodeQuery.adapter.get_source(actual)
107
+ if @adapter.is_node?(actual)
108
+ actual_source = @adapter.get_source(actual)
107
109
  actual_source == expected || actual_source == unwrap_quote(expected) ||
108
110
  unwrap_quote(actual_source) == expected || unwrap_quote(actual_source) == unwrap_quote(expected)
109
111
  else
110
112
  actual.to_s == expected || wrap_quote(actual.to_s) == expected
111
113
  end
112
114
  when Regexp
113
- if NodeQuery.adapter.is_node?(actual)
115
+ if @adapter.is_node?(actual)
114
116
  actual.to_source =~ Regexp.new(expected.to_s, Regexp::MULTILINE)
115
117
  else
116
118
  actual.to_s =~ Regexp.new(expected.to_s, Regexp::MULTILINE)
@@ -120,13 +122,13 @@ class NodeQuery::NodeRules
120
122
 
121
123
  actual.zip(expected).all? { |a, e| match_value?(a, e) }
122
124
  when NilClass
123
- if NodeQuery.adapter.is_node?(actual)
125
+ if @adapter.is_node?(actual)
124
126
  actual.to_value.nil?
125
127
  else
126
128
  actual.nil?
127
129
  end
128
130
  when Numeric
129
- if NodeQuery.adapter.is_node?(actual)
131
+ if @adapter.is_node?(actual)
130
132
  actual.children[0] == expected
131
133
  else
132
134
  actual == expected
@@ -136,7 +138,7 @@ class NodeQuery::NodeRules
136
138
  when FalseClass
137
139
  false == actual&.to_value
138
140
  else
139
- if NodeQuery.adapter.is_node?(expected)
141
+ if @adapter.is_node?(expected)
140
142
  actual == expected
141
143
  else
142
144
  raise NodeQuery::MethodNotSupported, "#{expected} is not supported"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class NodeQuery
4
- VERSION = "1.13.12"
4
+ VERSION = "1.14.0"
5
5
  end
data/lib/node_query.rb CHANGED
@@ -6,6 +6,7 @@ require_relative "./node_query_parser.racc"
6
6
 
7
7
  class NodeQuery
8
8
  class MethodNotSupported < StandardError; end
9
+ class InvalidAdapterError < StandardError; end
9
10
 
10
11
  autoload :Adapter, "node_query/adapter"
11
12
  autoload :ParserAdapter, "node_query/adapter/parser"
@@ -14,26 +15,15 @@ class NodeQuery
14
15
  autoload :Helper, "node_query/helper"
15
16
  autoload :NodeRules, "node_query/node_rules"
16
17
 
17
- # Configure NodeQuery
18
- # @param [Hash] options options to configure
19
- # @option options [NodeQuery::Adapter] :adapter the adpater
20
- def self.configure(options)
21
- @adapter = options[:adapter]
22
- end
23
-
24
- # Get the adapter
25
- # @return [NodeQuery::Adapter] current adapter, by default is {NodeQuery::ParserAdapter}
26
- def self.adapter
27
- @adapter ||= ParserAdapter.new
28
- end
29
-
30
18
  # Initialize a NodeQuery.
31
19
  # @param nql_or_ruls [String | Hash] node query language or node rules
32
- def initialize(nql_or_ruls)
20
+ # @param adapter [Symbol] :parser or :syntax_tree
21
+ def initialize(nql_or_ruls, adapter: :parser)
22
+ adapter_instance = get_adapter_instance(adapter)
33
23
  if nql_or_ruls.is_a?(String)
34
- @expression = NodeQueryParser.new.parse(nql_or_ruls)
24
+ @expression = NodeQueryParser.new(adapter: adapter_instance).parse(nql_or_ruls)
35
25
  else
36
- @rules = NodeRules.new(nql_or_ruls)
26
+ @rules = NodeRules.new(nql_or_ruls, adapter: adapter_instance)
37
27
  end
38
28
  end
39
29
 
@@ -66,4 +56,17 @@ class NodeQuery
66
56
  false
67
57
  end
68
58
  end
59
+
60
+ private
61
+
62
+ def get_adapter_instance(adapter)
63
+ case adapter.to_sym
64
+ when :parser
65
+ ParserAdapter.new
66
+ when :syntax_tree
67
+ SyntaxTreeAdapter.new
68
+ else
69
+ raise InvalidAdapterError, "adapter #{adapter} is not supported"
70
+ end
71
+ end
69
72
  end
@@ -7,18 +7,19 @@
7
7
  require 'racc/parser.rb'
8
8
  class NodeQueryParser < Racc::Parser
9
9
 
10
- def initialize
11
- @lexer = NodeQueryLexer.new
12
- end
13
-
14
- def parse string
15
- @lexer.parse string
16
- do_parse
17
- end
18
-
19
- def next_token
20
- @lexer.next_token
21
- end
10
+ def initialize(adapter:)
11
+ @lexer = NodeQueryLexer.new
12
+ @adapter = adapter
13
+ end
14
+
15
+ def parse string
16
+ @lexer.parse string
17
+ do_parse
18
+ end
19
+
20
+ def next_token
21
+ @lexer.next_token
22
+ end
22
23
  ##### State transition tables begin ###
23
24
 
24
25
  racc_action_table = [
@@ -213,31 +214,31 @@ def _reduce_4(val, _values)
213
214
  end
214
215
 
215
216
  def _reduce_5(val, _values)
216
- NodeQuery::Compiler::Selector.new(basic_selector: val[0], position: val[1] )
217
+ NodeQuery::Compiler::Selector.new(basic_selector: val[0], position: val[1], adapter: @adapter )
217
218
  end
218
219
 
219
220
  def _reduce_6(val, _values)
220
- NodeQuery::Compiler::Selector.new(basic_selector: val[0])
221
+ NodeQuery::Compiler::Selector.new(basic_selector: val[0], adapter: @adapter)
221
222
  end
222
223
 
223
224
  def _reduce_7(val, _values)
224
- NodeQuery::Compiler::Selector.new(pseudo_class: val[0], pseudo_selector: val[2])
225
+ NodeQuery::Compiler::Selector.new(pseudo_class: val[0], pseudo_selector: val[2], adapter: @adapter)
225
226
  end
226
227
 
227
228
  def _reduce_8(val, _values)
228
- NodeQuery::Compiler::Selector.new(relationship: val[0], rest: val[1])
229
+ NodeQuery::Compiler::Selector.new(relationship: val[0], rest: val[1], adapter: @adapter)
229
230
  end
230
231
 
231
232
  def _reduce_9(val, _values)
232
- NodeQuery::Compiler::Selector.new(goto_scope: val[0], rest: val[1])
233
+ NodeQuery::Compiler::Selector.new(goto_scope: val[0], rest: val[1], adapter: @adapter)
233
234
  end
234
235
 
235
236
  def _reduce_10(val, _values)
236
- NodeQuery::Compiler::BasicSelector.new(node_type: val[0])
237
+ NodeQuery::Compiler::BasicSelector.new(node_type: val[0], adapter: @adapter)
237
238
  end
238
239
 
239
240
  def _reduce_11(val, _values)
240
- NodeQuery::Compiler::BasicSelector.new(node_type: val[0], attribute_list: val[1])
241
+ NodeQuery::Compiler::BasicSelector.new(node_type: val[0], attribute_list: val[1], adapter: @adapter)
241
242
  end
242
243
 
243
244
  def _reduce_12(val, _values)
@@ -249,57 +250,57 @@ def _reduce_13(val, _values)
249
250
  end
250
251
 
251
252
  def _reduce_14(val, _values)
252
- NodeQuery::Compiler::Attribute.new(key: val[1], value: val[3], operator: val[2])
253
+ NodeQuery::Compiler::Attribute.new(key: val[1], value: val[3], operator: val[2], adapter: @adapter)
253
254
  end
254
255
 
255
256
  def _reduce_15(val, _values)
256
- NodeQuery::Compiler::Attribute.new(key: val[1], value: NodeQuery::Compiler::ArrayValue.new, operator: val[2])
257
+ NodeQuery::Compiler::Attribute.new(key: val[1], value: NodeQuery::Compiler::ArrayValue.new, operator: val[2], adapter: @adapter)
257
258
  end
258
259
 
259
260
  def _reduce_16(val, _values)
260
- NodeQuery::Compiler::Attribute.new(key: val[1], value: val[4], operator: val[2])
261
+ NodeQuery::Compiler::Attribute.new(key: val[1], value: val[4], operator: val[2], adapter: @adapter)
261
262
  end
262
263
 
263
264
  def _reduce_17(val, _values)
264
- NodeQuery::Compiler::ArrayValue.new(value: val[0], rest: val[1])
265
+ NodeQuery::Compiler::ArrayValue.new(value: val[0], rest: val[1], adapter: @adapter)
265
266
  end
266
267
 
267
268
  def _reduce_18(val, _values)
268
- NodeQuery::Compiler::ArrayValue.new(value: val[0])
269
+ NodeQuery::Compiler::ArrayValue.new(value: val[0], adapter: @adapter)
269
270
  end
270
271
 
271
272
  # reduce 19 omitted
272
273
 
273
274
  def _reduce_20(val, _values)
274
- NodeQuery::Compiler::Boolean.new(value: val[0])
275
+ NodeQuery::Compiler::Boolean.new(value: val[0], adapter: @adapter)
275
276
  end
276
277
 
277
278
  def _reduce_21(val, _values)
278
- NodeQuery::Compiler::Float.new(value: val[0])
279
+ NodeQuery::Compiler::Float.new(value: val[0], adapter: @adapter)
279
280
  end
280
281
 
281
282
  def _reduce_22(val, _values)
282
- NodeQuery::Compiler::Integer.new(value: val[0])
283
+ NodeQuery::Compiler::Integer.new(value: val[0], adapter: @adapter)
283
284
  end
284
285
 
285
286
  def _reduce_23(val, _values)
286
- NodeQuery::Compiler::Nil.new(value: val[0])
287
+ NodeQuery::Compiler::Nil.new(value: val[0], adapter: @adapter)
287
288
  end
288
289
 
289
290
  def _reduce_24(val, _values)
290
- NodeQuery::Compiler::Regexp.new(value: val[0])
291
+ NodeQuery::Compiler::Regexp.new(value: val[0], adapter: @adapter)
291
292
  end
292
293
 
293
294
  def _reduce_25(val, _values)
294
- NodeQuery::Compiler::String.new(value: val[0])
295
+ NodeQuery::Compiler::String.new(value: val[0], adapter: @adapter)
295
296
  end
296
297
 
297
298
  def _reduce_26(val, _values)
298
- NodeQuery::Compiler::Symbol.new(value: val[0])
299
+ NodeQuery::Compiler::Symbol.new(value: val[0], adapter: @adapter)
299
300
  end
300
301
 
301
302
  def _reduce_27(val, _values)
302
- NodeQuery::Compiler::Identifier.new(value: val[0])
303
+ NodeQuery::Compiler::Identifier.new(value: val[0], adapter: @adapter)
303
304
  end
304
305
 
305
306
  def _reduce_none(val, _values)
@@ -13,44 +13,45 @@ rule
13
13
  | selector { NodeQuery::Compiler::Expression.new(selector: val[0]) }
14
14
 
15
15
  selector
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]) }
18
- | tPSEUDO_CLASS tOPEN_SELECTOR selector tCLOSE_SELECTOR { NodeQuery::Compiler::Selector.new(pseudo_class: val[0], pseudo_selector: val[2]) }
19
- | tRELATIONSHIP selector { NodeQuery::Compiler::Selector.new(relationship: val[0], rest: val[1]) }
20
- | tGOTO_SCOPE selector { NodeQuery::Compiler::Selector.new(goto_scope: val[0], rest: val[1]) }
16
+ : basic_selector tPOSITION { NodeQuery::Compiler::Selector.new(basic_selector: val[0], position: val[1], adapter: @adapter ) }
17
+ | basic_selector { NodeQuery::Compiler::Selector.new(basic_selector: val[0], adapter: @adapter) }
18
+ | tPSEUDO_CLASS tOPEN_SELECTOR selector tCLOSE_SELECTOR { NodeQuery::Compiler::Selector.new(pseudo_class: val[0], pseudo_selector: val[2], adapter: @adapter) }
19
+ | tRELATIONSHIP selector { NodeQuery::Compiler::Selector.new(relationship: val[0], rest: val[1], adapter: @adapter) }
20
+ | tGOTO_SCOPE selector { NodeQuery::Compiler::Selector.new(goto_scope: val[0], rest: val[1], adapter: @adapter) }
21
21
 
22
22
  basic_selector
23
- : tNODE_TYPE { NodeQuery::Compiler::BasicSelector.new(node_type: val[0]) }
24
- | tNODE_TYPE attribute_list { NodeQuery::Compiler::BasicSelector.new(node_type: val[0], attribute_list: val[1]) }
23
+ : tNODE_TYPE { NodeQuery::Compiler::BasicSelector.new(node_type: val[0], adapter: @adapter) }
24
+ | tNODE_TYPE attribute_list { NodeQuery::Compiler::BasicSelector.new(node_type: val[0], attribute_list: val[1], adapter: @adapter) }
25
25
 
26
26
  attribute_list
27
27
  : attribute attribute_list { NodeQuery::Compiler::AttributeList.new(attribute: val[0], rest: val[1]) }
28
28
  | attribute { NodeQuery::Compiler::AttributeList.new(attribute: val[0]) }
29
29
 
30
30
  attribute
31
- : tOPEN_ATTRIBUTE tKEY tOPERATOR value tCLOSE_ATTRIBUTE { NodeQuery::Compiler::Attribute.new(key: val[1], value: val[3], operator: val[2]) }
32
- | tOPEN_ATTRIBUTE tKEY tOPERATOR tOPEN_ARRAY tCLOSE_ARRAY tCLOSE_ATTRIBUTE { NodeQuery::Compiler::Attribute.new(key: val[1], value: NodeQuery::Compiler::ArrayValue.new, operator: val[2]) }
33
- | tOPEN_ATTRIBUTE tKEY tOPERATOR tOPEN_ARRAY array_value tCLOSE_ARRAY tCLOSE_ATTRIBUTE { NodeQuery::Compiler::Attribute.new(key: val[1], value: val[4], operator: val[2]) }
31
+ : tOPEN_ATTRIBUTE tKEY tOPERATOR value tCLOSE_ATTRIBUTE { NodeQuery::Compiler::Attribute.new(key: val[1], value: val[3], operator: val[2], adapter: @adapter) }
32
+ | tOPEN_ATTRIBUTE tKEY tOPERATOR tOPEN_ARRAY tCLOSE_ARRAY tCLOSE_ATTRIBUTE { NodeQuery::Compiler::Attribute.new(key: val[1], value: NodeQuery::Compiler::ArrayValue.new, operator: val[2], adapter: @adapter) }
33
+ | tOPEN_ATTRIBUTE tKEY tOPERATOR tOPEN_ARRAY array_value tCLOSE_ARRAY tCLOSE_ATTRIBUTE { NodeQuery::Compiler::Attribute.new(key: val[1], value: val[4], operator: val[2], adapter: @adapter) }
34
34
 
35
35
  array_value
36
- : value array_value { NodeQuery::Compiler::ArrayValue.new(value: val[0], rest: val[1]) }
37
- | value { NodeQuery::Compiler::ArrayValue.new(value: val[0]) }
36
+ : value array_value { NodeQuery::Compiler::ArrayValue.new(value: val[0], rest: val[1], adapter: @adapter) }
37
+ | value { NodeQuery::Compiler::ArrayValue.new(value: val[0], adapter: @adapter) }
38
38
 
39
39
  value
40
40
  : selector
41
- | tBOOLEAN { NodeQuery::Compiler::Boolean.new(value: val[0]) }
42
- | tFLOAT { NodeQuery::Compiler::Float.new(value: val[0]) }
43
- | tINTEGER { NodeQuery::Compiler::Integer.new(value: val[0])}
44
- | tNIL { NodeQuery::Compiler::Nil.new(value: val[0]) }
45
- | tREGEXP { NodeQuery::Compiler::Regexp.new(value: val[0]) }
46
- | tSTRING { NodeQuery::Compiler::String.new(value: val[0]) }
47
- | tSYMBOL { NodeQuery::Compiler::Symbol.new(value: val[0]) }
48
- | tIDENTIFIER_VALUE { NodeQuery::Compiler::Identifier.new(value: val[0]) }
41
+ | tBOOLEAN { NodeQuery::Compiler::Boolean.new(value: val[0], adapter: @adapter) }
42
+ | tFLOAT { NodeQuery::Compiler::Float.new(value: val[0], adapter: @adapter) }
43
+ | tINTEGER { NodeQuery::Compiler::Integer.new(value: val[0], adapter: @adapter) }
44
+ | tNIL { NodeQuery::Compiler::Nil.new(value: val[0], adapter: @adapter) }
45
+ | tREGEXP { NodeQuery::Compiler::Regexp.new(value: val[0], adapter: @adapter) }
46
+ | tSTRING { NodeQuery::Compiler::String.new(value: val[0], adapter: @adapter) }
47
+ | tSYMBOL { NodeQuery::Compiler::Symbol.new(value: val[0], adapter: @adapter) }
48
+ | tIDENTIFIER_VALUE { NodeQuery::Compiler::Identifier.new(value: val[0], adapter: @adapter) }
49
49
  end
50
50
 
51
51
  ---- inner
52
- def initialize
52
+ def initialize(adapter:)
53
53
  @lexer = NodeQueryLexer.new
54
+ @adapter = adapter
54
55
  end
55
56
 
56
57
  def parse string
data/sig/node_query.rbs CHANGED
@@ -1,11 +1,7 @@
1
1
  class NodeQuery[T]
2
2
  VERSION: String
3
3
 
4
- def self.configure: (options: { adapter: NodeQuery::Adapter }) -> void
5
-
6
- def self.adapter: () -> NodeQuery::Adapter
7
-
8
- def initialize: (nqlOrRues: String | Hash) -> NodeQuery
4
+ def initialize: (nqlOrRues: String | Hash, adapter: Symbol) -> NodeQuery
9
5
 
10
6
  def query_nodes: (node: T, options: Hash) -> Array[T]
11
7
 
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.13.12
4
+ version: 1.14.0
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-09-29 00:00:00.000000000 Z
11
+ date: 2023-11-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: ast node query language
14
14
  email:
@@ -78,7 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
78
  - !ruby/object:Gem::Version
79
79
  version: '0'
80
80
  requirements: []
81
- rubygems_version: 3.4.18
81
+ rubygems_version: 3.4.20
82
82
  signing_key:
83
83
  specification_version: 4
84
84
  summary: ast node query language