opal 0.10.0.beta2 → 0.10.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
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++) {