opal 0.3.31 → 0.3.32
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/LICENSE +1 -1
- data/README.md +1 -1
- data/core/array.rb +24 -2
- data/core/basic_object.rb +49 -0
- data/core/boolean.rb +2 -2
- data/core/class.rb +2 -2
- data/core/enumerable.rb +27 -51
- data/core/hash.rb +159 -101
- data/core/json.rb +2 -1
- data/core/kernel.rb +9 -41
- data/core/load_order +1 -0
- data/core/numeric.rb +2 -2
- data/core/proc.rb +2 -2
- data/core/range.rb +2 -2
- data/core/runtime.js +9 -5
- data/core/string.rb +5 -5
- data/lib/opal.rb +2 -2
- data/lib/opal/parser.rb +59 -40
- data/lib/opal/scope.rb +4 -3
- data/lib/opal/version.rb +1 -1
- data/spec/core/array/sort_spec.rb +22 -0
- data/spec/core/runtime/class_hierarchy_spec.rb +3 -1
- metadata +6 -3
data/core/json.rb
CHANGED
@@ -38,11 +38,12 @@ module JSON
|
|
38
38
|
return arr;
|
39
39
|
}
|
40
40
|
else {
|
41
|
-
var hash = #{ {} }, v, map = hash.map;
|
41
|
+
var hash = #{ {} }, v, map = hash.map, keys = hash.keys;
|
42
42
|
|
43
43
|
for (var k in value) {
|
44
44
|
if (__hasOwn.call(value, k)) {
|
45
45
|
v = to_opal(value[k]);
|
46
|
+
keys.push(k);
|
46
47
|
map[k] = v;
|
47
48
|
}
|
48
49
|
}
|
data/core/kernel.rb
CHANGED
@@ -1,12 +1,17 @@
|
|
1
1
|
module Kernel
|
2
|
+
# bridged from BasicObject
|
3
|
+
alias :initialize :initialize
|
4
|
+
alias :== :==
|
5
|
+
alias :__send__ :__send__
|
6
|
+
alias :eql? :eql?
|
7
|
+
alias :equal? :equal?
|
8
|
+
alias :instance_eval :instance_eval
|
9
|
+
alias :instance_exec :instance_exec
|
10
|
+
|
2
11
|
def =~(obj)
|
3
12
|
false
|
4
13
|
end
|
5
14
|
|
6
|
-
def ==(other)
|
7
|
-
`#{self} === other`
|
8
|
-
end
|
9
|
-
|
10
15
|
def ===(other)
|
11
16
|
`#{self} == other`
|
12
17
|
end
|
@@ -45,14 +50,6 @@ module Kernel
|
|
45
50
|
}
|
46
51
|
end
|
47
52
|
|
48
|
-
def __send__(symbol, *args, &block)
|
49
|
-
%x{
|
50
|
-
return #{self}['$' + symbol].apply(#{self}, args);
|
51
|
-
}
|
52
|
-
end
|
53
|
-
|
54
|
-
alias eql? ==
|
55
|
-
|
56
53
|
def Array(object)
|
57
54
|
%x{
|
58
55
|
if (object.$to_ary) {
|
@@ -234,39 +231,10 @@ module Kernel
|
|
234
231
|
`#{self}._id`
|
235
232
|
end
|
236
233
|
|
237
|
-
def initialize(*)
|
238
|
-
end
|
239
|
-
|
240
234
|
def inspect
|
241
235
|
to_s
|
242
236
|
end
|
243
237
|
|
244
|
-
def instance_eval(&block)
|
245
|
-
%x{
|
246
|
-
if (block === nil) {
|
247
|
-
no_block_given();
|
248
|
-
}
|
249
|
-
|
250
|
-
var block_self = block._s, result;
|
251
|
-
|
252
|
-
block._s = null;
|
253
|
-
result = block.call(#{self}, #{self});
|
254
|
-
block._s = block_self;
|
255
|
-
|
256
|
-
return result;
|
257
|
-
}
|
258
|
-
end
|
259
|
-
|
260
|
-
def instance_exec(*args, &block)
|
261
|
-
%x{
|
262
|
-
if (block === nil) {
|
263
|
-
no_block_given();
|
264
|
-
}
|
265
|
-
|
266
|
-
return block.apply(#{self}, args);
|
267
|
-
}
|
268
|
-
end
|
269
|
-
|
270
238
|
def instance_of?(klass)
|
271
239
|
`#{self}._klass === klass`
|
272
240
|
end
|
data/core/load_order
CHANGED
data/core/numeric.rb
CHANGED
data/core/proc.rb
CHANGED
data/core/range.rb
CHANGED
@@ -2,7 +2,7 @@ class Range
|
|
2
2
|
include Enumerable
|
3
3
|
|
4
4
|
%x{
|
5
|
-
|
5
|
+
Range.prototype._isRange = true;
|
6
6
|
|
7
7
|
Opal.range = function(beg, end, exc) {
|
8
8
|
var range = new Range;
|
@@ -42,7 +42,7 @@ class Range
|
|
42
42
|
`#{self}.begin` <= value && value <= (exclude_end? ? `#{self}.end` - 1 : `#{self}.end`)
|
43
43
|
end
|
44
44
|
|
45
|
-
def each
|
45
|
+
def each(&block)
|
46
46
|
current = min
|
47
47
|
|
48
48
|
while current != max
|
data/core/runtime.js
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
// The Opal object that is exposed globally
|
2
2
|
var Opal = this.Opal = {};
|
3
3
|
|
4
|
+
// Very root class
|
5
|
+
function BasicObject(){}
|
6
|
+
|
4
7
|
// Core Object class
|
5
8
|
function Object(){}
|
6
9
|
|
@@ -216,11 +219,13 @@ Opal.puts = function(a) { console.log(a); };
|
|
216
219
|
// Initialization
|
217
220
|
// --------------
|
218
221
|
|
219
|
-
boot_defclass('
|
222
|
+
boot_defclass('BasicObject', BasicObject)
|
223
|
+
boot_defclass('Object', Object, BasicObject);
|
220
224
|
boot_defclass('Class', Class, Object);
|
221
225
|
|
222
226
|
Class.prototype = Function.prototype;
|
223
|
-
|
227
|
+
|
228
|
+
BasicObject._klass = Object._klass = Class._klass = Class;
|
224
229
|
|
225
230
|
// Implementation of Class#===
|
226
231
|
function module_eqq(object) {
|
@@ -279,7 +284,7 @@ function __sdonate(defined) {
|
|
279
284
|
|
280
285
|
var bridged_classes = Object.$included_in = [];
|
281
286
|
|
282
|
-
Object._scope = Opal;
|
287
|
+
BasicObject._scope = Object._scope = Opal;
|
283
288
|
Opal.Module = Opal.Class;
|
284
289
|
Opal.Kernel = Object;
|
285
290
|
|
@@ -296,6 +301,5 @@ Opal.top = new Object;
|
|
296
301
|
|
297
302
|
Opal.klass(Object, Object, 'NilClass', NilClass)
|
298
303
|
Opal.nil = new NilClass;
|
299
|
-
Opal.nil.call = Opal.nil.apply = no_block_given;
|
300
304
|
|
301
|
-
Opal.breaker = new Error('unexpected break');
|
305
|
+
Opal.breaker = new Error('unexpected break');
|
data/core/string.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class String < `String`
|
2
|
-
`
|
2
|
+
`String.prototype._isString = true`
|
3
3
|
|
4
4
|
include Comparable
|
5
5
|
|
@@ -232,7 +232,7 @@ class String < `String`
|
|
232
232
|
|
233
233
|
alias_native :getbyte, :charCodeAt
|
234
234
|
|
235
|
-
def gsub(pattern, replace
|
235
|
+
def gsub(pattern, replace)
|
236
236
|
if pattern.is_a?(String)
|
237
237
|
pattern = /#{Regexp.escape(pattern)}/
|
238
238
|
end
|
@@ -242,7 +242,7 @@ class String < `String`
|
|
242
242
|
options = pattern.substr(pattern.lastIndexOf('/') + 1) + 'g',
|
243
243
|
regexp = pattern.substr(1, pattern.lastIndexOf('/') - 1);
|
244
244
|
|
245
|
-
return #{sub
|
245
|
+
return #{self}.$sub(new RegExp(regexp, options), replace);
|
246
246
|
}
|
247
247
|
end
|
248
248
|
|
@@ -397,7 +397,7 @@ class String < `String`
|
|
397
397
|
`#{self}.replace(/^\\s*/, '').replace(/\\s*$/, '')`
|
398
398
|
end
|
399
399
|
|
400
|
-
def sub(pattern, replace, &block)
|
400
|
+
def sub(pattern, replace = undefined, &block)
|
401
401
|
%x{
|
402
402
|
if (typeof(replace) === 'string') {
|
403
403
|
return #{self}.replace(pattern, replace);
|
@@ -408,7 +408,7 @@ class String < `String`
|
|
408
408
|
return block(str);
|
409
409
|
});
|
410
410
|
}
|
411
|
-
else if (replace
|
411
|
+
else if (replace !== undefined) {
|
412
412
|
if (#{replace.is_a?(Hash)}) {
|
413
413
|
return #{self}.replace(pattern, function(str) {
|
414
414
|
var value = #{replace[str]};
|
data/lib/opal.rb
CHANGED
@@ -39,8 +39,8 @@ module Opal
|
|
39
39
|
|
40
40
|
[
|
41
41
|
"// Opal v#{Opal::VERSION}",
|
42
|
-
"// http://
|
43
|
-
"// Copyright
|
42
|
+
"// http://opalrb.org",
|
43
|
+
"// Copyright 2013, Adam Beynon",
|
44
44
|
"// Released under the MIT License",
|
45
45
|
"(function(undefined) {",
|
46
46
|
runtime,
|
data/lib/opal/parser.rb
CHANGED
@@ -693,7 +693,7 @@ module Opal
|
|
693
693
|
end
|
694
694
|
|
695
695
|
itercode = "function(#{params.join ', '}) {\n#{code}\n#@indent}"
|
696
|
-
call << ("(%s = %s, %s._s = %s, %s)" % [identity, itercode, identity, current_self, identity])
|
696
|
+
call[3] << s(:js_tmp, "(%s = %s, %s._s = %s, %s)" % [identity, itercode, identity, current_self, identity])
|
697
697
|
|
698
698
|
process call, level
|
699
699
|
end
|
@@ -796,7 +796,7 @@ module Opal
|
|
796
796
|
splat = arglist[1..-1].any? { |a| a.first == :splat }
|
797
797
|
|
798
798
|
if Array === arglist.last and arglist.last.first == :block_pass
|
799
|
-
|
799
|
+
arglist << s(:js_tmp, process(arglist.pop, :expr))
|
800
800
|
elsif iter
|
801
801
|
block = iter
|
802
802
|
end
|
@@ -815,24 +815,8 @@ module Opal
|
|
815
815
|
|
816
816
|
args = process arglist, :expr
|
817
817
|
|
818
|
-
|
819
|
-
|
820
|
-
[tmprecv, recv_code, tmprecv, mid, block, tmprecv, mid]
|
821
|
-
|
822
|
-
if splat
|
823
|
-
"%s.apply(null, %s))" % [dispatch, args]
|
824
|
-
else
|
825
|
-
"%s(%s))" % [dispatch, args]
|
826
|
-
end
|
827
|
-
else
|
828
|
-
# m_missing = " || __mm(#{meth.to_s.inspect})"
|
829
|
-
# dispatch = "((#{tmprecv} = #{recv_code}).$m#{mid}#{ m_missing })"
|
830
|
-
# splat ? "#{dispatch}.apply(null, #{args})" : "#{dispatch}(#{args})"
|
831
|
-
dispatch = tmprecv ? "(#{tmprecv} = #{recv_code})#{mid}" : "#{recv_code}#{mid}"
|
832
|
-
splat ? "#{dispatch}.apply(#{tmprecv || recv_code}, #{args})" : "#{dispatch}(#{args})"
|
833
|
-
end
|
834
|
-
|
835
|
-
result
|
818
|
+
dispatch = tmprecv ? "(#{tmprecv} = #{recv_code})#{mid}" : "#{recv_code}#{mid}"
|
819
|
+
splat ? "#{dispatch}.apply(#{tmprecv || recv_code}, #{args})" : "#{dispatch}(#{args})"
|
836
820
|
end
|
837
821
|
|
838
822
|
# s(:arglist, [arg [, arg ..]])
|
@@ -1035,22 +1019,28 @@ module Opal
|
|
1035
1019
|
# opt args if last arg is sexp
|
1036
1020
|
opt = args.pop if Array === args.last
|
1037
1021
|
|
1022
|
+
argc = args.length - 1
|
1023
|
+
|
1038
1024
|
# block name &block
|
1039
1025
|
if args.last.to_s.start_with? '&'
|
1040
1026
|
block_name = args.pop.to_s[1..-1].to_sym
|
1027
|
+
argc -= 1
|
1041
1028
|
end
|
1042
1029
|
|
1043
1030
|
# splat args *splat
|
1044
1031
|
if args.last.to_s.start_with? '*'
|
1045
1032
|
if args.last == :*
|
1046
1033
|
args.pop
|
1034
|
+
argc -= 1
|
1047
1035
|
else
|
1048
1036
|
splat = args[-1].to_s[1..-1].to_sym
|
1049
1037
|
args[-1] = splat
|
1050
|
-
|
1038
|
+
argc -= 1
|
1051
1039
|
end
|
1052
1040
|
end
|
1053
1041
|
|
1042
|
+
args << block_name if block_name # have to re-add incase there was a splat arg
|
1043
|
+
|
1054
1044
|
indent do
|
1055
1045
|
in_scope(:def) do
|
1056
1046
|
@scope.mid = mid
|
@@ -1064,30 +1054,59 @@ module Opal
|
|
1064
1054
|
@scope.block_name = yielder
|
1065
1055
|
|
1066
1056
|
params = process args, :expr
|
1067
|
-
|
1068
|
-
opt[1..-1].each do |o|
|
1069
|
-
next if o[2][2] == :undefined
|
1070
|
-
id = process s(:lvar, o[1]), :expr
|
1071
|
-
code += ("if (%s == null) {\n%s%s\n%s}" %
|
1072
|
-
[id, @indent + INDENT, process(o, :expre), @indent])
|
1073
|
-
end if opt
|
1074
|
-
|
1075
|
-
code += "#{splat} = __slice.call(arguments, #{len});" if splat
|
1076
|
-
code += "\n#@indent" + process(stmts, :stmt)
|
1077
|
-
|
1078
|
-
# Returns the identity name if identified, nil otherwise
|
1079
|
-
scope_name = @scope.identity
|
1057
|
+
stmt_code = "\n#@indent" + process(stmts, :stmt)
|
1080
1058
|
|
1081
1059
|
if @scope.uses_block?
|
1082
|
-
#
|
1083
|
-
|
1060
|
+
# CASE 1: no args - only the block
|
1061
|
+
if argc == 0 and !splat
|
1062
|
+
# add param name as a function param, to make it cleaner
|
1063
|
+
# params = yielder
|
1064
|
+
code += "if (typeof(#{yielder}) !== 'function') { #{yielder} = nil }"
|
1065
|
+
# CASE 2: we have a splat - use argc to get splat args, then check last one
|
1066
|
+
elsif splat
|
1067
|
+
@scope.add_temp yielder
|
1068
|
+
code += "#{splat} = __slice.call(arguments, #{argc});\n#{@indent}"
|
1069
|
+
code += "if (typeof(#{splat}[#{splat}.length - 1]) === 'function') { #{yielder} = #{splat}.pop(); } else { #{yielder} = nil; }\n#{@indent}"
|
1070
|
+
# CASE 3: we have some opt args
|
1071
|
+
elsif opt
|
1072
|
+
code += "var BLOCK_IDX = arguments.length - 1;\n#{@indent}"
|
1073
|
+
code += "if (typeof(arguments[BLOCK_IDX]) === 'function' && arguments[BLOCK_IDX]._s !== undefined) { #{yielder} = arguments[BLOCK_IDX] } else { #{yielder} = nil }"
|
1074
|
+
lastopt = opt[-1][1]
|
1075
|
+
opt[1..-1].each do |o|
|
1076
|
+
id = process s(:lvar, o[1]), :expr
|
1077
|
+
if o[2][2] == :undefined
|
1078
|
+
code += ("if (%s === %s && typeof(%s) === 'function') { %s = undefined; }" % [id, yielder, id, id])
|
1079
|
+
else
|
1080
|
+
code += ("if (%s == null || %s === %s) {\n%s%s\n%s}" %
|
1081
|
+
[id, id, yielder, @indent + INDENT, process(o, :expre), @indent])
|
1082
|
+
end
|
1083
|
+
end
|
1084
|
+
|
1085
|
+
# CASE 4: normal args and block
|
1086
|
+
else
|
1087
|
+
code += "if (typeof(#{yielder}) !== 'function') { #{yielder} = nil }"
|
1088
|
+
end
|
1089
|
+
else
|
1090
|
+
opt[1..-1].each do |o|
|
1091
|
+
next if o[2][2] == :undefined
|
1092
|
+
id = process s(:lvar, o[1]), :expr
|
1093
|
+
code += ("if (%s == null) {\n%s%s\n%s}" %
|
1094
|
+
[id, @indent + INDENT, process(o, :expre), @indent])
|
1095
|
+
end if opt
|
1096
|
+
|
1097
|
+
code += "#{splat} = __slice.call(arguments, #{argc});" if splat
|
1098
|
+
end
|
1084
1099
|
|
1085
|
-
|
1086
|
-
|
1100
|
+
code += stmt_code
|
1101
|
+
# code += "\n#@indent" + process(stmts, :stmt)
|
1087
1102
|
|
1088
|
-
|
1103
|
+
if @scope.uses_block? and !block_name
|
1104
|
+
params = params.empty? ? yielder : "#{params}, #{yielder}"
|
1089
1105
|
end
|
1090
1106
|
|
1107
|
+
# Returns the identity name if identified, nil otherwise
|
1108
|
+
scope_name = @scope.identity
|
1109
|
+
|
1091
1110
|
uses_super = @scope.uses_super
|
1092
1111
|
|
1093
1112
|
code = "#@indent#{@scope.to_vars}" + code
|
@@ -1237,7 +1256,7 @@ module Opal
|
|
1237
1256
|
map = hash_keys.map { |k| "#{k}: #{hash_obj[k]}"}
|
1238
1257
|
|
1239
1258
|
@helpers[:hash2] = true
|
1240
|
-
"__hash2({#{map.join(', ')}})"
|
1259
|
+
"__hash2([#{hash_keys.join ', '}], {#{map.join(', ')}})"
|
1241
1260
|
else
|
1242
1261
|
@helpers[:hash] = true
|
1243
1262
|
"__hash(#{sexp.map { |p| process p, :expr }.join ', '})"
|
data/lib/opal/scope.rb
CHANGED
@@ -86,7 +86,7 @@ module Opal
|
|
86
86
|
end
|
87
87
|
|
88
88
|
def proto
|
89
|
-
"
|
89
|
+
"def"
|
90
90
|
end
|
91
91
|
|
92
92
|
def should_donate?
|
@@ -98,9 +98,10 @@ module Opal
|
|
98
98
|
def to_vars
|
99
99
|
vars = @locals.map { |l| "#{l} = nil" }
|
100
100
|
vars.push *@temps
|
101
|
+
current_self = @parser.current_self
|
101
102
|
|
102
103
|
iv = ivars.map do |ivar|
|
103
|
-
"if (
|
104
|
+
"if (#{current_self}#{ivar} == null) #{current_self}#{ivar} = nil;\n"
|
104
105
|
end
|
105
106
|
|
106
107
|
indent = @parser.parser_indent
|
@@ -202,7 +203,7 @@ module Opal
|
|
202
203
|
@parent.uses_block!
|
203
204
|
else
|
204
205
|
@uses_block = true
|
205
|
-
identify!
|
206
|
+
# identify!
|
206
207
|
end
|
207
208
|
end
|
208
209
|
|
data/lib/opal/version.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
describe "Array#sort and Array#sort!" do
|
2
|
+
it "return new sorted Array if #sort" do
|
3
|
+
a = [2, 7, 5, 9]
|
4
|
+
b = a.sort
|
5
|
+
|
6
|
+
b.should == [2, 5, 7, 9]
|
7
|
+
b.object_id.should_not == a.object_id
|
8
|
+
end
|
9
|
+
|
10
|
+
it "return same sorted Array if #sort!" do
|
11
|
+
a = [2, 7, 5, 9]
|
12
|
+
b = a.sort!
|
13
|
+
|
14
|
+
b.should == [2, 5, 7, 9]
|
15
|
+
b.object_id.should == a.object_id
|
16
|
+
end
|
17
|
+
|
18
|
+
it "#sort and #sort! should support sorting functions" do
|
19
|
+
["one", "two", "three", "four"].sort {|a , b| a.length <=> b.length }.should == ["one", "two", "four", "three"]
|
20
|
+
[2, 7, 5, 9].sort! {|a , b| b <=> a }.should == [9, 7, 5, 2]
|
21
|
+
end
|
22
|
+
end
|