opal 0.9.0.rc1 → 0.9.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 62af1a23be47ed15ba180aab47ae2b960feb1a1d
4
- data.tar.gz: 228f0b9d53bb0029c97560efb41b58417e3a1312
3
+ metadata.gz: 6fe130e39483fb75ec092a749d65571a4bc6ed72
4
+ data.tar.gz: dd168e47177f8de9d738ada116a3fef82caea16d
5
5
  SHA512:
6
- metadata.gz: f2d35d332054d7da0a7c10c617d2c71b3d0f17b9f179d352d027dca887a38725fbca63b09cd963660bd82a358fc79d9fe841b353209981db8400a63e5df843cb
7
- data.tar.gz: ddb2ce713af79c8414966769b9cce482ee3d3e2cb9b16177ac9f14f4df7600e4a7a5265e8cf0ea4a713be37557d9038f576a0fdc5fec6698931e3b27b84c9289
6
+ metadata.gz: 8a69c71365c06a89859f96ea7447e94d1ace48757680fa6022526c14c58e3700f072d3c123650476630ffc2d6f2725dc56e19869f0067bd0b791d57ca88e9682
7
+ data.tar.gz: f7d8b51da3dfcb0cd4c1870a5380b311ed0b0a9e1cbbc0666c7295b4951b2895a3d184877fd2119e176ce5141dc2f7966950cd2676cd0357aeb08114c86ddcd9
data/CHANGELOG.md CHANGED
@@ -38,6 +38,8 @@
38
38
  * `Enumerable#chunk`
39
39
  * `Enumerable#each_cons`
40
40
  * `Enumerable#minmax`
41
+ * `Range#to_a`
42
+ * `Module` comparison methods: `#<` `#<=` `#<=>` `#>` `#>=`
41
43
 
42
44
  * Operator methods (e.g. `+`, `<`, etc.) can be handled by `method_missing`
43
45
 
@@ -77,6 +79,10 @@
77
79
 
