synvert-core 0.7.5 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -16
  3. data/lib/synvert/core/rewriter/action/append_action.rb +38 -0
  4. data/lib/synvert/core/rewriter/action/insert_action.rb +48 -0
  5. data/lib/synvert/core/rewriter/action/insert_after_action.rb +30 -0
  6. data/lib/synvert/core/rewriter/action/remove_action.rb +29 -0
  7. data/lib/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action.rb +40 -0
  8. data/lib/synvert/core/rewriter/action/replace_with_action.rb +45 -0
  9. data/lib/synvert/core/rewriter/action.rb +1 -212
  10. data/lib/synvert/core/rewriter/condition/if_exist_condition.rb +15 -0
  11. data/lib/synvert/core/rewriter/condition/if_only_exist_condition.rb +12 -0
  12. data/lib/synvert/core/rewriter/condition/unless_exist_condition.rb +15 -0
  13. data/lib/synvert/core/rewriter/condition.rb +0 -33
  14. data/lib/synvert/core/rewriter/instance.rb +3 -0
  15. data/lib/synvert/core/rewriter/scope/goto_scope.rb +27 -0
  16. data/lib/synvert/core/rewriter/scope/within_scope.rb +36 -0
  17. data/lib/synvert/core/rewriter/scope.rb +0 -57
  18. data/lib/synvert/core/rewriter.rb +11 -11
  19. data/lib/synvert/core/version.rb +1 -1
  20. data/spec/synvert/core/rewriter/action/append_action_spec.rb +47 -0
  21. data/spec/synvert/core/rewriter/action/insert_action_spec.rb +89 -0
  22. data/spec/synvert/core/rewriter/action/insert_after_action_spec.rb +24 -0
  23. data/spec/synvert/core/rewriter/action/remove_action_spec.rb +24 -0
  24. data/spec/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action_spec.rb +6 -0
  25. data/spec/synvert/core/rewriter/action/replace_with_action_spec.rb +53 -0
  26. data/spec/synvert/core/rewriter/action_spec.rb +0 -222
  27. data/spec/synvert/core/rewriter/condition/if_exist_condition_spec.rb +36 -0
  28. data/spec/synvert/core/rewriter/condition/if_only_exist_condition_spec.rb +43 -0
  29. data/spec/synvert/core/rewriter/condition/unless_exist_condition_spec.rb +36 -0
  30. data/spec/synvert/core/rewriter/condition_spec.rb +0 -83
  31. data/spec/synvert/core/rewriter/scope/goto_scope_spec.rb +34 -0
  32. data/spec/synvert/core/rewriter/scope/within_scope.rb +46 -0
  33. data/spec/synvert/core/rewriter/scope_spec.rb +1 -72
  34. metadata +35 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 147d5855d29224ef920cd0249c021c0825f52ae7
4
- data.tar.gz: 151c8fcd306d95ac3e401f6b5e7c266dde352bd5
3
+ metadata.gz: 7574aaacdd63c1c6cd7f6372491e69aa62b916dc
4
+ data.tar.gz: ff1c06c93de47e0a6a06d58cdf7f1d6856f05eb3
5
5
  SHA512:
6
- metadata.gz: efd95157a71e181ad15658aa06c3ddb41d85a80801ecb118cd4d74877db98bdfaf9a6ff66d9838deca432cdcbd3cc122c572c6998120053a3711db6ac6ea02b2
7
- data.tar.gz: 4d7105931e33abe42f7d6722e9948251151155db3ee401ecb6f187228c67226b0662f831dc45b3de0050a4bf280400781c20c1b6d3b43251889e28635030b8d1
6
+ metadata.gz: a36cf26c775659fecf1c73899d95b2b16a199a6675f8604df9514370afed213efec5c8425d6d4420265fce46f8df7575c7acdb83009464f5b3cbfe72f39b8662
7
+ data.tar.gz: 92e7917386a8497847d87f32ba68f0fecd3470cd007b1457dda3c51bb01b4a341a42990698cd18e0d64535bc277b4eec92239ffd12dd25314e9e1c4a62f1b95d
data/CHANGELOG.md CHANGED
@@ -1,26 +1,14 @@
1
1
  # CHANGELOG
2
2
 
3
- ## 0.7.5
4
-
5
- * Fix left_value and right_value node attribute
6
-
7
- ## 0.7.4
3
+ ## 0.8.0 (2014-10-26)
8
4
 
