opal 0.10.0.beta2 → 0.10.0.beta3
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/CHANGELOG.md +9 -1
- data/lib/opal/compiler.rb +15 -9
- data/lib/opal/fragment.rb +8 -1
- data/lib/opal/nodes/args/restarg.rb +6 -1
- data/lib/opal/nodes/base.rb +1 -1
- data/lib/opal/nodes/call.rb +4 -0
- data/lib/opal/nodes/def.rb +20 -25
- data/lib/opal/nodes/hash.rb +89 -17
- data/lib/opal/nodes/iter.rb +30 -2
- data/lib/opal/nodes/logic.rb +54 -4
- data/lib/opal/nodes/node_with_args.rb +72 -0
- data/lib/opal/parser.rb +16 -0
- data/lib/opal/parser/grammar.rb +2555 -2562
- data/lib/opal/parser/grammar.y +28 -20
- data/lib/opal/parser/lexer.rb +4 -4
- data/lib/opal/regexp_anchors.rb +13 -5
- data/lib/opal/source_map.rb +2 -1
- data/lib/opal/version.rb +1 -1
- data/opal/corelib/array.rb +4 -0
- data/opal/corelib/basic_object.rb +3 -1
- data/opal/corelib/constants.rb +1 -1
- data/opal/corelib/file.rb +196 -4
- data/opal/corelib/hash.rb +7 -7
- data/opal/corelib/kernel.rb +7 -4
- data/opal/corelib/marshal.rb +31 -0
- data/opal/corelib/marshal/read_buffer.rb +427 -0
- data/opal/corelib/marshal/write_buffer.rb +383 -0
- data/opal/corelib/method.rb +8 -0
- data/opal/corelib/module.rb +21 -0
- data/opal/corelib/number.rb +19 -5
- data/opal/corelib/proc.rb +33 -6
- data/opal/corelib/range.rb +6 -0
- data/opal/corelib/regexp.rb +5 -1
- data/opal/corelib/runtime.js +69 -17
- data/opal/corelib/string.rb +8 -0
- data/opal/corelib/string/inheritance.rb +4 -0
- data/opal/corelib/struct.rb +5 -0
- data/opal/corelib/unsupported.rb +0 -18
- data/opal/opal/full.rb +1 -0
- data/spec/filters/bugs/basicobject.rb +0 -2
- data/spec/filters/bugs/compiler_opal.rb +5 -0
- data/spec/filters/bugs/enumerable.rb +1 -0
- data/spec/filters/bugs/enumerator.rb +0 -2
- data/spec/filters/bugs/exception.rb +0 -1
- data/spec/filters/bugs/kernel.rb +0 -5
- data/spec/filters/bugs/language.rb +7 -27
- data/spec/filters/bugs/marshal.rb +43 -0
- data/spec/filters/bugs/method.rb +0 -56
- data/spec/filters/bugs/module.rb +0 -1
- data/spec/filters/bugs/proc.rb +0 -46
- data/spec/filters/bugs/regexp.rb +1 -0
- data/spec/filters/bugs/unboundmethod.rb +0 -13
- data/spec/filters/unsupported/bignum.rb +5 -0
- data/spec/filters/unsupported/freeze.rb +2 -0
- data/spec/filters/unsupported/marshal.rb +46 -0
- data/spec/filters/unsupported/symbol.rb +5 -0
- data/spec/lib/compiler/call_spec.rb +29 -29
- data/spec/lib/compiler_spec.rb +7 -1
- data/spec/opal/core/kernel/instance_variables_spec.rb +40 -0
- data/spec/opal/core/language/ternary_operator_spec.rb +6 -0
- data/spec/opal/core/marshal/dump_spec.rb +53 -0
- data/spec/opal/core/marshal/load_spec.rb +7 -0
- data/spec/opal/core/source_map_spec.rb +35 -1
- data/spec/opal/javascript_api_spec.rb +16 -0
- data/spec/opal/stdlib/source_map_spec.rb +8 -0
- data/spec/ruby_specs +7 -4
- data/spec/support/match_helpers.rb +57 -0
- data/spec/support/mspec_rspec_adapter.rb +1 -1
- data/stdlib/opal-parser.rb +3 -1
- data/stdlib/pathname.rb +105 -7
- data/stdlib/racc/parser.rb +551 -138
- data/stdlib/source_map/vlq.rb +3 -2
- data/tasks/testing.rake +4 -2
- metadata +22 -2
@@ -0,0 +1,383 @@
|
|
1
|
+
class NilClass
|
2
|
+
def __marshal__(buffer)
|
3
|
+
buffer.append('0')
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
class Boolean
|
8
|
+
def __marshal__(buffer)
|
9
|
+
if `self`
|
10
|
+
buffer.append('T')
|
11
|
+
else
|
12
|
+
buffer.append('F')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Fixnum
|
18
|
+
def __marshal__(buffer)
|
19
|
+
buffer.append('i')
|
20
|
+
buffer.write_fixnum(self)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Float
|
25
|
+
def __marshal__(buffer)
|
26
|
+
buffer.save_link(self)
|
27
|
+
buffer.append('f')
|
28
|
+
buffer.write_float(self)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class String
|
33
|
+
def __marshal__(buffer)
|
34
|
+
buffer.save_link(self)
|
35
|
+
buffer.write_ivars_prefix(self)
|
36
|
+
buffer.write_extends(self)
|
37
|
+
buffer.write_user_class(String, self)
|
38
|
+
buffer.append('"')
|
39
|
+
buffer.write_string(self)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class Array
|
44
|
+
def __marshal__(buffer)
|
45
|
+
buffer.save_link(self)
|
46
|
+
buffer.write_ivars_prefix(self)
|
47
|
+
buffer.write_extends(self)
|
48
|
+
buffer.write_user_class(Array, self)
|
49
|
+
buffer.append('[')
|
50
|
+
buffer.write_array(self)
|
51
|
+
buffer.write_ivars_suffix(self)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Hash
|
56
|
+
def __marshal__(buffer)
|
57
|
+
if default_proc
|
58
|
+
raise TypeError, "can't dump hash with default proc"
|
59
|
+
end
|
60
|
+
|
61
|
+
buffer.save_link(self)
|
62
|
+
buffer.write_ivars_prefix(self)
|
63
|
+
buffer.write_extends(self)
|
64
|
+
buffer.write_user_class(Hash, self)
|
65
|
+
if default
|
66
|
+
buffer.append('}')
|
67
|
+
buffer.write_hash(self)
|
68
|
+
buffer.write(default)
|
69
|
+
else
|
70
|
+
buffer.append('{')
|
71
|
+
buffer.write_hash(self)
|
72
|
+
end
|
73
|
+
buffer.write_ivars_suffix(self)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class Regexp
|
78
|
+
def __marshal__(buffer)
|
79
|
+
buffer.save_link(self)
|
80
|
+
buffer.write_ivars_prefix(self)
|
81
|
+
buffer.write_extends(self)
|
82
|
+
buffer.write_user_class(Regexp, self)
|
83
|
+
buffer.append('/')
|
84
|
+
buffer.write_regexp(self)
|
85
|
+
buffer.write_ivars_suffix(self)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
class Proc
|
90
|
+
def __marshal__(buffer)
|
91
|
+
raise TypeError, "no _dump_data is defined for class #{self.class}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class Method
|
96
|
+
def __marshal__(buffer)
|
97
|
+
raise TypeError, "no _dump_data is defined for class #{self.class}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
class MatchData
|
102
|
+
def __marshal__(buffer)
|
103
|
+
raise TypeError, "no _dump_data is defined for class #{self.class}"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class Module
|
108
|
+
def __marshal__(buffer)
|
109
|
+
unless name
|
110
|
+
raise TypeError, "can't dump anonymous module"
|
111
|
+
end
|
112
|
+
|
113
|
+
buffer.save_link(self)
|
114
|
+
buffer.append("m")
|
115
|
+
buffer.write_module(self)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
class Class
|
120
|
+
def __marshal__(buffer)
|
121
|
+
unless name
|
122
|
+
raise TypeError, "can't dump anonymous class"
|
123
|
+
end
|
124
|
+
|
125
|
+
if singleton_class?
|
126
|
+
raise TypeError, "singleton class can't be dumped"
|
127
|
+
end
|
128
|
+
|
129
|
+
buffer.save_link(self)
|
130
|
+
buffer.append("c")
|
131
|
+
buffer.write_class(self)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
class BasicObject
|
136
|
+
def __marshal__(buffer)
|
137
|
+
buffer.save_link(self)
|
138
|
+
buffer.write_extends(self)
|
139
|
+
buffer.append("o")
|
140
|
+
buffer.write_object(self)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
class Range
|
145
|
+
def __marshal__(buffer)
|
146
|
+
buffer.save_link(self)
|
147
|
+
buffer.write_extends(self)
|
148
|
+
buffer.append("o")
|
149
|
+
buffer.append_symbol(self.class.name)
|
150
|
+
buffer.write_fixnum(3)
|
151
|
+
buffer.append_symbol('excl')
|
152
|
+
buffer.write(exclude_end?)
|
153
|
+
buffer.append_symbol('begin')
|
154
|
+
buffer.write(self.begin)
|
155
|
+
buffer.append_symbol('end')
|
156
|
+
buffer.write(self.end)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
class Struct
|
161
|
+
def __marshal__(buffer)
|
162
|
+
buffer.save_link(self)
|
163
|
+
buffer.write_ivars_prefix(self)
|
164
|
+
buffer.write_extends(self)
|
165
|
+
buffer.append('S')
|
166
|
+
buffer.append_symbol(self.class.name)
|
167
|
+
buffer.write_fixnum(self.length)
|
168
|
+
each_pair do |attr_name, value|
|
169
|
+
buffer.append_symbol(attr_name)
|
170
|
+
buffer.write(value)
|
171
|
+
end
|
172
|
+
buffer.write_ivars_suffix(self)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
module Marshal
|
177
|
+
class WriteBuffer
|
178
|
+
attr_reader :buffer
|
179
|
+
|
180
|
+
def initialize(object)
|
181
|
+
@object = object
|
182
|
+
@buffer = BinaryString.new
|
183
|
+
@cache = []
|
184
|
+
@extends = Hash.new { |h, k| h[k] = [] }
|
185
|
+
append(version)
|
186
|
+
end
|
187
|
+
|
188
|
+
def write(object = @object)
|
189
|
+
if idx = @cache.index(object.object_id)
|
190
|
+
write_object_link(idx)
|
191
|
+
elsif object.respond_to?(:marshal_dump)
|
192
|
+
write_usr_marshal(object)
|
193
|
+
elsif object.respond_to?(:_dump)
|
194
|
+
write_userdef(object)
|
195
|
+
else
|
196
|
+
case object
|
197
|
+
when nil, true, false, Proc, Method, MatchData, Range, Struct, Array, Class, Module, Hash, Regexp
|
198
|
+
object.__marshal__(self)
|
199
|
+
when Integer
|
200
|
+
Fixnum.instance_method(:__marshal__).bind(object).call(self)
|
201
|
+
when Float
|
202
|
+
Float.instance_method(:__marshal__).bind(object).call(self)
|
203
|
+
when String
|
204
|
+
String.instance_method(:__marshal__).bind(object).call(self)
|
205
|
+
else
|
206
|
+
BasicObject.instance_method(:__marshal__).bind(object).call(self)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
@buffer
|
211
|
+
end
|
212
|
+
|
213
|
+
def write_fixnum(n)
|
214
|
+
%x{
|
215
|
+
var s;
|
216
|
+
|
217
|
+
if (n == 0) {
|
218
|
+
s = String.fromCharCode(n);
|
219
|
+
} else if (n > 0 && n < 123) {
|
220
|
+
s = String.fromCharCode(n + 5);
|
221
|
+
} else if (n < 0 && n > -124) {
|
222
|
+
s = String.fromCharCode(256 + n - 5);
|
223
|
+
} else {
|
224
|
+
s = "";
|
225
|
+
var cnt = 0;
|
226
|
+
for (var i = 0; i < 4; i++) {
|
227
|
+
var b = n & 255;
|
228
|
+
s += String.fromCharCode(b);
|
229
|
+
n >>= 8
|
230
|
+
cnt += 1;
|
231
|
+
if (n === 0 || n === -1) {
|
232
|
+
break;
|
233
|
+
}
|
234
|
+
}
|
235
|
+
var l_byte;
|
236
|
+
if (n < 0) {
|
237
|
+
l_byte = 256 - cnt;
|
238
|
+
} else {
|
239
|
+
l_byte = cnt;
|
240
|
+
}
|
241
|
+
s = String.fromCharCode(l_byte) + s;
|
242
|
+
}
|
243
|
+
#{append(`s`)}
|
244
|
+
}
|
245
|
+
end
|
246
|
+
|
247
|
+
def write_string(s)
|
248
|
+
write_fixnum(s.length)
|
249
|
+
append(s)
|
250
|
+
end
|
251
|
+
|
252
|
+
def append_symbol(sym)
|
253
|
+
append(':')
|
254
|
+
write_fixnum(sym.length)
|
255
|
+
append(sym)
|
256
|
+
end
|
257
|
+
|
258
|
+
def write_array(a)
|
259
|
+
write_fixnum(a.length)
|
260
|
+
a.each do |item|
|
261
|
+
write(item)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
def write_hash(h)
|
266
|
+
write_fixnum(h.length)
|
267
|
+
h.each do |key, value|
|
268
|
+
write(key)
|
269
|
+
write(value)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
def write_object(obj)
|
274
|
+
append_symbol(obj.class.name)
|
275
|
+
write_ivars_suffix(obj, true)
|
276
|
+
end
|
277
|
+
|
278
|
+
def write_class(klass)
|
279
|
+
write_string(klass.name)
|
280
|
+
end
|
281
|
+
|
282
|
+
def write_module(mod)
|
283
|
+
write_string(mod.name)
|
284
|
+
end
|
285
|
+
|
286
|
+
def write_regexp(regexp)
|
287
|
+
write_string(regexp.to_s)
|
288
|
+
append(`String.fromCharCode(#{regexp.options})`)
|
289
|
+
end
|
290
|
+
|
291
|
+
def write_float(f)
|
292
|
+
if f.equal?(Float::INFINITY)
|
293
|
+
write_string('inf')
|
294
|
+
elsif f.equal?(-Float::INFINITY)
|
295
|
+
write_string('-inf')
|
296
|
+
elsif f.equal?(Float::NAN)
|
297
|
+
write_string('nan')
|
298
|
+
else
|
299
|
+
write_string(f.to_s)
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
def write_ivars_suffix(object, force = false)
|
304
|
+
if object.instance_variables.length == 0 && !force
|
305
|
+
return
|
306
|
+
end
|
307
|
+
|
308
|
+
write_fixnum(object.instance_variables.length)
|
309
|
+
object.instance_variables.each do |ivar_name|
|
310
|
+
append_symbol(ivar_name)
|
311
|
+
write(object.instance_variable_get(ivar_name))
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
def write_extends(object)
|
316
|
+
singleton_mods = object.singleton_class.ancestors.reject { |mod| mod.is_a?(Class) }
|
317
|
+
class_mods = object.class.ancestors.reject { |mod| mod.is_a?(Class) }
|
318
|
+
own_mods = singleton_mods - class_mods
|
319
|
+
if own_mods.length > 0
|
320
|
+
own_mods.each do |mod|
|
321
|
+
append('e')
|
322
|
+
append_symbol(mod.name)
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
def write_user_class(klass, object)
|
328
|
+
unless object.class.equal?(klass)
|
329
|
+
append('C')
|
330
|
+
append_symbol(object.class.name)
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
def write_object_link(idx)
|
335
|
+
append('@')
|
336
|
+
write_fixnum(idx)
|
337
|
+
end
|
338
|
+
|
339
|
+
def save_link(object)
|
340
|
+
@cache << object.object_id
|
341
|
+
end
|
342
|
+
|
343
|
+
def write_usr_marshal(object)
|
344
|
+
value = object.marshal_dump
|
345
|
+
klass = object.class
|
346
|
+
append('U')
|
347
|
+
namespace = `#{klass}.$$base_module`
|
348
|
+
if namespace.equal?(Object)
|
349
|
+
append_symbol(`#{klass}.$$name`)
|
350
|
+
else
|
351
|
+
append_symbol(namespace.name + '::' + `#{klass}.$$name`)
|
352
|
+
end
|
353
|
+
write(value)
|
354
|
+
end
|
355
|
+
|
356
|
+
def write_userdef(object)
|
357
|
+
value = object._dump(0)
|
358
|
+
|
359
|
+
unless value.is_a?(String)
|
360
|
+
raise TypeError, "_dump() must return string"
|
361
|
+
end
|
362
|
+
|
363
|
+
write_ivars_prefix(value)
|
364
|
+
append('u')
|
365
|
+
append_symbol(object.class.name)
|
366
|
+
write_string(value)
|
367
|
+
end
|
368
|
+
|
369
|
+
def write_ivars_prefix(object)
|
370
|
+
if object.instance_variables.length > 0
|
371
|
+
append('I')
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
def append(s)
|
376
|
+
@buffer += s
|
377
|
+
end
|
378
|
+
|
379
|
+
def version
|
380
|
+
`String.fromCharCode(#{MAJOR_VERSION}, #{MINOR_VERSION})`
|
381
|
+
end
|
382
|
+
end
|
383
|
+
end
|
data/opal/corelib/method.rb
CHANGED
@@ -12,6 +12,10 @@ class Method
|
|
12
12
|
@method.arity
|
13
13
|
end
|
14
14
|
|
15
|
+
def parameters
|
16
|
+
`#{@method}.$$parameters`
|
17
|
+
end
|
18
|
+
|
15
19
|
def call(*args, &block)
|
16
20
|
%x{
|
17
21
|
#@method.$$p = block;
|
@@ -53,6 +57,10 @@ class UnboundMethod
|
|
53
57
|
@method.arity
|
54
58
|
end
|
55
59
|
|
60
|
+
def parameters
|
61
|
+
`#{@method}.$$parameters`
|
62
|
+
end
|
63
|
+
|
56
64
|
def bind(object)
|
57
65
|
# TODO: re-enable when Module#< is fixed
|
58
66
|
# unless object.class <= @owner
|
data/opal/corelib/module.rb
CHANGED
@@ -135,6 +135,9 @@ class Module
|
|
135
135
|
// initialize the instance variable as nil
|
136
136
|
proto[ivar] = nil;
|
137
137
|
|
138
|
+
body.$$parameters = [];
|
139
|
+
body.$$arity = 0;
|
140
|
+
|
138
141
|
if (self.$$is_singleton) {
|
139
142
|
proto.constructor.prototype[id] = body;
|
140
143
|
}
|
@@ -164,6 +167,9 @@ class Module
|
|
164
167
|
}
|
165
168
|
})(ivar);
|
166
169
|
|
170
|
+
body.$$parameters = [['req']];
|
171
|
+
body.$$arity = 1;
|
172
|
+
|
167
173
|
// initialize the instance variable as nil
|
168
174
|
proto[ivar] = nil;
|
169
175
|
|
@@ -608,4 +614,19 @@ class Module
|
|
608
614
|
|
609
615
|
self
|
610
616
|
end
|
617
|
+
|
618
|
+
def instance_variables
|
619
|
+
consts = constants
|
620
|
+
%x{
|
621
|
+
var result = [];
|
622
|
+
|
623
|
+
for (var name in self) {
|
624
|
+
if (self.hasOwnProperty(name) && name.charAt(0) !== '$' && name !== 'constructor' && !#{consts.include?(`name`)}) {
|
625
|
+
result.push('@' + name);
|
626
|
+
}
|
627
|
+
}
|
628
|
+
|
629
|
+
return result;
|
630
|
+
}
|
631
|
+
end
|
611
632
|
end
|
data/opal/corelib/number.rb
CHANGED
@@ -176,19 +176,33 @@ class Number < Numeric
|
|
176
176
|
}
|
177
177
|
end
|
178
178
|
|
179
|
-
|
180
|
-
|
179
|
+
# Compute the result of the spaceship operator inside its own function so it
|
180
|
+
# can be optimized despite a try/finally construct.
|
181
|
+
%x{
|
182
|
+
var spaceship_operator = function(self, other) {
|
181
183
|
if (other.$$is_number) {
|
182
184
|
if (isNaN(self) || isNaN(other)) {
|
183
185
|
return nil;
|
184
186
|
}
|
185
187
|
|
186
|
-
|
188
|
+
if (self > other) {
|
189
|
+
return 1;
|
190
|
+
} else if (self < other) {
|
191
|
+
return -1;
|
192
|
+
} else {
|
193
|
+
return 0;
|
194
|
+
}
|
187
195
|
}
|
188
196
|
else {
|
189
|
-
return #{__coerced__ :<=>, other};
|
197
|
+
return #{__coerced__ :<=>, `other`};
|
190
198
|
}
|
191
199
|
}
|
200
|
+
}
|
201
|
+
|
202
|
+
def <=>(other)
|
203
|
+
%x{
|
204
|
+
return spaceship_operator(self, other);
|
205
|
+
}
|
192
206
|
rescue ArgumentError
|
193
207
|
nil
|
194
208
|
end
|
@@ -586,7 +600,7 @@ class Number < Numeric
|
|
586
600
|
alias succ next
|
587
601
|
|
588
602
|
def times(&block)
|
589
|
-
return enum_for
|
603
|
+
return enum_for(:times) { self } unless block
|
590
604
|
|
591
605
|
%x{
|
592
606
|
for (var i = 0; i < self; i++) {
|