synvert-core 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 +4 -4
- data/.gitignore +0 -4
- data/CHANGELOG.md +16 -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 +89 -135
- 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 +49 -112
- data/spec/synvert/core/rewriter/scope/goto_scope_spec.rb +1 -4
- data/spec/synvert/core/rewriter/scope/query_scope_spec.rb +8 -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/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 -58
- 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 -138
- data/lib/synvert/core/node_query/compiler/simple_selector.rb +0 -29
- 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 -108
- data/lib/synvert/core/node_query/lexer.rex.rb +0 -321
- data/lib/synvert/core/node_query/parser.racc.rb +0 -322
- data/lib/synvert/core/node_query/parser.y +0 -62
- data/lib/synvert/core/node_query.rb +0 -37
- data/lib/synvert/core/rewriter/action/append_action.rb +0 -28
- data/lib/synvert/core/rewriter/action/delete_action.rb +0 -32
- 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 -53
- 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 -640
- data/spec/synvert/core/node_query/parser_spec.rb +0 -382
- 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,58 +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
|
-
# @param descendant_match [Boolean] whether to match in descendant node
|
25
|
-
# @return [Array<Parser::AST::Node>] matching nodes.
|
26
|
-
def query_nodes(node, descendant_match = true)
|
27
|
-
matching_nodes = find_nodes_by_selector(node, descendant_match)
|
28
|
-
return matching_nodes if @rest.nil?
|
29
|
-
|
30
|
-
matching_nodes.flat_map { |matching_node| find_nodes_by_rest(matching_node, descendant_match) }
|
31
|
-
end
|
32
|
-
|
33
|
-
def to_s
|
34
|
-
result = []
|
35
|
-
result << @selector.to_s if @selector
|
36
|
-
result << @rest.to_s if @rest
|
37
|
-
result.join(' ')
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
# Find nodes by @rest
|
43
|
-
# @param node [Parser::AST::Node] node to match
|
44
|
-
# @param descendant_match [Boolean] whether to match in descendant node
|
45
|
-
def find_nodes_by_rest(node, descendant_match = false)
|
46
|
-
@rest.query_nodes(node, descendant_match)
|
47
|
-
end
|
48
|
-
|
49
|
-
# Find nodes with nil relationship.
|
50
|
-
# @param node [Parser::AST::Node] node to match
|
51
|
-
# @param descendant_match [Boolean] whether to match in descendant node
|
52
|
-
def find_nodes_by_selector(node, descendant_match = true)
|
53
|
-
return Array(node) if !@selector
|
54
|
-
|
55
|
-
@selector.query_nodes(node, descendant_match)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
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,138 +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 simple_selector [Synvert::Core::NodeQuery::Compiler::SimpleSelector] the simple selector
|
11
|
-
# @param attribute_list [Synvert::Core::NodeQuery::Compiler::AttributeList] the attribute list
|
12
|
-
# @param index [Integer] the index
|
13
|
-
# @param pseudo_class [String] the pseudo class, can be <code>has</code> or <code>not_has</code>
|
14
|
-
# @param pseudo_selector [Synvert::Core::NodeQuery::Compiler::Expression] the pseudo selector
|
15
|
-
def initialize(goto_scope: nil, relationship: nil, rest: nil, simple_selector: nil, index: nil, pseudo_class: nil, pseudo_selector: nil)
|
16
|
-
@goto_scope = goto_scope
|
17
|
-
@relationship = relationship
|
18
|
-
@rest = rest
|
19
|
-
@simple_selector = simple_selector
|
20
|
-
@index = index
|
21
|
-
@pseudo_class = pseudo_class
|
22
|
-
@pseudo_selector = pseudo_selector
|
23
|
-
end
|
24
|
-
|
25
|
-
# Check if node matches the selector.
|
26
|
-
# @param node [Parser::AST::Node] the node
|
27
|
-
def match?(node)
|
28
|
-
node.is_a?(::Parser::AST::Node) &&
|
29
|
-
(!@simple_selector || @simple_selector.match?(node)) &&
|
30
|
-
match_pseudo_class?(node)
|
31
|
-
end
|
32
|
-
|
33
|
-
# Query nodes by the selector.
|
34
|
-
#
|
35
|
-
# * If relationship is nil, it will match in all recursive child nodes and return matching nodes.
|
36
|
-
# * If relationship is decendant, it will match in all recursive child nodes.
|
37
|
-
# * If relationship is child, it will match in direct child nodes.
|
38
|
-
# * If relationship is next sibling, it try to match next sibling node.
|
39
|
-
# * If relationship is subsequent sibling, it will match in all sibling nodes.
|
40
|
-
# @param node [Parser::AST::Node] node to match
|
41
|
-
# @param descendant_match [Boolean] whether to match in descendant node
|
42
|
-
# @return [Array<Parser::AST::Node>] matching nodes.
|
43
|
-
def query_nodes(node, descendant_match = true)
|
44
|
-
return find_nodes_by_relationship(node) if @relationship
|
45
|
-
|
46
|
-
if node.is_a?(::Array)
|
47
|
-
return node.flat_map { |child_node| query_nodes(child_node, descendant_match) }
|
48
|
-
end
|
49
|
-
|
50
|
-
return find_nodes_by_goto_scope(node) if @goto_scope
|
51
|
-
|
52
|
-
nodes = []
|
53
|
-
nodes << node if match?(node)
|
54
|
-
if descendant_match && @simple_selector
|
55
|
-
node.recursive_children do |child_node|
|
56
|
-
nodes << child_node if match?(child_node)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
filter(nodes)
|
60
|
-
end
|
61
|
-
|
62
|
-
def to_s
|
63
|
-
result = []
|
64
|
-
result << "<#{@goto_scope}> " if @goto_scope
|
65
|
-
result << "#{@relationship} " if @relationship
|
66
|
-
result << @rest.to_s if @rest
|
67
|
-
result << @simple_selector.to_s if @simple_selector
|
68
|
-
result << ":#{@pseudo_class}(#{@pseudo_selector})" if @pseudo_class
|
69
|
-
if @index
|
70
|
-
result <<
|
71
|
-
case @index
|
72
|
-
when 0
|
73
|
-
':first-child'
|
74
|
-
when -1
|
75
|
-
':last-child'
|
76
|
-
when (1..)
|
77
|
-
":nth-child(#{@index + 1})"
|
78
|
-
else # ...-1
|
79
|
-
":nth-last-child(#{-@index})"
|
80
|
-
end
|
81
|
-
end
|
82
|
-
result.join('')
|
83
|
-
end
|
84
|
-
|
85
|
-
private
|
86
|
-
|
87
|
-
# Find nodes by @goto_scope
|
88
|
-
# @param node [Parser::AST::Node] node to match
|
89
|
-
def find_nodes_by_goto_scope(node)
|
90
|
-
@goto_scope.split('.').each { |scope| node = node.send(scope) }
|
91
|
-
@rest.query_nodes(node, false)
|
92
|
-
end
|
93
|
-
|
94
|
-
# Find ndoes by @relationship
|
95
|
-
# @param node [Parser::AST::Node] node to match
|
96
|
-
def find_nodes_by_relationship(node)
|
97
|
-
nodes = []
|
98
|
-
case @relationship
|
99
|
-
when '>'
|
100
|
-
if node.is_a?(::Array)
|
101
|
-
node.each do |child_node|
|
102
|
-
nodes << child_node if @rest.match?(child_node)
|
103
|
-
end
|
104
|
-
else
|
105
|
-
node.children.each do |child_node|
|
106
|
-
nodes << child_node if @rest.match?(child_node)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
when '+'
|
110
|
-
next_sibling = node.siblings.first
|
111
|
-
nodes << next_sibling if @rest.match?(next_sibling)
|
112
|
-
when '~'
|
113
|
-
node.siblings.each do |sibling_node|
|
114
|
-
nodes << sibling_node if @rest.match?(sibling_node)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
return filter(nodes)
|
118
|
-
end
|
119
|
-
|
120
|
-
def match_pseudo_class?(node)
|
121
|
-
case @pseudo_class
|
122
|
-
when 'has'
|
123
|
-
!@pseudo_selector.query_nodes(node).empty?
|
124
|
-
when 'not_has'
|
125
|
-
@pseudo_selector.query_nodes(node).empty?
|
126
|
-
else
|
127
|
-
true
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
# Filter nodes by index.
|
132
|
-
def filter(nodes)
|
133
|
-
return nodes if @index.nil?
|
134
|
-
|
135
|
-
nodes[@index] ? [nodes[@index]] : []
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Synvert::Core::NodeQuery::Compiler
|
4
|
-
# SimpleSelector used to match nodes, it combines by node type and/or attribute list.
|
5
|
-
class SimpleSelector
|
6
|
-
# Initialize a SimpleSelector.
|
7
|
-
# @param node_type [String] the node type
|
8
|
-
# @param attribute_list [Synvert::Core::NodeQuery::Compiler::AttributeList] the attribute list
|
9
|
-
def initialize(node_type:, attribute_list: nil)
|
10
|
-
@node_type = node_type
|
11
|
-
@attribute_list = attribute_list
|
12
|
-
end
|
13
|
-
|
14
|
-
# Check if node matches the selector.
|
15
|
-
# @param node [Parser::AST::Node] the node
|
16
|
-
def match?(node, _operator = '==')
|
17
|
-
return false unless node
|
18
|
-
|
19
|
-
@node_type.to_sym == node.type && (!@attribute_list || @attribute_list.match?(node))
|
20
|
-
end
|
21
|
-
|
22
|
-
def to_s
|
23
|
-
result = []
|
24
|
-
result << ".#{@node_type}" if @node_type
|
25
|
-
result << @attribute_list.to_s if @attribute_list
|
26
|
-
result.join('')
|
27
|
-
end
|
28
|
-
end
|
29
|
-
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 :SimpleSelector, 'synvert/core/node_query/compiler/simple_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
|