5
+ * Add line method to ast node
9
6
  * Add add_arguments_with_parenthesis_if_necessary helper method
10
-
11
- ## 0.7.3
12
-
7
+ * Fix left_value and right_value node attribute
8
+ * Print warn when file was not parsed correctly
13
9
  * Handle indent for node array source
14
- * Add line method to ast node
15
-
16
- ## 0.7.2
17
-
18
10
  * Rescue NoMethodError and output node debug info
19
11
 
20
- ## 0.7.1
21
-
22
- * Hotfix a typo
23
-
24
12
  ## 0.7.0 (2014-09-29)
25
13
 
26
14
  * Add debug info for MethodNotSupported error.
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+
3
+ module Synvert::Core
4
+ # AppendWithAction to append code to the bottom of node body.
5
+ class Rewriter::AppendAction < Rewriter::Action
6
+ # Begin position to append code.
7
+ #
8
+ # @return [Integer] begin position.
9
+ def begin_pos
10
+ if :begin == @node.type
11
+ @node.loc.expression.end_pos
12
+ else
13
+ @node.loc.expression.end_pos - @node.indent - 4
14
+ end
15
+ end
16
+
17
+ # End position, always same to begin position.
18
+ #
19
+ # @return [Integer] end position.
20
+ def end_pos
21
+ begin_pos
22
+ end
23
+
24
+ private
25
+
26
+ # Indent of the node.
27
+ #
28
+ # @param node [Parser::AST::Node]
29
+ # @return [String] n times whitesphace
30
+ def indent(node)
31
+ if [:block, :class].include? node.type
32
+ ' ' * (node.indent + 2)
33
+ else
34
+ ' ' * node.indent
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+
3
+ module Synvert::Core
4
+ # InsertAction to insert code to the top of node body.
5
+ class Rewriter::InsertAction < Rewriter::Action
6
+ # Begin position to insert code.
7
+ #
8
+ # @return [Integer] begin position.
9
+ def begin_pos
10
+ insert_position(@node)
11
+ end
12
+
13
+ # End position, always same to begin position.
14
+ #
15
+ # @return [Integer] end position.
16
+ def end_pos
17
+ begin_pos
18
+ end
19
+
20
+ private
21
+
22
+ # Insert position.
23
+ #
24
+ # @return [Integer] insert position.
25
+ def insert_position(node)
26
+ case node.type
27
+ when :block
28
+ node.children[1].children.empty? ? node.children[0].loc.expression.end_pos + 3 : node.children[1].loc.expression.end_pos
29
+ when :class
30
+ node.children[1] ? node.children[1].loc.expression.end_pos : node.children[0].loc.expression.end_pos
31
+ else
32
+ node.children.last.loc.expression.end_pos
33
+ end
34
+ end
35
+
36
+ # Indent of the node.
37
+ #
38
+ # @param node [Parser::AST::Node]
39
+ # @return [String] n times whitesphace
40
+ def indent(node)
41
+ if [:block, :class].include? node.type
42
+ ' ' * (node.indent + 2)
43
+ else
44
+ ' ' * node.indent
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+ module Synvert::Core
4
+ # InsertAfterAction to insert code next to the node.
5
+ class Rewriter::InsertAfterAction < Rewriter::Action
6
+ # Begin position to insert code.
7
+ #
8
+ # @return [Integer] begin position.
9
+ def begin_pos
10
+ @node.loc.expression.end_pos
11
+ end
12
+
13
+ # End position, always same to begin position.
14
+ #
15
+ # @return [Integer] end position.
16
+ def end_pos
17
+ begin_pos
18
+ end
19
+
20
+ private
21
+
22
+ # Indent of the node.
23
+ #
24
+ # @param node [Parser::AST::Node]
25
+ # @return [String] n times whitesphace
26
+ def indent(node)
27
+ ' ' * node.indent
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ module Synvert::Core
4
+ # RemoveAction to remove code.
5
+ class Rewriter::RemoveAction < Rewriter::Action
6
+ def initialize(instance, code=nil)
7
+ super
8
+ end
9
+
10
+ # Begin position of code to replace.
11
+ #
12
+ # @return [Integer] begin position.
13
+ def begin_pos
14
+ @node.loc.expression.begin_pos
15
+ end
16
+
17
+ # End position of code to replace.
18
+ #
19
+ # @return [Integer] end position.
20
+ def end_pos
21
+ @node.loc.expression.end_pos
22
+ end
23
+
24
+ # The rewritten code, always empty string.
25
+ def rewritten_code
26
+ ''
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+ module Synvert::Core
4
+ # ReplaceErbStmtWithExprAction to replace erb stmt code to expr,
5
+ # e.g. <% form_for ... %> => <%= form_for ... %>.
6
+ class Rewriter::ReplaceErbStmtWithExprAction < Rewriter::Action
7
+ def initialize(instance, code=nil)
8
+ super
9
+ end
10
+
11
+ # Begin position of code to replace.
12
+ #
13
+ # @return [Integer] begin position.
14
+ def begin_pos
15
+ node_begin_pos = @node.loc.expression.begin_pos
16
+ while @node.loc.expression.source_buffer.source[node_begin_pos -= 1] == ' '
17
+ end
18
+ node_begin_pos - Engine::ERUBY_STMT_SPLITTER.length + 1
19
+ end
20
+
21
+ # End position of code to replace.
22
+ #
23
+ # @return [Integer] end position.
24
+ def end_pos
25
+ node_begin_pos = @node.loc.expression.begin_pos
26
+ node_begin_pos += @node.loc.expression.source.index "do"
27
+ while @node.loc.expression.source_buffer.source[node_begin_pos += 1] != '@'
28
+ end
29
+ node_begin_pos
30
+ end
31
+
32
+ # The rewritten erb expr code.
33
+ #
34
+ # @return [String] rewritten code.
35
+ def rewritten_code
36
+ @node.loc.expression.source_buffer.source[begin_pos...end_pos].sub(Engine::ERUBY_STMT_SPLITTER, "@output_buffer.append= ")
37
+ .sub(Engine::ERUBY_STMT_SPLITTER, Engine::ERUBY_EXPR_SPLITTER)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ module Synvert::Core
4
+ # ReplaceWithAction to replace code.
5
+ class Rewriter::ReplaceWithAction < Rewriter::Action
6
+ # Begin position of code to replace.
7
+ #
8
+ # @return [Integer] begin position.
9
+ def begin_pos
10
+ @node.loc.expression.begin_pos
11
+ end
12
+
13
+ # End position of code to replace.
14
+ #
15
+ # @return [Integer] end position.
16
+ def end_pos
17
+ @node.loc.expression.end_pos
18
+ end
19
+
20
+ # The rewritten source code with proper indent.
21
+ #
22
+ # @return [String] rewritten code.
23
+ def rewritten_code
24
+ if rewritten_source.split("\n").length > 1
25
+ new_code = []
26
+ rewritten_source.split("\n").each_with_index { |line, index|
27
+ new_code << (index == 0 ? line : indent(@node) + line)
28
+ }
29
+ new_code.join("\n")
30
+ else
31
+ rewritten_source
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ # Indent of the node
38
+ #
39
+ # @param node [Parser::AST::Node]
40
+ # @return [String] n times whitesphace
41
+ def indent(node)
42
+ ' ' * node.indent
43
+ end
44
+ end
45
+ end
@@ -48,216 +48,5 @@ module Synvert::Core
48
48
  self.begin_pos <=> action.begin_pos
