opal 0.5.2 → 0.5.4

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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -0
  3. data/lib/opal.rb +0 -5
  4. data/lib/opal/compiler.rb +24 -44
  5. data/lib/opal/nodes/base.rb +5 -8
  6. data/lib/opal/nodes/call.rb +4 -0
  7. data/lib/opal/nodes/class.rb +6 -7
  8. data/lib/opal/nodes/def.rb +4 -4
  9. data/lib/opal/nodes/definitions.rb +0 -14
  10. data/lib/opal/nodes/iter.rb +51 -38
  11. data/lib/opal/nodes/literal.rb +21 -24
  12. data/lib/opal/nodes/module.rb +4 -4
  13. data/lib/opal/nodes/runtime_helpers.rb +45 -0
  14. data/lib/opal/nodes/scope.rb +280 -0
  15. data/lib/opal/nodes/singleton_class.rb +4 -5
  16. data/lib/opal/nodes/super.rb +1 -1
  17. data/lib/opal/nodes/top.rb +9 -7
  18. data/lib/opal/nodes/yield.rb +14 -3
  19. data/lib/opal/parser.rb +4 -18
  20. data/lib/opal/parser/grammar.rb +3745 -3667
  21. data/lib/opal/parser/grammar.y +1692 -1778
  22. data/lib/opal/parser/keywords.rb +35 -35
  23. data/lib/opal/parser/lexer.rb +356 -325
  24. data/lib/opal/parser/sexp.rb +1 -1
  25. data/lib/opal/version.rb +1 -1
  26. data/opal.gemspec +1 -0
  27. data/opal/core/array.rb +320 -81
  28. data/opal/core/enumerable.rb +46 -5
  29. data/opal/core/hash.rb +6 -64
  30. data/opal/core/helpers.rb +67 -0
  31. data/opal/core/method.rb +1 -1
  32. data/opal/core/module.rb +4 -4
  33. data/opal/core/range.rb +1 -12
  34. data/opal/core/regexp.rb +2 -8
  35. data/opal/core/runtime.js +74 -3
  36. data/opal/core/string.rb +99 -74
  37. data/opal/opal.rb +3 -72
  38. data/spec/filters/bugs/array.rb +2 -30
  39. data/spec/filters/bugs/basic_object.rb +0 -1
  40. data/spec/filters/bugs/string.rb +26 -21
  41. data/spec/filters/unsupported/enumerator.rb +3 -0
  42. data/spec/filters/unsupported/float.rb +1 -0
  43. data/spec/filters/unsupported/immutable_strings.rb +15 -0
  44. data/spec/filters/unsupported/tainted.rb +58 -30
  45. data/spec/filters/unsupported/trusted.rb +35 -15
  46. data/spec/opal/parser/class_spec.rb +4 -4
  47. data/spec/opal/parser/def_spec.rb +4 -4
  48. data/spec/opal/parser/lvar_spec.rb +6 -6
  49. data/spec/opal/parser/module_spec.rb +4 -4
  50. data/spec/opal/parser/sclass_spec.rb +2 -2
  51. data/spec/stdlib/native/exposure_spec.rb +33 -0
  52. data/stdlib/buffer.rb +1 -1
  53. data/stdlib/buffer/view.rb +1 -1
  54. data/stdlib/native.rb +193 -174
  55. data/stdlib/opal-parser.rb +0 -6
  56. data/stdlib/pp.rb +9 -0
  57. data/tasks/mspec.rake +3 -1
  58. metadata +9 -9
  59. data/lib/opal/nodes/base_scope.rb +0 -11
  60. data/lib/opal/target_scope.rb +0 -281
  61. data/spec/filters/20.rb +0 -4
  62. data/spec/filters/unsupported/array_subclasses.rb +0 -37
@@ -67,6 +67,10 @@ module Enumerable
67
67
  }
68
68
  end
69
69
 
70
+ def chunk(state = undefined, &block)
71
+ raise NotImplementedError
72
+ end
73
+
70
74
  def collect(&block)
71
75
  return enum_for :collect unless block_given?
72
76
 
@@ -90,6 +94,10 @@ module Enumerable
90
94
  }
91
95
  end
92
96
 
97
+ def collect_concat(&block)
98
+ raise NotImplementedError
99
+ end
100
+
93
101
  def count(object = undefined, &block)
94
102
  %x{
95
103
  var result = 0;
@@ -282,6 +290,14 @@ module Enumerable
282
290
  }
283
291
  end
284
292
 
293
+ def each_cons(n, &block)
294
+ raise NotImplementedError
295
+ end
296
+
297
+ def each_entry(&block)
298
+ raise NotImplementedError
299
+ end
300
+
285
301
  def each_slice(n, &block)
286
302
  n = Opal.coerce_to n, Integer, :to_int
287
303
 
