opal 0.5.2 → 0.5.4

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -0
  3. data/lib/opal.rb +0 -5
  4. data/lib/opal/compiler.rb +24 -44
  5. data/lib/opal/nodes/base.rb +5 -8
  6. data/lib/opal/nodes/call.rb +4 -0
  7. data/lib/opal/nodes/class.rb +6 -7
  8. data/lib/opal/nodes/def.rb +4 -4
  9. data/lib/opal/nodes/definitions.rb +0 -14
  10. data/lib/opal/nodes/iter.rb +51 -38
  11. data/lib/opal/nodes/literal.rb +21 -24
  12. data/lib/opal/nodes/module.rb +4 -4
  13. data/lib/opal/nodes/runtime_helpers.rb +45 -0
  14. data/lib/opal/nodes/scope.rb +280 -0
  15. data/lib/opal/nodes/singleton_class.rb +4 -5
  16. data/lib/opal/nodes/super.rb +1 -1
  17. data/lib/opal/nodes/top.rb +9 -7
  18. data/lib/opal/nodes/yield.rb +14 -3
  19. data/lib/opal/parser.rb +4 -18
  20. data/lib/opal/parser/grammar.rb +3745 -3667
  21. data/lib/opal/parser/grammar.y +1692 -1778
  22. data/lib/opal/parser/keywords.rb +35 -35
  23. data/lib/opal/parser/lexer.rb +356 -325
  24. data/lib/opal/parser/sexp.rb +1 -1
  25. data/lib/opal/version.rb +1 -1
  26. data/opal.gemspec +1 -0
  27. data/opal/core/array.rb +320 -81
  28. data/opal/core/enumerable.rb +46 -5
  29. data/opal/core/hash.rb +6 -64
  30. data/opal/core/helpers.rb +67 -0
  31. data/opal/core/method.rb +1 -1
  32. data/opal/core/module.rb +4 -4
  33. data/opal/core/range.rb +1 -12
  34. data/opal/core/regexp.rb +2 -8
  35. data/opal/core/runtime.js +74 -3
  36. data/opal/core/string.rb +99 -74
  37. data/opal/opal.rb +3 -72
  38. data/spec/filters/bugs/array.rb +2 -30
  39. data/spec/filters/bugs/basic_object.rb +0 -1
  40. data/spec/filters/bugs/string.rb +26 -21
  41. data/spec/filters/unsupported/enumerator.rb +3 -0
  42. data/spec/filters/unsupported/float.rb +1 -0
  43. data/spec/filters/unsupported/immutable_strings.rb +15 -0
  44. data/spec/filters/unsupported/tainted.rb +58 -30
  45. data/spec/filters/unsupported/trusted.rb +35 -15
  46. data/spec/opal/parser/class_spec.rb +4 -4
  47. data/spec/opal/parser/def_spec.rb +4 -4
  48. data/spec/opal/parser/lvar_spec.rb +6 -6
  49. data/spec/opal/parser/module_spec.rb +4 -4
  50. data/spec/opal/parser/sclass_spec.rb +2 -2
  51. data/spec/stdlib/native/exposure_spec.rb +33 -0
  52. data/stdlib/buffer.rb +1 -1
  53. data/stdlib/buffer/view.rb +1 -1
  54. data/stdlib/native.rb +193 -174
  55. data/stdlib/opal-parser.rb +0 -6
  56. data/stdlib/pp.rb +9 -0
  57. data/tasks/mspec.rake +3 -1
  58. metadata +9 -9
  59. data/lib/opal/nodes/base_scope.rb +0 -11
  60. data/lib/opal/target_scope.rb +0 -281
  61. data/spec/filters/20.rb +0 -4
  62. data/spec/filters/unsupported/array_subclasses.rb +0 -37
@@ -2,7 +2,6 @@ class String
2
2
  include Comparable
3
3
 
4
4
  `def._isString = true`
5
- `var native_string = "".constructor;`
6
5
 
7
6
  def self.try_convert(what)
8
7
  what.to_str
@@ -11,7 +10,7 @@ class String
11
10
  end
12
11
 
13
12
  def self.new(str = '')
14
- `new native_string(str)`
13
+ `new String(str)`
15
14
  end
16
15
 
17
16
  def %(data)
@@ -45,30 +44,27 @@ class String
45
44
  end
