synvert-core 1.4.0 → 1.5.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/.gitignore +0 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile +0 -3
- data/Guardfile +0 -9
- data/README.md +30 -12
- data/Rakefile +1 -15
- data/lib/synvert/core/engine/erb.rb +1 -1
- data/lib/synvert/core/engine.rb +1 -1
- data/lib/synvert/core/node_ext.rb +0 -466
- data/lib/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action.rb +20 -17
- data/lib/synvert/core/rewriter/condition/if_exist_condition.rb +1 -1
- data/lib/synvert/core/rewriter/condition/unless_exist_condition.rb +1 -1
- data/lib/synvert/core/rewriter/instance.rb +83 -133
- data/lib/synvert/core/rewriter/scope/query_scope.rb +2 -2
- data/lib/synvert/core/rewriter/scope/within_scope.rb +4 -4
- data/lib/synvert/core/rewriter.rb +0 -10
- data/lib/synvert/core/version.rb +1 -1
- data/lib/synvert/core.rb +4 -6
- data/spec/synvert/core/engine/erb_spec.rb +3 -3
- data/spec/synvert/core/node_ext_spec.rb +0 -795
- data/spec/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action_spec.rb +21 -1
- data/spec/synvert/core/rewriter/instance_spec.rb +47 -115
- data/spec/synvert/core/rewriter/scope/goto_scope_spec.rb +1 -4
- data/spec/synvert/core/rewriter/scope/query_scope_spec.rb +1 -4
- data/spec/synvert/core/rewriter/scope/within_scope_spec.rb +1 -4
- data/synvert-core-ruby.gemspec +4 -2
- metadata +44 -61
- data/lib/synvert/core/array_ext.rb +0 -48
- data/lib/synvert/core/node_query/compiler/array.rb +0 -34
- data/lib/synvert/core/node_query/compiler/attribute.rb +0 -39
- data/lib/synvert/core/node_query/compiler/attribute_list.rb +0 -24
- data/lib/synvert/core/node_query/compiler/basic_selector.rb +0 -28
- data/lib/synvert/core/node_query/compiler/boolean.rb +0 -23
- data/lib/synvert/core/node_query/compiler/comparable.rb +0 -86
- data/lib/synvert/core/node_query/compiler/dynamic_attribute.rb +0 -51
- data/lib/synvert/core/node_query/compiler/expression.rb +0 -41
- data/lib/synvert/core/node_query/compiler/float.rb +0 -23
- data/lib/synvert/core/node_query/compiler/identifier.rb +0 -41
- data/lib/synvert/core/node_query/compiler/integer.rb +0 -23
- data/lib/synvert/core/node_query/compiler/invalid_operator_error.rb +0 -7
- data/lib/synvert/core/node_query/compiler/nil.rb +0 -23
- data/lib/synvert/core/node_query/compiler/parse_error.rb +0 -7
- data/lib/synvert/core/node_query/compiler/regexp.rb +0 -37
- data/lib/synvert/core/node_query/compiler/selector.rb +0 -113
- data/lib/synvert/core/node_query/compiler/string.rb +0 -23
- data/lib/synvert/core/node_query/compiler/symbol.rb +0 -23
- data/lib/synvert/core/node_query/compiler.rb +0 -25
- data/lib/synvert/core/node_query/lexer.rex +0 -99
- data/lib/synvert/core/node_query/lexer.rex.rb +0 -299
- data/lib/synvert/core/node_query/parser.racc.rb +0 -306
- data/lib/synvert/core/node_query/parser.y +0 -60
- data/lib/synvert/core/node_query.rb +0 -36
- data/lib/synvert/core/rewriter/action/append_action.rb +0 -28
- data/lib/synvert/core/rewriter/action/delete_action.rb +0 -34
- data/lib/synvert/core/rewriter/action/insert_action.rb +0 -34
- data/lib/synvert/core/rewriter/action/insert_after_action.rb +0 -22
- data/lib/synvert/core/rewriter/action/prepend_action.rb +0 -44
- data/lib/synvert/core/rewriter/action/remove_action.rb +0 -56
- data/lib/synvert/core/rewriter/action/replace_action.rb +0 -33
- data/lib/synvert/core/rewriter/action/replace_with_action.rb +0 -36
- data/lib/synvert/core/rewriter/action/wrap_action.rb +0 -37
- data/lib/synvert/core/rewriter/action.rb +0 -102
- data/spec/synvert/core/node_query/lexer_spec.rb +0 -580
- data/spec/synvert/core/node_query/parser_spec.rb +0 -337
- data/spec/synvert/core/rewriter/action/append_action_spec.rb +0 -70
- data/spec/synvert/core/rewriter/action/delete_action_spec.rb +0 -26
- data/spec/synvert/core/rewriter/action/insert_action_spec.rb +0 -70
- data/spec/synvert/core/rewriter/action/insert_after_action_spec.rb +0 -26
- data/spec/synvert/core/rewriter/action/prepend_action_spec.rb +0 -175
- data/spec/synvert/core/rewriter/action/remove_action_spec.rb +0 -26
- data/spec/synvert/core/rewriter/action/replace_action_spec.rb +0 -28
- data/spec/synvert/core/rewriter/action/replace_with_action_spec.rb +0 -59
- data/spec/synvert/core/rewriter/action/wrap_action_spec.rb +0 -31
- data/spec/synvert/core/rewriter/action_spec.rb +0 -14
@@ -1,86 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Synvert::Core::NodeQuery::Compiler
|
4
|
-
# Compare acutal value with expected value.
|
5
|
-
module Comparable
|
6
|
-
SIMPLE_VALID_OPERATORS = ['==', '!=', 'includes']
|
7
|
-
STRING_VALID_OPERATORS = ['==', '!=', '^=', '$=', '*=', 'includes']
|
8
|
-
NUMBER_VALID_OPERATORS = ['==', '!=', '>', '>=', '<', '<=', 'includes']
|
9
|
-
ARRAY_VALID_OPERATORS = ['==', '!=', 'in', 'not_in']
|
10
|
-
REGEXP_VALID_OPERATORS = ['=~', '!~']
|
11
|
-
|
12
|
-
# Check if the actual value matches the expected value.
|
13
|
-
#
|
14
|
-
# @param node [Parser::AST::Node] node to calculate actual value
|
15
|
-
# @param operator [Symbol] operator to compare with expected value, operator can be <code>'=='</code>, <code>'!='</code>, <code>'>'</code>, <code>'>='</code>, <code>'<'</code>, <code>'<='</code>, <code>'includes'</code>, <code>'in'</code>, <code>'not_in'</code>, <code>'=~'</code>, <code>'!~'</code>
|
16
|
-
# @return [Boolean] true if actual value matches the expected value
|
17
|
-
# @raise [Synvert::Core::NodeQuery::Compiler::InvalidOperatorError] if operator is invalid
|
18
|
-
def match?(node, operator)
|
19
|
-
raise InvalidOperatorError, "invalid operator #{operator}" unless valid_operator?(operator)
|
20
|
-
|
21
|
-
case operator
|
22
|
-
when '!='
|
23
|
-
if expected_value.is_a?(::Array)
|
24
|
-
actual = actual_value(node)
|
25
|
-
!actual.is_a?(::Array) || actual.size != expected_value.size ||
|
26
|
-
actual.zip(expected_value).any? { |actual_node, expected_node| expected_node.match?(actual_node, '!=') }
|
27
|
-
else
|
28
|
-
actual_value(node) != expected_value
|
29
|
-
end
|
30
|
-
when '=~'
|
31
|
-
actual_value(node) =~ expected_value
|
32
|
-
when '!~'
|
33
|
-
actual_value(node) !~ expected_value
|
34
|
-
when '^='
|
35
|
-
actual_value(node).start_with?(expected_value)
|
36
|
-
when '$='
|
37
|
-
actual_value(node).end_with?(expected_value)
|
38
|
-
when '*='
|
39
|
-
actual_value(node).include?(expected_value)
|
40
|
-
when '>'
|
41
|
-
actual_value(node) > expected_value
|
42
|
-
when '>='
|
43
|
-
actual_value(node) >= expected_value
|
44
|
-
when '<'
|
45
|
-
actual_value(node) < expected_value
|
46
|
-
when '<='
|
47
|
-
actual_value(node) <= expected_value
|
48
|
-
when 'in'
|
49
|
-
expected_value.any? { |expected| expected.match?(node, '==') }
|
50
|
-
when 'not_in'
|
51
|
-
expected_value.all? { |expected| expected.match?(node, '!=') }
|
52
|
-
when 'includes'
|
53
|
-
actual_value(node).any? { |actual| actual == expected_value }
|
54
|
-
else
|
55
|
-
if expected_value.is_a?(::Array)
|
56
|
-
actual = actual_value(node)
|
57
|
-
actual.is_a?(::Array) && actual.size == expected_value.size &&
|
58
|
-
actual.zip(expected_value).all? { |actual_node, expected_node| expected_node.match?(actual_node, '==') }
|
59
|
-
else
|
60
|
-
actual_value(node) == expected_value
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
# Get the actual value from ast node.
|
66
|
-
# @return if node is a {Parser::AST::Node}, return the node value, otherwise, return the node itself.
|
67
|
-
def actual_value(node)
|
68
|
-
if node.is_a?(::Parser::AST::Node)
|
69
|
-
node.to_value
|
70
|
-
else
|
71
|
-
node
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
# Get the expected value
|
76
|
-
def expected_value
|
77
|
-
@value
|
78
|
-
end
|
79
|
-
|
80
|
-
# Check if the operator is valid.
|
81
|
-
# @return [Boolean] true if the operator is valid
|
82
|
-
def valid_operator?(operator)
|
83
|
-
valid_operators.include?(operator)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Synvert::Core::NodeQuery::Compiler
|
4
|
-
# DynamicAttribute represents a ruby dynamic attribute.
|
5
|
-
# e.g. code is <code>{ a: a }</code>, query is <code>'.hash > .pair[key={{value}}]'</code>,
|
6
|
-
# <code>{{value}}</code> is the dynamic attribute.
|
7
|
-
class DynamicAttribute
|
8
|
-
include Comparable
|
9
|
-
|
10
|
-
attr_accessor :base_node
|
11
|
-
|
12
|
-
# Initialize a DynamicAttribute.
|
13
|
-
# @param value [String] the dynamic attribute value
|
14
|
-
def initialize(value:)
|
15
|
-
@value = value
|
16
|
-
end
|
17
|
-
|
18
|
-
# Get the actual value of a node.
|
19
|
-
#
|
20
|
-
# @param node the node
|
21
|
-
# @return [String] if node is a {Parser::AST::Node}, return the node source code, otherwise return the node itself.
|
22
|
-
def actual_value(node)
|
23
|
-
if node.is_a?(::Parser::AST::Node)
|
24
|
-
node.to_source
|
25
|
-
else
|
26
|
-
node
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
# Get the expected value.
|
31
|
-
#
|
32
|
-
# @return [String] Query the node by @valud from base_node, if the node is a {Parser::AST::Node}, return the node source code, otherwise return the node itself.
|
33
|
-
def expected_value
|
34
|
-
node = base_node.child_node_by_name(@value)
|
35
|
-
if node.is_a?(::Parser::AST::Node)
|
36
|
-
node.to_source
|
37
|
-
else
|
38
|
-
node
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# Get valid operators.
|
43
|
-
def valid_operators
|
44
|
-
SIMPLE_VALID_OPERATORS
|
45
|
-
end
|
46
|
-
|
47
|
-
def to_s
|
48
|
-
"{{#{@value}}}"
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Synvert::Core::NodeQuery::Compiler
|
4
|
-
# Expression represents a node query expression.
|
5
|
-
class Expression
|
6
|
-
# Initialize a Expression.
|
7
|
-
# @param selector [Synvert::Core::NodeQuery::Compiler::Selector] the selector
|
8
|
-
# @param rest [Synvert::Core::NodeQuery::Compiler::Expression] the rest expression
|
9
|
-
def initialize(selector: nil, rest: nil)
|
10
|
-
@selector = selector
|
11
|
-
@rest = rest
|
12
|
-
end
|
13
|
-
|
14
|
-
# Check if the node matches the expression.
|
15
|
-
# @param node [Parser::AST::Node] the node
|
16
|
-
# @return [Boolean]
|
17
|
-
def match?(node)
|
18
|
-
!query_nodes(node).empty?
|
19
|
-
end
|
20
|
-
|
21
|
-
# Query nodes by the selector and the rest expression.
|
22
|
-
#
|
23
|
-
# @param node [Parser::AST::Node] node to match
|
24
|
-
# @return [Array<Parser::AST::Node>] matching nodes.
|
25
|
-
def query_nodes(node)
|
26
|
-
matching_nodes = @selector.query_nodes(node)
|
27
|
-
return matching_nodes if @rest.nil?
|
28
|
-
|
29
|
-
matching_nodes.flat_map do |matching_node|
|
30
|
-
@rest.query_nodes(matching_node)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def to_s
|
35
|
-
result = []
|
36
|
-
result << @selector.to_s if @selector
|
37
|
-
result << @rest.to_s if @rest
|
38
|
-
result.join(' ')
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Synvert::Core::NodeQuery::Compiler
|
4
|
-
# Float represents a ruby float value.
|
5
|
-
class Float
|
6
|
-
include Comparable
|
7
|
-
|
8
|
-
# Initialize a Float.
|
9
|
-
# @param value [Float] the float value
|
10
|
-
def initialize(value:)
|
11
|
-
@value = value
|
12
|
-
end
|
13
|
-
|
14
|
-
# Get valid operators.
|
15
|
-
def valid_operators
|
16
|
-
NUMBER_VALID_OPERATORS
|
17
|
-
end
|
18
|
-
|
19
|
-
def to_s
|
20
|
-
@value.to_s
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Synvert::Core::NodeQuery::Compiler
|
4
|
-
# Identifier represents a ruby identifier value.
|
5
|
-
# e.g. code is `class Synvert; end`, `Synvert` is an identifier.
|
6
|
-
class Identifier
|
7
|
-
include Comparable
|
8
|
-
|
9
|
-
# Initialize an Identifier.
|
10
|
-
# @param value [String] the identifier value
|
11
|
-
def initialize(value:)
|
12
|
-
@value = value
|
13
|
-
end
|
14
|
-
|
15
|
-
# Get the actual value.
|
16
|
-
#
|
17
|
-
# @param node the node
|
18
|
-
# @return [String|Array]
|
19
|
-
# If the node is a {Parser::AST::Node}, return the node source code,
|
20
|
-
# if the node is an Array, return the array of each element's actual value,
|
21
|
-
# otherwise, return the String value.
|
22
|
-
def actual_value(node)
|
23
|
-
if node.is_a?(::Parser::AST::Node)
|
24
|
-
node.to_source
|
25
|
-
elsif node.is_a?(::Array)
|
26
|
-
node.map { |n| actual_value(n) }
|
27
|
-
else
|
28
|
-
node.to_s
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# Get valid operators.
|
33
|
-
def valid_operators
|
34
|
-
STRING_VALID_OPERATORS
|
35
|
-
end
|
36
|
-
|
37
|
-
def to_s
|
38
|
-
@value
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Synvert::Core::NodeQuery::Compiler
|
4
|
-
# Integer represents a ruby integer value.
|
5
|
-
class Integer
|
6
|
-
include Comparable
|
7
|
-
|
8
|
-
# Initialize a Integer.
|
9
|
-
# @param value [Integer] the integer value
|
10
|
-
def initialize(value:)
|
11
|
-
@value = value
|
12
|
-
end
|
13
|
-
|
14
|
-
# Get valid operators.
|
15
|
-
def valid_operators
|
16
|
-
NUMBER_VALID_OPERATORS
|
17
|
-
end
|
18
|
-
|
19
|
-
def to_s
|
20
|
-
@value.to_s
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Synvert::Core::NodeQuery::Compiler
|
4
|
-
# Nil represents a ruby nil value.
|
5
|
-
class Nil
|
6
|
-
include Comparable
|
7
|
-
|
8
|
-
# Initialize a Nil.
|
9
|
-
# @param value [nil] the nil value
|
10
|
-
def initialize(value:)
|
11
|
-
@value = value
|
12
|
-
end
|
13
|
-
|
14
|
-
# Get valid operators.
|
15
|
-
def valid_operators
|
16
|
-
SIMPLE_VALID_OPERATORS
|
17
|
-
end
|
18
|
-
|
19
|
-
def to_s
|
20
|
-
'nil'
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Synvert::Core::NodeQuery::Compiler
|
4
|
-
# Regexp represents a ruby regexp value.
|
5
|
-
class Regexp
|
6
|
-
include Comparable
|
7
|
-
|
8
|
-
# Initialize a Regexp.
|
9
|
-
# @param value [Regexp] the regexp value
|
10
|
-
def initialize(value:)
|
11
|
-
@value = value
|
12
|
-
end
|
13
|
-
|
14
|
-
# Check if the regexp value matches the node value.
|
15
|
-
# @param node [Parser::AST::Node] the node
|
16
|
-
# @param operator [Symbol] 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 node.is_a?(::Parser::AST::Node)
|
21
|
-
@value.match(node.to_source)
|
22
|
-
else
|
23
|
-
@value.match(node.to_s)
|
24
|
-
end
|
25
|
-
operator == '=~' ? match : !match
|
26
|
-
end
|
27
|
-
|
28
|
-
# Get valid operators.
|
29
|
-
def valid_operators
|
30
|
-
REGEXP_VALID_OPERATORS
|
31
|
-
end
|
32
|
-
|
33
|
-
def to_s
|
34
|
-
@value.to_s
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,113 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Synvert::Core::NodeQuery::Compiler
|
4
|
-
# Selector used to match nodes, it combines by node type and/or attribute list, plus index or has expression.
|
5
|
-
class Selector
|
6
|
-
# Initialize a Selector.
|
7
|
-
# @param goto_scope [String] goto scope
|
8
|
-
# @param relationship [Symbol] the relationship between the selectors, it can be descendant <code>nil</code>, child <code>></code>, next sibling <code>+</code> or subsequent sibing <code>~</code>.
|
9
|
-
# @param rest [Synvert::Core::NodeQuery::Compiler::Selector] the rest selector
|
10
|
-
# @param basic_selector [Synvert::Core::NodeQuery::Compiler::BasicSelector] the simple selector
|
11
|
-
# @param attribute_list [Synvert::Core::NodeQuery::Compiler::AttributeList] the attribute list
|
12
|
-
# @param pseudo_class [String] the pseudo class, can be <code>has</code> or <code>not_has</code>
|
13
|
-
# @param pseudo_selector [Synvert::Core::NodeQuery::Compiler::Expression] the pseudo selector
|
14
|
-
def initialize(goto_scope: nil, relationship: nil, rest: nil, basic_selector: nil, pseudo_class: nil, pseudo_selector: nil)
|
15
|
-
@goto_scope = goto_scope
|
16
|
-
@relationship = relationship
|
17
|
-
@rest = rest
|
18
|
-
@basic_selector = basic_selector
|
19
|
-
@pseudo_class = pseudo_class
|
20
|
-
@pseudo_selector = pseudo_selector
|
21
|
-
end
|
22
|
-
|
23
|
-
# Check if node matches the selector.
|
24
|
-
# @param node [Parser::AST::Node] the node
|
25
|
-
def match?(node)
|
26
|
-
node.is_a?(::Parser::AST::Node) && (!@basic_selector || @basic_selector.match?(node)) && match_pseudo_class?(node)
|
27
|
-
end
|
28
|
-
|
29
|
-
# Query nodes by the selector.
|
30
|
-
#
|
31
|
-
# * If relationship is nil, it will match in all recursive child nodes and return matching nodes.
|
32
|
-
# * If relationship is decendant, it will match in all recursive child nodes.
|
33
|
-
# * If relationship is child, it will match in direct child nodes.
|
34
|
-
# * If relationship is next sibling, it try to match next sibling node.
|
35
|
-
# * If relationship is subsequent sibling, it will match in all sibling nodes.
|
36
|
-
# @param node [Parser::AST::Node] node to match
|
37
|
-
# @return [Array<Parser::AST::Node>] matching nodes.
|
38
|
-
def query_nodes(node)
|
39
|
-
return find_nodes_by_relationship(node) if @relationship
|
40
|
-
|
41
|
-
if node.is_a?(::Array)
|
42
|
-
return node.flat_map { |child_node| query_nodes(child_node) }
|
43
|
-
end
|
44
|
-
|
45
|
-
return find_nodes_by_goto_scope(node) if @goto_scope
|
46
|
-
|
47
|
-
nodes = []
|
48
|
-
nodes << node if match?(node)
|
49
|
-
if @basic_selector
|
50
|
-
node.recursive_children do |child_node|
|
51
|
-
nodes << child_node if match?(child_node)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
nodes
|
55
|
-
end
|
56
|
-
|
57
|
-
def to_s
|
58
|
-
result = []
|
59
|
-
result << "#{@goto_scope} " if @goto_scope
|
60
|
-
result << "#{@relationship} " if @relationship
|
61
|
-
result << @rest.to_s if @rest
|
62
|
-
result << @basic_selector.to_s if @basic_selector
|
63
|
-
result << ":#{@pseudo_class}(#{@pseudo_selector})" if @pseudo_class
|
64
|
-
result.join('')
|
65
|
-
end
|
66
|
-
|
67
|
-
private
|
68
|
-
|
69
|
-
# Find nodes by @goto_scope
|
70
|
-
# @param node [Parser::AST::Node] node to match
|
71
|
-
def find_nodes_by_goto_scope(node)
|
72
|
-
@goto_scope.split('.').each { |scope| node = node.send(scope) }
|
73
|
-
@rest.query_nodes(node)
|
74
|
-
end
|
75
|
-
|
76
|
-
# Find ndoes by @relationship
|
77
|
-
# @param node [Parser::AST::Node] node to match
|
78
|
-
def find_nodes_by_relationship(node)
|
79
|
-
nodes = []
|
80
|
-
case @relationship
|
81
|
-
when '>'
|
82
|
-
if node.is_a?(::Array)
|
83
|
-
node.each do |child_node|
|
84
|
-
nodes << child_node if @rest.match?(child_node)
|
85
|
-
end
|
86
|
-
else
|
87
|
-
node.children.each do |child_node|
|
88
|
-
nodes << child_node if @rest.match?(child_node)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
when '+'
|
92
|
-
next_sibling = node.siblings.first
|
93
|
-
nodes << next_sibling if @rest.match?(next_sibling)
|
94
|
-
when '~'
|
95
|
-
node.siblings.each do |sibling_node|
|
96
|
-
nodes << sibling_node if @rest.match?(sibling_node)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
nodes
|
100
|
-
end
|
101
|
-
|
102
|
-
def match_pseudo_class?(node)
|
103
|
-
case @pseudo_class
|
104
|
-
when 'has'
|
105
|
-
!@pseudo_selector.query_nodes(node).empty?
|
106
|
-
when 'not_has'
|
107
|
-
@pseudo_selector.query_nodes(node).empty?
|
108
|
-
else
|
109
|
-
true
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Synvert::Core::NodeQuery::Compiler
|
4
|
-
# String represents a ruby string value.
|
5
|
-
class String
|
6
|
-
include Comparable
|
7
|
-
|
8
|
-
# Initialize a String.
|
9
|
-
# @param value [String] the string value
|
10
|
-
def initialize(value:)
|
11
|
-
@value = value
|
12
|
-
end
|
13
|
-
|
14
|
-
# Get valid operators.
|
15
|
-
def valid_operators
|
16
|
-
STRING_VALID_OPERATORS
|
17
|
-
end
|
18
|
-
|
19
|
-
def to_s
|
20
|
-
"\"#{@value}\""
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Synvert::Core::NodeQuery::Compiler
|
4
|
-
# Symbol represents a ruby symbol value.
|
5
|
-
class Symbol
|
6
|
-
include Comparable
|
7
|
-
|
8
|
-
# Initliaze a Symobol.
|
9
|
-
# @param value [Symbol] the symbol value
|
10
|
-
def initialize(value:)
|
11
|
-
@value = value
|
12
|
-
end
|
13
|
-
|
14
|
-
# Get valid operators.
|
15
|
-
def valid_operators
|
16
|
-
SIMPLE_VALID_OPERATORS
|
17
|
-
end
|
18
|
-
|
19
|
-
def to_s
|
20
|
-
":#{@value}"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Synvert::Core::NodeQuery::Compiler
|
4
|
-
autoload :InvalidOperatorError, 'synvert/core/node_query/compiler/invalid_operator_error'
|
5
|
-
autoload :ParseError, 'synvert/core/node_query/compiler/parse_error'
|
6
|
-
|
7
|
-
autoload :Comparable, 'synvert/core/node_query/compiler/comparable'
|
8
|
-
|
9
|
-
autoload :Expression, 'synvert/core/node_query/compiler/expression'
|
10
|
-
autoload :Selector, 'synvert/core/node_query/compiler/selector'
|
11
|
-
autoload :BasicSelector, 'synvert/core/node_query/compiler/basic_selector'
|
12
|
-
autoload :AttributeList, 'synvert/core/node_query/compiler/attribute_list'
|
13
|
-
autoload :Attribute, 'synvert/core/node_query/compiler/attribute'
|
14
|
-
|
15
|
-
autoload :Array, 'synvert/core/node_query/compiler/array'
|
16
|
-
autoload :Boolean, 'synvert/core/node_query/compiler/boolean'
|
17
|
-
autoload :DynamicAttribute, 'synvert/core/node_query/compiler/dynamic_attribute'
|
18
|
-
autoload :Float, 'synvert/core/node_query/compiler/float'
|
19
|
-
autoload :Identifier, 'synvert/core/node_query/compiler/identifier'
|
20
|
-
autoload :Integer, 'synvert/core/node_query/compiler/integer'
|
21
|
-
autoload :Nil, 'synvert/core/node_query/compiler/nil'
|
22
|
-
autoload :Regexp, 'synvert/core/node_query/compiler/regexp'
|
23
|
-
autoload :String, 'synvert/core/node_query/compiler/string'
|
24
|
-
autoload :Symbol, 'synvert/core/node_query/compiler/symbol'
|
25
|
-
end
|
@@ -1,99 +0,0 @@
|
|
1
|
-
class Synvert::Core::NodeQuery::Lexer
|
2
|
-
|
3
|
-
macros
|
4
|
-
OPEN_ATTRIBUTE /\[/
|
5
|
-
CLOSE_ATTRIBUTE /\]/
|
6
|
-
OPEN_ARRAY /\(/
|
7
|
-
CLOSE_ARRAY /\)/
|
8
|
-
OPEN_SELECTOR /\(/
|
9
|
-
CLOSE_SELECTOR /\)/
|
10
|
-
OPEN_DYNAMIC_ATTRIBUTE /{{/
|
11
|
-
CLOSE_DYNAMIC_ATTRIBUTE /}}/
|
12
|
-
NODE_TYPE /\.[a-z]+/
|
13
|
-
IDENTIFIER /[\.\w]+/
|
14
|
-
IDENTIFIER_VALUE /[\.\w!&:\?<>=]+/
|
15
|
-
FALSE /false/
|
16
|
-
FLOAT /\d+\.\d+/
|
17
|
-
INTEGER /\d+/
|
18
|
-
NIL /nil/
|
19
|
-
REGEXP_BODY /(?:[^\/]|\\\/)*/
|
20
|
-
REGEXP /\/(#{REGEXP_BODY})(?<!\\)\/([imxo]*)/
|
21
|
-
SYMBOL /:[\w!\?<>=]+/
|
22
|
-
TRUE /true/
|
23
|
-
SINGLE_QUOTE_STRING /'.*?'/
|
24
|
-
DOUBLE_QUOTE_STRING /".*?"/
|
25
|
-
|
26
|
-
rules
|
27
|
-
|
28
|
-
# [:state] pattern [actions]
|
29
|
-
/\s+/
|
30
|
-
/:has/ { [:tPSEUDO_CLASS, text[1..-1]] }
|
31
|
-
/:not_has/ { [:tPSEUDO_CLASS, text[1..-1]] }
|
32
|
-
/#{NODE_TYPE}/ { [:tNODE_TYPE, text[1..]] }
|
33
|
-
/#{IDENTIFIER}/ { [:tGOTO_SCOPE, text] }
|
34
|
-
/>/ { [:tRELATIONSHIP, text] }
|
35
|
-
/~/ { [:tRELATIONSHIP, text] }
|
36
|
-
/\+/ { [:tRELATIONSHIP, text] }
|
37
|
-
/#{OPEN_SELECTOR}/ { [:tOPEN_SELECTOR, text] }
|
38
|
-
/#{CLOSE_SELECTOR}/ { [:tCLOSE_SELECTOR, text] }
|
39
|
-
/#{OPEN_ATTRIBUTE}/ { @nested_count += 1; @state = :KEY; [:tOPEN_ATTRIBUTE, text] }
|
40
|
-
:KEY /\s+/
|
41
|
-
:KEY /\^=/ { @state = :VALUE; [:tOPERATOR, '^='] }
|
42
|
-
:KEY /\$=/ { @state = :VALUE; [:tOPERATOR, '$='] }
|
43
|
-
:KEY /\*=/ { @state = :VALUE; [:tOPERATOR, '*='] }
|
44
|
-
:KEY /!=/ { @state = :VALUE; [:tOPERATOR, '!='] }
|
45
|
-
:KEY /=~/ { @state = :VALUE; [:tOPERATOR, '=~'] }
|
46
|
-
:KEY /!~/ { @state = :VALUE; [:tOPERATOR, '!~'] }
|
47
|
-
:KEY />=/ { @state = :VALUE; [:tOPERATOR, '>='] }
|
48
|
-
:KEY /<=/ { @state = :VALUE; [:tOPERATOR, '<='] }
|
49
|
-
:KEY />/ { @state = :VALUE; [:tOPERATOR, '>'] }
|
50
|
-
:KEY /</ { @state = :VALUE; [:tOPERATOR, '<'] }
|
51
|
-
:KEY /=/ { @state = :VALUE; [:tOPERATOR, '=='] }
|
52
|
-
:KEY /includes/i { @state = :VALUE; [:tOPERATOR, 'includes'] }
|
53
|
-
:KEY /not in/i { @state = :VALUE; [:tOPERATOR, 'not_in'] }
|
54
|
-
:KEY /in/i { @state = :VALUE; [:tOPERATOR, 'in'] }
|
55
|
-
:KEY /#{IDENTIFIER}/ { [:tKEY, text] }
|
56
|
-
:VALUE /\s+/
|
57
|
-
:VALUE /\[\]=/ { [:tIDENTIFIER_VALUE, text] }
|
58
|
-
:VALUE /\[\]/ { [:tIDENTIFIER_VALUE, text] }
|
59
|
-
:VALUE /:\[\]=/ { [:tSYMBOL, text[1..-1].to_sym] }
|
60
|
-
:VALUE /:\[\]/ { [:tSYMBOL, text[1..-1].to_sym] }
|
61
|
-
:VALUE /#{OPEN_DYNAMIC_ATTRIBUTE}/ { @state = :DYNAMIC_ATTRIBUTE; [:tOPEN_DYNAMIC_ATTRIBUTE, text] }
|
62
|
-
:VALUE /#{OPEN_ARRAY}/ { @state = :ARRAY_VALUE; [:tOPEN_ARRAY, text] }
|
63
|
-
:VALUE /#{CLOSE_ATTRIBUTE}/ { @nested_count -= 1; @state = @nested_count == 0 ? nil : :VALUE; [:tCLOSE_ATTRIBUTE, text] }
|
64
|
-
:VALUE /#{NIL}\?/ { [:tIDENTIFIER_VALUE, text] }
|
65
|
-
:VALUE /#{NIL}/ { [:tNIL, nil] }
|
66
|
-
:VALUE /#{TRUE}/ { [:tBOOLEAN, true] }
|
67
|
-
:VALUE /#{FALSE}/ { [:tBOOLEAN, false] }
|
68
|
-
:VALUE /#{SYMBOL}/ { [:tSYMBOL, text[1..-1].to_sym] }
|
69
|
-
:VALUE /#{FLOAT}/ { [:tFLOAT, text.to_f] }
|
70
|
-
:VALUE /#{INTEGER}/ { [:tINTEGER, text.to_i] }
|
71
|
-
:VALUE /#{REGEXP}/ { [:tREGEXP, eval(text)] }
|
72
|
-
:VALUE /#{DOUBLE_QUOTE_STRING}/ { [:tSTRING, text[1...-1]] }
|
73
|
-
:VALUE /#{SINGLE_QUOTE_STRING}/ { [:tSTRING, text[1...-1]] }
|
74
|
-
:VALUE /#{NODE_TYPE}/ { [:tNODE_TYPE, text[1..]] }
|
75
|
-
:VALUE /#{OPEN_ATTRIBUTE}/ { @nested_count += 1; @state = :KEY; [:tOPEN_ATTRIBUTE, text] }
|
76
|
-
:VALUE /#{IDENTIFIER_VALUE}/ { [:tIDENTIFIER_VALUE, text] }
|
77
|
-
:DYNAMIC_ATTRIBUTE /#{CLOSE_DYNAMIC_ATTRIBUTE}/ { @state = :VALUE; [:tCLOSE_DYNAMIC_ATTRIBUTE, text] }
|
78
|
-
:DYNAMIC_ATTRIBUTE /#{IDENTIFIER}/ { [:tDYNAMIC_ATTRIBUTE, text] }
|
79
|
-
:ARRAY_VALUE /\s+/
|
80
|
-
:ARRAY_VALUE /#{CLOSE_ARRAY}/ { @state = :VALUE; [:tCLOSE_ARRAY, text] }
|
81
|
-
:ARRAY_VALUE /#{NIL}\?/ { [:tIDENTIFIER_VALUE, text] }
|
82
|
-
:ARRAY_VALUE /#{NIL}/ { [:tNIL, nil] }
|
83
|
-
:ARRAY_VALUE /#{TRUE}/ { [:tBOOLEAN, true] }
|
84
|
-
:ARRAY_VALUE /#{FALSE}/ { [:tBOOLEAN, false] }
|
85
|
-
:ARRAY_VALUE /#{SYMBOL}/ { [:tSYMBOL, text[1..-1].to_sym] }
|
86
|
-
:ARRAY_VALUE /#{FLOAT}/ { [:tFLOAT, text.to_f] }
|
87
|
-
:ARRAY_VALUE /#{INTEGER}/ { [:tINTEGER, text.to_i] }
|
88
|
-
:ARRAY_VALUE /#{REGEXP}/ { [:tREGEXP, eval(text)] }
|
89
|
-
:ARRAY_VALUE /#{DOUBLE_QUOTE_STRING}/ { [:tSTRING, text[1...-1]] }
|
90
|
-
:ARRAY_VALUE /#{SINGLE_QUOTE_STRING}/ { [:tSTRING, text[1...-1]] }
|
91
|
-
:ARRAY_VALUE /#{IDENTIFIER_VALUE}/ { [:tIDENTIFIER_VALUE, text] }
|
92
|
-
|
93
|
-
inner
|
94
|
-
def initialize
|
95
|
-
@nested_count = 0
|
96
|
-
end
|
97
|
-
|
98
|
-
def do_parse; end
|
99
|
-
end
|