49
49
  end
50
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
- new_code = []
74
- rewritten_source.split("\n").each_with_index { |line, index|
75
- new_code << (index == 0 ? line : indent(@node) + line)
76
- }
77
- new_code.join("\n")
78
- else
79
- rewritten_source
80
- end
81
- end
82
-
83
- private
84
-
85
- # Indent of the node
86
- #
87
- # @param node [Parser::AST::Node]
88
- # @return [String] n times whitesphace
89
- def indent(node)
90
- ' ' * node.indent
91
- end
92
- end
93
-
94
- # AppendWithAction to append code to the bottom of node body.
95
- class Rewriter::AppendAction < Rewriter::Action
96
- # Begin position to append code.
97
- #
98
- # @return [Integer] begin position.
99
- def begin_pos
100
- if :begin == @node.type
101
- @node.loc.expression.end_pos
102
- else
103
- @node.loc.expression.end_pos - @node.indent - 4
104
- end
105
- end
106
-
107
- # End position, always same to begin position.
108
- #
109
- # @return [Integer] end position.
110
- def end_pos
111
- begin_pos
112
- end
113
-
114
- private
115
-
116
- # Indent of the node.
117
- #
118
- # @param node [Parser::AST::Node]
119
- # @return [String] n times whitesphace
120
- def indent(node)
121
- if [:block, :class].include? node.type
122
- ' ' * (node.indent + 2)
123
- else
124
- ' ' * node.indent
125
- end
126
- end
127
- end
128
-
129
- # InsertAction to insert code to the top of node body.
130
- class Rewriter::InsertAction < Rewriter::Action
131
- # Begin position to insert code.
132
- #
133
- # @return [Integer] begin position.
134
- def begin_pos
135
- insert_position(@node)
136
- end
137
-
138
- # End position, always same to begin position.
139
- #
140
- # @return [Integer] end position.
141
- def end_pos
142
- begin_pos
143
- end
144
-
145
- private
146
-
147
- # Insert position.
148
- #
149
- # @return [Integer] insert position.
150
- def insert_position(node)
151
- case node.type
152
- when :block
153
- node.children[1].children.empty? ? node.children[0].loc.expression.end_pos + 3 : node.children[1].loc.expression.end_pos
154
- when :class
155
- node.children[1] ? node.children[1].loc.expression.end_pos : node.children[0].loc.expression.end_pos
156
- else
157
- node.children.last.loc.expression.end_pos
158
- end
159
- end
160
-
161
- # Indent of the node.
162
- #
163
- # @param node [Parser::AST::Node]
164
- # @return [String] n times whitesphace
165
- def indent(node)
166
- if [:block, :class].include? node.type
167
- ' ' * (node.indent + 2)
168
- else
169
- ' ' * node.indent
170
- end
171
- end
172
- end
173
-
174
- # InsertAfterAction to insert code next to the node.
175
- class Rewriter::InsertAfterAction < Rewriter::Action
176
- # Begin position to insert code.
177
- #
178
- # @return [Integer] begin position.
179
- def begin_pos
180
- @node.loc.expression.end_pos
181
- end
182
-
183
- # End position, always same to begin position.
184
- #
185
- # @return [Integer] end position.
186
- def end_pos
187
- begin_pos
188
- end
189
-
190
- private
191
-
192
- # Indent of the node.
193
- #
194
- # @param node [Parser::AST::Node]
195
- # @return [String] n times whitesphace
196
- def indent(node)
197
- ' ' * node.indent
198
- end
199
- end
200
-
201
- # RemoveAction to remove code.
202
- class Rewriter::RemoveAction < Rewriter::Action
203
- def initialize(instance, code=nil)
204
- super
205
- end
206
-
207
- # Begin position of code to replace.
208
- #
209
- # @return [Integer] begin position.
210
- def begin_pos
211
- @node.loc.expression.begin_pos
212
- end
213
-
214
- # End position of code to replace.
215
- #
216
- # @return [Integer] end position.
217
- def end_pos
218
- @node.loc.expression.end_pos
219
- end
220
-
221
- # The rewritten code, always empty string.
222
- def rewritten_code
223
- ''
224
- end
225
- end
226
-
227
- # ReplaceErbStmtWithExprAction to replace erb stmt code to expr,
228
- # e.g. <% form_for ... %> => <%= form_for ... %>.
229
- class Rewriter::ReplaceErbStmtWithExprAction < Rewriter::Action
230
- def initialize(instance, code=nil)
231
- super
232
- end
233
-
234
- # Begin position of code to replace.
235
- #
236
- # @return [Integer] begin position.
237
- def begin_pos
238
- node_begin_pos = @node.loc.expression.begin_pos
239
- while @node.loc.expression.source_buffer.source[node_begin_pos -= 1] == ' '
240
- end
241
- node_begin_pos - Engine::ERUBY_STMT_SPLITTER.length + 1
242
- end
243
-
244
- # End position of code to replace.
245
- #
246
- # @return [Integer] end position.
247
- def end_pos
248
- node_begin_pos = @node.loc.expression.begin_pos
249
- node_begin_pos += @node.loc.expression.source.index "do"
250
- while @node.loc.expression.source_buffer.source[node_begin_pos += 1] != '@'
251
- end
252
- node_begin_pos
253
- end
254
-
255
- # The rewritten erb expr code.
256
- #
257
- # @return [String] rewritten code.
258
- def rewritten_code
259
- @node.loc.expression.source_buffer.source[begin_pos...end_pos].sub(Engine::ERUBY_STMT_SPLITTER, "@output_buffer.append= ")
260
- .sub(Engine::ERUBY_STMT_SPLITTER, Engine::ERUBY_EXPR_SPLITTER)
261
- end
262
- end
263
51
  end
