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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -1
  3. data/lib/opal/compiler.rb +15 -9
  4. data/lib/opal/fragment.rb +8 -1
  5. data/lib/opal/nodes/args/restarg.rb +6 -1
  6. data/lib/opal/nodes/base.rb +1 -1
  7. data/lib/opal/nodes/call.rb +4 -0
  8. data/lib/opal/nodes/def.rb +20 -25
  9. data/lib/opal/nodes/hash.rb +89 -17
  10. data/lib/opal/nodes/iter.rb +30 -2
  11. data/lib/opal/nodes/logic.rb +54 -4
  12. data/lib/opal/nodes/node_with_args.rb +72 -0
  13. data/lib/opal/parser.rb +16 -0
  14. data/lib/opal/parser/grammar.rb +2555 -2562
  15. data/lib/opal/parser/grammar.y +28 -20
  16. data/lib/opal/parser/lexer.rb +4 -4
  17. data/lib/opal/regexp_anchors.rb +13 -5
  18. data/lib/opal/source_map.rb +2 -1
  19. data/lib/opal/version.rb +1 -1
  20. data/opal/corelib/array.rb +4 -0
  21. data/opal/corelib/basic_object.rb +3 -1
  22. data/opal/corelib/constants.rb +1 -1
  23. data/opal/corelib/file.rb +196 -4
  24. data/opal/corelib/hash.rb +7 -7
  25. data/opal/corelib/kernel.rb +7 -4
  26. data/opal/corelib/marshal.rb +31 -0
  27. data/opal/corelib/marshal/read_buffer.rb +427 -0
  28. data/opal/corelib/marshal/write_buffer.rb +383 -0
  29. data/opal/corelib/method.rb +8 -0
  30. data/opal/corelib/module.rb +21 -0
  31. data/opal/corelib/number.rb +19 -5
  32. data/opal/corelib/proc.rb +33 -6
  33. data/opal/corelib/range.rb +6 -0
  34. data/opal/corelib/regexp.rb +5 -1
  35. data/opal/corelib/runtime.js +69 -17
  36. data/opal/corelib/string.rb +8 -0
  37. data/opal/corelib/string/inheritance.rb +4 -0
  38. data/opal/corelib/struct.rb +5 -0
  39. data/opal/corelib/unsupported.rb +0 -18
  40. data/opal/opal/full.rb +1 -0
  41. data/spec/filters/bugs/basicobject.rb +0 -2
  42. data/spec/filters/bugs/compiler_opal.rb +5 -0
  43. data/spec/filters/bugs/enumerable.rb +1 -0
  44. data/spec/filters/bugs/enumerator.rb +0 -2
  45. data/spec/filters/bugs/exception.rb +0 -1
  46. data/spec/filters/bugs/kernel.rb +0 -5
  47. data/spec/filters/bugs/language.rb +7 -27
  48. data/spec/filters/bugs/marshal.rb +43 -0
  49. data/spec/filters/bugs/method.rb +0 -56
  50. data/spec/filters/bugs/module.rb +0 -1
  51. data/spec/filters/bugs/proc.rb +0 -46
  52. data/spec/filters/bugs/regexp.rb +1 -0
  53. data/spec/filters/bugs/unboundmethod.rb +0 -13
  54. data/spec/filters/unsupported/bignum.rb +5 -0
  55. data/spec/filters/unsupported/freeze.rb +2 -0
  56. data/spec/filters/unsupported/marshal.rb +46 -0
  57. data/spec/filters/unsupported/symbol.rb +5 -0
  58. data/spec/lib/compiler/call_spec.rb +29 -29
  59. data/spec/lib/compiler_spec.rb +7 -1
  60. data/spec/opal/core/kernel/instance_variables_spec.rb +40 -0
  61. data/spec/opal/core/language/ternary_operator_spec.rb +6 -0
  62. data/spec/opal/core/marshal/dump_spec.rb +53 -0
  63. data/spec/opal/core/marshal/load_spec.rb +7 -0
  64. data/spec/opal/core/source_map_spec.rb +35 -1
  65. data/spec/opal/javascript_api_spec.rb +16 -0
  66. data/spec/opal/stdlib/source_map_spec.rb +8 -0
  67. data/spec/ruby_specs +7 -4
  68. data/spec/support/match_helpers.rb +57 -0
  69. data/spec/support/mspec_rspec_adapter.rb +1 -1
  70. data/stdlib/opal-parser.rb +3 -1
  71. data/stdlib/pathname.rb +105 -7
  72. data/stdlib/racc/parser.rb +551 -138
  73. data/stdlib/source_map/vlq.rb +3 -2
  74. data/tasks/testing.rake +4 -2
  75. 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
@@ -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
@@ -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
@@ -176,19 +176,33 @@ class Number < Numeric
176
176
  }
177
177
  end
178
178
 
179
- def <=>(other)
180
- %x{
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
- return self > other ? 1 : (self < other ? -1 : 0);
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 :times unless block
603
+ return enum_for(:times) { self } unless block
590
604
 
591
605
  %x{
592
606
  for (var i = 0; i < self; i++) {