ruby2js 1.15.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/ruby2js.rb +36 -36
- data/lib/ruby2js/converter.rb +59 -20
- data/lib/ruby2js/converter/arg.rb +1 -1
- data/lib/ruby2js/converter/args.rb +1 -1
- data/lib/ruby2js/converter/array.rb +3 -4
- data/lib/ruby2js/converter/begin.rb +15 -1
- data/lib/ruby2js/converter/block.rb +6 -5
- data/lib/ruby2js/converter/boolean.rb +1 -1
- data/lib/ruby2js/converter/break.rb +1 -1
- data/lib/ruby2js/converter/case.rb +27 -7
- data/lib/ruby2js/converter/casgn.rb +5 -2
- data/lib/ruby2js/converter/class.rb +41 -11
- data/lib/ruby2js/converter/const.rb +1 -1
- data/lib/ruby2js/converter/cvar.rb +4 -3
- data/lib/ruby2js/converter/cvasgn.rb +5 -6
- data/lib/ruby2js/converter/def.rb +15 -3
- data/lib/ruby2js/converter/defined.rb +1 -1
- data/lib/ruby2js/converter/defs.rb +7 -3
- data/lib/ruby2js/converter/dstr.rb +3 -3
- data/lib/ruby2js/converter/for.rb +7 -10
- data/lib/ruby2js/converter/hash.rb +70 -34
- data/lib/ruby2js/converter/if.rb +35 -13
- data/lib/ruby2js/converter/in.rb +1 -1
- data/lib/ruby2js/converter/ivasgn.rb +1 -1
- data/lib/ruby2js/converter/kwbegin.rb +20 -20
- data/lib/ruby2js/converter/literal.rb +1 -1
- data/lib/ruby2js/converter/logical.rb +4 -8
- data/lib/ruby2js/converter/next.rb +1 -1
- data/lib/ruby2js/converter/nil.rb +1 -1
- data/lib/ruby2js/converter/nthref.rb +1 -1
- data/lib/ruby2js/converter/opasgn.rb +3 -3
- data/lib/ruby2js/converter/regexp.rb +12 -9
- data/lib/ruby2js/converter/return.rb +3 -3
- data/lib/ruby2js/converter/self.rb +2 -2
- data/lib/ruby2js/converter/send.rb +31 -30
- data/lib/ruby2js/converter/super.rb +8 -11
- data/lib/ruby2js/converter/sym.rb +1 -1
- data/lib/ruby2js/converter/undef.rb +9 -2
- data/lib/ruby2js/converter/var.rb +1 -1
- data/lib/ruby2js/converter/vasgn.rb +13 -5
- data/lib/ruby2js/converter/while.rb +2 -1
- data/lib/ruby2js/converter/whilepost.rb +2 -1
- data/lib/ruby2js/converter/xstr.rb +4 -3
- data/lib/ruby2js/execjs.rb +3 -3
- data/lib/ruby2js/filter/camelCase.rb +8 -8
- data/lib/ruby2js/filter/functions.rb +64 -65
- data/lib/ruby2js/filter/react.rb +44 -16
- data/lib/ruby2js/filter/require.rb +4 -1
- data/lib/ruby2js/filter/underscore.rb +21 -21
- data/lib/ruby2js/serializer.rb +347 -0
- data/lib/ruby2js/version.rb +3 -3
- data/ruby2js.gemspec +3 -3
- metadata +3 -2
data/lib/ruby2js.rb
CHANGED
@@ -13,18 +13,40 @@ module Ruby2JS
|
|
13
13
|
def s(type, *args)
|
14
14
|
Parser::AST::Node.new type, args
|
15
15
|
end
|
16
|
+
|
17
|
+
def S(type, *args)
|
18
|
+
@ast.updated(type, args)
|
19
|
+
end
|
16
20
|
end
|
17
21
|
|
18
22
|
class Processor < Parser::AST::Processor
|
19
23
|
BINARY_OPERATORS = Converter::OPERATORS[2..-1].flatten
|
20
24
|
|
25
|
+
def initialize(comments)
|
26
|
+
@comments = comments
|
27
|
+
end
|
28
|
+
|
21
29
|
def options=(options)
|
22
30
|
@options = options
|
23
31
|
end
|
24
32
|
|
33
|
+
def process(node)
|
34
|
+
ast, @ast = @ast, node
|
35
|
+
replacement = super
|
36
|
+
|
37
|
+
if replacement != node and @comments[node]
|
38
|
+
@comments[replacement] = @comments[node]
|
39
|
+
end
|
40
|
+
|
41
|
+
replacement
|
42
|
+
ensure
|
43
|
+
@ast = ast
|
44
|
+
end
|
45
|
+
|
25
46
|
# handle all of the 'invented' ast types
|
26
47
|
def on_attr(node); on_send(node); end
|
27
48
|
def on_autoreturn(node); on_return(node); end
|
49
|
+
def on_call(node); on_send(node); end
|
28
50
|
def on_constructor(node); on_def(node); end
|
29
51
|
def on_defp(node); on_defs(node); end
|
30
52
|
def on_method(node); on_send(node); end
|
@@ -56,17 +78,19 @@ module Ruby2JS
|
|
56
78
|
end
|
57
79
|
|
58
80
|
def self.convert(source, options={})
|
59
|
-
|
60
81
|
if Proc === source
|
61
82
|
file,line = source.source_location
|
62
83
|
source = File.read(file.dup.untaint).untaint
|
63
|
-
ast =
|
64
|
-
|
84
|
+
ast, comments = parse(source)
|
85
|
+
comments = Parser::Source::Comment.associate(ast, comments) if ast
|
86
|
+
ast = find_block( ast, line )
|
87
|
+
options = options.merge(file => file) unless options[:file]
|
65
88
|
elsif Parser::AST::Node === source
|
66
|
-
ast = source
|
89
|
+
ast, comments = source, {}
|
67
90
|
source = ast.loc.expression.source_buffer.source
|
68
91
|
else
|
69
|
-
ast = parse( source, options[:file] )
|
92
|
+
ast, comments = parse( source, options[:file] )
|
93
|
+
comments = Parser::Source::Comment.associate(ast, comments) if ast
|
70
94
|
end
|
71
95
|
|
72
96
|
filters = options[:filters] || Filter::DEFAULTS
|
@@ -76,12 +100,12 @@ module Ruby2JS
|
|
76
100
|
filters.reverse.each do |mod|
|
77
101
|
filter = Class.new(filter) {include mod}
|
78
102
|
end
|
79
|
-
filter = filter.new
|
103
|
+
filter = filter.new(comments)
|
80
104
|
filter.options = options
|
81
105
|
ast = filter.process(ast)
|
82
106
|
end
|
83
107
|
|
84
|
-
ruby2js = Ruby2JS::Converter.new(
|
108
|
+
ruby2js = Ruby2JS::Converter.new(ast, comments)
|
85
109
|
|
86
110
|
ruby2js.binding = options[:binding]
|
87
111
|
ruby2js.ivars = options[:ivars]
|
@@ -96,44 +120,20 @@ module Ruby2JS
|
|
96
120
|
|
97
121
|
ruby2js.width = options[:width] if options[:width]
|
98
122
|
|
99
|
-
if source.include? "\n"
|
100
|
-
ruby2js.enable_vertical_whitespace
|
101
|
-
lines = ruby2js.to_js.split("\n")
|
102
|
-
pre = []
|
103
|
-
pending = false
|
104
|
-
blank = true
|
105
|
-
lines.each do |line|
|
106
|
-
next if line.empty?
|
107
|
-
|
108
|
-
if ')}]'.include? line[0]
|
109
|
-
pre.pop
|
110
|
-
line.sub!(/([,;])$/,"\\1\n")
|
111
|
-
pending = true
|
112
|
-
else
|
113
|
-
pending = false
|
114
|
-
end
|
123
|
+
ruby2js.enable_vertical_whitespace if source.include? "\n"
|
115
124
|
|
116
|
-
|
117
|
-
if '({['.include? line[-1]
|
118
|
-
pre.push ' '
|
119
|
-
line.insert 0, "\n" unless blank or pending
|
120
|
-
pending = true
|
121
|
-
end
|
125
|
+
ruby2js.convert
|
122
126
|
|
123
|
-
|
124
|
-
end
|
127
|
+
ruby2js.timestamp options[:file]
|
125
128
|
|
126
|
-
|
127
|
-
else
|
128
|
-
ruby2js.to_js
|
129
|
-
end
|
129
|
+
ruby2js
|
130
130
|
end
|
131
131
|
|
132
132
|
def self.parse(source, file=nil)
|
133
133
|
# workaround for https://github.com/whitequark/parser/issues/112
|
134
134
|
buffer = Parser::Source::Buffer.new(file || '__SOURCE__')
|
135
135
|
buffer.raw_source = source.encode('utf-8')
|
136
|
-
Parser::CurrentRuby.new.
|
136
|
+
Parser::CurrentRuby.new.parse_with_comments(buffer)
|
137
137
|
rescue Parser::SyntaxError => e
|
138
138
|
split = source[0..e.diagnostic.location.begin_pos].split("\n")
|
139
139
|
line, col = split.length, split.last.length
|
data/lib/ruby2js/converter.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
require 'parser/current'
|
2
2
|
|
3
|
+
require 'ruby2js/serializer'
|
4
|
+
|
3
5
|
module Ruby2JS
|
4
|
-
class Converter
|
6
|
+
class Converter < Serializer
|
7
|
+
attr_accessor :ast
|
8
|
+
|
5
9
|
LOGICAL = :and, :not, :or
|
6
10
|
OPERATORS = [:[], :[]=], [:not, :!], [:*, :/, :%], [:+, :-], [:>>, :<<],
|
7
11
|
[:&], [:^, :|], [:<=, :<, :>, :>=], [:==, :!=, :===, :"!=="], [:and, :or]
|
@@ -20,14 +24,13 @@ module Ruby2JS
|
|
20
24
|
|
21
25
|
attr_accessor :binding, :ivars
|
22
26
|
|
23
|
-
def initialize( ast, vars = {} )
|
24
|
-
|
25
|
-
|
26
|
-
@
|
27
|
-
@ws = ' '
|
27
|
+
def initialize( ast, comments, vars = {} )
|
28
|
+
super()
|
29
|
+
|
30
|
+
@ast, @comments, @vars = ast, comments, vars.dup
|
28
31
|
@varstack = []
|
32
|
+
@scope = true
|
29
33
|
@rbstack = []
|
30
|
-
@width = 80
|
31
34
|
@next_token = :return
|
32
35
|
|
33
36
|
@handlers = {}
|
@@ -35,12 +38,6 @@ module Ruby2JS
|
|
35
38
|
@handlers[name] = method("on_#{name}")
|
36
39
|
end
|
37
40
|
end
|
38
|
-
|
39
|
-
def enable_vertical_whitespace
|
40
|
-
@sep = ";\n"
|
41
|
-
@nl = "\n"
|
42
|
-
@ws = @nl
|
43
|
-
end
|
44
41
|
|
45
42
|
def binding=(binding)
|
46
43
|
@binding = binding
|
@@ -50,7 +47,7 @@ module Ruby2JS
|
|
50
47
|
@width = width
|
51
48
|
end
|
52
49
|
|
53
|
-
def
|
50
|
+
def convert
|
54
51
|
parse( @ast, :statement )
|
55
52
|
end
|
56
53
|
|
@@ -59,11 +56,14 @@ module Ruby2JS
|
|
59
56
|
end
|
60
57
|
|
61
58
|
def scope( ast, args=nil )
|
62
|
-
@
|
59
|
+
scope, @scope = @scope, true
|
60
|
+
@varstack.push @vars
|
63
61
|
@vars = args if args
|
62
|
+
@vars = Hash[@vars.map {|key, value| [key, true]}]
|
64
63
|
parse( ast, :statement )
|
65
64
|
ensure
|
66
65
|
@vars = @varstack.pop
|
66
|
+
@scope = scope
|
67
67
|
end
|
68
68
|
|
69
69
|
def s(type, *args)
|
@@ -78,22 +78,60 @@ module Ruby2JS
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
+
# extract comments that either precede or are included in the node.
|
82
|
+
# remove from the list this node may appear later in the tree.
|
83
|
+
def comments(ast)
|
84
|
+
if ast.loc and ast.loc.respond_to? :expression
|
85
|
+
expression = ast.loc.expression
|
86
|
+
|
87
|
+
list = @comments[ast].select do |comment|
|
88
|
+
expression.source_buffer == comment.loc.expression.source_buffer and
|
89
|
+
comment.loc.expression.begin_pos < expression.end_pos
|
90
|
+
end
|
91
|
+
else
|
92
|
+
list = @comments[ast]
|
93
|
+
end
|
94
|
+
|
95
|
+
@comments[ast] -= list
|
96
|
+
|
97
|
+
list.map do |comment|
|
98
|
+
comment.text.sub(/^#/, '//') + "\n"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
81
102
|
def parse(ast, state=:expression)
|
82
|
-
|
103
|
+
oldstate, @state = @state, state
|
104
|
+
oldast, @ast = @ast, ast
|
105
|
+
return unless ast
|
83
106
|
|
84
|
-
@state = state
|
85
|
-
@ast = ast
|
86
107
|
handler = @handlers[ast.type]
|
87
108
|
|
88
109
|
unless handler
|
89
110
|
raise NotImplementedError, "unknown AST type #{ ast.type }"
|
90
111
|
end
|
91
112
|
|
92
|
-
|
113
|
+
if state == :statement and not @comments[ast].empty?
|
114
|
+
comments(ast).each {|comment| puts comment.chomp}
|
115
|
+
end
|
116
|
+
|
117
|
+
handler.call(*ast.children)
|
118
|
+
ensure
|
119
|
+
@ast = oldast
|
120
|
+
end
|
121
|
+
|
122
|
+
def parse_all(*args)
|
123
|
+
options = (Hash === args.last) ? args.pop : {}
|
124
|
+
sep = options[:join].to_s
|
125
|
+
state = options[:state] || :expression
|
126
|
+
|
127
|
+
args.each_with_index do |arg, index|
|
128
|
+
put sep unless index == 0
|
129
|
+
parse arg, state
|
130
|
+
end
|
93
131
|
end
|
94
132
|
|
95
133
|
def group( ast )
|
96
|
-
|
134
|
+
put '('; parse ast; put ')'
|
97
135
|
end
|
98
136
|
end
|
99
137
|
end
|
@@ -103,6 +141,7 @@ module Parser
|
|
103
141
|
class Node
|
104
142
|
def is_method?
|
105
143
|
return false if type == :attr
|
144
|
+
return true if type == :call
|
106
145
|
return true unless loc
|
107
146
|
|
108
147
|
if loc.respond_to? :selector
|
@@ -21,11 +21,10 @@ module Ruby2JS
|
|
21
21
|
:concat, s(:array, *items[splat+1..-1]))
|
22
22
|
end
|
23
23
|
else
|
24
|
-
items.
|
25
|
-
|
26
|
-
"[#{ items.join(', ') }]"
|
24
|
+
if items.length <= 1
|
25
|
+
put '['; parse_all *items, join: ', '; put ']'
|
27
26
|
else
|
28
|
-
|
27
|
+
compact { puts '['; parse_all *items, join: ",#{@ws}"; sput ']' }
|
29
28
|
end
|
30
29
|
end
|
31
30
|
end
|
@@ -28,7 +28,7 @@ module Ruby2JS
|
|
28
28
|
statements.compact!
|
29
29
|
end
|
30
30
|
|
31
|
-
statements
|
31
|
+
parse_all *statements, state: state, join: @sep
|
32
32
|
end
|
33
33
|
|
34
34
|
def combine_properties(body)
|
@@ -36,7 +36,21 @@ module Ruby2JS
|
|
36
36
|
next unless body[i] and body[i].type == :prop
|
37
37
|
for j in i+1...body.length
|
38
38
|
break unless body[j] and body[j].type == :prop
|
39
|
+
|
39
40
|
if body[i].children[0] == body[j].children[0]
|
41
|
+
# relocate property comment to first method
|
42
|
+
[body[i], body[j]].each do |node|
|
43
|
+
unless @comments[node].empty?
|
44
|
+
node.children[1].values.first.each do |key, value|
|
45
|
+
if [:get, :set].include? key and Parser::AST::Node === value
|
46
|
+
@comments[value] = @comments[node]
|
47
|
+
break
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# merge properties
|
40
54
|
merge = Hash[(body[i].children[1].to_a+body[j].children[1].to_a).
|
41
55
|
group_by {|name, value| name.to_s}.map {|name, values|
|
42
56
|
[name, values.map(&:last).reduce(:merge)]}]
|
@@ -17,13 +17,14 @@ module Ruby2JS
|
|
17
17
|
var = args.children.first
|
18
18
|
expression = call.children.first.children.first
|
19
19
|
comp = (expression.type == :irange ? '<=' : '<')
|
20
|
-
"for (var
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
put "for (var "; parse var; put " = "; parse expression.children.first
|
21
|
+
put "; "; parse var; put " #{comp} "; parse expression.children.last
|
22
|
+
put "; "; parse var; put " += "; parse call.children[2]; puts ") {"
|
23
|
+
scope block
|
24
|
+
sput "}"
|
24
25
|
else
|
25
26
|
block ||= s(:begin)
|
26
|
-
function =
|
27
|
+
function = @ast.updated(:def, [nil, args, block])
|
27
28
|
parse s(:send, *call.children, function)
|
28
29
|
end
|
29
30
|
end
|
@@ -9,15 +9,35 @@ module Ruby2JS
|
|
9
9
|
# (...))
|
10
10
|
|
11
11
|
handle :case do |expr, *whens, other|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
begin
|
13
|
+
scope, @scope = @scope, false
|
14
|
+
mark = output_location
|
15
|
+
|
16
|
+
put 'switch ('; parse expr; puts ') {'
|
17
|
+
|
18
|
+
whens.each_with_index do |node, index|
|
19
|
+
puts '' unless index == 0
|
17
20
|
|
18
|
-
|
21
|
+
*values, code = node.children
|
22
|
+
values.each {|value| put 'case '; parse value; put ":#@ws"}
|
23
|
+
parse code, :statement
|
24
|
+
put "#{@sep}break#@sep" if other or index < whens.length-1
|
25
|
+
end
|
19
26
|
|
20
|
-
|
27
|
+
(put "#{@nl}default:#@ws"; parse other, :statement) if other
|
28
|
+
|
29
|
+
sput '}'
|
30
|
+
|
31
|
+
if scope
|
32
|
+
vars = @vars.select {|key, value| value == :pending}.keys
|
33
|
+
unless vars.empty?
|
34
|
+
insert mark, "var #{vars.join(', ')}#{@sep}"
|
35
|
+
vars.each {|var| @vars[var] = true}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
ensure
|
39
|
+
@scope = scope
|
40
|
+
end
|
21
41
|
end
|
22
42
|
end
|
23
43
|
end
|
@@ -6,8 +6,11 @@ module Ruby2JS
|
|
6
6
|
|
7
7
|
handle :casgn do |cbase, var, value|
|
8
8
|
begin
|
9
|
-
|
10
|
-
|
9
|
+
put "var "
|
10
|
+
|
11
|
+
(parse cbase; put '.') if cbase
|
12
|
+
|
13
|
+
put "#{ var } = "; parse value
|
11
14
|
ensure
|
12
15
|
@vars[var] = true
|
13
16
|
end
|
@@ -12,7 +12,7 @@ module Ruby2JS
|
|
12
12
|
if inheritance
|
13
13
|
init = s(:def, :initialize, s(:args), s(:super))
|
14
14
|
else
|
15
|
-
init = s(:def, :initialize, s(:args))
|
15
|
+
init = s(:def, :initialize, s(:args), nil)
|
16
16
|
end
|
17
17
|
|
18
18
|
body.compact!
|
@@ -24,7 +24,7 @@ module Ruby2JS
|
|
24
24
|
body.compact!
|
25
25
|
visible = {}
|
26
26
|
body.map! do |m|
|
27
|
-
if m.type == :def
|
27
|
+
node = if m.type == :def
|
28
28
|
if m.children.first == :initialize
|
29
29
|
# constructor: remove from body and overwrite init function
|
30
30
|
init = m
|
@@ -43,7 +43,7 @@ module Ruby2JS
|
|
43
43
|
s(:prop, s(:attr, name, :prototype), m.children.first =>
|
44
44
|
{enumerable: s(:true), configurable: s(:true),
|
45
45
|
get: s(:block, s(:send, nil, :proc), m.children[1],
|
46
|
-
|
46
|
+
m.updated(:autoreturn, m.children[2..-1]))})
|
47
47
|
else
|
48
48
|
# method: add to prototype
|
49
49
|
s(:method, s(:attr, name, :prototype),
|
@@ -66,7 +66,7 @@ module Ruby2JS
|
|
66
66
|
s(:prop, name, m.children[1].to_s =>
|
67
67
|
{enumerable: s(:true), configurable: s(:true),
|
68
68
|
get: s(:block, s(:send, nil, :proc), m.children[2],
|
69
|
-
|
69
|
+
m.updated(:autoreturn, m.children[3..-1]))})
|
70
70
|
else
|
71
71
|
# class method definition: add to prototype
|
72
72
|
s(:prototype, s(:send, name, "#{m.children[1]}=",
|
@@ -134,6 +134,19 @@ module Ruby2JS
|
|
134
134
|
else
|
135
135
|
raise NotImplementedError, "class #{ m.type }"
|
136
136
|
end
|
137
|
+
|
138
|
+
# associate comments
|
139
|
+
if node and @comments[m]
|
140
|
+
if Array === node
|
141
|
+
node[0] = m.updated(node.first.type, node.first.children)
|
142
|
+
@comments[node.first] = @comments[m]
|
143
|
+
else
|
144
|
+
node = m.updated(node.type, node.children)
|
145
|
+
@comments[node] = @comments[m]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
node
|
137
150
|
end
|
138
151
|
|
139
152
|
body.flatten!
|
@@ -167,12 +180,23 @@ module Ruby2JS
|
|
167
180
|
if methods > 1 or (methods == 1 and body[start].type == :prop)
|
168
181
|
pairs = body[start...start+methods].map do |node|
|
169
182
|
if node.type == :method
|
170
|
-
|
171
|
-
node.children[
|
183
|
+
replacement = node.updated(:pair, [
|
184
|
+
s(:str, node.children[1].to_s.chomp('=')),
|
185
|
+
node.children[2]])
|
172
186
|
else
|
173
|
-
node.children[1].map
|
174
|
-
|
187
|
+
replacement = node.children[1].map do |prop, descriptor|
|
188
|
+
node.updated(:pair, [s(:prop, prop), descriptor])
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
if @comments[node]
|
193
|
+
if Array === replacement
|
194
|
+
@comments[replacement.first] = @comments[node]
|
195
|
+
else
|
196
|
+
@comments[replacement] = @comments[node]
|
197
|
+
end
|
175
198
|
end
|
199
|
+
replacement
|
176
200
|
end
|
177
201
|
body[start...start+methods] =
|
178
202
|
s(:send, name, :prototype=, s(:hash, *pairs.flatten))
|
@@ -180,7 +204,9 @@ module Ruby2JS
|
|
180
204
|
end
|
181
205
|
|
182
206
|
# prepend constructor
|
183
|
-
|
207
|
+
constructor = init.updated(:constructor, [name, *init.children[1..-1]])
|
208
|
+
@comments[constructor] = @comments[init] unless @comments[init].empty?
|
209
|
+
body.unshift constructor
|
184
210
|
|
185
211
|
begin
|
186
212
|
# save class name
|
@@ -193,7 +219,7 @@ module Ruby2JS
|
|
193
219
|
# add locally visible interfaces to rbstack. See send.rb, const.rb
|
194
220
|
@rbstack.push visible
|
195
221
|
|
196
|
-
parse s(:begin, *body.compact)
|
222
|
+
parse s(:begin, *body.compact), :statement
|
197
223
|
ensure
|
198
224
|
self.ivars = ivars
|
199
225
|
@class_name = class_name
|
@@ -224,8 +250,12 @@ module Ruby2JS
|
|
224
250
|
end
|
225
251
|
elsif @ast.type == :method
|
226
252
|
parse s(:send, *args)
|
253
|
+
elsif args.first.children.first
|
254
|
+
parse s(:send, args.first.children.first,
|
255
|
+
"#{args.first.children[1]}=", s(:block, s(:send, nil, :proc),
|
256
|
+
*args[1..-1]))
|
227
257
|
else
|
228
|
-
parse s(:def, *args)
|
258
|
+
parse s(:def, args.first.children[1], *args[1..-1])
|
229
259
|
end
|
230
260
|
ensure
|
231
261
|
@instance_method = instance_method
|