node_query 1.4.0 → 1.6.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: 95dcf07d501c704e59bb792454be0bae1ddfafb915c77b6a062c6331d654564b
4
- data.tar.gz: 7b835b8479ff5239ea77dcb5ed09f4868b1a09cbdf5edc2f4ab9413d352030be
3
+ metadata.gz: 86cae1819b055b5c50aa47879d3da1902805a24fa484f9697270e1591f4af73f
4
+ data.tar.gz: 59c4f42f81cd67758c0e3e6d237c3e23e3f35aec2175ae9d4798d93b3b4d11c6
5
5
  SHA512:
6
- metadata.gz: e2dbea64418363ad059ea2b6e9d93b3c2d010bdba59317327904b6a48411517a511ab6737fe40bdf4847b2833ec4d81eb5d474be7db7d831a6119c89fe904fea
7
- data.tar.gz: c2cf0bfec6edfa28b644a38957dce1276cc287507c3c3034a39e0ce018f25e420faded6ad0c7c3c3838757df5107082c30d05fcf9f4323c5d5d3f32bc68337f1
6
+ metadata.gz: 1b10e103621f14acc695c6b27c26d15a4751c804a907273b95056516697934d381aefdb8396aa90056385b90a741052bc9d5dc8a2a2c2afe05e69101d06af958
7
+ data.tar.gz: 36063af159d24d01bdf7e447aab58fc0800a95d3c764915635a31f2f26ae7ff401a8243287c3d1b01ca5cae1ddc6753ad952dee7c7f3ffa62c66834114bc572d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.6.0 (2022-09-16)
4
+
5
+ * Rename `nodeType` to `node_type`
6
+
7
+ ## 1.5.0 (2022-09-15)
8
+
9
+ * Add `Helper.to_string`
10
+ * Only check the current node if `including_self` is true and `recursive` is false
11
+ * Fix `Regexp#match?` and `String#match?`
12
+ * Rename `stop_on_match` to `stop_at_first_match`
13
+
3
14
  ## 1.4.0 (2022-09-14)
4
15
 