78
80
  * Fixed a number of syntax errors (e.g. #1224 #1225 #1227 #1231 #1233 #1226)
79
81
 
82
+ * Fix `Array#to_n`, `Hash#to_n`, `Struct#to_n` when the object contains native objects (#1249).
83
+
84
+ * Internal cleanup and lots of bugs!
85
+
80
86
  ## 0.8.1 2015-10-12
81
87
 
82
88
  * Use official Sprockets processor cache keys API:
@@ -900,7 +900,7 @@ module Opal
900
900
  (@lex_state == :expr_arg && @space_seen) or
901
901
  @lex_state == :expr_mid
902
902
  start_word = scan(/./)
903
- end_word = { '(' => ')', '[' => ']', '{' => '}' }[start_word] || start_word
903
+ end_word = { '(' => ')', '[' => ']', '{' => '}', '<' => '>' }[start_word] || start_word
904
904
  self.strterm = new_strterm2(STR_DQUOTE, end_word, start_word)
905
905
  return :tSTRING_BEG
906
906
  end
data/lib/opal/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Opal
2
2
  # WHEN RELEASING:
3
3
  # Remember to update RUBY_ENGINE_VERSION in opal/corelib/constants.rb too!
4
- VERSION = '0.9.0.rc1'
4
+ VERSION = '0.9.0'
5
5
  end
@@ -1328,20 +1328,20 @@ class Array < `Array`
1328
1328
  alias map collect
1329
1329
 
1330
1330
  alias map! collect!
1331
-
1331
+
1332
1332
  def permutation(num = undefined, &block)
1333
1333
  return enum_for(:permutation, num){self.size} unless block_given?
1334
1334
 
1335
1335
  %x{
1336
1336
  var permute, offensive, output;
1337
-
1337
+
1338
1338
  if (num === undefined) {
1339
1339
  num = self.length;
1340
1340
  }
1341
1341
  else {
1342
1342
  num = #{ Opal.coerce_to num, Integer, :to_int }
1343
1343
  }
1344
-
1344
+
1345
1345
  if (num < 0 || self.length < num) {
1346
1346
  // no permutations, yield nothing
1347
1347
  }
@@ -1359,17 +1359,17 @@ class Array < `Array`
1359
1359
  // this is the general case
1360
1360
  #{ perm = Array.new(num) }
1361
1361
  #{ used = Array.new(`self.length`, false) }
1362
-
1362
+
1363
1363
  permute = function(num, perm, index, used, blk) {
1364
1364
  self = this;
1365
1365
  for(var i = 0; i < self.length; i++){
1366
- if(#{ !used[`i`] }) {
1366
+ if(#{ !used[`i`] }) {
1367
1367
  perm[index] = i;
1368
1368
  if(index < num - 1) {
1369
1369
  used[i] = true;
1370
1370
  permute.call(self, num, perm, index + 1, used, blk);
1371
1371
  used[i] = false;
1372
- }
1372
+ }
1373
1373
  else {
1374
1374
  output = [];
1375
1375
  for (var j = 0; j < perm.length; j++) {
@@ -1380,7 +1380,7 @@ class Array < `Array`
1380
1380
  }
1381
1381
  }
1382
1382
  }
1383
-
1383
+
1384
1384
  if (#{block_given?}) {
1385
1385
  // offensive (both definitions) copy.
1386
1386
  offensive = self.slice();
@@ -1394,7 +1394,7 @@ class Array < `Array`
1394
1394
 
1395
1395
  self
1396
1396
  end
1397
-
1397
+
1398
1398
  def pop(count = undefined)
1399
1399
  if `count === undefined`
1400
1400
  return if `self.length === 0`
@@ -1586,28 +1586,28 @@ class Array < `Array`
1586
1586
  return nil;
1587
1587
  }
1588
1588
  end
1589
-
1589
+
1590
1590
  def rotate(n=1)
1591
1591
  n = Opal.coerce_to n, Integer, :to_int
1592
1592
  %x{
1593
1593
  var ary, idx, firstPart, lastPart;
1594
-
1594
+
1595
1595
  if (self.length === 1) {
1596
1596
  return self.slice();
1597
1597
  }
1598
1598
  if (self.length === 0) {
1599
1599
  return [];
1600
1600
  }
1601
-
1601
+
1602
1602
  ary = self.slice();
1603
1603
  idx = n % ary.length;
1604
-
1604
+
1605
1605
  firstPart = ary.slice(idx);
1606
1606
  lastPart = ary.slice(0, idx);
1607
1607
  return firstPart.concat(lastPart);
1608
- }
1608
+ }
1609
1609
  end
1610
-
1610
+
1611
1611
  def rotate!(cnt=1)
1612
1612
  %x{
1613
1613
  if (self.length === 0 || self.length === 1) {
@@ -1618,7 +1618,7 @@ class Array < `Array`
1618
1618
  ary = rotate(cnt)
1619
1619
  replace ary
1620
1620
  end
1621
-
1621
+
1622
1622
  class SampleRandom
1623
1623
  def initialize(rng)
1624
1624
  @rng = rng
@@ -1635,7 +1635,7 @@ class Array < `Array`
1635
1635
 
1636
1636
  def sample(count = undefined, options = undefined)
1637
1637
  return at Kernel.rand(`self.length`) if `count === undefined`
1638
-
1638
+
1639
1639
  if `options === undefined`
1640
1640
  if (o = Opal.coerce_to? count, Hash, :to_hash)
1641
1641
  options = o
@@ -1663,13 +1663,13 @@ class Array < `Array`
1663
1663
  return `self[#{rng.rand(`self.length`)}]` unless count
1664
1664
 
1665
1665
  %x{
1666
-
1666
+
1667
1667
  var abandon, spin, result, i, j, k, targetIndex, oldValue;
1668
-
1669
- if (count > self.length) {
1668
+
1669
+ if (count > self.length) {
1670
1670
  count = self.length;
1671
1671
  }
1672
-
1672
+
1673
1673
  switch (count) {
1674
1674
  case 0:
1675
1675
  return [];
@@ -1689,15 +1689,15 @@ class Array < `Array`
1689
1689
  if (self.length / count > 3) {
1690
1690
  abandon = false;
1691
1691
  spin = 0;
1692
-
1692
+
1693
1693
  result = #{ Array.new(count) };
1694
1694
  i = 1;
1695
-
1695
+
1696
1696
  result[0] = #{rng.rand(`self.length`)};
1697
1697
  while (i < count) {
1698
1698
  k = #{rng.rand(`self.length`)};
1699
1699
  j = 0;
1700
-
1700
+
1701
1701
  while (j < i) {
1702
1702
  while (k === result[j]) {
1703
1703
  spin++;
@@ -1708,42 +1708,42 @@ class Array < `Array`
1708
1708
  k = #{rng.rand(`self.length`)};
1709
1709
  }
1710
1710
  if (abandon) { break; }
1711
-
1711
+
1712
1712
  j++;
1713
1713
  }
1714
-
1714
+
1715
1715
  if (abandon) { break; }
1716
-
1716
+
1717
1717
  result[i] = k;
1718
-
1718
+
1719
1719
  i++;
1720
1720
  }
1721
-
1721
+
1722
1722
  if (!abandon) {
1723
1723
  i = 0;
1724
1724
  while (i < count) {
1725
1725
  result[i] = self[result[i]];
1726
1726
  i++;
1727
1727
  }
1728
-
1728
+
1729
1729
  return result;
1730
1730
  }
1731
1731
  }
1732
-
1732
+
1733
1733
  result = self.slice();
1734
-
1734
+
1735
1735
  for (var c = 0; c < count; c++) {
1736
1736
  targetIndex = #{rng.rand(`self.length`)};
1737
1737
  oldValue = result[c];
1738
1738
  result[c] = result[targetIndex];
1739
1739
  result[targetIndex] = oldValue;
1740
1740
  }
1741
-
1741
+
1742
1742
  return count === self.length ? result : #{`result`[0, count]};
1743
1743
  }
1744
1744
  }
1745
1745
  end
1746
-
1746
+
1747
1747
  def select(&block)
1748
1748
  return enum_for(:select){self.size} unless block_given?
1749
1749
 
@@ -2069,7 +2069,7 @@ class Array < `Array`
2069
2069
  if elem.kind_of? Range
2070
2070
  finish = Opal.coerce_to elem.last, Integer, :to_int
2071
2071
  start = Opal.coerce_to elem.first, Integer, :to_int
2072
-
2072
+
2073
2073
  %x{
2074
2074
  if (start < 0) {
2075
2075
  start = start + self.length;
@@ -1,8 +1,8 @@
1
1
  RUBY_PLATFORM = 'opal'
2
2
  RUBY_ENGINE = 'opal'
3
3
  RUBY_VERSION = '2.2.3'
4
- RUBY_ENGINE_VERSION = '0.9.0.rc1'
5
- RUBY_RELEASE_DATE = '2015-11-06'
4
+ RUBY_ENGINE_VERSION = '0.9.0'
5
+ RUBY_RELEASE_DATE = '2015-12-20'
6
6
  RUBY_PATCHLEVEL = 0
7
7
  RUBY_REVISION = 0
8
8
  RUBY_COPYRIGHT = 'opal - Copyright (C) 2013-2015 Adam Beynon'
@@ -29,28 +29,66 @@ class Module
29
29
  end
30
30
 
31
31
  def <(other)
32
+ unless Module === other
33
+ raise TypeError, "compared with non class/module"
34
+ end
35
+
32
36
  # class cannot be a descendant of itself
33
37
  %x{
34
- var working = self;
38
+ var working = self,
39
+ ancestors,
40
+ i, length;
35
41
 
36
42
  if (working === other) {
37
43
  return false;
38
44
  }
39
45
 
40
- while (working) {
41
- if (working === other) {
46
+ for (i = 0, ancestors = Opal.ancestors(self), length = ancestors.length; i < length; i++) {
47
+ if (ancestors[i] === other) {
42
48
  return true;
43
49
  }
50
+ }
44
51
 
45
- working = working.$$parent;
52
+ for (i = 0, ancestors = Opal.ancestors(other), length = ancestors.length; i < length; i++) {
53
+ if (ancestors[i] === self) {
54
+ return false;
55
+ }
46
56
  }
47
57
 
48
- return false;
58
+ return nil;
49
59
  }
50
60
  end
51
61
 
52
62
  def <=(other)
53
- equal?(other) or self < other
63
+ equal?(other) || self < other
64
+ end
65
+
66
+ def >(other)
67
+ unless Module === other
68
+ raise TypeError, "compared with non class/module"
69
+ end
70
+
71
+ other < self
72
+ end
73
+
74
+ def >=(other)
75
+ equal?(other) || self > other
76
+ end
77
+
78
+ def <=>(other)
79
+ %x{
80
+ if (self === other) {
81
+ return 0;
82
+ }
83
+ }
84
+
85
+ unless Module === other
86
+ return nil
87
+ end
88
+
89
+ lt = self < other
90
+ return nil if lt.nil?
91
+ lt ? -1 : 1
54
92
  end
55
93
 
56
94
  def alias_method(newname, oldname)
@@ -38,6 +38,36 @@ class Range
38
38
  def each(&block)
39
39
  return enum_for :each unless block_given?
40
40
 
41
+ %x{
42
+ var i, limit, value;
43
+
44
+ if (#@begin.$$is_number && #@end.$$is_number) {
45
+ if (#@begin % 1 !== 0 || #@end % 1 !== 0) {
46
+ #{raise TypeError, "can't iterate from Float"}
47
+ }
48
+
49
+ for (i = #@begin, limit = #@end + #{@exclude ? 0 : 1}; i < limit; i++) {
50
+ value = block(i);
51
+ if (value === $breaker) { return $breaker.$v; }
52
+ }
53
+
54
+ return self;
55
+ }
56
+
57
+ if (#@begin.$$is_string && #@end.$$is_string) {
58
+ value = #{@begin.upto(@end, @exclude, &block)};
59
+
60
+ // The following is a bit hackish: we know that
61
+ // String#upto normally returns self, but may
62
+ // return a different value if there's a `break`
63
+ // statement in the supplied block. We need to
64
+ // propagate this `break` value here, so we
65
+ // test for equality with `@begin` string to
66
+ // determine the return value:
67
+ return value === #@begin ? self : value;
68
+ }
69
+ }
70
+
41
71
  current = @begin
42
72
  last = @end
43
73
 
@@ -3,16 +3,16 @@ class RegexpError < StandardError; end
3
3
  class Regexp < `RegExp`
4
4
  IGNORECASE = 1
5
5
  MULTILINE = 4
6
-
7
- `def.$$is_regexp = true`
6
+
7
+ `def.$$is_regexp = true`
8
8
 
9
9
  class << self
10
10
  def allocate
11
11
  allocated = super
12
12
  `#{allocated}.uninitialized = true`
13
- allocated
13
+ allocated
14
14
  end
15
-
15
+
16
16
  def escape(string)
17
17
  %x{
18
18
  return string.replace(/([-[\]\/{}()*+?.^$\\| ])/g, '\\$1')
@@ -55,8 +55,8 @@ class Regexp < `RegExp`
55
55
  if (part.$$is_string) {
56
56
  quoted_validated.push(#{escape(`part`)});
57
57
  }
58
- else if (part.$$is_regexp) {
59
- each_part_options = #{`part`.options};
58
+ else if (part.$$is_regexp) {
59
+ each_part_options = #{`part`.options};
60
60
  if (options != undefined && options != each_part_options) {
61
61
  #{raise TypeError, 'All expressions must use the same options'}
62
62
  }
@@ -69,10 +69,10 @@ class Regexp < `RegExp`
69
69
  }
70
70
  }
71
71
  # Take advantage of logic that can parse options from JS Regex
72
- new(`quoted_validated`.join('|'), `options`)
72
+ new(`quoted_validated`.join('|'), `options`)
73
73
  end
74
74
 
75
- def new(regexp, options = undefined)
75
+ def new(regexp, options = undefined)
76
76
  %x{
77
77
  if (regexp.$$is_regexp) {
78
78
  return new RegExp(regexp);
@@ -126,7 +126,7 @@ class Regexp < `RegExp`
126
126
  if (self.uninitialized) {
127
127
  #{raise TypeError, 'uninitialized Regexp'}
128
128
  }
129
-
129
+
130
130
  if (pos === undefined) {
131
131
  pos = 0;
132
132
  } else {
@@ -154,7 +154,7 @@ class Regexp < `RegExp`
154
154
  flags += 'm';
155
155
  }
156
156
 
157
- // global RegExp maintains state, so not using self/this
157
+ // global RegExp maintains state, so not using self/this
158
158
  var md, re = new RegExp(source, flags + (self.ignoreCase ? 'i' : ''));
159
159
 
160
160
  while (true) {
@@ -178,13 +178,13 @@ class Regexp < `RegExp`
178
178
  def source
179
179
  `self.source`
180
180
  end
181
-
181
+
182
182
  def options
183
183
  # Flags would be nice to use with this, but still experimental - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/flags
184
184
  %x{
185
185
  if (self.uninitialized) {
186
186
  #{raise TypeError, 'uninitialized Regexp'}
187
- }
187
+ }
188
188
  var result = 0;
189
189
  // should be supported in IE6 according to https://msdn.microsoft.com/en-us/library/7f5z26w4(v=vs.94).aspx
190
190
  if (self.multiline) {
@@ -192,11 +192,11 @@ class Regexp < `RegExp`
192
192
  }
193
193
  if (self.ignoreCase) {
194
194
  result |= #{IGNORECASE};
195
- }
195
+ }
196
196
  return result;
197
- }
197
+ }
198
198
  end
199
-
199
+
200
200
  def casefold?
201
201
  `self.ignoreCase`
202
202
  end