46
45
 
47
46
  def +(other)
48
- %x{
49
- if (other._isString) {
50
- return self + other;
51
- }
52
- }
47
+ other = Opal.coerce_to other, String, :to_str
53
48
 
54
- unless other.respond_to? :to_str
55
- raise TypeError, "no implicit conversion of #{other.class.name} into String"
56
- end
57
-
58
- `self + #{other.to_str}`
49
+ `self + #{other.to_s}`
59
50
  end
60
51
 
61
52
  def <=>(other)
62
- %x{
63
- if (other._isString) {
64
- return self > other ? 1 : (self < other ? -1 : 0);
65
- }
66
- }
67
-
68
53
  if other.respond_to? :to_str
69
- other = other.to_str
54
+ other = other.to_str.to_s
70
55
 
71
56
  `self > other ? 1 : (self < other ? -1 : 0)`
57
+ else
58
+ %x{
59
+ var cmp = #{other <=> self};
60
+
61
+ if (cmp === nil) {
62
+ return nil;
63
+ }
64
+ else {
65
+ return cmp > 0 ? -1 : (cmp < 0 ? 1 : 0);
66
+ }
67
+ }
72
68
  end
73
69
  end
74
70
 
@@ -147,27 +143,26 @@ class String
147
143
  end
148
144
 
149
145
  def casecmp(other)
150
- %x{
151
- if (other._isString) {
152
- return #{`self.toLowerCase()` <=> `other.toLowerCase()`};
153
- }
154
- }
155
-
156
- unless other.respond_to? :to_str
157
- raise TypeError, "no implicit conversion of #{other.class.name} into String"
158
- end
146
+ other = Opal.coerce_to(other, String, :to_str).to_s
159
147
 
160
- `self.toLowerCase()` <=> `#{other.to_str}.toLowerCase()`
148
+ `self.toLowerCase()` <=> `other.toLowerCase()`
161
149
  end
162
150
 
163
151
  def center(width, padstr = ' ')
164
- return self if `width === self.length`
152
+ width = Opal.coerce_to(width, Integer, :to_int)
153
+ padstr = Opal.coerce_to(padstr, String, :to_str).to_s
154
+
155
+ if padstr.empty?
156
+ raise ArgumentError, 'zero width padding'
157
+ end
158
+
159
+ return self if `width <= self.length`
165
160
 
166
161
  %x{
167
- var ljustified = #{ljust ((width + @length) / 2).floor, padstr},
168
- rjustified = #{rjust ((width + @length) / 2).ceil, padstr};
162
+ var ljustified = #{ljust ((width + @length) / 2).ceil, padstr},
163
+ rjustified = #{rjust ((width + @length) / 2).floor, padstr};
169
164
 
170
- return ljustified + rjustified.slice(self.length);
165
+ return rjustified + ljustified.slice(self.length);
171
166
  }
172
167
  end
173
168
 
@@ -178,13 +173,7 @@ class String
178
173
  def chomp(separator = $/)
179
174
  return self if `separator === nil || self.length === 0`
180
175
 
181
- if `separator._isString == null`
182
- unless separator.respond_to? :to_str
183
- raise TypeError, "no implicit conversion of #{separator.class.name} into String"
184
- end
185
-
186
- separator = separator.to_str
187
- end
176
+ separator = Opal.coerce_to!(separator, String, :to_str).to_s
188
177
 
