opal 0.3.19 → 0.3.20
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -1
- data/Gemfile +3 -2
- data/README.md +304 -48
- data/Rakefile +1 -2
- data/core/alpha.rb +2 -1
- data/core/array.rb +92 -96
- data/core/basic_object.rb +1 -10
- data/core/boolean.rb +6 -18
- data/core/class.rb +9 -10
- data/core/comparable.rb +1 -1
- data/core/enumerable.rb +11 -11
- data/core/enumerator.rb +2 -10
- data/core/error.rb +16 -31
- data/core/hash.rb +32 -36
- data/core/json.rb +50 -0
- data/core/kernel.rb +48 -57
- data/core/load_order +3 -5
- data/core/module.rb +37 -35
- data/core/nil_class.rb +4 -0
- data/core/numeric.rb +10 -30
- data/core/proc.rb +1 -1
- data/core/range.rb +3 -4
- data/core/regexp.rb +21 -6
- data/core/runtime.js +278 -370
- data/core/string.rb +21 -37
- data/core/struct.rb +11 -3
- data/core/time.rb +44 -37
- data/lib/opal.rb +3 -3
- data/lib/opal/builder.rb +48 -27
- data/lib/opal/builder_task.rb +3 -20
- data/lib/opal/grammar.rb +18 -13
- data/lib/opal/grammar.y +7 -4
- data/lib/opal/parser.rb +290 -199
- data/lib/opal/scope.rb +187 -176
- data/lib/opal/version.rb +1 -1
- data/test/core/kernel/define_singleton_method_spec.rb +21 -0
- data/test/core/time/at_spec.rb +7 -0
- data/test/core/time/day_spec.rb +5 -0
- data/test/core/time/friday_spec.rb +9 -0
- data/test/core/time/hour_spec.rb +5 -0
- data/test/core/time/min_spec.rb +5 -0
- data/test/core/time/monday_spec.rb +9 -0
- data/test/core/time/month_spec.rb +5 -0
- data/test/core/time/now_spec.rb +5 -0
- data/test/core/time/saturday_spec.rb +9 -0
- data/test/index.html +2 -1
- data/test/language/singleton_class_spec.rb +0 -16
- data/test/opal/array/to_json_spec.rb +7 -0
- data/test/opal/boolean/singleton_class_spec.rb +9 -0
- data/test/opal/boolean/to_json_spec.rb +9 -0
- data/test/opal/hash/to_json_spec.rb +9 -0
- data/test/opal/json/parse_spec.rb +31 -0
- data/test/opal/kernel/to_json_spec.rb +5 -0
- data/test/opal/nil/to_json_spec.rb +5 -0
- data/test/opal/numeric/to_json_spec.rb +6 -0
- data/test/opal/runtime/call_spec.rb +16 -0
- data/test/opal/runtime/defined_spec.rb +11 -0
- data/test/opal/runtime/super_spec.rb +16 -0
- data/test/opal/string/to_json_spec.rb +6 -0
- data/test/spec_helper.rb +1 -3
- metadata +48 -15
- data/core/dir.rb +0 -89
- data/core/file.rb +0 -85
- data/core/match_data.rb +0 -35
- data/core/rational.rb +0 -16
- data/test/core/file/expand_path_spec.rb +0 -20
data/lib/opal/builder_task.rb
CHANGED
@@ -4,8 +4,7 @@ module Opal
|
|
4
4
|
class BuilderTask
|
5
5
|
include Rake::DSL if defined? Rake::DSL
|
6
6
|
|
7
|
-
attr_accessor :name, :build_dir, :specs_dir, :files, :dependencies
|
8
|
-
:main, :specs_main
|
7
|
+
attr_accessor :name, :build_dir, :specs_dir, :files, :dependencies
|
9
8
|
|
10
9
|
def initialize(namespace = nil)
|
11
10
|
@project_dir = Dir.getwd
|
@@ -16,7 +15,6 @@ module Opal
|
|
16
15
|
@files = Dir['lib/**/*.{rb,js}']
|
17
16
|
@dependencies = []
|
18
17
|
@debug_mode = false
|
19
|
-
@spec_main = "spec/spec_helper"
|
20
18
|
|
21
19
|
yield self if block_given?
|
22
20
|
|
@@ -29,9 +27,7 @@ module Opal
|
|
29
27
|
:build_dir => @build_dir,
|
30
28
|
:specs_dir => @specs_dir,
|
31
29
|
:files => @files,
|
32
|
-
:dependencies => @dependencies
|
33
|
-
:main => get_main,
|
34
|
-
:specs_main => @specs_main
|
30
|
+
:dependencies => @dependencies
|
35
31
|
}
|
36
32
|
end
|
37
33
|
|
@@ -51,30 +47,17 @@ module Opal
|
|
51
47
|
Builder.build opts
|
52
48
|
end
|
53
49
|
|
54
|
-
def get_main
|
55
|
-
return @main if @main
|
56
|
-
|
57
|
-
unless @files.empty?
|
58
|
-
f = @files.first
|
59
|
-
return f.chomp(File.extname(f))
|
60
|
-
end
|
61
|
-
|
62
|
-
nil
|
63
|
-
end
|
64
|
-
|
65
50
|
def define_tasks
|
66
51
|
define_task :build, "Build Opal Project" do
|
67
52
|
name = @debug_mode ? "#@name.debug.js" : "#@name.js"
|
68
53
|
build_files :files => @files,
|
69
|
-
:out => File.join(@build_dir, "#@name.js")
|
70
|
-
:main => get_main
|
54
|
+
:out => File.join(@build_dir, "#@name.js")
|
71
55
|
end
|
72
56
|
|
73
57
|
define_task :spec, "Build Specs" do
|
74
58
|
name = @debug_mode ? "#@name.specs.debug.js" : "#@name.specs.js"
|
75
59
|
build_files :files => @specs_dir,
|
76
60
|
:out => File.join(@build_dir, name),
|
77
|
-
:main => @specs_main,
|
78
61
|
:debug => @debug_mode
|
79
62
|
end
|
80
63
|
|
data/lib/opal/grammar.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
# DO NOT MODIFY!!!!
|
3
|
-
# This file is automatically generated by Racc 1.4.
|
3
|
+
# This file is automatically generated by Racc 1.4.8
|
4
4
|
# from Racc grammer file "".
|
5
5
|
#
|
6
6
|
|
@@ -710,7 +710,7 @@ clist = [
|
|
710
710
|
',118,136,134,133,129,130,125,123,116,142,117,459,403,141,,460,,,,,,',
|
711
711
|
',137,138,,135,119,120,121,143,124,126,,,122,,,,,139,140,127,128,,,,',
|
712
712
|
',257,,,,,,,132,131,,118,136,134,133,129,130,125,123,116,142,117,,,141' ]
|
713
|
-
racc_action_table = arr = Array.new(21316, nil)
|
713
|
+
racc_action_table = arr = ::Array.new(21316, nil)
|
714
714
|
idx = 0
|
715
715
|
clist.each do |str|
|
716
716
|
str.split(',', -1).each do |i|
|
@@ -1480,7 +1480,7 @@ clist = [
|
|
1480
1480
|
'416,416,416,416,416,416,416,416,416,665,665,416,,665,,,,,,,,665,665',
|
1481
1481
|
',665,665,665,665,665,665,665,,,665,,,,,665,665,665,665,,,,,,665,,,,',
|
1482
1482
|
',,665,665,,665,665,665,665,665,665,665,665,665,665,665,,,665' ]
|
1483
|
-
racc_action_check = arr = Array.new(21316, nil)
|
1483
|
+
racc_action_check = arr = ::Array.new(21316, nil)
|
1484
1484
|
idx = 0
|
1485
1485
|
clist.each do |str|
|
1486
1486
|
str.split(',', -1).each do |i|
|
@@ -1730,7 +1730,7 @@ clist = [
|
|
1730
1730
|
',,,788,,,,792,815,,,777,,,,,,,,,,,,,,,,,,,,,,239,,,,,,,,,635,,,,,,,',
|
1731
1731
|
',,,239,,,,,,,,,635,,,,,,,,,,,,,,239,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',
|
1732
1732
|
',,725,,,,,,,,,,,297,,,,,,,,,,,,,,,,,,725' ]
|
1733
|
-
racc_goto_table = arr = Array.new(2089, nil)
|
1733
|
+
racc_goto_table = arr = ::Array.new(2089, nil)
|
1734
1734
|
idx = 0
|
1735
1735
|
clist.each do |str|
|
1736
1736
|
str.split(',', -1).each do |i|
|
@@ -1794,7 +1794,7 @@ clist = [
|
|
1794
1794
|
',,,,,,,,,,9,9,,,,,26,,,,9,,,,9,23,,,26,,,,,,,,,,,,,,,,,,,,,,26,,,,,',
|
1795
1795
|
',,,23,,,,,,,,,,,26,,,,,,,,,23,,,,,,,,,,,,,,26,,,,,,,,,,,,,,,,,,,,,,',
|
1796
1796
|
',,,,,,,,,,,,9,,,,,,,,,,,9,,,,,,,,,,,,,,,,,,9' ]
|
1797
|
-
racc_goto_check = arr = Array.new(2089, nil)
|
1797
|
+
racc_goto_check = arr = ::Array.new(2089, nil)
|
1798
1798
|
idx = 0
|
1799
1799
|
clist.each do |str|
|
1800
1800
|
str.split(',', -1).each do |i|
|
@@ -2183,8 +2183,8 @@ racc_reduce_table = [
|
|
2183
2183
|
2, 207, :_reduce_344,
|
2184
2184
|
4, 207, :_reduce_345,
|
2185
2185
|
3, 207, :_reduce_346,
|
2186
|
-
4, 207, :
|
2187
|
-
3, 207, :
|
2186
|
+
4, 207, :_reduce_347,
|
2187
|
+
3, 207, :_reduce_348,
|
2188
2188
|
2, 207, :_reduce_349,
|
2189
2189
|
1, 207, :_reduce_350,
|
2190
2190
|
0, 248, :_reduce_351,
|
@@ -3635,10 +3635,7 @@ def _reduce_214(val, _values, result)
|
|
3635
3635
|
end
|
3636
3636
|
|
3637
3637
|
def _reduce_215(val, _values, result)
|
3638
|
-
result = s(:array, val[0])
|
3639
|
-
#result.line = val[0].line
|
3640
|
-
# FIXME:
|
3641
|
-
result = s(:array)
|
3638
|
+
result = s(:array, s(:hash, *val[0]))
|
3642
3639
|
|
3643
3640
|
result
|
3644
3641
|
end
|
@@ -4321,9 +4318,17 @@ def _reduce_346(val, _values, result)
|
|
4321
4318
|
result
|
4322
4319
|
end
|
4323
4320
|
|
4324
|
-
|
4321
|
+
def _reduce_347(val, _values, result)
|
4322
|
+
result = new_call val[0], val[2].intern, val[3]
|
4323
|
+
|
4324
|
+
result
|
4325
|
+
end
|
4325
4326
|
|
4326
|
-
|
4327
|
+
def _reduce_348(val, _values, result)
|
4328
|
+
result = new_call val[0], val[2].intern, s(:arglist)
|
4329
|
+
|
4330
|
+
result
|
4331
|
+
end
|
4327
4332
|
|
4328
4333
|
def _reduce_349(val, _values, result)
|
4329
4334
|
result = new_super val[1]
|
data/lib/opal/grammar.y
CHANGED
@@ -590,10 +590,7 @@ aref_args:
|
|
590
590
|
}
|
591
591
|
| assocs trailer
|
592
592
|
{
|
593
|
-
result = s(:array, val[0])
|
594
|
-
#result.line = val[0].line
|
595
|
-
# FIXME:
|
596
|
-
result = s(:array)
|
593
|
+
result = s(:array, s(:hash, *val[0]))
|
597
594
|
}
|
598
595
|
|
599
596
|
paren_args:
|
@@ -1100,7 +1097,13 @@ method_call:
|
|
1100
1097
|
result = new_call val[0], :call, val[2]
|
1101
1098
|
}
|
1102
1099
|
| primary_value '::' operation2 paren_args
|
1100
|
+
{
|
1101
|
+
result = new_call val[0], val[2].intern, val[3]
|
1102
|
+
}
|
1103
1103
|
| primary_value '::' operation3
|
1104
|
+
{
|
1105
|
+
result = new_call val[0], val[2].intern, s(:arglist)
|
1106
|
+
}
|
1104
1107
|
| SUPER paren_args
|
1105
1108
|
{
|
1106
1109
|
result = new_super val[1]
|
data/lib/opal/parser.rb
CHANGED
@@ -55,50 +55,20 @@ module Opal
|
|
55
55
|
|
56
56
|
STATEMENTS = [:xstr, :dxstr]
|
57
57
|
|
58
|
-
DEBUG_CODE = <<-CODE
|
59
|
-
var __const_get = function(const_table, id) {
|
60
|
-
if (const_table && const_table[id]) {
|
61
|
-
return const_table[id];
|
62
|
-
}
|
63
|
-
|
64
|
-
throw new Error('uninitialized constant ' + id);
|
65
|
-
};
|
66
|
-
|
67
|
-
var __send = function(recv, mid, jsid, block) {
|
68
|
-
var args = Array.prototype.slice.call(arguments, 4);
|
69
|
-
|
70
|
-
if (recv == null) {
|
71
|
-
throw new Error("cannot send '" + mid + "' to null");
|
72
|
-
}
|
73
|
-
|
74
|
-
var func = recv[jsid];
|
75
|
-
|
76
|
-
if (!func) {
|
77
|
-
throw new Error(recv + " does not respond to '" + mid + "'");
|
78
|
-
}
|
79
|
-
|
80
|
-
func._p = block;
|
81
|
-
|
82
|
-
return func.apply(recv, args);
|
83
|
-
};
|
84
|
-
|
85
|
-
var __send_splat = function(recv, mid, jsid, block, splat) {
|
86
|
-
return __send.apply(null, [recv, mid, jsid, block].concat(splat));
|
87
|
-
};
|
88
|
-
CODE
|
89
|
-
|
90
58
|
attr_reader :grammar
|
91
59
|
|
60
|
+
attr_reader :requires
|
61
|
+
|
92
62
|
def self.parse(str)
|
93
63
|
self.new.parse str
|
94
64
|
end
|
95
65
|
|
96
66
|
def initialize(opts = {})
|
97
|
-
@debug = opts[:debug] or false
|
98
67
|
end
|
99
68
|
|
100
69
|
def parse(source, file = '(file)')
|
101
70
|
@file = file
|
71
|
+
@requires = []
|
102
72
|
@helpers = {
|
103
73
|
:breaker => true,
|
104
74
|
:slice => true
|
@@ -109,8 +79,12 @@ module Opal
|
|
109
79
|
top @grammar.parse(source, file)
|
110
80
|
end
|
111
81
|
|
112
|
-
def
|
113
|
-
|
82
|
+
def warn(msg)
|
83
|
+
puts "#{msg} :#{@file}:#{@line}"
|
84
|
+
end
|
85
|
+
|
86
|
+
def error(msg)
|
87
|
+
raise "#{msg} :#{@file}:#{@line}"
|
114
88
|
end
|
115
89
|
|
116
90
|
def parser_indent
|
@@ -152,8 +126,10 @@ module Opal
|
|
152
126
|
}
|
153
127
|
|
154
128
|
vars << "__opal = Opal"
|
129
|
+
vars << "self = __opal.top"
|
155
130
|
vars << "__scope = __opal"
|
156
131
|
vars << "nil = __opal.nil"
|
132
|
+
vars << "def = #{current_self}._klass.prototype" if @scope.defines_defn
|
157
133
|
vars.concat @helpers.keys.map { |h| "__#{h} = __opal.#{h}" }
|
158
134
|
|
159
135
|
code = "var #{vars.join ', '};\n" + @scope.to_vars + "\n" + code
|
@@ -162,10 +138,9 @@ module Opal
|
|
162
138
|
pre = "function() {\n"
|
163
139
|
post = ""
|
164
140
|
|
165
|
-
pre += DEBUG_CODE if @debug
|
166
141
|
uniques = []
|
167
142
|
|
168
|
-
@unique.times { |i| uniques << "TMP_#{i+1}" }
|
143
|
+
# @unique.times { |i| uniques << "TMP_#{i+1}" }
|
169
144
|
|
170
145
|
unless uniques.empty?
|
171
146
|
post += ";var #{uniques.join ', '};"
|
@@ -189,8 +164,17 @@ module Opal
|
|
189
164
|
def indent(&block)
|
190
165
|
indent = @indent
|
191
166
|
@indent += INDENT
|
167
|
+
@space = "\n#@indent"
|
192
168
|
res = yield
|
193
169
|
@indent = indent
|
170
|
+
@space = "\n#@indent"
|
171
|
+
res
|
172
|
+
end
|
173
|
+
|
174
|
+
def with_temp(&block)
|
175
|
+
tmp = @scope.new_temp
|
176
|
+
res = yield tmp
|
177
|
+
@scope.queue_temp tmp
|
194
178
|
res
|
195
179
|
end
|
196
180
|
|
@@ -220,6 +204,8 @@ module Opal
|
|
220
204
|
meth = "process_#{type}"
|
221
205
|
raise "Unsupported sexp: #{type}" unless respond_to? meth
|
222
206
|
|
207
|
+
@line = sexp.line
|
208
|
+
|
223
209
|
__send__ meth, sexp, level
|
224
210
|
end
|
225
211
|
|
@@ -229,6 +215,9 @@ module Opal
|
|
229
215
|
case sexp.first
|
230
216
|
when :break, :next
|
231
217
|
sexp
|
218
|
+
when :yield
|
219
|
+
sexp[0] = :returnable_yield
|
220
|
+
sexp
|
232
221
|
when :scope
|
233
222
|
sexp
|
234
223
|
when :block
|
@@ -281,7 +270,7 @@ module Opal
|
|
281
270
|
result << (expr ? "#{code};" : code)
|
282
271
|
end
|
283
272
|
|
284
|
-
result.join "\n#@indent"
|
273
|
+
result.join(@scope.class_scope? ? "\n\n#@indent" : "\n#@indent")
|
285
274
|
end
|
286
275
|
|
287
276
|
def process_scope(sexp, level)
|
@@ -310,16 +299,15 @@ module Opal
|
|
310
299
|
meth, recv, arg = sexp
|
311
300
|
mid = mid_to_jsid meth.to_s
|
312
301
|
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
@scope.queue_temp a
|
319
|
-
@scope.queue_temp b
|
302
|
+
with_temp do |a|
|
303
|
+
with_temp do |b|
|
304
|
+
l = process recv, :expr
|
305
|
+
r = process arg, :expr
|
320
306
|
|
321
|
-
|
322
|
-
|
307
|
+
"(%s = %s, %s = %s, typeof(%s) === 'number' ? %s %s %s : %s.%s(%s))" %
|
308
|
+
[a, l, b, r, a, a, meth.to_s, b, a, mid, b]
|
309
|
+
end
|
310
|
+
end
|
323
311
|
end
|
324
312
|
|
325
313
|
def js_block_given(sexp, level)
|
@@ -327,6 +315,13 @@ module Opal
|
|
327
315
|
"(#{@scope.block_name} !== nil)"
|
328
316
|
end
|
329
317
|
|
318
|
+
def handle_block_given(sexp, reverse = false)
|
319
|
+
@scope.uses_block!
|
320
|
+
name = @scope.block_name
|
321
|
+
|
322
|
+
reverse ? "#{ name } === nil" : "#{ name } !== nil"
|
323
|
+
end
|
324
|
+
|
330
325
|
# s(:lit, 1)
|
331
326
|
# s(:lit, :foo)
|
332
327
|
def process_lit(sexp, level)
|
@@ -398,8 +393,10 @@ module Opal
|
|
398
393
|
"false".inspect
|
399
394
|
when :call
|
400
395
|
mid = mid_to_jsid part[2].to_s
|
401
|
-
recv = part[1] ? process(part[1], :expr) :
|
396
|
+
recv = part[1] ? process(part[1], :expr) : current_self
|
402
397
|
"(#{recv}.#{mid} ? 'method' : nil)"
|
398
|
+
when :xstr
|
399
|
+
"(typeof(#{process part, :expression}) !== 'undefined')"
|
403
400
|
else
|
404
401
|
raise "bad defined? part: #{part[0]}"
|
405
402
|
end
|
@@ -457,29 +454,38 @@ module Opal
|
|
457
454
|
end
|
458
455
|
|
459
456
|
if block_arg
|
460
|
-
@scope.
|
461
|
-
|
457
|
+
@scope.block_name = block_arg
|
458
|
+
@scope.add_temp block_arg
|
459
|
+
@scope.add_temp '__context'
|
460
|
+
scope_name = @scope.identify!
|
461
|
+
# @scope.add_arg block_arg
|
462
|
+
# code += "var #{block_arg} = _$ || nil, $context = #{block_arg}.$S;"
|
463
|
+
blk = "\n%s%s = %s._p || nil, __context = %s._s, %s.p = null;\n%s" %
|
464
|
+
[@indent, block_arg, scope_name, block_arg, scope_name, @indent]
|
465
|
+
|
466
|
+
code = blk + code
|
462
467
|
end
|
463
468
|
|
464
469
|
code += "\n#@indent" + process(body, :stmt)
|
465
470
|
|
471
|
+
if @scope.defines_defn
|
472
|
+
@scope.add_temp 'def = (this._isObject ? this._klass.prototype : this.prototype)'
|
473
|
+
end
|
474
|
+
|
466
475
|
code = "\n#@indent#{@scope.to_vars}\n#@indent#{code}"
|
467
476
|
|
468
477
|
scope_name = @scope.identity
|
469
478
|
end
|
470
479
|
end
|
471
480
|
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
itercode = "#{scope_name} = #{itercode}" if scope_name
|
481
|
+
with_temp do |tmp|
|
482
|
+
itercode = "function(#{params.join ', '}) {\n#{code}\n#@indent}"
|
483
|
+
itercode = "#{scope_name} = #{itercode}" if scope_name
|
476
484
|
|
477
|
-
|
485
|
+
call << ("(%s = %s, %s._s = %s, %s)" % [tmp, itercode, tmp, current_self, tmp])
|
478
486
|
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
res
|
487
|
+
process call, level
|
488
|
+
end
|
483
489
|
end
|
484
490
|
|
485
491
|
def js_block_args(sexp)
|
@@ -518,23 +524,33 @@ module Opal
|
|
518
524
|
out = []
|
519
525
|
|
520
526
|
attrs.each do |attr|
|
521
|
-
|
527
|
+
mid = attr[1]
|
528
|
+
ivar = "@#{mid}".intern
|
529
|
+
pre = @scope.proto
|
522
530
|
|
523
531
|
unless meth == :attr_writer
|
524
|
-
|
525
|
-
check = "this.#{ivar} == null ? nil : this.#{ivar}"
|
526
|
-
out << "def.#{attr} = function() { return #{check}; }"
|
532
|
+
out << process(s(:defn, mid, s(:args), s(:scope, s(:ivar, ivar))), :stmt)
|
527
533
|
end
|
528
534
|
|
529
535
|
unless meth == :attr_reader
|
530
|
-
|
531
|
-
out <<
|
536
|
+
mid = "#{mid}=".intern
|
537
|
+
out << process(s(:defn, mid, s(:args, :val), s(:scope,
|
538
|
+
s(:iasgn, ivar, s(:lvar, :val)))), :stmt)
|
532
539
|
end
|
533
540
|
end
|
534
541
|
|
535
542
|
out.join ", \n#@indent"
|
536
543
|
end
|
537
544
|
|
545
|
+
def handle_alias_native(sexp)
|
546
|
+
args = sexp[2]
|
547
|
+
meth = mid_to_jsid args[1][1].to_s
|
548
|
+
func = args[2][1]
|
549
|
+
|
550
|
+
@scope.methods << meth
|
551
|
+
"%s.%s = %s.%s" % [@scope.proto, meth, @scope.proto, func]
|
552
|
+
end
|
553
|
+
|
538
554
|
# s(:call, recv, :mid, s(:arglist))
|
539
555
|
# s(:call, nil, :mid, s(:arglist))
|
540
556
|
def process_call(sexp, level)
|
@@ -549,16 +565,19 @@ module Opal
|
|
549
565
|
end
|
550
566
|
when :block_given?
|
551
567
|
return js_block_given(sexp, level)
|
568
|
+
when :alias_native
|
569
|
+
return handle_alias_native(sexp) if @scope.class_scope?
|
552
570
|
when :require
|
553
|
-
|
571
|
+
path = arglist[1]
|
554
572
|
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
573
|
+
if path and path[0] == :str
|
574
|
+
path_name = path[1].sub(/^opal\//, '')
|
575
|
+
@requires << path_name
|
576
|
+
return "nil"
|
577
|
+
else
|
578
|
+
warn "Opal cannot do dynamic requires"
|
579
|
+
return "nil"
|
580
|
+
end
|
562
581
|
end
|
563
582
|
|
564
583
|
splat = arglist[1..-1].any? { |a| a.first == :splat }
|
@@ -649,17 +668,17 @@ module Opal
|
|
649
668
|
body[1] = s(:nil) unless body[1]
|
650
669
|
|
651
670
|
code = nil
|
652
|
-
@helpers[:klass] =
|
671
|
+
@helpers[:klass] = true
|
653
672
|
|
654
673
|
if Symbol === cid or String === cid
|
655
|
-
base =
|
656
|
-
name = cid.to_s
|
674
|
+
base = current_self
|
675
|
+
name = cid.to_s
|
657
676
|
elsif cid[0] == :colon2
|
658
677
|
base = process(cid[1], :expr)
|
659
|
-
name = cid[2].to_s
|
678
|
+
name = cid[2].to_s
|
660
679
|
elsif cid[0] == :colon3
|
661
680
|
base = 'Opal.Object'
|
662
|
-
name = cid[1].to_s
|
681
|
+
name = cid[1].to_s
|
663
682
|
else
|
664
683
|
raise "Bad receiver in class"
|
665
684
|
end
|
@@ -668,13 +687,21 @@ module Opal
|
|
668
687
|
|
669
688
|
indent do
|
670
689
|
in_scope(:class) do
|
690
|
+
@scope.name = name
|
691
|
+
@scope.add_temp "#{ @scope.proto } = #{name}.prototype", "__scope = #{name}._scope"
|
671
692
|
@scope.donates_methods = true
|
672
|
-
|
693
|
+
body = process body, :stmt
|
694
|
+
code = @indent + @scope.to_vars + "\n\n#@indent" + body
|
673
695
|
code += "\n#{@scope.to_donate_methods}"
|
674
696
|
end
|
675
697
|
end
|
676
698
|
|
677
|
-
"
|
699
|
+
spacer = "\n#{@indent}#{INDENT}"
|
700
|
+
cls = "function #{name}() {};"
|
701
|
+
boot = "#{name} = __klass(__base, __super, #{name.inspect}, #{name});"
|
702
|
+
comment = "#{spacer}// line #{ sexp.line }, #{ @file }, class #{ name }#{spacer}"
|
703
|
+
|
704
|
+
"(function(__base, __super){#{comment}#{cls}#{spacer}#{boot}\n#{code}\n#{@indent}})(#{base}, #{sup})"
|
678
705
|
end
|
679
706
|
|
680
707
|
# s(:sclass, recv, body)
|
@@ -683,13 +710,13 @@ module Opal
|
|
683
710
|
body = sexp[1]
|
684
711
|
code = nil
|
685
712
|
base = process recv, :expr
|
686
|
-
@helpers[:sklass] = true
|
687
713
|
|
688
714
|
in_scope(:sclass) do
|
715
|
+
@scope.add_temp '__scope = this._scope'
|
689
716
|
code = @scope.to_vars + process(body, :stmt)
|
690
717
|
end
|
691
718
|
|
692
|
-
"
|
719
|
+
"(function(){#{ code }}).call(#{ base }.$singleton_class())"
|
693
720
|
end
|
694
721
|
|
695
722
|
# s(:module, cid, body)
|
@@ -697,29 +724,37 @@ module Opal
|
|
697
724
|
cid = sexp[0]
|
698
725
|
body = sexp[1]
|
699
726
|
code = nil
|
700
|
-
@helpers[:module] =
|
727
|
+
@helpers[:module] = true
|
701
728
|
|
702
729
|
if Symbol === cid or String === cid
|
703
|
-
base =
|
704
|
-
name = cid.to_s
|
730
|
+
base = current_self
|
731
|
+
name = cid.to_s
|
705
732
|
elsif cid[0] == :colon2
|
706
733
|
base = process(cid[1], :expr)
|
707
|
-
name = cid[2].to_s
|
734
|
+
name = cid[2].to_s
|
708
735
|
elsif cid[0] == :colon3
|
709
736
|
base = 'Opal.Object'
|
710
|
-
name = cid[1].to_s
|
737
|
+
name = cid[1].to_s
|
711
738
|
else
|
712
739
|
raise "Bad receiver in class"
|
713
740
|
end
|
714
741
|
|
715
742
|
indent do
|
716
743
|
in_scope(:module) do
|
744
|
+
@scope.name = name
|
745
|
+
@scope.add_temp "#{ @scope.proto } = #{name}.prototype", "__scope = #{name}._scope"
|
717
746
|
@scope.donates_methods = true
|
718
|
-
|
747
|
+
body = process body, :stmt
|
748
|
+
code = @indent + @scope.to_vars + "\n\n#@indent" + body + "\n#@indent" + @scope.to_donate_methods
|
719
749
|
end
|
720
750
|
end
|
721
751
|
|
722
|
-
"
|
752
|
+
spacer = "\n#{@indent}#{INDENT}"
|
753
|
+
cls = "function #{name}() {};"
|
754
|
+
boot = "#{name} = __module(__base, #{name.inspect}, #{name});"
|
755
|
+
comment = "#{spacer}// line #{ sexp.line }, #{ @file }, module #{ name }#{spacer}"
|
756
|
+
|
757
|
+
"(function(__base){#{comment}#{cls}#{spacer}#{boot}\n#{code}\n#{@indent}})(#{base})"
|
723
758
|
end
|
724
759
|
|
725
760
|
def process_undef(exp, level)
|
@@ -730,7 +765,7 @@ module Opal
|
|
730
765
|
# FIXME: maybe add this to donate(). it will be undefined, so
|
731
766
|
# when added to includees it will actually undefine methods there
|
732
767
|
# too.
|
733
|
-
"delete
|
768
|
+
"delete #{ @scope.proto }.#{jsid}"
|
734
769
|
end
|
735
770
|
|
736
771
|
# s(:defn, mid, s(:args), s(:scope))
|
@@ -751,14 +786,15 @@ module Opal
|
|
751
786
|
end
|
752
787
|
|
753
788
|
def js_def(recvr, mid, args, stmts, line, end_line)
|
754
|
-
|
789
|
+
jsid = mid_to_jsid mid.to_s
|
755
790
|
|
756
791
|
if recvr
|
757
792
|
@scope.defines_defs = true
|
793
|
+
smethod = true if @scope.class_scope? && recvr.first == :self
|
758
794
|
recv = process(recvr, :expr)
|
759
795
|
else
|
760
796
|
@scope.defines_defn = true
|
761
|
-
recv =
|
797
|
+
recv = current_self
|
762
798
|
end
|
763
799
|
|
764
800
|
code = ''
|
@@ -784,66 +820,71 @@ module Opal
|
|
784
820
|
end
|
785
821
|
end
|
786
822
|
|
787
|
-
# aritycode = arity_check(args, opt, splat) if @debug && false
|
788
|
-
|
789
823
|
indent do
|
790
|
-
|
791
|
-
|
824
|
+
in_scope(:def) do
|
825
|
+
@scope.mid = mid
|
826
|
+
@scope.defs = true if recvr
|
792
827
|
|
793
|
-
|
794
|
-
|
795
|
-
|
828
|
+
if block_name
|
829
|
+
@scope.uses_block!
|
830
|
+
end
|
796
831
|
|
797
|
-
|
798
|
-
|
832
|
+
yielder = block_name || '__yield'
|
833
|
+
@scope.block_name = yielder
|
799
834
|
|
800
|
-
|
835
|
+
params = process args, :expr
|
801
836
|
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
837
|
+
opt[1..-1].each do |o|
|
838
|
+
next if o[2][2] == :undefined
|
839
|
+
id = process s(:lvar, o[1]), :expr
|
840
|
+
code += ("if (%s == null) {\n%s%s\n%s}" %
|
841
|
+
[id, @indent + INDENT, process(o, :expre), @indent])
|
842
|
+
end if opt
|
807
843
|
|
808
|
-
|
809
|
-
|
844
|
+
code += "#{splat} = __slice.call(arguments, #{len});" if splat
|
845
|
+
code += "\n#@indent" + process(stmts, :stmt)
|
810
846
|
|
811
|
-
|
812
|
-
|
847
|
+
# Returns the identity name if identified, nil otherwise
|
848
|
+
scope_name = @scope.identity
|
813
849
|
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
blk = "\n#{@indent}#{yielder} = #{scope_name}._p || nil;\n#{@indent}__context = #{yielder}._s"
|
818
|
-
blk += ";\n#{@indent}#{scope_name}._p = null;\n#{@indent}"
|
819
|
-
code = blk + code
|
820
|
-
end
|
850
|
+
if @scope.uses_block?
|
851
|
+
@scope.add_temp '__context'
|
852
|
+
@scope.add_temp yielder
|
821
853
|
|
822
|
-
|
823
|
-
|
824
|
-
end
|
854
|
+
blk = "\n%s%s = %s._p || nil, __context = %s._s, %s._p = null;\n%s" %
|
855
|
+
[@indent, yielder, scope_name, yielder, scope_name, @indent]
|
825
856
|
|
826
|
-
|
827
|
-
|
857
|
+
code = blk + code
|
858
|
+
end
|
859
|
+
|
860
|
+
code = "#@indent#{@scope.to_vars}" + code
|
861
|
+
end
|
828
862
|
end
|
829
863
|
|
830
864
|
defcode = "#{"#{scope_name} = " if scope_name}function(#{params}) {\n#{code}\n#@indent}"
|
831
865
|
|
866
|
+
comment = "// line #{line}, #{@file}"
|
867
|
+
|
868
|
+
if @scope.class_scope?
|
869
|
+
comment += ", #{ @scope.name }#{ recvr ? '.' : '#' }#{ mid }"
|
870
|
+
end
|
871
|
+
|
872
|
+
comment += "\n#{@indent}"
|
873
|
+
|
832
874
|
if recvr
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
875
|
+
if smethod
|
876
|
+
@scope.smethods << jsid
|
877
|
+
"#{ comment }#{ @scope.name }.#{jsid} = #{defcode}"
|
878
|
+
else
|
879
|
+
"#{recv}.$singleton_class().prototype.#{jsid} = #{defcode}"
|
880
|
+
end
|
881
|
+
elsif @scope.class_scope?
|
882
|
+
@scope.methods << jsid
|
883
|
+
"#{ comment }#{ @scope.proto }.#{jsid} = #{defcode}"
|
841
884
|
elsif @scope.type == :iter
|
842
|
-
|
843
|
-
"def.#{mid} = #{defcode}"
|
885
|
+
"def.#{jsid} = #{defcode}"
|
844
886
|
else
|
845
|
-
|
846
|
-
"def.#{mid} = #{defcode}"
|
887
|
+
"def.#{jsid} = #{defcode}"
|
847
888
|
end
|
848
889
|
end
|
849
890
|
|
@@ -878,7 +919,20 @@ module Opal
|
|
878
919
|
|
879
920
|
# s(:self) # => this
|
880
921
|
def process_self(sexp, level)
|
881
|
-
|
922
|
+
current_self
|
923
|
+
end
|
924
|
+
|
925
|
+
# Returns the current value for 'self'. This will be native
|
926
|
+
# 'this' for methods and blocks, and the class name for class
|
927
|
+
# and module bodies.
|
928
|
+
def current_self
|
929
|
+
if @scope.class_scope?
|
930
|
+
@scope.name
|
931
|
+
elsif @scope.top?
|
932
|
+
'self'
|
933
|
+
else
|
934
|
+
'this'
|
935
|
+
end
|
882
936
|
end
|
883
937
|
|
884
938
|
# s(:true) # => true
|
@@ -960,7 +1014,7 @@ module Opal
|
|
960
1014
|
@scope.queue_temp redo_var
|
961
1015
|
|
962
1016
|
if stmt_level == :stmt_closure
|
963
|
-
code = "(function() {#{code}; return nil;}).call(
|
1017
|
+
code = "(function() {#{code}; return nil;}).call(#{current_self})"
|
964
1018
|
end
|
965
1019
|
|
966
1020
|
code
|
@@ -996,23 +1050,25 @@ module Opal
|
|
996
1050
|
@scope.queue_temp redo_var
|
997
1051
|
|
998
1052
|
if stmt_level == :stmt_closure
|
999
|
-
code = "(function() {#{code}; return nil;}).call(
|
1053
|
+
code = "(function() {#{code}; return nil;}).call(#{current_self})"
|
1000
1054
|
end
|
1001
1055
|
|
1002
1056
|
code
|
1003
1057
|
end
|
1004
1058
|
|
1005
|
-
##
|
1006
1059
|
# alias foo bar
|
1007
1060
|
#
|
1008
1061
|
# s(:alias, s(:lit, :foo), s(:lit, :bar))
|
1009
1062
|
def process_alias(exp, level)
|
1010
|
-
@helpers['alias'] = true
|
1011
1063
|
new = mid_to_jsid exp[0][1].to_s
|
1012
1064
|
old = mid_to_jsid exp[1][1].to_s
|
1013
|
-
|
1014
|
-
@scope.
|
1015
|
-
|
1065
|
+
|
1066
|
+
if [:class, :module].include? @scope.type
|
1067
|
+
@scope.methods << new
|
1068
|
+
"%s.%s = %s.%s" % [@scope.proto, new, @scope.proto, old]
|
1069
|
+
else
|
1070
|
+
"def.%s = def.%s" % [new, old]
|
1071
|
+
end
|
1016
1072
|
end
|
1017
1073
|
|
1018
1074
|
def process_masgn(sexp, level)
|
@@ -1080,7 +1136,7 @@ module Opal
|
|
1080
1136
|
ivar = exp[0]
|
1081
1137
|
rhs = exp[1]
|
1082
1138
|
ivar = ivar.to_s[1..-1]
|
1083
|
-
lhs = RESERVED.include?(ivar) ? "
|
1139
|
+
lhs = RESERVED.include?(ivar) ? "#{current_self}['#{ivar}']" : "#{current_self}.#{ivar}"
|
1084
1140
|
"#{lhs} = #{process rhs, :expr}"
|
1085
1141
|
end
|
1086
1142
|
|
@@ -1089,19 +1145,19 @@ module Opal
|
|
1089
1145
|
ivar = exp.shift.to_s[1..-1]
|
1090
1146
|
part = RESERVED.include?(ivar) ? "['#{ivar}']" : ".#{ivar}"
|
1091
1147
|
@scope.add_ivar part
|
1092
|
-
"
|
1148
|
+
"#{current_self}#{part}"
|
1093
1149
|
end
|
1094
1150
|
|
1095
1151
|
# s(:gvar, gvar)
|
1096
1152
|
def process_gvar(sexp, level)
|
1097
|
-
gvar = sexp.shift.to_s
|
1153
|
+
gvar = sexp.shift.to_s[1..-1]
|
1098
1154
|
@helpers['gvars'] = true
|
1099
1155
|
"__gvars[#{gvar.inspect}]"
|
1100
1156
|
end
|
1101
1157
|
|
1102
1158
|
# s(:gasgn, :gvar, rhs)
|
1103
1159
|
def process_gasgn(sexp, level)
|
1104
|
-
gvar = sexp[0]
|
1160
|
+
gvar = sexp[0].to_s[1..-1]
|
1105
1161
|
rhs = sexp[1]
|
1106
1162
|
@helpers['gvars'] = true
|
1107
1163
|
"__gvars[#{gvar.to_s.inspect}] = #{process rhs, :expr}"
|
@@ -1109,11 +1165,7 @@ module Opal
|
|
1109
1165
|
|
1110
1166
|
# s(:const, :const)
|
1111
1167
|
def process_const(sexp, level)
|
1112
|
-
|
1113
|
-
"__const_get(__scope, #{sexp.shift.to_s.inspect})"
|
1114
|
-
else
|
1115
|
-
"__scope.#{sexp.shift}"
|
1116
|
-
end
|
1168
|
+
"__scope.#{sexp.shift}"
|
1117
1169
|
end
|
1118
1170
|
|
1119
1171
|
# s(:cdecl, :const, rhs)
|
@@ -1201,12 +1253,21 @@ module Opal
|
|
1201
1253
|
falsy = returns(falsy || s(:nil))
|
1202
1254
|
end
|
1203
1255
|
|
1204
|
-
|
1256
|
+
# optimize unless (we don't want else unless we need to)
|
1257
|
+
if falsy and !truthy
|
1258
|
+
truthy = falsy
|
1259
|
+
falsy = nil
|
1260
|
+
check = js_falsy test
|
1261
|
+
else
|
1262
|
+
check = js_truthy test
|
1263
|
+
end
|
1264
|
+
|
1265
|
+
code = "if (#{check}) {\n"
|
1205
1266
|
indent { code += @indent + process(truthy, :stmt) } if truthy
|
1206
1267
|
indent { code += "\n#@indent} else {\n#@indent#{process falsy, :stmt}" } if falsy
|
1207
1268
|
code += "\n#@indent}"
|
1208
1269
|
|
1209
|
-
code = "(function() { #{code}; return nil; }).call(
|
1270
|
+
code = "(function() { #{code}; return nil; }).call(#{current_self})" if returnable
|
1210
1271
|
|
1211
1272
|
code
|
1212
1273
|
end
|
@@ -1218,7 +1279,12 @@ module Opal
|
|
1218
1279
|
return process sexp, :expr
|
1219
1280
|
elsif COMPARE.include? mid.to_s
|
1220
1281
|
return process sexp, :expr
|
1282
|
+
elsif mid == :"=="
|
1283
|
+
return process sexp, :expr
|
1221
1284
|
end
|
1285
|
+
elsif [:lvar, :self].include? sexp.first
|
1286
|
+
name = process sexp, :expr
|
1287
|
+
"#{name} !== false && #{name} !== nil"
|
1222
1288
|
end
|
1223
1289
|
end
|
1224
1290
|
|
@@ -1227,10 +1293,22 @@ module Opal
|
|
1227
1293
|
return optimized
|
1228
1294
|
end
|
1229
1295
|
|
1230
|
-
|
1231
|
-
|
1296
|
+
with_temp do |tmp|
|
1297
|
+
"(%s = %s) !== false && %s !== nil" % [tmp, process(sexp, :expr), tmp]
|
1298
|
+
end
|
1299
|
+
end
|
1232
1300
|
|
1233
|
-
|
1301
|
+
def js_falsy(sexp)
|
1302
|
+
if sexp.first == :call
|
1303
|
+
mid = sexp[2]
|
1304
|
+
if mid == :block_given?
|
1305
|
+
return handle_block_given(sexp, true)
|
1306
|
+
end
|
1307
|
+
end
|
1308
|
+
|
1309
|
+
with_temp do |tmp|
|
1310
|
+
"(%s = %s) === false || %s === nil" % [tmp, process(sexp, :expr), tmp]
|
1311
|
+
end
|
1234
1312
|
end
|
1235
1313
|
|
1236
1314
|
# s(:and, lhs, rhs)
|
@@ -1272,36 +1350,48 @@ module Opal
|
|
1272
1350
|
end
|
1273
1351
|
|
1274
1352
|
# s(:yield, arg1, arg2)
|
1275
|
-
#
|
1276
|
-
# FIXME: yield as an expression (when used with js_return) should have the
|
1277
|
-
# right action. We should then warn when used as an expression in other cases
|
1278
|
-
# that we would need to use a try/catch/throw block (which is slow and bad
|
1279
|
-
# mmmkay).
|
1280
1353
|
def process_yield(sexp, level)
|
1354
|
+
call = handle_yield_call sexp, level
|
1355
|
+
|
1356
|
+
if level == :stmt
|
1357
|
+
"if (#{call} === __breaker) return __breaker.$v"
|
1358
|
+
else
|
1359
|
+
call
|
1360
|
+
end
|
1361
|
+
end
|
1362
|
+
|
1363
|
+
# Created by `#returns()` for when a yield statement should return
|
1364
|
+
# it's value (its last in a block etc).
|
1365
|
+
def process_returnable_yield(sexp, level)
|
1366
|
+
call = handle_yield_call sexp, level
|
1367
|
+
|
1368
|
+
with_temp do |tmp|
|
1369
|
+
"return %s = #{call}, %s === __breaker ? __breaker.$v : %s" %
|
1370
|
+
[tmp, tmp, tmp]
|
1371
|
+
end
|
1372
|
+
end
|
1373
|
+
|
1374
|
+
def handle_yield_call(sexp, level)
|
1281
1375
|
@scope.uses_block!
|
1376
|
+
|
1282
1377
|
splat = sexp.any? { |s| s.first == :splat }
|
1283
1378
|
sexp.unshift s(:js_tmp, '__context') unless splat
|
1284
|
-
args = process_arglist
|
1379
|
+
args = process_arglist sexp, level
|
1285
1380
|
|
1286
|
-
|
1381
|
+
y = @scope.block_name || '__yield'
|
1287
1382
|
|
1288
|
-
|
1289
|
-
"#{yielder}.apply(__context, #{args})"
|
1290
|
-
else
|
1291
|
-
"#{yielder}.call(#{args})"
|
1292
|
-
end
|
1383
|
+
splat ? "#{y}.apply(__context, #{args})" : "#{y}.call(#{args})"
|
1293
1384
|
end
|
1294
1385
|
|
1295
1386
|
def process_break(exp, level)
|
1296
1387
|
val = exp.empty? ? 'nil' : process(exp.shift, :expr)
|
1297
1388
|
if in_while?
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
end
|
1389
|
+
@while_loop[:closure] ? "return #{ val };" : "break;"
|
1390
|
+
elsif @scope.iter?
|
1391
|
+
error "break must be used as a statement" unless level == :stmt
|
1392
|
+
"return (__breaker.$v = #{ val }, __breaker)"
|
1303
1393
|
else
|
1304
|
-
"
|
1394
|
+
error "cannot use break outside of iter/while"
|
1305
1395
|
end
|
1306
1396
|
end
|
1307
1397
|
|
@@ -1330,8 +1420,8 @@ module Opal
|
|
1330
1420
|
|
1331
1421
|
code << "else {return nil}" if returnable and !done_else
|
1332
1422
|
|
1333
|
-
code = "$case = #{expr};#{code.join
|
1334
|
-
code = "(function() { #{code} }).call(
|
1423
|
+
code = "$case = #{expr};#{code.join @space}"
|
1424
|
+
code = "(function() { #{code} }).call(#{current_self})" if returnable
|
1335
1425
|
code
|
1336
1426
|
end
|
1337
1427
|
|
@@ -1352,7 +1442,7 @@ module Opal
|
|
1352
1442
|
call = s(:call, s(:js_tmp, "$splt[i]"), :===, s(:arglist, s(:js_tmp, "$case")))
|
1353
1443
|
splt = "(function($splt) {for(var i = 0; i < $splt.length; i++) {"
|
1354
1444
|
splt += "if (#{process call, :expr}) { return true; }"
|
1355
|
-
splt += "} return false; }).call(
|
1445
|
+
splt += "} return false; }).call(#{current_self}, #{process a[1], :expr})"
|
1356
1446
|
|
1357
1447
|
test << splt
|
1358
1448
|
else
|
@@ -1364,7 +1454,7 @@ module Opal
|
|
1364
1454
|
end
|
1365
1455
|
end
|
1366
1456
|
|
1367
|
-
"if (%s) {
|
1457
|
+
"if (%s) {%s%s%s}" % [test.join(' || '), @space, body, @space]
|
1368
1458
|
end
|
1369
1459
|
|
1370
1460
|
# lhs =~ rhs
|
@@ -1381,9 +1471,10 @@ module Opal
|
|
1381
1471
|
#
|
1382
1472
|
# s(:cvar, name)
|
1383
1473
|
def process_cvar(exp, level)
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1474
|
+
with_temp do |tmp|
|
1475
|
+
"((%s = Opal.cvars[%s]) == null ? nil : %s)" %
|
1476
|
+
[tmp, exp.shift.to_s.inspect, tmp]
|
1477
|
+
end
|
1387
1478
|
end
|
1388
1479
|
|
1389
1480
|
# @@name = rhs
|
@@ -1432,15 +1523,16 @@ module Opal
|
|
1432
1523
|
def js_super args
|
1433
1524
|
if @scope.type == :def
|
1434
1525
|
identity = @scope.identify!
|
1526
|
+
cls_name = @scope.parent.name
|
1527
|
+
jsid = mid_to_jsid @scope.mid.to_s
|
1528
|
+
base = @scope.defs ? '' : ".prototype"
|
1435
1529
|
|
1436
|
-
|
1437
|
-
# for `def self.foo`.
|
1438
|
-
"__class._super._proto.#{@scope.mid}.apply(this, #{args})"
|
1530
|
+
"%s._super%s.%s.apply(this, %s)" % [cls_name, base, jsid, args]
|
1439
1531
|
|
1440
1532
|
elsif @scope.type == :iter
|
1441
1533
|
chain, defn, mid = @scope.get_super_chain
|
1442
|
-
trys = chain.map { |c| "#{c}.
|
1443
|
-
"this._klass._super._proto[#{
|
1534
|
+
trys = chain.map { |c| "#{c}._sup" }.join ' || '
|
1535
|
+
"(#{trys} || this._klass._super._proto[#{mid}]).apply(this, #{args})"
|
1444
1536
|
|
1445
1537
|
else
|
1446
1538
|
raise "Cannot call super() from outside a method block"
|
@@ -1470,14 +1562,13 @@ module Opal
|
|
1470
1562
|
if op.to_s == "||"
|
1471
1563
|
raise "op_asgn2 for ||"
|
1472
1564
|
else
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1565
|
+
with_temp do |temp|
|
1566
|
+
getr = s(:call, s(:js_tmp, temp), mid, s(:arglist))
|
1567
|
+
oper = s(:call, getr, op, s(:arglist, rhs))
|
1568
|
+
asgn = s(:call, s(:js_tmp, temp), "#{mid}=", s(:arglist, oper))
|
1477
1569
|
|
1478
|
-
|
1479
|
-
|
1480
|
-
}
|
1570
|
+
"(#{temp} = #{lhs}, #{process asgn, :expr})"
|
1571
|
+
end
|
1481
1572
|
end
|
1482
1573
|
end
|
1483
1574
|
|
@@ -1494,8 +1585,8 @@ module Opal
|
|
1494
1585
|
ensr = process ensr, level
|
1495
1586
|
body = "try {\n#{body}}" unless body =~ /^try \{/
|
1496
1587
|
|
1497
|
-
res = "#{body}
|
1498
|
-
res = "(function() { #{res}; }).call(
|
1588
|
+
res = "#{body}#{@space}finally {#{@space}#{ensr}}"
|
1589
|
+
res = "(function() { #{res}; }).call(#{current_self})" if retn
|
1499
1590
|
res
|
1500
1591
|
end
|
1501
1592
|
|
@@ -1512,8 +1603,8 @@ module Opal
|
|
1512
1603
|
# if no rescue statement captures our error, we should rethrow
|
1513
1604
|
parts << "else { throw $err; }"
|
1514
1605
|
|
1515
|
-
code = "try {
|
1516
|
-
code = "(function() { #{code} }).call(
|
1606
|
+
code = "try {#@space#{body}#@space} catch ($err) {#@space#{parts.join @space}#{@space}}"
|
1607
|
+
code = "(function() { #{code} }).call(#{current_self})" if level == :expr
|
1517
1608
|
|
1518
1609
|
code
|
1519
1610
|
end
|
@@ -1538,7 +1629,7 @@ module Opal
|
|
1538
1629
|
val = process(val, :expr) + ";"
|
1539
1630
|
end
|
1540
1631
|
|
1541
|
-
"if (#{err}) {
|
1632
|
+
"if (#{err}) {#{@space}#{val}#{body}}"
|
1542
1633
|
# raise exp.inspect
|
1543
1634
|
end
|
1544
1635
|
|