opal 1.1.1 → 1.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +3 -2
  3. data/.github/ISSUE_TEMPLATE/bug-report.md +47 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  5. data/.github/workflows/build.yml +11 -5
  6. data/.gitignore +1 -0
  7. data/.jshintrc +1 -1
  8. data/Gemfile +0 -4
  9. data/HACKING.md +1 -1
  10. data/README.md +19 -15
  11. data/UNRELEASED.md +41 -0
  12. data/benchmark-ips/bm_array_unshift.rb +7 -0
  13. data/bin/opal-mspec +2 -0
  14. data/docs/compiler.md +1 -1
  15. data/examples/rack/Gemfile +0 -1
  16. data/examples/rack/Gemfile.lock +0 -4
  17. data/lib/opal/cli.rb +1 -0
  18. data/lib/opal/cli_options.rb +4 -0
  19. data/lib/opal/cli_runners/nodejs.rb +4 -0
  20. data/lib/opal/cli_runners/source-map-support-browser.js +3 -1
  21. data/lib/opal/cli_runners/source-map-support-node.js +3 -1
  22. data/lib/opal/cli_runners/source-map-support.js +3 -1
  23. data/lib/opal/compiler.rb +2 -2
  24. data/lib/opal/nodes/args/arity_check.rb +1 -0
  25. data/lib/opal/nodes/args/parameters.rb +6 -0
  26. data/lib/opal/nodes/class.rb +1 -13
  27. data/lib/opal/nodes/literal.rb +14 -7
  28. data/lib/opal/nodes/module.rb +13 -9
  29. data/lib/opal/nodes/variables.rb +13 -4
  30. data/lib/opal/nodes/while.rb +54 -17
  31. data/lib/opal/parser.rb +1 -5
  32. data/lib/opal/parser/patch.rb +34 -0
  33. data/lib/opal/repl.rb +7 -0
  34. data/lib/opal/rewriter.rb +2 -0
  35. data/lib/opal/rewriters/arguments.rb +4 -1
  36. data/lib/opal/rewriters/forward_args.rb +54 -0
  37. data/lib/opal/rewriters/logical_operator_assignment.rb +5 -2
  38. data/lib/opal/rewriters/opal_engine_check.rb +5 -7
  39. data/lib/opal/version.rb +1 -1
  40. data/opal/corelib/array.rb +42 -20
  41. data/opal/corelib/array/pack.rb +6 -1
  42. data/opal/corelib/complex.rb +2 -0
  43. data/opal/corelib/constants.rb +3 -3
  44. data/opal/corelib/hash.rb +36 -38
  45. data/opal/corelib/module.rb +2 -7
  46. data/opal/corelib/number.rb +2 -180
  47. data/opal/corelib/numeric.rb +156 -0
  48. data/opal/corelib/object_space.rb +102 -0
  49. data/opal/corelib/random.rb +31 -66
  50. data/opal/corelib/random/formatter.rb +122 -0
  51. data/opal/corelib/range.rb +50 -19
  52. data/opal/corelib/runtime.js +82 -21
  53. data/opal/corelib/string.rb +86 -52
  54. data/opal/corelib/string/encoding.rb +140 -25
  55. data/opal/corelib/string/unpack.rb +26 -40
  56. data/opal/opal.rb +1 -0
  57. data/opal/opal/full.rb +1 -0
  58. data/spec/filters/bugs/array.rb +0 -22
  59. data/spec/filters/bugs/basicobject.rb +3 -0
  60. data/spec/filters/bugs/encoding.rb +0 -2
  61. data/spec/filters/bugs/exception.rb +1 -0
  62. data/spec/filters/bugs/float.rb +0 -2
  63. data/spec/filters/bugs/hash.rb +2 -7
  64. data/spec/filters/bugs/integer.rb +0 -2
  65. data/spec/filters/bugs/kernel.rb +16 -3
  66. data/spec/filters/bugs/language.rb +6 -14
  67. data/spec/filters/bugs/marshal.rb +1 -3
  68. data/spec/filters/bugs/module.rb +16 -1
  69. data/spec/filters/bugs/numeric.rb +4 -12
  70. data/spec/filters/bugs/objectspace.rb +67 -0
  71. data/spec/filters/bugs/pack_unpack.rb +0 -9
  72. data/spec/filters/bugs/pathname.rb +1 -0
  73. data/spec/filters/bugs/proc.rb +8 -0
  74. data/spec/filters/bugs/random.rb +3 -6
  75. data/spec/filters/bugs/range.rb +83 -113
  76. data/spec/filters/bugs/set.rb +2 -0
  77. data/spec/filters/bugs/string.rb +31 -70
  78. data/spec/filters/bugs/struct.rb +2 -0
  79. data/spec/filters/bugs/time.rb +8 -2
  80. data/spec/filters/unsupported/float.rb +3 -0
  81. data/spec/filters/unsupported/freeze.rb +1 -0
  82. data/spec/filters/unsupported/integer.rb +3 -0
  83. data/spec/filters/unsupported/refinements.rb +5 -0
  84. data/spec/filters/unsupported/string.rb +100 -95
  85. data/spec/filters/unsupported/time.rb +4 -0
  86. data/spec/lib/compiler_spec.rb +16 -0
  87. data/spec/lib/rewriters/forward_args_spec.rb +61 -0
  88. data/spec/lib/rewriters/logical_operator_assignment_spec.rb +1 -1
  89. data/spec/lib/rewriters/numblocks_spec.rb +44 -0
  90. data/spec/lib/rewriters/opal_engine_check_spec.rb +49 -4
  91. data/spec/opal/core/language/forward_args_spec.rb +53 -0
  92. data/spec/opal/core/language/infinite_range_spec.rb +13 -0
  93. data/spec/opal/core/language/memoization_spec.rb +16 -0
  94. data/spec/opal/core/module_spec.rb +38 -2
  95. data/spec/opal/core/number/to_i_spec.rb +28 -0
  96. data/spec/opal/core/runtime/bridged_classes_spec.rb +16 -0
  97. data/spec/opal/core/runtime/constants_spec.rb +20 -1
  98. data/spec/opal/core/string/subclassing_spec.rb +16 -0
  99. data/spec/opal/core/string/unpack_spec.rb +22 -0
  100. data/spec/opal/core/string_spec.rb +4 -4
  101. data/spec/ruby_specs +4 -1
  102. data/stdlib/json.rb +3 -1
  103. data/stdlib/securerandom.rb +55 -35
  104. data/tasks/testing.rake +6 -3
  105. data/test/nodejs/test_string.rb +25 -0
  106. data/vendored-minitest/minitest/assertions.rb +2 -0
  107. metadata +31 -10
  108. data/lib/opal/parser/with_c_lexer.rb +0 -15