52
+
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ module Synvert::Core
4
+ # IfExistCondition checks if matching node exists in the node children.
5
+ class Rewriter::IfExistCondition < Rewriter::Condition
6
+ # check if any child node matches the rules.
7
+ def match?
8
+ match = false
9
+ @instance.current_node.recursive_children do |child_node|
10
+ match = match || (child_node && child_node.match?(@rules))
11
+ end
12
+ match
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ module Synvert::Core
4
+ # IfExistCondition checks if node has only one child node and the child node matches rules.
5
+ class Rewriter::IfOnlyExistCondition < Rewriter::Condition
6
+ # check if only have one child node and the child node matches rules.
7
+ def match?
8
+ @instance.current_node.body.size == 1 &&
9
+ @instance.current_node.body.first.match?(@rules)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ module Synvert::Core
4
+ # UnlessExistCondition checks if matching node doesn't exist in the node children.
5
+ class Rewriter::UnlessExistCondition < Rewriter::Condition
6
+ # check if none of child node matches the rules.
7
+ def match?
8
+ match = false
9
+ @instance.current_node.recursive_children do |child_node|
10
+ match = match || (child_node && child_node.match?(@rules))
11
+ end
12
+ !match
13
+ end
14
+ end
15
+ end
@@ -20,37 +20,4 @@ module Synvert::Core
20
20
  @instance.instance_eval &@block if match?