@@ -511,6 +527,8 @@ module Enumerable
511
527
  result
512
528
  end
513
529
 
530
+ alias flat_map collect_concat
531
+
514
532
  def grep(pattern, &block)
515
533
  %x{
516
534
  var result = [];
@@ -658,7 +676,6 @@ module Enumerable
658
676
  def enumerator_size
659
677
  respond_to?(:size) ? size : nil
660
678
  end
661
-
662
679
  private :enumerator_size
663
680
 
664
681
  alias map collect
@@ -833,6 +850,14 @@ module Enumerable
833
850
  }
834
851
  end
835
852
 
853
+ def minmax(&block)
854
+ raise NotImplementedError
855
+ end
856
+
857
+ def minmax_by(&block)
858
+ raise NotImplementedError
859
+ end
860
+
836
861
  def none?(&block)
837
862
  %x{
838
863
  var result = true;
@@ -913,6 +938,18 @@ module Enumerable
913
938
  }
914
939
  end
915
940
 
941
+ def partition(&block)
942
+ raise NotImplementedError
943
+ end
944
+
945
+ alias reduce inject
946
+
947
+ def reverse_each(&block)
948
+ raise NotImplementedError
949
+ end
950
+
951
+ alias select find_all
952
+
916
953
  def slice_before(pattern = undefined, &block)
917
954
  if `pattern === undefined && block === nil || arguments.length > 1`
918
955
  raise ArgumentError, "wrong number of arguments (#{`arguments.length`} for 1)"
@@ -973,6 +1010,10 @@ module Enumerable
973
1010
  }
974
1011
  end
975
1012
 
1013
+ def sort(&block)
1014
+ raise NotImplementedError
1015
+ end
1016
+
976
1017
  def sort_by(&block)
977
1018
  return enum_for :sort_by unless block_given?
978
1019
 
@@ -983,10 +1024,6 @@ module Enumerable
983
1024
  }.sort { |a, b| a[0] <=> b[0] }.map { |arg| `arg[1]` }
984
1025
  end
985
1026
 
986
- alias select find_all
987
-
988
- alias reduce inject
989
-
990
1027
  def take(num)
991
1028
  first(num)
992
1029
  end
@@ -1020,5 +1057,9 @@ module Enumerable
1020
1057
  end
1021
1058
 
1022
1059
  alias to_a entries
1060
+
1061
+ def zip(*lists, &block)
1062
+ raise NotImplementedError
1063
+ end
1023
1064
  end
1024
1065
 
@@ -1,68 +1,10 @@
1
1
  class Hash
2
2
  include Enumerable
3
3
 
4
- %x{
5
- var $hash = Opal.hash = function() {
6
- if (arguments.length == 1 && arguments[0]._klass == Hash) {
7
- return arguments[0];
8
- }
9
-
10
- var hash = new Hash._alloc,
11
- keys = [],
12
- assocs = {};
13
-
14
- hash.map = assocs;
15
- hash.keys = keys;
16
-
17
- if (arguments.length == 1 && arguments[0]._isArray) {
18
- var args = arguments[0];
19
-
20
- for (var i = 0, length = args.length; i < length; i++) {
21
- var key = args[i][0], obj = args[i][1];
22
-
23
- if (assocs[key] == null) {
24
- keys.push(key);
25
- }
26
-
27
- assocs[key] = obj;
28
- }
29
- }
30
- else {
31
- for (var i = 0, length = arguments.length; i < length; i++) {
32
- var key = arguments[i],
33
- obj = arguments[++i];
34
-
35
- if (assocs[key] == null) {
36
- keys.push(key);
37
- }
38
-
39
- assocs[key] = obj;
40
- }
41
- }
42
-
43
- return hash;
44
- };
45
- }
46
-
47
- # hash2 is a faster creator for hashes that just use symbols and
48
- # strings as keys. The map and keys array can be constructed at
49
- # compile time, so they are just added here by the constructor
50
- # function
51
- %x{
52
- var $hash2 = Opal.hash2 = function(keys, map) {
53
- var hash = new Hash._alloc;
54
-
55
- hash.keys = keys;
56
- hash.map = map;
57
-
58
- return hash;
59
- };
60
- }
61
-
62
4
  `var $hasOwn = {}.hasOwnProperty`
63
5
 
64
6
  def self.[](*objs)
65
- `$hash.apply(null, objs)`
7
+ `$opal.hash.apply(null, objs)`
66
8
  end
67
9
 
68
10
  def self.allocate
@@ -450,7 +392,7 @@ class Hash
450
392
 
451
393
  def invert
452
394
  %x{
453
- var result = $hash(), keys = self.keys, map = self.map,
395
+ var result = $opal.hash(), keys = self.keys, map = self.map,
454
396
  keys2 = result.keys, map2 = result.map;
455
397
 
456
398
  for (var i = 0, length = keys.length; i < length; i++) {
@@ -507,7 +449,7 @@ class Hash
507
449
  def merge(other, &block)
508
450
  %x{
509
451
  var keys = self.keys, map = self.map,
510
- result = $hash(), keys2 = result.keys, map2 = result.map;
452
+ result = $opal.hash(), keys2 = result.keys, map2 = result.map;
511
453
 
512
454
  for (var i = 0, length = keys.length; i < length; i++) {
513
455
  var key = keys[i];
@@ -602,7 +544,7 @@ class Hash
602
544
 
603
545
  %x{
604
546
  var keys = self.keys, map = self.map,
605
- result = $hash(), map2 = result.map, keys2 = result.keys;
547
+ result = $opal.hash(), map2 = result.map, keys2 = result.keys;
606
548
 
607
549
  for (var i = 0, length = keys.length; i < length; i++) {
608
550
  var key = keys[i], obj = map[key], value;
@@ -640,7 +582,7 @@ class Hash
640
582
 
641
583
  %x{
642
584
  var keys = self.keys, map = self.map,
643
- result = $hash(), map2 = result.map, keys2 = result.keys;
585
+ result = $opal.hash(), map2 = result.map, keys2 = result.keys;
644
586
 
645
587
  for (var i = 0, length = keys.length; i < length; i++) {
646
588
  var key = keys[i], obj = map[key], value;
@@ -722,7 +664,7 @@ class Hash
722
664
 
723
665
  def to_h
724
666
  %x{
725
- var hash = new Hash._alloc,
667
+ var hash = new Opal.Hash._alloc,
726
668
  cloned = #{clone};
727
669
 
728
670
  hash.map = cloned.map;
@@ -0,0 +1,67 @@
1
+ module Opal
2
+ def self.coerce_to(object, type, method)
3
+ return object if type === object
4
+
5
+ unless object.respond_to? method
6
+ raise TypeError, "no implicit conversion of #{object.class} into #{type}"
7
+ end
8
+
9
+ object.__send__ method
10
+ end
11
+
12
+ def self.coerce_to!(object, type, method)
13
+ coerced = coerce_to(object, type, method)
14
+
15
+ unless type === coerced
16
+ raise TypeError, "can't convert #{object.class} into #{type} (#{object.class}##{method} gives #{coerced.class}"
17
+ end
18
+
19
+ coerced
20
+ end
21
+
22
+ def self.try_convert(object, type, method)
23
+ return object if type === object
24
+
25
+ if object.respond_to? method
26
+ object.__send__ method
27
+ end
28
+ end
29
+
30
+ def self.compare(a, b)
31
+ compare = a <=> b
32
+
33
+ if `compare === nil`
34
+ raise ArgumentError, "comparison of #{a.class.name} with #{b.class.name} failed"
35
+ end
36
+
37
+ compare
38
+ end
39
+
40
+ def self.fits_fixnum!(value)
41
+ # since we have Fixnum#size as 32 bit, this is based on the int limits
42
+ if `value > 2147483648`
43
+ raise RangeError, "bignum too big to convert into `long'"
44
+ end
45
+ end
46
+
47
+ def self.fits_array!(value)
48
+ # this is the computed ARY_MAX_SIZE for 32 bit
49
+ if `value >= 536870910`
50
+ raise ArgumentError, "argument too big"
51
+ end
52
+ end
53
+
54
+ def self.destructure(args)
55
+ %x{
56
+ if (args.length == 1) {
57
+ return args[0];
58
+ }
59
+ else if (args._isArray) {
60
+ return args;
61
+ }
62
+ else {
63
+ return $slice.call(args);
64
+ }
65
+ }
66
+ end
67
+ end
@@ -16,7 +16,7 @@ class Method
16
16
  %x{
17
17
  #@method._p = block;
18
18
 
19
- return #@method.apply(#@object, args);
19
+ return #@method.apply(#@receiver, args);
20
20
  }
21
21
  end
22
22
 
@@ -2,15 +2,15 @@ class Module
2
2
  def self.new(&block)
3
3
  %x{
4
4
  function AnonModule(){}
5
- var klass = Opal.boot(Module, AnonModule);
5
+ var klass = Opal.boot(Opal.Module, AnonModule);
6
6
  klass._name = nil;
7
- klass._klass = Module;
7
+ klass._klass = Opal.Module;
8
8
  klass.__dep__ = []
9
9
  klass.__mod__ = true;
10
10
  klass._proto = {};
11
11
 
12
12
  // inherit scope from parent
13
- $opal.create_scope(Module._scope, klass);
13
+ $opal.create_scope(Opal.Module._scope, klass);
14
14
 
15
15
  if (block !== nil) {
16
16
  var block_self = block._s;
@@ -262,7 +262,7 @@ class Module
262
262
  def define_method(name, method = undefined, &block)
263
263
  %x{
264
264
  if (method) {
265
- block = method;
265
+ block = #{method.to_proc};
266
266
  }
267
267
 
268
268
  if (block === nil) {
@@ -1,18 +1,7 @@
1
1
  class Range
2
2
  include Enumerable
3
3
 
4
- %x{
5
- Range._proto._isRange = true;
6
-
7
- Opal.range = function(first, last, exc) {
8
- var range = new Range._alloc;
9
- range.begin = first;
10
- range.end = last;
11
- range.exclude = exc;
12
-
13
- return range;
14
- };
15
- }
4
+ `def._isRange = true;`
16
5
 
17
6
  attr_reader :begin, :end
18
7
 
@@ -2,7 +2,7 @@ class Regexp
2
2
  `def._isRegexp = true`
3
3
 
4
4
  def self.escape(string)
5
- `string.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\^\\$\\|]/g, '\\\\$&')`
5
+ `string.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\^\\$\\| ]/g, '\\\\$&')`
6
6
  end
7
7
 
8
8
  def self.union(*parts)
@@ -36,13 +36,7 @@ class Regexp
36
36
  return
37
37
  end
38
38
 
39
- if `string._isString == null`
40
- unless string.respond_to? :to_str
41
- raise TypeError, "no implicit conversion of #{string.class} into String"
42
- end
43
-
44
- string = string.to_str
45
- end
39
+ string = Opal.coerce_to(string, String, :to_str).to_s
46
40
 
47
41
  %x{
48
42
  var re = self;
@@ -494,7 +494,7 @@
494
494
  }
495
495
  else {
496
496
  if (obj._isClass) {
497
- dispatcher = obj._klass;
497
+ dispatcher = obj._super;
498
498
  }
499
499
  else {
500
500
  dispatcher = find_obj_super_dispatcher(obj, jsid, current_func);
@@ -603,6 +603,10 @@
603
603
  };
604
604
 
605
605
  Opal.is_a = function(object, klass) {
606
+ if (object.__meta__ === klass) {
607
+ return true;
608
+ }
609
+
606
610
  var search = object._klass;
607
611
 
608
612
  while (search) {
@@ -735,6 +739,75 @@
735
739
  }
736
740
  }
737
741
 
742
+ Opal.hash = function() {
743
+ if (arguments.length == 1 && arguments[0]._klass == Opal.Hash) {
744
+ return arguments[0];
745
+ }
746
+
747
+ var hash = new Opal.Hash._alloc,
748
+ keys = [],
749
+ assocs = {};
750
+
751
+ hash.map = assocs;
752
+ hash.keys = keys;
753
+
754
+ if (arguments.length == 1 && arguments[0]._isArray) {
755
+ var args = arguments[0];
756
+
757
+ for (var i = 0, length = args.length; i < length; i++) {
758
+ var key = args[i][0], obj = args[i][1];
759
+
760
+ if (assocs[key] == null) {
761
+ keys.push(key);
762
+ }
763
+
764
+ assocs[key] = obj;
765
+ }
766
+ }
767
+ else {
768
+ for (var i = 0, length = arguments.length; i < length; i++) {
769
+ var key = arguments[i],
770
+ obj = arguments[++i];
771
+
772
+ if (assocs[key] == null) {
773
+ keys.push(key);
774
+ }
775
+
776
+ assocs[key] = obj;
777
+ }
778
+ }
779
+
780
+ return hash;
781
+ };
782
+
783
+ /*
784
+ * hash2 is a faster creator for hashes that just use symbols and
785
+ * strings as keys. The map and keys array can be constructed at
786
+ * compile time, so they are just added here by the constructor
787
+ * function
788
+ */
789
+ Opal.hash2 = function(keys, map) {
790
+ var hash = new Opal.Hash._alloc;
791
+
792
+ hash.keys = keys;
793
+ hash.map = map;
794
+
795
+ return hash;
796
+ };
797
+
798
+ /*
799
+ * Create a new range instance with first and last values, and whether the
800
+ * range excludes the last value.
801
+ */
802
+ Opal.range = function(first, last, exc) {
803
+ var range = new Opal.Range._alloc;
804
+ range.begin = first;
805
+ range.end = last;
806
+ range.exclude = exc;
807
+
808
+ return range;
809
+ };
810
+
738
811
  // Initialization
739
812
  // --------------
740
813
 
@@ -782,8 +855,6 @@
782
855
  return this.$to_s();
783
856
  };
784
857
 
785
- RubyClass._proto._defn = function(mid, body) { this._proto[mid] = body; };
786
-
787
858
  Opal.top = new RubyObject._alloc();
788
859
 
789
860
  Opal.klass(RubyObject, RubyObject, 'NilClass', NilClass);