node_query 1.8.1 → 1.10.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: 3dec6cb33f976a8d4eab33d781441941dad502fe794ced0b22ee37e2ef15afd0
4
- data.tar.gz: 50b703ba607c8efe543fa4a019d84959416795d6fe199b7320eb6f2c0fe454dd
3
+ metadata.gz: cc14f10f4a27631913cd6d9b3b66b100864778756bc317b1529abe45999255b4
4
+ data.tar.gz: 2e04f47d2bbc0eade7ea2a047fe27174ec0e343d875203a0d3cd39fcaea50120
5
5
  SHA512:
6
- metadata.gz: 9b7232c12af438ecbc69dfd24ee62c6f3c60be26760047afa95154d862da50a098c9079f4c744d15f31ab34e319a2bc8a874fb4d4fb396143f2a6e5e802f7d2f
7
- data.tar.gz: 60afc766f3d6e4b3cf44efc3e7bf6fac3b7256b8ce47831311ac3fef6a23768bb40ec5d0c5ae6bdf6193dbba6bf40f6349aa71f9d7726a1c9ecf1841ed565fe3
6
+ metadata.gz: 4b434f39629e544435594f4d299b845841b4610bed644954b0e835a7eed7d1b178d510d2ba5be8bfea0d3365d15f46d73a64ea8e9310037f4a851fa9989d05f3
7
+ data.tar.gz: bee545aae91e3769cb616e156f4cf6a69f628f5cc3a9e25432ea7eb9224a8ea49f1f76518b09601ce692b52790e5f0fd5da518d55650a243c0478d9056ac9a53
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.10.0 (2022-10-26)
4
+
5
+ * Add `NodeQuery::MethodNotSupported` error
6
+ * Add `NodeQuery::AnyValue` to match any value in node rules
7
+
8
+ ## 1.9.0 (2022-10-23)
9
+
10
+ * Support `NOT INCLUDES` operator
11
+ * `includes` / `not_includes` a selector
12
+
3
13
  ## 1.8.1 (2022-10-15)
4
14
 