@@ -20,7 +20,7 @@ module Opal
20
20
  get_node = lhs.updated(get_type) # lhs
21
21
  condition_node = s(root_type, get_node, rhs) # lhs || rhs
22
22
 
23
- if get_type == :const && root_type == :or
23
+ if %i[const cvar].include?(get_type) && root_type == :or
24
24
  # defined?(lhs)
25
25
  defined_node = s(:defined?, get_node)
26
26
  # LHS = defined?(LHS) ? (LHS || rhs) : rhs
@@ -51,7 +51,10 @@ module Opal
51
51
  GlobalVariableHandler = GET_SET[:gvar, :gvasgn]
52
52
 
53
53
  # Takes `@@lhs ||= rhs`
54
- # Produces `@@lhs = @@lhs || rhs`
54
+ # Produces `@@lhs = defined?(@@lhs) ? (@@lhs || rhs) : rhs`
55
+ #
56
+ # Takes `@@lhs &&= rhs`
57
+ # Produces `@@lhs = @@lhs && rhs`
55
58
  ClassVariableHandler = GET_SET[:cvar, :cvasgn]
56
59
 
57
60
  # Takes `recvr.meth ||= rhs`
@@ -9,14 +9,12 @@ module Opal
9
9
  test, true_body, false_body = *node.children
10
10
 