5
16
  * Add options `including_self`, `stop_on_match` and `recursive`
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- node_query (1.4.0)
4
+ node_query (1.6.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, options = { including_self: true, stop_on_match: false, recursive: 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
 
@@ -83,7 +83,7 @@ node = Parser::CurrentRuby.parse(source)
83
83
 
84
84
  # It will get the node of initialize.
85
85
  NodeQuery.new('.def[name=initialize]').query_nodes(node)
86
- NodeQuery.new({ nodeType: 'def', name: 'initialize' }).query_nodes(node)
86
+ NodeQuery.new({ node_type: 'def', name: 'initialize' }).query_nodes(node)
87
87
  ```
88
88
 
89
89
  ## Node Query Language
@@ -313,7 +313,7 @@ It matches ivasgn node whose left value is either @id or @name.
313
313
  ### rules matches node type
314
314
 
315
315
  ```
316
- { nodeType: 'class' }
316
+ { node_type: 'class' }
317
317
  ```
318
318
 
319
319
  It matches class node
@@ -321,13 +321,13 @@ It matches class node
321
321
  ### rules matches attribute
322
322
 
323
323
  ```
324
- { nodeType: 'def', name: 'initialize' }
324
+ { node_type: 'def', name: 'initialize' }
325
325
  ```
326
326
 
327
327
  It matches def node whose name is initialize
328
328
 
329
329
  ```
330
- { nodeType: 'def', arguments: { "0": 1, "1": "Murphy" } }
330
+ { node_type: 'def', arguments: { "0": 1, "1": "Murphy" } }
331
331
  ```
332
332
 
333
333
  It matches def node whose arguments are 1 and Murphy.
@@ -335,7 +335,7 @@ It matches def node whose arguments are 1 and Murphy.
335
335
  ### rules matches nested attribute
336
336
 
337
337
  ```
338
- { nodeType: 'class', parent_class: { name: 'Base' } }
338
+ { node_type: 'class', parent_class: { name: 'Base' } }
339
339
  ```
340
340
 
341
341
  It matches class node whose parent class name is Base
@@ -343,7 +343,7 @@ It matches class node whose parent class name is Base
343
343
  ### rules matches evaluated value
344
344
 
345
345
  ```
346
- { nodeType: 'ivasgn', left_value: '@{{right_value}}' }
346
+ { node_type: 'ivasgn', left_value: '@{{right_value}}' }
347
347
  ```
348
348
 
349
349
  It matches ivasgn node whose left value equals '@' plus the evaluated value of right value.
@@ -351,7 +351,7 @@ It matches ivasgn node whose left value equals '@' plus the evaluated value of r
351
351
  ### rules matches nested selector
352
352
 
353
353
  ```
354
- { nodeType: 'def', body: { "0": { nodeType: 'ivasgn' } } }
354
+ { node_type: 'def', body: { "0": { node_type: 'ivasgn' } } }
355
355
  ```
356
356
 
357
357
  It matches def node whose first child node is an ivasgn node.
@@ -359,7 +359,7 @@ It matches def node whose first child node is an ivasgn node.
359
359
  ### rules matches method result
360
360
 
361
361
  ```
362
- { nodeType: 'def', arguments: { size: 2 } }
362
+ { node_type: 'def', arguments: { size: 2 } }
363
363
  ```
364
364
 
365
365
  It matches def node whose arguments size is 2.
@@ -367,73 +367,73 @@ It matches def node whose arguments size is 2.
367
367
  ### rules matches operators
368
368
 
369
369
  ```
370
- { nodeType: 'class', name: 'User' }
370
+ { node_type: 'class', name: 'User' }
371
371
  ```
372
372
 
373
373
  Value of name is equal to User
374
374
 
375
375
  ```
376
- { nodeType: 'def', arguments: { size { not: 2 } }
376
+ { node_type: 'def', arguments: { size { not: 2 } }
377
377
  ```
378
378
 
379
379
  Size of arguments is not equal to 2
380
380
 
381
381
  ```
382
- { nodeType: 'def', arguments: { size { gte: 2 } }
382
+ { node_type: 'def', arguments: { size { gte: 2 } }
383
383
  ```
384
384
 
385
385
  Size of arguments is greater than or equal to 2
386
386
 
387
387
  ```
388
- { nodeType: 'def', arguments: { size { gt: 2 } }
388
+ { node_type: 'def', arguments: { size { gt: 2 } }
389
389
  ```
390
390
 
391
391
  Size of arguments is greater than 2
392
392
 
393
393
  ```
394
- { nodeType: 'def', arguments: { size { lte: 2 } }
394
+ { node_type: 'def', arguments: { size { lte: 2 } }
395
395
  ```
396
396
 
397
397
  Size of arguments is less than or equal to 2
398
398
 
399
399
  ```
400
- { nodeType: 'def', arguments: { size { lt: 2 } }
400
+ { node_type: 'def', arguments: { size { lt: 2 } }
401
401
  ```
402
402
 
403
403
  Size of arguments is less than 2
404
404
 
405
405
  ```
406
- { nodeType: 'class', name: { in: ['User', 'Account'] } }
406
+ { node_type: 'class', name: { in: ['User', 'Account'] } }
407
407
  ```
408
408
 
409
409
  Value of name is either User or Account
410
410
 
411
411
  ```
412
- { nodeType: 'class', name: { not_in: ['User', 'Account'] } }
412
+ { node_type: 'class', name: { not_in: ['User', 'Account'] } }
413
413
  ```
414
414
 
415
415
  Value of name is neither User nor Account
416
416
 
417
417
  ```
418
- { nodeType: 'def', arguments: { includes: 'id' } }
418
+ { node_type: 'def', arguments: { includes: 'id' } }
419
419
  ```
420
420
 
421
421
  Value of arguments includes id
422
422
 
423
423
  ```
424
- { nodeType: 'class', name: /User/ }
424
+ { node_type: 'class', name: /User/ }
425
425
  ```
426
426
 
427
427
  Value of name matches User
428
428
 
429
429
  ```
430
- { nodeType: 'class', name: { not: /User/ } }
430
+ { node_type: 'class', name: { not: /User/ } }
431
431
  ```
432
432
 
433
433
  Value of name does not match User
434
434
 
435
435
  ```
436
- { nodeType: 'class', name: { in: [/User/, /Account/] } }
436
+ { node_type: 'class', name: { in: [/User/, /Account/] } }
437
437
  ```
438
438
 
439
439
  Value of name matches either /User/ or /Account/
@@ -441,7 +441,7 @@ Value of name matches either /User/ or /Account/
441
441
  ### rules matches array nodes attribute
442
442
 
443
443
  ```
444
- { nodeType: 'def', arguments: ['id', 'name'] }
444
+ { node_type: 'def', arguments: ['id', 'name'] }
445
445
  ```
446
446
 
447
447
  It matches def node whose arguments are id and name.
@@ -15,8 +15,8 @@ module NodeQuery::Compiler
15
15
  # @param node [Node] node to match
16
16
  # @param options [Hash] if query the current node
17
17
  # @option options [boolean] :including_self if query the current node, default is ture
18
- # @option options [boolean] :stop_on_match if stop on first match, default is false
19
- # @option options [boolean] :recursive if stop on first match, default is true
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
20
20
  # @return [Array<Node>] matching nodes.
21
21
  def query_nodes(node, options = {})
22
22
  matching_nodes = @selector.query_nodes(node, options)
@@ -15,8 +15,8 @@ module NodeQuery::Compiler
15
15
  # @param node [Node] node to match
16
16
  # @param options [Hash] if query the current node
17
17
  # @option options [boolean] :including_self if query the current node, default is ture
18
- # @option options [boolean] :stop_on_match if stop on first match, default is false
19
- # @option options [boolean] :recursive if stop on first match, default is true
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
20
20
  # @return [Array<Node>] matching nodes.
21
21
  def query_nodes(node, options = {})
22
22
  matching_nodes = @expression.query_nodes(node, options)
@@ -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.
@@ -35,11 +35,11 @@ module NodeQuery::Compiler
35
35
  # @param node [Node] node to match
36
36
  # @param options [Hash] if query the current node
37
37
  # @option options [boolean] :including_self if query the current node, default is ture
38
- # @option options [boolean] :stop_on_match if stop on first match, default is false
39
- # @option options [boolean] :recursive if stop on first match, default is true
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
40
40
  # @return [Array<Node>] matching nodes.
41
41
  def query_nodes(node, options = {})
42
- options = { including_self: true, stop_on_match: false, recursive: true }.merge(options)
42
+ options = { including_self: true, stop_at_first_match: false, recursive: true }.merge(options)
43
43
  return find_nodes_by_relationship(node) if @relationship
44
44
 
45
45
  if node.is_a?(::Array)
@@ -48,24 +48,28 @@ module NodeQuery::Compiler
48
48
 
49
49
  return find_nodes_by_goto_scope(node) if @goto_scope
50
50
 
51
+ if options[:including_self] && !options[:recursive]
52
+ return match?(node) ? [node] : []
53
+ end
54
+
51
55
  nodes = []
52
56
  if options[:including_self] && match?(node)
53
57
  nodes << node
54
- return matching_nodes if options[:stop_on_match]
58
+ return nodes if options[:stop_at_first_match]
55
59
  end
56
60
  if @basic_selector
57
61
  if options[:recursive]
58
62
  NodeQuery::Helper.handle_recursive_child(node) do |child_node|
59
63
  if match?(child_node)
60
64
  nodes << child_node
61
- break if options[:stop_on_match]
65
+ break if options[:stop_at_first_match]
62
66
  end
63
67
  end
64
68
  else
65
69
  NodeQuery.adapter.get_children(node).each do |child_node|
66
70
  if match?(child_node)
67
71
  nodes << child_node
68
- break if options[:stop_on_match]
72
+ break if options[:stop_at_first_match]
69
73
  end
70
74
  end
71
75
  end
@@ -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.
@@ -18,7 +18,7 @@ class NodeQuery::Helper
18
18
  child_node = node[first_key.to_i]
19
19
  elsif node.respond_to?(first_key)
20
20
  child_node = node.send(first_key)
21
- elsif first_key == "nodeType"
21
+ elsif first_key == "node_type"
22
22
  child_node = NodeQuery.adapter.get_node_type(node)
23
23
  end
24
24
 
@@ -50,9 +50,17 @@ class NodeQuery::Helper
50
50
  def evaluate_node_value(node, str)
51
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
@@ -13,28 +13,32 @@ class NodeQuery::NodeRules
13
13
  # @param node [Node] node to query
14
14
  # @param options [Hash] if query the current node
15
15
  # @option options [boolean] :including_self if query the current node, default is ture
16
- # @option options [boolean] :stop_on_match if stop on first match, default is false
17
- # @option options [boolean] :recursive if stop on first match, default is true
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
18
18
  # @return [Array<Node>] matching nodes.
19
19
  def query_nodes(node, options = {})
20
- options = { including_self: true, stop_on_match: false, recursive: true }.merge(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
+
21
25
  matching_nodes = []
22
26
  if options[:including_self] && match_node?(node)
23
27
  matching_nodes.push(node)
24
- return matching_nodes if options[:stop_on_match]
28
+ return matching_nodes if options[:stop_at_first_match]
25
29
  end
26
30
  if options[:recursive]
27
31
  NodeQuery::Helper.handle_recursive_child(node) do |child_node|
28
32
  if match_node?(child_node)
29
33
  matching_nodes.push(child_node)
30
- break if options[:stop_on_match]
34
+ break if options[:stop_at_first_match]
31
35
  end
32
36
  end
33
37
  else
34
38
  NodeQuery.adapter.get_children(node).each do |child_node|
35
39
  if match_node?(child_node)
36
40
  matching_nodes.push(child_node)
37
- break if options[:stop_on_match]
41
+ break if options[:stop_at_first_match]
38
42
  end
39
43
  end
40
44
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class NodeQuery
4
- VERSION = "1.4.0"
4
+ VERSION = "1.6.0"
5
5
  end
data/lib/node_query.rb CHANGED
@@ -40,8 +40,8 @@ class NodeQuery
40
40
  # @param node [Node] ast node
41
41
  # @param options [Hash] if query the current node
42
42
  # @option options [boolean] :including_self if query the current node, default is ture
43
- # @option options [boolean] :stop_on_match if stop on first match, default is false
44
- # @option options [boolean] :recursive if stop on first match, default is true
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
45
45
  # @return [Array<Node>] matching child nodes
46
46
  def query_nodes(node, options = {})
47
47
  if @expression
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.0
4
+ version: 1.6.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-14 00:00:00.000000000 Z
11
+ date: 2022-09-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport