opal 0.5.0 → 0.5.2

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -2
  3. data/README.md +1 -1
  4. data/Rakefile +11 -8
  5. data/lib/opal.rb +1 -1
  6. data/lib/opal/version.rb +1 -1
  7. data/opal.gemspec +1 -1
  8. data/{corelib → opal/core}/array.rb +47 -40
  9. data/{corelib → opal/core}/basic_object.rb +4 -0
  10. data/{corelib → opal/core}/boolean.rb +2 -6
  11. data/{corelib → opal/core}/class.rb +0 -0
  12. data/{corelib → opal/core}/comparable.rb +0 -0
  13. data/{corelib → opal/core}/encoding.rb +0 -0
  14. data/{corelib → opal/core}/enumerable.rb +160 -38
  15. data/opal/core/enumerator.rb +416 -0
  16. data/{corelib → opal/core}/error.rb +0 -0
  17. data/{corelib → opal/core}/hash.rb +38 -48
  18. data/{corelib → opal/core}/io.rb +13 -9
  19. data/{corelib → opal/core}/kernel.rb +75 -49
  20. data/{corelib → opal/core}/main.rb +0 -0
  21. data/{corelib → opal/core}/match_data.rb +0 -4
  22. data/{corelib → opal/core}/method.rb +0 -0
  23. data/{corelib → opal/core}/module.rb +24 -3
  24. data/{corelib → opal/core}/nil_class.rb +0 -4
  25. data/{corelib → opal/core}/numeric.rb +3 -4
  26. data/{corelib → opal/core}/proc.rb +0 -4
  27. data/{corelib → opal/core}/range.rb +0 -0
  28. data/{corelib → opal/core}/regexp.rb +0 -4
  29. data/{corelib → opal/core}/runtime.js +0 -0
  30. data/{corelib → opal/core}/string.rb +4 -6
  31. data/{corelib → opal/core}/struct.rb +3 -21
  32. data/{corelib → opal/core}/time.rb +0 -4
  33. data/opal/opal.rb +121 -0
  34. data/spec/corelib/array/select_spec.rb +14 -0
  35. data/spec/filters/20.rb +4 -0
  36. data/spec/filters/bugs/enumerable.rb +1 -48
  37. data/spec/filters/unsupported/enumerator.rb +13 -0
  38. data/spec/opal/compiler/irb_spec.rb +1 -0
  39. data/spec/rubyspecs +1 -0
  40. data/spec/{corelib → stdlib}/native/alias_native_spec.rb +6 -4
  41. data/spec/{corelib → stdlib}/native/each_spec.rb +3 -1
  42. data/spec/{corelib → stdlib}/native/element_reference_spec.rb +3 -1
  43. data/spec/stdlib/native/ext_spec.rb +19 -0
  44. data/spec/{corelib → stdlib}/native/initialize_spec.rb +4 -4
  45. data/spec/{corelib → stdlib}/native/method_missing_spec.rb +13 -1
  46. data/spec/{corelib → stdlib}/native/new_spec.rb +3 -1
  47. data/stdlib/enumerator.rb +1 -0
  48. data/stdlib/json.rb +1 -1
  49. data/stdlib/native.rb +483 -0
  50. metadata +52 -47
  51. data/corelib/enumerator.rb +0 -55
  52. data/corelib/native.rb +0 -270
  53. data/corelib/opal.rb +0 -88
  54. data/spec/corelib/native/ext_spec.rb +0 -5
  55. data/spec/filters/bugs/enumerator.rb +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fdf74450cbd2b81a0d8ba44700ef6e0e77b5ca45
4
- data.tar.gz: 01e6a0e881a43bdaa1eb4db93c0e1989ca1d4568
3
+ metadata.gz: 8fd073f86d2b6572a34ed96ac1e8bc35e14be214
4
+ data.tar.gz: 5f55dcc5f1e555bc2d53afababdfedd8a1fc480e
5
5
  SHA512:
6
- metadata.gz: 90d5d6913908ef1d38f69d029d6033fbcd0d2214035a3cf34ebe5c5d8725e2bd37689009dbbd28e99ca27f9069cfe09b44445a0a3710e3d0e71f0d1ce00dd72b
7
- data.tar.gz: bca3fd06513433d71ff656a473acf3269caa301a55589fdccea45cc463d9f865b6d558bbc1f427552f46586172f6f053cf6396cb5bbe193aa2e5b113783d0a86
6
+ metadata.gz: 8db2e2f1545e635e7822d52fe6a009ac2d50d335bd7a2855e0ac44f5eff366171106eec3d783ef3600924d60d28c042d634056119b594f54fa44d1f600952776
7
+ data.tar.gz: ba90ff768744ca87c6d5a54070292d6d6877dfbf4c3c21bdaa3fe73d13258acfaeea85bf8900251b42d325ce78a7b80b1479606cd1ec504516dd7bb4595f86f3
data/Gemfile CHANGED
@@ -1,8 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec
3
3
 
4
- gem 'opal-sprockets', :github => 'opal/opal-sprockets'
5
-
6
4
  # Stick with older racc until
7
5
  # https://github.com/tenderlove/racc/issues/32
8
6
  # is solved.
data/README.md CHANGED
@@ -71,7 +71,7 @@ visit `http://localhost:9292/` in any web browser.
71
71
  What code is supposed to run where?
72
72
 
73
73
  * `lib/` code runs inside your ruby env. It compiles ruby to javascript.
74
- * `corelib/` is the runtime/corelib for our implementation (runs in browser)
74
+ * `opal/` is the runtime/corelib for our implementation (runs in browser)
75
75
  * `stdlib/` is our implementation of ruby stdlib. It is optional (for browser).
76
76
 
77
77
  ### lib
data/Rakefile CHANGED
@@ -54,9 +54,12 @@ task :dist do
54
54
  env = Opal::Environment.new
55
55
 
56
56
  Dir.mkdir 'build' unless File.directory? 'build'
57
+ libs = Dir['{opal,stdlib}/*.rb'].map { |lib| File.basename(lib, '.rb') }
58
+ width = libs.map(&:size).max
57
59
 
58
- %w[opal opal-parser].each do |lib|
59
- puts "* building #{lib}..."
60
+ libs.each do |lib|
61
+ print "* building #{lib}...".ljust(width+'* building ... '.size)
62
+ $stdout.flush
60
63
 
61
64
  src = env[lib].to_s
62
65
  min = uglify src
@@ -66,11 +69,11 @@ task :dist do
66
69
  File.open("build/#{lib}.min.js", 'w+') { |f| f << min } if min
67
70
  File.open("build/#{lib}.min.js.gz", 'w+') { |f| f << gzp } if gzp
68
71
 
69
- print "done. (development: #{src.size}B"
70
- print ", minified: #{min.size}B" if min
71
- print ", gzipped: #{gzp.size}Bx" if gzp
72
+ print "done. ("
73
+ print "development: #{('%.2f' % (src.size/1000.0)).rjust(6)}KB"
74
+ print ", minified: #{('%.2f' % (min.size/1000.0)).rjust(6)}KB" if min
75
+ print ", gzipped: #{('%.2f' % (gzp.size/1000.0)).rjust(6)}KB" if gzp
72
76
  puts ")."
73
- puts
74
77
  end
75
78
  end
76
79
 
@@ -81,7 +84,7 @@ end
81
84
 
82
85
  # Used for uglifying source to minify
83
86
  def uglify(str)
84
- IO.popen('uglifyjs', 'r+') do |i|
87
+ IO.popen('uglifyjs 2> /dev/null', 'r+') do |i|
85
88
  i.puts str
86
89
  i.close_write
87
90
  return i.read
@@ -93,7 +96,7 @@ end
93
96
 
94
97
  # Gzip code to check file size
95
98
  def gzip(str)
96
- IO.popen('gzip -f', 'r+') do |i|
99
+ IO.popen('gzip -f 2> /dev/null', 'r+') do |i|
97
100
  i.puts str
98
101
  i.close_write
99
102
  return i.read
data/lib/opal.rb CHANGED
@@ -16,7 +16,7 @@ module Opal
16
16
  end
