synvert-core 0.63.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +1 -1
- data/.gitignore +4 -0
- data/CHANGELOG.md +9 -1
- data/Guardfile +11 -2
- data/README.md +74 -34
- data/Rakefile +15 -1
- data/lib/synvert/core/array_ext.rb +41 -0
- data/lib/synvert/core/configuration.rb +12 -0
- data/lib/synvert/core/engine/erb.rb +9 -8
- data/lib/synvert/core/exceptions.rb +0 -4
- data/lib/synvert/core/node_ext.rb +232 -128
- data/lib/synvert/core/node_query/compiler/array.rb +34 -0
- data/lib/synvert/core/node_query/compiler/attribute.rb +51 -0
- data/lib/synvert/core/node_query/compiler/attribute_list.rb +24 -0
- data/lib/synvert/core/node_query/compiler/boolean.rb +23 -0
- data/lib/synvert/core/node_query/compiler/comparable.rb +79 -0
- data/lib/synvert/core/node_query/compiler/dynamic_attribute.rb +51 -0
- data/lib/synvert/core/node_query/compiler/expression.rb +88 -0
- data/lib/synvert/core/node_query/compiler/float.rb +23 -0
- data/lib/synvert/core/node_query/compiler/identifier.rb +41 -0
- data/lib/synvert/core/node_query/compiler/integer.rb +23 -0
- data/lib/synvert/core/node_query/compiler/invalid_operator_error.rb +7 -0
- data/lib/synvert/core/node_query/compiler/nil.rb +23 -0
- data/lib/synvert/core/node_query/compiler/parse_error.rb +7 -0
- data/lib/synvert/core/node_query/compiler/regexp.rb +37 -0
- data/lib/synvert/core/node_query/compiler/selector.rb +51 -0
- data/lib/synvert/core/node_query/compiler/string.rb +34 -0
- data/lib/synvert/core/node_query/compiler/symbol.rb +23 -0
- data/lib/synvert/core/node_query/compiler.rb +24 -0
- data/lib/synvert/core/node_query/lexer.rex +96 -0
- data/lib/synvert/core/node_query/lexer.rex.rb +293 -0
- data/lib/synvert/core/node_query/parser.racc.rb +518 -0
- data/lib/synvert/core/node_query/parser.y +84 -0
- data/lib/synvert/core/node_query.rb +36 -0
- data/lib/synvert/core/rewriter/action/append_action.rb +4 -3
- data/lib/synvert/core/rewriter/action/delete_action.rb +17 -8
- data/lib/synvert/core/rewriter/action/insert_action.rb +16 -7
- data/lib/synvert/core/rewriter/action/insert_after_action.rb +3 -2
- data/lib/synvert/core/rewriter/action/prepend_action.rb +3 -2
- data/lib/synvert/core/rewriter/action/remove_action.rb +16 -10
- data/lib/synvert/core/rewriter/action/replace_action.rb +15 -5
- data/lib/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action.rb +18 -11
- data/lib/synvert/core/rewriter/action/replace_with_action.rb +6 -5
- data/lib/synvert/core/rewriter/action/wrap_action.rb +16 -7
- data/lib/synvert/core/rewriter/action.rb +22 -10
- data/lib/synvert/core/rewriter/any_value.rb +1 -0
- data/lib/synvert/core/rewriter/condition/if_exist_condition.rb +4 -0
- data/lib/synvert/core/rewriter/condition/if_only_exist_condition.rb +4 -0
- data/lib/synvert/core/rewriter/condition/unless_exist_condition.rb +4 -0
- data/lib/synvert/core/rewriter/condition.rb +11 -3
- data/lib/synvert/core/rewriter/gem_spec.rb +6 -3
- data/lib/synvert/core/rewriter/helper.rb +7 -4
- data/lib/synvert/core/rewriter/instance.rb +217 -104
- data/lib/synvert/core/rewriter/ruby_version.rb +4 -4
- data/lib/synvert/core/rewriter/scope/goto_scope.rb +5 -6
- data/lib/synvert/core/rewriter/scope/query_scope.rb +36 -0
- data/lib/synvert/core/rewriter/scope/within_scope.rb +10 -5
- data/lib/synvert/core/rewriter/scope.rb +8 -0
- data/lib/synvert/core/rewriter/warning.rb +1 -1
- data/lib/synvert/core/rewriter.rb +91 -43
- data/lib/synvert/core/version.rb +1 -1
- data/lib/synvert/core.rb +22 -6
- data/spec/synvert/core/engine/erb_spec.rb +2 -2
- data/spec/synvert/core/node_ext_spec.rb +36 -12
- data/spec/synvert/core/node_query/lexer_spec.rb +525 -0
- data/spec/synvert/core/node_query/parser_spec.rb +270 -0
- data/spec/synvert/core/rewriter/action_spec.rb +0 -4
- data/spec/synvert/core/rewriter/condition/if_only_exist_condition_spec.rb +1 -6
- data/spec/synvert/core/rewriter/gem_spec_spec.rb +1 -1
- data/spec/synvert/core/rewriter/helper_spec.rb +4 -1
- data/spec/synvert/core/rewriter/instance_spec.rb +31 -20
- data/spec/synvert/core/rewriter/scope/query_scope_spec.rb +74 -0
- data/spec/synvert/core/rewriter/scope/within_scope_spec.rb +12 -9
- data/spec/synvert/core/rewriter_spec.rb +4 -2
- data/synvert-core-ruby.gemspec +7 -2
- metadata +91 -4
@@ -3,23 +3,32 @@
|
|
3
3
|
module Synvert::Core
|
4
4
|
# InsertAction to add code to the node.
|
5
5
|
class Rewriter::InsertAction < Rewriter::Action
|
6
|
-
|
6
|
+
# Initialize an InsertAction.
|
7
|
+
#
|
8
|
+
# @param instance [Synvert::Core::Rewriter::Instance]
|
9
|
+
# @param code [String] to be inserted
|
10
|
+
# @param at [String] position to insert, beginning or end
|
11
|
+
# @param to [<Symbol|String>] name of child node
|
12
|
+
def initialize(instance, code, at: 'end', to: nil)
|
7
13
|
super(instance, code)
|
8
14
|
@at = at
|
9
15
|
@to = to
|
10
16
|
end
|
11
17
|
|
12
|
-
def calculate_position
|
13
|
-
node_range = @to ? @node.child_node_range(@to) : @node.loc.expression
|
14
|
-
@begin_pos = @at == 'end' ? node_range.end_pos : node_range.begin_pos
|
15
|
-
@end_pos = @begin_pos
|
16
|
-
end
|
17
|
-
|
18
18
|
# The rewritten source code.
|
19
19
|
#
|
20
20
|
# @return [String] rewritten code.
|
21
21
|
def rewritten_code
|
22
22
|
rewritten_source
|
23
23
|
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# Calculate the begin and end positions.
|
28
|
+
def calculate_position
|
29
|
+
node_range = @to ? @node.child_node_range(@to) : @node.loc.expression
|
30
|
+
@begin_pos = @at == 'end' ? node_range.end_pos : node_range.begin_pos
|
31
|
+
@end_pos = @begin_pos
|
32
|
+
end
|
24
33
|
end
|
25
34
|
end
|
@@ -3,13 +3,14 @@
|
|
3
3
|
module Synvert::Core
|
4
4
|
# InsertAfterAction to insert code next to the node.
|
5
5
|
class Rewriter::InsertAfterAction < Rewriter::Action
|
6
|
+
private
|
7
|
+
|
8
|
+
# Calculate the begin and end positions.
|
6
9
|
def calculate_position
|
7
10
|
@begin_pos = @node.loc.expression.end_pos
|
8
11
|
@end_pos = @begin_pos
|
9
12
|
end
|
10
13
|
|
11
|
-
private
|
12
|
-
|
13
14
|
# Indent of the node.
|
14
15
|
#
|
15
16
|
# @param node [Parser::AST::Node]
|
@@ -3,8 +3,11 @@
|
|
3
3
|
module Synvert::Core
|
4
4
|
# PrependAction to prepend code to the top of node body.
|
5
5
|
class Rewriter::PrependAction < Rewriter::Action
|
6
|
+
private
|
7
|
+
|
6
8
|
DO_LENGTH = ' do'.length
|
7
9
|
|
10
|
+
# Calculate the begin and end positions.
|
8
11
|
def calculate_position
|
9
12
|
@begin_pos =
|
10
13
|
case @node.type
|
@@ -26,8 +29,6 @@ module Synvert::Core
|
|
26
29
|
@end_pos = @begin_pos
|
27
30
|
end
|
28
31
|
|
29
|
-
private
|
30
|
-
|
31
32
|
# Indent of the node.
|
32
33
|
#
|
33
34
|
# @param node [Parser::AST::Node]
|
@@ -3,13 +3,21 @@
|
|
3
3
|
module Synvert::Core
|
4
4
|
# RemoveAction to remove current node.
|
5
5
|
class Rewriter::RemoveAction < Rewriter::Action
|
6
|
+
# Initialize a RemoveAction.
|
7
|
+
#
|
8
|
+
# @param instance [Synvert::Core::Rewriter::RemoveAction]
|
6
9
|
def initialize(instance)
|
7
10
|
super(instance, nil)
|
8
11
|
end
|
9
12
|
|
10
|
-
#
|
11
|
-
|
12
|
-
|
13
|
+
# The rewritten code, always empty string.
|
14
|
+
def rewritten_code
|
15
|
+
''
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
# Calculate the begin the end positions.
|
13
21
|
def calculate_position
|
14
22
|
if take_whole_line?
|
15
23
|
@begin_pos = start_index
|
@@ -23,22 +31,20 @@ module Synvert::Core
|
|
23
31
|
end
|
24
32
|
end
|
25
33
|
|
26
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
34
|
+
# Check if the source code of current node takes the whole line.
|
35
|
+
#
|
36
|
+
# @return [Boolean]
|
33
37
|
def take_whole_line?
|
34
38
|
@node.to_source == file_source[start_index...end_index].strip
|
35
39
|
end
|
36
40
|
|
41
|
+
# Get the start position of the line
|
37
42
|
def start_index
|
38
43
|
index = file_source[0..@node.loc.expression.begin_pos].rindex("\n")
|
39
44
|
index ? index + "\n".length : @node.loc.expression.begin_pos
|
40
45
|
end
|
41
46
|
|
47
|
+
# Get the end position of the line
|
42
48
|
def end_index
|
43
49
|
index = file_source[@node.loc.expression.end_pos..-1].index("\n")
|
44
50
|
index ? @node.loc.expression.end_pos + index + "\n".length : @node.loc.expression.end_pos
|
@@ -3,21 +3,31 @@
|
|
3
3
|
module Synvert::Core
|
4
4
|
# ReplaceAction to replace child node with code.
|
5
5
|
class Rewriter::ReplaceAction < Rewriter::Action
|
6
|
+
# Initailize a ReplaceAction.
|
7
|
+
#
|
8
|
+
# @param instance [Synvert::Core::Rewriter::Instance]
|
9
|
+
# @param selectors [Array<Symbol|String>] used to select child nodes
|
10
|
+
# @param with [String] the new code
|
6
11
|
def initialize(instance, *selectors, with:)
|
7
12
|
super(instance, with)
|
8
13
|
@selectors = selectors
|
9
14
|
end
|
10
15
|
|
11
|
-
def calculate_position
|
12
|
-
@begin_pos = @selectors.map { |selector| @node.child_node_range(selector).begin_pos }.min
|
13
|
-
@end_pos = @selectors.map { |selector| @node.child_node_range(selector).end_pos }.max
|
14
|
-
end
|
15
|
-
|
16
16
|
# The rewritten source code.
|
17
17
|
#
|
18
18
|
# @return [String] rewritten code.
|
19
19
|
def rewritten_code
|
20
20
|
rewritten_source
|
21
21
|
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
# Calculate the begin the end positions.
|
26
|
+
def calculate_position
|
27
|
+
@begin_pos = @selectors.map { |selector| @node.child_node_range(selector).begin_pos }
|
28
|
+
.min
|
29
|
+
@end_pos = @selectors.map { |selector| @node.child_node_range(selector).end_pos }
|
30
|
+
.max
|
31
|
+
end
|
22
32
|
end
|
23
33
|
end
|
@@ -2,12 +2,28 @@
|
|
2
2
|
|
3
3
|
module Synvert::Core
|
4
4
|
# ReplaceErbStmtWithExprAction to replace erb stmt code to expr,
|
5
|
+
# @example
|
5
6
|
# e.g. <% form_for ... %> => <%= form_for ... %>.
|
6
7
|
class Rewriter::ReplaceErbStmtWithExprAction < Rewriter::Action
|
7
|
-
|
8
|
-
|
8
|
+
# Initialize a ReplaceErbStmtWithExprAction.
|
9
|
+
#
|
10
|
+
# @param instance [Synvert::Core::Rewriter::Instance]
|
11
|
+
def initialize(instance)
|
12
|
+
super(instance, nil)
|
13
|
+
end
|
14
|
+
|
15
|
+
# The rewritten erb expr code.
|
16
|
+
#
|
17
|
+
# @return [String] rewritten code.
|
18
|
+
def rewritten_code
|
19
|
+
@node.loc.expression.source_buffer.source[begin_pos...end_pos]
|
20
|
+
.sub(Engine::ERUBY_STMT_SPLITTER, '@output_buffer.append= ')
|
21
|
+
.sub(Engine::ERUBY_STMT_SPLITTER, Engine::ERUBY_EXPR_SPLITTER)
|
9
22
|
end
|
10
23
|
|
24
|
+
private
|
25
|
+
|
26
|
+
# Calculate the begin the end positions.
|
11
27
|
def calculate_position
|
12
28
|
node_begin_pos = @node.loc.expression.begin_pos
|
13
29
|
while @node.loc.expression.source_buffer.source[node_begin_pos -= 1] == ' '
|
@@ -20,14 +36,5 @@ module Synvert::Core
|
|
20
36
|
end
|
21
37
|
@end_pos = node_begin_pos
|
22
38
|
end
|
23
|
-
|
24
|
-
# The rewritten erb expr code.
|
25
|
-
#
|
26
|
-
# @return [String] rewritten code.
|
27
|
-
def rewritten_code
|
28
|
-
@node.loc.expression.source_buffer.source[begin_pos...end_pos]
|
29
|
-
.sub(Engine::ERUBY_STMT_SPLITTER, '@output_buffer.append= ')
|
30
|
-
.sub(Engine::ERUBY_STMT_SPLITTER, Engine::ERUBY_EXPR_SPLITTER)
|
31
|
-
end
|
32
39
|
end
|
33
40
|
end
|
@@ -3,11 +3,6 @@
|
|
3
3
|
module Synvert::Core
|
4
4
|
# ReplaceWithAction to replace code.
|
5
5
|
class Rewriter::ReplaceWithAction < Rewriter::Action
|
6
|
-
def calculate_position
|
7
|
-
@begin_pos = @node.loc.expression.begin_pos
|
8
|
-
@end_pos = @node.loc.expression.end_pos
|
9
|
-
end
|
10
|
-
|
11
6
|
# The rewritten source code with proper indent.
|
12
7
|
#
|
13
8
|
# @return [String] rewritten code.
|
@@ -25,6 +20,12 @@ module Synvert::Core
|
|
25
20
|
|
26
21
|
private
|
27
22
|
|
23
|
+
# Calculate the begin the end positions.
|
24
|
+
def calculate_position
|
25
|
+
@begin_pos = @node.loc.expression.begin_pos
|
26
|
+
@end_pos = @node.loc.expression.end_pos
|
27
|
+
end
|
28
|
+
|
28
29
|
# Indent of the node
|
29
30
|
#
|
30
31
|
# @return [String] n times whitesphace
|
@@ -6,23 +6,32 @@ module Synvert::Core
|
|
6
6
|
# Note: if WrapAction is conflicted with another action (begin_pos and end_pos are overlapped),
|
7
7
|
# we have to put those 2 actions into 2 within_file scopes.
|
8
8
|
class Rewriter::WrapAction < Rewriter::Action
|
9
|
+
# Initialize a WrapAction.
|
10
|
+
#
|
11
|
+
# @param instance [Synvert::Core::Rewriter::WrapAction]
|
12
|
+
# @param with [String] new code to wrap
|
13
|
+
# @param indent [Integer, nil] number of whitespaces
|
9
14
|
def initialize(instance, with:, indent: nil)
|
10
15
|
super(instance, with)
|
11
16
|
@indent = indent || @node.column
|
12
17
|
end
|
13
18
|
|
14
|
-
def calculate_position
|
15
|
-
@begin_pos = @node.loc.expression.begin_pos
|
16
|
-
@end_pos = @node.loc.expression.end_pos
|
17
|
-
end
|
18
|
-
|
19
19
|
# The rewritten source code.
|
20
20
|
#
|
21
21
|
# @return [String] rewritten code.
|
22
22
|
def rewritten_code
|
23
23
|
"#{@code}\n#{' ' * @indent}" +
|
24
|
-
|
25
|
-
|
24
|
+
@node.to_source.split("\n").map { |line| " #{line}" }
|
25
|
+
.join("\n") +
|
26
|
+
"\n#{' ' * @indent}end"
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# Calculate the begin the end positions.
|
32
|
+
def calculate_position
|
33
|
+
@begin_pos = @node.loc.expression.begin_pos
|
34
|
+
@end_pos = @node.loc.expression.end_pos
|
26
35
|
end
|
27
36
|
end
|
28
37
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Synvert::Core
|
4
|
-
# Action defines rewriter action,
|
4
|
+
# Action defines rewriter action, insert, replace or delete code.
|
5
5
|
class Rewriter::Action
|
6
6
|
DEFAULT_INDENT = 2
|
7
7
|
|
@@ -14,31 +14,28 @@ module Synvert::Core
|
|
14
14
|
# Initialize an action.
|
15
15
|
#
|
16
16
|
# @param instance [Synvert::Core::Rewriter::Instance]
|
17
|
-
# @param code [String] new code to
|
17
|
+
# @param code [String] new code to insert, replace or delete.
|
18
18
|
def initialize(instance, code)
|
19
19
|
@instance = instance
|
20
20
|
@code = code
|
21
21
|
@node = @instance.current_node
|
22
22
|
end
|
23
23
|
|
24
|
+
# Calculate begin and end positions, and return self.
|
25
|
+
#
|
26
|
+
# @return [Synvert::Core::Rewriter::Action] self
|
24
27
|
def process
|
25
28
|
calculate_position
|
26
29
|
self
|
27
30
|
end
|
28
31
|
|
29
|
-
# Line number of current node.
|
30
|
-
#
|
31
|
-
# @return [Integer] line number.
|
32
|
-
def line
|
33
|
-
@node.loc.expression.line
|
34
|
-
end
|
35
|
-
|
36
32
|
# The rewritten source code with proper indent.
|
37
33
|
#
|
38
34
|
# @return [String] rewritten code.
|
39
35
|
def rewritten_code
|
40
36
|
if rewritten_source.split("\n").length > 1
|
41
|
-
"\n\n" + rewritten_source.split("\n").map { |line| indent(@node) + line }
|
37
|
+
"\n\n" + rewritten_source.split("\n").map { |line| indent(@node) + line }
|
38
|
+
.join("\n")
|
42
39
|
else
|
43
40
|
"\n" + indent(@node) + rewritten_source
|
44
41
|
end
|
@@ -46,6 +43,13 @@ module Synvert::Core
|
|
46
43
|
|
47
44
|
protected
|
48
45
|
|
46
|
+
# Calculate the begin the end positions.
|
47
|
+
#
|
48
|
+
# @abstract
|
49
|
+
def calculate_position
|
50
|
+
raise NotImplementedError, 'must be implemented by subclasses'
|
51
|
+
end
|
52
|
+
|
49
53
|
# The rewritten source code.
|
50
54
|
#
|
51
55
|
# @return [String] rewritten source code.
|
@@ -53,12 +57,14 @@ module Synvert::Core
|
|
53
57
|
@rewritten_source ||= @node.rewritten_source(@code)
|
54
58
|
end
|
55
59
|
|
60
|
+
# Squeeze spaces from source code.
|
56
61
|
def squeeze_spaces
|
57
62
|
if file_source[@begin_pos - 1] == ' ' && file_source[@end_pos] == ' '
|
58
63
|
@begin_pos -= 1
|
59
64
|
end
|
60
65
|
end
|
61
66
|
|
67
|
+
# Squeeze empty lines from source code.
|
62
68
|
def squeeze_lines
|
63
69
|
lines = file_source.split("\n")
|
64
70
|
begin_line = @node.loc.expression.first_line
|
@@ -71,6 +77,9 @@ module Synvert::Core
|
|
71
77
|
end
|
72
78
|
end
|
73
79
|
|
80
|
+
# Remove unused comma.
|
81
|
+
# e.g. `foobar(foo, bar)`, if we remove `foo`, the comma should also be removed,
|
82
|
+
# the code should be changed to `foobar(bar)`.
|
74
83
|
def remove_comma
|
75
84
|
if ',' == file_source[@begin_pos - 1]
|
76
85
|
@begin_pos -= 1
|
@@ -83,6 +92,9 @@ module Synvert::Core
|
|
83
92
|
end
|
84
93
|
end
|
85
94
|
|
95
|
+
# Return file source.
|
96
|
+
#
|
97
|
+
# @return [String]
|
86
98
|
def file_source
|
87
99
|
@file_source ||= @instance.file_source
|
88
100
|
end
|
@@ -3,7 +3,11 @@
|
|
3
3
|
module Synvert::Core
|
4
4
|
# IfExistCondition checks if matching node exists in the node children.
|
5
5
|
class Rewriter::IfExistCondition < Rewriter::Condition
|
6
|
+
private
|
7
|
+
|
6
8
|
# check if any child node matches the rules.
|
9
|
+
#
|
10
|
+
# @return [Boolean]
|
7
11
|
def match?
|
8
12
|
match = false
|
9
13
|
@instance.current_node.recursive_children do |child_node|
|
@@ -3,7 +3,11 @@
|
|
3
3
|
module Synvert::Core
|
4
4
|
# IfOnlyExistCondition checks if node has only one child node and the child node matches rules.
|
5
5
|
class Rewriter::IfOnlyExistCondition < Rewriter::Condition
|
6
|
+
private
|
7
|
+
|
6
8
|
# check if only have one child node and the child node matches rules.
|
9
|
+
#
|
10
|
+
# @return [Boolean]
|
7
11
|
def match?
|
8
12
|
@instance.current_node.body.size == 1 && @instance.current_node.body.first.match?(@rules)
|
9
13
|
end
|
@@ -3,7 +3,11 @@
|
|
3
3
|
module Synvert::Core
|
4
4
|
# UnlessExistCondition checks if matching node doesn't exist in the node children.
|
5
5
|
class Rewriter::UnlessExistCondition < Rewriter::Condition
|
6
|
+
private
|
7
|
+
|
6
8
|
# check if none of child node matches the rules.
|
9
|
+
#
|
10
|
+
# return [Boolean]
|
7
11
|
def match?
|
8
12
|
match = false
|
9
13
|
@instance.current_node.recursive_children do |child_node|
|
@@ -3,12 +3,11 @@
|
|
3
3
|
module Synvert::Core
|
4
4
|
# Condition checks if rules matches.
|
5
5
|
class Rewriter::Condition
|
6
|
-
# Initialize a
|
6
|
+
# Initialize a Condition.
|
7
7
|
#
|
8
8
|
# @param instance [Synvert::Core::Rewriter::Instance]
|
9
9
|
# @param rules [Hash]
|
10
|
-
# @
|
11
|
-
# @return [Synvert::Core::Rewriter::Condition]
|
10
|
+
# @yield run when condition matches
|
12
11
|
def initialize(instance, rules, &block)
|
13
12
|
@instance = instance
|
14
13
|
@rules = rules
|
@@ -19,5 +18,14 @@ module Synvert::Core
|
|
19
18
|
def process
|
20
19
|
@instance.instance_eval(&@block) if match?
|
21
20
|
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
# Check if condition matches
|
25
|
+
#
|
26
|
+
# @abstract
|
27
|
+
def match?
|
28
|
+
raise NotImplementedError, 'must be implemented by subclasses'
|
29
|
+
end
|
22
30
|
end
|
23
31
|
end
|
@@ -3,12 +3,16 @@
|
|
3
3
|
module Synvert::Core
|
4
4
|
# GemSpec checks and compares gem version.
|
5
5
|
class Rewriter::GemSpec
|
6
|
+
# @!attribute [r] name
|
7
|
+
# @return [String] the name of gem_spec
|
8
|
+
# @!attribute [r] version
|
9
|
+
# @return [String] the version of gem_spec
|
6
10
|
attr_reader :name, :version
|
7
11
|
|
8
|
-
# Initialize a
|
12
|
+
# Initialize a GemSpec.
|
9
13
|
#
|
10
14
|
# @param name [String] gem name
|
11
|
-
# @param version [String] gem version, e.g. '~> 2.0.0'
|
15
|
+
# @param version [String] gem version, e.g. '~> 2.0.0'
|
12
16
|
def initialize(name, version)
|
13
17
|
@name = name
|
14
18
|
@version = version
|
@@ -17,7 +21,6 @@ module Synvert::Core
|
|
17
21
|
# Check if the specified gem version in Gemfile.lock matches gem_spec comparator.
|
18
22
|
#
|
19
23
|
# @return [Boolean] true if matches, otherwise false.
|
20
|
-
# @raise [Synvert::Core::GemfileLockNotFound] raise if Gemfile.lock does not exist.
|
21
24
|
def match?
|
22
25
|
gemfile_lock_path = File.expand_path(File.join(Configuration.path, 'Gemfile.lock'))
|
23
26
|
|
@@ -24,7 +24,7 @@ module Synvert::Core
|
|
24
24
|
|
25
25
|
# Add arguments with parenthesis if necessary.
|
26
26
|
#
|
27
|
-
# @return [String] return
|
27
|
+
# @return [String] return (!{{arguments}}) if node.arguments present, otherwise return nothing.
|
28
28
|
#
|
29
29
|
# @example
|
30
30
|
#
|
@@ -65,7 +65,9 @@ module Synvert::Core
|
|
65
65
|
#
|
66
66
|
# strip_brackets("(1..100)") #=> "1..100"
|
67
67
|
def strip_brackets(code)
|
68
|
-
code.sub(/^\((.*)\)$/) { Regexp.last_match(1) }
|
68
|
+
code.sub(/^\((.*)\)$/) { Regexp.last_match(1) }
|
69
|
+
.sub(/^\[(.*)\]$/) { Regexp.last_match(1) }
|
70
|
+
.sub(/^{(.*)}$/) {
|
69
71
|
Regexp.last_match(1).strip
|
70
72
|
}
|
71
73
|
end
|
@@ -73,7 +75,7 @@ module Synvert::Core
|
|
73
75
|
# Reject some keys from hash node.
|
74
76
|
#
|
75
77
|
# @param hash_node [Parser::AST::Node]
|
76
|
-
# @param keys [Array] keys should be rejected from the hash.
|
78
|
+
# @param keys [Array<String, Symbol>] keys should be rejected from the hash.
|
77
79
|
# @return [String] source of of the hash node after rejecting some keys.
|
78
80
|
#
|
79
81
|
# @example
|
@@ -81,7 +83,8 @@ module Synvert::Core
|
|
81
83
|
# hash_node = Parser::CurrentRuby.parse("{ key1: 'value1', key2: 'value2' }")
|
82
84
|
# reject_keys_from_hash(hash_node, :key1) => "key2: 'value2'"
|
83
85
|
def reject_keys_from_hash(hash_node, *keys)
|
84
|
-
hash_node.children.reject { |pair_node| keys.include?(pair_node.key.to_value) }
|
86
|
+
hash_node.children.reject { |pair_node| keys.include?(pair_node.key.to_value) }
|
87
|
+
.map(&:to_source).join(', ')
|
85
88
|
end
|
86
89
|
end
|
87
90
|
end
|