11
11
  if skip_check_present?(test)
12
- false_body = s(:nil)
12
+ process(true_body || s(:nil))
13
+ elsif skip_check_present_not?(test)
14
+ process(false_body || s(:nil))
15
+ else
16
+ super
13
17
  end
14
-
15
- if skip_check_present_not?(test)
16
- true_body = s(:nil)
17
- end
18
-
19
- node.updated(nil, process_all([test, true_body, false_body]))
20
18
  end
21
19
 
22
20
  def skip_check_present?(test)
data/lib/opal/version.rb CHANGED
@@ -3,5 +3,5 @@
3
3
  module Opal
4
4
  # WHEN RELEASING:
5
5
  # Remember to update RUBY_ENGINE_VERSION in opal/corelib/constants.rb too!
6
- VERSION = '1.1.1'
6
+ VERSION = '1.2.0.beta1'
7
7
  end
@@ -196,7 +196,7 @@ class Array < `Array`
196
196
  result = result.concat(converted);
197
197
  }
198
198
 
199
- return toArraySubclass(result, #{self.class});
199
+ return result;
200
200
  }
201
201
  end
202
202
 
@@ -361,7 +361,7 @@ class Array < `Array`
361
361
  }
362
362
 
363
363
  result = self.slice(from, to);
364
- return toArraySubclass(result, self.$class());
364
+ return result;
365
365
  }
366
366
 
367
367
  function $array_slice_index_length(self, index, length) {
@@ -394,7 +394,7 @@ class Array < `Array`
394
394
 
395
395
  result = self.slice(index, index + length);
396
396
  }
397
- return toArraySubclass(result, self.$class());
397
+ return result;
398
398
  }
399
399
  }
400
400
 
@@ -883,7 +883,9 @@ class Array < `Array`
883
883
  self
884
884
  end
885
885
 
886
- alias difference -
886
+ def difference(*arrays)
887
+ arrays.reduce(to_a.dup) { |a, b| a - b }
888
+ end
887
889
 
888
890
  def dig(idx, *idxs)
889
891
  item = self[idx]
@@ -1180,7 +1182,7 @@ class Array < `Array`
1180
1182
  level = $coerce_to(level, #{Integer}, 'to_int');
1181
1183
  }
1182
1184
 
1183
- return toArraySubclass(_flatten(self, level), #{self.class});
1185
+ return _flatten(self, level);
1184
1186
  }
1185
1187
  end
1186
1188
 
@@ -1335,7 +1337,9 @@ class Array < `Array`
1335
1337
  }
1336
1338
  end
1337
1339
 
1338
- alias intersection &
1340
+ def intersection(*arrays)
1341
+ arrays.reduce(to_a.dup) { |a, b| a & b }
1342
+ end
1339
1343
 
1340
1344
  def join(sep = nil)
1341
1345
  return '' if `self.length === 0`
@@ -2165,10 +2169,19 @@ class Array < `Array`
2165
2169
  end
2166
2170
 
2167
2171
  def to_a
2168
- self
2172
+ %x{
2173
+ if (self.$$class === Opal.Array) {
2174
+ return self;
2175
+ }
2176
+ else {
2177
+ return Opal.Array.$new(self);
2178
+ }
2179
+ }
2169
2180
  end
2170
2181
 
2171
- alias to_ary to_a
2182
+ def to_ary
2183
+ self
2184
+ end
2172
2185
 
2173
2186
  def to_h(&block)
2174
2187
  array = self
@@ -2224,7 +2237,9 @@ class Array < `Array`
2224
2237
  result
2225
2238
  end
2226
2239
 
2227
- alias union |
2240
+ def union(*arrays)
2241
+ arrays.reduce(uniq) { |a, b| a | b }
2242
+ end
2228
2243
 
2229
2244
  def uniq(&block)
2230
2245
  %x{
@@ -2248,7 +2263,7 @@ class Array < `Array`
2248
2263
  }
2249
2264
  }
2250
2265
 
2251
- return toArraySubclass(#{`hash`.values}, #{self.class});
2266
+ return #{`hash`.values};
2252
2267
  }
