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/opal/corelib/kernel.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Kernel
|
|
4
4
|
def method_missing(symbol, *args, &block)
|
|
5
|
-
raise NoMethodError.new("undefined method `#{symbol}' for #{inspect}", symbol, args)
|
|
5
|
+
raise NoMethodError.new("undefined method `#{symbol}' for #{inspect}", symbol, args), nil, caller(1)
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
def =~(obj)
|
|
@@ -94,19 +94,18 @@ module Kernel
|
|
|
94
94
|
|
|
95
95
|
def caller(start = 1, length = nil)
|
|
96
96
|
%x{
|
|
97
|
-
var stack, result
|
|
97
|
+
var stack, result;
|
|
98
98
|
|
|
99
|
-
stack =
|
|
100
|
-
result = []
|
|
99
|
+
stack = new Error().$backtrace();
|
|
100
|
+
result = [];
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
result.push(stack[i].replace(/^ *\w+ +/, ''))
|
|
106
|
-
if (length && result.length == length) break
|
|
102
|
+
for (var i = #{start} + 1, ii = stack.length; i < ii; i++) {
|
|
103
|
+
if (!stack[i].match(/runtime\.js/)) {
|
|
104
|
+
result.push(stack[i]);
|
|
107
105
|
}
|
|
108
106
|
}
|
|
109
|
-
|
|
107
|
+
if (length != nil) result = result.slice(0, length);
|
|
108
|
+
return result;
|
|
110
109
|
}
|
|
111
110
|
end
|
|
112
111
|
|
|
@@ -239,6 +238,10 @@ module Kernel
|
|
|
239
238
|
self
|
|
240
239
|
end
|
|
241
240
|
|
|
241
|
+
def gets(*args)
|
|
242
|
+
$stdin.gets(*args)
|
|
243
|
+
end
|
|
244
|
+
|
|
242
245
|
def hash
|
|
243
246
|
__id__
|
|
244
247
|
end
|
|
@@ -247,7 +250,11 @@ module Kernel
|
|
|
247
250
|
end
|
|
248
251
|
|
|
249
252
|
def inspect
|
|
250
|
-
|
|
253
|
+
ivs = ''
|
|
254
|
+
instance_variables.each do |i|
|
|
255
|
+
ivs += " #{i}=#{instance_variable_get(i)}"
|
|
256
|
+
end
|
|
257
|
+
"#<#{self.class}:0x#{__id__.to_s(16)}#{ivs}>"
|
|
251
258
|
end
|
|
252
259
|
|
|
253
260
|
def instance_of?(klass)
|
|
@@ -367,22 +374,26 @@ module Kernel
|
|
|
367
374
|
base = 2;
|
|
368
375
|
return head;
|
|
369
376
|
}
|
|
377
|
+
// no-break
|
|
370
378
|
case '0':
|
|
371
379
|
case '0o':
|
|
372
380
|
if (base === 0 || base === 8) {
|
|
373
381
|
base = 8;
|
|
374
382
|
return head;
|
|
375
383
|
}
|
|
384
|
+
// no-break
|
|
376
385
|
case '0d':
|
|
377
386
|
if (base === 0 || base === 10) {
|
|
378
387
|
base = 10;
|
|
379
388
|
return head;
|
|
380
389
|
}
|
|
390
|
+
// no-break
|
|
381
391
|
case '0x':
|
|
382
392
|
if (base === 0 || base === 16) {
|
|
383
393
|
base = 16;
|
|
384
394
|
return head;
|
|
385
395
|
}
|
|
396
|
+
// no-break
|
|
386
397
|
}
|
|
387
398
|
#{raise ArgumentError, "invalid value for Integer(): \"#{value}\""}
|
|
388
399
|
});
|
|
@@ -516,11 +527,15 @@ module Kernel
|
|
|
516
527
|
$stdout.print(*strs)
|
|
517
528
|
end
|
|
518
529
|
|
|
530
|
+
def readline(*args)
|
|
531
|
+
$stdin.readline(*args)
|
|
532
|
+
end
|
|
533
|
+
|
|
519
534
|
def warn(*strs, uplevel: nil)
|
|
520
535
|
if uplevel
|
|
521
536
|
uplevel = Opal.coerce_to!(uplevel, Integer, :to_str)
|
|
522
537
|
raise ArgumentError, "negative level (#{uplevel})" if uplevel < 0
|
|
523
|
-
location = caller(uplevel +
|
|
538
|
+
location = caller(uplevel + 1, 1).first&.split(':in `')&.first
|
|
524
539
|
location = "#{location}: " if location
|
|
525
540
|
strs = strs.map { |s| "#{location}warning: #{s}" }
|
|
526
541
|
end
|
|
@@ -528,33 +543,38 @@ module Kernel
|
|
|
528
543
|
$stderr.puts(*strs) unless $VERBOSE.nil? || strs.empty?
|
|
529
544
|
end
|
|
530
545
|
|
|
531
|
-
def raise(exception = undefined, string = nil,
|
|
546
|
+
def raise(exception = undefined, string = nil, backtrace = nil)
|
|
532
547
|
%x{
|
|
533
548
|
if (exception == null && #{$!} !== nil) {
|
|
534
549
|
throw #{$!};
|
|
535
550
|
}
|
|
536
551
|
if (exception == null) {
|
|
537
|
-
exception = #{RuntimeError.new};
|
|
552
|
+
exception = #{RuntimeError.new ''};
|
|
538
553
|
}
|
|
539
|
-
else if (exception
|
|
540
|
-
exception = #{RuntimeError.new exception};
|
|
554
|
+
else if ($respond_to(exception, '$to_str')) {
|
|
555
|
+
exception = #{RuntimeError.new exception.to_str};
|
|
541
556
|
}
|
|
542
557
|
// using respond_to? and not an undefined check to avoid method_missing matching as true
|
|
543
|
-
else if (exception.$$is_class &&
|
|
558
|
+
else if (exception.$$is_class && $respond_to(exception, '$exception')) {
|
|
544
559
|
exception = #{exception.exception string};
|
|
545
560
|
}
|
|
546
|
-
else if (
|
|
561
|
+
else if (exception.$$is_exception) {
|
|
547
562
|
// exception is fine
|
|
548
563
|
}
|
|
549
564
|
else {
|
|
550
565
|
exception = #{TypeError.new 'exception class/object expected'};
|
|
551
566
|
}
|
|
552
567
|
|
|
568
|
+
if (backtrace !== nil) {
|
|
569
|
+
exception.$set_backtrace(backtrace);
|
|
570
|
+
}
|
|
571
|
+
|
|
553
572
|
if (#{$!} !== nil) {
|
|
554
573
|
Opal.exceptions.push(#{$!});
|
|
555
574
|
}
|
|
556
575
|
|
|
557
576
|
#{$!} = exception;
|
|
577
|
+
#{$@} = #{`exception`.backtrace};
|
|
558
578
|
|
|
559
579
|
throw exception;
|
|
560
580
|
}
|
|
@@ -687,15 +707,16 @@ module Kernel
|
|
|
687
707
|
"#<#{self.class}:0x#{__id__.to_s(16)}>"
|
|
688
708
|
end
|
|
689
709
|
|
|
690
|
-
def catch(
|
|
691
|
-
|
|
710
|
+
def catch(tag = nil)
|
|
711
|
+
tag ||= Object.new
|
|
712
|
+
yield(tag)
|
|
692
713
|
rescue UncaughtThrowError => e
|
|
693
|
-
return e.
|
|
714
|
+
return e.value if e.tag == tag
|
|
694
715
|
raise
|
|
695
716
|
end
|
|
696
717
|
|
|
697
|
-
def throw(
|
|
698
|
-
raise UncaughtThrowError,
|
|
718
|
+
def throw(tag, obj = nil)
|
|
719
|
+
raise UncaughtThrowError.new(tag, obj)
|
|
699
720
|
end
|
|
700
721
|
|
|
701
722
|
# basic implementation of open, delegate to File.open
|
data/opal/corelib/main.rb
CHANGED
data/opal/corelib/method.rb
CHANGED
data/opal/corelib/module.rb
CHANGED
|
@@ -629,6 +629,8 @@ class Module
|
|
|
629
629
|
`Opal.Module.$name.call(self)` || "#<#{`self.$$is_module ? 'Module' : 'Class'`}:0x#{__id__.to_s(16)}>"
|
|
630
630
|
end
|
|
631
631
|
|
|
632
|
+
alias inspect to_s
|
|
633
|
+
|
|
632
634
|
def undef_method(*names)
|
|
633
635
|
%x{
|
|
634
636
|
for (var i = 0, length = names.length; i < length; i++) {
|
|
@@ -678,4 +680,30 @@ class Module
|
|
|
678
680
|
}
|
|
679
681
|
}
|
|
680
682
|
end
|
|
683
|
+
|
|
684
|
+
def refine(mod, &block)
|
|
685
|
+
s, m, mod_id = self, nil, nil
|
|
686
|
+
%x{
|
|
687
|
+
mod_id = Opal.id(mod);
|
|
688
|
+
if (typeof self.$$refine_modules === "undefined") {
|
|
689
|
+
self.$$refine_modules = {};
|
|
690
|
+
}
|
|
691
|
+
if (typeof self.$$refine_modules[mod_id] === "undefined") {
|
|
692
|
+
m = self.$$refine_modules[mod_id] = #{::Module.new};
|
|
693
|
+
}
|
|
694
|
+
else {
|
|
695
|
+
m = self.$$refine_modules[mod_id];
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
m.define_singleton_method :inspect do
|
|
699
|
+
"#<refinement:#{mod.inspect}@#{s.inspect}>"
|
|
700
|
+
end
|
|
701
|
+
m.class_exec(&block)
|
|
702
|
+
m
|
|
703
|
+
end
|
|
704
|
+
|
|
705
|
+
# Compiler overrides this method
|
|
706
|
+
def using(mod)
|
|
707
|
+
raise 'Module#using is not permitted in methods'
|
|
708
|
+
end
|
|
681
709
|
end
|
data/opal/corelib/number.rb
CHANGED
|
@@ -711,6 +711,11 @@ class Number < Numeric
|
|
|
711
711
|
raise ArgumentError, "invalid radix #{base}"
|
|
712
712
|
end
|
|
713
713
|
|
|
714
|
+
# Don't lose the negative zero
|
|
715
|
+
if self == 0 && `1/self === -Infinity`
|
|
716
|
+
return '-0.0'
|
|
717
|
+
end
|
|
718
|
+
|
|
714
719
|
`self.toString(base)`
|
|
715
720
|
end
|
|
716
721
|
|
|
@@ -747,9 +752,15 @@ class Number < Numeric
|
|
|
747
752
|
end
|
|
748
753
|
|
|
749
754
|
%x{
|
|
755
|
+
if (self != parseInt(self)) #{raise NoMethodError, "undefined method `digits' for #{inspect}"}
|
|
756
|
+
|
|
750
757
|
var value = self, result = [];
|
|
751
758
|
|
|
752
|
-
|
|
759
|
+
if (self == 0) {
|
|
760
|
+
return [0];
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
while (value != 0) {
|
|
753
764
|
result.push(value % base);
|
|
754
765
|
value = parseInt(value / base, 10);
|
|
755
766
|
}
|
|
@@ -2,7 +2,7 @@ class Random
|
|
|
2
2
|
%x{
|
|
3
3
|
var module = { exports: {} };
|
|
4
4
|
|
|
5
|
-
/*
|
|
5
|
+
/* eslint-disable */
|
|
6
6
|
/*
|
|
7
7
|
seedrandom.min.js 2.4.1 (original source: https://github.com/davidbau/seedrandom/blob/2.4.1/seedrandom.min.js)
|
|
8
8
|
How to update:
|
|
@@ -12,7 +12,7 @@ class Random
|
|
|
12
12
|
.. Add a module id for the RequireJS `define` method: https://github.com/Mogztter/seedrandom/commit/e047540c3d81f955cab9a01d17b8141d439fbd7d
|
|
13
13
|
*/
|
|
14
14
|
!function(a,b){function c(c,j,k){var n=[];j=1==j?{entropy:!0}:j||{};var s=g(f(j.entropy?[c,i(a)]:null==c?h():c,3),n),t=new d(n),u=function(){for(var a=t.g(m),b=p,c=0;a<q;)a=(a+c)*l,b*=l,c=t.g(1);for(;a>=r;)a/=2,b/=2,c>>>=1;return(a+c)/b};return u.int32=function(){return 0|t.g(4)},u.quick=function(){return t.g(4)/4294967296},u.double=u,g(i(t.S),a),(j.pass||k||function(a,c,d,f){return f&&(f.S&&e(f,t),a.state=function(){return e(t,{})}),d?(b[o]=a,c):a})(u,s,"global"in j?j.global:this==b,j.state)}function d(a){var b,c=a.length,d=this,e=0,f=d.i=d.j=0,g=d.S=[];for(c||(a=[c++]);e<l;)g[e]=e++;for(e=0;e<l;e++)g[e]=g[f=s&f+a[e%c]+(b=g[e])],g[f]=b;(d.g=function(a){for(var b,c=0,e=d.i,f=d.j,g=d.S;a--;)b=g[e=s&e+1],c=c*l+g[s&(g[e]=g[f=s&f+b])+(g[f]=b)];return d.i=e,d.j=f,c})(l)}function e(a,b){return b.i=a.i,b.j=a.j,b.S=a.S.slice(),b}function f(a,b){var c,d=[],e=typeof a;if(b&&"object"==e)for(c in a)if(a.hasOwnProperty(c))try{d.push(f(a[c],b-1))}catch(a){}return d.length?d:"string"==e?a:a+"\0"}function g(a,b){for(var c,d=a+"",e=0;e<d.length;)b[s&e]=s&(c^=19*b[s&e])+d.charCodeAt(e++);return i(b)}function h(){try{if(j)return i(j.randomBytes(l));var b=new Uint8Array(l);return(k.crypto||k.msCrypto).getRandomValues(b),i(b)}catch(b){var c=k.navigator,d=c&&c.plugins;return[+new Date,k,d,k.screen,i(a)]}}function i(a){return String.fromCharCode.apply(0,a)}var j,k=this,l=256,m=6,n=52,o="random",p=b.pow(l,m),q=b.pow(2,n),r=2*q,s=l-1;if(b["seed"+o]=c,g(b.random(),a),"object"==typeof module&&module.exports){module.exports=c;try{j=require("crypto")}catch(a){}}else"function"==typeof define&&define.amd&&define('seekrandom',function(){return c})}([],Math);
|
|
15
|
-
/*
|
|
15
|
+
/* eslint-enable */
|
|
16
16
|
var seedrandom = module.exports
|
|
17
17
|
var $seed_generator = new Math.seedrandom('opal', { entropy: true })
|
|
18
18
|
}
|
data/opal/corelib/regexp.rb
CHANGED
|
@@ -244,6 +244,20 @@ class Regexp < `RegExp`
|
|
|
244
244
|
}
|
|
245
245
|
end
|
|
246
246
|
|
|
247
|
+
def names
|
|
248
|
+
source.scan(/\(?<(\w+)>/).map(&:first).uniq
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def named_captures
|
|
252
|
+
source.scan(/\(?<(\w+)>/) # Scan for capture groups
|
|
253
|
+
.map(&:first) # Get the first regexp match (\w+)
|
|
254
|
+
.each_with_index # Add index to an iterator
|
|
255
|
+
.group_by(&:first) # Group by the capture group names
|
|
256
|
+
.transform_values do |i| # Convert hash values
|
|
257
|
+
i.map { |j| j.last + 1 } # Drop the capture group names; increase indexes by 1
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
247
261
|
def ~
|
|
248
262
|
self =~ $_
|
|
249
263
|
end
|
|
@@ -304,7 +318,17 @@ class MatchData
|
|
|
304
318
|
end
|
|
305
319
|
|
|
306
320
|
def [](*args)
|
|
307
|
-
|
|
321
|
+
%x{
|
|
322
|
+
if (args[0].$$is_string) {
|
|
323
|
+
if (#{!regexp.names.include?(args[0])}) {
|
|
324
|
+
#{raise IndexError, "undefined group name reference: #{args[0]}"}
|
|
325
|
+
}
|
|
326
|
+
return #{named_captures[args[0]]}
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
return #{@matches[*args]}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
308
332
|
end
|
|
309
333
|
|
|
310
334
|
def offset(n)
|
|
@@ -350,12 +374,32 @@ class MatchData
|
|
|
350
374
|
`#{@matches}.slice(1)`
|
|
351
375
|
end
|
|
352
376
|
|
|
377
|
+
def named_captures
|
|
378
|
+
matches = captures
|
|
379
|
+
regexp.named_captures.transform_values do |i|
|
|
380
|
+
matches[i.last - 1]
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
def names
|
|
385
|
+
regexp.names
|
|
386
|
+
end
|
|
387
|
+
|
|
353
388
|
def inspect
|
|
354
389
|
%x{
|
|
355
390
|
var str = "#<MatchData " + #{`#{@matches}[0]`.inspect};
|
|
356
391
|
|
|
357
|
-
|
|
358
|
-
|
|
392
|
+
if (#{regexp.names.empty?}) {
|
|
393
|
+
for (var i = 1, length = #{@matches}.length; i < length; i++) {
|
|
394
|
+
str += " " + i + ":" + #{`#{@matches}[i]`.inspect};
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
#{ named_captures.each do |k, v|
|
|
399
|
+
%x{
|
|
400
|
+
str += " " + #{k} + ":" + #{v.inspect}
|
|
401
|
+
}
|
|
402
|
+
end }
|
|
359
403
|
}
|
|
360
404
|
|
|
361
405
|
return str + ">";
|
data/opal/corelib/runtime.js
CHANGED
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
Opal.config = {
|
|
66
66
|
missing_require_severity: 'error', // error, warning, ignore
|
|
67
67
|
unsupported_features_severity: 'warning', // error, warning, ignore
|
|
68
|
+
experimental_features_severity: 'warning',// warning, ignore
|
|
68
69
|
enable_stack_trace: true // true, false
|
|
69
70
|
};
|
|
70
71
|
|
|
@@ -111,7 +112,14 @@
|
|
|
111
112
|
// @private
|
|
112
113
|
// Pops an exception from the stack and updates `$!`.
|
|
113
114
|
Opal.pop_exception = function() {
|
|
114
|
-
|
|
115
|
+
var exception = Opal.exceptions.pop();
|
|
116
|
+
if (exception) {
|
|
117
|
+
Opal.gvars["!"] = exception;
|
|
118
|
+
Opal.gvars["@"] = exception.$backtrace();
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
Opal.gvars["!"] = Opal.gvars["@"] = nil;
|
|
122
|
+
}
|
|
115
123
|
};
|
|
116
124
|
|
|
117
125
|
// Inspect any kind of object, including non Ruby ones
|
|
@@ -209,6 +217,22 @@
|
|
|
209
217
|
}
|
|
210
218
|
}
|
|
211
219
|
|
|
220
|
+
// TracePoint support
|
|
221
|
+
// ------------------
|
|
222
|
+
//
|
|
223
|
+
// Support for `TracePoint.trace(:class) do ... end`
|
|
224
|
+
Opal.trace_class = false;
|
|
225
|
+
Opal.tracers_for_class = [];
|
|
226
|
+
|
|
227
|
+
function invoke_tracers_for_class(klass_or_module) {
|
|
228
|
+
var i, ii, tracer;
|
|
229
|
+
|
|
230
|
+
for(i = 0, ii = Opal.tracers_for_class.length; i < ii; i++) {
|
|
231
|
+
tracer = Opal.tracers_for_class[i];
|
|
232
|
+
tracer.trace_object = klass_or_module;
|
|
233
|
+
tracer.block.$call(tracer);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
212
236
|
|
|
213
237
|
// Constants
|
|
214
238
|
// ---------
|
|
@@ -565,6 +589,9 @@
|
|
|
565
589
|
// Make sure existing class has same superclass
|
|
566
590
|
ensureSuperclassMatch(klass, superclass);
|
|
567
591
|
}
|
|
592
|
+
|
|
593
|
+
if (Opal.trace_class) { invoke_tracers_for_class(klass); }
|
|
594
|
+
|
|
568
595
|
return klass;
|
|
569
596
|
}
|
|
570
597
|
|
|
@@ -588,6 +615,8 @@
|
|
|
588
615
|
Opal.bridge(bridged, klass);
|
|
589
616
|
}
|
|
590
617
|
|
|
618
|
+
if (Opal.trace_class) { invoke_tracers_for_class(klass); }
|
|
619
|
+
|
|
591
620
|
return klass;
|
|
592
621
|
};
|
|
593
622
|
|
|
@@ -665,6 +694,9 @@
|
|
|
665
694
|
module = find_existing_module(scope, name);
|
|
666
695
|
|
|
667
696
|
if (module) {
|
|
697
|
+
|
|
698
|
+
if (Opal.trace_class) { invoke_tracers_for_class(module); }
|
|
699
|
+
|
|
668
700
|
return module;
|
|
669
701
|
}
|
|
670
702
|
|
|
@@ -672,6 +704,8 @@
|
|
|
672
704
|
module = Opal.allocate_module(name);
|
|
673
705
|
Opal.const_set(scope, name, module);
|
|
674
706
|
|
|
707
|
+
if (Opal.trace_class) { invoke_tracers_for_class(module); }
|
|
708
|
+
|
|
675
709
|
return module;
|
|
676
710
|
};
|
|
677
711
|
|
|
@@ -1358,9 +1392,10 @@
|
|
|
1358
1392
|
// @return [undefined]
|
|
1359
1393
|
Opal.add_stubs = function(stubs) {
|
|
1360
1394
|
var proto = Opal.BasicObject.$$prototype;
|
|
1395
|
+
var stub, existing_method;
|
|
1361
1396
|
|
|
1362
1397
|
for (var i = 0, length = stubs.length; i < length; i++) {
|
|
1363
|
-
|
|
1398
|
+
stub = stubs[i], existing_method = proto[stub];
|
|
1364
1399
|
|
|
1365
1400
|
if (existing_method == null || existing_method.$$stub) {
|
|
1366
1401
|
Opal.add_stub_for(proto, stub);
|
|
@@ -1375,8 +1410,8 @@
|
|
|
1375
1410
|
// @param stub [String] stub name to add (e.g. "$foo")
|
|
1376
1411
|
// @return [undefined]
|
|
1377
1412
|
Opal.add_stub_for = function(prototype, stub) {
|
|
1378
|
-
|
|
1379
|
-
$defineProperty(prototype, stub,
|
|
1413
|
+
// Opal.stub_for(stub) is the method_missing_stub
|
|
1414
|
+
$defineProperty(prototype, stub, Opal.stub_for(stub));
|
|
1380
1415
|
};
|
|
1381
1416
|
|
|
1382
1417
|
// Generate the method_missing stub for a given method name.
|
|
@@ -1386,8 +1421,6 @@
|
|
|
1386
1421
|
Opal.stub_for = function(method_name) {
|
|
1387
1422
|
|
|
1388
1423
|
function method_missing_stub() {
|
|
1389
|
-
/* jshint validthis: true */
|
|
1390
|
-
|
|
1391
1424
|
// Copy any given block onto the method_missing dispatcher
|
|
1392
1425
|
this.$method_missing.$$p = method_missing_stub.$$p;
|
|
1393
1426
|
|
|
@@ -1443,7 +1476,7 @@
|
|
|
1443
1476
|
};
|
|
1444
1477
|
|
|
1445
1478
|
// Super dispatcher
|
|
1446
|
-
Opal.
|
|
1479
|
+
Opal.find_super = function(obj, mid, current_func, defcheck, allow_stubs) {
|
|
1447
1480
|
var jsid = '$' + mid, ancestors, super_method;
|
|
1448
1481
|
|
|
1449
1482
|
if (obj.hasOwnProperty('$$meta')) {
|
|
@@ -1477,7 +1510,7 @@
|
|
|
1477
1510
|
};
|
|
1478
1511
|
|
|
1479
1512
|
// Iter dispatcher for super in a block
|
|
1480
|
-
Opal.
|
|
1513
|
+
Opal.find_block_super = function(obj, jsid, current_func, defcheck, implicit) {
|
|
1481
1514
|
var call_jsid = jsid;
|
|
1482
1515
|
|
|
1483
1516
|
if (!current_func) {
|
|
@@ -1495,6 +1528,12 @@
|
|
|
1495
1528
|
return Opal.find_super_dispatcher(obj, call_jsid, current_func, defcheck);
|
|
1496
1529
|
};
|
|
1497
1530
|
|
|
1531
|
+
// @deprecated
|
|
1532
|
+
Opal.find_super_dispatcher = Opal.find_super;
|
|
1533
|
+
|
|
1534
|
+
// @deprecated
|
|
1535
|
+
Opal.find_iter_super_dispatcher = Opal.find_block_super;
|
|
1536
|
+
|
|
1498
1537
|
// Used to return as an expression. Sometimes, we can't simply return from
|
|
1499
1538
|
// a javascript function as if we were a method, as the return is used as
|
|
1500
1539
|
// an expression, or even inside a block which must "return" to the outer
|
|
@@ -1773,6 +1812,44 @@
|
|
|
1773
1812
|
return body.apply(recv, args);
|
|
1774
1813
|
};
|
|
1775
1814
|
|
|
1815
|
+
Opal.refined_send = function(refinement_groups, recv, method, args, block) {
|
|
1816
|
+
var i, j, k, ancestors, ancestor, refinements, refinement, refine_modules, refine_module, body;
|
|
1817
|
+
|
|
1818
|
+
if (recv.hasOwnProperty('$$meta')) {
|
|
1819
|
+
ancestors = Opal.ancestors(recv.$$meta);
|
|
1820
|
+
} else {
|
|
1821
|
+
ancestors = Opal.ancestors(recv.$$class);
|
|
1822
|
+
}
|
|
1823
|
+
|
|
1824
|
+
// For all ancestors that there are, starting from the closest to the furthest...
|
|
1825
|
+
for (i = 0; i < ancestors.length; i++) {
|
|
1826
|
+
ancestor = Opal.id(ancestors[i]);
|
|
1827
|
+
// For all refinement groups there are, starting from the closest scope to the furthest...
|
|
1828
|
+
for (j = 0; j < refinement_groups.length; j++) {
|
|
1829
|
+
refinements = refinement_groups[j];
|
|
1830
|
+
// For all refinements there are, starting from the last `using` call to the furthest...
|
|
1831
|
+
for (k = refinements.length - 1; k >= 0; k--) {
|
|
1832
|
+
refinement = refinements[k];
|
|
1833
|
+
if (typeof refinement.$$refine_modules === 'undefined') continue;
|
|
1834
|
+
// A single module being given as an argument of the `using` call contains multiple
|
|
1835
|
+
// refinement modules
|
|
1836
|
+
refine_modules = refinement.$$refine_modules;
|
|
1837
|
+
// Does this module refine a given call for a given ancestor module?
|
|
1838
|
+
if (typeof refine_modules[ancestor] !== 'undefined') {
|
|
1839
|
+
refine_module = refine_modules[ancestor];
|
|
1840
|
+
// Does this module define a method we want to call?
|
|
1841
|
+
if (typeof refine_module.$$prototype['$'+method] !== 'undefined') {
|
|
1842
|
+
body = refine_module.$$prototype['$'+method];
|
|
1843
|
+
return Opal.send2(recv, body, method, args, block);
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
return Opal.send(recv, method, args, block);
|
|
1851
|
+
};
|
|
1852
|
+
|
|
1776
1853
|
Opal.lambda = function(block) {
|
|
1777
1854
|
block.$$is_lambda = true;
|
|
1778
1855
|
return block;
|
|
@@ -1915,9 +1992,16 @@
|
|
|
1915
1992
|
Opal.alias = function(obj, name, old) {
|
|
1916
1993
|
var id = '$' + name,
|
|
1917
1994
|
old_id = '$' + old,
|
|
1918
|
-
body
|
|
1995
|
+
body,
|
|
1919
1996
|
alias;
|
|
1920
1997
|
|
|
1998
|
+
// Aliasing on main means aliasing on Object...
|
|
1999
|
+
if (typeof obj.$$prototype === 'undefined') {
|
|
2000
|
+
obj = Opal.Object;
|
|
2001
|
+
}
|
|
2002
|
+
|
|
2003
|
+
body = obj.$$prototype['$' + old];
|
|
2004
|
+
|
|
1921
2005
|
// When running inside #instance_eval the alias refers to class methods.
|
|
1922
2006
|
if (obj.$$eval) {
|
|
1923
2007
|
return Opal.alias(Opal.get_singleton_class(obj), name, old);
|
|
@@ -1982,6 +2066,20 @@
|
|
|
1982
2066
|
return obj;
|
|
1983
2067
|
};
|
|
1984
2068
|
|
|
2069
|
+
Opal.alias_gvar = function(new_name, old_name) {
|
|
2070
|
+
Object.defineProperty(Opal.gvars, new_name, {
|
|
2071
|
+
configurable: true,
|
|
2072
|
+
enumerable: true,
|
|
2073
|
+
get: function() {
|
|
2074
|
+
return Opal.gvars[old_name];
|
|
2075
|
+
},
|
|
2076
|
+
set: function(new_value) {
|
|
2077
|
+
Opal.gvars[old_name] = new_value;
|
|
2078
|
+
}
|
|
2079
|
+
});
|
|
2080
|
+
return nil;
|
|
2081
|
+
}
|
|
2082
|
+
|
|
1985
2083
|
Opal.alias_native = function(obj, name, native_name) {
|
|
1986
2084
|
var id = '$' + name,
|
|
1987
2085
|
body = obj.$$prototype[native_name];
|
|
@@ -2085,7 +2183,7 @@
|
|
|
2085
2183
|
};
|
|
2086
2184
|
|
|
2087
2185
|
Opal.hash_delete = function(hash, key) {
|
|
2088
|
-
var i, keys = hash.$$keys, length = keys.length, value;
|
|
2186
|
+
var i, keys = hash.$$keys, length = keys.length, value, key_tmp;
|
|
2089
2187
|
|
|
2090
2188
|
if (key.$$is_string) {
|
|
2091
2189
|
if (typeof key !== "string") key = key.valueOf();
|
|
@@ -2095,7 +2193,13 @@
|
|
|
2095
2193
|
}
|
|
2096
2194
|
|
|
2097
2195
|
for (i = 0; i < length; i++) {
|
|
2098
|
-
|
|
2196
|
+
key_tmp = keys[i];
|
|
2197
|
+
|
|
2198
|
+
if (key_tmp.$$is_string && typeof key_tmp !== "string") {
|
|
2199
|
+
key_tmp = key_tmp.valueOf();
|
|
2200
|
+
}
|
|
2201
|
+
|
|
2202
|
+
if (key_tmp === key) {
|
|
2099
2203
|
keys.splice(i, 1);
|
|
2100
2204
|
break;
|
|
2101
2205
|
}
|
|
@@ -2444,7 +2548,12 @@
|
|
|
2444
2548
|
var module = Opal.modules[path];
|
|
2445
2549
|
|
|
2446
2550
|
if (module) {
|
|
2447
|
-
module(Opal);
|
|
2551
|
+
var retval = module(Opal);
|
|
2552
|
+
if (typeof Promise !== 'undefined' && retval instanceof Promise) {
|
|
2553
|
+
// A special case of require having an async top:
|
|
2554
|
+
// We will need to await it.
|
|
2555
|
+
return retval.then(function() { return true; });
|
|
2556
|
+
}
|
|
2448
2557
|
}
|
|
2449
2558
|
else {
|
|
2450
2559
|
var severity = Opal.config.missing_require_severity;
|
|
@@ -2523,6 +2632,37 @@
|
|
|
2523
2632
|
return Opal.set_encoding(dup, "binary", "internal_encoding");
|
|
2524
2633
|
}
|
|
2525
2634
|
|
|
2635
|
+
Opal.last_promise = null;
|
|
2636
|
+
Opal.promise_unhandled_exception = false;
|
|
2637
|
+
|
|
2638
|
+
// Run a block of code, but if it returns a Promise, don't run the next
|
|
2639
|
+
// one, but queue it.
|
|
2640
|
+
Opal.queue = function(proc) {
|
|
2641
|
+
if (Opal.last_promise) {
|
|
2642
|
+
// The async path is taken only if anything before returned a
|
|
2643
|
+
// Promise(V2).
|
|
2644
|
+
Opal.last_promise = Opal.last_promise.then(function() {
|
|
2645
|
+
if (!Opal.promise_unhandled_exception) return proc(Opal);
|
|
2646
|
+
})['catch'](function(error) {
|
|
2647
|
+
if (Opal.respond_to(error, '$full_message')) {
|
|
2648
|
+
error = error.$full_message();
|
|
2649
|
+
}
|
|
2650
|
+
console.error(error);
|
|
2651
|
+
// Abort further execution
|
|
2652
|
+
Opal.promise_unhandled_exception = true;
|
|
2653
|
+
Opal.exit(1);
|
|
2654
|
+
});
|
|
2655
|
+
return Opal.last_promise;
|
|
2656
|
+
}
|
|
2657
|
+
else {
|
|
2658
|
+
var ret = proc(Opal);
|
|
2659
|
+
if (typeof Promise === 'function' && typeof ret === 'object' && ret instanceof Promise) {
|
|
2660
|
+
Opal.last_promise = ret;
|
|
2661
|
+
}
|
|
2662
|
+
return ret;
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2665
|
+
|
|
2526
2666
|
|
|
2527
2667
|
// Initialization
|
|
2528
2668
|
// --------------
|