opal 1.3.2 → 1.4.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 +0 -3
- data/.rubocop.yml +5 -1
- data/UNRELEASED.md +66 -2
- data/benchmark-ips/bm_truthy.rb +30 -0
- data/bin/opal-mspec +1 -3
- data/bin/opal-repl +1 -2
- data/bin/remove-filters +1 -4
- data/docs/compiled_ruby.md +10 -6
- data/exe/opal-repl +1 -3
- data/lib/opal/ast/builder.rb +1 -1
- data/lib/opal/cli.rb +2 -2
- data/lib/opal/cli_runners/nodejs.rb +9 -2
- data/lib/opal/cli_runners/source-map-support-browser.js +80 -216
- data/lib/opal/cli_runners/source-map-support-node.js +80 -216
- data/lib/opal/cli_runners/source-map-support.js +5 -1
- data/lib/opal/cli_runners/system_runner.rb +10 -4
- data/lib/opal/compiler.rb +3 -5
- data/lib/opal/fragment.rb +5 -1
- data/lib/opal/nodes/args/extract_block_arg.rb +1 -8
- data/lib/opal/nodes/args/extract_kwoptarg.rb +1 -3
- data/lib/opal/nodes/args/extract_optarg.rb +1 -3
- data/lib/opal/nodes/args/extract_post_arg.rb +2 -5
- data/lib/opal/nodes/args/extract_post_optarg.rb +2 -7
- data/lib/opal/nodes/args/initialize_iterarg.rb +1 -3
- data/lib/opal/nodes/args/prepare_post_args.rb +5 -1
- data/lib/opal/nodes/base.rb +3 -2
- data/lib/opal/nodes/call.rb +20 -9
- data/lib/opal/nodes/call_special.rb +50 -0
- data/lib/opal/nodes/class.rb +24 -15
- data/lib/opal/nodes/constants.rb +23 -5
- data/lib/opal/nodes/def.rb +20 -23
- data/lib/opal/nodes/defined.rb +5 -5
- data/lib/opal/nodes/definitions.rb +2 -2
- data/lib/opal/nodes/defs.rb +2 -5
- data/lib/opal/nodes/helpers.rb +48 -18
- data/lib/opal/nodes/if.rb +109 -8
- data/lib/opal/nodes/iter.rb +23 -16
- data/lib/opal/nodes/literal.rb +18 -4
- data/lib/opal/nodes/logic.rb +2 -1
- data/lib/opal/nodes/masgn.rb +4 -9
- data/lib/opal/nodes/module.rb +29 -19
- data/lib/opal/nodes/node_with_args.rb +1 -7
- data/lib/opal/nodes/scope.rb +54 -15
- data/lib/opal/nodes/singleton_class.rb +5 -3
- data/lib/opal/nodes/super.rb +3 -3
- data/lib/opal/nodes/top.rb +34 -31
- data/lib/opal/nodes/variables.rb +2 -2
- data/lib/opal/nodes/x_string.rb +3 -0
- data/lib/opal/nodes.rb +0 -1
- data/lib/opal/parser/patch.rb +75 -0
- data/lib/opal/parser/with_ruby_lexer.rb +1 -1
- data/lib/opal/regexp_anchors.rb +7 -7
- data/lib/opal/requires.rb +19 -0
- data/lib/opal/rewriters/pattern_matching.rb +1 -1
- data/lib/opal/rewriters/returnable_logic.rb +102 -4
- data/lib/opal/util.rb +2 -2
- data/lib/opal/version.rb +1 -1
- data/lib/opal.rb +1 -17
- data/opal/corelib/array/pack.rb +11 -11
- data/opal/corelib/array.rb +193 -152
- data/opal/corelib/basic_object.rb +14 -14
- data/opal/corelib/binding.rb +7 -7
- data/opal/corelib/boolean.rb +12 -15
- data/opal/corelib/class.rb +23 -1
- data/opal/corelib/comparable.rb +8 -8
- data/opal/corelib/complex/base.rb +2 -2
- data/opal/corelib/complex.rb +79 -88
- data/opal/corelib/constants.rb +9 -9
- data/opal/corelib/dir.rb +4 -3
- data/opal/corelib/enumerable.rb +140 -127
- data/opal/corelib/enumerator/arithmetic_sequence.rb +177 -0
- data/opal/corelib/enumerator/chain.rb +42 -0
- data/opal/corelib/enumerator/generator.rb +35 -0
- data/opal/corelib/enumerator/lazy.rb +243 -0
- data/opal/corelib/enumerator/yielder.rb +36 -0
- data/opal/corelib/enumerator.rb +45 -300
- data/opal/corelib/error/errno.rb +47 -0
- data/opal/corelib/error.rb +62 -60
- data/opal/corelib/file.rb +26 -12
- data/opal/corelib/hash.rb +98 -107
- data/opal/corelib/helpers.rb +62 -13
- data/opal/corelib/io.rb +47 -34
- data/opal/corelib/kernel/format.rb +29 -29
- data/opal/corelib/kernel.rb +86 -83
- data/opal/corelib/main.rb +14 -12
- data/opal/corelib/marshal/read_buffer.rb +15 -15
- data/opal/corelib/marshal/write_buffer.rb +45 -44
- data/opal/corelib/marshal.rb +3 -3
- data/opal/corelib/math.rb +50 -50
- data/opal/corelib/method.rb +12 -8
- data/opal/corelib/module.rb +96 -79
- data/opal/corelib/nil.rb +9 -11
- data/opal/corelib/number.rb +113 -118
- data/opal/corelib/numeric.rb +37 -33
- data/opal/corelib/object_space.rb +11 -10
- data/opal/corelib/pack_unpack/format_string_parser.rb +3 -3
- data/opal/corelib/pattern_matching/base.rb +7 -7
- data/opal/corelib/pattern_matching.rb +1 -1
- data/opal/corelib/proc.rb +15 -16
- data/opal/corelib/process/base.rb +2 -2
- data/opal/corelib/process/status.rb +21 -0
- data/opal/corelib/process.rb +5 -5
- data/opal/corelib/random/formatter.rb +11 -11
- data/opal/corelib/random/math_random.js.rb +1 -1
- data/opal/corelib/random/mersenne_twister.rb +3 -3
- data/opal/corelib/random/seedrandom.js.rb +3 -3
- data/opal/corelib/random.rb +17 -17
- data/opal/corelib/range.rb +51 -35
- data/opal/corelib/rational/base.rb +4 -4
- data/opal/corelib/rational.rb +61 -62
- data/opal/corelib/regexp.rb +47 -38
- data/opal/corelib/runtime.js +245 -139
- data/opal/corelib/string/encoding.rb +21 -21
- data/opal/corelib/string/unpack.rb +19 -14
- data/opal/corelib/string.rb +135 -128
- data/opal/corelib/struct.rb +59 -46
- data/opal/corelib/time.rb +47 -57
- data/opal/corelib/trace_point.rb +2 -2
- data/opal/corelib/unsupported.rb +31 -120
- data/opal/corelib/variables.rb +3 -3
- data/opal/opal/base.rb +9 -8
- data/opal/opal/full.rb +8 -8
- data/opal/opal/mini.rb +17 -17
- data/opal/opal.rb +17 -18
- data/opal.gemspec +1 -1
- data/spec/filters/bugs/array.rb +4 -24
- data/spec/filters/bugs/bigdecimal.rb +0 -23
- data/spec/filters/bugs/binding.rb +0 -1
- data/spec/filters/bugs/boolean.rb +3 -0
- data/spec/filters/bugs/class.rb +2 -0
- data/spec/filters/bugs/date.rb +0 -5
- data/spec/filters/bugs/encoding.rb +8 -50
- data/spec/filters/bugs/enumerable.rb +4 -1
- data/spec/filters/bugs/enumerator.rb +3 -36
- data/spec/filters/bugs/exception.rb +0 -2
- data/spec/filters/bugs/file.rb +0 -2
- data/spec/filters/bugs/float.rb +0 -3
- data/spec/filters/bugs/hash.rb +5 -3
- data/spec/filters/bugs/integer.rb +2 -3
- data/spec/filters/bugs/kernel.rb +2 -31
- data/spec/filters/bugs/language.rb +29 -49
- data/spec/filters/bugs/main.rb +0 -2
- data/spec/filters/bugs/marshal.rb +2 -3
- data/spec/filters/bugs/matrix.rb +0 -36
- data/spec/filters/bugs/module.rb +7 -61
- data/spec/filters/bugs/numeric.rb +0 -7
- data/spec/filters/bugs/objectspace.rb +1 -1
- data/spec/filters/bugs/pack_unpack.rb +0 -4
- data/spec/filters/bugs/proc.rb +0 -9
- data/spec/filters/bugs/random.rb +0 -5
- data/spec/filters/bugs/range.rb +1 -6
- data/spec/filters/bugs/regexp.rb +0 -3
- data/spec/filters/bugs/set.rb +8 -1
- data/spec/filters/bugs/string.rb +9 -34
- data/spec/filters/bugs/stringscanner.rb +8 -7
- data/spec/filters/bugs/struct.rb +2 -3
- data/spec/filters/bugs/symbol.rb +0 -1
- data/spec/filters/bugs/time.rb +0 -8
- data/spec/filters/bugs/unboundmethod.rb +0 -8
- data/spec/filters/bugs/warnings.rb +1 -7
- data/spec/filters/unsupported/freeze.rb +24 -0
- data/spec/filters/unsupported/integer.rb +1 -0
- data/spec/filters/unsupported/kernel.rb +12 -0
- data/spec/filters/unsupported/privacy.rb +3 -0
- data/spec/filters/unsupported/string.rb +2 -0
- data/spec/lib/builder_spec.rb +2 -2
- data/spec/lib/cli_spec.rb +1 -1
- data/spec/lib/compiler_spec.rb +37 -37
- data/spec/lib/simple_server_spec.rb +2 -2
- data/spec/lib/source_map/file_spec.rb +1 -1
- data/spec/opal/compiler/irb_spec.rb +2 -2
- data/spec/opal/core/kernel/puts_spec.rb +90 -0
- data/spec/opal/core/language/super_spec.rb +24 -0
- data/spec/ruby_specs +4 -2
- data/spec/support/rewriters_helper.rb +1 -1
- data/stdlib/bigdecimal.rb +7 -11
- data/stdlib/buffer/view.rb +2 -2
- data/stdlib/buffer.rb +2 -2
- data/stdlib/date.rb +5 -6
- data/stdlib/erb.rb +1 -0
- data/stdlib/js.rb +2 -1
- data/stdlib/native.rb +7 -8
- data/stdlib/nodejs/argf.rb +4 -4
- data/stdlib/nodejs/base.rb +29 -0
- data/stdlib/nodejs/dir.rb +1 -1
- data/stdlib/nodejs/env.rb +6 -9
- data/stdlib/nodejs/file.rb +23 -17
- data/stdlib/nodejs/fileutils.rb +3 -3
- data/stdlib/nodejs/io.rb +2 -20
- data/stdlib/nodejs/irb.rb +0 -0
- data/stdlib/nodejs/kernel.rb +2 -37
- data/stdlib/nodejs.rb +1 -3
- data/stdlib/opal/miniracer.rb +2 -0
- data/stdlib/opal/platform.rb +6 -13
- data/stdlib/opal/replutils.rb +16 -5
- data/stdlib/opal-parser.rb +2 -2
- data/stdlib/optparse/ac.rb +54 -0
- data/stdlib/optparse/date.rb +14 -0
- data/stdlib/optparse/kwargs.rb +22 -0
- data/stdlib/optparse/shellwords.rb +7 -0
- data/stdlib/optparse/time.rb +15 -0
- data/stdlib/optparse/uri.rb +7 -0
- data/stdlib/optparse/version.rb +69 -0
- data/stdlib/optparse.rb +2279 -0
- data/stdlib/pathname.rb +5 -6
- data/stdlib/pp.rb +18 -2
- data/stdlib/promise/v2.rb +18 -22
- data/stdlib/promise.rb +15 -21
- data/stdlib/set.rb +32 -32
- data/stdlib/shellwords.rb +240 -0
- data/stdlib/stringio.rb +3 -6
- data/stdlib/strscan.rb +5 -8
- data/stdlib/template.rb +2 -2
- data/stdlib/thread.rb +7 -9
- data/tasks/performance.rake +5 -2
- data/tasks/testing/mspec_special_calls.rb +0 -12
- data/tasks/testing.rake +55 -37
- data/test/nodejs/test_file.rb +11 -0
- metadata +55 -10
- data/lib/opal/nodes/case.rb +0 -114
data/lib/opal/compiler.rb
CHANGED
@@ -205,6 +205,9 @@ module Opal
|
|
205
205
|
# Current scope
|
206
206
|
attr_accessor :scope
|
207
207
|
|
208
|
+
# Top scope
|
209
|
+
attr_accessor :top_scope
|
210
|
+
|
208
211
|
# Current case_stmt
|
209
212
|
attr_reader :case_stmt
|
210
213
|
|
@@ -284,11 +287,6 @@ module Opal
|
|
284
287
|
)
|
285
288
|
end
|
286
289
|
|
287
|
-
# Operator helpers
|
288
|
-
def operator_helpers
|
289
|
-
@operator_helpers ||= Set.new
|
290
|
-
end
|
291
|
-
|
292
290
|
# Method calls made in this file
|
293
291
|
def method_calls
|
294
292
|
@method_calls ||= Set.new
|
data/lib/opal/fragment.rb
CHANGED
@@ -18,15 +18,8 @@ module Opal
|
|
18
18
|
def compile
|
19
19
|
scope.uses_block!
|
20
20
|
scope.add_arg name
|
21
|
-
scope.block_name = name
|
22
21
|
|
23
|
-
|
24
|
-
yielder = scope.block_name
|
25
|
-
|
26
|
-
add_temp "$iter = #{scope_name}.$$p"
|
27
|
-
add_temp "#{yielder} = $iter || nil"
|
28
|
-
|
29
|
-
line "if ($iter) #{scope_name}.$$p = null;"
|
22
|
+
scope.prepare_block(name)
|
30
23
|
end
|
31
24
|
end
|
32
25
|
end
|
@@ -25,9 +25,7 @@ module Opal
|
|
25
25
|
|
26
26
|
return if default_value.children[1] == :undefined
|
27
27
|
|
28
|
-
line "if (#{lvar_name} == null) {"
|
29
|
-
line " #{lvar_name} = ", expr(default_value)
|
30
|
-
line "}"
|
28
|
+
line "if (#{lvar_name} == null) #{lvar_name} = ", expr(default_value)
|
31
29
|
end
|
32
30
|
end
|
33
31
|
end
|
@@ -25,9 +25,7 @@ module Opal
|
|
25
25
|
def compile
|
26
26
|
return if default_value.children[1] == :undefined
|
27
27
|
|
28
|
-
line "if (#{name} == null) {"
|
29
|
-
line " #{name} = ", expr(default_value), ";"
|
30
|
-
line "}"
|
28
|
+
line "if (#{name} == null) #{name} = ", expr(default_value), ";"
|
31
29
|
end
|
32
30
|
end
|
33
31
|
end
|
@@ -15,12 +15,9 @@ module Opal
|
|
15
15
|
def compile
|
16
16
|
add_temp name
|
17
17
|
|
18
|
-
line "#{name} = $post_args
|
19
|
-
line "$post_args.splice(0, 1);"
|
18
|
+
line "#{name} = $post_args.shift();"
|
20
19
|
|
21
|
-
line "if (#{name} == null) {"
|
22
|
-
line " #{name} = nil"
|
23
|
-
line "}"
|
20
|
+
line "if (#{name} == null) #{name} = nil;"
|
24
21
|
end
|
25
22
|
end
|
26
23
|
end
|
@@ -24,16 +24,11 @@ module Opal
|
|
24
24
|
def compile
|
25
25
|
add_temp name
|
26
26
|
|
27
|
-
line "if ($post_args.length > #{args_to_keep}) {"
|
28
|
-
line " #{name} = $post_args[0];"
|
29
|
-
line " $post_args.splice(0, 1);"
|
30
|
-
line "}"
|
27
|
+
line "if ($post_args.length > #{args_to_keep}) #{name} = $post_args.shift();"
|
31
28
|
|
32
29
|
return if default_value.children[1] == :undefined
|
33
30
|
|
34
|
-
line "if (#{name} == null) {"
|
35
|
-
line " #{name} = ", expr(default_value), ";"
|
36
|
-
line "}"
|
31
|
+
line "if (#{name} == null) #{name} = ", expr(default_value), ";"
|
37
32
|
end
|
38
33
|
end
|
39
34
|
end
|
@@ -14,7 +14,11 @@ module Opal
|
|
14
14
|
def compile
|
15
15
|
add_temp '$post_args'
|
16
16
|
|
17
|
-
|
17
|
+
if offset == 0
|
18
|
+
line "$post_args = Opal.slice.call(arguments)"
|
19
|
+
else
|
20
|
+
line "$post_args = Opal.slice.call(arguments, #{offset})"
|
21
|
+
end
|
18
22
|
end
|
19
23
|
end
|
20
24
|
end
|
data/lib/opal/nodes/base.rb
CHANGED
@@ -36,6 +36,7 @@ module Opal
|
|
36
36
|
@type = sexp.type
|
37
37
|
@level = level
|
38
38
|
@compiler = compiler
|
39
|
+
@compiler.top_scope ||= self
|
39
40
|
end
|
40
41
|
|
41
42
|
def children
|
@@ -86,7 +87,7 @@ module Opal
|
|
86
87
|
end
|
87
88
|
|
88
89
|
def top_scope
|
89
|
-
|
90
|
+
@compiler.top_scope
|
90
91
|
end
|
91
92
|
|
92
93
|
def s(type, *children)
|
@@ -199,7 +200,7 @@ module Opal
|
|
199
200
|
|
200
201
|
def class_variable_owner
|
201
202
|
if scope
|
202
|
-
"
|
203
|
+
"#{scope.nesting}[#{class_variable_owner_nesting_level}]"
|
203
204
|
else
|
204
205
|
'Opal.Object'
|
205
206
|
end
|
data/lib/opal/nodes/call.rb
CHANGED
@@ -252,9 +252,11 @@ module Opal
|
|
252
252
|
|
253
253
|
OPERATORS.each do |operator, name|
|
254
254
|
add_special(operator.to_sym) do |compile_default|
|
255
|
-
if
|
255
|
+
if invoke_using_refinement?
|
256
|
+
compile_default.call
|
257
|
+
elsif compiler.inline_operators?
|
256
258
|
compiler.method_calls << operator.to_sym if record_method?
|
257
|
-
|
259
|
+
helper :"rb_#{name}"
|
258
260
|
lhs, rhs = expr(recvr), expr(arglist)
|
259
261
|
|
260
262
|
push fragment("$rb_#{name}(")
|
@@ -281,7 +283,7 @@ module Opal
|
|
281
283
|
dir = File.dirname(file)
|
282
284
|
compiler.requires << Pathname(dir).join(arg.children[0]).cleanpath.to_s
|
283
285
|
end
|
284
|
-
push fragment("self.$require(#{file.inspect}+ '/../' + ")
|
286
|
+
push fragment("#{scope.self}.$require(#{file.inspect}+ '/../' + ")
|
285
287
|
push process(arglist)
|
286
288
|
push fragment(')')
|
287
289
|
end
|
@@ -351,9 +353,9 @@ module Opal
|
|
351
353
|
def using_refinement(arg)
|
352
354
|
prev, curr = *scope.refinements_temp
|
353
355
|
if prev
|
354
|
-
push "(#{curr} = #{prev}.slice(), #{curr}.push(", expr(arg),
|
356
|
+
push "(#{curr} = #{prev}.slice(), #{curr}.push(", expr(arg), "), #{scope.self})"
|
355
357
|
else
|
356
|
-
push "(#{curr} = [", expr(arg),
|
358
|
+
push "(#{curr} = [", expr(arg), "], #{scope.self})"
|
357
359
|
end
|
358
360
|
end
|
359
361
|
|
@@ -373,14 +375,14 @@ module Opal
|
|
373
375
|
|
374
376
|
add_special :nesting do |compile_default|
|
375
377
|
push_nesting = push_nesting?
|
376
|
-
push
|
378
|
+
push "(Opal.Module.$$nesting = #{scope.nesting}, " if push_nesting
|
377
379
|
compile_default.call
|
378
380
|
push ')' if push_nesting
|
379
381
|
end
|
380
382
|
|
381
383
|
add_special :constants do |compile_default|
|
382
384
|
push_nesting = push_nesting?
|
383
|
-
push
|
385
|
+
push "(Opal.Module.$$nesting = #{scope.nesting}, " if push_nesting
|
384
386
|
compile_default.call
|
385
387
|
push ')' if push_nesting
|
386
388
|
end
|
@@ -390,18 +392,27 @@ module Opal
|
|
390
392
|
add_special :eval do |compile_default|
|
391
393
|
next compile_default.call if arglist.children.length != 1 || ![s(:self), nil].include?(recvr)
|
392
394
|
|
395
|
+
scope.nesting
|
393
396
|
temp = scope.new_temp
|
394
397
|
scope_variables = scope.scope_locals.map(&:to_s).inspect
|
395
398
|
push "(#{temp} = ", expr(arglist)
|
396
399
|
push ", typeof Opal.compile === 'function' ? eval(Opal.compile(#{temp}"
|
397
400
|
push ', {scope_variables: ', scope_variables
|
398
401
|
push ", arity_check: #{compiler.arity_check?}, file: '(eval)', eval: true})) : "
|
399
|
-
push "self.$eval(#{temp}))"
|
402
|
+
push "#{scope.self}.$eval(#{temp}))"
|
403
|
+
end
|
404
|
+
|
405
|
+
add_special :local_variables do |compile_default|
|
406
|
+
next compile_default.call unless [s(:self), nil].include?(recvr)
|
407
|
+
|
408
|
+
scope_variables = scope.scope_locals.map(&:to_s).inspect
|
409
|
+
push scope_variables
|
400
410
|
end
|
401
411
|
|
402
412
|
add_special :binding do |compile_default|
|
403
413
|
next compile_default.call unless recvr.nil?
|
404
414
|
|
415
|
+
scope.nesting
|
405
416
|
push "Opal.Binding.$new("
|
406
417
|
push " function($code, $value) {"
|
407
418
|
push " if (typeof $value === 'undefined') {"
|
@@ -412,7 +423,7 @@ module Opal
|
|
412
423
|
push " }"
|
413
424
|
push " },"
|
414
425
|
push " ", scope.scope_locals.map(&:to_s).inspect, ","
|
415
|
-
push " self,"
|
426
|
+
push " ", scope.self, ","
|
416
427
|
push " ", source_location
|
417
428
|
push ")"
|
418
429
|
end
|
@@ -69,6 +69,56 @@ module Opal
|
|
69
69
|
|
70
70
|
def compile
|
71
71
|
sexp = s(:send, lhs, :=~, rhs)
|
72
|
+
# Handle named matches like: /(?<abc>b)/ =~ 'b'
|
73
|
+
if lhs.type == :regexp && lhs.children.first.type == :str
|
74
|
+
re = lhs.children.first.children.first
|
75
|
+
names = re.scan(/\(\?<([^>]*)>/).flatten.map(&:to_sym)
|
76
|
+
unless names.empty?
|
77
|
+
# $m3names = $~ ? $~.named_captures : {}
|
78
|
+
names_def = s(:lvasgn, :$m3names,
|
79
|
+
s(:if,
|
80
|
+
s(:gvar, :$~),
|
81
|
+
s(:send, s(:gvar, :$~), :named_captures),
|
82
|
+
s(:hash)
|
83
|
+
)
|
84
|
+
)
|
85
|
+
|
86
|
+
names = names.map do |name|
|
87
|
+
# abc = $m3names[:abc]
|
88
|
+
s(:lvasgn, name,
|
89
|
+
s(:send,
|
90
|
+
s(:lvar, :$m3names),
|
91
|
+
:[],
|
92
|
+
s(:sym, name)
|
93
|
+
)
|
94
|
+
)
|
95
|
+
end
|
96
|
+
|
97
|
+
if stmt?
|
98
|
+
# We don't care about a return value of this one, so we
|
99
|
+
# ignore it and just assign the local variables.
|
100
|
+
#
|
101
|
+
# (/(?<abc>b)/ =~ 'f')
|
102
|
+
# $m3names = $~ ? $~.named_captures : {}
|
103
|
+
# abc = $m3names[:abc]
|
104
|
+
sexp = s(:begin, sexp, names_def, *names)
|
105
|
+
else
|
106
|
+
# We actually do care about a return value, so we must
|
107
|
+
# keep it saved.
|
108
|
+
#
|
109
|
+
# $m3tmp = (/(?<abc>b)/ =~ 'f')
|
110
|
+
# $m3names = $~ ? $~.named_captures : {}
|
111
|
+
# abc = $m3names[:abc]
|
112
|
+
# $m3tmp
|
113
|
+
sexp = s(:begin,
|
114
|
+
s(:lvasgn, :$m3tmp, sexp),
|
115
|
+
names_def,
|
116
|
+
*names,
|
117
|
+
s(:lvar, :$m3tmp)
|
118
|
+
)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
72
122
|
push process(sexp, @level)
|
73
123
|
end
|
74
124
|
end
|
data/lib/opal/nodes/class.rb
CHANGED
@@ -13,23 +13,32 @@ module Opal
|
|
13
13
|
name, base = name_and_base
|
14
14
|
helper :klass
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
await_begin = '(await '
|
24
|
-
await_end = ')'
|
25
|
-
async = 'async '
|
26
|
-
parent.await_encountered = true
|
16
|
+
if body.nil?
|
17
|
+
# Simplified compile for empty body
|
18
|
+
if stmt?
|
19
|
+
unshift '$klass(', base, ', ', super_code, ", '#{name}')"
|
20
|
+
else
|
21
|
+
unshift '($klass(', base, ', ', super_code, ", '#{name}'), nil)"
|
22
|
+
end
|
27
23
|
else
|
28
|
-
|
24
|
+
line " var self = $klass($base, $super, '#{name}');"
|
25
|
+
in_scope do
|
26
|
+
scope.name = name
|
27
|
+
compile_body
|
28
|
+
end
|
29
|
+
|
30
|
+
if await_encountered
|
31
|
+
await_begin = '(await '
|
32
|
+
await_end = ')'
|
33
|
+
async = 'async '
|
34
|
+
parent.await_encountered = true
|
35
|
+
else
|
36
|
+
await_begin, await_end, async = '', '', ''
|
37
|
+
end
|
38
|
+
|
39
|
+
unshift "#{await_begin}(#{async}function($base, $super#{', $parent_nesting' if @define_nesting}) {"
|
40
|
+
line '})(', base, ', ', super_code, "#{', ' + scope.nesting if @define_nesting})#{await_end}"
|
29
41
|
end
|
30
|
-
|
31
|
-
unshift "#{await_begin}(#{async}function($base, $super, $parent_nesting) {"
|
32
|
-
line '})(', base, ', ', super_code, ", $nesting)#{await_end}"
|
33
42
|
end
|
34
43
|
|
35
44
|
def super_code
|
data/lib/opal/nodes/constants.rb
CHANGED
@@ -12,12 +12,17 @@ module Opal
|
|
12
12
|
def compile
|
13
13
|
if magical_data_const?
|
14
14
|
push('$__END__')
|
15
|
+
elsif optimized_access?
|
16
|
+
helper :"#{name}"
|
17
|
+
push "$#{name}"
|
18
|
+
elsif const_scope == s(:cbase)
|
19
|
+
push "#{top_scope.absolute_const}('#{name}')"
|
15
20
|
elsif const_scope
|
16
|
-
push
|
21
|
+
push "#{top_scope.absolute_const}(", recv(const_scope), ", '#{name}')"
|
17
22
|
elsif compiler.eval?
|
18
|
-
push "
|
23
|
+
push "#{scope.relative_access}('#{name}')"
|
19
24
|
else
|
20
|
-
push "
|
25
|
+
push "#{scope.relative_access}('#{name}')"
|
21
26
|
end
|
22
27
|
end
|
23
28
|
|
@@ -30,6 +35,17 @@ module Opal
|
|
30
35
|
def magical_data_const?
|
31
36
|
const_scope.nil? && name == :DATA && compiler.eof_content
|
32
37
|
end
|
38
|
+
|
39
|
+
OPTIMIZED_ACCESS_CONSTS = %i[
|
40
|
+
BasicObject Object Module Class Opal Kernel NilClass
|
41
|
+
].freeze
|
42
|
+
|
43
|
+
# For a certain case of calls like `::Opal.coerce_to?` we can
|
44
|
+
# optimize the calls. We can be sure they are defined from the
|
45
|
+
# beginning.
|
46
|
+
def optimized_access?
|
47
|
+
const_scope == s(:cbase) && OPTIMIZED_ACCESS_CONSTS.include?(name)
|
48
|
+
end
|
33
49
|
end
|
34
50
|
|
35
51
|
# ::CONST
|
@@ -48,10 +64,12 @@ module Opal
|
|
48
64
|
children :base, :name, :value
|
49
65
|
|
50
66
|
def compile
|
67
|
+
helper :const_set
|
68
|
+
|
51
69
|
if base
|
52
|
-
push '
|
70
|
+
push '$const_set(', expr(base), ", '#{name}', ", expr(value), ')'
|
53
71
|
else
|
54
|
-
push "
|
72
|
+
push "$const_set(#{scope.nesting}[0], '#{name}', ", expr(value), ')'
|
55
73
|
end
|
56
74
|
end
|
57
75
|
end
|
data/lib/opal/nodes/def.rb
CHANGED
@@ -29,7 +29,7 @@ module Opal
|
|
29
29
|
|
30
30
|
compile_block_arg
|
31
31
|
|
32
|
-
add_temp 'self = this'
|
32
|
+
add_temp 'self = this' if @define_self
|
33
33
|
|
34
34
|
compile_arity_check
|
35
35
|
|
@@ -44,50 +44,47 @@ module Opal
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
# There are some special utf8 chars that can be used as valid JS
|
48
|
-
# identifiers, some examples:
|
49
|
-
#
|
50
|
-
# utf8_pond = 'ⵌ'
|
51
|
-
# utf8_question = 'ʔ̣'
|
52
|
-
# utf8_exclamation 'ǃ'
|
53
|
-
#
|
54
|
-
# For now we're just using $$, to maintain compatibility with older IEs.
|
55
|
-
function_name = valid_name?(mid) ? " $$#{mid}" : ''
|
56
|
-
|
57
47
|
unshift ') {'
|
58
48
|
unshift(inline_params)
|
59
|
-
unshift "function#{
|
49
|
+
unshift "function #{scope_name}("
|
60
50
|
if await_encountered
|
61
51
|
unshift "async "
|
62
52
|
end
|
63
|
-
unshift "#{scope_name} = " if scope_name
|
64
53
|
line '}'
|
65
54
|
|
66
|
-
|
55
|
+
blockopts = []
|
56
|
+
|
57
|
+
blockopts << "$$arity: #{arity}"
|
67
58
|
|
68
59
|
if compiler.arity_check?
|
69
|
-
|
60
|
+
blockopts << "$$parameters: #{parameters_code}"
|
70
61
|
end
|
71
62
|
|
72
63
|
if compiler.parse_comments?
|
73
|
-
|
64
|
+
blockopts << "$$comments: #{comments_code}"
|
74
65
|
end
|
75
66
|
|
76
67
|
if compiler.enable_source_location?
|
77
|
-
|
68
|
+
blockopts << "$$source_location: #{source_location}"
|
69
|
+
end
|
70
|
+
|
71
|
+
if blockopts.length == 1
|
72
|
+
push ", #{arity}"
|
73
|
+
elsif blockopts.length > 1
|
74
|
+
push ', {', blockopts.join(', '), '}'
|
78
75
|
end
|
79
76
|
|
80
77
|
wrap_with_definition
|
78
|
+
|
79
|
+
scope.nesting if @define_nesting
|
80
|
+
scope.relative_access if @define_relative_access
|
81
81
|
end
|
82
82
|
|
83
83
|
def wrap_with_definition
|
84
|
-
|
84
|
+
helper :def
|
85
|
+
wrap "$def(#{scope.self}, '$#{mid}', ", ')'
|
85
86
|
|
86
|
-
|
87
|
-
wrap '(', ", nil) && '#{mid}'"
|
88
|
-
else
|
89
|
-
unshift "\n#{current_indent}"
|
90
|
-
end
|
87
|
+
unshift "\n#{current_indent}" unless expr?
|
91
88
|
end
|
92
89
|
|
93
90
|
def comments_code
|
data/lib/opal/nodes/defined.rb
CHANGED
@@ -107,7 +107,7 @@ module Opal
|
|
107
107
|
recv_tmp = scope.new_temp
|
108
108
|
push "(#{recv_tmp} = ", recv_code, ", #{recv_tmp}) && "
|
109
109
|
else
|
110
|
-
recv_tmp =
|
110
|
+
recv_tmp = scope.self
|
111
111
|
end
|
112
112
|
|
113
113
|
recv_value_tmp = scope.new_temp
|
@@ -139,7 +139,7 @@ module Opal
|
|
139
139
|
# we can't tell if it was the user that put nil and made the ivar #defined?
|
140
140
|
# or not.
|
141
141
|
tmp = scope.new_temp
|
142
|
-
push "(#{tmp} = self['#{name}'], #{tmp} != null && #{tmp} !== nil)"
|
142
|
+
push "(#{tmp} = #{scope.self}['#{name}'], #{tmp} != null && #{tmp} !== nil)"
|
143
143
|
|
144
144
|
tmp
|
145
145
|
end
|
@@ -165,12 +165,12 @@ module Opal
|
|
165
165
|
const_tmp = scope.new_temp
|
166
166
|
|
167
167
|
if const_scope.nil?
|
168
|
-
push "(#{const_tmp} =
|
168
|
+
push "(#{const_tmp} = #{scope.relative_access}('#{const_name}', 'skip_raise'))"
|
169
169
|
elsif const_scope == s(:cbase)
|
170
|
-
push "(#{const_tmp} =
|
170
|
+
push "(#{const_tmp} = #{top_scope.absolute_const}('::', '#{const_name}', 'skip_raise'))"
|
171
171
|
else
|
172
172
|
const_scope_tmp = compile_defined(const_scope)
|
173
|
-
push " && (#{const_tmp} =
|
173
|
+
push " && (#{const_tmp} = #{top_scope.absolute_const}(#{const_scope_tmp}, '#{const_name}', 'skip_raise'))"
|
174
174
|
end
|
175
175
|
const_tmp
|
176
176
|
end
|
@@ -11,7 +11,7 @@ module Opal
|
|
11
11
|
|
12
12
|
def compile
|
13
13
|
children.each do |child|
|
14
|
-
line "Opal.udef(self, '$' + ", expr(child), ');'
|
14
|
+
line "Opal.udef(#{scope.self}, '$' + ", expr(child), ');'
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -31,7 +31,7 @@ module Opal
|
|
31
31
|
push '$alias_gvar(', new_name_str, ', ', old_name_str, ')'
|
32
32
|
when :dsym, :sym # This is a method alias: alias a b
|
33
33
|
helper :alias
|
34
|
-
push
|
34
|
+
push "$alias(#{scope.self}, ", expr(new_name), ', ', expr(old_name), ')'
|
35
35
|
else # Nothing else is available, but just in case, drop an error
|
36
36
|
error "Opal doesn't know yet how to alias with #{new_name.type}"
|
37
37
|
end
|
data/lib/opal/nodes/defs.rb
CHANGED
@@ -9,12 +9,9 @@ module Opal
|
|
9
9
|
children :recvr, :mid, :inline_args, :stmts
|
10
10
|
|
11
11
|
def wrap_with_definition
|
12
|
-
|
12
|
+
helper :defs
|
13
|
+
unshift '$defs(', expr(recvr), ", '$#{mid}', "
|
13
14
|
push ')'
|
14
|
-
|
15
|
-
if expr?
|
16
|
-
wrap '(', ", nil) && '#{mid}'"
|
17
|
-
end
|
18
15
|
end
|
19
16
|
end
|
20
17
|
end
|
data/lib/opal/nodes/helpers.rb
CHANGED
@@ -52,23 +52,11 @@ module Opal
|
|
52
52
|
[fragment('$truthy('), expr(sexp), fragment(')')]
|
53
53
|
end
|
54
54
|
|
55
|
-
def js_falsy(sexp)
|
56
|
-
if sexp.type == :send
|
57
|
-
mid = sexp.children[1]
|
58
|
-
if mid == :block_given?
|
59
|
-
scope.uses_block!
|
60
|
-
return "#{scope.block_name} === nil"
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
helper :falsy
|
65
|
-
[fragment('$falsy('), expr(sexp), fragment(')')]
|
66
|
-
end
|
67
|
-
|
68
55
|
def js_truthy_optimize(sexp)
|
69
|
-
|
70
|
-
|
71
|
-
|
56
|
+
case sexp.type
|
57
|
+
when :send
|
58
|
+
receiver, mid, *args = *sexp
|
59
|
+
receiver_handler_class = receiver && compiler.handlers[receiver.type]
|
72
60
|
|
73
61
|
# Only operator calls on the truthy_optimize? node classes should be optimized.
|
74
62
|
# Monkey patch method calls might return 'self'/aka a bridged instance and need
|
@@ -78,8 +66,50 @@ module Opal
|
|
78
66
|
receiver_handler_class.truthy_optimize?
|
79
67
|
|
80
68
|
if allow_optimization_on_type ||
|
81
|
-
mid == :block_given?
|
82
|
-
|
69
|
+
mid == :block_given?
|
70
|
+
expr(sexp)
|
71
|
+
elsif args.count == 1
|
72
|
+
case mid
|
73
|
+
when :==
|
74
|
+
helper :eqeq
|
75
|
+
compiler.method_calls << mid
|
76
|
+
[fragment('$eqeq('), expr(receiver), fragment(', '), expr(args.first), fragment(')')]
|
77
|
+
when :===
|
78
|
+
helper :eqeqeq
|
79
|
+
compiler.method_calls << mid
|
80
|
+
[fragment('$eqeqeq('), expr(receiver), fragment(', '), expr(args.first), fragment(')')]
|
81
|
+
when :!=
|
82
|
+
helper :neqeq
|
83
|
+
compiler.method_calls << mid
|
84
|
+
[fragment('$neqeq('), expr(receiver), fragment(', '), expr(args.first), fragment(')')]
|
85
|
+
end
|
86
|
+
elsif args.count == 0
|
87
|
+
case mid
|
88
|
+
when :!
|
89
|
+
helper :not
|
90
|
+
compiler.method_calls << mid
|
91
|
+
[fragment('$not('), expr(receiver), fragment(')')]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
when :begin
|
95
|
+
if sexp.children.count == 1
|
96
|
+
js_truthy_optimize(sexp.children.first)
|
97
|
+
end
|
98
|
+
when :if
|
99
|
+
_test, true_body, false_body = *sexp
|
100
|
+
if true_body == s(:true)
|
101
|
+
# Ensure we recurse the js_truthy call on the `false_body` of the if `expr`.
|
102
|
+
# This transforms an expression like:
|
103
|
+
#
|
104
|
+
# $truthy($truthy(a) || b)
|
105
|
+
#
|
106
|
+
# Into:
|
107
|
+
#
|
108
|
+
# $truthy(a) || $truthy(b)
|
109
|
+
sexp.meta[:do_js_truthy_on_false_body] = true
|
110
|
+
expr(sexp)
|
111
|
+
elsif false_body == s(:false)
|
112
|
+
sexp.meta[:do_js_truthy_on_true_body] = true
|
83
113
|
expr(sexp)
|
84
114
|
end
|
85
115
|
end
|