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.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/lib/opal.rb +0 -5
- data/lib/opal/compiler.rb +24 -44
- data/lib/opal/nodes/base.rb +5 -8
- data/lib/opal/nodes/call.rb +4 -0
- data/lib/opal/nodes/class.rb +6 -7
- data/lib/opal/nodes/def.rb +4 -4
- data/lib/opal/nodes/definitions.rb +0 -14
- data/lib/opal/nodes/iter.rb +51 -38
- data/lib/opal/nodes/literal.rb +21 -24
- data/lib/opal/nodes/module.rb +4 -4
- data/lib/opal/nodes/runtime_helpers.rb +45 -0
- data/lib/opal/nodes/scope.rb +280 -0
- data/lib/opal/nodes/singleton_class.rb +4 -5
- data/lib/opal/nodes/super.rb +1 -1
- data/lib/opal/nodes/top.rb +9 -7
- data/lib/opal/nodes/yield.rb +14 -3
- data/lib/opal/parser.rb +4 -18
- data/lib/opal/parser/grammar.rb +3745 -3667
- data/lib/opal/parser/grammar.y +1692 -1778
- data/lib/opal/parser/keywords.rb +35 -35
- data/lib/opal/parser/lexer.rb +356 -325
- data/lib/opal/parser/sexp.rb +1 -1
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +1 -0
- data/opal/core/array.rb +320 -81
- data/opal/core/enumerable.rb +46 -5
- data/opal/core/hash.rb +6 -64
- data/opal/core/helpers.rb +67 -0
- data/opal/core/method.rb +1 -1
- data/opal/core/module.rb +4 -4
- data/opal/core/range.rb +1 -12
- data/opal/core/regexp.rb +2 -8
- data/opal/core/runtime.js +74 -3
- data/opal/core/string.rb +99 -74
- data/opal/opal.rb +3 -72
- data/spec/filters/bugs/array.rb +2 -30
- data/spec/filters/bugs/basic_object.rb +0 -1
- data/spec/filters/bugs/string.rb +26 -21
- data/spec/filters/unsupported/enumerator.rb +3 -0
- data/spec/filters/unsupported/float.rb +1 -0
- data/spec/filters/unsupported/immutable_strings.rb +15 -0
- data/spec/filters/unsupported/tainted.rb +58 -30
- data/spec/filters/unsupported/trusted.rb +35 -15
- data/spec/opal/parser/class_spec.rb +4 -4
- data/spec/opal/parser/def_spec.rb +4 -4
- data/spec/opal/parser/lvar_spec.rb +6 -6
- data/spec/opal/parser/module_spec.rb +4 -4
- data/spec/opal/parser/sclass_spec.rb +2 -2
- data/spec/stdlib/native/exposure_spec.rb +33 -0
- data/stdlib/buffer.rb +1 -1
- data/stdlib/buffer/view.rb +1 -1
- data/stdlib/native.rb +193 -174
- data/stdlib/opal-parser.rb +0 -6
- data/stdlib/pp.rb +9 -0
- data/tasks/mspec.rake +3 -1
- metadata +9 -9
- data/lib/opal/nodes/base_scope.rb +0 -11
- data/lib/opal/target_scope.rb +0 -281
- data/spec/filters/20.rb +0 -4
- data/spec/filters/unsupported/array_subclasses.rb +0 -37
data/opal/core/enumerable.rb
CHANGED
@@ -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
|
|
data/opal/core/hash.rb
CHANGED
@@ -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
|
data/opal/core/method.rb
CHANGED
data/opal/core/module.rb
CHANGED
@@ -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) {
|
data/opal/core/range.rb
CHANGED
@@ -1,18 +1,7 @@
|
|
1
1
|
class Range
|
2
2
|
include Enumerable
|
3
3
|
|
4
|
-
|
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
|
|
data/opal/core/regexp.rb
CHANGED
@@ -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
|
-
|
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;
|
data/opal/core/runtime.js
CHANGED
@@ -494,7 +494,7 @@
|
|
494
494
|
}
|
495
495
|
else {
|
496
496
|
if (obj._isClass) {
|
497
|
-
dispatcher = obj.
|
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);
|