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 +4 -4
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +1 -1
- data/README.md +12 -0
- data/lib/node_query/any_value.rb +5 -0
- data/lib/node_query/compiler/attribute.rb +2 -0
- data/lib/node_query/compiler/comparable.rb +6 -4
- data/lib/node_query/compiler/selector.rb +12 -2
- data/lib/node_query/node_rules.rb +7 -5
- data/lib/node_query/version.rb +1 -1
- data/lib/node_query.rb +3 -0
- data/lib/node_query_lexer.rex +1 -0
- data/lib/node_query_lexer.rex.rb +2 -0
- data/lib/node_query_parser.racc.rb +30 -26
- data/lib/node_query_parser.y +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc14f10f4a27631913cd6d9b3b66b100864778756bc317b1529abe45999255b4
|
4
|
+
data.tar.gz: 2e04f47d2bbc0eade7ea2a047fe27174ec0e343d875203a0d3cd39fcaea50120
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
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
|
```
|
@@ -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
|
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
|
-
|
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[
|
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 :
|
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 [
|
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
|
139
|
+
when NodeQuery::AnyValue
|
138
140
|
!actual.nil?
|
139
141
|
else
|
140
|
-
raise
|
142
|
+
raise NodeQuery::MethodNotSupported, "#{expected} is not supported"
|
141
143
|
end
|
142
144
|
end
|
143
145
|
|
data/lib/node_query/version.rb
CHANGED
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
|
data/lib/node_query_lexer.rex
CHANGED
@@ -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'] }
|
data/lib/node_query_lexer.rex.rb
CHANGED
@@ -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,
|
26
|
-
28,
|
27
|
-
33, 34, 35, 36, 8,
|
28
|
-
|
29
|
-
nil, 30, 31, 32, 33, 34, 35, 36, 30,
|
30
|
-
32, 33, 34, 35, 36, 8, 7, 8, 7,
|
31
|
-
7, 5, 6, 5, 6, 5, 6, 8, 7,
|
32
|
-
|
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,
|
36
|
-
25, 8, 9, 17,
|
37
|
-
25, 25, 25, 25, 28,
|
38
|
-
|
39
|
-
nil, 28, 28, 28, 28, 28, 28, 28,
|
40
|
-
40, 40, 40, 40, 40,
|
41
|
-
|
42
|
-
|
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
|
-
-
|
46
|
-
|
47
|
-
|
48
|
-
nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
49
|
-
|
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
|
-
|
60
|
-
nil, nil, nil,
|
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
|
-
|
64
|
-
nil, nil, nil,
|
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,
|
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 ]
|
data/lib/node_query_parser.y
CHANGED
@@ -37,7 +37,7 @@ rule
|
|
37
37
|
| value { NodeQuery::Compiler::ArrayValue.new(value: val[0]) }
|
38
38
|
|
39
39
|
value
|
40
|
-
:
|
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.
|
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-
|
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
|