opal 0.5.2 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
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);