synvert 0.0.17 → 0.1.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/.travis.yml +0 -1
- data/CHANGELOG.md +4 -0
- data/README.md +7 -26
- data/bin/synvert +0 -1
- data/lib/synvert/cli.rb +26 -14
- data/lib/synvert/snippet.rb +17 -0
- data/lib/synvert/version.rb +1 -1
- data/lib/synvert.rb +3 -11
- data/synvert.gemspec +2 -3
- metadata +6 -85
- data/lib/synvert/configuration.rb +0 -25
- data/lib/synvert/exceptions.rb +0 -13
- data/lib/synvert/node_ext.rb +0 -319
- data/lib/synvert/rewriter/action.rb +0 -224
- data/lib/synvert/rewriter/condition.rb +0 -56
- data/lib/synvert/rewriter/gem_spec.rb +0 -42
- data/lib/synvert/rewriter/instance.rb +0 -185
- data/lib/synvert/rewriter/scope.rb +0 -46
- data/lib/synvert/rewriter.rb +0 -200
- data/lib/synvert/snippets/check_syntax.rb +0 -5
- data/lib/synvert/snippets/factory_girl/syntax_methods.rb +0 -98
- data/lib/synvert/snippets/rails/convert_dynamic_finders.rb +0 -93
- data/lib/synvert/snippets/rails/strong_parameters.rb +0 -93
- data/lib/synvert/snippets/rails/upgrade_3_0_to_3_1.rb +0 -135
- data/lib/synvert/snippets/rails/upgrade_3_1_to_3_2.rb +0 -42
- data/lib/synvert/snippets/rails/upgrade_3_2_to_4_0.rb +0 -230
- data/lib/synvert/snippets/rspec/be_close_to_be_within.rb +0 -18
- data/lib/synvert/snippets/rspec/block_to_expect.rb +0 -22
- data/lib/synvert/snippets/rspec/boolean_matcher.rb +0 -20
- data/lib/synvert/snippets/rspec/collection_matcher.rb +0 -34
- data/lib/synvert/snippets/rspec/its_to_it.rb +0 -89
- data/lib/synvert/snippets/rspec/message_expectation.rb +0 -41
- data/lib/synvert/snippets/rspec/method_stub.rb +0 -84
- data/lib/synvert/snippets/rspec/negative_error_expectation.rb +0 -21
- data/lib/synvert/snippets/rspec/new_syntax.rb +0 -18
- data/lib/synvert/snippets/rspec/one_liner_expectation.rb +0 -71
- data/lib/synvert/snippets/rspec/should_to_expect.rb +0 -50
- data/lib/synvert/snippets/rspec/stub_and_mock_to_double.rb +0 -22
- data/lib/synvert/snippets/ruby/new_hash_syntax.rb +0 -21
- data/lib/synvert/snippets/ruby/new_lambda_syntax.rb +0 -20
- data/spec/spec_helper.rb +0 -26
- data/spec/support/parser_helper.rb +0 -5
- data/spec/synvert/node_ext_spec.rb +0 -201
- data/spec/synvert/rewriter/action_spec.rb +0 -225
- data/spec/synvert/rewriter/condition_spec.rb +0 -106
- data/spec/synvert/rewriter/gem_spec_spec.rb +0 -52
- data/spec/synvert/rewriter/instance_spec.rb +0 -163
- data/spec/synvert/rewriter/scope_spec.rb +0 -42
- data/spec/synvert/rewriter_spec.rb +0 -153
- data/spec/synvert/snippets/factory_girl/syntax_methods_spec.rb +0 -154
- data/spec/synvert/snippets/rails/convert_dynamic_finders_spec.rb +0 -83
- data/spec/synvert/snippets/rails/strong_parameters_spec.rb +0 -132
- data/spec/synvert/snippets/rails/upgrade_3_0_to_3_1_spec.rb +0 -88
- data/spec/synvert/snippets/rails/upgrade_3_1_to_3_2_spec.rb +0 -41
- data/spec/synvert/snippets/rails/upgrade_3_2_to_4_0_spec.rb +0 -299
- data/spec/synvert/snippets/rspec/new_syntax_spec.rb +0 -183
- data/spec/synvert/snippets/ruby/new_hash_syntax_spec.rb +0 -27
- data/spec/synvert/snippets/ruby/new_lambda_syntax_spec.rb +0 -27
data/lib/synvert/node_ext.rb
DELETED
@@ -1,319 +0,0 @@
|
|
1
|
-
# Parser::AST::Node monkey patch.
|
2
|
-
class Parser::AST::Node
|
3
|
-
# Get name node of :class, :module, :def and :defs node.
|
4
|
-
#
|
5
|
-
# @return [Parser::AST::Node] name node.
|
6
|
-
# @raise [Synvert::MethodNotSupported] if calls on other node.
|
7
|
-
def name
|
8
|
-
case self.type
|
9
|
-
when :class, :module, :def
|
10
|
-
self.children[0]
|
11
|
-
when :defs
|
12
|
-
self.children[1]
|
13
|
-
else
|
14
|
-
raise Synvert::MethodNotSupported.new "name is not handled for #{self.inspect}"
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
# Get receiver node of :send node.
|
19
|
-
#
|
20
|
-
# @return [Parser::AST::Node] receiver node.
|
21
|
-
# @raise [Synvert::MethodNotSupported] if calls on other node.
|
22
|
-
def receiver
|
23
|
-
if :send == self.type
|
24
|
-
self.children[0]
|
25
|
-
else
|
26
|
-
raise Synvert::MethodNotSupported.new "receiver is not handled for #{self.inspect}"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
# Get message node of :send node.
|
31
|
-
#
|
32
|
-
# @return [Parser::AST::Node] mesage node.
|
33
|
-
# @raise [Synvert::MethodNotSupported] if calls on other node.
|
34
|
-
def message
|
35
|
-
if :send == self.type
|
36
|
-
self.children[1]
|
37
|
-
else
|
38
|
-
raise Synvert::MethodNotSupported.new "message is not handled for #{self.inspect}"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# Get arguments node of :send, :block or :defined? node.
|
43
|
-
#
|
44
|
-
# @return [Array<Parser::AST::Node>] arguments node.
|
45
|
-
# @raise [Synvert::MethodNotSupported] if calls on other node.
|
46
|
-
def arguments
|
47
|
-
case self.type
|
48
|
-
when :send
|
49
|
-
self.children[2..-1]
|
50
|
-
when :block
|
51
|
-
self.children[1].children
|
52
|
-
when :defined?
|
53
|
-
self.children
|
54
|
-
else
|
55
|
-
raise Synvert::MethodNotSupported.new "arguments is not handled for #{self.inspect}"
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
# Get caller node of :block node.
|
60
|
-
#
|
61
|
-
# @return [Parser::AST::Node] caller node.
|
62
|
-
# @raise [Synvert::MethodNotSupported] if calls on other node.
|
63
|
-
def caller
|
64
|
-
if :block == self.type
|
65
|
-
self.children[0]
|
66
|
-
else
|
67
|
-
raise Synvert::MethodNotSupported.new "caller is not handled for #{self.inspect}"
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
# Get body node of :begin or :block node.
|
72
|
-
#
|
73
|
-
# @return [Array<Parser::AST::Node>] body node.
|
74
|
-
# @raise [Synvert::MethodNotSupported] if calls on other node.
|
75
|
-
def body
|
76
|
-
case self.type
|
77
|
-
when :begin
|
78
|
-
self.children
|
79
|
-
when :block
|
80
|
-
:begin == self.children[2].type ? self.children[2].children : [self.children[2]]
|
81
|
-
else
|
82
|
-
raise Synvert::MethodNotSupported.new "body is not handled for #{self.inspect}"
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
# Get condition node of :if node.
|
87
|
-
#
|
88
|
-
# @return [Parser::AST::Node] condition node.
|
89
|
-
# @raise [Synvert::MethodNotSupported] if calls on other node.
|
90
|
-
def condition
|
91
|
-
if :if == self.type
|
92
|
-
self.children[0]
|
93
|
-
else
|
94
|
-
raise Synvert::MethodNotSupported.new "condition is not handled for #{self.inspect}"
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
# Get keys node of :hash node.
|
99
|
-
#
|
100
|
-
# @return [Array<Parser::AST::Node>] keys node.
|
101
|
-
# @raise [Synvert::MethodNotSupported] if calls on other node.
|
102
|
-
def keys
|
103
|
-
if :hash == self.type
|
104
|
-
self.children.map { |child| child.children[0] }
|
105
|
-
else
|
106
|
-
raise Synvert::MethodNotSupported.new "keys is not handled for #{self.inspect}"
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
# Get values node of :hash node.
|
111
|
-
#
|
112
|
-
# @return [Array<Parser::AST::Node>] values node.
|
113
|
-
# @raise [Synvert::MethodNotSupported] if calls on other node.
|
114
|
-
def values
|
115
|
-
if :hash == self.type
|
116
|
-
self.children.map { |child| child.children[1] }
|
117
|
-
else
|
118
|
-
raise Synvert::MethodNotSupported.new "keys is not handled for #{self.inspect}"
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
# Get key node of hash :pair node.
|
123
|
-
#
|
124
|
-
# @return [Parser::AST::Node] key node.
|
125
|
-
# @raise [Synvert::MethodNotSupported] if calls on other node.
|
126
|
-
def key
|
127
|
-
if :pair == self.type
|
128
|
-
self.children.first
|
129
|
-
else
|
130
|
-
raise Synvert::MethodNotSupported.new "key is not handled for #{self.inspect}"
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
# Get value node of hash :pair node.
|
135
|
-
#
|
136
|
-
# @return [Parser::AST::Node] value node.
|
137
|
-
# @raise [Synvert::MethodNotSupported] if calls on other node.
|
138
|
-
def value
|
139
|
-
if :pair == self.type
|
140
|
-
self.children.last
|
141
|
-
else
|
142
|
-
raise Synvert::MethodNotSupported.new "value is not handled for #{self.inspect}"
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
# Get the source code of current node.
|
147
|
-
#
|
148
|
-
# @param instance [Synvert::Rewriter::Instance]
|
149
|
-
# @return [String] source code.
|
150
|
-
def source(instance)
|
151
|
-
if self.loc.expression
|
152
|
-
instance.current_source[self.loc.expression.begin_pos...self.loc.expression.end_pos]
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
# Get the indent of current node.
|
157
|
-
#
|
158
|
-
# @return [Integer] indent.
|
159
|
-
def indent
|
160
|
-
self.loc.expression.column
|
161
|
-
end
|
162
|
-
|
163
|
-
# Recursively iterate all child nodes of current node.
|
164
|
-
#
|
165
|
-
# @yield [child] Gives a child node.
|
166
|
-
# @yieldparam child [Parser::AST::Node] child node
|
167
|
-
def recursive_children
|
168
|
-
self.children.each do |child|
|
169
|
-
if Parser::AST::Node === child
|
170
|
-
yield child
|
171
|
-
child.recursive_children { |c| yield c }
|
172
|
-
end
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
# Match current node with rules.
|
177
|
-
#
|
178
|
-
# @param instance [Synvert::Rewriter::Instance] used to get crrent source code.
|
179
|
-
# @param rules [Hash] rules to match.
|
180
|
-
# @return true if matches.
|
181
|
-
def match?(instance, rules)
|
182
|
-
flat_hash(rules).keys.all? do |multi_keys|
|
183
|
-
if multi_keys.last == :any
|
184
|
-
actual_values = actual_value(self, instance, multi_keys[0...-1])
|
185
|
-
expected = expected_value(rules, multi_keys)
|
186
|
-
actual_values.any? { |actual| match_value?(instance, actual, expected) }
|
187
|
-
elsif multi_keys.last == :not
|
188
|
-
actual = actual_value(self, instance, multi_keys[0...-1])
|
189
|
-
expected = expected_value(rules, multi_keys)
|
190
|
-
!match_value?(instance, actual, expected)
|
191
|
-
else
|
192
|
-
actual = actual_value(self, instance, multi_keys)
|
193
|
-
expected = expected_value(rules, multi_keys)
|
194
|
-
match_value?(instance, actual, expected)
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
# Get rewritten source code.
|
200
|
-
# @example
|
201
|
-
# node.rewritten_source("create({{arguments}})") #=> "create(:post)"
|
202
|
-
#
|
203
|
-
# @param code [String] raw code.
|
204
|
-
# @return [String] rewritten code, replace string in block {{ }} in raw code.
|
205
|
-
# @raise [Synvert::MethodNotSupported] if string in block {{ }} does not support.
|
206
|
-
def rewritten_source(code)
|
207
|
-
code.gsub(/{{(.*?)}}/m) do
|
208
|
-
evaluated = self.instance_eval $1
|
209
|
-
case evaluated
|
210
|
-
when Parser::AST::Node
|
211
|
-
source = evaluated.loc.expression.source_buffer.source
|
212
|
-
source[evaluated.loc.expression.begin_pos...evaluated.loc.expression.end_pos]
|
213
|
-
when Array
|
214
|
-
if evaluated.size > 0
|
215
|
-
source = evaluated.first.loc.expression.source_buffer.source
|
216
|
-
source[evaluated.first.loc.expression.begin_pos...evaluated.last.loc.expression.end_pos]
|
217
|
-
end
|
218
|
-
when String
|
219
|
-
evaluated
|
220
|
-
when NilClass
|
221
|
-
'nil'
|
222
|
-
else
|
223
|
-
raise Synvert::MethodNotSupported.new "rewritten_source is not handled for #{evaluated.inspect}"
|
224
|
-
end
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
private
|
229
|
-
|
230
|
-
# Compare actual value with expected value.
|
231
|
-
#
|
232
|
-
# @param instance [Synvert::Rewriter::Instance] used to get source code.
|
233
|
-
# @param actual [Object] actual value.
|
234
|
-
# @param expected [Object] expected value.
|
235
|
-
# @return [Integer] -1, 0 or 1.
|
236
|
-
# @raise [Synvert::MethodNotSupported] if expected class is not supported.
|
237
|
-
def match_value?(instance, actual, expected)
|
238
|
-
case expected
|
239
|
-
when Symbol
|
240
|
-
if Parser::AST::Node === actual
|
241
|
-
actual.source(instance) == ":#{expected}"
|
242
|
-
else
|
243
|
-
actual.to_sym == expected
|
244
|
-
end
|
245
|
-
when String
|
246
|
-
if Parser::AST::Node === actual
|
247
|
-
actual.source(instance) == expected || actual.source(instance)[1...-1] == expected
|
248
|
-
else
|
249
|
-
actual.to_s == expected
|
250
|
-
end
|
251
|
-
when Regexp
|
252
|
-
if Parser::AST::Node === actual
|
253
|
-
actual.source(instance) =~ Regexp.new(expected.to_s, Regexp::MULTILINE)
|
254
|
-
else
|
255
|
-
actual.to_s =~ Regexp.new(expected.to_s, Regexp::MULTILINE)
|
256
|
-
end
|
257
|
-
when Array
|
258
|
-
actual.zip(expected).all? { |a, e| match_value?(instance, a, e) }
|
259
|
-
when NilClass
|
260
|
-
actual.nil?
|
261
|
-
when Numeric
|
262
|
-
if Parser::AST::Node === actual
|
263
|
-
actual.children[0] == expected
|
264
|
-
else
|
265
|
-
actual == expected
|
266
|
-
end
|
267
|
-
when TrueClass
|
268
|
-
:true == actual.type
|
269
|
-
when FalseClass
|
270
|
-
:false == actual.type
|
271
|
-
when Parser::AST::Node
|
272
|
-
actual == expected
|
273
|
-
else
|
274
|
-
raise Synvert::MethodNotSupported.new "#{expected.class} is not handled for match_value?"
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
|
-
# Convert a hash to flat one.
|
279
|
-
#
|
280
|
-
# @example
|
281
|
-
# flat_hash(type: 'block', caller: {type: 'send', receiver: 'RSpec'})
|
282
|
-
# #=> {[:type] => 'block', [:caller, :type] => 'send', [:caller, :receiver] => 'RSpec'}
|
283
|
-
# @param h [Hash] original hash.
|
284
|
-
# @return flatten hash.
|
285
|
-
def flat_hash(h, k = [])
|
286
|
-
new_hash = {}
|
287
|
-
h.each_pair do |key, val|
|
288
|
-
if val.is_a?(Hash)
|
289
|
-
new_hash.merge!(flat_hash(val, k + [key]))
|
290
|
-
else
|
291
|
-
new_hash[k + [key]] = val
|
292
|
-
end
|
293
|
-
end
|
294
|
-
new_hash
|
295
|
-
end
|
296
|
-
|
297
|
-
# Get actual value from the node.
|
298
|
-
#
|
299
|
-
# @param node [Parser::AST::Node]
|
300
|
-
# @param instance [Synvert::Rewriter::Instance]
|
301
|
-
# @param multi_keys [Array<Symbol>]
|
302
|
-
# @return [Object] actual value.
|
303
|
-
def actual_value(node, instance, multi_keys)
|
304
|
-
multi_keys.inject(node) { |n, key|
|
305
|
-
if n
|
306
|
-
key == :source ? n.send(key, instance) : n.send(key)
|
307
|
-
end
|
308
|
-
}
|
309
|
-
end
|
310
|
-
|
311
|
-
# Get expected value from rules.
|
312
|
-
#
|
313
|
-
# @param rules [Hash]
|
314
|
-
# @param multi_keys [Array<Symbol>]
|
315
|
-
# @return [Object] expected value.
|
316
|
-
def expected_value(rules, multi_keys)
|
317
|
-
multi_keys.inject(rules) { |o, key| o[key] }
|
318
|
-
end
|
319
|
-
end
|
@@ -1,224 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Synvert
|
4
|
-
# Action defines rewriter action, add, replace or remove code.
|
5
|
-
class Rewriter::Action
|
6
|
-
# Initialize an action.
|
7
|
-
#
|
8
|
-
# @param instance [Synvert::Rewriter::Instance]
|
9
|
-
# @param code {String] new code to add, replace or remove.
|
10
|
-
def initialize(instance, code)
|
11
|
-
@instance = instance
|
12
|
-
@code = code
|
13
|
-
@node = @instance.current_node
|
14
|
-
end
|
15
|
-
|
16
|
-
# Line number of the node.
|
17
|
-
#
|
18
|
-
# @return [Integer] line number.
|
19
|
-
def line
|
20
|
-
@node.loc.expression.line
|
21
|
-
end
|
22
|
-
|
23
|
-
# The rewritten source code with proper indent.
|
24
|
-
#
|
25
|
-
# @return [String] rewritten code.
|
26
|
-
def rewritten_code
|
27
|
-
if rewritten_source.split("\n").length > 1
|
28
|
-
"\n\n" + rewritten_source.split("\n").map { |line|
|
29
|
-
indent(@node) + line
|
30
|
-
}.join("\n")
|
31
|
-
else
|
32
|
-
"\n" + indent(@node) + rewritten_source
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# The rewritten source code.
|
37
|
-
#
|
38
|
-
# @return [String] rewritten source code.
|
39
|
-
def rewritten_source
|
40
|
-
@rewritten_source ||= @node.rewritten_source(@code)
|
41
|
-
end
|
42
|
-
|
43
|
-
# Compare actions by begin position.
|
44
|
-
#
|
45
|
-
# @param action [Synvert::Rewriter::Action]
|
46
|
-
# @return [Integer] -1, 0 or 1
|
47
|
-
def <=>(action)
|
48
|
-
self.begin_pos <=> action.begin_pos
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# ReplaceWithAction to replace code.
|
53
|
-
class Rewriter::ReplaceWithAction < Rewriter::Action
|
54
|
-
# Begin position of code to replace.
|
55
|
-
#
|
56
|
-
# @return [Integer] begin position.
|
57
|
-
def begin_pos
|
58
|
-
@node.loc.expression.begin_pos
|
59
|
-
end
|
60
|
-
|
61
|
-
# End position of code to replace.
|
62
|
-
#
|
63
|
-
# @return [Integer] end position.
|
64
|
-
def end_pos
|
65
|
-
@node.loc.expression.end_pos
|
66
|
-
end
|
67
|
-
|
68
|
-
# The rewritten source code with proper indent.
|
69
|
-
#
|
70
|
-
# @return [String] rewritten code.
|
71
|
-
def rewritten_code
|
72
|
-
if rewritten_source.split("\n").length > 1
|
73
|
-
"\n\n" + rewritten_source.split("\n").map { |line|
|
74
|
-
indent(@node) + line
|
75
|
-
}.join("\n")
|
76
|
-
else
|
77
|
-
rewritten_source
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
private
|
82
|
-
|
83
|
-
# Indent of the node
|
84
|
-
#
|
85
|
-
# @param node [Parser::AST::Node]
|
86
|
-
# @return [String] n times whitesphace
|
87
|
-
def indent(node)
|
88
|
-
' ' * node.indent
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
# AppendWithAction to append code to the bottom of node body.
|
93
|
-
class Rewriter::AppendAction < Rewriter::Action
|
94
|
-
# Begin position to append code.
|
95
|
-
#
|
96
|
-
# @return [Integer] begin position.
|
97
|
-
def begin_pos
|
98
|
-
if :begin == @node.type
|
99
|
-
@node.loc.expression.end_pos
|
100
|
-
else
|
101
|
-
@node.loc.expression.end_pos - 4
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
# End position, always same to begin position.
|
106
|
-
#
|
107
|
-
# @return [Integer] end position.
|
108
|
-
def end_pos
|
109
|
-
begin_pos
|
110
|
-
end
|
111
|
-
|
112
|
-
private
|
113
|
-
|
114
|
-
# Indent of the node.
|
115
|
-
#
|
116
|
-
# @param node [Parser::AST::Node]
|
117
|
-
# @return [String] n times whitesphace
|
118
|
-
def indent(node)
|
119
|
-
if [:block, :class].include? node.type
|
120
|
-
' ' * (node.indent + 2)
|
121
|
-
else
|
122
|
-
' ' * node.indent
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
# InsertAction to insert code to the top of node body.
|
128
|
-
class Rewriter::InsertAction < Rewriter::Action
|
129
|
-
# Begin position to insert code.
|
130
|
-
#
|
131
|
-
# @return [Integer] begin position.
|
132
|
-
def begin_pos
|
133
|
-
insert_position(@node)
|
134
|
-
end
|
135
|
-
|
136
|
-
# End position, always same to begin position.
|
137
|
-
#
|
138
|
-
# @return [Integer] end position.
|
139
|
-
def end_pos
|
140
|
-
begin_pos
|
141
|
-
end
|
142
|
-
|
143
|
-
private
|
144
|
-
|
145
|
-
# Insert position.
|
146
|
-
#
|
147
|
-
# @return [Integer] insert position.
|
148
|
-
def insert_position(node)
|
149
|
-
case node.type
|
150
|
-
when :block
|
151
|
-
node.children[1].children.empty? ? node.children[0].loc.expression.end_pos + 3 : node.children[1].loc.expression.end_pos
|
152
|
-
when :class
|
153
|
-
node.children[1] ? node.children[1].loc.expression.end_pos : node.children[0].loc.expression.end_pos
|
154
|
-
else
|
155
|
-
node.children.last.loc.expression.end_pos
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
# Indent of the node.
|
160
|
-
#
|
161
|
-
# @param node [Parser::AST::Node]
|
162
|
-
# @return [String] n times whitesphace
|
163
|
-
def indent(node)
|
164
|
-
if [:block, :class].include? node.type
|
165
|
-
' ' * (node.indent + 2)
|
166
|
-
else
|
167
|
-
' ' * node.indent
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
# InsertAfterAction to insert code next to the node.
|
173
|
-
class Rewriter::InsertAfterAction < Rewriter::Action
|
174
|
-
# Begin position to insert code.
|
175
|
-
#
|
176
|
-
# @return [Integer] begin position.
|
177
|
-
def begin_pos
|
178
|
-
@node.loc.expression.end_pos
|
179
|
-
end
|
180
|
-
|
181
|
-
# End position, always same to begin position.
|
182
|
-
#
|
183
|
-
# @return [Integer] end position.
|
184
|
-
def end_pos
|
185
|
-
begin_pos
|
186
|
-
end
|
187
|
-
|
188
|
-
private
|
189
|
-
|
190
|
-
# Indent of the node.
|
191
|
-
#
|
192
|
-
# @param node [Parser::AST::Node]
|
193
|
-
# @return [String] n times whitesphace
|
194
|
-
def indent(node)
|
195
|
-
' ' * node.indent
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
# RemoveAction to remove code.
|
200
|
-
class Rewriter::RemoveAction < Rewriter::Action
|
201
|
-
def initialize(instance, code=nil)
|
202
|
-
super
|
203
|
-
end
|
204
|
-
|
205
|
-
# Begin position of code to replace.
|
206
|
-
#
|
207
|
-
# @return [Integer] begin position.
|
208
|
-
def begin_pos
|
209
|
-
@node.loc.expression.begin_pos
|
210
|
-
end
|
211
|
-
|
212
|
-
# End position of code to replace.
|
213
|
-
#
|
214
|
-
# @return [Integer] end position.
|
215
|
-
def end_pos
|
216
|
-
@node.loc.expression.end_pos
|
217
|
-
end
|
218
|
-
|
219
|
-
# The rewritten code, always empty string.
|
220
|
-
def rewritten_code
|
221
|
-
''
|
222
|
-
end
|
223
|
-
end
|
224
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Synvert
|
4
|
-
# Condition checks if rules matches.
|
5
|
-
class Rewriter::Condition
|
6
|
-
# Initialize a condition.
|
7
|
-
#
|
8
|
-
# @param instance [Synvert::Rewriter::Instance]
|
9
|
-
# @param rules [Hash]
|
10
|
-
# @param block [Block]
|
11
|
-
# @return [Synvert::Rewriter::Condition]
|
12
|
-
def initialize(instance, rules, &block)
|
13
|
-
@instance = instance
|
14
|
-
@rules = rules
|
15
|
-
@block = block
|
16
|
-
end
|
17
|
-
|
18
|
-
# If condition matches, run the block code.
|
19
|
-
def process
|
20
|
-
@instance.instance_eval &@block if match?
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# IfExistCondition checks if matching node exists in the node children.
|
25
|
-
class Rewriter::IfExistCondition < Rewriter::Condition
|
26
|
-
# check if any child node matches the rules.
|
27
|
-
def match?
|
28
|
-
match = false
|
29
|
-
@instance.current_node.recursive_children do |child_node|
|
30
|
-
match = match || (child_node && child_node.match?(@instance, @rules))
|
31
|
-
end
|
32
|
-
match
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# UnlessExistCondition checks if matching node doesn't exist in the node children.
|
37
|
-
class Rewriter::UnlessExistCondition < Rewriter::Condition
|
38
|
-
# check if none of child node matches the rules.
|
39
|
-
def match?
|
40
|
-
match = false
|
41
|
-
@instance.current_node.recursive_children do |child_node|
|
42
|
-
match = match || (child_node && child_node.match?(@instance, @rules))
|
43
|
-
end
|
44
|
-
!match
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
# IfExistCondition checks if node has only one child node and the child node matches rules.
|
49
|
-
class Rewriter::IfOnlyExistCondition < Rewriter::Condition
|
50
|
-
# check if only have one child node and the child node matches rules.
|
51
|
-
def match?
|
52
|
-
@instance.current_node.body.size == 1 &&
|
53
|
-
@instance.current_node.body.first.match?(@instance, @rules)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Synvert
|
4
|
-
# GemSpec checks and compares gem version.
|
5
|
-
class Rewriter::GemSpec
|
6
|
-
OPERATORS = {eq: '==', lt: '<', gt: '>', lte: '<=', gte: '>=', ne: '!='}
|
7
|
-
|
8
|
-
# Initialize a gem_spec.
|
9
|
-
#
|
10
|
-
# @param name [String] gem name
|
11
|
-
# @param comparator [Hash] comparator to gem version, e.g. {eg: '2.0.0'},
|
12
|
-
# comparator key can be eq, lt, gt, lte, gte or ne.
|
13
|
-
def initialize(name, comparator)
|
14
|
-
@name = name
|
15
|
-
if Hash === comparator
|
16
|
-
@operator = comparator.keys.first
|
17
|
-
@version = Gem::Version.new comparator.values.first
|
18
|
-
else
|
19
|
-
@operator = :eq
|
20
|
-
@version = Gem::Version.new comparator
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# Check if the specified gem version in Gemfile.lock matches gem_spec comparator.
|
25
|
-
#
|
26
|
-
# @return [Boolean] true if matches, otherwise false.
|
27
|
-
# @raise [Synvert::GemfileLockNotFound] raise if Gemfile.lock does not exist.
|
28
|
-
def match?
|
29
|
-
gemfile_lock_path = File.join(Configuration.instance.get(:path), 'Gemfile.lock')
|
30
|
-
if File.exists? gemfile_lock_path
|
31
|
-
parser = Bundler::LockfileParser.new(File.read(gemfile_lock_path))
|
32
|
-
if spec = parser.specs.find { |spec| spec.name == @name }
|
33
|
-
Gem::Version.new(spec.version).send(OPERATORS[@operator], @version)
|
34
|
-
else
|
35
|
-
false
|
36
|
-
end
|
37
|
-
else
|
38
|
-
raise GemfileLockNotFound.new 'Gemfile.lock does not exist'
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|