node_query 1.3.0 → 1.5.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: 8c7363cd71167f293f046d95014611ceb1f695c6639036a3cc0e202ab0ae5b2b
4
- data.tar.gz: 161c5784daae011699a1300b0cedc2f18bdc7235f71b7e89e1b1dce41caef71a
3
+ metadata.gz: 526c6ef0b0f58f1a8f1f7aff14e147ce4220cd6366bea5d5108db29591e0ab02
4
+ data.tar.gz: 347fc60e4f3629871356757349c5a126235a192049eefa713fb15890d26033d0
5
5
  SHA512:
6
- metadata.gz: 356e94651bf61cb5c244399bbfe0aa353aafe3a3506fc7e6b1efba9cc4c853a0b963850c9d64e9b9de26dd3986f10967b2752a3dc7ec627dfd7466ddcf9a70f8
7
- data.tar.gz: 0fdacf2a86292f60968a02054ce43e02a131d3a1da7c528d1e6df2e8279afd5de19afe714a80bd1b9ab17143c433b4e219c7be2cf8b55e3f28e45ff82a25d274
6
+ metadata.gz: b94b5f913b63824d89211dc6156add8ada6963a0122cf5d6adafc60fcf20af62a4f9a239f2bd341ef12167adcf8a5785b96b9c1b6bbad41d2ebe3f0eb90b498f
7
+ data.tar.gz: 2a9613221d35553af7e91e1e2a20792dbee63572634e254633cb0951180adb48b582454dee93f6c817d870ec16962af346bb1ce4ea253b253da10cb7e78ada49
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.5.0 (2022-09-15)
4
+
5
+ * Add `Helper.to_string`
6
+ * Only check the current node if `including_self` is true and `recursive` is false
7
+ * Fix `Regexp#match?` and `String#match?`
8
+ * Rename `stop_on_match` to `stop_at_first_match`
9
+
10
+ ## 1.4.0 (2022-09-14)
11
+
12
+ * Add options `including_self`, `stop_on_match` and `recursive`
13
+ * Fix regex to match evaluated value
14
+
3
15
  ## 1.3.0 (2022-09-13)
4
16
 
