synvert 0.0.17 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|