opal 0.5.2 → 0.5.4

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