opal 1.2.0 → 1.3.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.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
|
// --------------
|