opal 1.4.0.alpha1 → 1.5.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.eslintrc.js +5 -3
- data/.github/workflows/build.yml +20 -18
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +98 -7
- data/UNRELEASED.md +31 -59
- data/benchmark-ips/bm_js_symbols_vs_strings.rb +39 -14
- data/docs/releasing.md +11 -4
- data/lib/opal/ast/matcher.rb +77 -0
- data/lib/opal/cache.rb +1 -1
- data/lib/opal/cli_runners/applescript.rb +2 -0
- data/lib/opal/compiler.rb +18 -9
- data/lib/opal/nodes/call.rb +73 -28
- data/lib/opal/nodes/def.rb +31 -27
- data/lib/opal/nodes/definitions.rb +2 -0
- data/lib/opal/nodes/helpers.rb +4 -23
- data/lib/opal/nodes/if.rb +226 -0
- data/lib/opal/nodes/iter.rb +41 -37
- data/lib/opal/nodes/literal.rb +2 -2
- data/lib/opal/nodes/masgn.rb +15 -17
- data/lib/opal/nodes/node_with_args/shortcuts.rb +100 -0
- data/lib/opal/nodes/node_with_args.rb +1 -0
- data/lib/opal/nodes/super.rb +9 -9
- data/lib/opal/nodes/top.rb +26 -10
- data/lib/opal/nodes/x_string.rb +27 -28
- data/lib/opal/nodes.rb +0 -1
- data/lib/opal/parser/default_config.rb +3 -2
- data/lib/opal/repl.rb +1 -1
- data/lib/opal/rewriter.rb +13 -6
- data/lib/opal/rewriters/base.rb +12 -1
- data/lib/opal/rewriters/rubyspec/filters_rewriter.rb +1 -0
- data/lib/opal/version.rb +1 -1
- data/opal/corelib/array.rb +23 -28
- data/opal/corelib/binding.rb +14 -4
- data/opal/corelib/constants.rb +3 -3
- data/opal/corelib/hash.rb +2 -2
- data/opal/corelib/irb.rb +192 -0
- data/opal/corelib/math/polyfills.rb +127 -0
- data/opal/corelib/math.rb +14 -194
- data/opal/corelib/module.rb +25 -40
- data/opal/corelib/number.rb +63 -14
- data/opal/corelib/regexp.rb +2 -0
- data/opal/corelib/runtime.js +56 -20
- data/opal/corelib/string.rb +38 -59
- data/opal/corelib/time.rb +106 -68
- data/opal/opal/full.rb +0 -1
- data/opal/opal.rb +4 -1
- data/spec/filters/bugs/date.rb +0 -3
- data/spec/filters/bugs/datetime.rb +65 -0
- data/spec/filters/bugs/float.rb +0 -18
- data/spec/filters/bugs/hash.rb +0 -2
- data/spec/filters/bugs/language.rb +0 -3
- data/spec/filters/bugs/marshal.rb +0 -1
- data/spec/filters/bugs/string.rb +0 -30
- data/spec/filters/bugs/time.rb +18 -8
- data/spec/lib/cli_spec.rb +2 -2
- data/spec/lib/compiler_spec.rb +8 -8
- data/spec/lib/rewriters/base_spec.rb +1 -1
- data/spec/lib/rewriters/binary_operator_assignment_spec.rb +34 -59
- data/spec/lib/rewriters/block_to_iter_spec.rb +3 -6
- data/spec/lib/rewriters/dot_js_syntax_spec.rb +2 -5
- data/spec/lib/rewriters/for_rewriter_spec.rb +0 -1
- data/spec/lib/rewriters/forward_args_spec.rb +2 -3
- data/spec/lib/rewriters/js_reserved_words_spec.rb +2 -15
- data/spec/lib/rewriters/logical_operator_assignment_spec.rb +64 -89
- data/spec/lib/rewriters/numblocks_spec.rb +3 -5
- data/spec/lib/rewriters/opal_engine_check_spec.rb +2 -14
- data/spec/lib/rewriters/rubyspec/filters_rewriter_spec.rb +10 -2
- data/spec/opal/compiler/irb_spec.rb +4 -0
- data/spec/opal/core/language/super_spec.rb +40 -17
- data/spec/opal/core/language/xstring_spec.rb +13 -0
- data/spec/opal/core/regexp/assertions_spec.rb +19 -0
- data/spec/opal/core/string/to_proc_spec.rb +19 -0
- data/spec/ruby_specs +4 -0
- data/spec/support/rewriters_helper.rb +43 -23
- data/stdlib/date/date_time.rb +71 -0
- data/stdlib/date/formatters.rb +28 -0
- data/stdlib/date/infinity.rb +73 -0
- data/stdlib/date.rb +77 -214
- data/stdlib/opal/repl_js.rb +1 -1
- data/stdlib/{opal/replutils.rb → opal-replutils.rb} +3 -3
- data/stdlib/promise/v2.rb +0 -7
- data/stdlib/time.rb +39 -2
- data/stdlib/uri.rb +53 -0
- data/tasks/performance/asciidoctor_test.rb.erb +3 -1
- data/tasks/performance/optimization_status.rb +3 -2
- data/tasks/performance.rake +69 -35
- data/tasks/testing.rake +1 -0
- data/test/opal/test_uri.rb +35 -0
- data/yarn.lock +27 -5
- metadata +30 -16
- data/lib/opal/nodes/csend.rb +0 -24
- data/lib/opal/rewriters/explicit_writer_return.rb +0 -59
- data/spec/lib/rewriters/explicit_writer_return_spec.rb +0 -186
- data/stdlib/nodejs/irb.rb +0 -43
data/lib/opal/nodes/masgn.rb
CHANGED
@@ -11,24 +11,22 @@ module Opal
|
|
11
11
|
children :lhs, :rhs
|
12
12
|
|
13
13
|
def compile
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
14
|
+
with_temp do |array|
|
15
|
+
if rhs.type == :array
|
16
|
+
push "#{array} = ", expr(rhs)
|
17
|
+
rhs_len = rhs.children.any? { |c| c.type == :splat } ? nil : rhs.children.size
|
18
|
+
compile_masgn(lhs.children, array, rhs_len)
|
19
|
+
push ", #{array}" # a mass assignment evaluates to the RHS
|
20
|
+
else
|
21
|
+
helper :to_ary
|
22
|
+
with_temp do |retval|
|
23
|
+
push "#{retval} = ", expr(rhs)
|
24
|
+
push ", #{array} = $to_ary(#{retval})"
|
25
|
+
compile_masgn(lhs.children, array)
|
26
|
+
push ", #{retval}"
|
27
|
+
end
|
28
|
+
end
|
29
29
|
end
|
30
|
-
|
31
|
-
scope.queue_temp(array)
|
32
30
|
end
|
33
31
|
|
34
32
|
# 'len' is how many rhs items are we sure we have
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Opal
|
4
|
+
module Nodes
|
5
|
+
class NodeWithArgs < ScopeNode
|
6
|
+
# Shortcuts for the simplest kinds of methods
|
7
|
+
Shortcut = Struct.new(:name, :for, :when, :transform) do
|
8
|
+
def match?(node)
|
9
|
+
node.instance_exec(&self.when)
|
10
|
+
end
|
11
|
+
|
12
|
+
def compile(node)
|
13
|
+
node.helper name
|
14
|
+
node.instance_exec(&transform)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
@shortcuts = []
|
19
|
+
@shortcuts_for = {}
|
20
|
+
def self.define_shortcut(name, **kwargs, &block)
|
21
|
+
kwargs[:for] ||= :def
|
22
|
+
@shortcuts << Shortcut.new(name, kwargs[:for], kwargs[:when], block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.shortcuts_for(node_type)
|
26
|
+
@shortcuts_for[node_type] ||=
|
27
|
+
@shortcuts.select do |shortcut|
|
28
|
+
[node_type, :*].include? shortcut.for
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def compile_body_or_shortcut
|
33
|
+
# The shortcuts don't check arity. If we want to check arity,
|
34
|
+
# we can't use them.
|
35
|
+
return compile_body if compiler.arity_check?
|
36
|
+
|
37
|
+
node_type = is_a?(DefNode) ? :def : :iter
|
38
|
+
|
39
|
+
NodeWithArgs.shortcuts_for(node_type).each do |shortcut|
|
40
|
+
if shortcut.match?(self)
|
41
|
+
if ENV['OPAL_DEBUG_SHORTCUTS']
|
42
|
+
node_desc = node_type == :def ? "def #{mid}" : "iter"
|
43
|
+
warn "* shortcut #{shortcut.name} used for #{node_desc}"
|
44
|
+
end
|
45
|
+
|
46
|
+
return shortcut.compile(self)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
compile_body
|
51
|
+
end
|
52
|
+
|
53
|
+
# Shortcut definitions
|
54
|
+
# --------------------
|
55
|
+
|
56
|
+
# def a; self; end
|
57
|
+
define_shortcut :return_self, when: -> { stmts.type == :self } do
|
58
|
+
push '$return_self'
|
59
|
+
end
|
60
|
+
|
61
|
+
def simple_value?(node = stmts)
|
62
|
+
%i[true false nil int float str sym].include?(node.type)
|
63
|
+
end
|
64
|
+
|
65
|
+
# def a; 123; end
|
66
|
+
define_shortcut :return_val, for: :*, when: -> { simple_value? } do
|
67
|
+
push '$return_val(', expr(stmts), ')'
|
68
|
+
end
|
69
|
+
|
70
|
+
# def a; @x; end
|
71
|
+
define_shortcut :return_ivar, when: -> { stmts.type == :ivar } do
|
72
|
+
name = stmts.children.first.to_s[1..-1].to_sym
|
73
|
+
push '$return_ivar(', expr(stmts.updated(:sym, [name])), ')'
|
74
|
+
end
|
75
|
+
|
76
|
+
# def a; @x = 5; end
|
77
|
+
define_shortcut :assign_ivar, when: -> {
|
78
|
+
stmts.type == :ivasgn &&
|
79
|
+
inline_args.children.length == 1 &&
|
80
|
+
inline_args.children.last.type == :arg &&
|
81
|
+
stmts.children.last.type == :lvar &&
|
82
|
+
stmts.children.last.children.last == inline_args.children.last.children.last
|
83
|
+
} do
|
84
|
+
name = stmts.children.first.to_s[1..-1].to_sym
|
85
|
+
name = expr(stmts.updated(:sym, [name]))
|
86
|
+
push '$assign_ivar(', name, ')'
|
87
|
+
end
|
88
|
+
|
89
|
+
# def a(x); @x = x; end
|
90
|
+
define_shortcut :assign_ivar_val, when: -> {
|
91
|
+
stmts.type == :ivasgn &&
|
92
|
+
simple_value?(stmts.children.last)
|
93
|
+
} do
|
94
|
+
name = stmts.children.first.to_s[1..-1].to_sym
|
95
|
+
name = expr(stmts.updated(:sym, [name]))
|
96
|
+
push '$assign_ivar_val(', name, ', ', expr(stmts.children.last), ')'
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/lib/opal/nodes/super.rb
CHANGED
@@ -179,28 +179,28 @@ module Opal
|
|
179
179
|
same_arg_counter = Hash.new(0)
|
180
180
|
|
181
181
|
def_scope.original_args.children.each do |sexp|
|
182
|
-
|
182
|
+
lvar_name = sexp.children[0]
|
183
183
|
|
184
184
|
case sexp.type
|
185
185
|
when :arg, :optarg
|
186
|
-
arg_node = s(:lvar,
|
186
|
+
arg_node = s(:lvar, lvar_name)
|
187
187
|
# def m(_, _)
|
188
188
|
# is compiled to
|
189
189
|
# function $$m(_, __$2)
|
190
190
|
# See Opal::Node::ArgsNode
|
191
|
-
if
|
192
|
-
same_arg_counter[
|
193
|
-
arg_node = s(:js_tmp, "#{
|
191
|
+
if lvar_name[0] == '_'
|
192
|
+
same_arg_counter[lvar_name] += 1
|
193
|
+
arg_node = s(:js_tmp, "#{lvar_name}_$#{same_arg_counter[lvar_name]}") if same_arg_counter[lvar_name] > 1
|
194
194
|
end
|
195
|
-
|
196
195
|
args << arg_node
|
197
196
|
when :restarg
|
198
|
-
arg_node =
|
197
|
+
arg_node = lvar_name ? s(:lvar, lvar_name) : s(:js_tmp, '$rest_arg')
|
199
198
|
args << s(:splat, arg_node)
|
200
199
|
when :kwarg, :kwoptarg
|
201
|
-
|
200
|
+
key_name = sexp.meta[:arg_name]
|
201
|
+
kwargs << s(:pair, s(:sym, key_name), s(:lvar, lvar_name))
|
202
202
|
when :kwrestarg
|
203
|
-
arg_node =
|
203
|
+
arg_node = lvar_name ? s(:lvar, lvar_name) : s(:js_tmp, '$kw_rest_arg')
|
204
204
|
kwargs << s(:kwsplat, arg_node)
|
205
205
|
end
|
206
206
|
end
|
data/lib/opal/nodes/top.rb
CHANGED
@@ -14,14 +14,22 @@ module Opal
|
|
14
14
|
|
15
15
|
def compile
|
16
16
|
compiler.top_scope = self
|
17
|
+
compiler.dynamic_cache_result = true if sexp.meta[:dynamic_cache_result]
|
17
18
|
|
18
19
|
push version_comment
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
helper :return_val if compiler.eof_content
|
22
|
+
|
23
|
+
if body == s(:nil)
|
24
|
+
# A shortpath for empty (stub?) modules.
|
25
|
+
if compiler.requirable? || compiler.esm? || compiler.eval?
|
26
|
+
unshift 'Opal.return_val(Opal.nil); '
|
27
|
+
definition
|
24
28
|
else
|
29
|
+
unshift 'Opal.nil; '
|
30
|
+
end
|
31
|
+
else
|
32
|
+
in_scope do
|
25
33
|
line '"use strict";' if compiler.use_strict?
|
26
34
|
|
27
35
|
body_code = stmt(stmts)
|
@@ -47,20 +55,28 @@ module Opal
|
|
47
55
|
|
48
56
|
line body_code
|
49
57
|
end
|
58
|
+
|
59
|
+
opening
|
60
|
+
definition
|
61
|
+
closing
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def definition
|
66
|
+
if compiler.requirable?
|
67
|
+
unshift "Opal.modules[#{Opal::Compiler.module_name(compiler.file).inspect}] = "
|
68
|
+
elsif compiler.esm?
|
69
|
+
unshift 'export default '
|
50
70
|
end
|
51
|
-
opening
|
52
|
-
closing
|
53
71
|
end
|
54
72
|
|
55
73
|
def opening
|
56
74
|
async_prefix = "async " if await_encountered
|
57
75
|
|
58
76
|
if compiler.requirable?
|
59
|
-
unshift "
|
77
|
+
unshift "#{async_prefix}function(Opal) {"
|
60
78
|
elsif compiler.eval?
|
61
79
|
unshift "(#{async_prefix}function(Opal, self) {"
|
62
|
-
elsif compiler.esm?
|
63
|
-
unshift "export default Opal.queue(#{async_prefix}function(Opal) {"
|
64
80
|
else
|
65
81
|
unshift "Opal.queue(#{async_prefix}function(Opal) {"
|
66
82
|
end
|
@@ -108,7 +124,7 @@ module Opal
|
|
108
124
|
def compile_end_construct
|
109
125
|
if content = compiler.eof_content
|
110
126
|
line 'var $__END__ = Opal.Object.$new();'
|
111
|
-
line "$__END__.$read =
|
127
|
+
line "$__END__.$read = $return_val(#{content.inspect});"
|
112
128
|
end
|
113
129
|
end
|
114
130
|
|
data/lib/opal/nodes/x_string.rb
CHANGED
@@ -8,9 +8,9 @@ module Opal
|
|
8
8
|
def compile
|
9
9
|
@should_add_semicolon = false
|
10
10
|
unpacked_children = unpack_return(children)
|
11
|
-
stripped_children = strip_empty_children(unpacked_children)
|
11
|
+
stripped_children = XStringNode.strip_empty_children(unpacked_children)
|
12
12
|
|
13
|
-
if single_line?(stripped_children)
|
13
|
+
if XStringNode.single_line?(stripped_children)
|
14
14
|
# If it's a single line we'll try to:
|
15
15
|
#
|
16
16
|
# - strip empty lines
|
@@ -30,6 +30,31 @@ module Opal
|
|
30
30
|
push ';' if @should_add_semicolon
|
31
31
|
end
|
32
32
|
|
33
|
+
# Check if there's only one child or if they're all part of
|
34
|
+
# the same line (e.g. because of interpolations)
|
35
|
+
def self.single_line?(children)
|
36
|
+
(children.size == 1) || children.none? do |c|
|
37
|
+
c.type == :str && c.loc.expression.source.end_with?("\n")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Will remove empty :str lines coming from cosmetic newlines in x-strings
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
# # this will generate two additional empty
|
45
|
+
# # children before and after `foo()`
|
46
|
+
# %x{
|
47
|
+
# foo()
|
48
|
+
# }
|
49
|
+
def self.strip_empty_children(children)
|
50
|
+
children = children.dup
|
51
|
+
empty_line = ->(child) { child.nil? || (child.type == :str && child.loc.expression.source.rstrip.empty?) }
|
52
|
+
|
53
|
+
children.shift while children.any? && empty_line[children.first]
|
54
|
+
children.pop while children.any? && empty_line[children.last]
|
55
|
+
|
56
|
+
children
|
57
|
+
end
|
33
58
|
|
34
59
|
private
|
35
60
|
|
@@ -97,14 +122,6 @@ module Opal
|
|
97
122
|
last_value
|
98
123
|
end
|
99
124
|
|
100
|
-
# Check if there's only one child or if they're all part of
|
101
|
-
# the same line (e.g. because of interpolations)
|
102
|
-
def single_line?(children)
|
103
|
-
(children.size == 1) || children.none? do |c|
|
104
|
-
c.type == :str && c.loc.expression.source.end_with?("\n")
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
125
|
# A case for manually created :js_return statement in Compiler#returns
|
109
126
|
# Since we need to take original source of :str we have to use raw source
|
110
127
|
# so we need to combine "return" with "raw_source"
|
@@ -119,24 +136,6 @@ module Opal
|
|
119
136
|
|
120
137
|
children
|
121
138
|
end
|
122
|
-
|
123
|
-
# Will remove empty :str lines coming from cosmetic newlines in x-strings
|
124
|
-
#
|
125
|
-
# @example
|
126
|
-
# # this will generate two additional empty
|
127
|
-
# # children before and after `foo()`
|
128
|
-
# %x{
|
129
|
-
# foo()
|
130
|
-
# }
|
131
|
-
def strip_empty_children(children)
|
132
|
-
children = children.dup
|
133
|
-
empty_line = ->(child) { child.nil? || (child.type == :str && child.loc.expression.source.rstrip.empty?) }
|
134
|
-
|
135
|
-
children.shift while children.any? && empty_line[children.first]
|
136
|
-
children.pop while children.any? && empty_line[children.last]
|
137
|
-
|
138
|
-
children
|
139
|
-
end
|
140
139
|
end
|
141
140
|
end
|
142
141
|
end
|
data/lib/opal/nodes.rb
CHANGED
data/lib/opal/repl.rb
CHANGED
data/lib/opal/rewriter.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require 'opal/rewriters/opal_engine_check'
|
4
4
|
require 'opal/rewriters/for_rewriter'
|
5
|
-
require 'opal/rewriters/explicit_writer_return'
|
6
5
|
require 'opal/rewriters/js_reserved_words'
|
7
6
|
require 'opal/rewriters/block_to_iter'
|
8
7
|
require 'opal/rewriters/dot_js_syntax'
|
@@ -19,6 +18,8 @@ require 'opal/rewriters/forward_args'
|
|
19
18
|
|
20
19
|
module Opal
|
21
20
|
class Rewriter
|
21
|
+
@disabled = false
|
22
|
+
|
22
23
|
class << self
|
23
24
|
def list
|
24
25
|
@list ||= []
|
@@ -32,15 +33,21 @@ module Opal
|
|
32
33
|
list.delete(rewriter)
|
33
34
|
end
|
34
35
|
|
35
|
-
def disable
|
36
|
-
|
36
|
+
def disable(except: nil)
|
37
|
+
old_disabled = @disabled
|
38
|
+
@disabled = except || true
|
37
39
|
yield
|
38
40
|
ensure
|
39
|
-
@disabled =
|
41
|
+
@disabled = old_disabled
|
40
42
|
end
|
41
43
|
|
42
44
|
def disabled?
|
43
|
-
@disabled
|
45
|
+
@disabled == true
|
46
|
+
end
|
47
|
+
|
48
|
+
def rewritter_disabled?(rewriter)
|
49
|
+
return false if @disabled == false
|
50
|
+
@disabled != rewriter
|
44
51
|
end
|
45
52
|
end
|
46
53
|
|
@@ -54,7 +61,6 @@ module Opal
|
|
54
61
|
use Rewriters::JsReservedWords
|
55
62
|
use Rewriters::LogicalOperatorAssignment
|
56
63
|
use Rewriters::BinaryOperatorAssignment
|
57
|
-
use Rewriters::ExplicitWriterReturn
|
58
64
|
use Rewriters::Hashes::KeyDuplicatesRewriter
|
59
65
|
use Rewriters::ReturnableLogic
|
60
66
|
use Rewriters::DumpArgs
|
@@ -69,6 +75,7 @@ module Opal
|
|
69
75
|
return @sexp if self.class.disabled?
|
70
76
|
|
71
77
|
self.class.list.each do |rewriter_class|
|
78
|
+
next if self.class.rewritter_disabled?(rewriter_class)
|
72
79
|
rewriter = rewriter_class.new
|
73
80
|
@sexp = rewriter.process(@sexp)
|
74
81
|
end
|
data/lib/opal/rewriters/base.rb
CHANGED
@@ -51,7 +51,6 @@ module Opal
|
|
51
51
|
end
|
52
52
|
|
53
53
|
alias on_iter process_regular_node
|
54
|
-
alias on_top process_regular_node
|
55
54
|
alias on_zsuper process_regular_node
|
56
55
|
alias on_jscall on_send
|
57
56
|
alias on_jsattr process_regular_node
|
@@ -124,6 +123,18 @@ module Opal
|
|
124
123
|
error.location = current_node.loc if current_node
|
125
124
|
raise error
|
126
125
|
end
|
126
|
+
|
127
|
+
def on_top(node)
|
128
|
+
node = process_regular_node(node)
|
129
|
+
node.meta[:dynamic_cache_result] = true if @dynamic_cache_result
|
130
|
+
node
|
131
|
+
end
|
132
|
+
|
133
|
+
# Called when a given transformation is deemed to be dynamic, so
|
134
|
+
# that cache is conditionally disabled for a given file.
|
135
|
+
def dynamic!
|
136
|
+
@dynamic_cache_result = true
|
137
|
+
end
|
127
138
|
end
|
128
139
|
end
|
129
140
|
end
|
data/lib/opal/version.rb
CHANGED
data/opal/corelib/array.rb
CHANGED
@@ -441,20 +441,18 @@ class ::Array < `Array`
|
|
441
441
|
end
|
442
442
|
|
443
443
|
def []=(index, value, extra = undefined)
|
444
|
+
data = nil
|
444
445
|
%x{
|
445
446
|
var i, size = self.length;
|
446
|
-
}
|
447
447
|
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
end
|
448
|
+
if (index.$$is_range) {
|
449
|
+
if (value.$$is_array)
|
450
|
+
data = #{value.to_a};
|
451
|
+
else if (#{value.respond_to? :to_ary})
|
452
|
+
data = #{value.to_ary.to_a};
|
453
|
+
else
|
454
|
+
data = [value];
|
456
455
|
|
457
|
-
%x{
|
458
456
|
var exclude = index.excl,
|
459
457
|
from = index.begin === nil ? 0 : $coerce_to(index.begin, Opal.Integer, 'to_int'),
|
460
458
|
to = index.end === nil ? -1 : $coerce_to(index.end, Opal.Integer, 'to_int');
|
@@ -489,24 +487,21 @@ class ::Array < `Array`
|
|
489
487
|
}
|
490
488
|
|
491
489
|
return value;
|
492
|
-
}
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
end
|
507
|
-
end
|
490
|
+
} else {
|
491
|
+
if (extra === undefined) {
|
492
|
+
#{length = 1}
|
493
|
+
} else {
|
494
|
+
length = value;
|
495
|
+
value = extra;
|
496
|
+
|
497
|
+
if (value.$$is_array)
|
498
|
+
data = #{value.to_a};
|
499
|
+
else if (#{value.respond_to? :to_ary})
|
500
|
+
data = #{value.to_ary.to_a};
|
501
|
+
else
|
502
|
+
data = [value];
|
503
|
+
}
|
508
504
|
|
509
|
-
%x{
|
510
505
|
var old;
|
511
506
|
|
512
507
|
index = $coerce_to(index, #{::Integer}, 'to_int');
|
@@ -540,7 +535,7 @@ class ::Array < `Array`
|
|
540
535
|
|
541
536
|
return value;
|
542
537
|
}
|
543
|
-
|
538
|
+
}
|
544
539
|
end
|
545
540
|
|
546
541
|
def any?(pattern = undefined, &block)
|
data/opal/corelib/binding.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
class ::Binding
|
2
2
|
# @private
|
3
|
-
def initialize(jseval, scope_variables, receiver, source_location)
|
3
|
+
def initialize(jseval, scope_variables = [], receiver = undefined, source_location = nil)
|
4
4
|
@jseval, @scope_variables, @receiver, @source_location = \
|
5
5
|
jseval, scope_variables, receiver, source_location
|
6
|
+
receiver = js_eval('self') unless `typeof receiver !== undefined`
|
6
7
|
end
|
7
8
|
|
8
9
|
def js_eval(*args)
|
@@ -20,7 +21,10 @@ class ::Binding
|
|
20
21
|
end
|
21
22
|
|
22
23
|
def local_variable_set(symbol, value)
|
23
|
-
|
24
|
+
`Opal.Binding.tmp_value = value`
|
25
|
+
js_eval("#{symbol} = Opal.Binding.tmp_value")
|
26
|
+
`delete Opal.Binding.tmp_value`
|
27
|
+
value
|
24
28
|
end
|
25
29
|
|
26
30
|
def local_variables
|
@@ -46,5 +50,11 @@ module ::Kernel
|
|
46
50
|
end
|
47
51
|
end
|
48
52
|
|
49
|
-
TOPLEVEL_BINDING =
|
50
|
-
|
53
|
+
TOPLEVEL_BINDING = ::Binding.new(
|
54
|
+
%x{
|
55
|
+
function(js) {
|
56
|
+
return (new Function("self", "return " + js))(self);
|
57
|
+
}
|
58
|
+
},
|
59
|
+
[], self, ['<main>', 0]
|
60
|
+
)
|
data/opal/corelib/constants.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
::RUBY_PLATFORM = 'opal'
|
2
2
|
::RUBY_ENGINE = 'opal'
|
3
3
|
::RUBY_VERSION = '3.1.0'
|
4
|
-
::RUBY_ENGINE_VERSION = '1.
|
5
|
-
::RUBY_RELEASE_DATE = '
|
4
|
+
::RUBY_ENGINE_VERSION = '1.5.0.rc1'
|
5
|
+
::RUBY_RELEASE_DATE = '2022-04-06'
|
6
6
|
::RUBY_PATCHLEVEL = 0
|
7
7
|
::RUBY_REVISION = '0'
|
8
|
-
::RUBY_COPYRIGHT = 'opal - Copyright (C) 2013-
|
8
|
+
::RUBY_COPYRIGHT = 'opal - Copyright (C) 2013-2022 Adam Beynon and the Opal contributors'
|
9
9
|
::RUBY_DESCRIPTION = "opal #{::RUBY_ENGINE_VERSION} (#{::RUBY_RELEASE_DATE} revision #{::RUBY_REVISION})"
|
data/opal/corelib/hash.rb
CHANGED
@@ -423,7 +423,7 @@ class ::Hash
|
|
423
423
|
return enum_for(:each) { size } unless block
|
424
424
|
|
425
425
|
%x{
|
426
|
-
for (var i = 0, keys = self.$$keys, length = keys.length, key, value; i < length; i++) {
|
426
|
+
for (var i = 0, keys = self.$$keys.slice(), length = keys.length, key, value; i < length; i++) {
|
427
427
|
key = keys[i];
|
428
428
|
|
429
429
|
if (key.$$is_string) {
|
@@ -444,7 +444,7 @@ class ::Hash
|
|
444
444
|
return enum_for(:each_key) { size } unless block
|
445
445
|
|
446
446
|
%x{
|
447
|
-
for (var i = 0, keys = self.$$keys, length = keys.length, key; i < length; i++) {
|
447
|
+
for (var i = 0, keys = self.$$keys.slice(), length = keys.length, key; i < length; i++) {
|
448
448
|
key = keys[i];
|
449
449
|
|
450
450
|
block(key.$$is_string ? key : key.key);
|