17
17
 
18
18
  def self.core_dir
19
- File.expand_path('../../corelib', __FILE__.untaint)
19
+ File.expand_path('../../opal', __FILE__.untaint)
20
20
  end
21
21
 
22
22
  def self.std_dir
data/lib/opal/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Opal
2
- VERSION = '0.5.0'
2
+ VERSION = '0.5.2'
3
3
  end
data/opal.gemspec CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
22
22
  s.add_development_dependency 'mspec', '1.5.20'
23
23
  s.add_development_dependency 'rake'
24
24
  s.add_development_dependency 'racc'
25
- s.add_development_dependency 'opal-sprockets', '~> 0.2.1'
25
+ s.add_development_dependency 'opal-sprockets', '~> 0.3.0'
26
26
  s.add_development_dependency 'rspec', '~> 2.14'
27
27
  s.add_development_dependency 'octokit', '~> 2.4.0'
28
28
  end
@@ -353,27 +353,42 @@ class Array
353
353
  end
354
354
 
355
355
  def cycle(n = nil, &block)
356
- return if `self.length === 0 || n === 0`
356
+ return if empty? || n == 0
357
+
357
358
  return enum_for :cycle, n unless block
358
359
 
359
- if `n === nil`
360
- while true
361
- if `#{(value = each(&block))} !== self`
362
- return value
363
- end
364
- end
360
+ if n.nil?
361
+ %x{
362
+ while (true) {
363
+ for (var i = 0, length = self.length; i < length; i++) {
364
+ var value = $opal.$yield1(block, self[i]);
365
+
366
+ if (value === $breaker) {
367
+ return $breaker.$v;
368
+ }
369
+ }
370
+ }
371
+ }
365
372
  else
366
- cycles = Opal.coerce_to n, Integer, :to_int
373
+ n = Opal.coerce_to! n, Integer, :to_int
367
374
 
368
- unless Integer === cycles
369
- raise TypeError, "can't convert #{n.class} into Integer (#{n.class}#to_int gives #{cycles.class}"
370
- end
375
+ %x{
376
+ if (n <= 0) {
377
+ return self;
378
+ }
371
379
 
372
- while cycles > 0
373
- each(&block)
380
+ while (n > 0) {
381
+ for (var i = 0, length = self.length; i < length; i++) {
382
+ var value = $opal.$yield1(block, self[i]);
374
383
 
375
- cycles -= 1
376
- end
384
+ if (value === $breaker) {
385
+ return $breaker.$v;
386
+ }
387
+ }
388
+
389
+ n--;
390
+ }
391
+ }
377
392
  end
378
393
 
379
394
  self
@@ -459,6 +474,12 @@ class Array
459
474
  end
460
475
 
461
476
  def concat(other)
477
+ if Array === other
478
+ other = other.to_a
479
+ else
480
+ other = Opal.coerce_to other, Array, :to_ary
481
+ end
482
+
462
483
  %x{
463
484
  for (var i = 0, length = other.length; i < length; i++) {
464
485
  self.push(other[i]);
@@ -592,7 +613,12 @@ class Array
592
613
  return defaults;
593
614
  }
594
615
 
595
- #{ raise IndexError, "Array#fetch" };
616
+ if (self.length === 0) {
617
+ #{raise IndexError, "index #{`original`} outside of array bounds: 0...0"}
618
+ }
619
+ else {
620
+ #{raise IndexError, "index #{`original`} outside of array bounds: -#{`self.length`}...#{`self.length`}"};
621
+ }
596
622
  }
597
623
  end
598
624
 