5
15
  * Fix `filter_by_position` with empty nodes
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- node_query (1.8.1)
4
+ node_query (1.10.0)
5
5
  activesupport (< 7.0.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -210,6 +210,12 @@ Value of name is neither User nor Account
210
210
 
211
211
  Value of arguments includes id
212
212
 
213
+ ```
214
+ .def[arguments NOT INCLUDES id]
215
+ ```
216
+
217
+ Value of arguments not includes id
218
+
213
219
  ```
214
220
  .class[name=~/User/]
215
221
  ```
@@ -434,6 +440,12 @@ Value of name is neither User nor Account
434
440
 
435
441
  Value of arguments includes id
436
442
 
443
+ ```
444
+ { node_type: 'def', arguments: { not_includes: 'id' } }
445
+ ```
446
+
447
+ Value of arguments not includes id
448
+
437
449
  ```
438
450
  { node_type: 'class', name: /User/ }
439
451
  ```
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A new type to match any value.
4
+ class NodeQuery::AnyValue
5
+ end
@@ -31,6 +31,8 @@ module NodeQuery::Compiler
31
31
  "#{@key} not in (#{@value})"
32
32
  when 'includes'
33
33
  "#{@key} includes #{@value}"
34
+ when 'not_includes'
35
+ "#{@key} not includes #{@value}"
34
36
  else
35
37
  "#{@key}=#{@value}"
36
38
  end
@@ -3,9 +3,9 @@
3
3
  module NodeQuery::Compiler
4
4
  # Compare acutal value with expected value.
5
5
  module Comparable
6
- SIMPLE_VALID_OPERATORS = ['==', '!=', 'includes']
7
- STRING_VALID_OPERATORS = ['==', '!=', '^=', '$=', '*=', 'includes']
8
- NUMBER_VALID_OPERATORS = ['==', '!=', '>', '>=', '<', '<=', 'includes']
6
+ SIMPLE_VALID_OPERATORS = ['==', '!=', 'includes', 'not_includes']
7
+ STRING_VALID_OPERATORS = ['==', '!=', '^=', '$=', '*=', 'includes', 'not_includes']
8
+ NUMBER_VALID_OPERATORS = ['==', '!=', '>', '>=', '<', '<=', 'includes', 'not_includes']
9
9
  ARRAY_VALID_OPERATORS = ['==', '!=', 'in', 'not_in']
10
10
  REGEXP_VALID_OPERATORS = ['=~', '!~']
11
11
 
@@ -60,7 +60,9 @@ module NodeQuery::Compiler
60
60
  expected.all? { |expected_child| expected_child.match?(node, base_node, '!=') }
61
61
  end
62
62
  when 'includes'
63
- actual.any? { |actual_child| actual_child == expected }
63
+ actual.any? { |actual_child| expected.match?(actual_child) }
64
+ when 'not_includes'
65
+ actual.none? { |actual_child| expected.match?(actual_child) }
64
66
  else
65
67
  if expected.is_a?(::Array)
66
68
  actual.is_a?(::Array) && actual.size == expected.size &&
@@ -25,8 +25,18 @@ module NodeQuery::Compiler
25
25
  # Check if node matches the selector.
26
26
  # @param node [Parser::AST::Node] the node
27
27
  # @param base_node [Parser::AST::Node] the base node for evaluated node
28
- def match?(node, base_node)
29
- NodeQuery.adapter.is_node?(node) && (!@basic_selector || @basic_selector.match?(node, base_node)) && match_pseudo_class?(node)
28
+ def match?(node, base_node, operator = "==")
29
+ if node.is_a?(::Array)
30
+ case operator
31
+ when "not_includes"
32
+ return node.none? { |child_node| match?(child_node, base_node) }
33
+ when "includes"
34
+ return node.any? { |child_node| match?(child_node, base_node) }
35
+ else
36
+ return false
37
+ end
38
+ end
39
+ NodeQuery.adapter.is_node?(node) && (!@basic_selector || (operator == "!=" ? !@basic_selector.match?(node, base_node) : @basic_selector.match?(node, base_node))) && match_pseudo_class?(node)
30
40
  end
31
41
 
32
42
  # Query nodes by the selector.
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class NodeQuery::NodeRules
4
- KEYWORDS = %i[any includes not in not_in gt gte lt lte]
4
+ KEYWORDS = %i[not_includes includes not in not_in gt gte lt lte]
5
5
 
6
6
  # Initialize a NodeRules.
7
7
  # @param rules [Hash] the nod rules
@@ -57,8 +57,10 @@ class NodeQuery::NodeRules
57
57
  expected = expected_value(@rules, multi_keys)
58
58
  expected = NodeQuery::Helper.evaluate_node_value(node, expected) if expected.is_a?(String)
59
59
  case last_key
60
- when :any, :includes
60
+ when :includes
61
61
  actual.any? { |actual_value| match_value?(actual_value, expected) }
62
+ when :not_includes
63
+ actual.all? { |actual_value| !match_value?(actual_value, expected) }
62
64
  when :not
63
65
  !match_value?(actual, expected)
64
66
  when :in
@@ -86,7 +88,7 @@ class NodeQuery::NodeRules
86
88
  # @param actual [Object] actual value.
87
89
  # @param expected [Object] expected value.
88
90
  # @return [Boolean]
89
- # @raise [Synvert::Core::MethodNotSupported] if expected class is not supported.
91
+ # @raise [NodeQuery::MethodNotSupported] if expected class is not supported.
90
92
  def match_value?(actual, expected)
91
93
  return true if actual == expected
92
94
 
@@ -134,10 +136,10 @@ class NodeQuery::NodeRules
134
136
  :false == actual.type
135
137
  when Parser::AST::Node
136
138
  actual == expected
137
- when Synvert::Core::Rewriter::AnyValue
139
+ when NodeQuery::AnyValue
138
140
  !actual.nil?
139
141
  else
140
- raise Synvert::Core::MethodNotSupported, "#{expected.class} is not handled for match_value?"
142
+ raise NodeQuery::MethodNotSupported, "#{expected} is not supported"
141
143
  end
142
144
  end
143
145
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class NodeQuery
4
- VERSION = "1.8.1"
4
+ VERSION = "1.10.0"
5
5
  end
data/lib/node_query.rb CHANGED
@@ -7,11 +7,14 @@ require_relative "./node_query_lexer.rex"
7
7
  require_relative "./node_query_parser.racc"
8
8
 
9
9
  class NodeQuery
10
+ class MethodNotSupported < StandardError; end
11
+
10
12
  autoload :Adapter, "node_query/adapter"
11
13
  autoload :ParserAdapter, "node_query/parser_adapter"
12
14
  autoload :Compiler, "node_query/compiler"
13
15
  autoload :Helper, "node_query/helper"
14
16
  autoload :NodeRules, "node_query/node_rules"
17
+ autoload :AnyValue, 'node_query/any_value'
15
18
 
16
19
  # Configure NodeQuery
17
20
  # @param [Hash] options options to configure
@@ -50,6 +50,7 @@ rules
50
50
  :KEY />/ { @state = :VALUE; [:tOPERATOR, '>'] }
51
51
  :KEY /</ { @state = :VALUE; [:tOPERATOR, '<'] }
52
52
  :KEY /=/ { @state = :VALUE; [:tOPERATOR, '=='] }
53
+ :KEY /not includes/i { @state = :VALUE; [:tOPERATOR, 'not_includes'] }
53
54
  :KEY /includes/i { @state = :VALUE; [:tOPERATOR, 'includes'] }
54
55
  :KEY /not in/i { @state = :VALUE; [:tOPERATOR, 'not_in'] }
55
56
  :KEY /in/i { @state = :VALUE; [:tOPERATOR, 'in'] }
@@ -179,6 +179,8 @@ class NodeQueryLexer
179
179
  action { @state = :VALUE; [:tOPERATOR, '<'] }
180
180
  when ss.skip(/=/) then
181
181
  action { @state = :VALUE; [:tOPERATOR, '=='] }
182
+ when ss.skip(/not includes/i) then
183
+ action { @state = :VALUE; [:tOPERATOR, 'not_includes'] }
182
184
  when ss.skip(/includes/i) then
183
185
  action { @state = :VALUE; [:tOPERATOR, 'includes'] }
184
186
  when ss.skip(/not in/i) then
@@ -22,31 +22,31 @@ class NodeQueryParser < Racc::Parser
22
22
  ##### State transition tables begin ###
23
23
 
24
24
  racc_action_table = [
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 ]
25
+ 8, 7, 8, 7, 9, 37, 5, 6, 5, 6,
26
+ 28, 10, 12, 13, 17, 18, 22, 30, 31, 32,
27
+ 33, 34, 35, 36, 8, 7, 23, 24, 25, 37,
28
+ 5, 6, 8, 7, 17, 38, 41, 37, 5, 6,
29
+ nil, 30, 31, 32, 33, 34, 35, 36, nil, 30,
30
+ 31, 32, 33, 34, 35, 36, 8, 7, 8, 7,
31
+ 8, 7, 5, 6, 5, 6, 5, 6, 8, 7,
32
+ 8, 7, nil, nil, 5, 6, 5, 6 ]
33
33
 
