opal 1.7.2 → 1.8.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.eslintrc.js +1 -0
- data/.github/workflows/build.yml +9 -9
- data/.rubocop/todo.yml +2 -2
- data/.rubocop.yml +17 -10
- data/.rubocop_todo.yml +311 -0
- data/CHANGELOG.md +16 -2
- data/UNRELEASED.md +78 -1
- data/benchmark-ips/bm_block_vs_yield.rb +3 -0
- data/benchmark-ips/bm_slice_or_not.rb +53 -0
- data/docs/bridging.md +112 -0
- data/docs/compiled_ruby.md +10 -10
- data/docs/getting_started.md +18 -22
- data/docs/index.md +1 -1
- data/lib/opal/builder_scheduler/prefork.rb +2 -2
- data/lib/opal/cache/file_cache.rb +7 -10
- data/lib/opal/cli_runners/chrome_cdp_interface.rb +5 -2
- data/lib/opal/cli_runners/firefox_cdp_interface.rb +5 -2
- data/lib/opal/compiler.rb +33 -1
- data/lib/opal/nodes/args/extract_kwoptarg.rb +2 -1
- data/lib/opal/nodes/call.rb +1 -1
- data/lib/opal/nodes/call_special.rb +71 -47
- data/lib/opal/nodes/hash.rb +14 -30
- data/lib/opal/nodes/if.rb +38 -30
- data/lib/opal/nodes/literal.rb +5 -1
- data/lib/opal/nodes/x_string.rb +13 -0
- data/lib/opal/parser/patch.rb +7 -0
- data/lib/opal/rewriters/for_rewriter.rb +36 -24
- data/lib/opal/source_map/file.rb +1 -1
- data/lib/opal/version.rb +1 -1
- data/opal/corelib/array/pack.rb +1 -0
- data/opal/corelib/array.rb +75 -47
- data/opal/corelib/basic_object.rb +1 -0
- data/opal/corelib/binding.rb +2 -0
- data/opal/corelib/boolean.rb +1 -0
- data/opal/corelib/class.rb +2 -0
- data/opal/corelib/comparable.rb +1 -0
- data/opal/corelib/complex.rb +2 -0
- data/opal/corelib/constants.rb +2 -2
- data/opal/corelib/dir.rb +2 -0
- data/opal/corelib/enumerable.rb +3 -2
- data/opal/corelib/enumerator/arithmetic_sequence.rb +2 -0
- data/opal/corelib/enumerator/chain.rb +1 -0
- data/opal/corelib/enumerator/generator.rb +1 -0
- data/opal/corelib/enumerator/lazy.rb +1 -0
- data/opal/corelib/enumerator/yielder.rb +2 -0
- data/opal/corelib/enumerator.rb +1 -0
- data/opal/corelib/error/errno.rb +2 -0
- data/opal/corelib/error.rb +12 -0
- data/opal/corelib/file.rb +1 -0
- data/opal/corelib/hash.rb +197 -504
- data/opal/corelib/helpers.rb +1 -0
- data/opal/corelib/io.rb +2 -0
- data/opal/corelib/irb.rb +2 -0
- data/opal/corelib/kernel/format.rb +1 -0
- data/opal/corelib/kernel.rb +70 -14
- data/opal/corelib/main.rb +2 -0
- data/opal/corelib/marshal/read_buffer.rb +2 -0
- data/opal/corelib/marshal/write_buffer.rb +2 -0
- data/opal/corelib/math/polyfills.rb +2 -0
- data/opal/corelib/math.rb +1 -0
- data/opal/corelib/method.rb +2 -0
- data/opal/corelib/module.rb +1 -0
- data/opal/corelib/nil.rb +3 -1
- data/opal/corelib/number.rb +2 -0
- data/opal/corelib/numeric.rb +2 -0
- data/opal/corelib/object_space.rb +1 -0
- data/opal/corelib/pack_unpack/format_string_parser.rb +2 -0
- data/opal/corelib/proc.rb +30 -28
- data/opal/corelib/process.rb +2 -0
- data/opal/corelib/random/formatter.rb +2 -0
- data/opal/corelib/random/math_random.js.rb +2 -0
- data/opal/corelib/random/mersenne_twister.rb +2 -0
- data/opal/corelib/random/seedrandom.js.rb +2 -0
- data/opal/corelib/random.rb +1 -0
- data/opal/corelib/range.rb +34 -12
- data/opal/corelib/rational.rb +2 -0
- data/opal/corelib/regexp.rb +5 -1
- data/opal/corelib/runtime.js +188 -224
- data/opal/corelib/set.rb +2 -0
- data/opal/corelib/string/encoding.rb +3 -0
- data/opal/corelib/string/unpack.rb +2 -0
- data/opal/corelib/string.rb +20 -12
- data/opal/corelib/struct.rb +3 -1
- data/opal/corelib/time.rb +1 -0
- data/opal/corelib/trace_point.rb +2 -0
- data/opal/corelib/unsupported.rb +2 -0
- data/opal/corelib/variables.rb +2 -0
- data/opal.gemspec +2 -2
- data/spec/filters/bugs/array.rb +0 -3
- data/spec/filters/bugs/enumerable.rb +0 -3
- data/spec/filters/bugs/hash.rb +0 -13
- data/spec/filters/bugs/integer.rb +0 -1
- data/spec/filters/bugs/kernel.rb +0 -39
- data/spec/filters/bugs/language.rb +0 -3
- data/spec/filters/bugs/range.rb +0 -1
- data/spec/filters/bugs/ruby-32.rb +0 -2
- data/spec/filters/bugs/string.rb +0 -1
- data/spec/filters/bugs/struct.rb +1 -5
- data/spec/filters/unsupported/hash.rb +1 -0
- data/spec/lib/compiler_spec.rb +24 -17
- data/spec/mspec-opal/formatters.rb +2 -0
- data/spec/mspec-opal/runner.rb +2 -0
- data/spec/opal/core/array/dup_spec.rb +2 -0
- data/spec/opal/core/exception_spec.rb +2 -0
- data/spec/opal/core/hash/internals_spec.rb +154 -206
- data/spec/opal/core/hash_spec.rb +2 -0
- data/spec/opal/core/iterable_props_spec.rb +2 -0
- data/spec/opal/core/kernel/at_exit_spec.rb +2 -0
- data/spec/opal/core/kernel/respond_to_spec.rb +2 -0
- data/spec/opal/core/language/arguments/mlhs_arg_spec.rb +2 -0
- data/spec/opal/core/language/case_spec.rb +13 -0
- data/spec/opal/core/language/safe_navigator_spec.rb +2 -0
- data/spec/opal/core/language/xstring_send_spec.rb +15 -0
- data/spec/opal/core/language/xstring_spec.rb +2 -0
- data/spec/opal/core/language_spec.rb +2 -0
- data/spec/opal/core/module_spec.rb +44 -0
- data/spec/opal/core/number/to_i_spec.rb +2 -0
- data/spec/opal/core/object_id_spec.rb +2 -0
- data/spec/opal/core/regexp/match_spec.rb +2 -0
- data/spec/opal/core/runtime/bridged_classes_spec.rb +38 -0
- data/spec/opal/core/runtime/constants_spec.rb +2 -0
- data/spec/opal/core/runtime/eval_spec.rb +2 -0
- data/spec/opal/core/runtime/exit_spec.rb +2 -0
- data/spec/opal/core/runtime/is_a_spec.rb +2 -0
- data/spec/opal/core/runtime/loaded_spec.rb +2 -0
- data/spec/opal/core/runtime/method_missing_spec.rb +2 -0
- data/spec/opal/core/runtime/rescue_spec.rb +2 -0
- data/spec/opal/core/runtime/string_spec.rb +2 -0
- data/spec/opal/core/runtime/truthy_spec.rb +2 -0
- data/spec/opal/core/runtime_spec.rb +2 -6
- data/spec/opal/core/string/to_sym_spec.rb +2 -0
- data/spec/opal/stdlib/js_spec.rb +2 -0
- data/spec/opal/stdlib/native/alias_native_spec.rb +2 -0
- data/spec/opal/stdlib/native/array_spec.rb +2 -0
- data/spec/opal/stdlib/native/date_spec.rb +2 -0
- data/spec/opal/stdlib/native/each_spec.rb +2 -0
- data/spec/opal/stdlib/native/element_reference_spec.rb +2 -0
- data/spec/opal/stdlib/native/exposure_spec.rb +2 -0
- data/spec/opal/stdlib/native/ext_spec.rb +2 -0
- data/spec/opal/stdlib/native/hash_spec.rb +30 -2
- data/spec/opal/stdlib/native/initialize_spec.rb +2 -0
- data/spec/opal/stdlib/native/method_missing_spec.rb +2 -0
- data/spec/opal/stdlib/native/native_alias_spec.rb +2 -0
- data/spec/opal/stdlib/native/native_class_spec.rb +2 -0
- data/spec/opal/stdlib/native/native_module_spec.rb +2 -0
- data/spec/opal/stdlib/native/native_reader_spec.rb +2 -0
- data/spec/opal/stdlib/native/native_writer_spec.rb +2 -0
- data/spec/opal/stdlib/native/new_spec.rb +2 -0
- data/spec/opal/stdlib/native/struct_spec.rb +2 -0
- data/spec/spec_helper.rb +2 -0
- data/stdlib/await.rb +1 -0
- data/stdlib/base64.rb +2 -0
- data/stdlib/bigdecimal/bignumber.js.rb +2 -0
- data/stdlib/bigdecimal/util.rb +1 -0
- data/stdlib/bigdecimal.rb +2 -0
- data/stdlib/buffer/array.rb +2 -0
- data/stdlib/buffer/view.rb +2 -0
- data/stdlib/buffer.rb +2 -0
- data/stdlib/cgi.rb +14 -0
- data/stdlib/console.rb +2 -0
- data/stdlib/date/date_time.rb +2 -0
- data/stdlib/date.rb +2 -0
- data/stdlib/delegate.rb +2 -0
- data/stdlib/deno/base.rb +2 -0
- data/stdlib/deno/file.rb +2 -0
- data/stdlib/erb.rb +2 -0
- data/stdlib/gjs/io.rb +2 -0
- data/stdlib/gjs/kernel.rb +2 -0
- data/stdlib/headless_browser/base.rb +2 -0
- data/stdlib/headless_browser/file.rb +1 -0
- data/stdlib/headless_browser.rb +1 -0
- data/stdlib/js.rb +2 -0
- data/stdlib/json.rb +9 -15
- data/stdlib/logger.rb +2 -0
- data/stdlib/nashorn/file.rb +2 -0
- data/stdlib/nashorn/io.rb +2 -0
- data/stdlib/native.rb +48 -48
- data/stdlib/nodejs/base.rb +2 -0
- data/stdlib/nodejs/dir.rb +2 -0
- data/stdlib/nodejs/env.rb +2 -0
- data/stdlib/nodejs/file.rb +2 -0
- data/stdlib/nodejs/fileutils.rb +2 -0
- data/stdlib/nodejs/io.rb +2 -0
- data/stdlib/nodejs/js-yaml-3-6-1.js +1 -1
- data/stdlib/nodejs/kernel.rb +2 -0
- data/stdlib/nodejs/open-uri.rb +2 -0
- data/stdlib/nodejs/pathname.rb +2 -0
- data/stdlib/nodejs/require.rb +2 -0
- data/stdlib/nodejs/yaml.rb +9 -3
- data/stdlib/opal/miniracer.rb +2 -0
- data/stdlib/opal-parser.rb +8 -1
- data/stdlib/opal-platform.rb +2 -0
- data/stdlib/opal-replutils.rb +2 -0
- data/stdlib/open-uri.rb +4 -1
- data/stdlib/ostruct.rb +4 -2
- data/stdlib/pathname.rb +2 -0
- data/stdlib/pp.rb +1 -0
- data/stdlib/promise/v2.rb +2 -0
- data/stdlib/quickjs/io.rb +2 -0
- data/stdlib/quickjs/kernel.rb +2 -0
- data/stdlib/quickjs.rb +2 -0
- data/stdlib/securerandom.rb +2 -0
- data/stdlib/strscan.rb +2 -0
- data/stdlib/time.rb +2 -0
- data/stdlib/uri.rb +1 -0
- data/tasks/performance/optimization_status.rb +2 -0
- data/tasks/testing.rake +1 -0
- data/test/nodejs/test_await.rb +1 -0
- data/test/nodejs/test_dir.rb +2 -0
- data/test/nodejs/test_error.rb +2 -0
- data/test/nodejs/test_file.rb +2 -0
- data/test/nodejs/test_string.rb +2 -0
- data/test/nodejs/test_yaml.rb +20 -0
- metadata +24 -14
- data/spec/filters/bugs/openstruct.rb +0 -8
data/lib/opal/nodes/if.rb
CHANGED
@@ -349,7 +349,7 @@ module Opal
|
|
349
349
|
@switch_additional_rules = sexp.meta[:switch_additional_rules]
|
350
350
|
compile_switch_case(sexp.meta[:switch_test])
|
351
351
|
else
|
352
|
-
line "switch (", expr(@switch_first_test), ") {"
|
352
|
+
line "switch (", expr(@switch_first_test), ".valueOf()) {"
|
353
353
|
indent do
|
354
354
|
compile_switch_case(@switch_test)
|
355
355
|
end
|
@@ -392,45 +392,53 @@ module Opal
|
|
392
392
|
end
|
393
393
|
end
|
394
394
|
|
395
|
-
class
|
396
|
-
|
397
|
-
|
398
|
-
children :from, :to
|
399
|
-
|
400
|
-
# Is this an exclusive flip flop? If no, run both branches
|
401
|
-
def excl
|
402
|
-
""
|
403
|
-
end
|
395
|
+
class BaseFlipFlop < Base
|
396
|
+
children :start_condition, :end_condition
|
404
397
|
|
405
|
-
# We create a function that we put in the top scope, that stores the state of our
|
406
|
-
# flip-flop. We pass to it functions that are ran with the current binding.
|
407
398
|
def compile
|
408
399
|
helper :truthy
|
409
400
|
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
push "
|
415
|
-
|
416
|
-
|
417
|
-
push "
|
418
|
-
|
419
|
-
|
420
|
-
push "
|
421
|
-
|
422
|
-
|
423
|
-
push "})
|
424
|
-
|
425
|
-
|
401
|
+
func_name = top_scope.new_temp
|
402
|
+
flip_flop_state = "#{func_name}.$$ff"
|
403
|
+
|
404
|
+
# Start function definition, checking and initializing it if necessary
|
405
|
+
push "(#{func_name} = #{func_name} || function(_start_func, _end_func){"
|
406
|
+
|
407
|
+
# If flip flop state is not defined, set it to false
|
408
|
+
push " var flip_flop = #{flip_flop_state} || false;"
|
409
|
+
|
410
|
+
# If flip flop state is false, call the 'start_condition' function and store its truthy result into flip flop state
|
411
|
+
push " if (!flip_flop) #{flip_flop_state} = flip_flop = $truthy(_start_func());"
|
412
|
+
|
413
|
+
# If flip flop state is true, call the 'end_condition' function and set flip flop state to false if 'end_condition' is truthy
|
414
|
+
push " #{excl}if (flip_flop && $truthy(_end_func())) #{flip_flop_state} = false;"
|
415
|
+
|
416
|
+
# Return current state of flip flop
|
417
|
+
push " return flip_flop;"
|
418
|
+
|
419
|
+
# End function definition
|
420
|
+
push "})("
|
421
|
+
|
422
|
+
# Call the function with 'start_condition' and 'end_condition' arguments wrapped in functions to ensure correct binding and delay evaluation
|
423
|
+
push " function() { ", stmt(compiler.returns(start_condition)), " },"
|
424
|
+
push " function() { ", stmt(compiler.returns(end_condition)), " }"
|
426
425
|
push ")"
|
427
426
|
end
|
428
427
|
end
|
429
428
|
|
430
|
-
class
|
429
|
+
class IFlipFlop < BaseFlipFlop
|
430
|
+
handle :iflipflop
|
431
|
+
|
432
|
+
# Inclusive flip flop, check 'end_condition' in the same iteration when 'start_condition' is truthy
|
433
|
+
def excl
|
434
|
+
""
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
class EFlipFlop < BaseFlipFlop
|
431
439
|
handle :eflipflop
|
432
440
|
|
433
|
-
#
|
441
|
+
# Exclusive flip flop, check 'end_condition' in the next iteration after 'start_condition' is truthy
|
434
442
|
def excl
|
435
443
|
"else "
|
436
444
|
end
|
data/lib/opal/nodes/literal.rb
CHANGED
@@ -158,11 +158,15 @@ module Opal
|
|
158
158
|
case value
|
159
159
|
when ''
|
160
160
|
push('/(?:)/')
|
161
|
-
when /\(
|
161
|
+
when /\(\?[(<>#]|[*+?]\+/
|
162
162
|
# Safari/WebKit will not execute javascript code if it contains a lookbehind literal RegExp
|
163
163
|
# and they fail with "Syntax Error". This tricks their parser by disguising the literal RegExp
|
164
164
|
# as string for the dynamic $regexp helper. Safari/Webkit will still fail to execute the RegExp,
|
165
165
|
# but at least they will parse and run everything else.
|
166
|
+
#
|
167
|
+
# Also, let's compile a couple of more patterns into $regexp calls, as there are many syntax
|
168
|
+
# errors in RubySpec when ran in reverse, while there shouldn't be (they should be catchable
|
169
|
+
# errors) - at least since Node 17.
|
166
170
|
static_as_dynamic(value)
|
167
171
|
else
|
168
172
|
push "#{Regexp.new(value).inspect}#{flags.join}"
|
data/lib/opal/nodes/x_string.rb
CHANGED
@@ -6,6 +6,19 @@ module Opal
|
|
6
6
|
handle :xstr
|
7
7
|
|
8
8
|
def compile
|
9
|
+
if compiler.backtick_javascript_or_warn?
|
10
|
+
compile_javascript
|
11
|
+
else
|
12
|
+
compile_send
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def compile_send
|
17
|
+
sexp = s(:send, nil, :`, s(:dstr, *children))
|
18
|
+
push process(sexp, @level)
|
19
|
+
end
|
20
|
+
|
21
|
+
def compile_javascript
|
9
22
|
@should_add_semicolon = false
|
10
23
|
unpacked_children = unpack_return(children)
|
11
24
|
stripped_children = XStringNode.strip_empty_children(unpacked_children)
|
data/lib/opal/parser/patch.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# backtick_javascript: true
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
if RUBY_ENGINE == 'opal'
|
@@ -13,6 +14,12 @@ if RUBY_ENGINE == 'opal'
|
|
13
14
|
else
|
14
15
|
@source_pts = nil
|
15
16
|
end
|
17
|
+
|
18
|
+
# Since parser v3.2.1 Parser::Lexer has @strings
|
19
|
+
if @strings
|
20
|
+
@strings.source_buffer = @source_buffer
|
21
|
+
@strings.source_pts = @source_pts
|
22
|
+
end
|
16
23
|
end
|
17
24
|
end
|
18
25
|
|
@@ -34,40 +34,52 @@ module Opal
|
|
34
34
|
# j = nil
|
35
35
|
# [[1, 2], [3, 4]].each { |__jstmp| i, j = __jstmp }
|
36
36
|
#
|
37
|
-
def on_for(node)
|
38
|
-
loop_variable, iterating_value, loop_body = *node
|
39
37
|
|
40
|
-
|
41
|
-
|
38
|
+
def on_for(node)
|
39
|
+
loop_variable, loop_range, loop_body = *node
|
42
40
|
|
43
|
-
#
|
44
|
-
|
45
|
-
s(:lvdeclare, lvar_name)
|
46
|
-
end
|
41
|
+
# Declare local variables used in the loop and the loop body at the outer scope
|
42
|
+
outer_assignments = generate_outer_assignments(loop_variable, loop_body)
|
47
43
|
|
48
|
-
#
|
44
|
+
# Generate temporary loop variable
|
49
45
|
tmp_loop_variable = self.class.next_tmp
|
50
46
|
get_tmp_loop_variable = s(:js_tmp, tmp_loop_variable)
|
51
47
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
48
|
+
# Assign the loop variables in the loop body
|
49
|
+
loop_body = prepend_to_body(loop_body, assign_loop_variable(loop_variable, get_tmp_loop_variable))
|
50
|
+
|
51
|
+
# Transform the for-loop into each-loop with updated loop body
|
52
|
+
node = transform_for_to_each_loop(node, loop_range, tmp_loop_variable, loop_body)
|
53
|
+
|
54
|
+
node.updated(:begin, [*outer_assignments, node])
|
55
|
+
end
|
60
56
|
|
61
|
-
|
57
|
+
private
|
62
58
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
)
|
59
|
+
def generate_outer_assignments(loop_variable, loop_body)
|
60
|
+
loop_local_vars = LocalVariableAssigns.find(loop_variable)
|
61
|
+
body_local_vars = LocalVariableAssigns.find(loop_body)
|
62
|
+
|
63
|
+
(loop_local_vars + body_local_vars).map { |lvar_name| s(:lvdeclare, lvar_name) }
|
64
|
+
end
|
65
|
+
|
66
|
+
def assign_loop_variable(loop_variable, tmp_loop_variable)
|
67
|
+
case loop_variable.type
|
68
|
+
when :mlhs # multiple left-hand statement like in "for i,j in [[1, 2], [3, 4]]"
|
69
|
+
loop_variable.updated(:masgn, [loop_variable, tmp_loop_variable])
|
70
|
+
else # single argument like "for i in (0..3)"
|
71
|
+
loop_variable << tmp_loop_variable
|
72
|
+
end
|
73
|
+
end
|
68
74
|
|
69
|
-
|
75
|
+
# rubocop:disable Layout/MultilineMethodCallBraceLayout,Layout/MultilineArrayBraceLayout
|
76
|
+
def transform_for_to_each_loop(node, loop_range, tmp_loop_variable, loop_body)
|
77
|
+
node.updated(:send, [loop_range, :each, # (0..3).each {
|
78
|
+
node.updated(:iter, [s(:args, s(:arg, tmp_loop_variable)), # |__jstmp|
|
79
|
+
process(loop_body) # i = __jstmp; j = i + 1 }
|
80
|
+
])])
|
70
81
|
end
|
82
|
+
# rubocop:enable Layout/MultilineMethodCallBraceLayout,Layout/MultilineArrayBraceLayout
|
71
83
|
|
72
84
|
class LocalVariableAssigns < Base
|
73
85
|
attr_reader :result
|
data/lib/opal/source_map/file.rb
CHANGED
@@ -134,7 +134,7 @@ class Opal::SourceMap::File
|
|
134
134
|
absolute_mapping.map do |absolute_segment|
|
135
135
|
segment = []
|
136
136
|
|
137
|
-
segment[0] = absolute_segment[0] -
|
137
|
+
segment[0] = absolute_segment[0] - reference_segment[0]
|
138
138
|
segment[1] = absolute_segment[1] - (reference_segment[1] || 0)
|
139
139
|
segment[2] = absolute_segment[2] - (reference_segment[2] || 0)
|
140
140
|
segment[3] = absolute_segment[3] - (reference_segment[3] || 0)
|
data/lib/opal/version.rb
CHANGED
data/opal/corelib/array/pack.rb
CHANGED
data/opal/corelib/array.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# helpers: truthy, falsy, hash_ids, yield1, hash_get, hash_put, hash_delete, coerce_to, respond_to, deny_frozen_access, freeze
|
2
|
+
# backtick_javascript: true
|
2
3
|
|
3
4
|
require 'corelib/enumerable'
|
4
5
|
require 'corelib/numeric'
|
@@ -68,6 +69,13 @@ class ::Array < `Array`
|
|
68
69
|
|
69
70
|
if (raised) throw raised;
|
70
71
|
}
|
72
|
+
|
73
|
+
function convertToArray(array) {
|
74
|
+
if (!array.$$is_array) {
|
75
|
+
array = $coerce_to(array, #{::Array}, 'to_ary');
|
76
|
+
}
|
77
|
+
return #{`array`.to_a};
|
78
|
+
}
|
71
79
|
}
|
72
80
|
|
73
81
|
def self.[](*objects)
|
@@ -135,13 +143,13 @@ class ::Array < `Array`
|
|
135
143
|
end
|
136
144
|
|
137
145
|
def &(other)
|
138
|
-
other = if ::Array === other
|
139
|
-
other.to_a
|
140
|
-
else
|
141
|
-
`$coerce_to(other, #{::Array}, 'to_ary')`.to_a
|
142
|
-
end
|
143
|
-
|
144
146
|
%x{
|
147
|
+
other = convertToArray(other)
|
148
|
+
|
149
|
+
if (self.length === 0 || other.length === 0) {
|
150
|
+
return [];
|
151
|
+
}
|
152
|
+
|
145
153
|
var result = [], hash = #{{}}, i, length, item;
|
146
154
|
|
147
155
|
for (i = 0, length = other.length; i < length; i++) {
|
@@ -160,11 +168,7 @@ class ::Array < `Array`
|
|
160
168
|
end
|
161
169
|
|
162
170
|
def |(other)
|
163
|
-
other =
|
164
|
-
other.to_a
|
165
|
-
else
|
166
|
-
`$coerce_to(other, #{::Array}, 'to_ary')`.to_a
|
167
|
-
end
|
171
|
+
other = `convertToArray(other)`
|
168
172
|
|
169
173
|
%x{
|
170
174
|
var hash = #{{}}, i, length, item;
|
@@ -203,21 +207,13 @@ class ::Array < `Array`
|
|
203
207
|
end
|
204
208
|
|
205
209
|
def +(other)
|
206
|
-
other =
|
207
|
-
other.to_a
|
208
|
-
else
|
209
|
-
`$coerce_to(other, #{::Array}, 'to_ary')`.to_a
|
210
|
-
end
|
210
|
+
other = `convertToArray(other)`
|
211
211
|
|
212
212
|
`self.concat(other)`
|
213
213
|
end
|
214
214
|
|
215
215
|
def -(other)
|
216
|
-
other =
|
217
|
-
other.to_a
|
218
|
-
else
|
219
|
-
`$coerce_to(other, #{::Array}, 'to_ary')`.to_a
|
220
|
-
end
|
216
|
+
other = `convertToArray(other)`
|
221
217
|
|
222
218
|
return [] if `self.length === 0`
|
223
219
|
return `self.slice()` if `other.length === 0`
|
@@ -696,11 +692,12 @@ class ::Array < `Array`
|
|
696
692
|
return enum_for(:collect) { size } unless block_given?
|
697
693
|
|
698
694
|
%x{
|
699
|
-
var
|
695
|
+
var length = self.length;
|
696
|
+
var result = new Array(length);
|
700
697
|
|
701
|
-
for (var i = 0
|
698
|
+
for (var i = 0; i < length; i++) {
|
702
699
|
var value = $yield1(block, self[i]);
|
703
|
-
result
|
700
|
+
result[i] = value;
|
704
701
|
}
|
705
702
|
|
706
703
|
return result;
|
@@ -849,11 +846,7 @@ class ::Array < `Array`
|
|
849
846
|
`$deny_frozen_access(self)`
|
850
847
|
|
851
848
|
others = others.map do |other|
|
852
|
-
other =
|
853
|
-
other.to_a
|
854
|
-
else
|
855
|
-
`$coerce_to(other, #{::Array}, 'to_ary')`.to_a
|
856
|
-
end
|
849
|
+
`other = convertToArray(other)`
|
857
850
|
|
858
851
|
if other.equal?(self)
|
859
852
|
other = other.dup
|
@@ -1410,11 +1403,54 @@ class ::Array < `Array`
|
|
1410
1403
|
end
|
1411
1404
|
|
1412
1405
|
def intersection(*arrays)
|
1413
|
-
|
1406
|
+
%x{
|
1407
|
+
if (arrays.length === 0) {
|
1408
|
+
return #{to_a.dup};
|
1409
|
+
}
|
1410
|
+
arrays = arrays.map(convertToArray);
|
1411
|
+
if (self.length === 0) {
|
1412
|
+
return [];
|
1413
|
+
}
|
1414
|
+
}
|
1415
|
+
|
1416
|
+
arrays = arrays.sort_by(&:length)
|
1417
|
+
# When self is the smallest among the arrays
|
1418
|
+
if `self.length < arrays[0].length`
|
1419
|
+
return arrays.reduce(self, &:&)
|
1420
|
+
end
|
1421
|
+
|
1422
|
+
# First, calculate intersection of argument arrays.
|
1423
|
+
# Array#& is faster when the argument size is small.
|
1424
|
+
# So `largest & shortest & second_shortest & ...` would be the fastest.
|
1425
|
+
largest = `arrays.pop()`
|
1426
|
+
intersection_of_args = arrays.reduce(largest, &:&)
|
1427
|
+
|
1428
|
+
# self array must come last to maintain the order
|
1429
|
+
self & intersection_of_args
|
1414
1430
|
end
|
1415
1431
|
|
1416
1432
|
def intersect?(other)
|
1417
|
-
|
1433
|
+
%x{
|
1434
|
+
var small, large, hash = #{{}}, i, length;
|
1435
|
+
if (self.length < other.length) {
|
1436
|
+
small = self;
|
1437
|
+
large = other;
|
1438
|
+
} else {
|
1439
|
+
small = other;
|
1440
|
+
large = self;
|
1441
|
+
}
|
1442
|
+
|
1443
|
+
for (i = 0, length = small.length; i < length; i++) {
|
1444
|
+
$hash_put(hash, small[i], true);
|
1445
|
+
}
|
1446
|
+
|
1447
|
+
for (i = 0, length = large.length; i < length; i++) {
|
1448
|
+
if ($hash_get(hash, large[i])) {
|
1449
|
+
return true;
|
1450
|
+
}
|
1451
|
+
}
|
1452
|
+
return false;
|
1453
|
+
}
|
1418
1454
|
end
|
1419
1455
|
|
1420
1456
|
def join(sep = nil)
|
@@ -1762,11 +1798,7 @@ class ::Array < `Array`
|
|
1762
1798
|
def replace(other)
|
1763
1799
|
`$deny_frozen_access(self)`
|
1764
1800
|
|
1765
|
-
other =
|
1766
|
-
other.to_a
|
1767
|
-
else
|
1768
|
-
`$coerce_to(other, #{::Array}, 'to_ary')`.to_a
|
1769
|
-
end
|
1801
|
+
other = `convertToArray(other)`
|
1770
1802
|
|
1771
1803
|
%x{
|
1772
1804
|
self.splice(0, self.length);
|
@@ -1927,9 +1959,9 @@ class ::Array < `Array`
|
|
1927
1959
|
break;
|
1928
1960
|
case 2:
|
1929
1961
|
i = #{rng.rand(`self.length`)};
|
1930
|
-
j = #{rng.rand(`self.length`)};
|
1931
|
-
if (i
|
1932
|
-
j
|
1962
|
+
j = #{rng.rand(`self.length - 1`)};
|
1963
|
+
if (i <= j) {
|
1964
|
+
j++;
|
1933
1965
|
}
|
1934
1966
|
return [self[i], self[j]];
|
1935
1967
|
break;
|
@@ -1981,7 +2013,7 @@ class ::Array < `Array`
|
|
1981
2013
|
result = self.slice();
|
1982
2014
|
|
1983
2015
|
for (var c = 0; c < count; c++) {
|
1984
|
-
targetIndex = #{rng.rand(`self.length`)};
|
2016
|
+
targetIndex = #{rng.rand(`self.length - c`)} + c;
|
1985
2017
|
oldValue = result[c];
|
1986
2018
|
result[c] = result[targetIndex];
|
1987
2019
|
result[targetIndex] = oldValue;
|
@@ -2284,10 +2316,10 @@ class ::Array < `Array`
|
|
2284
2316
|
for (i = 0; i < len; i++) {
|
2285
2317
|
ary = #{::Opal.coerce_to?(`array[i]`, ::Array, :to_ary)};
|
2286
2318
|
if (!ary.$$is_array) {
|
2287
|
-
#{::Kernel.raise ::TypeError, "wrong element type #{`
|
2319
|
+
#{::Kernel.raise ::TypeError, "wrong element type #{`array[i]`.class} at #{`i`} (expected array)"}
|
2288
2320
|
}
|
2289
2321
|
if (ary.length !== 2) {
|
2290
|
-
#{::Kernel.raise ::ArgumentError, "wrong array length at #{`i`} (expected 2, was #{`ary`.length})"}
|
2322
|
+
#{::Kernel.raise ::ArgumentError, "element has wrong array length at #{`i`} (expected 2, was #{`ary`.length})"}
|
2291
2323
|
}
|
2292
2324
|
key = ary[0];
|
2293
2325
|
val = ary[1];
|
@@ -2305,11 +2337,7 @@ class ::Array < `Array`
|
|
2305
2337
|
max = nil
|
2306
2338
|
|
2307
2339
|
each do |row|
|
2308
|
-
row =
|
2309
|
-
row.to_a
|
2310
|
-
else
|
2311
|
-
`$coerce_to(row, #{::Array}, 'to_ary')`.to_a
|
2312
|
-
end
|
2340
|
+
`row = convertToArray(row)`
|
2313
2341
|
|
2314
2342
|
max ||= `row.length`
|
2315
2343
|
|
data/opal/corelib/binding.rb
CHANGED
data/opal/corelib/boolean.rb
CHANGED
data/opal/corelib/class.rb
CHANGED
data/opal/corelib/comparable.rb
CHANGED
data/opal/corelib/complex.rb
CHANGED
data/opal/corelib/constants.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
::RUBY_PLATFORM = 'opal'
|
2
2
|
::RUBY_ENGINE = 'opal'
|
3
3
|
::RUBY_VERSION = '3.2.0'
|
4
|
-
::RUBY_ENGINE_VERSION = '1.
|
5
|
-
::RUBY_RELEASE_DATE = '2023-
|
4
|
+
::RUBY_ENGINE_VERSION = '1.8.0.alpha1'
|
5
|
+
::RUBY_RELEASE_DATE = '2023-08-04'
|
6
6
|
::RUBY_PATCHLEVEL = 0
|
7
7
|
::RUBY_REVISION = '0'
|
8
8
|
::RUBY_COPYRIGHT = 'opal - Copyright (C) 2011-2023 Adam Beynon and the Opal contributors'
|
data/opal/corelib/dir.rb
CHANGED
data/opal/corelib/enumerable.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# helpers: truthy, coerce_to, yield1, yieldX, deny_frozen_access
|
2
|
+
# backtick_javascript: true
|
2
3
|
|
3
4
|
module ::Enumerable
|
4
5
|
%x{
|
@@ -1251,10 +1252,10 @@ module ::Enumerable
|
|
1251
1252
|
var param = #{::Opal.destructure(`arguments`)};
|
1252
1253
|
var ary = #{::Opal.coerce_to?(`param`, ::Array, :to_ary)}, key, val;
|
1253
1254
|
if (!ary.$$is_array) {
|
1254
|
-
#{::Kernel.raise ::TypeError, "wrong element type #{`
|
1255
|
+
#{::Kernel.raise ::TypeError, "wrong element type #{`param`.class} (expected array)"}
|
1255
1256
|
}
|
1256
1257
|
if (ary.length !== 2) {
|
1257
|
-
#{::Kernel.raise ::ArgumentError, "wrong array length (expected 2, was #{`ary`.length})"}
|
1258
|
+
#{::Kernel.raise ::ArgumentError, "element has wrong array length (expected 2, was #{`ary`.length})"}
|
1258
1259
|
}
|
1259
1260
|
key = ary[0];
|
1260
1261
|
val = ary[1];
|
data/opal/corelib/enumerator.rb
CHANGED
data/opal/corelib/error/errno.rb
CHANGED
data/opal/corelib/error.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# backtick_javascript: true
|
2
|
+
|
1
3
|
class ::Exception < `Error`
|
2
4
|
`Opal.prop(self.$$prototype, '$$is_exception', true)`
|
3
5
|
`var stack_trace_limit`
|
@@ -36,6 +38,16 @@ class ::Exception < `Error`
|
|
36
38
|
`self.message = (args.length > 0) ? args[0] : nil`
|
37
39
|
end
|
38
40
|
|
41
|
+
# Those instance variables are not enumerable.
|
42
|
+
def copy_instance_variables(other)
|
43
|
+
super
|
44
|
+
%x{
|
45
|
+
self.message = other.message;
|
46
|
+
self.cause = other.cause;
|
47
|
+
self.stack = other.stack;
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
39
51
|
%x{
|
40
52
|
// Convert backtrace from any format to Ruby format
|
41
53
|
function correct_backtrace(backtrace) {
|