opal 0.3.27 → 0.3.28
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/CONTRIBUTING.md +24 -0
- data/README.md +6 -5
- data/Rakefile +12 -2
- data/core/array.rb +3 -31
- data/core/enumerable.rb +32 -4
- data/core/hash.rb +218 -186
- data/core/json.rb +3 -2
- data/core/kernel.rb +28 -28
- data/core/numeric.rb +2 -2
- data/core/runtime.js +0 -1
- data/lib/opal.rb +4 -2
- data/lib/opal/grammar.rb +6 -2
- data/lib/opal/grammar.y +3 -0
- data/lib/opal/lexer.rb +25 -10
- data/lib/opal/parser.rb +75 -34
- data/lib/opal/scope.rb +7 -7
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +1 -1
- data/spec/core/array/reduce_spec.rb +31 -0
- data/spec/{opal → core}/array/to_json_spec.rb +0 -0
- data/spec/core/boolean/and_spec.rb +17 -0
- data/spec/core/boolean/inspect_spec.rb +9 -0
- data/spec/core/boolean/or_spec.rb +17 -0
- data/spec/{opal → core}/boolean/singleton_class_spec.rb +0 -0
- data/spec/{opal → core}/boolean/to_json_spec.rb +1 -1
- data/spec/core/boolean/to_s_spec.rb +9 -0
- data/spec/core/boolean/xor_spec.rb +17 -0
- data/spec/{opal → core}/class/bridge_class_spec.rb +0 -0
- data/spec/{opal → core}/class/instance_methods_spec.rb +0 -0
- data/spec/core/class/last_value_spec.rb +68 -0
- data/spec/core/enumerable/detect_spec.rb +1 -1
- data/spec/core/enumerable/find_spec.rb +1 -1
- data/spec/{opal → core}/hash/to_json_spec.rb +0 -0
- data/spec/{opal → core}/hash/to_native_spec.rb +0 -0
- data/spec/{opal → core}/json/parse_spec.rb +0 -0
- data/spec/core/kernel/block_given.rb +30 -0
- data/spec/core/kernel/methods_spec.rb +11 -0
- data/spec/core/kernel/p_spec.rb +13 -0
- data/spec/{opal → core}/kernel/to_json_spec.rb +0 -0
- data/spec/{opal → core}/nil/to_json_spec.rb +0 -0
- data/spec/core/numeric/abs_spec.rb +12 -0
- data/spec/core/numeric/bit_and_spec.rb +7 -0
- data/spec/core/numeric/bit_or_spec.rb +8 -0
- data/spec/core/numeric/bit_xor_spec.rb +6 -0
- data/spec/core/numeric/ceil_spec.rb +8 -0
- data/spec/core/numeric/chr_spec.rb +8 -0
- data/spec/core/numeric/comparison_spec.rb +24 -0
- data/spec/core/numeric/complement_spec.rb +8 -0
- data/spec/core/numeric/divide_spec.rb +10 -0
- data/spec/core/numeric/downto_spec.rb +19 -0
- data/spec/core/numeric/eql_spec.rb +9 -0
- data/spec/core/numeric/even_spec.rb +21 -0
- data/spec/core/numeric/exponent_spec.rb +33 -0
- data/spec/core/numeric/floor_spec.rb +8 -0
- data/spec/core/numeric/gt_spec.rb +11 -0
- data/spec/core/numeric/gte_spec.rb +12 -0
- data/spec/core/numeric/integer_spec.rb +9 -0
- data/spec/core/numeric/left_shift_spec.rb +21 -0
- data/spec/core/numeric/lt_spec.rb +11 -0
- data/spec/core/numeric/lte_spec.rb +12 -0
- data/spec/core/numeric/magnitude_spec.rb +12 -0
- data/spec/core/numeric/minus_spec.rb +8 -0
- data/spec/core/numeric/modulo_spec.rb +19 -0
- data/spec/core/numeric/multiply_spec.rb +9 -0
- data/spec/core/numeric/next_spec.rb +9 -0
- data/spec/core/numeric/odd_spec.rb +21 -0
- data/spec/core/numeric/ord_spec.rb +9 -0
- data/spec/core/numeric/plus_spec.rb +8 -0
- data/spec/core/numeric/pred_spec.rb +7 -0
- data/spec/core/numeric/right_shift_spec.rb +25 -0
- data/spec/core/numeric/succ_spec.rb +9 -0
- data/spec/core/numeric/times_spec.rb +36 -0
- data/spec/core/numeric/to_f_spec.rb +7 -0
- data/spec/core/numeric/to_i_spec.rb +7 -0
- data/spec/{opal → core}/numeric/to_json_spec.rb +0 -0
- data/spec/core/numeric/to_s_spec.rb +8 -0
- data/spec/core/numeric/uminus_spec.rb +9 -0
- data/spec/core/numeric/upto_spec.rb +19 -0
- data/spec/core/numeric/zero_spec.rb +7 -0
- data/spec/{opal → core}/runtime/call_spec.rb +0 -0
- data/spec/{opal → core}/runtime/class_hierarchy_spec.rb +0 -0
- data/spec/{opal → core}/runtime/def_spec.rb +0 -0
- data/spec/{opal → core}/runtime/defined_spec.rb +0 -0
- data/spec/{opal → core}/runtime/super_spec.rb +0 -0
- data/spec/{opal → core}/string/demodulize_spec.rb +0 -0
- data/spec/{opal → core}/string/to_json_spec.rb +0 -0
- data/spec/{opal → core}/string/underscore_spec.rb +0 -0
- data/spec/{opal → core}/strscan/check_spec.rb +0 -0
- data/spec/{opal → core}/strscan/scan_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/alias_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/and_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/array_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/attrasgn_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/begin_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/block_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/break_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/call_spec.rb +23 -1
- data/spec/{lib/grammar → grammar}/class_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/const_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/cvar_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/def_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/false_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/file_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/gvar_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/hash_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/iasgn_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/if_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/iter_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/ivar_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/lambda_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/lasgn_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/line_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/lvar_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/masgn_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/module_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/nil_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/not_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/op_asgn1_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/op_asgn2_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/or_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/return_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/sclass_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/self_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/str_spec.rb +7 -0
- data/spec/{lib/grammar → grammar}/super_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/true_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/undef_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/unless_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/while_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/xstr_spec.rb +0 -0
- data/spec/{lib/grammar → grammar}/yield_spec.rb +0 -0
- data/spec/language/string_spec.rb +5 -0
- data/spec/{lib/parser → parser}/simple_spec.rb +0 -0
- metadata +231 -159
- data/spec/core/false/and_spec.rb +0 -9
- data/spec/core/false/inspect_spec.rb +0 -5
- data/spec/core/false/or_spec.rb +0 -9
- data/spec/core/false/to_s_spec.rb +0 -5
- data/spec/core/false/xor_spec.rb +0 -9
- data/spec/core/true/and_spec.rb +0 -9
- data/spec/core/true/inspect_spec.rb +0 -5
- data/spec/core/true/or_spec.rb +0 -9
- data/spec/core/true/to_s_spec.rb +0 -5
- data/spec/core/true/xor_spec.rb +0 -9
- data/spec/lib/erb_parser/simple.erb +0 -1
- data/spec/opal/kernel/attribute_spec.rb +0 -57
- data/spec/opal/runtime/method_missing_spec.rb +0 -17
data/.gitignore
CHANGED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Contributing
|
2
|
+
|
3
|
+
## Quick Start
|
4
|
+
|
5
|
+
Clone repo:
|
6
|
+
|
7
|
+
```
|
8
|
+
$ git clone git://github.com/opal/opal.git
|
9
|
+
```
|
10
|
+
|
11
|
+
Get dependencies:
|
12
|
+
|
13
|
+
```
|
14
|
+
$ bundle
|
15
|
+
```
|
16
|
+
|
17
|
+
## Tests
|
18
|
+
|
19
|
+
You need phantomjs installed to run tests. To build opal, its dependencies
|
20
|
+
and all specs, run:
|
21
|
+
|
22
|
+
```
|
23
|
+
$ rake
|
24
|
+
```
|
data/README.md
CHANGED
@@ -6,21 +6,22 @@ Opal is a ruby to javascript source-to-source compiler. It also has an
|
|
6
6
|
implementation of the ruby corelib.
|
7
7
|
|
8
8
|
Opal is [hosted on github](http://github.com/opal/opal), and there
|
9
|
-
is a Freenode IRC channel at
|
9
|
+
is a Freenode IRC channel at [#opal](http://webchat.freenode.net/?channels=opal). There is also a [google group for opal](http://groups.google.com/forum/#!forum/opalrb).
|
10
10
|
|
11
11
|
## Usage
|
12
12
|
|
13
|
-
See the website, [http://
|
13
|
+
See the website, [http://opalrb.org](http://opalrb.org).
|
14
14
|
|
15
15
|
## Running tests
|
16
16
|
|
17
|
-
Build the runtime, tests and dependencies, and
|
18
|
-
go:
|
17
|
+
Build the runtime, tests and dependencies, and run the tests with:
|
19
18
|
|
20
19
|
```
|
21
|
-
|
20
|
+
rake
|
22
21
|
```
|
23
22
|
|
23
|
+
You can just build opal using `rake opal`.
|
24
|
+
|
24
25
|
Alternatively, after building, you can open `spec/index.html` in any
|
25
26
|
web browser.
|
26
27
|
|
data/Rakefile
CHANGED
@@ -10,6 +10,16 @@ end
|
|
10
10
|
# build runtime, dependencies and specs, then run the tests
|
11
11
|
task :default => %w[opal opal:test]
|
12
12
|
|
13
|
+
desc "opal.min.js and opal-parser.min.js"
|
14
|
+
task :min do
|
15
|
+
%w[opal opal-parser].each do |file|
|
16
|
+
puts " * #{file}.min.js"
|
17
|
+
File.open("build/#{file}.min.js", "w+") do |o|
|
18
|
+
o.puts uglify(File.read "build/#{file}.js")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
13
23
|
desc "Check file sizes for opal.js runtime"
|
14
24
|
task :sizes do
|
15
25
|
o = File.read 'build/opal.js'
|
@@ -44,11 +54,11 @@ def gzip(str)
|
|
44
54
|
end
|
45
55
|
|
46
56
|
# For testing just specific sections of opal
|
47
|
-
desc "Build each test case"
|
57
|
+
desc "Build each test case into build/"
|
48
58
|
task :test_cases do
|
49
59
|
FileUtils.mkdir_p 'build/test_cases'
|
50
60
|
|
51
|
-
sources = Dir['spec/core/*', 'spec/language', 'spec/
|
61
|
+
sources = Dir['spec/core/*', 'spec/language', 'spec/parser', 'spec/grammar']
|
52
62
|
|
53
63
|
sources.each do |c|
|
54
64
|
dest = "build/test_cases/#{File.basename c}"
|
data/core/array.rb
CHANGED
@@ -666,21 +666,8 @@ class Array < `Array`
|
|
666
666
|
def reject!(&block)
|
667
667
|
%x{
|
668
668
|
var original = #{self}.length;
|
669
|
-
|
670
|
-
|
671
|
-
if ((value = block.call(__context, #{self}[i])) === __breaker) {
|
672
|
-
return __breaker.$v;
|
673
|
-
}
|
674
|
-
|
675
|
-
if (value !== false && value !== nil) {
|
676
|
-
#{self}.splice(i, 1);
|
677
|
-
|
678
|
-
length--;
|
679
|
-
i--;
|
680
|
-
}
|
681
|
-
}
|
682
|
-
|
683
|
-
return original === #{self}.length ? nil : #{self};
|
669
|
+
#{ delete_if &block };
|
670
|
+
return #{self}.length === original ? nil : #{self};
|
684
671
|
}
|
685
672
|
end
|
686
673
|
|
@@ -756,22 +743,7 @@ class Array < `Array`
|
|
756
743
|
def select!(&block)
|
757
744
|
%x{
|
758
745
|
var original = #{self}.length;
|
759
|
-
|
760
|
-
for (var i = 0, length = original, item, value; i < length; i++) {
|
761
|
-
item = #{self}[i];
|
762
|
-
|
763
|
-
if ((value = block(__context, item)) === __breaker) {
|
764
|
-
return __breaker.$v;
|
765
|
-
}
|
766
|
-
|
767
|
-
if (value === false || value === nil) {
|
768
|
-
#{self}.splice(i, 1);
|
769
|
-
|
770
|
-
length--;
|
771
|
-
i--;
|
772
|
-
}
|
773
|
-
}
|
774
|
-
|
746
|
+
#{ keep_if &block };
|
775
747
|
return #{self}.length === original ? nil : #{self};
|
776
748
|
}
|
777
749
|
end
|
data/core/enumerable.rb
CHANGED
@@ -96,6 +96,30 @@ module Enumerable
|
|
96
96
|
}
|
97
97
|
end
|
98
98
|
|
99
|
+
def reduce(object, &block)
|
100
|
+
%x{
|
101
|
+
var result = #{object} == undefined ? 0 : #{object};
|
102
|
+
|
103
|
+
var proc = function() {
|
104
|
+
var obj = __slice.call(arguments), value;
|
105
|
+
|
106
|
+
if ((value = block.apply(__context, [result].concat(obj))) === __breaker) {
|
107
|
+
result = __breaker.$v;
|
108
|
+
__breaker.$v = nil;
|
109
|
+
|
110
|
+
return __breaker;
|
111
|
+
}
|
112
|
+
|
113
|
+
result = value;
|
114
|
+
};
|
115
|
+
|
116
|
+
#{self}.$each._p = proc;
|
117
|
+
#{self}.$each();
|
118
|
+
|
119
|
+
return result;
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
99
123
|
def count(object, &block)
|
100
124
|
%x{
|
101
125
|
var result = 0;
|
@@ -193,8 +217,8 @@ module Enumerable
|
|
193
217
|
result.push(obj);
|
194
218
|
return value;
|
195
219
|
}
|
196
|
-
|
197
|
-
|
220
|
+
|
221
|
+
|
198
222
|
return __breaker;
|
199
223
|
};
|
200
224
|
|
@@ -283,7 +307,7 @@ module Enumerable
|
|
283
307
|
var proc, result = nil, index = 0;
|
284
308
|
|
285
309
|
if (object != null) {
|
286
|
-
proc = function (obj) {
|
310
|
+
proc = function (obj) {
|
287
311
|
if (#{ `obj` == `object` }) {
|
288
312
|
result = index;
|
289
313
|
return __breaker;
|
@@ -376,9 +400,13 @@ module Enumerable
|
|
376
400
|
}
|
377
401
|
end
|
378
402
|
|
403
|
+
alias map collect
|
404
|
+
|
379
405
|
alias select find_all
|
380
406
|
|
381
407
|
alias take first
|
382
408
|
|
383
409
|
alias to_a entries
|
384
|
-
|
410
|
+
|
411
|
+
alias inject reduce
|
412
|
+
end
|
data/core/hash.rb
CHANGED
@@ -5,17 +5,35 @@ class Hash
|
|
5
5
|
__hash = Opal.hash = function() {
|
6
6
|
var hash = new Hash,
|
7
7
|
args = __slice.call(arguments),
|
8
|
+
keys = [],
|
8
9
|
assocs = {};
|
9
10
|
|
10
11
|
hash.map = assocs;
|
12
|
+
hash.keys = keys;
|
11
13
|
|
12
14
|
for (var i = 0, length = args.length, key; i < length; i++) {
|
13
|
-
key = args[i];
|
14
|
-
|
15
|
+
var key = args[i], obj = args[++i];
|
16
|
+
|
17
|
+
if (assocs[key] == null) {
|
18
|
+
keys.push(key);
|
19
|
+
}
|
20
|
+
|
21
|
+
assocs[key] = obj;
|
15
22
|
}
|
16
23
|
|
17
24
|
return hash;
|
18
25
|
};
|
26
|
+
|
27
|
+
// hash2 is a faster creator for hashes that just use symbols and
|
28
|
+
// strings as keys. The map and keys array can be constructed at
|
29
|
+
// compile time, so they are just added here by the constructor
|
30
|
+
// function
|
31
|
+
__hash2 = Opal.hash2 = function(keys, map) {
|
32
|
+
var hash = new Hash;
|
33
|
+
hash.keys = keys;
|
34
|
+
hash.map = map;
|
35
|
+
return hash;
|
36
|
+
}
|
19
37
|
}
|
20
38
|
|
21
39
|
def self.[](*objs)
|
@@ -28,10 +46,11 @@ class Hash
|
|
28
46
|
|
29
47
|
def self.from_native(obj)
|
30
48
|
%x{
|
31
|
-
var hash = __hash(), map = hash.map;
|
49
|
+
var hash = __hash(), map = hash.map, keys = hash.keys;
|
32
50
|
|
33
51
|
for (var key in obj) {
|
34
|
-
|
52
|
+
keys.push(key);
|
53
|
+
map[key] = obj[key];
|
35
54
|
}
|
36
55
|
|
37
56
|
return hash;
|
@@ -59,20 +78,19 @@ class Hash
|
|
59
78
|
return true;
|
60
79
|
}
|
61
80
|
|
62
|
-
if (!other.map) {
|
81
|
+
if (!other.map || !other.keys) {
|
82
|
+
return false;
|
83
|
+
}
|
84
|
+
|
85
|
+
if (#{self}.keys.length !== other.keys.length) {
|
63
86
|
return false;
|
64
87
|
}
|
65
88
|
|
66
89
|
var map = #{self}.map,
|
67
90
|
map2 = other.map;
|
68
91
|
|
69
|
-
for (var
|
70
|
-
|
71
|
-
return false;
|
72
|
-
}
|
73
|
-
|
74
|
-
var obj = map[assoc][1],
|
75
|
-
obj2 = map2[assoc][1];
|
92
|
+
for (var i = 0, length = #{self}.keys.length; i < length; i++) {
|
93
|
+
var key = #{self}.keys[i], obj = map[key], obj2 = map2[key];
|
76
94
|
|
77
95
|
if (#{`obj` != `obj2`}) {
|
78
96
|
return false;
|
@@ -85,10 +103,10 @@ class Hash
|
|
85
103
|
|
86
104
|
def [](key)
|
87
105
|
%x{
|
88
|
-
var bucket;
|
106
|
+
var bucket = #{self}.map[key];
|
89
107
|
|
90
|
-
if (bucket
|
91
|
-
return bucket
|
108
|
+
if (bucket != null) {
|
109
|
+
return bucket;
|
92
110
|
}
|
93
111
|
|
94
112
|
var proc = #{@proc};
|
@@ -103,7 +121,13 @@ class Hash
|
|
103
121
|
|
104
122
|
def []=(key, value)
|
105
123
|
%x{
|
106
|
-
#{self}.map
|
124
|
+
var map = #{self}.map;
|
125
|
+
|
126
|
+
if (!__hasOwn.call(map, key)) {
|
127
|
+
#{self}.keys.push(key);
|
128
|
+
}
|
129
|
+
|
130
|
+
map[key] = value;
|
107
131
|
|
108
132
|
return value;
|
109
133
|
}
|
@@ -111,11 +135,13 @@ class Hash
|
|
111
135
|
|
112
136
|
def assoc(object)
|
113
137
|
%x{
|
114
|
-
|
115
|
-
|
138
|
+
var keys = #{self}.keys, key;
|
139
|
+
|
140
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
141
|
+
key = keys[i];
|
116
142
|
|
117
|
-
if (#{`
|
118
|
-
return [
|
143
|
+
if (#{`key` == object}) {
|
144
|
+
return [key, #{self}.map[key]];
|
119
145
|
}
|
120
146
|
}
|
121
147
|
|
@@ -126,7 +152,7 @@ class Hash
|
|
126
152
|
def clear
|
127
153
|
%x{
|
128
154
|
#{self}.map = {};
|
129
|
-
|
155
|
+
#{self}.keys = [];
|
130
156
|
return #{self};
|
131
157
|
}
|
132
158
|
end
|
@@ -135,10 +161,12 @@ class Hash
|
|
135
161
|
%x{
|
136
162
|
var result = __hash(),
|
137
163
|
map = #{self}.map,
|
138
|
-
map2 = result.map
|
164
|
+
map2 = result.map,
|
165
|
+
keys2 = result.keys;
|
139
166
|
|
140
|
-
for (var
|
141
|
-
|
167
|
+
for (var i = 0, length = #{self}.keys.length; i < length; i++) {
|
168
|
+
keys2.push(#{self}.keys[i]);
|
169
|
+
map2[#{self}.keys[i]] = map[#{self}.keys[i]];
|
142
170
|
}
|
143
171
|
|
144
172
|
return result;
|
@@ -163,12 +191,12 @@ class Hash
|
|
163
191
|
|
164
192
|
def delete(key)
|
165
193
|
%x{
|
166
|
-
var map = #{self}.map, result;
|
167
|
-
|
168
|
-
if (result = map[key]) {
|
169
|
-
result = result[1];
|
194
|
+
var map = #{self}.map, result = map[key];
|
170
195
|
|
196
|
+
if (result != null) {
|
171
197
|
delete map[key];
|
198
|
+
#{self}.keys.$delete(key);
|
199
|
+
|
172
200
|
return result;
|
173
201
|
}
|
174
202
|
|
@@ -178,18 +206,21 @@ class Hash
|
|
178
206
|
|
179
207
|
def delete_if(&block)
|
180
208
|
%x{
|
181
|
-
var map = #{self}.map;
|
209
|
+
var map = #{self}.map, keys = #{self}.keys, value;
|
182
210
|
|
183
|
-
for (var
|
184
|
-
var
|
185
|
-
value;
|
211
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
212
|
+
var key = keys[i], obj = map[key];
|
186
213
|
|
187
|
-
if ((value = block.call(__context,
|
214
|
+
if ((value = block.call(__context, key, obj)) === __breaker) {
|
188
215
|
return __breaker.$v;
|
189
216
|
}
|
190
217
|
|
191
218
|
if (value !== false && value !== nil) {
|
192
|
-
|
219
|
+
keys.splice(i, 1);
|
220
|
+
delete map[key];
|
221
|
+
|
222
|
+
length--;
|
223
|
+
i--;
|
193
224
|
}
|
194
225
|
}
|
195
226
|
|
@@ -201,12 +232,12 @@ class Hash
|
|
201
232
|
|
202
233
|
def each(&block)
|
203
234
|
%x{
|
204
|
-
var map = #{self}.map;
|
235
|
+
var map = #{self}.map, keys = #{self}.keys;
|
205
236
|
|
206
|
-
for (var
|
207
|
-
var
|
237
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
238
|
+
var key = keys[i];
|
208
239
|
|
209
|
-
if (block.call(__context,
|
240
|
+
if (block.call(__context, key, map[key]) === __breaker) {
|
210
241
|
return __breaker.$v;
|
211
242
|
}
|
212
243
|
}
|
@@ -217,12 +248,12 @@ class Hash
|
|
217
248
|
|
218
249
|
def each_key(&block)
|
219
250
|
%x{
|
220
|
-
var
|
251
|
+
var keys = #{self}.keys;
|
221
252
|
|
222
|
-
for (var
|
223
|
-
var
|
253
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
254
|
+
var key = keys[i];
|
224
255
|
|
225
|
-
if (block.call(__context,
|
256
|
+
if (block.call(__context, key) === __breaker) {
|
226
257
|
return __breaker.$v;
|
227
258
|
}
|
228
259
|
}
|
@@ -235,12 +266,10 @@ class Hash
|
|
235
266
|
|
236
267
|
def each_value(&block)
|
237
268
|
%x{
|
238
|
-
var map = #{self}.map;
|
239
|
-
|
240
|
-
for (var assoc in map) {
|
241
|
-
var bucket = map[assoc];
|
269
|
+
var map = #{self}.map, keys = #{self}.keys;
|
242
270
|
|
243
|
-
|
271
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
272
|
+
if (block.call(__context, map[keys[i]]) === __breaker) {
|
244
273
|
return __breaker.$v;
|
245
274
|
}
|
246
275
|
}
|
@@ -251,11 +280,7 @@ class Hash
|
|
251
280
|
|
252
281
|
def empty?
|
253
282
|
%x{
|
254
|
-
|
255
|
-
return false;
|
256
|
-
}
|
257
|
-
|
258
|
-
return true;
|
283
|
+
return #{self}.keys.length === 0;
|
259
284
|
}
|
260
285
|
end
|
261
286
|
|
@@ -263,10 +288,10 @@ class Hash
|
|
263
288
|
|
264
289
|
def fetch(key, defaults, &block)
|
265
290
|
%x{
|
266
|
-
var
|
291
|
+
var value = #{self}.map[key];
|
267
292
|
|
268
|
-
if (
|
269
|
-
return
|
293
|
+
if (value != null) {
|
294
|
+
return value;
|
270
295
|
}
|
271
296
|
|
272
297
|
if (block !== nil) {
|
@@ -287,15 +312,12 @@ class Hash
|
|
287
312
|
}
|
288
313
|
end
|
289
314
|
|
290
|
-
def flatten(level)
|
315
|
+
def flatten(level=undefined)
|
291
316
|
%x{
|
292
|
-
var map
|
293
|
-
result = [];
|
317
|
+
var map = #{self}.map, keys = #{self}.keys, result = [];
|
294
318
|
|
295
|
-
for (var
|
296
|
-
var
|
297
|
-
key = bucket[0],
|
298
|
-
value = bucket[1];
|
319
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
320
|
+
var key = keys[i], value = map[key];
|
299
321
|
|
300
322
|
result.push(key);
|
301
323
|
|
@@ -304,7 +326,7 @@ class Hash
|
|
304
326
|
result.push(value);
|
305
327
|
}
|
306
328
|
else {
|
307
|
-
result = result.concat(#{`value`.flatten(level - 1)});
|
329
|
+
result = result.concat(#{`value`.flatten(`level - 1`)});
|
308
330
|
}
|
309
331
|
}
|
310
332
|
else {
|
@@ -317,13 +339,13 @@ class Hash
|
|
317
339
|
end
|
318
340
|
|
319
341
|
def has_key?(key)
|
320
|
-
|
342
|
+
`#{self}.map[key] != null`
|
321
343
|
end
|
322
344
|
|
323
345
|
def has_value?(value)
|
324
346
|
%x{
|
325
347
|
for (var assoc in #{self}.map) {
|
326
|
-
if (#{`#{self}.map[assoc]
|
348
|
+
if (#{`#{self}.map[assoc]` == value}) {
|
327
349
|
return true;
|
328
350
|
}
|
329
351
|
}
|
@@ -340,11 +362,13 @@ class Hash
|
|
340
362
|
|
341
363
|
def index(object)
|
342
364
|
%x{
|
343
|
-
|
344
|
-
|
365
|
+
var map = #{self}.map, keys = #{self}.keys;
|
366
|
+
|
367
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
368
|
+
var key = keys[i];
|
345
369
|
|
346
|
-
if (#{object == `
|
347
|
-
return
|
370
|
+
if (#{object == `map[key]`}) {
|
371
|
+
return key;
|
348
372
|
}
|
349
373
|
}
|
350
374
|
|
@@ -354,13 +378,13 @@ class Hash
|
|
354
378
|
|
355
379
|
def indexes(*keys)
|
356
380
|
%x{
|
357
|
-
var result = [], map = #{self}.map,
|
381
|
+
var result = [], map = #{self}.map, val;
|
358
382
|
|
359
383
|
for (var i = 0, length = keys.length; i < length; i++) {
|
360
|
-
var key = keys[i];
|
384
|
+
var key = keys[i], val = map[key];
|
361
385
|
|
362
|
-
if (
|
363
|
-
result.push(
|
386
|
+
if (val != null) {
|
387
|
+
result.push(val);
|
364
388
|
}
|
365
389
|
else {
|
366
390
|
result.push(#{self}.none);
|
@@ -375,28 +399,27 @@ class Hash
|
|
375
399
|
|
376
400
|
def inspect
|
377
401
|
%x{
|
378
|
-
var inspect = [],
|
379
|
-
map = #{self}.map;
|
380
|
-
|
381
|
-
for (var assoc in map) {
|
382
|
-
var bucket = map[assoc];
|
402
|
+
var inspect = [], keys = #{self}.keys, map = #{self}.map;
|
383
403
|
|
384
|
-
|
404
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
405
|
+
var key = keys[i];
|
406
|
+
inspect.push(#{`key`.inspect} + '=>' + #{`map[key]`.inspect});
|
385
407
|
}
|
408
|
+
|
386
409
|
return '{' + inspect.join(', ') + '}';
|
387
410
|
}
|
388
411
|
end
|
389
412
|
|
390
413
|
def invert
|
391
414
|
%x{
|
392
|
-
var result = __hash(),
|
393
|
-
|
394
|
-
map2 = result.map;
|
415
|
+
var result = __hash(), keys = #{self}.keys, map = #{self}.map,
|
416
|
+
keys2 = result.keys, map2 = result.map;
|
395
417
|
|
396
|
-
for (var
|
397
|
-
var
|
418
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
419
|
+
var key = keys[i], obj = map[key];
|
398
420
|
|
399
|
-
|
421
|
+
keys2.push(obj);
|
422
|
+
map2[obj] = key;
|
400
423
|
}
|
401
424
|
|
402
425
|
return result;
|
@@ -405,17 +428,21 @@ class Hash
|
|
405
428
|
|
406
429
|
def keep_if(&block)
|
407
430
|
%x{
|
408
|
-
var map = #{self}.map, value;
|
431
|
+
var map = #{self}.map, keys = #{self}.keys, value;
|
409
432
|
|
410
|
-
for (var
|
411
|
-
var
|
433
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
434
|
+
var key = keys[i], obj = map[key];
|
412
435
|
|
413
|
-
if ((value = block.call(__context,
|
436
|
+
if ((value = block.call(__context, key, obj)) === __breaker) {
|
414
437
|
return __breaker.$v;
|
415
438
|
}
|
416
439
|
|
417
440
|
if (value === false || value === nil) {
|
418
|
-
|
441
|
+
keys.splice(i, 1);
|
442
|
+
delete map[key];
|
443
|
+
|
444
|
+
length--;
|
445
|
+
i--;
|
419
446
|
}
|
420
447
|
}
|
421
448
|
|
@@ -429,25 +456,13 @@ class Hash
|
|
429
456
|
|
430
457
|
def keys
|
431
458
|
%x{
|
432
|
-
|
433
|
-
|
434
|
-
for (var assoc in #{self}.map) {
|
435
|
-
result.push(#{self}.map[assoc][0]);
|
436
|
-
}
|
437
|
-
|
438
|
-
return result;
|
459
|
+
return #{self}.keys.slice(0);
|
439
460
|
}
|
440
461
|
end
|
441
462
|
|
442
463
|
def length
|
443
464
|
%x{
|
444
|
-
|
445
|
-
|
446
|
-
for (var assoc in #{self}.map) {
|
447
|
-
result++;
|
448
|
-
}
|
449
|
-
|
450
|
-
return result;
|
465
|
+
return #{self}.keys.length;
|
451
466
|
}
|
452
467
|
end
|
453
468
|
|
@@ -455,34 +470,40 @@ class Hash
|
|
455
470
|
|
456
471
|
def merge(other, &block)
|
457
472
|
%x{
|
458
|
-
var
|
459
|
-
|
460
|
-
map2 = result.map;
|
473
|
+
var keys = #{self}.keys, map = #{self}.map,
|
474
|
+
result = __hash(), keys2 = result.keys, map2 = result.map;
|
461
475
|
|
462
|
-
for (var
|
463
|
-
var
|
476
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
477
|
+
var key = keys[i];
|
464
478
|
|
465
|
-
|
479
|
+
keys2.push(key);
|
480
|
+
map2[key] = map[key];
|
466
481
|
}
|
467
482
|
|
468
|
-
map = other.map;
|
483
|
+
var keys = other.keys, map = other.map;
|
469
484
|
|
470
485
|
if (block === nil) {
|
471
|
-
for (var
|
472
|
-
var
|
486
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
487
|
+
var key = keys[i];
|
488
|
+
|
489
|
+
if (map2[key] == null) {
|
490
|
+
keys2.push(key);
|
491
|
+
}
|
473
492
|
|
474
|
-
map2[
|
493
|
+
map2[key] = map[key];
|
475
494
|
}
|
476
495
|
}
|
477
496
|
else {
|
478
|
-
for (var
|
479
|
-
var
|
497
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
498
|
+
var key = keys[i];
|
480
499
|
|
481
|
-
if (
|
482
|
-
|
500
|
+
if (map2[key] == null) {
|
501
|
+
keys2.push(key);
|
502
|
+
map2[key] = map[key];
|
503
|
+
}
|
504
|
+
else {
|
505
|
+
map2[key] = block.call(__context, key, map2[key], map[key]);
|
483
506
|
}
|
484
|
-
|
485
|
-
map2[assoc] = [key, val];
|
486
507
|
}
|
487
508
|
}
|
488
509
|
|
@@ -492,25 +513,31 @@ class Hash
|
|
492
513
|
|
493
514
|
def merge!(other, &block)
|
494
515
|
%x{
|
495
|
-
var map
|
496
|
-
map2 = other.map;
|
516
|
+
var keys = #{self}.keys, map = #{self}.map,
|
517
|
+
keys2 = other.keys, map2 = other.map;
|
497
518
|
|
498
519
|
if (block === nil) {
|
499
|
-
for (var
|
500
|
-
var
|
520
|
+
for (var i = 0, length = keys2.length; i < length; i++) {
|
521
|
+
var key = keys2[i];
|
501
522
|
|
502
|
-
map[
|
523
|
+
if (map[key] == null) {
|
524
|
+
keys.push(key);
|
525
|
+
}
|
526
|
+
|
527
|
+
map[key] = map2[key];
|
503
528
|
}
|
504
529
|
}
|
505
530
|
else {
|
506
|
-
for (var
|
507
|
-
var
|
531
|
+
for (var i = 0, length = keys2.length; i < length; i++) {
|
532
|
+
var key = keys2[i];
|
508
533
|
|
509
|
-
if (
|
510
|
-
|
534
|
+
if (map[key] == null) {
|
535
|
+
keys.push(key);
|
536
|
+
map[key] = map2[key];
|
537
|
+
}
|
538
|
+
else {
|
539
|
+
map[key] = block.call(__context, key, map[key], map2[key]);
|
511
540
|
}
|
512
|
-
|
513
|
-
map[assoc] = [key, val];
|
514
541
|
}
|
515
542
|
}
|
516
543
|
|
@@ -520,13 +547,13 @@ class Hash
|
|
520
547
|
|
521
548
|
def rassoc(object)
|
522
549
|
%x{
|
523
|
-
var map = #{self}.map;
|
550
|
+
var keys = #{self}.keys, map = #{self}.map;
|
524
551
|
|
525
|
-
for (var
|
526
|
-
var
|
552
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
553
|
+
var key = keys[i], obj = map[key];
|
527
554
|
|
528
|
-
if (#{`
|
529
|
-
return [
|
555
|
+
if (#{`obj` == object}) {
|
556
|
+
return [key, obj];
|
530
557
|
}
|
531
558
|
}
|
532
559
|
|
@@ -536,18 +563,19 @@ class Hash
|
|
536
563
|
|
537
564
|
def reject(&block)
|
538
565
|
%x{
|
539
|
-
var
|
566
|
+
var keys = #{self}.keys, map = #{self}.map,
|
567
|
+
result = __hash(), map2 = result.map, keys2 = result.keys;
|
540
568
|
|
541
|
-
for (var
|
542
|
-
var
|
543
|
-
value;
|
569
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
570
|
+
var key = keys[i], obj = map[key], value;
|
544
571
|
|
545
|
-
if ((value = block.call(__context,
|
572
|
+
if ((value = block.call(__context, key, obj)) === __breaker) {
|
546
573
|
return __breaker.$v;
|
547
574
|
}
|
548
575
|
|
549
576
|
if (value === false || value === nil) {
|
550
|
-
|
577
|
+
keys2.push(key);
|
578
|
+
map2[key] = obj;
|
551
579
|
}
|
552
580
|
}
|
553
581
|
|
@@ -557,12 +585,12 @@ class Hash
|
|
557
585
|
|
558
586
|
def replace(other)
|
559
587
|
%x{
|
560
|
-
var map = #{self}.map = {};
|
561
|
-
|
562
|
-
for (var assoc in other.map) {
|
563
|
-
var bucket = other.map[assoc];
|
588
|
+
var map = #{self}.map = {}, keys = #{self}.keys = [];
|
564
589
|
|
565
|
-
|
590
|
+
for (var i = 0, length = other.keys.length; i < length; i++) {
|
591
|
+
var key = other.keys[i];
|
592
|
+
keys.push(key);
|
593
|
+
map[key] = other.map[key];
|
566
594
|
}
|
567
595
|
|
568
596
|
return #{self};
|
@@ -571,18 +599,19 @@ class Hash
|
|
571
599
|
|
572
600
|
def select(&block)
|
573
601
|
%x{
|
574
|
-
var
|
602
|
+
var keys = #{self}.keys, map = #{self}.map,
|
603
|
+
result = __hash(), map2 = result.map, keys2 = result.keys;
|
575
604
|
|
576
|
-
for (var
|
577
|
-
var
|
578
|
-
value;
|
605
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
606
|
+
var key = keys[i], obj = map[key], value;
|
579
607
|
|
580
|
-
if ((value = block.call(__context,
|
608
|
+
if ((value = block.call(__context, key, obj)) === __breaker) {
|
581
609
|
return __breaker.$v;
|
582
610
|
}
|
583
611
|
|
584
612
|
if (value !== false && value !== nil) {
|
585
|
-
|
613
|
+
keys2.push(key);
|
614
|
+
map2[key] = obj;
|
586
615
|
}
|
587
616
|
}
|
588
617
|
|
@@ -592,19 +621,22 @@ class Hash
|
|
592
621
|
|
593
622
|
def select!(&block)
|
594
623
|
%x{
|
595
|
-
var map = #{self}.map, result = nil;
|
624
|
+
var map = #{self}.map, keys = #{self}.keys, value, result = nil;
|
596
625
|
|
597
|
-
for (var
|
598
|
-
var
|
599
|
-
value;
|
626
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
627
|
+
var key = keys[i], obj = map[key];
|
600
628
|
|
601
|
-
if ((value = block.call(__context,
|
629
|
+
if ((value = block.call(__context, key, obj)) === __breaker) {
|
602
630
|
return __breaker.$v;
|
603
631
|
}
|
604
632
|
|
605
633
|
if (value === false || value === nil) {
|
606
|
-
|
607
|
-
|
634
|
+
keys.splice(i, 1);
|
635
|
+
delete map[key];
|
636
|
+
|
637
|
+
length--;
|
638
|
+
i--;
|
639
|
+
result = #{self}
|
608
640
|
}
|
609
641
|
}
|
610
642
|
|
@@ -614,12 +646,15 @@ class Hash
|
|
614
646
|
|
615
647
|
def shift
|
616
648
|
%x{
|
617
|
-
var map = #{self}.map;
|
649
|
+
var keys = #{self}.keys, map = #{self}.map;
|
618
650
|
|
619
|
-
|
620
|
-
var
|
621
|
-
|
622
|
-
|
651
|
+
if (keys.length) {
|
652
|
+
var key = keys[0], obj = map[key];
|
653
|
+
|
654
|
+
delete map[key];
|
655
|
+
keys.splice(0, 1);
|
656
|
+
|
657
|
+
return [key, obj];
|
623
658
|
}
|
624
659
|
|
625
660
|
return nil;
|
@@ -630,13 +665,11 @@ class Hash
|
|
630
665
|
|
631
666
|
def to_a
|
632
667
|
%x{
|
633
|
-
var map
|
634
|
-
result = [];
|
668
|
+
var keys = #{self}.keys, map = #{self}.map, result = [];
|
635
669
|
|
636
|
-
for (var
|
637
|
-
var
|
638
|
-
|
639
|
-
result.push([bucket[0], bucket[1]]);
|
670
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
671
|
+
var key = keys[i];
|
672
|
+
result.push([key, map[key]]);
|
640
673
|
}
|
641
674
|
|
642
675
|
return result;
|
@@ -649,30 +682,29 @@ class Hash
|
|
649
682
|
|
650
683
|
def to_json
|
651
684
|
%x{
|
652
|
-
var
|
685
|
+
var inspect = [], keys = #{self}.keys, map = #{self}.map;
|
653
686
|
|
654
|
-
for (var
|
655
|
-
|
656
|
-
|
687
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
688
|
+
var key = keys[i];
|
689
|
+
inspect.push(#{`key`.to_json} + ': ' + #{`map[key]`.to_json});
|
657
690
|
}
|
658
691
|
|
659
|
-
return '{' +
|
692
|
+
return '{' + inspect.join(', ') + '}';
|
660
693
|
}
|
661
694
|
end
|
662
695
|
|
663
696
|
def to_native
|
664
697
|
%x{
|
665
|
-
var result = {}, map = #{self}.map, bucket, value;
|
698
|
+
var result = {}, keys = #{self}.keys, map = #{self}.map, bucket, value;
|
666
699
|
|
667
|
-
for (var
|
668
|
-
|
669
|
-
value = bucket[1];
|
700
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
701
|
+
var key = keys[i], obj = map[key];
|
670
702
|
|
671
|
-
if (
|
672
|
-
result[
|
703
|
+
if (obj.$to_native) {
|
704
|
+
result[key] = #{`obj`.to_native};
|
673
705
|
}
|
674
706
|
else {
|
675
|
-
result[
|
707
|
+
result[key] = obj;
|
676
708
|
}
|
677
709
|
}
|
678
710
|
|
@@ -689,7 +721,7 @@ class Hash
|
|
689
721
|
var map = #{self}.map;
|
690
722
|
|
691
723
|
for (var assoc in map) {
|
692
|
-
var v = map[assoc]
|
724
|
+
var v = map[assoc];
|
693
725
|
if (#{`v` == value}) {
|
694
726
|
return true;
|
695
727
|
}
|
@@ -706,8 +738,8 @@ class Hash
|
|
706
738
|
var map = #{self}.map,
|
707
739
|
result = [];
|
708
740
|
|
709
|
-
for (var
|
710
|
-
result.push(map[
|
741
|
+
for (var key in map) {
|
742
|
+
result.push(map[key]);
|
711
743
|
}
|
712
744
|
|
713
745
|
return result;
|