189
178
  %x{
190
179
  if (separator === "\\n") {
@@ -206,7 +195,20 @@ class String
206
195
  end
207
196
 
208
197
  def chop
209
- `self.substr(0, self.length - 1)`
198
+ %x{
199
+ var length = self.length;
200
+
201
+ if (length <= 1) {
202
+ return "";
203
+ }
204
+
205
+ if (self.charAt(length - 1) === "\\n" && self.charAt(length - 2) === "\\r") {
206
+ return self.substr(0, length - 2);
207
+ }
208
+ else {
209
+ return self.substr(0, length - 1);
210
+ }
211
+ }
210
212
  end
211
213
 
212
214
  def chr
@@ -323,44 +325,53 @@ class String
323
325
  end
324
326
 
325
327
  def index(what, offset = nil)
326
- %x{
327
- if (!(what._isString || what._isRegexp)) {
328
- #{raise TypeError, "type mismatch: #{what.class} given"};
329
- }
328
+ if String === what
329
+ what = what.to_s
330
+ elsif what.respond_to? :to_str
331
+ what = what.to_str.to_s
332
+ elsif not Regexp === what
333
+ raise TypeError, "type mismatch: #{what.class} given"
334
+ end
330
335
 
331
- var result = -1;
336
+ result = -1
337
+
338
+ if offset
339
+ offset = Opal.coerce_to offset, Integer, :to_int
340
+
341
+ %x{
342
+ var size = self.length;
332
343
 
333
- if (offset !== nil) {
334
344
  if (offset < 0) {
335
- offset = offset + self.length;
345
+ offset = offset + size;
336
346
  }
337
347
 
338
- if (offset > self.length) {
348
+ if (offset > size) {
339
349
  return nil;
340
350
  }
351
+ }
341
352
 
342
- if (what._isRegexp) {
343
- result = #{(what =~ `self.substr(offset)`) || -1}
344
- }
345
- else {
346
- result = self.substr(offset).indexOf(what);
347
- }
353
+ if Regexp === what
354
+ result = (what =~ `self.substr(offset)`) || -1
355
+ else
356
+ result = `self.substr(offset).indexOf(what)`
357
+ end
348
358
 
359
+ %x{
349
360
  if (result !== -1) {
350
361
  result += offset;
351
362
  }
352
363
  }
353
- else {
354
- if (what._isRegexp) {
355
- result = #{(what =~ self) || -1}
356
- }
357
- else {
358
- result = self.indexOf(what);
359
- }
360
- }
364
+ else
365
+ if Regexp === what
366
+ result = (what =~ self) || -1
367
+ else
368
+ result = `self.indexOf(what)`
369
+ end
370
+ end
361
371
 
362
- return result === -1 ? nil : result;
363
- }
372
+ unless `result === -1`
373
+ result
374
+ end
364
375
  end
365
376
 
366
377
  def inspect
@@ -400,6 +411,13 @@ class String
400
411
  end
401
412
 
402
413
  def ljust(width, padstr = ' ')
414
+ width = Opal.coerce_to(width, Integer, :to_int)
415
+ padstr = Opal.coerce_to(padstr, String, :to_str).to_s
416
+
417
+ if padstr.empty?
418
+ raise ArgumentError, 'zero width padding'
419
+ end
420
+
403
421
  return self if `width <= self.length`
404
422
 
405
423
  %x{
@@ -439,7 +457,7 @@ class String
439
457
  }
440
458
 
441
459
  var initial = #{self}.substr(0, #{self}.length - 1);
442
- var last = native_string.fromCharCode(#{self}.charCodeAt(#{self}.length - 1) + 1);
460
+ var last = String.fromCharCode(#{self}.charCodeAt(#{self}.length - 1) + 1);
443
461
 
444
462
  return initial + last;
445
463
  }
@@ -466,7 +484,7 @@ class String
466
484
  def rindex(search, offset = undefined)
467
485
  %x{
468
486
  var search_type = (search == null ? Opal.NilClass : search.constructor);
469
- if (search_type != native_string && search_type != RegExp) {
487
+ if (search_type != String && search_type != RegExp) {
470
488
  var msg = "type mismatch: " + search_type + " given";
471
489
  #{raise TypeError.new(`msg`)};
472
490
  }
@@ -481,7 +499,7 @@ class String
481
499
  offset = #{self}.length + offset;
482
500
  }
483
501
 
484
- if (search_type == native_string) {
502
+ if (search_type == String) {
485
503
  result = #{self}.lastIndexOf(search, offset);
486
504
  }
487
505
  else {
@@ -492,7 +510,7 @@ class String
492
510
  }
493
511
  }
494
512
  else {
495
- if (search_type == native_string) {
513
+ if (search_type == String) {
496
514
  result = #{self}.lastIndexOf(search);
497
515
  }
498
516
  else {
@@ -508,6 +526,13 @@ class String
508
526
  end
509
527
 
510
528
  def rjust(width, padstr = ' ')
529
+ width = Opal.coerce_to(width, Integer, :to_int)
530
+ padstr = Opal.coerce_to(padstr, String, :to_str).to_s
531
+
532
+ if padstr.empty?
533
+ raise ArgumentError, 'zero width padding'
534
+ end
535
+
511
536
  return self if `width <= self.length`
512
537
 
513
538
  %x{
@@ -658,7 +683,7 @@ class String
658
683
  return $1 ? $0.toUpperCase() : $0.toLowerCase();
659
684
  });
660
685
 
661
- if (#{self}.constructor === native_string) {
686
+ if (#{self}.constructor === String) {
662
687
  return str;
663
688
  }
664
689
 
@@ -761,7 +786,7 @@ class String
761
786
  var start = last_from.charCodeAt(0) + 1;
762
787
  var end = char.charCodeAt(0);
763
788
  for (var c = start; c < end; c++) {
764
- from_chars_expanded.push(native_string.fromCharCode(c));
789
+ from_chars_expanded.push(String.fromCharCode(c));
765
790
  }
766
791
  from_chars_expanded.push(char);
767
792
  in_range = null;
@@ -807,7 +832,7 @@ class String
807
832
  var start = last_from.charCodeAt(0) + 1;
808
833
  var end = char.charCodeAt(0);
809
834
  for (var c = start; c < end; c++) {
810
- to_chars_expanded.push(native_string.fromCharCode(c));
835
+ to_chars_expanded.push(String.fromCharCode(c));
811
836
  }
812
837
  to_chars_expanded.push(char);
813
838
  in_range = null;
@@ -896,7 +921,7 @@ class String
896
921
  var start = last_from.charCodeAt(0) + 1;
897
922
  var end = char.charCodeAt(0);
898
923
  for (var c = start; c < end; c++) {
899
- from_chars_expanded.push(native_string.fromCharCode(c));
924
+ from_chars_expanded.push(String.fromCharCode(c));
900
925
  }
901
926
  from_chars_expanded.push(char);
902
927
  in_range = null;
@@ -942,7 +967,7 @@ class String
942
967
  var start = last_from.charCodeAt(0) + 1;
943
968
  var end = char.charCodeAt(0);
944
969
  for (var c = start; c < end; c++) {
945
- to_chars_expanded.push(native_string.fromCharCode(c));
970
+ to_chars_expanded.push(String.fromCharCode(c));
946
971
  }
947
972
  to_chars_expanded.push(char);
948
973
  in_range = null;
@@ -1,4 +1,5 @@
1
1
  require 'core/runtime'
2
+ require 'core/helpers'
2
3
  require 'core/module'
3
4
  require 'core/class'
4
5
  require 'core/basic_object'
@@ -47,75 +48,5 @@ $SAFE = 0
47
48
  RUBY_PLATFORM = 'opal'
48
49
  RUBY_ENGINE = 'opal'
49
50
  RUBY_VERSION = '1.9.3'
50
- RUBY_ENGINE_VERSION = '0.5.2'
51
- RUBY_RELEASE_DATE = '2013-11-11'
52
-
53
- module Opal
54
- def self.coerce_to(object, type, method)
55
- return object if type === object
56
-
57
- unless object.respond_to? method
58
- raise TypeError, "no implicit conversion of #{object.class} into #{type}"
59
- end
60
-
61
- object.__send__ method
62
- end
63
-
64
- def self.coerce_to!(object, type, method)
65
- coerced = coerce_to(object, type, method)
66
-
67
- unless type === coerced
68
- raise TypeError, "can't convert #{object.class} into #{type} (#{object.class}##{method} gives #{coerced.class}"
69
- end
70
-
71
- coerced
72
- end
73
-
74
- def self.try_convert(object, type, method)
75
- return object if type === object
76
-
77
- if object.respond_to? method
78
- object.__send__ method
79
- end
80
- end
81
-
82
- def self.compare(a, b)
83
- compare = a <=> b
84
-
85
- if `compare === nil`
86
- raise ArgumentError, "comparison of #{a.class.name} with #{b.class.name} failed"
87
- end
88
-
89
- compare
90
- end
91
-
92
- def self.truthy?(value)
93
- if value
94
- true
95
- else
96
- false
97
- end
98
- end
99
-
100
- def self.falsy?(value)
101
- if value
102
- false
103
- else
104
- true
105
- end
106
- end
107
-
108
- def self.destructure(args)
109
- %x{
110
- if (args.length == 1) {
111
- return args[0];
112
- }
113
- else if (args._isArray) {
114
- return args;
115
- }
116
- else {
117
- return $slice.call(args);
118
- }
119
- }
120
- end
121
- end
51
+ RUBY_ENGINE_VERSION = '0.5.4'
52
+ RUBY_RELEASE_DATE = '2013-11-20'
@@ -31,35 +31,11 @@ opal_filter "Array" do
31
31
  fails "Array#delete may be given a block that is executed if no element matches object"
32
32
  fails "Array#delete returns the last element in the array for which object is equal under #=="
33
33
 
34
- fails "Array#drop_while removes elements from the start of the array until the block returns false"
35
- fails "Array#drop_while removes elements from the start of the array until the block returns nil"
36
- fails "Array#drop_while removes elements from the start of the array while the block evaluates to true"
37
-
38
34
  fails "Array#dup creates a new array containing all elements or the original"
39
35
 
40
- fails "Array#[] tries to convert the passed argument to an Integer using #to_int"
41
- fails "Array#[] accepts Range instances having a negative m and both signs for n with [m..n] and [m...n]"
42
- fails "Array#[] tries to convert Range elements to Integers using #to_int with [m..n] and [m...n]"
43
- fails "Array#[] returns nil if range start is not in the array with [m..n]"
44
- fails "Array#[] raises a RangeError when the start index is out of range of Fixnum"
45
- fails "Array#[] raises a RangeError when the start index is out of range of Fixnum"
46
- fails "Array#[] raises a RangeError when the length is out of range of Fixnum"
47
- fails "Array#[] raises a RangeError when the length is out of range of Fixnum"
48
36
  fails "Array.[] can unpack 2 or more nested referenced array"
49
37
 
50
- fails "Array#[]= calls to_ary on its rhs argument for multi-element sets"
51
- fails "Array#[]= raises an IndexError when passed indexes out of bounds"
52
- fails "Array#[]= tries to convert Range elements to Integers using #to_int with [m..n] and [m...n]"
53
-
54
- fails "Array#[]= with [m..n] accepts Range subclasses"
55
- fails "Array#[]= with [m..n] inserts the other section at m if m > n"
56
- fails "Array#[]= with [m..n] replaces the section if m < 0 and n > 0"
57
- fails "Array#[]= with [m..n] replaces the section if m and n < 0"
58
- fails "Array#[]= with [m..n] just sets the section defined by range to nil if m and n < 0 and the rhs is nil"
59
-
60
38
  fails "Array#[]= sets elements in the range arguments when passed ranges"
61
- fails "Array#[]= calls to_int on its start and length arguments"
62
- fails "Array#[]= does nothing if the section defined by range has negative width and the rhs is an empty array"
63
39
 
64
40
  fails "Array#eql? ignores array class differences"
65
41
  fails "Array#eql? handles well recursive arrays"
@@ -213,6 +189,7 @@ opal_filter "Array" do
213
189
  fails "Array#values_at returns an array of elements in the ranges when passes ranges"
214
190
  fails "Array#values_at properly handles recursive arrays"
215
191
  fails "Array#values_at calls to_int on arguments of ranges when passes ranges"
192
+ fails "Array#values_at does not return subclass instance on Array subclasses"
216
193
 
217
194
  fails "Array#zip calls #to_ary to convert the argument to an Array"
218
195
  fails "Array#zip uses #each to extract arguments' elements when #to_ary fails"
@@ -225,13 +202,8 @@ opal_filter "Array" do
225
202
  fails "Array#hash returns the same hash for equal recursive arrays"
226
203
  fails "Array#hash returns the same fixnum for arrays with the same content"
227
204
 
228
- fails "Array#initialize_copy tries to convert the passed argument to an Array using #to_ary"
229
- fails "Array#initialize_copy does not make self dependent to the original array"
230
- fails "Array#initialize_copy returns self"
231
- fails "Array#initialize_copy properly handles recursive arrays"
232
- fails "Array#initialize_copy replaces the elements with elements from other array"
233
-
234
205
  fails "Array#partition properly handles recursive arrays"
235
206
  fails "Array#partition returns in the left array values for which the block evaluates to true"
236
207
  fails "Array#partition returns two arrays"
208
+ fails "Array#partition does not return subclass instances on Array subclasses"
237
209
  end