node_query 1.13.12 → 1.14.0

Sign up to get free protection for your applications and to get access to all the features.
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