34
34
  racc_action_check = [
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 ]
35
+ 25, 25, 0, 0, 1, 25, 25, 25, 0, 0,
36
+ 25, 2, 4, 5, 8, 9, 17, 25, 25, 25,
37
+ 25, 25, 25, 25, 28, 28, 20, 21, 22, 28,
38
+ 28, 28, 40, 40, 24, 28, 39, 40, 40, 40,
39
+ nil, 28, 28, 28, 28, 28, 28, 28, nil, 40,
40
+ 40, 40, 40, 40, 40, 40, 3, 3, 6, 6,
41
+ 7, 7, 3, 3, 6, 6, 7, 7, 10, 10,
42
+ 13, 13, nil, nil, 10, 10, 13, 13 ]
43
43
 
44
44
  racc_action_pointer = [
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 ]
45
+ -1, 4, 9, 53, -5, -2, 55, 57, 3, 15,
46
+ 65, nil, nil, 67, nil, nil, nil, 10, nil, nil,
47
+ 10, 15, 10, nil, 23, -3, nil, nil, 21, nil,
48
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, 22,
49
+ 29, nil, nil ]
50
50
 
51
51
  racc_action_default = [
52
52
  -28, -28, -2, -4, -6, -28, -28, -28, -10, -28,
@@ -56,15 +56,19 @@ racc_action_default = [
56
56
  -18, -16, -17 ]
57
57
 
58
58
  racc_goto_table = [
59
- 16, 39, 29, 11, 1, 29, 21, 27, 14, 15,
60
- nil, nil, nil, 42, 19, 20, 26, 29 ]
59
+ 14, 15, 16, 39, 1, 11, 21, 20, 27, nil,
60
+ nil, nil, nil, nil, 19, 42, nil, nil, 26, 29,
61
+ nil, nil, 29, nil, nil, nil, nil, nil, nil, nil,
62
+ nil, nil, nil, nil, 29 ]
61
63
 
62
64
  racc_goto_check = [
63
- 5, 8, 4, 2, 1, 4, 6, 7, 3, 3,
64
- nil, nil, nil, 8, 1, 3, 5, 4 ]
65
+ 3, 3, 5, 8, 1, 2, 6, 3, 7, nil,
66
+ nil, nil, nil, nil, 1, 8, nil, nil, 5, 3,
67
+ nil, nil, 3, nil, nil, nil, nil, nil, nil, nil,
68
+ nil, nil, nil, nil, 3 ]
65
69
 
66
70
  racc_goto_pointer = [
67
- nil, 4, 0, 2, -23, -8, -11, -18, -27 ]
71
+ nil, 4, 2, -6, nil, -6, -11, -17, -25 ]
68
72
 
69
73
  racc_goto_default = [
70
74
  nil, nil, 2, 3, 4, nil, nil, 40, nil ]
@@ -37,7 +37,7 @@ rule
37
37
  | value { NodeQuery::Compiler::ArrayValue.new(value: val[0]) }
38
38
 
39
39
  value
40
- : basic_selector
40
+ : selector
41
41
  | tBOOLEAN { NodeQuery::Compiler::Boolean.new(value: val[0]) }
42
42
  | tFLOAT { NodeQuery::Compiler::Float.new(value: val[0]) }
43
43
  | tINTEGER { NodeQuery::Compiler::Integer.new(value: val[0])}
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.8.1
4
+ version: 1.10.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: 2022-10-15 00:00:00.000000000 Z
11
+ date: 2022-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -40,6 +40,7 @@ files:
40
40
  - Rakefile
41
41
  - lib/node_query.rb
42
42
  - lib/node_query/adapter.rb
43
+ - lib/node_query/any_value.rb
43
44
  - lib/node_query/compiler.rb
44
45
  - lib/node_query/compiler/array_value.rb
45
46
  - lib/node_query/compiler/attribute.rb