opal 1.2.0 → 1.3.0.alpha1
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 +4 -4
- data/.eslintrc.await.js +6 -0
- data/.eslintrc.js +34 -0
- data/.github/workflows/build.yml +8 -0
- data/.rubocop.yml +9 -0
- data/CHANGELOG.md +4 -0
- data/README.md +1 -1
- data/Rakefile +1 -0
- data/UNRELEASED.md +64 -38
- data/docs/async.md +109 -0
- data/docs/roda-sprockets.md +0 -2
- data/exe/opal +2 -0
- data/exe/opal-repl +2 -2
- data/lib/opal/builder.rb +5 -1
- data/lib/opal/builder_processors.rb +7 -2
- data/lib/opal/cache/file_cache.rb +119 -0
- data/lib/opal/cache.rb +71 -0
- data/lib/opal/cli.rb +35 -1
- data/lib/opal/cli_options.rb +21 -0
- data/lib/opal/cli_runners/chrome.rb +21 -14
- data/lib/opal/cli_runners/chrome_cdp_interface.js +30285 -0
- data/lib/opal/cli_runners/{chrome.js → chrome_cdp_interface.rb} +27 -6
- data/lib/opal/cli_runners/compiler.rb +2 -1
- data/lib/opal/cli_runners/gjs.rb +27 -0
- data/lib/opal/cli_runners/mini_racer.rb +36 -0
- data/lib/opal/cli_runners/source-map-support-browser.js +276 -91
- data/lib/opal/cli_runners/source-map-support-node.js +276 -91
- data/lib/opal/cli_runners/source-map-support.js +60 -18
- data/lib/opal/cli_runners.rb +2 -0
- data/lib/opal/compiler.rb +99 -10
- data/lib/opal/fragment.rb +77 -14
- data/lib/opal/nodes/args/extract_kwrestarg.rb +6 -4
- data/lib/opal/nodes/args/extract_restarg.rb +10 -12
- data/lib/opal/nodes/args.rb +28 -0
- data/lib/opal/nodes/base.rb +29 -5
- data/lib/opal/nodes/call.rb +123 -2
- data/lib/opal/nodes/case.rb +7 -1
- data/lib/opal/nodes/class.rb +12 -2
- data/lib/opal/nodes/def.rb +3 -23
- data/lib/opal/nodes/definitions.rb +21 -4
- data/lib/opal/nodes/helpers.rb +2 -2
- data/lib/opal/nodes/if.rb +39 -9
- data/lib/opal/nodes/iter.rb +15 -3
- data/lib/opal/nodes/lambda.rb +3 -1
- data/lib/opal/nodes/literal.rb +13 -7
- data/lib/opal/nodes/logic.rb +2 -2
- data/lib/opal/nodes/module.rb +12 -2
- data/lib/opal/nodes/rescue.rb +59 -34
- data/lib/opal/nodes/scope.rb +88 -6
- data/lib/opal/nodes/super.rb +52 -25
- data/lib/opal/nodes/top.rb +13 -7
- data/lib/opal/nodes/while.rb +7 -1
- data/lib/opal/parser/patch.rb +2 -1
- data/lib/opal/repl.rb +137 -49
- data/lib/opal/rewriters/binary_operator_assignment.rb +10 -10
- data/lib/opal/rewriters/block_to_iter.rb +3 -3
- data/lib/opal/rewriters/for_rewriter.rb +7 -7
- data/lib/opal/rewriters/js_reserved_words.rb +5 -3
- data/lib/opal/source_map/file.rb +7 -4
- data/lib/opal/source_map/map.rb +17 -3
- data/lib/opal/version.rb +1 -1
- data/opal/corelib/array.rb +2 -2
- data/opal/corelib/binding.rb +46 -0
- data/opal/corelib/boolean.rb +54 -4
- data/opal/corelib/class.rb +2 -0
- data/opal/corelib/constants.rb +2 -2
- data/opal/corelib/error.rb +98 -12
- data/opal/corelib/io.rb +250 -38
- data/opal/corelib/kernel/format.rb +5 -2
- data/opal/corelib/kernel.rb +44 -23
- data/opal/corelib/main.rb +5 -0
- data/opal/corelib/method.rb +1 -0
- data/opal/corelib/module.rb +28 -0
- data/opal/corelib/number.rb +12 -1
- data/opal/corelib/random/seedrandom.js.rb +2 -2
- data/opal/corelib/regexp.rb +47 -3
- data/opal/corelib/runtime.js +152 -12
- data/opal/corelib/string/encoding.rb +17 -17
- data/opal/corelib/string.rb +2 -0
- data/opal/corelib/struct.rb +10 -3
- data/opal/corelib/trace_point.rb +57 -0
- data/opal/opal/full.rb +2 -0
- data/package.json +3 -2
- data/spec/filters/bugs/array.rb +0 -1
- data/spec/filters/bugs/basicobject.rb +0 -1
- data/spec/filters/bugs/binding.rb +27 -0
- data/spec/filters/bugs/enumerator.rb +132 -0
- data/spec/filters/bugs/exception.rb +70 -93
- data/spec/filters/bugs/float.rb +0 -1
- data/spec/filters/bugs/kernel.rb +3 -9
- data/spec/filters/bugs/language.rb +15 -58
- data/spec/filters/bugs/main.rb +16 -0
- data/spec/filters/bugs/matrix.rb +39 -0
- data/spec/filters/bugs/method.rb +0 -2
- data/spec/filters/bugs/module.rb +36 -79
- data/spec/filters/bugs/proc.rb +0 -1
- data/spec/filters/bugs/regexp.rb +0 -16
- data/spec/filters/bugs/trace_point.rb +12 -0
- data/spec/filters/bugs/warnings.rb +0 -4
- data/spec/filters/unsupported/freeze.rb +2 -0
- data/spec/filters/unsupported/privacy.rb +4 -0
- data/spec/lib/compiler_spec.rb +7 -1
- data/spec/lib/repl_spec.rb +4 -2
- data/spec/lib/source_map/file_spec.rb +1 -1
- data/spec/mspec-opal/formatters.rb +18 -4
- data/spec/mspec-opal/runner.rb +2 -2
- data/spec/opal/core/boolean_spec.rb +44 -0
- data/spec/opal/core/hash_spec.rb +8 -0
- data/spec/opal/core/number/to_s_spec.rb +11 -0
- data/spec/opal/stdlib/json/ext_spec.rb +3 -3
- data/spec/opal/stdlib/logger/logger_spec.rb +10 -1
- data/spec/ruby_specs +18 -0
- data/stdlib/await.rb +83 -0
- data/stdlib/base64.rb +4 -4
- data/stdlib/bigdecimal/bignumber.js.rb +4 -2
- data/stdlib/bigdecimal.rb +1 -0
- data/stdlib/gjs/io.rb +33 -0
- data/stdlib/gjs/kernel.rb +5 -0
- data/stdlib/gjs.rb +2 -0
- data/stdlib/js.rb +4 -0
- data/stdlib/json.rb +3 -3
- data/stdlib/logger.rb +1 -1
- data/stdlib/nashorn/file.rb +2 -0
- data/stdlib/nodejs/env.rb +7 -0
- data/stdlib/nodejs/file.rb +6 -41
- data/stdlib/nodejs/io.rb +21 -5
- data/stdlib/nodejs/js-yaml-3-6-1.js +2 -2
- data/stdlib/opal/miniracer.rb +6 -0
- data/stdlib/opal/platform.rb +4 -0
- data/stdlib/opal/repl_js.rb +5 -0
- data/stdlib/opal/replutils.rb +271 -0
- data/stdlib/opal-parser.rb +24 -11
- data/stdlib/opal-platform.rb +8 -0
- data/stdlib/promise/v2.rb +16 -4
- data/stdlib/promise.rb +14 -0
- data/stdlib/stringio.rb +13 -110
- data/stdlib/thread.rb +29 -0
- data/tasks/building.rake +10 -4
- data/tasks/linting-parse-eslint-results.js +39 -0
- data/tasks/linting.rake +38 -28
- data/tasks/performance/asciidoctor_test.rb.erb +6 -0
- data/tasks/performance/optimization_status.rb +77 -0
- data/tasks/performance.rake +149 -0
- data/tasks/testing.rake +9 -1
- data/test/nodejs/test_await.rb +169 -0
- data/test/opal/promisev2/test_error.rb +9 -3
- data/test/opal/unsupported_and_bugs.rb +5 -0
- data/vendored-minitest/minitest/benchmark.rb +9 -7
- data/vendored-minitest/minitest/test.rb +14 -12
- data/vendored-minitest/minitest.rb +19 -16
- data/yarn.lock +686 -117
- metadata +60 -23
- data/.jshintrc +0 -41
- data/spec/filters/unsupported/refinements.rb +0 -8
- data/vendored-minitest/minitest/hell.rb +0 -11
- data/vendored-minitest/minitest/parallel.rb +0 -65
- data/vendored-minitest/minitest/pride.rb +0 -4
- data/vendored-minitest/minitest/pride_plugin.rb +0 -142
- data/vendored-minitest/minitest/unit.rb +0 -45
data/lib/opal/nodes/call.rb
CHANGED
|
@@ -45,6 +45,9 @@ module Opal
|
|
|
45
45
|
handle_special do
|
|
46
46
|
compiler.method_calls << meth.to_sym if record_method?
|
|
47
47
|
|
|
48
|
+
# if trying to access an lvar in eval or irb mode
|
|
49
|
+
return compile_eval_var if using_eval?
|
|
50
|
+
|
|
48
51
|
# if trying to access an lvar in irb mode
|
|
49
52
|
return compile_irb_var if using_irb?
|
|
50
53
|
|
|
@@ -81,8 +84,19 @@ module Opal
|
|
|
81
84
|
iter || splat?
|
|
82
85
|
end
|
|
83
86
|
|
|
87
|
+
def invoke_using_refinement?
|
|
88
|
+
!scope.scope.collect_refinements_temps.empty?
|
|
89
|
+
end
|
|
90
|
+
|
|
84
91
|
def default_compile
|
|
85
|
-
if
|
|
92
|
+
if auto_await?
|
|
93
|
+
push 'await '
|
|
94
|
+
scope.await_encountered = true
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
if invoke_using_refinement?
|
|
98
|
+
compile_using_refined_send
|
|
99
|
+
elsif invoke_using_send?
|
|
86
100
|
compile_using_send
|
|
87
101
|
else
|
|
88
102
|
compile_simple_call_chain
|
|
@@ -109,6 +123,25 @@ module Opal
|
|
|
109
123
|
push ')'
|
|
110
124
|
end
|
|
111
125
|
|
|
126
|
+
# Compiles method call using `Opal.refined_send`
|
|
127
|
+
#
|
|
128
|
+
# @example
|
|
129
|
+
# a.b(c, &block)
|
|
130
|
+
#
|
|
131
|
+
# Opal.refined_send(a, 'b', [c], block, [[Opal.MyRefinements]])
|
|
132
|
+
#
|
|
133
|
+
def compile_using_refined_send
|
|
134
|
+
helper :refined_send
|
|
135
|
+
|
|
136
|
+
push '$refined_send('
|
|
137
|
+
compile_refinements
|
|
138
|
+
compile_receiver
|
|
139
|
+
compile_method_name
|
|
140
|
+
compile_arguments
|
|
141
|
+
compile_block_pass
|
|
142
|
+
push ')'
|
|
143
|
+
end
|
|
144
|
+
|
|
112
145
|
def compile_receiver
|
|
113
146
|
push recv(receiver_sexp)
|
|
114
147
|
end
|
|
@@ -135,6 +168,11 @@ module Opal
|
|
|
135
168
|
end
|
|
136
169
|
end
|
|
137
170
|
|
|
171
|
+
def compile_refinements
|
|
172
|
+
refinements = scope.collect_refinements_temps.map { |i| s(:js_tmp, i) }
|
|
173
|
+
push expr(s(:array, *refinements)), ', '
|
|
174
|
+
end
|
|
175
|
+
|
|
138
176
|
def compile_break_catcher
|
|
139
177
|
if iter_has_break?
|
|
140
178
|
unshift 'return '
|
|
@@ -172,16 +210,34 @@ module Opal
|
|
|
172
210
|
end
|
|
173
211
|
end
|
|
174
212
|
|
|
213
|
+
def compile_eval_var
|
|
214
|
+
push meth.to_s
|
|
215
|
+
end
|
|
216
|
+
|
|
175
217
|
# a variable reference in irb mode in top scope might be a var ref,
|
|
176
218
|
# or it might be a method call
|
|
177
219
|
def using_irb?
|
|
178
|
-
@compiler.irb? && scope.top? &&
|
|
220
|
+
@compiler.irb? && scope.top? && variable_like?
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def using_eval?
|
|
224
|
+
@compiler.eval? && scope.top? && @compiler.scope_variables.include?(meth)
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def variable_like?
|
|
228
|
+
arglist == s(:arglist) && recvr.nil? && iter.nil?
|
|
179
229
|
end
|
|
180
230
|
|
|
181
231
|
def sexp_with_arglist
|
|
182
232
|
@sexp.updated(nil, [recvr, meth, arglist])
|
|
183
233
|
end
|
|
184
234
|
|
|
235
|
+
def auto_await?
|
|
236
|
+
awaited_set = compiler.async_await
|
|
237
|
+
|
|
238
|
+
awaited_set && awaited_set != true && awaited_set.match?(meth.to_s)
|
|
239
|
+
end
|
|
240
|
+
|
|
185
241
|
# Handle "special" method calls, e.g. require(). Subclasses can override
|
|
186
242
|
# this method. If this method returns nil, then the method will continue
|
|
187
243
|
# to be generated by CallNode.
|
|
@@ -273,6 +329,24 @@ module Opal
|
|
|
273
329
|
end
|
|
274
330
|
end
|
|
275
331
|
|
|
332
|
+
# Refinements support
|
|
333
|
+
add_special :using do |compile_default|
|
|
334
|
+
if scope.accepts_using? && arglist.children.count == 1
|
|
335
|
+
using_refinement(arglist.children.first)
|
|
336
|
+
else
|
|
337
|
+
compile_default.call
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def using_refinement(arg)
|
|
342
|
+
prev, curr = *scope.refinements_temp
|
|
343
|
+
if prev
|
|
344
|
+
push "(#{curr} = #{prev}.slice(), #{curr}.push(", expr(arg), '), self)'
|
|
345
|
+
else
|
|
346
|
+
push "(#{curr} = [", expr(arg), '], self)'
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
|
|
276
350
|
add_special :debugger do
|
|
277
351
|
push fragment 'debugger'
|
|
278
352
|
end
|
|
@@ -281,6 +355,12 @@ module Opal
|
|
|
281
355
|
push fragment "Opal.hash({ arity_check: #{compiler.arity_check?} })"
|
|
282
356
|
end
|
|
283
357
|
|
|
358
|
+
add_special :lambda do |compile_default|
|
|
359
|
+
scope.defines_lambda do
|
|
360
|
+
compile_default.call
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
|
|
284
364
|
add_special :nesting do |compile_default|
|
|
285
365
|
push_nesting = push_nesting?
|
|
286
366
|
push '(Opal.Module.$$nesting = $nesting, ' if push_nesting
|
|
@@ -295,6 +375,47 @@ module Opal
|
|
|
295
375
|
push ')' if push_nesting
|
|
296
376
|
end
|
|
297
377
|
|
|
378
|
+
# This can be refactored in terms of binding, but it would 'corelib/binding'
|
|
379
|
+
# to be required in existing code.
|
|
380
|
+
add_special :eval do |compile_default|
|
|
381
|
+
next compile_default.call if arglist.children.length != 1 || ![s(:self), nil].include?(recvr)
|
|
382
|
+
|
|
383
|
+
temp = scope.new_temp
|
|
384
|
+
scope_variables = scope.scope_locals.map(&:to_s).inspect
|
|
385
|
+
push "(#{temp} = ", expr(arglist)
|
|
386
|
+
push ", typeof Opal.compile === 'function' ? eval(Opal.compile(#{temp}"
|
|
387
|
+
push ', {scope_variables: ', scope_variables
|
|
388
|
+
push ", arity_check: #{compiler.arity_check?}, file: '(eval)', eval: true})) : "
|
|
389
|
+
push "self.$eval(#{temp}))"
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
add_special :binding do
|
|
393
|
+
push "Opal.Binding.$new("
|
|
394
|
+
push " function($code, $value) {"
|
|
395
|
+
push " if (typeof $value === 'undefined') {"
|
|
396
|
+
push " return eval($code);"
|
|
397
|
+
push " }"
|
|
398
|
+
push " else {"
|
|
399
|
+
push " return eval($code + ' = $value');"
|
|
400
|
+
push " }"
|
|
401
|
+
push " },"
|
|
402
|
+
push " ", scope.scope_locals.map(&:to_s).inspect, ","
|
|
403
|
+
push " self,"
|
|
404
|
+
push " ", source_location
|
|
405
|
+
push ")"
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
add_special :__await__ do |compile_default|
|
|
409
|
+
if compiler.async_await
|
|
410
|
+
push fragment '(await ('
|
|
411
|
+
push process(recvr)
|
|
412
|
+
push fragment '))'
|
|
413
|
+
scope.await_encountered = true
|
|
414
|
+
else
|
|
415
|
+
compile_default.call
|
|
416
|
+
end
|
|
417
|
+
end
|
|
418
|
+
|
|
298
419
|
def push_nesting?
|
|
299
420
|
recv = children.first
|
|
300
421
|
|
data/lib/opal/nodes/case.rb
CHANGED
|
@@ -13,7 +13,13 @@ module Opal
|
|
|
13
13
|
compiler.in_case do
|
|
14
14
|
compile_code
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
if needs_closure?
|
|
17
|
+
if scope.await_encountered
|
|
18
|
+
wrap '(await (async function() {', '})())'
|
|
19
|
+
else
|
|
20
|
+
wrap '(function() {', '})()'
|
|
21
|
+
end
|
|
22
|
+
end
|
|
17
23
|
end
|
|
18
24
|
end
|
|
19
25
|
|
data/lib/opal/nodes/class.rb
CHANGED
|
@@ -13,13 +13,23 @@ module Opal
|
|
|
13
13
|
name, base = name_and_base
|
|
14
14
|
helper :klass
|
|
15
15
|
|
|
16
|
-
push '(function($base, $super, $parent_nesting) {'
|
|
17
16
|
line " var self = $klass($base, $super, '#{name}');"
|
|
18
17
|
in_scope do
|
|
19
18
|
scope.name = name
|
|
20
19
|
compile_body
|
|
21
20
|
end
|
|
22
|
-
|
|
21
|
+
|
|
22
|
+
if await_encountered
|
|
23
|
+
await_begin = '(await '
|
|
24
|
+
await_end = ')'
|
|
25
|
+
async = 'async '
|
|
26
|
+
parent.await_encountered = true
|
|
27
|
+
else
|
|
28
|
+
await_begin, await_end, async = '', '', ''
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
unshift "#{await_begin}(#{async}function($base, $super, $parent_nesting) {"
|
|
32
|
+
line '})(', base, ', ', super_code, ", $nesting)#{await_end}"
|
|
23
33
|
end
|
|
24
34
|
|
|
25
35
|
def super_code
|
data/lib/opal/nodes/def.rb
CHANGED
|
@@ -33,10 +33,6 @@ module Opal
|
|
|
33
33
|
|
|
34
34
|
compile_arity_check
|
|
35
35
|
|
|
36
|
-
if scope.uses_zuper
|
|
37
|
-
prepare_super
|
|
38
|
-
end
|
|
39
|
-
|
|
40
36
|
unshift "\n#{current_indent}", scope.to_vars
|
|
41
37
|
|
|
42
38
|
line stmt_code
|
|
@@ -61,6 +57,9 @@ module Opal
|
|
|
61
57
|
unshift ') {'
|
|
62
58
|
unshift(inline_params)
|
|
63
59
|
unshift "function#{function_name}("
|
|
60
|
+
if await_encountered
|
|
61
|
+
unshift "async "
|
|
62
|
+
end
|
|
64
63
|
unshift "#{scope_name} = " if scope_name
|
|
65
64
|
line '}'
|
|
66
65
|
|
|
@@ -91,28 +90,9 @@ module Opal
|
|
|
91
90
|
end
|
|
92
91
|
end
|
|
93
92
|
|
|
94
|
-
def source_location
|
|
95
|
-
file = @sexp.loc.expression.source_buffer.name
|
|
96
|
-
file = "<internal:#{file}>" if file.start_with?("corelib/")
|
|
97
|
-
file = "<js:#{file}>" if file.end_with?(".js")
|
|
98
|
-
line = @sexp.loc.line
|
|
99
|
-
"['#{file}', #{line}]"
|
|
100
|
-
end
|
|
101
|
-
|
|
102
93
|
def comments_code
|
|
103
94
|
'[' + comments.map { |comment| comment.text.inspect }.join(', ') + ']'
|
|
104
95
|
end
|
|
105
|
-
|
|
106
|
-
def prepare_super
|
|
107
|
-
add_local '$zuper'
|
|
108
|
-
add_local '$zuper_i'
|
|
109
|
-
add_local '$zuper_ii'
|
|
110
|
-
|
|
111
|
-
line '// Prepare super implicit arguments'
|
|
112
|
-
line 'for($zuper_i = 0, $zuper_ii = arguments.length, $zuper = new Array($zuper_ii); $zuper_i < $zuper_ii; $zuper_i++) {'
|
|
113
|
-
line ' $zuper[$zuper_i] = arguments[$zuper_i];'
|
|
114
|
-
line '}'
|
|
115
|
-
end
|
|
116
96
|
end
|
|
117
97
|
end
|
|
118
98
|
end
|
|
@@ -22,7 +22,19 @@ module Opal
|
|
|
22
22
|
children :new_name, :old_name
|
|
23
23
|
|
|
24
24
|
def compile
|
|
25
|
-
|
|
25
|
+
# We only need to check one type, because parser otherwise denies invalid expressions
|
|
26
|
+
case new_name.type
|
|
27
|
+
when :gvar # This is a gvar alias: alias $a $b
|
|
28
|
+
helper :alias_gvar
|
|
29
|
+
new_name_str = new_name.children.first.to_s[1..-1].inspect
|
|
30
|
+
old_name_str = old_name.children.first.to_s[1..-1].inspect
|
|
31
|
+
push '$alias_gvar(', new_name_str, ', ', old_name_str, ')'
|
|
32
|
+
when :dsym, :sym # This is a method alias: alias a b
|
|
33
|
+
helper :alias
|
|
34
|
+
push '$alias(self, ', expr(new_name), ', ', expr(old_name), ')'
|
|
35
|
+
else # Nothing else is available, but just in case, drop an error
|
|
36
|
+
error "Opal doesn't know yet how to alias with #{new_name.type}"
|
|
37
|
+
end
|
|
26
38
|
end
|
|
27
39
|
end
|
|
28
40
|
|
|
@@ -41,7 +53,12 @@ module Opal
|
|
|
41
53
|
compile_inline_children(returned_children, @level)
|
|
42
54
|
else
|
|
43
55
|
compile_children(returned_children, @level)
|
|
44
|
-
|
|
56
|
+
|
|
57
|
+
if scope.parent.await_encountered
|
|
58
|
+
wrap '(await (async function() {', '})())'
|
|
59
|
+
else
|
|
60
|
+
wrap '(function() {', '})()'
|
|
61
|
+
end
|
|
45
62
|
end
|
|
46
63
|
end
|
|
47
64
|
|
|
@@ -58,7 +75,7 @@ module Opal
|
|
|
58
75
|
|
|
59
76
|
def compile_children(children, level)
|
|
60
77
|
children.each do |child|
|
|
61
|
-
line process(child, level), ';'
|
|
78
|
+
line process(child, level), fragment(';', loc: false)
|
|
62
79
|
end
|
|
63
80
|
end
|
|
64
81
|
|
|
@@ -76,7 +93,7 @@ module Opal
|
|
|
76
93
|
end
|
|
77
94
|
|
|
78
95
|
processed_children.reject(&:empty?).each_with_index do |child, idx|
|
|
79
|
-
push ', ' unless idx == 0
|
|
96
|
+
push fragment(', ', loc: false) unless idx == 0
|
|
80
97
|
push child
|
|
81
98
|
end
|
|
82
99
|
end
|
data/lib/opal/nodes/helpers.rb
CHANGED
|
@@ -35,12 +35,12 @@ module Opal
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def line(*strs)
|
|
38
|
-
push "\n#{current_indent}"
|
|
38
|
+
push fragment("\n#{current_indent}", loc: false)
|
|
39
39
|
push(*strs)
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def empty_line
|
|
43
|
-
push "\n"
|
|
43
|
+
push fragment("\n", loc: false)
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
def js_truthy(sexp)
|
data/lib/opal/nodes/if.rb
CHANGED
|
@@ -33,7 +33,13 @@ module Opal
|
|
|
33
33
|
push '}'
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
if needs_wrapper?
|
|
37
|
+
if scope.await_encountered
|
|
38
|
+
wrap '(await (async function() {', '; return nil; })())'
|
|
39
|
+
else
|
|
40
|
+
wrap '(function() {', '; return nil; })()'
|
|
41
|
+
end
|
|
42
|
+
end
|
|
37
43
|
end
|
|
38
44
|
|
|
39
45
|
def truthy
|
|
@@ -52,20 +58,44 @@ module Opal
|
|
|
52
58
|
class IFlipFlop < Base
|
|
53
59
|
handle :iflipflop
|
|
54
60
|
|
|
61
|
+
children :from, :to
|
|
62
|
+
|
|
63
|
+
# Is this an exclusive flip flop? If no, run both branches
|
|
64
|
+
def excl
|
|
65
|
+
""
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# We create a function that we put in the top scope, that stores the state of our
|
|
69
|
+
# flip-flop. We pass to it functions that are ran with the current binding.
|
|
55
70
|
def compile
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
71
|
+
helper :truthy
|
|
72
|
+
|
|
73
|
+
fun_name = top_scope.new_temp
|
|
74
|
+
ff = "#{fun_name}.$$ff"
|
|
75
|
+
|
|
76
|
+
push "(typeof #{fun_name} === 'undefined' ? (#{fun_name} = function(from, to){"
|
|
77
|
+
push " if (typeof #{ff} === 'undefined') #{ff} = false;"
|
|
78
|
+
push " var retval = #{ff};"
|
|
79
|
+
push " if (!#{ff}) {"
|
|
80
|
+
push " #{ff} = retval = $truthy(from());"
|
|
81
|
+
push " }"
|
|
82
|
+
push " #{excl}if (#{ff}) {"
|
|
83
|
+
push " if ($truthy(to())) #{ff} = false;"
|
|
84
|
+
push " }"
|
|
85
|
+
push " return retval;"
|
|
86
|
+
push "}) : #{fun_name})("
|
|
87
|
+
push " function() { ", stmt(compiler.returns(from)), " },"
|
|
88
|
+
push " function() { ", stmt(compiler.returns(to)), " }"
|
|
89
|
+
push ")"
|
|
59
90
|
end
|
|
60
91
|
end
|
|
61
92
|
|
|
62
|
-
class EFlipFlop <
|
|
93
|
+
class EFlipFlop < IFlipFlop
|
|
63
94
|
handle :eflipflop
|
|
64
95
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
push 'true'
|
|
96
|
+
# Is this an exclusive flip flop? If yes, run only a single branch
|
|
97
|
+
def excl
|
|
98
|
+
"else "
|
|
69
99
|
end
|
|
70
100
|
end
|
|
71
101
|
end
|
data/lib/opal/nodes/iter.rb
CHANGED
|
@@ -11,6 +11,8 @@ module Opal
|
|
|
11
11
|
children :inline_args, :body
|
|
12
12
|
|
|
13
13
|
def compile
|
|
14
|
+
is_lambda! if scope.lambda_definition?
|
|
15
|
+
|
|
14
16
|
inline_params = nil
|
|
15
17
|
|
|
16
18
|
to_vars = identity = body_code = nil
|
|
@@ -25,13 +27,23 @@ module Opal
|
|
|
25
27
|
|
|
26
28
|
body_code = stmt(returned_body)
|
|
27
29
|
to_vars = scope.to_vars
|
|
28
|
-
end
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
line body_code
|
|
32
|
+
|
|
33
|
+
if scope.catch_return
|
|
34
|
+
unshift "try {\n"
|
|
35
|
+
line '} catch ($returner) { if ($returner === Opal.returner) { return $returner.$v }'
|
|
36
|
+
push ' throw $returner; }'
|
|
37
|
+
end
|
|
38
|
+
end
|
|
31
39
|
|
|
32
40
|
unshift to_vars
|
|
33
41
|
|
|
34
|
-
|
|
42
|
+
if await_encountered
|
|
43
|
+
unshift "(#{identity} = async function(", inline_params, '){'
|
|
44
|
+
else
|
|
45
|
+
unshift "(#{identity} = function(", inline_params, '){'
|
|
46
|
+
end
|
|
35
47
|
push "}, #{identity}.$$s = self,"
|
|
36
48
|
push " #{identity}.$$brk = $brk," if contains_break?
|
|
37
49
|
push " #{identity}.$$arity = #{arity},"
|
data/lib/opal/nodes/lambda.rb
CHANGED
data/lib/opal/nodes/literal.rb
CHANGED
|
@@ -152,9 +152,6 @@ module Opal
|
|
|
152
152
|
case value
|
|
153
153
|
when ''
|
|
154
154
|
push('/(?:)/')
|
|
155
|
-
when %r{\?<\w+\>}
|
|
156
|
-
message = "named captures are not supported in javascript: #{value.inspect}"
|
|
157
|
-
push "self.$raise(new SyntaxError('#{message}'))"
|
|
158
155
|
else
|
|
159
156
|
push "#{Regexp.new(value).inspect}#{flags.join}"
|
|
160
157
|
end
|
|
@@ -164,11 +161,10 @@ module Opal
|
|
|
164
161
|
*values, flags_sexp = *children
|
|
165
162
|
self.flags = flags_sexp.children.map(&:to_s)
|
|
166
163
|
|
|
167
|
-
self.value =
|
|
168
|
-
when 0
|
|
164
|
+
self.value = if values.empty?
|
|
169
165
|
# empty regexp, we can process it inline
|
|
170
166
|
s(:str, '')
|
|
171
|
-
|
|
167
|
+
elsif single_line?(values)
|
|
172
168
|
# simple plain regexp, we can put it inline
|
|
173
169
|
values[0]
|
|
174
170
|
else
|
|
@@ -200,6 +196,16 @@ module Opal
|
|
|
200
196
|
def raw_value
|
|
201
197
|
self.value = @sexp.loc.expression.source
|
|
202
198
|
end
|
|
199
|
+
|
|
200
|
+
private
|
|
201
|
+
|
|
202
|
+
def single_line?(values)
|
|
203
|
+
return false if values.length > 1
|
|
204
|
+
|
|
205
|
+
value = values[0]
|
|
206
|
+
# JavaScript doesn't support multiline regexp
|
|
207
|
+
value.type != :str || !value.children[0].include?("\n")
|
|
208
|
+
end
|
|
203
209
|
end
|
|
204
210
|
|
|
205
211
|
# $_ = 'foo'; call if /foo/
|
|
@@ -229,7 +235,7 @@ module Opal
|
|
|
229
235
|
push ' + '
|
|
230
236
|
|
|
231
237
|
if part.type == :str
|
|
232
|
-
push part
|
|
238
|
+
push expr(part)
|
|
233
239
|
else
|
|
234
240
|
push '(', expr(part), ')'
|
|
235
241
|
end
|
data/lib/opal/nodes/logic.rb
CHANGED
|
@@ -126,13 +126,13 @@ module Opal
|
|
|
126
126
|
end
|
|
127
127
|
|
|
128
128
|
def return_in_iter?
|
|
129
|
-
if scope.iter? && parent_def = scope.find_parent_def
|
|
129
|
+
if (scope.iter? && !scope.lambda?) && parent_def = scope.find_parent_def
|
|
130
130
|
parent_def
|
|
131
131
|
end
|
|
132
132
|
end
|
|
133
133
|
|
|
134
134
|
def return_expr_in_def?
|
|
135
|
-
return scope if expr? && scope.def?
|
|
135
|
+
return scope if expr? && (scope.def? || scope.lambda?)
|
|
136
136
|
end
|
|
137
137
|
|
|
138
138
|
def scope_to_catch_return
|
data/lib/opal/nodes/module.rb
CHANGED
|
@@ -13,13 +13,23 @@ module Opal
|
|
|
13
13
|
name, base = name_and_base
|
|
14
14
|
helper :module
|
|
15
15
|
|
|
16
|
-
push '(function($base, $parent_nesting) {'
|
|
17
16
|
line " var self = $module($base, '#{name}');"
|
|
18
17
|
in_scope do
|
|
19
18
|
scope.name = name
|
|
20
19
|
compile_body
|
|
21
20
|
end
|
|
22
|
-
|
|
21
|
+
|
|
22
|
+
if await_encountered
|
|
23
|
+
await_begin = '(await '
|
|
24
|
+
await_end = ')'
|
|
25
|
+
async = 'async '
|
|
26
|
+
parent.await_encountered = true
|
|
27
|
+
else
|
|
28
|
+
await_begin, await_end, async = '', '', ''
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
unshift "#{await_begin}(#{async}function($base, $parent_nesting) {"
|
|
32
|
+
line '})(', base, ", $nesting)#{await_end}"
|
|
23
33
|
end
|
|
24
34
|
|
|
25
35
|
private
|