2253
2268
  end
2254
2269
 
@@ -2276,12 +2291,23 @@ class Array < `Array`
2276
2291
 
2277
2292
  def unshift(*objects)
2278
2293
  %x{
2279
- for (var i = objects.length - 1; i >= 0; i--) {
2280
- self.unshift(objects[i]);
2294
+ var selfLength = self.length
2295
+ var objectsLength = objects.length
2296
+ if (objectsLength == 0) return self;
2297
+ var index = selfLength - objectsLength
2298
+ for (var i = 0; i < objectsLength; i++) {
2299
+ self.push(self[index + i])
2300
+ }
2301
+ var len = selfLength - 1
2302
+ while (len - objectsLength >= 0) {
2303
+ self[len] = self[len - objectsLength]
2304
+ len--
2305
+ }
2306
+ for (var j = 0; j < objectsLength; j++) {
2307
+ self[j] = objects[j]
2281
2308
  }
2309
+ return self;
2282
2310
  }
2283
-
2284
- self
2285
2311
  end
2286
2312
 
2287
2313
  alias prepend unshift
@@ -2332,12 +2358,8 @@ class Array < `Array`
2332
2358
  if (o.$$is_array) {
2333
2359
  continue;
2334
2360
  }
2335
- if (o.$$is_enumerator) {
2336
- if (o.$size() === Infinity) {
2337
- others[j] = o.$take(size);
2338
- } else {
2339
- others[j] = o.$to_a();
2340
- }
2361
+ if (o.$$is_range || o.$$is_enumerator) {
2362
+ others[j] = o.$take(size);
2341
2363
  continue;
2342
2364
  }
2343
2365
  others[j] = #{(
@@ -442,7 +442,12 @@ class Array
442
442
  output = output.concat(part);
443
443
  });
444
444
 
445
- return output;
445
+ if (format.match(/^(U\*?)+$/)) {
446
+ return output;
447
+ }
448
+ else {
449
+ return Opal.enc(output, "binary");
450
+ }
446
451
  }
447
452
  end
448
453
  end
@@ -245,6 +245,8 @@ class Complex < Numeric
245
245
 
246
246
  alias rectangular rect
247
247
 
248
+ undef step
249
+
248
250
  def to_f
249
251
  unless @imag == 0
250
252
  raise RangeError, "can't convert #{self} into Float"
@@ -1,8 +1,8 @@
1
1
  RUBY_PLATFORM = 'opal'
2
2
  RUBY_ENGINE = 'opal'
3
- RUBY_VERSION = '3.0.0'
4
- RUBY_ENGINE_VERSION = '1.1.1'
5
- RUBY_RELEASE_DATE = '2021-02-23'
3
+ RUBY_VERSION = '3.0.2'
4
+ RUBY_ENGINE_VERSION = '1.2.0.beta1'
5
+ RUBY_RELEASE_DATE = '2021-07-23'
6
6
  RUBY_PATCHLEVEL = 0
7
7
  RUBY_REVISION = '0'
8
8
  RUBY_COPYRIGHT = 'opal - Copyright (C) 2013-2021 Adam Beynon and the Opal contributors'
data/opal/corelib/hash.rb CHANGED
@@ -762,53 +762,51 @@ class Hash
762
762
 
763
763
  alias member? has_key?
764
764
 
765
- def merge(other, &block)
766
- dup.merge!(other, &block)
765
+ def merge(*others, &block)
766
+ dup.merge!(*others, &block)
767
767
  end
768
768
 