21
21
  end
22
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?(@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?(@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?(@rules)
54
- end
55
- end
56
23
  end
@@ -112,6 +112,9 @@ module Synvert::Core
112
112
 
113
113
  self.class.write_file(file_path, source)
114
114
  end
115
+ rescue Parser::SyntaxError
116
+ puts "[Warn] file #{file_path} was not parsed correctly."
117
+ # do nothing, iterate next file
115
118
  end while !conflict_actions.empty?
116
119
  end
117
120
  end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ module Synvert::Core
4
+ # Go to and change its scope to a child node.
5
+ class Rewriter::GotoScope < Rewriter::Scope
6
+ # Initialize a scope
7
+ #
8
+ # @param instance [Synvert::Core::Rewriter::Instance]
9
+ # @param child_node_name [String]
10
+ # @param block [Block]
11
+ def initialize(instance, child_node_name, &block)
12
+ @instance = instance
13
+ @child_node_name = child_node_name
14
+ @block = block
15
+ end
16
+
17
+ # Go to a child now, then run the block code with the the child node.
18
+ def process
19
+ current_node = @instance.current_node
20
+ return unless current_node
21
+ child_node = current_node.send @child_node_name
22
+ @instance.process_with_other_node child_node do
23
+ @instance.instance_eval &@block
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+
3
+ module Synvert::Core
4
+ # WithinScope finds out nodes which match rules, then change its scope to matching node.
5
+ class Rewriter::WithinScope < Rewriter::Scope
6
+ # Initialize a scope
7
+ #
8
+ # @param instance [Synvert::Core::Rewriter::Instance]
9
+ # @param rules [Hash]
10
+ # @param block [Block]
11
+ def initialize(instance, rules, &block)
12
+ @instance = instance
13
+ @rules = rules
14
+ @block = block
15
+ end
16
+
17
+ # Find out the matching nodes. It checks the current node and iterates all child nodes,
18
+ # then run the block code with each matching node.
19
+ def process
20
+ current_node = @instance.current_node
21
+ return unless current_node
22
+ @instance.process_with_node current_node do
23
+ matching_nodes = []
24
+ matching_nodes << current_node if current_node.match? @rules
25
+ current_node.recursive_children do |child_node|
26
+ matching_nodes << child_node if child_node.match? @rules
27
+ end
28
+ matching_nodes.each do |matching_node|
29
+ @instance.process_with_node matching_node do
30
+ @instance.instance_eval &@block
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end