@@ -707,17 +733,17 @@ class Array
707
733
  for (var i = 0, length = self.length; i < length; i++) {
708
734
  var item = self[i];
709
735
 
710
- if (#{`item`.respond_to?(:to_ary)}) {
736
+ if (#{`item`.respond_to? :to_ary}) {
711
737
  item = #{`item`.to_ary};
712
738
 
713
739
  if (level == null) {
714
- result = result.concat(#{`item`.flatten});
740
+ result.push.apply(result, #{`item`.flatten.to_a});
715
741
  }
716
- else if (level === 0) {
742
+ else if (level == 0) {
717
743
  result.push(item);
718
744
  }
719
745
  else {
720
- result = result.concat(#{`item`.flatten(`level - 1`)});
746
+ result.push.apply(result, #{`item`.flatten(`level - 1`).to_a});
721
747
  }
722
748
  }
723
749
  else {
@@ -1056,7 +1082,7 @@ class Array
1056
1082
  for (var i = 0, length = self.length, item, value; i < length; i++) {
1057
1083
  item = self[i];
1058
1084
 
1059
- if ((value = block(item)) === $breaker) {
1085
+ if ((value = $opal.$yield1(block, item)) === $breaker) {
1060
1086
  return $breaker.$v;
1061
1087
  }
1062
1088
 
@@ -1222,25 +1248,6 @@ class Array
1222
1248
 
1223
1249
  alias to_ary to_a
1224
1250
 
1225
- def to_n
1226
- %x{
1227
- var result = [], obj
1228
-
1229
- for (var i = 0, len = self.length; i < len; i++) {
1230
- obj = self[i];
1231
-
1232
- if (#{`obj`.respond_to? :to_n}) {
1233
- result.push(#{`obj`.to_n});
1234
- }
1235
- else {
1236
- result.push(obj);
1237
- }
1238
- }
1239
-
1240
- return result;
1241
- }
1242
- end
1243
-
1244
1251
  alias to_s inspect
1245
1252
 
1246
1253
  def transpose
@@ -6,6 +6,10 @@ class BasicObject
6
6
  `self === other`
7
7
  end
8
8
 
9
+ def __id__
10
+ `self._id || (self._id = Opal.uid())`
11
+ end
12
+
9
13
  def __send__(symbol, *args, &block)
10
14
  %x{
11
15
  var func = self['$' + symbol]
@@ -28,14 +28,10 @@ class Boolean
28
28
  def to_s
29
29
  `(self == true) ? 'true' : 'false'`
30
30
  end
31
-
32
- def to_n
33
- `self.valueOf()`
34
- end
35
31
  end
36
32
 
37
- TrueClass = Boolean
33
+ TrueClass = Boolean
38
34
  FalseClass = Boolean
39
35
 
40
- TRUE = true
36
+ TRUE = true
41
37
  FALSE = false
File without changes
File without changes
File without changes
@@ -122,6 +122,71 @@ module Enumerable
122
122
  }
123
123
  end
124
124
 
125
+ def cycle(n = nil, &block)
126
+ return enum_for :cycle, n unless block
127
+
128
+ unless n.nil?
129
+ n = Opal.coerce_to! n, Integer, :to_int
130
+
131
+ return if `n <= 0`
132
+ end
133
+
134
+ %x{
135
+ var result,
136
+ all = [];
137
+
138
+ self.$each._p = function() {
139
+ var param = #{Opal.destructure(`arguments`)},
140
+ value = $opal.$yield1(block, param);
141
+
142
+ if (value === $breaker) {
143
+ result = $breaker.$v;
144
+ return $breaker;
145
+ }
146
+
147
+ all.push(param);
148
+ }
149
+
150
+ self.$each();
151
+
152
+ if (result !== undefined) {
153
+ return result;
154
+ }
155
+
156
+ if (all.length === 0) {
157
+ return nil;
158
+ }
159
+ }
160
+
161
+ if n.nil?
162
+ %x{
163
+ while (true) {
164
+ for (var i = 0, length = all.length; i < length; i++) {
165
+ var value = $opal.$yield1(block, all[i]);
166
+
167
+ if (value === $breaker) {
168
+ return $breaker.$v;
169
+ }
170
+ }
171
+ }
172
+ }
173
+ else
174
+ %x{
175
+ while (n > 1) {
176
+ for (var i = 0, length = all.length; i < length; i++) {
177
+ var value = $opal.$yield1(block, all[i]);
178
+
179
+ if (value === $breaker) {
180
+ return $breaker.$v;
181
+ }
182
+ }
183
+
184
+ n--;
185
+ }
186
+ }
187
+ end
188
+ end
189
+
125
190
  def detect(ifnone = undefined, &block)
126
191
  return enum_for :detect, ifnone unless block_given?
127
192
 
@@ -170,7 +235,7 @@ module Enumerable
170
235
  current = 0;
171
236
 
172
237
  self.$each._p = function() {
173
- if (number < current) {
238
+ if (number <= current) {
174
239
  result.push(#{Opal.destructure(`arguments`)});
175
240
  }
176
241
 
@@ -187,22 +252,28 @@ module Enumerable
187
252
  return enum_for :drop_while unless block_given?
188
253
 
189
254
  %x{
190
- var result = [];
255
+ var result = [],
256
+ dropping = true;
191
257
 
192
258
  self.$each._p = function() {
193
- var param = #{Opal.destructure(`arguments`)},
194
- value = $opal.$yield1(block, param);
259
+ var param = #{Opal.destructure(`arguments`)};
195
260
 
196
- if (value === $breaker) {
197
- result = $breaker.$v;
198
- return $breaker;
199
- }
261
+ if (dropping) {
262
+ var value = $opal.$yield1(block, param);
200
263
 
201
- if (#{Opal.truthy?(`value`)}) {
202
- return;
203
- }
264
+ if (value === $breaker) {
265
+ result = $breaker.$v;
266
+ return $breaker;
267
+ }
204
268
 
205
- result.push(param);
269
+ if (#{Opal.falsy?(`value`)}) {
270
+ dropping = false;
271
+ result.push(param);
272
+ }
273
+ }
274
+ else {
275
+ result.push(param);
276
+ }
206
277
  };
207
278
 
208
279
  self.$each();
@@ -214,6 +285,10 @@ module Enumerable
214
285
  def each_slice(n, &block)
215
286
  n = Opal.coerce_to n, Integer, :to_int
216
287
 
288
+ if `n <= 0`
289
+ raise ArgumentError, 'invalid slice size'
290
+ end
291
+
217
292
  return enum_for :each_slice, n unless block_given?
218
293
 
219
294
  %x{
@@ -252,8 +327,8 @@ module Enumerable
252
327
  nil
253
328
  end
254
329
 
255
- def each_with_index(&block)
256
- return enum_for :each_with_index unless block_given?
330
+ def each_with_index(*args, &block)
331
+ return enum_for :each_with_index, *args unless block_given?
257
332
 
258
333
  %x{
259
334
  var result,
@@ -271,14 +346,14 @@ module Enumerable
271
346
  index++;
272
347
  };
273
348
 
274
- self.$each();
349
+ self.$each.apply(self, args);
275
350
 
276
351
  if (result !== undefined) {
277
352
  return result;
278
353
  }
279
354
  }
280
355
 
281
- nil
356
+ self
282
357
  end
283
358
 
284
359
  def each_with_object(object, &block)
@@ -307,7 +382,7 @@ module Enumerable
307
382
  object
308
383
  end
309
384
 
310
- def entries
385
+ def entries(*args)
311
386
  %x{
312
387
  var result = [];
313
388
 
@@ -315,7 +390,7 @@ module Enumerable
315
390
  result.push(#{Opal.destructure(`arguments`)});
316
391
  };
317
392
 
318
- self.$each();
393
+ self.$each.apply(self, args);
319
394
 
320
395
  return result;
321
396
  }
@@ -393,35 +468,47 @@ module Enumerable
393
468
  end
394
469
 
395
470
  def first(number = undefined)
396
- %x{
397
- if (number == null) {
398
- var result = nil;
471
+ if `number === undefined`
472
+ result = nil
399
473
 
474
+ %x{
400
475
  self.$each._p = function() {
401
476
  result = #{Opal.destructure(`arguments`)};
477
+
402
478
  return $breaker;
403
479
  };
480
+
481
+ self.$each();
404
482
  }
405
- else {
483
+ else
484
+ result = []
485
+ number = Opal.coerce_to number, Integer, :to_int
486
+
487
+ if `number < 0`
488
+ raise ArgumentError, 'attempt to take negative size'
489
+ end
490
+
491
+ if `number == 0`
492
+ return []
493
+ end
494
+
495
+ %x{
406
496
  var current = 0,
407
- result = [],
408
497
  number = #{Opal.coerce_to number, Integer, :to_int};
409
498
 
410
499
  self.$each._p = function() {
411
- if (number <= current) {
412
- return $breaker;
413
- }
414
-
415
500
  result.push(#{Opal.destructure(`arguments`)});
416
501
 
417
- current++;
502
+ if (number <= ++current) {
503
+ return $breaker;
504
+ }
418
505
  };
419
- }
420
506
 
421
- self.$each();
507
+ self.$each();
508
+ }
509
+ end
422
510
 
423
- return result;
424
- }
511
+ result
425
512
  end
426
513
 
427
514
  def grep(pattern, &block)
@@ -465,7 +552,7 @@ module Enumerable
465
552
  def group_by(&block)
466
553
  return enum_for :group_by unless block_given?
467
554
 
468
- hash = Hash.new { |h, k| h[k] = [] }
555
+ hash = Hash.new
469
556
 
470
557
  %x{
471
558
  var result;
@@ -479,7 +566,7 @@ module Enumerable
479
566
  return $breaker;
480
567
  }
481
568
 
482
- #{hash[`value`] << `param`};
569
+ #{(hash[`value`] ||= []) << `param`};
483
570
  }
484
571
 
485
572
  self.$each();
@@ -493,14 +580,29 @@ module Enumerable
493
580
  end
494
581
 
495
582
  def include?(obj)
496
- any? { |v| v == obj }
583
+ %x{
584
+ var result = false;
585
+
586
+ self.$each._p = function() {
587
+ var param = #{Opal.destructure(`arguments`)};
588
+
589
+ if (#{`param` == obj}) {
590
+ result = true;
591
+ return $breaker;
592
+ }
593
+ }
594
+
595
+ self.$each();
596
+
597
+ return result;
598
+ }
497
599
  end
498
600
 
499
601
  def inject(object = undefined, sym = undefined, &block)
500
602
  %x{
501
603
  var result = object;
502
604
 
503
- if (block !== nil) {
605
+ if (block !== nil && sym === undefined) {
504
606
  self.$each._p = function() {
505
607
  var value = #{Opal.destructure(`arguments`)};
506
608
 
@@ -547,6 +649,18 @@ module Enumerable
547
649
  }
548
650
  end
549
651
 
652
+ def lazy
653
+ Enumerator::Lazy.new(self, enumerator_size) {|enum, *args|
654
+ enum.yield(*args)
655
+ }
656
+ end
657
+
658
+ def enumerator_size
659
+ respond_to?(:size) ? size : nil
660
+ end
661
+
662
+ private :enumerator_size
663
+
550
664
  alias map collect
551
665
 
552
666
  def max(&block)
@@ -569,6 +683,10 @@ module Enumerable
569
683
  return $breaker;
570
684
  }
571
685
 
686
+ if (value === nil) {
687
+ #{raise ArgumentError, "comparison failed"};
688
+ }
689
+
572
690
  if (value > 0) {
573
691
  result = param;
574
692
  }
@@ -583,7 +701,7 @@ module Enumerable
583
701
  return;
584
702
  }
585
703
 
586
- if (#{`param` <=> `result`} > 0) {
704
+ if (#{Opal.compare(`param`, `result`)} > 0) {
587
705
  result = param;
588
706
  }
589
707
  };
@@ -651,6 +769,10 @@ module Enumerable
651
769
  return $breaker;
652
770
  }
653
771
 
772
+ if (value === nil) {
773
+ #{raise ArgumentError, "comparison failed"};
774
+ }
775
+
654
776
  if (value < 0) {
655
777
  result = param;
656
778
  }
@@ -665,7 +787,7 @@ module Enumerable
665
787
  return;
666
788
  }
667
789
 
668
- if (#{`param` <=> `result`} < 0) {
790
+ if (#{Opal.compare(`param`, `result`)} < 0) {
669
791
  result = param;
670
792
  }
671
793
  };