769
- def merge!(other, &block)
769
+ def merge!(*others, &block)
770
770
  %x{
771
- if (!other.$$is_hash) {
772
- other = #{Opal.coerce_to!(other, Hash, :to_hash)};
773
- }
774
-
775
- var i, other_keys = other.$$keys, length = other_keys.length, key, value, other_value;
776
-
777
- if (block === nil) {
778
- for (i = 0; i < length; i++) {
779
- key = other_keys[i];
780
-
781
- if (key.$$is_string) {
782
- other_value = other.$$smap[key];
783
- } else {
784
- other_value = key.value;
785
- key = key.key;
771
+ var i, j, other, other_keys, length, key, value, other_value;
772
+ for (i = 0; i < others.length; ++i) {
773
+ other = #{Opal.coerce_to!(`others[i]`, Hash, :to_hash)};
774
+ other_keys = other.$$keys, length = other_keys.length;
775
+
776
+ if (block === nil) {
777
+ for (j = 0; j < length; j++) {
778
+ key = other_keys[j];
779
+
780
+ if (key.$$is_string) {
781
+ other_value = other.$$smap[key];
782
+ } else {
783
+ other_value = key.value;
784
+ key = key.key;
785
+ }
786
+
787
+ Opal.hash_put(self, key, other_value);
786
788
  }
789
+ } else {
790
+ for (j = 0; j < length; j++) {
791
+ key = other_keys[j];
787
792
 
788
- Opal.hash_put(self, key, other_value);
789
- }
793
+ if (key.$$is_string) {
794
+ other_value = other.$$smap[key];
795
+ } else {
796
+ other_value = key.value;
797
+ key = key.key;
798
+ }
790
799
 
791
- return self;
792
- }
800
+ value = Opal.hash_get(self, key);
793
801
 
794
- for (i = 0; i < length; i++) {
795
- key = other_keys[i];
802
+ if (value === undefined) {
803
+ Opal.hash_put(self, key, other_value);
804
+ continue;
805
+ }
796
806
 
797
- if (key.$$is_string) {
798
- other_value = other.$$smap[key];
799
- } else {
800
- other_value = key.value;
801
- key = key.key;
802
- }
803
-
804
- value = Opal.hash_get(self, key);
805
-
806
- if (value === undefined) {
807
- Opal.hash_put(self, key, other_value);
808
- continue;
807
+ Opal.hash_put(self, key, block(key, value, other_value));
808
+ }
809
809
  }
810
-
811
- Opal.hash_put(self, key, block(key, value, other_value));
812
810
  }
813
811
 
814
812
  return self;
@@ -204,13 +204,8 @@ class Module
204
204
 
205
205
  def class_variable_get(name)
206
206
  name = Opal.class_variable_name!(name)
207
- %x{
208
- var value = Opal.class_variables(self)[name];
209
- if (value == null) {
210
- #{raise NameError.new("uninitialized class variable #{name} in #{self}", name)}
211
- }
212
- return value;
213
- }
207
+
208
+ `Opal.class_variable_get(self, name, false)`
214
209
  end
215
210
 
216
211
  def class_variable_set(name, value)
@@ -379,7 +379,7 @@ class Number < Numeric
379
379
  end
380
380
 
381
381
  def chr(encoding = undefined)
382
- `String.fromCharCode(self)`
382
+ `Opal.enc(String.fromCharCode(self), encoding || "BINARY")`
383
383
  end
384
384
 
385
385
  def denominator
@@ -668,184 +668,6 @@ class Number < Numeric
668
668
  end
669
669
  end
670
670
 
671
- def step(limit = undefined, step = undefined, to: undefined, by: undefined, &block)
672
- %x{
673
- if (limit !== undefined && to !== undefined) {
674
- #{raise ArgumentError, 'to is given twice'}
675
- }
676
-
677
- if (step !== undefined && by !== undefined) {
678
- #{raise ArgumentError, 'step is given twice'}
679
- }
680
-
681
- function validateParameters() {
682
- if (to !== undefined) {
683
- limit = to;
684
- }
685
-
686
- if (limit === undefined) {
687
- limit = nil;
688
- }
689
-
690
- if (step === nil) {
691
- #{raise TypeError, 'step must be numeric'}
692
- }
693
-
694
- if (step === 0) {
695
- #{raise ArgumentError, "step can't be 0"}
696
- }
697
-
698
- if (by !== undefined) {
699
- step = by;
700
- }
701
-
702
- if (step === nil || step == null) {
703
- step = 1;
704
- }
705
-
706
- var sign = #{step <=> 0};
707
-
708
- if (sign === nil) {
709
- #{raise ArgumentError, "0 can't be coerced into #{step.class}"}
710
- }
711
-
712
- if (limit === nil || limit == null) {
713
- limit = sign > 0 ? #{Float::INFINITY} : #{-Float::INFINITY};
714
- }
715
-
716
- #{Opal.compare(self, limit)}
717
- }
718
-
719
- function stepFloatSize() {
720
- if ((step > 0 && self > limit) || (step < 0 && self < limit)) {
721
- return 0;
722
- } else if (step === Infinity || step === -Infinity) {
723
- return 1;
724
- } else {
725
- var abs = Math.abs, floor = Math.floor,
726
- err = (abs(self) + abs(limit) + abs(limit - self)) / abs(step) * #{Float::EPSILON};
727
-
728
- if (err === Infinity || err === -Infinity) {
729
- return 0;
730
- } else {
731
- if (err > 0.5) {
732
- err = 0.5;
733
- }
734
-
735
- return floor((limit - self) / step + err) + 1
736
- }
737
- }
738
- }
739
-
740
- function stepSize() {
741
- validateParameters();
742
-
743
- if (step === 0) {
744
- return Infinity;
745
- }
746
-
747
- if (step % 1 !== 0) {
748
- return stepFloatSize();
749
- } else if ((step > 0 && self > limit) || (step < 0 && self < limit)) {
750
- return 0;
751
- } else {
752
- var ceil = Math.ceil, abs = Math.abs,
753
- lhs = abs(self - limit) + 1,
754
- rhs = abs(step);
755
-
756
- return ceil(lhs / rhs);
757
- }
758
- }
759
- }
760
-
761
- unless block_given?
762
- positional_args = []
763
- keyword_args = {}
764
-
765
- %x{
766
- if (limit !== undefined) {
767
- positional_args.push(limit);
768
- }
769
-
770
- if (step !== undefined) {
771
- positional_args.push(step);
772
- }
773
-
774
- if (to !== undefined) {
775
- Opal.hash_put(keyword_args, "to", to);
776
- }
777
-
778
- if (by !== undefined) {
779
- Opal.hash_put(keyword_args, "by", by);
780
- }
781
-
782
- if (#{keyword_args.any?}) {
783
- positional_args.push(keyword_args);
784
- }
785
- }
786
-
787
- return enum_for(:step, *positional_args) { `stepSize()` }
788
- end
789
-
790
- %x{
791
- validateParameters();
792
-
793
- if (step === 0) {
794
- while (true) {
795
- block(self);
796
- }
797
- }
798
-
799
- if (self % 1 !== 0 || limit % 1 !== 0 || step % 1 !== 0) {
800
- var n = stepFloatSize();
801
-
802
- if (n > 0) {
803
- if (step === Infinity || step === -Infinity) {
804
- block(self);
805
- } else {
806
- var i = 0, d;
807
-
808
- if (step > 0) {
809
- while (i < n) {
810
- d = i * step + self;
811
- if (limit < d) {
812
- d = limit;
813
- }
814
- block(d);
815
- i += 1;
816
- }
817
- } else {
818
- while (i < n) {
819
- d = i * step + self;
820
- if (limit > d) {
821
- d = limit;
822
- }
823
- block(d);
824
- i += 1
825
- }
826
- }
827
- }
828
- }
829
- } else {
830
- var value = self;
831
-
832
- if (step > 0) {
833
- while (value <= limit) {
834
- block(value);
835
- value += step;
836
- }
837
- } else {
838
- while (value >= limit) {
839
- block(value);
840
- value += step
841
- }
842
- }
843
- }
844
-
845
- return self;
846
- }
847
- end
848
-
849
671
  alias succ next
850
672
 
851
673
  def times(&block)
@@ -865,7 +687,7 @@ class Number < Numeric
865
687
  end
866
688
 
867
689
  def to_i
868
- `parseInt(self, 10)`
690
+ `self < 0 ? Math.ceil(self) : Math.floor(self)`
869
691
  end
870
692
 
871
693
  alias to_int to_i