synvert-core 0.7.5 → 0.8.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.
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