5
17
  * Rename `NodeQuery#parse` to `NodeQuery#query_nodes`
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- node_query (1.3.0)
4
+ node_query (1.5.0)
5
5
  activesupport (< 7.0.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -62,7 +62,7 @@ It provides two apis: `query_nodes` and `match_node?`
62
62
 
63
63
  ```ruby
64
64
  node_query = NodeQuery.new(nqlOrRules: String | Hash) # Initialize NodeQuery
65
- node_query.query_nodes(node: Node, including_self = true): Node[] # Get the matching nodes.
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
  ```
68
68
 
@@ -13,14 +13,17 @@ module NodeQuery::Compiler
13
13
 
14
14
  # Query nodes by the selector and the rest expression.
15
15
  # @param node [Node] node to match
16
- # @params including_self [boolean] if query the current node.
16
+ # @param options [Hash] if query the current node
17
+ # @option options [boolean] :including_self if query the current node, default is ture
18
+ # @option options [boolean] :stop_at_first_match if stop at first match, default is false
19
+ # @option options [boolean] :recursive if recursively query child nodes, default is true
17
20
  # @return [Array<Node>] matching nodes.
18
- def query_nodes(node, including_self = true)
19
- matching_nodes = @selector.query_nodes(node, including_self)
21
+ def query_nodes(node, options = {})
22
+ matching_nodes = @selector.query_nodes(node, options)
20
23
  return matching_nodes if @rest.nil?
21
24
 
22
25
  matching_nodes.flat_map do |matching_node|
23
- @rest.query_nodes(matching_node, including_self)
26
+ @rest.query_nodes(matching_node, options)
24
27
  end
25
28
  end
26
29
 
@@ -13,13 +13,16 @@ module NodeQuery::Compiler
13
13
 
14
14
  # Query nodes by the current and the rest expression.
15
15
  # @param node [Node] node to match
16
- # @params including_self [boolean] if query the current node.
16
+ # @param options [Hash] if query the current node
17
+ # @option options [boolean] :including_self if query the current node, default is ture
18
+ # @option options [boolean] :stop_at_first_match if stop at first match, default is false
19
+ # @option options [boolean] :recursive if recursively query child nodes, default is true
17
20
  # @return [Array<Node>] matching nodes.
18
- def query_nodes(node, including_self = true)
19
- matching_nodes = @expression.query_nodes(node, including_self)
21
+ def query_nodes(node, options = {})
22
+ matching_nodes = @expression.query_nodes(node, options)
20
23
  return matching_nodes if @rest.nil?
21
24
 
22
- matching_nodes + @rest.query_nodes(node, including_self)
25
+ matching_nodes + @rest.query_nodes(node, options)
23
26
  end
24
27
 
25
28
  # Check if the node matches the expression list.
@@ -13,13 +13,16 @@ module NodeQuery::Compiler
13
13
 
14
14
  # Check if the regexp value matches the node value.
15
15
  # @param node [Node] the node
16
- # @return [Boolean] true if the regexp value matches the node value.
17
- def is_equal?(node)
18
- if NodeQuery.adapter.is_node?(node)
19
- @value.match(NodeQuery.adapter.get_source(node))
20
- else
21
- @value.match(node.to_s)
22
- end
16
+ # @param operator [String] the operator
17
+ # @return [Boolean] true if the regexp value matches the node value, otherwise, false.
18
+ def match?(node, operator = '=~')
19
+ match =
20
+ if NodeQuery.adapter.is_node?(node)
21
+ @value.match(NodeQuery.adapter.get_source(node))
22
+ else
23
+ @value.match(node.to_s)
24
+ end
25
+ operator == '=~' ? match : !match
23
26
  end
24
27
 
25
28
  # Get valid operators.
@@ -33,9 +33,13 @@ module NodeQuery::Compiler
33
33
  # * If relationship is next sibling, it try to match next sibling node.
34
34
  # * If relationship is subsequent sibling, it will match in all sibling nodes.
35
35
  # @param node [Node] node to match
36
- # @params including_self [boolean] if query the current node.
36
+ # @param options [Hash] if query the current node
37
+ # @option options [boolean] :including_self if query the current node, default is ture
38
+ # @option options [boolean] :stop_at_first_match if stop at first match, default is false
39
+ # @option options [boolean] :recursive if recursively query child nodes, default is true
37
40
  # @return [Array<Node>] matching nodes.
38
- def query_nodes(node, including_self = true)
41
+ def query_nodes(node, options = {})
42
+ options = { including_self: true, stop_at_first_match: false, recursive: true }.merge(options)
39
43
  return find_nodes_by_relationship(node) if @relationship
40
44
 
41
45
  if node.is_a?(::Array)
@@ -44,13 +48,30 @@ module NodeQuery::Compiler
44
48
 
45
49
  return find_nodes_by_goto_scope(node) if @goto_scope
46
50
 
51
+ if options[:including_self] && !options[:recursive]
52
+ return match?(node) ? [node] : []
53
+ end
54
+
47
55
  nodes = []
48
- if including_self && match?(node)
56
+ if options[:including_self] && match?(node)
49
57
  nodes << node
58
+ return nodes if options[:stop_at_first_match]
50
59
  end
51
60
  if @basic_selector
52
- NodeQuery::Helper.handle_recursive_child(node) do |child_node|
53
- nodes << child_node if match?(child_node)
61
+ if options[:recursive]
62
+ NodeQuery::Helper.handle_recursive_child(node) do |child_node|
63
+ if match?(child_node)
64
+ nodes << child_node
65
+ break if options[:stop_at_first_match]
66
+ end
67
+ end
68
+ else
69
+ NodeQuery.adapter.get_children(node).each do |child_node|
70
+ if match?(child_node)
71
+ nodes << child_node
72
+ break if options[:stop_at_first_match]
73
+ end
74
+ end
54
75
  end
55
76
  end
56
77
  nodes
@@ -27,7 +27,7 @@ module NodeQuery::Compiler
27
27
  # @param node [Node] the node
28
28
  # @return [Boolean] true if the actual value equals the node value.
29
29
  def is_equal?(node)
30
- actual_value(node).to_s == expected_value
30
+ NodeQuery::Helper.to_string(actual_value(node)) == expected_value
31
31
  end
32
32
 
33
33
  # Get valid operators.
@@ -48,11 +48,19 @@ class NodeQuery::Helper
48
48
  # @param str [String] string to be evaluated
49
49
  # @return [String] evaluated string
50
50
  def evaluate_node_value(node, str)
51
- str.scan(/{{(.*)}}/).each do |match_data|
51
+ str.scan(/{{(.*?)}}/).each do |match_data|
52
52
  target_node = NodeQuery::Helper.get_target_node(node, match_data.first)
53
- str = str.sub("{{#{match_data.first}}}", NodeQuery.adapter.get_source(target_node))
53
+ str = str.sub("{{#{match_data.first}}}", to_string(target_node))
54
54
  end
55
55
  str
56
56
  end
57
+
58
+ def to_string(node)
59
+ if NodeQuery.adapter.is_node?(node)
60
+ return NodeQuery.adapter.get_source(node)
61
+ end
62
+
63
+ node.to_s
64
+ end
57
65
  end
58
66
  end
@@ -11,16 +11,35 @@ class NodeQuery::NodeRules
11
11
 
12
12
  # Query nodes by the rules.
13
13
  # @param node [Node] node to query
14
- # @params including_self [boolean] if query the current node.
14
+ # @param options [Hash] if query the current node
15
+ # @option options [boolean] :including_self if query the current node, default is ture
16
+ # @option options [boolean] :stop_at_first_match if stop at first match, default is false
17
+ # @option options [boolean] :recursive if recursively query child nodes, default is true
15
18
  # @return [Array<Node>] matching nodes.
16
- def query_nodes(node, including_self = true)
19
+ def query_nodes(node, options = {})
20
+ options = { including_self: true, stop_at_first_match: false, recursive: true }.merge(options)
21
+ if options[:including_self] && !options[:recursive]
22
+ return match_node?(node) ? [node] : []
23
+ end
24
+
17
25
  matching_nodes = []
18
- if (including_self && match_node?(node))
26
+ if options[:including_self] && match_node?(node)
19
27
  matching_nodes.push(node)
28
+ return matching_nodes if options[:stop_at_first_match]
20
29
  end
21
- NodeQuery::Helper.handle_recursive_child(node) do |child_node|
22
- if (match_node?(child_node))
23
- matching_nodes.push(child_node)
30
+ if options[:recursive]
31
+ NodeQuery::Helper.handle_recursive_child(node) do |child_node|
32
+ if match_node?(child_node)
33
+ matching_nodes.push(child_node)
34
+ break if options[:stop_at_first_match]
35
+ end
36
+ end
37
+ else
38
+ NodeQuery.adapter.get_children(node).each do |child_node|
39
+ if match_node?(child_node)
40
+ matching_nodes.push(child_node)
41
+ break if options[:stop_at_first_match]
42
+ end
24
43
  end
25
44
  end
26
45
  matching_nodes
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class NodeQuery
4
- VERSION = "1.3.0"
4
+ VERSION = "1.5.0"
5
5
  end
data/lib/node_query.rb CHANGED
@@ -38,13 +38,16 @@ class NodeQuery
38
38
 
39
39
  # Query matching nodes.
40
40
  # @param node [Node] ast node
41
- # @param including_self [boolean] if check the node itself
41
+ # @param options [Hash] if query the current node
42
+ # @option options [boolean] :including_self if query the current node, default is ture
43
+ # @option options [boolean] :stop_at_first_match if stop at first match, default is false
44
+ # @option options [boolean] :recursive if recursively query child nodes, default is true
42
45
  # @return [Array<Node>] matching child nodes
43
- def query_nodes(node, including_self = true)
46
+ def query_nodes(node, options = {})
44
47
  if @expression
45
- @expression.query_nodes(node, including_self)
48
+ @expression.query_nodes(node, options)
46
49
  elsif @rules
47
- @rules.query_nodes(node, including_self)
50
+ @rules.query_nodes(node, options)
48
51
  else
49
52
  []
50
53
  end
data/sig/node_query.rbs CHANGED
@@ -7,7 +7,7 @@ class NodeQuery[T]
7
7
 
8
8
  def initialize: (nqlOrRues: String | Hash) -> NodeQuery
9
9
 
10
- def query_nodes: (node: T, including_self: boolean) -> Array[T]
10
+ def query_nodes: (node: T, options: Hash) -> Array[T]
11
11
 
12
12
  def match_node?: (node: T) -> boolean
13
13
  end
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.3.0
4
+ version: 1.5.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-09-13 00:00:00.000000000 Z
11
+ date: 2022-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport