Class: Synvert::Core::NodeQuery::Compiler::Expression

Inherits:
Object
  • Object
show all
Defined in:
lib/synvert/core/node_query/compiler/expression.rb

Overview

Expression represents a node query expression.

Instance Method Summary collapse

Constructor Details

#initialize(selector: nil, rest: nil, relationship: nil) ⇒ Expression

Initialize a Expression.

Parameters:



10
11
12
13
14
# File 'lib/synvert/core/node_query/compiler/expression.rb', line 10

def initialize(selector: nil, rest: nil, relationship: nil)
  @selector = selector
  @rest = rest
  @relationship = relationship
end

Instance Method Details

#match?(node) ⇒ Boolean

Check if the node matches the expression.

Parameters:

Returns:



19
20
21
# File 'lib/synvert/core/node_query/compiler/expression.rb', line 19

def match?(node)
  !query_nodes(node).empty?
end

#query_nodes(node, descendant_match: true) ⇒ Array<Parser::AST::Node>

Query nodes by the expression.

  • If relationship is nil, it will match in all recursive child nodes and return matching nodes.

  • If relationship is :decendant, it will match in all recursive child nodes.

  • If relationship is :child, it will match in direct child nodes.

  • If relationship is :next_sibling, it try to match next sibling node.

  • If relationship is :subsequent_sibling, it will match in all sibling nodes.

Parameters:

  • node (Parser::AST::Node)

    node to match

  • descendant_match (Boolean) (defaults to: true)

    whether to match in descendant node

Returns:



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/synvert/core/node_query/compiler/expression.rb', line 33

def query_nodes(node, descendant_match: true)
  matching_nodes = find_nodes_without_relationship(node, descendant_match: descendant_match)
  if @relationship.nil?
    return matching_nodes
  end

  expression_nodes = matching_nodes.map do |matching_node|
    case @relationship
    when :descendant
      nodes = []
      matching_node.recursive_children { |child_node|
        nodes += @rest.query_nodes(child_node, descendant_match: false)
      }
      nodes
    when :child
      matching_node.children.map { |child_node| @rest.query_nodes(child_node, descendant_match: false) }
                   .flatten
    when :next_sibling
      @rest.query_nodes(matching_node.siblings.first, descendant_match: false)
    when :subsequent_sibling
      matching_node.siblings.map { |sibling_node| @rest.query_nodes(sibling_node, descendant_match: false) }
                   .flatten
    end
  end.flatten
end

#to_sObject



59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/synvert/core/node_query/compiler/expression.rb', line 59

def to_s
  return @selector.to_s unless @rest

  result = []
  result << @selector if @selector
  case @relationship
  when :child then result << '>'
  when :subsequent_sibling then result << '~'
  when :next_sibling then result << '+'
  end
  result << @rest
  result.map(&:to_s).join(' ')
end