thor 0.9.2 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ require "thor/task"
2
+
3
+ class Thor::PackageTask < Thor::Task
4
+ attr_accessor :spec
5
+ attr_accessor :opts
6
+
7
+ def initialize(gemspec, opts = {})
8
+ super(:package, "build a gem package")
9
+ @spec = gemspec
10
+ @opts = {:dir => File.join(Dir.pwd, "pkg")}.merge(opts)
11
+ end
12
+
13
+ def run
14
+ FileUtils.mkdir_p(@opts[:dir])
15
+ Gem::Builder.new(spec).build
16
+ FileUtils.mv(spec.file_name, File.join(@opts[:dir], spec.file_name))
17
+ end
18
+ end
@@ -0,0 +1,43 @@
1
+ require 'thor/error'
2
+
3
+ class Thor
4
+ module Util
5
+
6
+ def self.constant_to_thor_path(str, remove_default = true)
7
+ str = snake_case(str.to_s).squeeze(":")
8
+ str.gsub!(/^default/, '') if remove_default
9
+ str
10
+ end
11
+
12
+ def self.constant_from_thor_path(str)
13
+ make_constant(to_constant(str))
14
+ rescue NameError => e
15
+ raise e unless e.message =~ /^uninitialized constant (.*)$/
16
+ raise Error, "There was no available namespace `#{str}'."
17
+ end
18
+
19
+ def self.to_constant(str)
20
+ str = 'default' if str.empty?
21
+ str.gsub(/:(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
22
+ end
23
+
24
+ def self.constants_in_contents(str)
25
+ klasses = self.constants.dup
26
+ eval(str)
27
+ ret = self.constants - klasses
28
+ ret.each {|k| self.send(:remove_const, k)}
29
+ ret
30
+ end
31
+
32
+ def self.make_constant(str)
33
+ list = str.split("::").inject(Object) {|obj, x| obj.const_get(x)}
34
+ end
35
+
36
+ def self.snake_case(str)
37
+ return str.downcase if str =~ /^[A-Z_]+$/
38
+ str.gsub(/\B[A-Z]/, '_\&').squeeze('_') =~ /_*(.*)/
39
+ return $+.downcase
40
+ end
41
+
42
+ end
43
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.9.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yehuda Katz
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-05-13 00:00:00 -07:00
12
+ date: 2008-08-27 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -17,25 +17,32 @@ description: A gem that maps options to a class
17
17
  email: wycats@gmail.com
18
18
  executables:
19
19
  - thor
20
+ - rake2thor
20
21
  extensions: []
21
22
 
22
23
  extra_rdoc_files:
23
24
  - README.markdown
25
+ - CHANGELOG.rdoc
24
26
  - LICENSE
25
27
  files:
26
- - LICENSE
27
28
  - README.markdown
29
+ - LICENSE
30
+ - CHANGELOG.rdoc
28
31
  - Rakefile
32
+ - bin/rake2thor
29
33
  - bin/thor
30
- - lib/getopt.rb
31
34
  - lib/thor
35
+ - lib/thor/error.rb
36
+ - lib/thor/options.rb
37
+ - lib/thor/ordered_hash.rb
38
+ - lib/thor/runner.rb
39
+ - lib/thor/task.rb
40
+ - lib/thor/task_hash.rb
41
+ - lib/thor/tasks
42
+ - lib/thor/tasks/package.rb
32
43
  - lib/thor/tasks.rb
44
+ - lib/thor/util.rb
33
45
  - lib/thor.rb
34
- - lib/vendor
35
- - lib/vendor/ruby2ruby.rb
36
- - lib/vendor/sexp.rb
37
- - lib/vendor/sexp_processor.rb
38
- - lib/vendor/unified_ruby.rb
39
46
  has_rdoc: true
40
47
  homepage: http://yehudakatz.com
41
48
  post_install_message:
@@ -58,7 +65,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
58
65
  requirements: []
59
66
 
60
67
  rubyforge_project: thor
61
- rubygems_version: 1.1.1
68
+ rubygems_version: 1.2.0
62
69
  signing_key:
63
70
  specification_version: 2
64
71
  summary: A gem that maps options to a class
@@ -1,238 +0,0 @@
1
- # The last time the Getopt gem was modified was August 2007, so it's safe to vendor (it does everything we need)
2
-
3
- module Getopt
4
-
5
- REQUIRED = 0
6
- BOOLEAN = 1
7
- OPTIONAL = 2
8
- INCREMENT = 3
9
- NEGATABLE = 4
10
- NUMERIC = 5
11
-
12
- class Long
13
- class Error < StandardError; end
14
-
15
- VERSION = '1.3.6'
16
-
17
- # Takes an array of switches. Each array consists of up to three
18
- # elements that indicate the name and type of switch. Returns a hash
19
- # containing each switch name, minus the '-', as a key. The value
20
- # for each key depends on the type of switch and/or the value provided
21
- # by the user.
22
- #
23
- # The long switch _must_ be provided. The short switch defaults to the
24
- # first letter of the short switch. The default type is BOOLEAN.
25
- #
26
- # Example:
27
- #
28
- # opts = Getopt::Long.getopts(
29
- # ["--debug"],
30
- # ["--verbose", "-v"],
31
- # ["--level", "-l", NUMERIC]
32
- # )
33
- #
34
- # See the README file for more information.
35
- #
36
- def self.getopts(*switches)
37
- if switches.empty?
38
- raise ArgumentError, "no switches provided"
39
- end
40
-
41
- hash = {} # Hash returned to user
42
- valid = [] # Tracks valid switches
43
- types = {} # Tracks argument types
44
- syns = {} # Tracks long and short arguments, or multiple shorts
45
-
46
- # If a string is passed, split it and convert it to an array of arrays
47
- if switches.first.kind_of?(String)
48
- switches = switches.join.split
49
- switches.map!{ |switch| switch = [switch] }
50
- end
51
-
52
- # Set our list of valid switches, and proper types for each switch
53
- switches.each{ |switch|
54
- valid.push(switch[0]) # Set valid long switches
55
-
56
- # Set type for long switch, default to BOOLEAN.
57
- if switch[1].kind_of?(Fixnum)
58
- switch[2] = switch[1]
59
- types[switch[0]] = switch[2]
60
- switch[1] = switch[0][1..2]
61
- else
62
- switch[2] ||= BOOLEAN
63
- types[switch[0]] = switch[2]
64
- switch[1] ||= switch[0][1..2]
65
- end
66
-
67
- # Create synonym hash. Default to first char of long switch for
68
- # short switch, e.g. "--verbose" creates a "-v" synonym. The same
69
- # synonym can only be used once - first one wins.
70
- syns[switch[0]] = switch[1] unless syns[switch[1]]
71
- syns[switch[1]] = switch[0] unless syns[switch[1]]
72
-
73
- switch[1].each{ |char|
74
- types[char] = switch[2] # Set type for short switch
75
- valid.push(char) # Set valid short switches
76
- }
77
-
78
- if ARGV.empty? && switch[2] == REQUIRED
79
- raise Error, "no value provided for required argument '#{switch[0]}'"
80
- end
81
- }
82
-
83
- re_long = /^(--\w+[-\w+]*)?$/
84
- re_short = /^(-\w)$/
85
- re_long_eq = /^(--\w+[-\w+]*)?=(.*?)$|(-\w?)=(.*?)$/
86
- re_short_sq = /^(-\w)(\S+?)$/
87
-
88
- ARGV.each_with_index{ |opt, index|
89
-
90
- # Allow either -x -v or -xv style for single char args
91
- if re_short_sq.match(opt)
92
- chars = opt.split("")[1..-1].map{ |s| s = "-#{s}" }
93
-
94
- chars.each_with_index{ |char, i|
95
- unless valid.include?(char)
96
- raise Error, "invalid switch '#{char}'"
97
- end
98
-
99
- # Grab the next arg if the switch takes a required arg
100
- if types[char] == REQUIRED
101
- # Deal with a argument squished up against switch
102
- if chars[i+1]
103
- arg = chars[i+1..-1].join.tr("-","")
104
- ARGV.push(char, arg)
105
- break
106
- else
107
- arg = ARGV.delete_at(index+1)
108
- if arg.nil? || valid.include?(arg) # Minor cheat here
109
- err = "no value provided for required argument '#{char}'"
110
- raise Error, err
111
- end
112
- ARGV.push(char, arg)
113
- end
114
- elsif types[char] == OPTIONAL
115
- if chars[i+1] && !valid.include?(chars[i+1])
116
- arg = chars[i+1..-1].join.tr("-","")
117
- ARGV.push(char, arg)
118
- break
119
- elsif
120
- if ARGV[index+1] && !valid.include?(ARGV[index+1])
121
- arg = ARGV.delete_at(index+1)
122
- ARGV.push(char, arg)
123
- end
124
- else
125
- ARGV.push(char)
126
- end
127
- else
128
- ARGV.push(char)
129
- end
130
- }
131
- next
132
- end
133
-
134
- if match = re_long.match(opt) || match = re_short.match(opt)
135
- switch = match.captures.first
136
- end
137
-
138
- if match = re_long_eq.match(opt)
139
- switch, value = match.captures.compact
140
- ARGV.push(switch, value)
141
- next
142
- end
143
-
144
- # Make sure that all the switches are valid. If 'switch' isn't
145
- # defined at this point, it means an option was passed without
146
- # a preceding switch, e.g. --option foo bar.
147
- unless valid.include?(switch)
148
- switch ||= opt
149
- raise Error, "invalid switch '#{switch}'"
150
- end
151
-
152
- # Required arguments
153
- if types[switch] == REQUIRED
154
- nextval = ARGV[index+1]
155
-
156
- # Make sure there's a value for mandatory arguments
157
- if nextval.nil?
158
- err = "no value provided for required argument '#{switch}'"
159
- raise Error, err
160
- end
161
-
162
- # If there is a value, make sure it's not another switch
163
- if valid.include?(nextval)
164
- err = "cannot pass switch '#{nextval}' as an argument"
165
- raise Error, err
166
- end
167
-
168
- # If the same option appears more than once, put the values
169
- # in array.
170
- if hash[switch]
171
- hash[switch] = [hash[switch], nextval].flatten
172
- else
173
- hash[switch] = nextval
174
- end
175
- ARGV.delete_at(index+1)
176
- end
177
-
178
- # For boolean arguments set the switch's value to true.
179
- if types[switch] == BOOLEAN
180
- if hash.has_key?(switch)
181
- raise Error, "boolean switch already set"
182
- end
183
- hash[switch] = true
184
- end
185
-
186
- # For increment arguments, set the switch's value to 0, or
187
- # increment it by one if it already exists.
188
- if types[switch] == INCREMENT
189
- if hash.has_key?(switch)
190
- hash[switch] += 1
191
- else
192
- hash[switch] = 1
193
- end
194
- end
195
-
196
- # For optional argument, there may be an argument. If so, it
197
- # cannot be another switch. If not, it is set to true.
198
- if types[switch] == OPTIONAL
199
- nextval = ARGV[index+1]
200
- if valid.include?(nextval)
201
- hash[switch] = true
202
- else
203
- hash[switch] = nextval
204
- ARGV.delete_at(index+1)
205
- end
206
- end
207
- }
208
-
209
- # Set synonymous switches to the same value, e.g. if -t is a synonym
210
- # for --test, and the user passes "--test", then set "-t" to the same
211
- # value that "--test" was set to.
212
- #
213
- # This allows users to refer to the long or short switch and get
214
- # the same value
215
- hash.each{ |switch, val|
216
- if syns.keys.include?(switch)
217
- syns[switch].each{ |key|
218
- hash[key] = val
219
- }
220
- end
221
- }
222
-
223
- # Get rid of leading "--" and "-" to make it easier to reference
224
- hash.each{ |key, value|
225
- if key[0,2] == '--'
226
- nkey = key.sub('--', '')
227
- else
228
- nkey = key.sub('-', '')
229
- end
230
- hash.delete(key)
231
- hash[nkey] = value
232
- }
233
-
234
- hash
235
- end
236
-
237
- end
238
- end
@@ -1,1090 +0,0 @@
1
- require 'vendor/sexp_processor'
2
- require 'vendor/unified_ruby'
3
-
4
- class Ruby2Ruby < SexpProcessor
5
- include UnifiedRuby
6
-
7
- VERSION = '1.1.8'
8
- LINE_LENGTH = 78
9
-
10
- ##
11
- # Nodes that represent assignment and probably need () around them.
12
-
13
- ASSIGN_NODES = [
14
- :dasgn,
15
- :flip2,
16
- :flip3,
17
- :lasgn,
18
- :masgn,
19
- :op_asgn1,
20
- :op_asgn2,
21
- :op_asgn_and,
22
- :op_asgn_or,
23
- :return,
24
- ]
25
-
26
- def self.translate(klass_or_str, method = nil)
27
- self.new.process(ParseTree.translate(klass_or_str, method))
28
- end
29
-
30
- def initialize
31
- super
32
- @indent = " "
33
- self.auto_shift_type = true
34
- self.strict = true
35
- self.expected = String
36
-
37
- # self.debug[:defn] = /zsuper/
38
- end
39
-
40
- def process exp
41
- exp = Sexp.from_array(exp) if Array === exp unless Sexp === exp
42
- super exp
43
- end
44
-
45
- ############################################################
46
- # Processors
47
-
48
- def process_alias(exp)
49
- "alias_method #{process(exp.shift)}, #{process(exp.shift)}"
50
- end
51
-
52
- def process_and(exp)
53
- "(#{process exp.shift} and #{process exp.shift})"
54
- end
55
-
56
- def process_args(exp)
57
- args = []
58
-
59
- until exp.empty? do
60
- arg = exp.shift
61
- case arg
62
- when Symbol then
63
- args << arg
64
- when Array then
65
- case arg.first
66
- when :block then
67
- asgns = {}
68
- arg[1..-1].each do |lasgn|
69
- asgns[lasgn[1]] = process(lasgn)
70
- end
71
-
72
- args.each_with_index do |name, index|
73
- args[index] = asgns[name] if asgns.has_key? name
74
- end
75
- when :block_arg then
76
- args << "&#{arg.last}"
77
- else
78
- raise "unknown arg type #{arg.first.inspect}"
79
- end
80
- else
81
- raise "unknown arg type #{arg.inspect}"
82
- end
83
- end
84
-
85
- return "(#{args.join ', '})"
86
- end
87
-
88
- def process_arglist(exp) # custom made node
89
- code = []
90
- until exp.empty? do
91
- code << process(exp.shift)
92
- end
93
- code.join ', '
94
- end
95
-
96
- def process_argscat(exp)
97
- args = []
98
-
99
- ary = exp.shift
100
- ary.shift # :array
101
- until ary.empty? do
102
- args << process(ary.shift)
103
- end
104
-
105
- args << "*#{process(exp.shift)}"
106
- args << process(exp.shift) unless exp.empty? # optional block arg
107
-
108
- args.join ', '
109
- end
110
-
111
- def process_argspush(exp)
112
- process_arglist(exp)
113
- end
114
-
115
- def process_array(exp)
116
- "[#{process_arglist(exp)}]"
117
- end
118
-
119
- def process_attrasgn(exp)
120
- receiver = process exp.shift
121
- name = exp.shift
122
- args = exp.empty? ? nil : exp.shift
123
-
124
- case name
125
- when :[]= then
126
- rhs = process args.pop
127
- args[0] = :arglist if args[0] == :array
128
- "#{receiver}[#{process(args)}] = #{rhs}"
129
- else
130
- if args then
131
- "#{receiver}.#{name.to_s[0..-2]} = #{process(args)[1..-2]}"
132
- else
133
- "#{receiver}.#{name.to_s[0..-2]}"
134
- end
135
- end
136
- end
137
-
138
- def process_back_ref(exp)
139
- "$#{exp.shift}"
140
- end
141
-
142
- def process_begin(exp)
143
- is_rescue = exp.first.first == :rescue rescue false
144
- code = []
145
- code << "begin"
146
- until exp.empty?
147
- src = process(exp.shift)
148
- src = indent(src) unless src =~ /(^|\n)rescue/ # ensures no level 0 rescues
149
- code << src
150
- end
151
- code << "end" unless is_rescue
152
- return code.join("\n")
153
- end
154
-
155
- def process_block(exp)
156
- result = []
157
-
158
- exp << nil if exp.empty?
159
- until exp.empty? do
160
- code = exp.shift
161
- if code.nil? or code.first == :nil then
162
- result << "# do nothing"
163
- else
164
- result << process(code)
165
- end
166
- end
167
-
168
- result = result.join "\n"
169
-
170
- result = case self.context[1]
171
- when nil, :scope, :if, :iter, :resbody, :when, :while then
172
- result + "\n"
173
- else
174
- "(#{result})"
175
- end
176
-
177
- return result
178
- end
179
-
180
- def process_block_arg(exp)
181
- "&#{exp.shift}"
182
- end
183
-
184
- def process_block_pass(exp)
185
- bname = s(:block_arg, process(exp.shift)) # FIX
186
- call = exp.shift
187
-
188
- if Array === call.last then # HACK - I _really_ need rewrites to happen first
189
- case call.last.first
190
- when :splat then
191
- call << [:array, call.pop]
192
- when :array then
193
- # do nothing
194
- else
195
- has_args = Array === call.last and call.last.first == :array
196
- call << [:array] unless has_args
197
- end
198
- call.last << bname
199
- else
200
- call << [:array, bname]
201
- end
202
-
203
- process(call)
204
- end
205
-
206
- def process_break(exp)
207
- val = exp.empty? ? nil : process(exp.shift)
208
- # HACK "break" + (val ? " #{val}" : "")
209
- if val then
210
- "break #{val}"
211
- else
212
- "break"
213
- end
214
- end
215
-
216
- def process_call(exp)
217
- receiver_node_type = exp.first.nil? ? nil : exp.first.first
218
- receiver = process exp.shift
219
-
220
- receiver = "(#{receiver})" if
221
- Ruby2Ruby::ASSIGN_NODES.include? receiver_node_type
222
-
223
- name = exp.shift
224
- args_exp = exp.shift rescue nil
225
- if args_exp && args_exp.first == :array # FIX
226
- args = "#{process(args_exp)[1..-2]}"
227
- else
228
- args = process args_exp
229
- args = nil if args.empty?
230
- end
231
-
232
- case name
233
- when :<=>, :==, :<, :>, :<=, :>=, :-, :+, :*, :/, :%, :<<, :>>, :** then
234
- "(#{receiver} #{name} #{args})"
235
- when :[] then
236
- "#{receiver}[#{args}]"
237
- when :"-@" then
238
- "-#{receiver}"
239
- when :"+@" then
240
- "+#{receiver}"
241
- else
242
- unless receiver.nil? then
243
- "#{receiver}.#{name}#{args ? "(#{args})" : args}"
244
- else
245
- "#{name}#{args ? "(#{args})" : args}"
246
- end
247
- end
248
- end
249
-
250
- def process_case(exp)
251
- result = []
252
- expr = process exp.shift
253
- if expr then
254
- result << "case #{expr}"
255
- else
256
- result << "case"
257
- end
258
- until exp.empty?
259
- pt = exp.shift
260
- if pt and pt.first == :when
261
- result << "#{process(pt)}"
262
- else
263
- code = indent(process(pt))
264
- code = indent("# do nothing") if code =~ /^\s*$/
265
- result << "else\n#{code}"
266
- end
267
- end
268
- result << "end"
269
- result.join("\n")
270
- end
271
-
272
- def process_cdecl(exp)
273
- "#{exp.shift} = #{process(exp.shift)}"
274
- end
275
-
276
- def process_class(exp)
277
- "class #{util_module_or_class(exp, true)}"
278
- end
279
-
280
- def process_colon2(exp)
281
- "#{process(exp.shift)}::#{exp.shift}"
282
- end
283
-
284
- def process_colon3(exp)
285
- "::#{exp.shift}"
286
- end
287
-
288
- def process_const(exp)
289
- exp.shift.to_s
290
- end
291
-
292
- def process_cvar(exp)
293
- "#{exp.shift}"
294
- end
295
-
296
- def process_cvasgn(exp)
297
- "#{exp.shift} = #{process(exp.shift)}"
298
- end
299
-
300
- def process_cvdecl(exp)
301
- "#{exp.shift} = #{process(exp.shift)}"
302
- end
303
-
304
- # (a, lit1) => "a = 1"
305
- # (a, (b, lit2)) => "a = b = 2"
306
- # (a, (b)) => ""
307
-
308
- def process_dasgn_curr(exp)
309
- lhs = exp.shift.to_s
310
- rhs = (exp.empty? ? nil : exp.shift)
311
- if rhs.nil? then
312
- if self.context[1] == :block then
313
- return ''
314
- end
315
-
316
- return lhs
317
- end
318
- return "#{lhs} = #{process rhs}" unless rhs.first == :dasgn_curr
319
-
320
- # keep recursing. ensure that the leaf node assigns to _something_
321
- "#{lhs} = #{process rhs}"
322
- end
323
-
324
- def process_dasgn(exp)
325
- if exp.size == 1 then
326
- exp.shift.to_s
327
- else
328
- "#{exp.shift} = #{process(exp.shift)}"
329
- end
330
- end
331
-
332
- def process_defined(exp)
333
- "defined? #{process(exp.shift)}"
334
- end
335
-
336
- def process_defn(exp)
337
- type1 = exp[1].first
338
- type2 = exp[2].first rescue nil
339
-
340
- if type1 == :args and [:ivar, :attrset].include? type2 then
341
- name = exp.shift
342
- case type2
343
- when :ivar then
344
- exp.clear
345
- return "attr_reader #{name.inspect}"
346
- when :attrset then
347
- exp.clear
348
- return "attr_writer :#{name.to_s[0..-2]}"
349
- else
350
- raise "Unknown defn type: #{exp.inspect}"
351
- end
352
- end
353
-
354
- case type1
355
- when :scope, :args then
356
- name = exp.shift
357
- args = process(exp.shift)
358
- args = "" if args == "()"
359
- body = indent(process(exp.shift))
360
- return "def #{name}#{args}\n#{body}\nend".gsub(/\n\s*\n+/, "\n")
361
- else
362
- raise "Unknown defn type: #{type1} for #{exp.inspect}"
363
- end
364
- end
365
-
366
- def process_defs(exp)
367
- exp.unshift "#{process(exp.shift)}.#{exp.shift}"
368
- process_defn(exp)
369
- end
370
-
371
- def process_dot2(exp)
372
- "(#{process exp.shift}..#{process exp.shift})"
373
- end
374
-
375
- def process_dot3(exp)
376
- "(#{process exp.shift}...#{process exp.shift})"
377
- end
378
-
379
- def process_dregx(exp)
380
- "/" << util_dthing(exp, true) << "/"
381
- end
382
-
383
- def process_dregx_once(exp)
384
- process_dregx(exp) + "o"
385
- end
386
-
387
- def process_dstr(exp)
388
- "\"#{util_dthing(exp)}\""
389
- end
390
-
391
- def process_dsym(exp)
392
- ":#{process_dstr(exp)}"
393
- end
394
-
395
- def process_dvar(exp)
396
- exp.shift.to_s
397
- end
398
-
399
- def process_dxstr(exp)
400
- "`#{process_dstr(exp)[1..-2]}`"
401
- end
402
-
403
- def process_ensure(exp)
404
- body = process exp.shift
405
- ens = process exp.shift
406
- return "#{body}\nensure\n#{indent ens}"
407
- end
408
-
409
- def process_evstr(exp)
410
- process exp.shift
411
- end
412
-
413
- def process_false(exp)
414
- "false"
415
- end
416
-
417
- # TODO: remove for unified
418
- def process_fcall(exp)
419
- recv = exp.shift unless Symbol === exp.first # HACK conditional - some not getting rewritten?
420
- name = exp.shift.to_s
421
- args = exp.shift
422
- code = []
423
- unless args.nil? then
424
- args[0] = :arglist if args.first == :array
425
- code << process(args)
426
- end
427
- return code.empty? ? name : "#{name}(#{code.join(', ')})"
428
- end
429
-
430
- def process_flip2(exp)
431
- "#{process(exp.shift)}..#{process(exp.shift)}"
432
- end
433
-
434
- def process_flip3(exp)
435
- "#{process(exp.shift)}...#{process(exp.shift)}"
436
- end
437
-
438
- def process_for(exp)
439
- recv = process exp.shift
440
- iter = process exp.shift
441
- body = exp.empty? ? nil : process(exp.shift)
442
-
443
- result = ["for #{iter} in #{recv} do"]
444
- result << indent(body ? body : "# do nothing")
445
- result << "end"
446
-
447
- result.join("\n")
448
- end
449
-
450
- def process_gasgn(exp)
451
- process_iasgn(exp)
452
- end
453
-
454
- def process_gvar(exp)
455
- return exp.shift.to_s
456
- end
457
-
458
- def process_hash(exp)
459
- result = []
460
- until exp.empty?
461
- result << "#{process(exp.shift)} => #{process(exp.shift)}"
462
- end
463
-
464
- case self.context[1]
465
- when :arglist, :argscat then
466
- return "#{result.join(', ')}" # HACK - this will break w/ 2 hashes as args
467
- else
468
- return "{ #{result.join(', ')} }"
469
- end
470
- end
471
-
472
- def process_iasgn(exp)
473
- lhs = exp.shift
474
- if exp.empty? then # part of an masgn
475
- lhs.to_s
476
- else
477
- "#{lhs} = #{process exp.shift}"
478
- end
479
- end
480
-
481
- def process_if(exp)
482
- expand = Ruby2Ruby::ASSIGN_NODES.include? exp.first.first
483
- c = process exp.shift
484
- t = process exp.shift
485
- f = process exp.shift
486
-
487
- c = "(#{c.chomp})" if c =~ /\n/
488
-
489
- if t then
490
- unless expand then
491
- if f then
492
- r = "#{c} ? (#{t}) : (#{f})"
493
- r = nil if r =~ /return/ # HACK - need contextual awareness or something
494
- else
495
- r = "#{t} if #{c}"
496
- end
497
- return r if r and (@indent+r).size < LINE_LENGTH and r !~ /\n/
498
- end
499
-
500
- r = "if #{c} then\n#{indent(t)}\n"
501
- r << "else\n#{indent(f)}\n" if f
502
- r << "end"
503
-
504
- r
505
- else
506
- unless expand then
507
- r = "#{f} unless #{c}"
508
- return r if (@indent+r).size < LINE_LENGTH and r !~ /\n/
509
- end
510
- "unless #{c} then\n#{indent(f)}\nend"
511
- end
512
- end
513
-
514
- def process_iter(exp)
515
- iter = process exp.shift
516
- args = exp.shift
517
- args = (args == 0) ? '' : process(args)
518
- body = exp.empty? ? nil : process(exp.shift)
519
-
520
- b, e = if iter == "END" then
521
- [ "{", "}" ]
522
- else
523
- [ "do", "end" ]
524
- end
525
-
526
- iter.sub!(/\(\)$/, '')
527
-
528
- # REFACTOR: ugh
529
- result = []
530
- result << "#{iter} {"
531
- result << " |#{args}|" if args
532
- if body then
533
- result << " #{body.strip} "
534
- else
535
- result << ' '
536
- end
537
- result << "}"
538
- result = result.join
539
- return result if result !~ /\n/ and result.size < LINE_LENGTH
540
-
541
- result = []
542
- result << "#{iter} #{b}"
543
- result << " |#{args}|" if args
544
- result << "\n"
545
- result << indent(body.strip)
546
- result << "\n"
547
- result << e
548
- result.join
549
- end
550
-
551
- def process_ivar(exp)
552
- exp.shift.to_s
553
- end
554
-
555
- def process_lasgn(exp)
556
- s = "#{exp.shift}"
557
- s += " = #{process exp.shift}" unless exp.empty?
558
- s
559
- end
560
-
561
- def process_lit(exp)
562
- obj = exp.shift
563
- case obj
564
- when Range then
565
- "(#{obj.inspect})"
566
- else
567
- obj.inspect
568
- end
569
- end
570
-
571
- def process_lvar(exp)
572
- exp.shift.to_s
573
- end
574
-
575
- def splat(sym)
576
- :"*#{sym}"
577
- end
578
-
579
- def process_masgn(exp)
580
- lhs = exp.shift
581
- rhs = exp.empty? ? nil : exp.shift
582
-
583
- unless exp.empty? then
584
- rhs[-1] = splat(rhs[-1]) unless rhs == s(:splat)
585
- lhs << rhs
586
- rhs = exp.shift
587
- end
588
-
589
- case lhs.first
590
- when :array then
591
- lhs.shift
592
- lhs = lhs.map do |l|
593
- case l.first
594
- when :masgn then
595
- "(#{process(l)})"
596
- else
597
- process(l)
598
- end
599
- end
600
- when :dasgn_curr then
601
- lhs = [ splat(lhs.last) ]
602
- when :splat then
603
- lhs = [ :"*" ]
604
- else
605
- raise "no clue: #{lhs.inspect}"
606
- end
607
-
608
- if context[1] == :iter and rhs then
609
- lhs << splat(rhs.last)
610
- rhs = nil
611
- end
612
-
613
- unless rhs.nil? then
614
- t = rhs.first
615
- rhs = if t == :argscat then
616
- rhs.shift
617
- process_argscat(rhs)
618
- else
619
- r = process(rhs)
620
- r = r[1..-2] if t != :to_ary
621
- r
622
- end
623
- return "#{lhs.join(", ")} = #{rhs}"
624
- else
625
- return lhs.join(", ")
626
- end
627
-
628
- end
629
-
630
- def process_match(exp)
631
- "#{process(exp.shift)}"
632
- end
633
-
634
- def process_match2(exp)
635
- lhs = process(exp.shift)
636
- rhs = process(exp.shift)
637
- "#{lhs} =~ #{rhs}"
638
- end
639
-
640
- def process_match3(exp)
641
- rhs = process(exp.shift)
642
- lhs = process(exp.shift)
643
- "#{lhs} =~ #{rhs}"
644
- end
645
-
646
- def process_module(exp)
647
- "module #{util_module_or_class(exp)}"
648
- end
649
-
650
- def process_next(exp)
651
- val = exp.empty? ? nil : process(exp.shift)
652
- if val then
653
- "next #{val}"
654
- else
655
- "next"
656
- end
657
- end
658
-
659
- def process_nil(exp)
660
- "nil"
661
- end
662
-
663
- def process_not(exp)
664
- "(not #{process exp.shift})"
665
- end
666
-
667
- def process_nth_ref(exp)
668
- "$#{exp.shift}"
669
- end
670
-
671
- def process_op_asgn1(exp)
672
- # [[:lvar, :b], [:array, [:lit, 1]], :"||", [:lit, 10]]
673
- lhs = process(exp.shift)
674
- index = process(exp.shift)
675
- msg = exp.shift
676
- rhs = process(exp.shift)
677
-
678
- "#{lhs}#{index} #{msg}= #{rhs}"
679
- end
680
-
681
- def process_op_asgn2(exp)
682
- # [[:lvar, :c], :var=, :"||", [:lit, 20]]
683
- lhs = process(exp.shift)
684
- index = exp.shift.to_s[0..-2]
685
- msg = exp.shift
686
-
687
- rhs = process(exp.shift)
688
-
689
- "#{lhs}.#{index} #{msg}= #{rhs}"
690
- end
691
-
692
- def process_op_asgn_or(exp)
693
- # a ||= 1
694
- # [[:lvar, :a], [:lasgn, :a, [:lit, 1]]]
695
- exp.shift
696
- process(exp.shift).sub(/=/, '||=')
697
- end
698
-
699
- def process_op_asgn_and(exp)
700
- # a &&= 1
701
- # [[:lvar, :a], [:lasgn, :a, [:lit, 1]]]
702
- exp.shift
703
- process(exp.shift).sub(/=/, '&&=')
704
- end
705
-
706
- def process_or(exp)
707
- "(#{process exp.shift} or #{process exp.shift})"
708
- end
709
-
710
- def process_postexe(exp)
711
- "END"
712
- end
713
-
714
- def process_redo(exp)
715
- "redo"
716
- end
717
-
718
- def process_resbody(exp) # TODO: rewrite this fucker
719
- code = []
720
-
721
- sexp = exp
722
- until exp.empty? and (sexp.nil? or sexp.empty?)
723
- list = sexp.shift
724
- body = sexp.shift
725
-
726
- var = if list and
727
- list.size > 1 and
728
- [:lasgn, :dasgn, :dasgn_curr].include? list.last.first then
729
- list.pop[1]
730
- else
731
- nil
732
- end
733
-
734
- # FIX: omg this is horrid. I should be punished
735
- var = body.delete_at(1)[1] if
736
- [:dasgn_curr, :dasgn].include? body[1][0] unless
737
- var or body.nil? rescue nil
738
-
739
- if list and list.size > 1 then
740
- list[0] = :arglist
741
- code << "rescue #{process(list)}"
742
- else
743
- code << "rescue"
744
- end
745
-
746
- code.last << " => #{var}" if var
747
-
748
- if body then
749
- code << indent(process(body)).chomp
750
- else
751
- code << indent("# do nothing")
752
- end
753
-
754
- unless exp.empty? then
755
- sexp = exp.shift
756
- assert_type sexp, :resbody
757
- sexp.shift
758
- end
759
- end
760
-
761
- code.join("\n")
762
- end
763
-
764
- def process_rescue(exp)
765
- # TODO: rewrite this
766
- #
767
- # a = b rescue c => [lasgn a [rescue b c]]
768
- # begin; a = b; rescue c => [begin [rescue [lasgn a b] c]]
769
-
770
- current = self.context[1]
771
- case current
772
- when :begin, :ensure, :block then
773
- body = (exp.first.first == :resbody) ? nil : process(exp.shift)
774
- resbody = exp.empty? ? '' : process(exp.shift)
775
- els = exp.empty? ? nil : process(exp.shift)
776
-
777
- code = []
778
- code << indent(body) if body
779
- code << resbody
780
- if els then
781
- code << "else"
782
- code << indent(els)
783
- else
784
- unless [:block].include? current then
785
- code << "end\n" unless current == :ensure
786
- else
787
- r = [body, resbody.gsub(/rescue\n\s+/, 'rescue ')].compact.join(' ')
788
- code = [r] if (@indent+r).size < LINE_LENGTH and r !~ /\n/
789
- end
790
- end
791
-
792
- code.join("\n").chomp
793
- else # a rescue b and others
794
- body = process exp.shift
795
- assert_type exp.first, :resbody
796
- resbody = exp.shift
797
- resbody.shift # resbody
798
- resbody.shift # nil (no types for expression form)
799
- resbody = resbody.shift # actual code
800
-
801
- resbody = process resbody
802
- code = "#{body} rescue #{resbody}"
803
- case current
804
- when :hash then # HACK move to process_hash
805
- "(#{code})"
806
- else
807
- code
808
- end
809
- end
810
- end
811
-
812
- def process_retry(exp)
813
- "retry"
814
- end
815
-
816
- def process_return(exp)
817
- # HACK return "return" + (exp.empty? ? "" : " #{process exp.shift}")
818
-
819
- if exp.empty? then
820
- return "return"
821
- else
822
- return "return #{process exp.shift}"
823
- end
824
- end
825
-
826
- def process_sclass(exp)
827
- "class << #{process(exp.shift)}\n#{indent(process(exp.shift))}\nend"
828
- end
829
-
830
- def process_scope(exp)
831
- exp.empty? ? "" : process(exp.shift)
832
- end
833
-
834
- def process_self(exp)
835
- "self"
836
- end
837
-
838
- def process_splat(exp)
839
- if exp.empty? then
840
- "*"
841
- else
842
- "*#{process(exp.shift)}"
843
- end
844
- end
845
-
846
- def process_str(exp)
847
- return exp.shift.dump
848
- end
849
-
850
- def process_super(exp)
851
- args = exp.shift
852
- args[0] = :arglist if args[0] == :array
853
- "super(#{process(args)})"
854
- end
855
-
856
- def process_svalue(exp)
857
- process(exp.shift)
858
- end
859
-
860
- def process_to_ary(exp)
861
- process(exp.shift)
862
- end
863
-
864
- def process_true(exp)
865
- "true"
866
- end
867
-
868
- def process_undef(exp)
869
- "undef #{process(exp.shift)}"
870
- end
871
-
872
- def process_until(exp)
873
- cond_loop(exp, 'until')
874
- end
875
-
876
- def process_valias(exp)
877
- "alias #{exp.shift} #{exp.shift}"
878
- end
879
-
880
- def process_when(exp)
881
- src = []
882
-
883
- if self.context[1] == :array then # ugh. matz! why not an argscat?!?
884
- val = process(exp.shift)
885
- exp.shift # empty body
886
- return "*#{val}"
887
- end
888
-
889
- until exp.empty?
890
- cond = process(exp.shift).to_s[1..-2]
891
- code = indent(process(exp.shift))
892
- code = indent "# do nothing" if code =~ /\A\s*\Z/
893
- src << "when #{cond} then\n#{code.chomp}"
894
- end
895
-
896
- src.join("\n")
897
- end
898
-
899
- def process_while(exp)
900
- cond_loop(exp, 'while')
901
- end
902
-
903
- def process_xstr(exp)
904
- "`#{process_str(exp)[1..-2]}`"
905
- end
906
-
907
- def process_yield(exp)
908
- args = exp.empty? ? nil : exp.shift
909
- if args then
910
- args[0] = :arglist if args.first == :array
911
- args = process(args)
912
- end
913
-
914
- # "yield" + (args ? "(#{args})" : "")
915
- if args then
916
- "yield(#{args})"
917
- else
918
- "yield"
919
- end
920
- end
921
-
922
- def process_zarray(exp)
923
- "[]"
924
- end
925
-
926
- def process_zsuper(exp)
927
- "super"
928
- end
929
-
930
- def cond_loop(exp, name)
931
- cond = process(exp.shift)
932
- body = process(exp.shift)
933
- head_controlled = exp.shift
934
-
935
- body = indent(body).chomp if body
936
-
937
- code = []
938
- if head_controlled then
939
- code << "#{name} #{cond} do"
940
- code << body if body
941
- code << "end"
942
- else
943
- code << "begin"
944
- code << body if body
945
- code << "end #{name} #{cond}"
946
- end
947
- code.join("\n")
948
- end
949
-
950
- ############################################################
951
- # Rewriters:
952
-
953
- def rewrite_rescue exp
954
- exp = s(:begin, exp) if
955
- context[1] == :block unless
956
- context[2] == :scope and [:defn, :defs].include? context[3]
957
- exp
958
- end
959
-
960
- ############################################################
961
- # Utility Methods:
962
-
963
- def util_dthing(exp, regx = false)
964
- s = []
965
- suck = true
966
- if suck then
967
- x = exp.shift.gsub(/"/, '\"').gsub(/\n/, '\n')
968
- else
969
- x = exp.shift.dump[1..-2]
970
- end
971
- x.gsub!(/\//, '\/') if regx
972
-
973
- s << x
974
- until exp.empty?
975
- pt = exp.shift
976
- case pt
977
- when Sexp then
978
- case pt.first
979
- when :str then
980
- if suck then
981
- x = pt.last.gsub(/"/, '\"').gsub(/\n/, '\n')
982
- else
983
- x = pt.last.dump[1..-2]
984
- end
985
- x.gsub!(/\//, '\/') if regx
986
- s << x
987
- else
988
- s << '#{' << process(pt) << '}' # do not use interpolation here
989
- end
990
- else
991
- # do nothing - yet
992
- end
993
- end
994
-
995
- s.join
996
- end
997
-
998
- def util_module_or_class(exp, is_class=false)
999
- s = "#{exp.shift}"
1000
-
1001
- if is_class then
1002
- superk = process(exp.shift)
1003
- s << " < #{superk}" if superk
1004
- end
1005
-
1006
- s << "\n"
1007
-
1008
- body = []
1009
- begin
1010
- code = process(exp.shift).chomp
1011
- body << code unless code.nil? or code.empty?
1012
- end until exp.empty?
1013
- unless body.empty? then
1014
- body = indent(body.join("\n\n")) + "\n"
1015
- else
1016
- body = ""
1017
- end
1018
- s + body + "end"
1019
- end
1020
-
1021
- def indent(s)
1022
- s.to_s.map{|line| @indent + line}.join
1023
- end
1024
- end
1025
-
1026
- RubyToRuby = Ruby2Ruby # For backwards compatibilty... TODO: remove 2008-03-28
1027
-
1028
- class Method
1029
- def with_class_and_method_name
1030
- if self.inspect =~ /<Method: (.*)\#(.*)>/ then
1031
- klass = eval $1
1032
- method = $2.intern
1033
- raise "Couldn't determine class from #{self.inspect}" if klass.nil?
1034
- return yield(klass, method)
1035
- else
1036
- raise "Can't parse signature: #{self.inspect}"
1037
- end
1038
- end
1039
-
1040
- def to_sexp
1041
- with_class_and_method_name do |klass, method|
1042
- ParseTree.new(false).parse_tree_for_method(klass, method)
1043
- end
1044
- end
1045
-
1046
- def to_ruby
1047
- Ruby2Ruby.new.process(self.to_sexp)
1048
- end
1049
- end
1050
-
1051
- class ProcStoreTmp
1052
- @@n = 0
1053
- def self.name
1054
- @@n += 1
1055
- return :"myproc#{@@n}"
1056
- end
1057
- end
1058
-
1059
- class UnboundMethod
1060
- def to_ruby
1061
- name = ProcStoreTmp.name
1062
- ProcStoreTmp.send(:define_method, name, self)
1063
- m = ProcStoreTmp.new.method(name)
1064
- result = m.to_ruby.sub(/def #{name}(?:\(([^\)]*)\))?/,
1065
- 'proc { |\1|').sub(/end\Z/, '}')
1066
- return result
1067
- end
1068
- end
1069
-
1070
- class Proc
1071
- def to_method
1072
- name = ProcStoreTmp.name
1073
- ProcStoreTmp.send(:define_method, name, self)
1074
- ProcStoreTmp.new.method(name)
1075
- end
1076
-
1077
- def to_sexp
1078
- body = self.to_method.to_sexp[2][1..-1]
1079
- [:proc, *body]
1080
- end
1081
-
1082
- def to_ruby
1083
- ruby = self.to_method.to_ruby
1084
- ruby.sub!(/\A(def \S+)\(([^\)]*)\)/, '\1 |\2|') # move args
1085
- ruby.sub!(/\Adef[^\n\|]+/, 'proc { ') # strip def name
1086
- ruby.sub!(/end\Z/, '}') # strip end
1087
- ruby.gsub!(/\s+$/, '') # trailing WS bugs me
1088
- ruby
1089
- end
1090
- end