rephrase 0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 35b9da1b746b755618ad23cc57fa70559f35064277b61965278544333d678f1d
4
+ data.tar.gz: 0467c2c8bc54226c445ed39cedb4a16ca85a945c326bd3bae26abf049f5622b2
5
+ SHA512:
6
+ metadata.gz: '0912d93aac2a5fdbdf6c69490947530b6147f2fb55eff205c3839fdc1ad48dd6adddf35d2db868cef4da109b82fdae5b74a489f93d73d6dfed3a65ee8cd8d381'
7
+ data.tar.gz: aa45eefab2311a46c513af8f161345065cb08e2efdd56f7cbfc20e75c56bccf9b1907a90ba4a97e43976fc00efac096387b272895e68a49d212694e1ed7b9f92
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## 0.1 2021-11-16
2
+
3
+ - First working version
data/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # Rephrase - a gem for manipulating Ruby code
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/rephrase.svg)](http://rubygems.org/gems/rephrase)
4
+ [![Modulation Test](https://github.com/digital-fabric/rephrase/workflows/Tests/badge.svg)](https://github.com/digital-fabric/rephrase/actions?query=workflow%3ATests)
5
+ [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/digital-fabric/rephrase/blob/master/LICENSE)
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Rephrase
4
+ VERSION = '0.1'
5
+ end
data/lib/rephrase.rb ADDED
@@ -0,0 +1,276 @@
1
+ # frozen_string_literal: true
2
+
3
+ # for use with IRB, see https://dev.to/okinawarb/how-can-i-use-rubyvm-abstractsyntaxtree-in-irb-m2k
4
+ # for use in Pry, see https://dev.to/okinawarb/using-rubyvm-abstractsyntaxtree-of-in-pry-4cm3
5
+
6
+ class Rephrase
7
+ class FakeNode
8
+ def self.list(children)
9
+ new(:LIST_EMBEDDED, children)
10
+ end
11
+
12
+ def self.iter_scope(children)
13
+ new(:ITER_SCOPE, children)
14
+ end
15
+
16
+ attr_reader :type, :children
17
+
18
+ def initialize(type, children)
19
+ @type = type
20
+ @children = children
21
+ end
22
+ end
23
+
24
+ def convert(ctx, node)
25
+ ctx[:buffer] ||= +''
26
+ ctx[:indent] ||= 0
27
+ method_name = :"on_#{node.type.downcase}"
28
+ if respond_to?(method_name)
29
+ send(method_name, ctx, node)
30
+ ctx[:buffer]
31
+ else
32
+ raise "Could not convert #{node.type} node to ruby"
33
+ end
34
+ end
35
+
36
+ def on_scope(ctx, node)
37
+ body = node.children.last
38
+ # if body.type != :BLOCK
39
+ # body = FakeNode.new(:BLOCK, [body])
40
+ # end
41
+ emit(ctx, "proc do", [body], "end")
42
+ end
43
+
44
+ def on_block(ctx, node)
45
+ last_idx = node.children.size - 1
46
+ node.children.each_with_index do |c, idx|
47
+ emit(ctx, c)
48
+ emit(ctx, "\n") if idx < last_idx
49
+ end
50
+ end
51
+
52
+ def on_iter(ctx, node)
53
+ call, scope = node.children
54
+ emit(ctx, call)
55
+ emit(ctx, FakeNode.iter_scope(scope.children))
56
+ end
57
+
58
+ def on_iter_scope(ctx, node)
59
+ args, arg_spec, body = node.children
60
+ emit(ctx, " do")
61
+ emit(ctx, " |", args.map(&:to_s).join(", "), "|") unless args.empty?
62
+ emit(ctx, "\n")
63
+ emit(ctx, body)
64
+ emit(ctx, "\nend")
65
+ end
66
+
67
+ def on_const(ctx, node)
68
+ emit(ctx, node.children.first.to_s)
69
+ end
70
+
71
+ def on_colon2(ctx, node)
72
+ left, right = node.children
73
+ emit(ctx, left, "::", right.to_s)
74
+ end
75
+
76
+ def on_call(ctx, node)
77
+ receiver, method, args = node.children
78
+ args = args && FakeNode.list(args.children)
79
+ case method
80
+ when :[]
81
+ emit(ctx, receiver, "[", args, "]")
82
+ else
83
+ if args
84
+ emit(ctx, receiver, ".", "#{method}(", args, ")")
85
+ else
86
+ emit(ctx, receiver, ".", "#{method}()")
87
+ end
88
+ end
89
+ end
90
+
91
+ def on_fcall(ctx, node)
92
+ method, args = node.children
93
+ args = args && FakeNode.list(args.children)
94
+ emit(ctx, "#{method}(", args, ")")
95
+ end
96
+
97
+ def on_vcall(ctx, node)
98
+ emit(ctx, node.children.first.to_s, "()")
99
+ end
100
+
101
+ def on_opcall(ctx, node)
102
+ left, op, right = node.children
103
+ if op == :!
104
+ emit(ctx, "!(", left, ")")
105
+ else
106
+ emit(ctx, left, " #{op} ", right.children.first)
107
+ end
108
+ end
109
+
110
+ def on_dasgn_curr(ctx, node)
111
+ left, right = node.children
112
+ emit(ctx, left.to_s, " = ", right)
113
+ end
114
+
115
+ def on_iasgn(ctx, node)
116
+ left, right = node.children
117
+ emit(ctx, left.to_s, " = ", right)
118
+ end
119
+
120
+ def on_if(ctx, node)
121
+ cond, branch1, branch2 = node.children
122
+ if branch2
123
+ emit(ctx, "if ", cond, "\n", branch1, "\nelse\n", branch2, "\nend")
124
+ else
125
+ emit(ctx, "if ", cond, "\n", branch1, "\nend")
126
+ end
127
+ end
128
+
129
+ def on_unless(ctx, node)
130
+ cond, branch1, branch2 = node.children
131
+ if branch2
132
+ emit(ctx, "unless ", cond, "\n", branch1, "\nelse\n", branch2, "\nend")
133
+ else
134
+ emit(ctx, "unless ", cond, "\n", branch1, "\nend")
135
+ end
136
+ end
137
+
138
+ def on_while(ctx, node)
139
+ cond, body = node.children
140
+ emit(ctx, "while ", cond, "\n", body, "\nend")
141
+ end
142
+
143
+ def on_lit(ctx, node)
144
+ emit(ctx, node.children.first.inspect)
145
+ end
146
+
147
+ def on_nil(ctx, node)
148
+ emit(ctx, "nil")
149
+ end
150
+
151
+ def on_true(ctx, node)
152
+ emit(ctx, "true")
153
+ end
154
+
155
+ def on_false(ctx, node)
156
+ emit(ctx, "false")
157
+ end
158
+
159
+ def on_dvar(ctx, node)
160
+ emit(ctx, node.children.first.to_s)
161
+ end
162
+
163
+ def on_ivar(ctx, node)
164
+ emit(ctx, node.children.first.to_s)
165
+ end
166
+
167
+ def on_str(ctx, node)
168
+ emit(ctx, node.children.first.inspect)
169
+ end
170
+
171
+ def on_dstr(ctx, node)
172
+ prefix, evstr1, rest = node.children
173
+ emit(ctx, "\"", prefix.inspect[1..-2], evstr1)
174
+ if rest
175
+ rest.children.compact.each do |n|
176
+ case n.type
177
+ when :STR
178
+ emit(ctx, n.children.first.inspect[1..-2])
179
+ when :EVSTR
180
+ emit(ctx, n)
181
+ else
182
+ raise "Unexpected node #{n.type.inspect} encountered in DSTR"
183
+ end
184
+ end
185
+ end
186
+ emit(ctx, "\"")
187
+ end
188
+
189
+ def on_evstr(ctx, node)
190
+ emit(ctx, "\#{", node.children.first, "}")
191
+ end
192
+
193
+ def on_and(ctx, node)
194
+ left, right = node.children
195
+ emit(ctx, left, " && ", right)
196
+ end
197
+
198
+ def on_or(ctx, node)
199
+ left, right = node.children
200
+ emit(ctx, left, " || ", right)
201
+ end
202
+
203
+ def on_list(ctx, node)
204
+ items = node.children[0..-2]
205
+ last_idx = items.size - 1
206
+ emit(ctx, "[")
207
+ items.each_with_index do |c, idx|
208
+ emit(ctx, c)
209
+ emit(ctx, ", ") if idx < last_idx
210
+ end
211
+ emit(ctx, "]")
212
+ end
213
+
214
+ def on_list_embedded(ctx, node)
215
+ items = node.children.compact
216
+ last_idx = items.size - 1
217
+ items.each_with_index do |c, idx|
218
+ emit(ctx, c)
219
+ emit(ctx, ", ") if idx < last_idx
220
+ end
221
+ end
222
+
223
+ def on_hash(ctx, node)
224
+ list = node.children.first
225
+ idx = 0
226
+ emit(ctx, "{")
227
+ while true
228
+ k, v = list.children[idx, 2]
229
+ break unless k
230
+
231
+ emit(ctx, ", ") if idx > 0
232
+ idx += 2
233
+ emit(ctx, k, " => ", v)
234
+ end
235
+ emit(ctx, "}")
236
+ end
237
+
238
+ def on_attrasgn(ctx, node)
239
+ left, op, args = node.children
240
+ emit(ctx, left)
241
+ case op
242
+ when :[]=
243
+ args_list = args.children[0..-2]
244
+ subscript = FakeNode.list(args_list[0..-2])
245
+ right = args_list.last
246
+ emit(ctx, "[", subscript, "] = ", right)
247
+ else
248
+ raise "Unsupported ATTRASGN op #{op.inspect}"
249
+ end
250
+ end
251
+
252
+ def on_rescue(ctx, node)
253
+ code, rescue_body = node.children
254
+ emit(ctx, code)
255
+ emit(ctx, " rescue ", rescue_body.children[1])
256
+ end
257
+
258
+ def emit(ctx, *entries)
259
+ entries.each do |e|
260
+ case e
261
+ when RubyVM::AbstractSyntaxTree::Node, FakeNode
262
+ convert(ctx, e)
263
+ when Array
264
+ ctx[:buffer] << "\n"
265
+ e.each { |e2| convert(ctx, e2) }
266
+ ctx[:buffer] << "\n"
267
+ when String
268
+ ctx[:buffer] << e
269
+ when nil
270
+ # ignore
271
+ else
272
+ raise "Invalid entry #{e.inspect}"
273
+ end
274
+ end
275
+ end
276
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rephrase
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Sharon Rosner
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-11-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: minitest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 5.11.3
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 5.11.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '12.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '12.0'
41
+ description:
42
+ email: ciconia@gmail.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files:
46
+ - README.md
47
+ files:
48
+ - CHANGELOG.md
49
+ - README.md
50
+ - lib/rephrase.rb
51
+ - lib/rephrase/version.rb
52
+ homepage: http://github.com/digital-fabric/rephrase
53
+ licenses:
54
+ - MIT
55
+ metadata:
56
+ source_code_uri: https://github.com/digital-fabric/rephrase
57
+ post_install_message:
58
+ rdoc_options:
59
+ - "--title"
60
+ - Rephrase
61
+ - "--main"
62
+ - README.md
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '2.7'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ requirements: []
76
+ rubygems_version: 3.1.2
77
+ signing_key:
78
+ specification_version: 4
79
+ summary: 'Rephrase: a gem for manipulating Ruby code'
80
+ test_files: []