opal 0.3.19 → 0.3.20
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.
- data/.gitignore +3 -1
- data/Gemfile +3 -2
- data/README.md +304 -48
- data/Rakefile +1 -2
- data/core/alpha.rb +2 -1
- data/core/array.rb +92 -96
- data/core/basic_object.rb +1 -10
- data/core/boolean.rb +6 -18
- data/core/class.rb +9 -10
- data/core/comparable.rb +1 -1
- data/core/enumerable.rb +11 -11
- data/core/enumerator.rb +2 -10
- data/core/error.rb +16 -31
- data/core/hash.rb +32 -36
- data/core/json.rb +50 -0
- data/core/kernel.rb +48 -57
- data/core/load_order +3 -5
- data/core/module.rb +37 -35
- data/core/nil_class.rb +4 -0
- data/core/numeric.rb +10 -30
- data/core/proc.rb +1 -1
- data/core/range.rb +3 -4
- data/core/regexp.rb +21 -6
- data/core/runtime.js +278 -370
- data/core/string.rb +21 -37
- data/core/struct.rb +11 -3
- data/core/time.rb +44 -37
- data/lib/opal.rb +3 -3
- data/lib/opal/builder.rb +48 -27
- data/lib/opal/builder_task.rb +3 -20
- data/lib/opal/grammar.rb +18 -13
- data/lib/opal/grammar.y +7 -4
- data/lib/opal/parser.rb +290 -199
- data/lib/opal/scope.rb +187 -176
- data/lib/opal/version.rb +1 -1
- data/test/core/kernel/define_singleton_method_spec.rb +21 -0
- data/test/core/time/at_spec.rb +7 -0
- data/test/core/time/day_spec.rb +5 -0
- data/test/core/time/friday_spec.rb +9 -0
- data/test/core/time/hour_spec.rb +5 -0
- data/test/core/time/min_spec.rb +5 -0
- data/test/core/time/monday_spec.rb +9 -0
- data/test/core/time/month_spec.rb +5 -0
- data/test/core/time/now_spec.rb +5 -0
- data/test/core/time/saturday_spec.rb +9 -0
- data/test/index.html +2 -1
- data/test/language/singleton_class_spec.rb +0 -16
- data/test/opal/array/to_json_spec.rb +7 -0
- data/test/opal/boolean/singleton_class_spec.rb +9 -0
- data/test/opal/boolean/to_json_spec.rb +9 -0
- data/test/opal/hash/to_json_spec.rb +9 -0
- data/test/opal/json/parse_spec.rb +31 -0
- data/test/opal/kernel/to_json_spec.rb +5 -0
- data/test/opal/nil/to_json_spec.rb +5 -0
- data/test/opal/numeric/to_json_spec.rb +6 -0
- data/test/opal/runtime/call_spec.rb +16 -0
- data/test/opal/runtime/defined_spec.rb +11 -0
- data/test/opal/runtime/super_spec.rb +16 -0
- data/test/opal/string/to_json_spec.rb +6 -0
- data/test/spec_helper.rb +1 -3
- metadata +48 -15
- data/core/dir.rb +0 -89
- data/core/file.rb +0 -85
- data/core/match_data.rb +0 -35
- data/core/rational.rb +0 -16
- data/test/core/file/expand_path_spec.rb +0 -20
data/core/basic_object.rb
CHANGED
@@ -25,7 +25,7 @@ class BasicObject
|
|
25
25
|
no_block_given();
|
26
26
|
}
|
27
27
|
|
28
|
-
return block.call(this,
|
28
|
+
return block.call(this, this);
|
29
29
|
}
|
30
30
|
end
|
31
31
|
|
@@ -42,13 +42,4 @@ class BasicObject
|
|
42
42
|
def method_missing(symbol, *args)
|
43
43
|
raise NoMethodError, "undefined method `#{symbol}` for #{inspect}"
|
44
44
|
end
|
45
|
-
|
46
|
-
def singleton_method_added(symbol)
|
47
|
-
end
|
48
|
-
|
49
|
-
def singleton_method_removed(symbol)
|
50
|
-
end
|
51
|
-
|
52
|
-
def singleton_method_undefined(symbol)
|
53
|
-
end
|
54
45
|
end
|
data/core/boolean.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class Boolean < `Boolean`
|
2
2
|
%x{
|
3
|
-
|
3
|
+
Boolean_prototype._isBoolean = true;
|
4
4
|
}
|
5
5
|
|
6
6
|
def &(other)
|
@@ -19,28 +19,16 @@ class Boolean < `Boolean`
|
|
19
19
|
`(this == true) === other.valueOf()`
|
20
20
|
end
|
21
21
|
|
22
|
-
def class
|
23
|
-
`(this == true) ? #{TrueClass} : #{FalseClass}`
|
24
|
-
end
|
25
|
-
|
26
22
|
alias singleton_class class
|
27
23
|
|
28
|
-
def
|
29
|
-
`(
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
class TrueClass
|
34
|
-
def self.===(obj)
|
35
|
-
`obj === true`
|
24
|
+
def to_json
|
25
|
+
`this.valueOf() ? 'true' : 'false'`
|
36
26
|
end
|
37
|
-
end
|
38
27
|
|
39
|
-
|
40
|
-
|
41
|
-
`obj === false`
|
28
|
+
def to_s
|
29
|
+
`(this == true) ? 'true' : 'false'`
|
42
30
|
end
|
43
31
|
end
|
44
32
|
|
45
33
|
TRUE = true
|
46
|
-
FALSE = false
|
34
|
+
FALSE = false
|
data/core/class.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
class Class
|
2
2
|
def self.new(sup = Object, &block)
|
3
3
|
%x{
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
make_metaclass(klass, sup._klass);
|
4
|
+
function AnonClass(){};
|
5
|
+
var klass = boot_class(sup, AnonClass)
|
6
|
+
klass._name = nil;
|
8
7
|
|
9
8
|
sup.$inherited(klass);
|
10
9
|
|
@@ -17,7 +16,11 @@ class Class
|
|
17
16
|
end
|
18
17
|
|
19
18
|
def allocate
|
20
|
-
|
19
|
+
%x{
|
20
|
+
var obj = new this;
|
21
|
+
obj._id = unique_id++;
|
22
|
+
return obj;
|
23
|
+
}
|
21
24
|
end
|
22
25
|
|
23
26
|
def new(*args, &block)
|
@@ -37,11 +40,7 @@ class Class
|
|
37
40
|
var sup = this._super;
|
38
41
|
|
39
42
|
if (!sup) {
|
40
|
-
|
41
|
-
return nil;
|
42
|
-
}
|
43
|
-
|
44
|
-
throw RubyRuntimeError.$new('uninitialized class');
|
43
|
+
return nil;
|
45
44
|
}
|
46
45
|
|
47
46
|
while (sup && (sup._isIClass)) {
|
data/core/comparable.rb
CHANGED
data/core/enumerable.rb
CHANGED
@@ -98,7 +98,7 @@ module Enumerable
|
|
98
98
|
}
|
99
99
|
end
|
100
100
|
|
101
|
-
def count(object
|
101
|
+
def count(object, &block)
|
102
102
|
%x{
|
103
103
|
var result = 0;
|
104
104
|
|
@@ -130,8 +130,8 @@ module Enumerable
|
|
130
130
|
}
|
131
131
|
end
|
132
132
|
|
133
|
-
def detect(ifnone
|
134
|
-
return enum_for :detect, ifnone unless
|
133
|
+
def detect(ifnone, &block)
|
134
|
+
return enum_for :detect, ifnone unless block_given?
|
135
135
|
|
136
136
|
%x{
|
137
137
|
var result = nil;
|
@@ -161,7 +161,7 @@ module Enumerable
|
|
161
161
|
return ifnone.$call();
|
162
162
|
}
|
163
163
|
|
164
|
-
return ifnone
|
164
|
+
return ifnone == null ? nil : ifnone;
|
165
165
|
}
|
166
166
|
end
|
167
167
|
|
@@ -185,7 +185,7 @@ module Enumerable
|
|
185
185
|
end
|
186
186
|
|
187
187
|
def drop_while(&block)
|
188
|
-
return enum_for :drop_while unless
|
188
|
+
return enum_for :drop_while unless block_given?
|
189
189
|
|
190
190
|
%x{
|
191
191
|
var result = [];
|
@@ -212,7 +212,7 @@ module Enumerable
|
|
212
212
|
end
|
213
213
|
|
214
214
|
def each_with_index(&block)
|
215
|
-
return enum_for :each_with_index unless
|
215
|
+
return enum_for :each_with_index unless block_given?
|
216
216
|
|
217
217
|
%x{
|
218
218
|
var index = 0;
|
@@ -234,7 +234,7 @@ module Enumerable
|
|
234
234
|
end
|
235
235
|
|
236
236
|
def each_with_object(object, &block)
|
237
|
-
return enum_for :each_with_object unless
|
237
|
+
return enum_for :each_with_object unless block_given?
|
238
238
|
|
239
239
|
%x{
|
240
240
|
this.$each._p = function(obj) {
|
@@ -268,7 +268,7 @@ module Enumerable
|
|
268
268
|
alias find detect
|
269
269
|
|
270
270
|
def find_all(&block)
|
271
|
-
return enum_for :find_all unless
|
271
|
+
return enum_for :find_all unless block_given?
|
272
272
|
|
273
273
|
%x{
|
274
274
|
var result = [];
|
@@ -295,7 +295,7 @@ module Enumerable
|
|
295
295
|
}
|
296
296
|
end
|
297
297
|
|
298
|
-
def find_index(object
|
298
|
+
def find_index(object, &block)
|
299
299
|
%x{
|
300
300
|
var proc, result = nil, index = 0;
|
301
301
|
|
@@ -336,7 +336,7 @@ module Enumerable
|
|
336
336
|
}
|
337
337
|
end
|
338
338
|
|
339
|
-
def first(number
|
339
|
+
def first(number)
|
340
340
|
%x{
|
341
341
|
var result = [],
|
342
342
|
current = 0,
|
@@ -400,4 +400,4 @@ module Enumerable
|
|
400
400
|
alias take first
|
401
401
|
|
402
402
|
alias to_a entries
|
403
|
-
end
|
403
|
+
end
|
data/core/enumerator.rb
CHANGED
@@ -75,7 +75,7 @@ class Enumerator
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def each(&block)
|
78
|
-
return self unless
|
78
|
+
return self unless block_given?
|
79
79
|
|
80
80
|
@object.__send__ @method, *@args, &block
|
81
81
|
end
|
@@ -115,12 +115,4 @@ class Enumerator
|
|
115
115
|
@cache = nil
|
116
116
|
@current = nil
|
117
117
|
end
|
118
|
-
end
|
119
|
-
|
120
|
-
module Kernel
|
121
|
-
def enum_for (method = :each, *args)
|
122
|
-
Enumerator.new(self, method, *args)
|
123
|
-
end
|
124
|
-
|
125
|
-
alias to_enum enum_for
|
126
|
-
end
|
118
|
+
end
|
data/core/error.rb
CHANGED
@@ -1,30 +1,22 @@
|
|
1
1
|
class Exception < `Error`
|
2
|
-
|
3
|
-
%x{
|
4
|
-
if (Error.captureStackTrace) {
|
5
|
-
Error.captureStackTrace(this);
|
6
|
-
}
|
2
|
+
attr_reader :message
|
7
3
|
|
8
|
-
|
9
|
-
|
4
|
+
def initialize(message = '')
|
5
|
+
@message = message
|
10
6
|
end
|
11
7
|
|
12
8
|
def backtrace
|
13
9
|
%x{
|
14
|
-
if (this._bt !== undefined) {
|
15
|
-
return this._bt;
|
16
|
-
}
|
17
|
-
|
18
10
|
var backtrace = this.stack;
|
19
11
|
|
20
12
|
if (typeof(backtrace) === 'string') {
|
21
|
-
return
|
13
|
+
return backtrace.split("\\n");
|
22
14
|
}
|
23
15
|
else if (backtrace) {
|
24
|
-
|
16
|
+
return backtrace;
|
25
17
|
}
|
26
18
|
|
27
|
-
return
|
19
|
+
return ["No backtrace available"];
|
28
20
|
}
|
29
21
|
end
|
30
22
|
|
@@ -32,23 +24,16 @@ class Exception < `Error`
|
|
32
24
|
"#<#{self.class}: '#{message}'>"
|
33
25
|
end
|
34
26
|
|
35
|
-
def message
|
36
|
-
`this.message`
|
37
|
-
end
|
38
|
-
|
39
27
|
alias to_s message
|
40
28
|
end
|
41
29
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
class KeyError < IndexError; end
|
53
|
-
class RangeError < StandardError; end
|
54
|
-
class NotImplementedError < Exception; end
|
30
|
+
StandardError = Exception
|
31
|
+
RuntimeError = Exception
|
32
|
+
LocalJumpError = Exception
|
33
|
+
TypeError = Exception
|
34
|
+
NameError = Exception
|
35
|
+
NoMethodError = Exception
|
36
|
+
ArgumentError = Exception
|
37
|
+
IndexError = Exception
|
38
|
+
KeyError = Exception
|
39
|
+
RangeError = Exception
|
data/core/hash.rb
CHANGED
@@ -2,35 +2,18 @@ class Hash
|
|
2
2
|
include Enumerable
|
3
3
|
|
4
4
|
%x{
|
5
|
-
|
5
|
+
__hash = Opal.hash = function() {
|
6
|
+
var hash = new Hash,
|
7
|
+
args = __slice.call(arguments),
|
8
|
+
assocs = {};
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
assocs = {};
|
10
|
+
hash.map = assocs;
|
11
|
+
hash.none = nil;
|
12
|
+
hash.proc = nil;
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
if (args.length == 1 && args[0]._isArray) {
|
17
|
-
args = args[0];
|
18
|
-
|
19
|
-
for (var i = 0, length = args.length, key; i < length; i++) {
|
20
|
-
key = args[i][0];
|
21
|
-
|
22
|
-
assocs[key] = [key, args[i][1]];
|
23
|
-
}
|
24
|
-
}
|
25
|
-
else if (arguments.length % 2 == 0) {
|
26
|
-
for (var i = 0, length = args.length, key; i < length; i++) {
|
27
|
-
key = args[i];
|
28
|
-
|
29
|
-
assocs[key] = [key, args[++i]];
|
30
|
-
}
|
31
|
-
}
|
32
|
-
else {
|
33
|
-
throw RubyArgError.$new('odd number of arguments for Hash');
|
14
|
+
for (var i = 0, length = args.length, key; i < length; i++) {
|
15
|
+
key = args[i];
|
16
|
+
assocs[key] = [key, args[++i]];
|
34
17
|
}
|
35
18
|
|
36
19
|
return hash;
|
@@ -45,7 +28,7 @@ class Hash
|
|
45
28
|
`__hash()`
|
46
29
|
end
|
47
30
|
|
48
|
-
def self.new(defaults
|
31
|
+
def self.new(defaults, &block)
|
49
32
|
%x{
|
50
33
|
var hash = __hash();
|
51
34
|
|
@@ -211,7 +194,7 @@ class Hash
|
|
211
194
|
var bucket = map[assoc];
|
212
195
|
|
213
196
|
if (block.call(__context, bucket[0], bucket[1]) === __breaker) {
|
214
|
-
return
|
197
|
+
return __breaker.$v;
|
215
198
|
}
|
216
199
|
}
|
217
200
|
|
@@ -269,7 +252,7 @@ class Hash
|
|
269
252
|
|
270
253
|
alias eql? ==
|
271
254
|
|
272
|
-
def fetch(key, defaults
|
255
|
+
def fetch(key, defaults, &block)
|
273
256
|
%x{
|
274
257
|
var bucket = this.map[key];
|
275
258
|
|
@@ -291,11 +274,11 @@ class Hash
|
|
291
274
|
return defaults;
|
292
275
|
}
|
293
276
|
|
294
|
-
|
277
|
+
#{ raise "key not found" };
|
295
278
|
}
|
296
279
|
end
|
297
280
|
|
298
|
-
def flatten(level
|
281
|
+
def flatten(level)
|
299
282
|
%x{
|
300
283
|
var map = this.map,
|
301
284
|
result = [];
|
@@ -421,7 +404,7 @@ class Hash
|
|
421
404
|
var bucket = map[assoc];
|
422
405
|
|
423
406
|
if ((value = block.call(__context, bucket[0], bucket[1])) === __breaker) {
|
424
|
-
return
|
407
|
+
return __breaker.$v;
|
425
408
|
}
|
426
409
|
|
427
410
|
if (value === false || value === nil) {
|
@@ -488,7 +471,7 @@ class Hash
|
|
488
471
|
for (var assoc in map) {
|
489
472
|
var bucket = map[assoc], key = bucket[0], val = bucket[1];
|
490
473
|
|
491
|
-
if (
|
474
|
+
if (__hasOwn.call(map2, assoc)) {
|
492
475
|
val = block.call(__context, key, map2[assoc][1], val);
|
493
476
|
}
|
494
477
|
|
@@ -516,7 +499,7 @@ class Hash
|
|
516
499
|
for (var assoc in map2) {
|
517
500
|
var bucket = map2[assoc], key = bucket[0], val = bucket[1];
|
518
501
|
|
519
|
-
if (
|
502
|
+
if (__hasOwn.call(map, assoc)) {
|
520
503
|
val = block.call(__context, key, map[assoc][1], val);
|
521
504
|
}
|
522
505
|
|
@@ -663,6 +646,19 @@ class Hash
|
|
663
646
|
self
|
664
647
|
end
|
665
648
|
|
649
|
+
def to_json
|
650
|
+
%x{
|
651
|
+
var parts = [], map = this.map, bucket;
|
652
|
+
|
653
|
+
for (var assoc in map) {
|
654
|
+
bucket = map[assoc];
|
655
|
+
parts.push(#{ `bucket[0]`.to_json } + ': ' + #{ `bucket[1]`.to_json });
|
656
|
+
}
|
657
|
+
|
658
|
+
return '{' + parts.join(', ') + '}';
|
659
|
+
}
|
660
|
+
end
|
661
|
+
|
666
662
|
alias to_s inspect
|
667
663
|
|
668
664
|
alias update merge!
|
@@ -696,4 +692,4 @@ class Hash
|
|
696
692
|
return result;
|
697
693
|
}
|
698
694
|
end
|
699
|
-
end
|
695
|
+
end
|
data/core/json.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
`var json_parse = JSON.parse;`
|
2
|
+
|
3
|
+
module JSON
|
4
|
+
def self.parse(source)
|
5
|
+
`return to_opal(json_parse(source));`
|
6
|
+
end
|
7
|
+
|
8
|
+
%x{
|
9
|
+
function to_opal(value) {
|
10
|
+
switch (typeof value) {
|
11
|
+
case 'string':
|
12
|
+
return value;
|
13
|
+
|
14
|
+
case 'number':
|
15
|
+
return value;
|
16
|
+
|
17
|
+
case 'boolean':
|
18
|
+
return !!value;
|
19
|
+
|
20
|
+
case 'null':
|
21
|
+
return nil;
|
22
|
+
|
23
|
+
case 'object':
|
24
|
+
if (!value) return nil;
|
25
|
+
|
26
|
+
if (value._isArray) {
|
27
|
+
var arr = [];
|
28
|
+
|
29
|
+
for (var i = 0, ii = value.length; i < ii; i++) {
|
30
|
+
arr.push(to_opal(value[i]));
|
31
|
+
}
|
32
|
+
|
33
|
+
return arr;
|
34
|
+
}
|
35
|
+
else {
|
36
|
+
var hash = #{ {} }, v, map = hash.map;
|
37
|
+
|
38
|
+
for (var k in value) {
|
39
|
+
if (__hasOwn.call(value, k)) {
|
40
|
+
v = to_opal(value[k]);
|
41
|
+
map[k] = [k, v];
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
return hash;
|
47
|
+
}
|
48
|
+
};
|
49
|
+
}
|
50
|
+
end
|