opal 0.10.0.beta3 → 0.10.0.beta4

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -0
  3. data/CHANGELOG.md +9 -1
  4. data/HACKING.md +2 -2
  5. data/docs/compiled_ruby.md +6 -6
  6. data/lib/opal/cli_runners/nodejs.rb +3 -1
  7. data/lib/opal/nodes/args/mlhsarg.rb +1 -3
  8. data/lib/opal/nodes/def.rb +18 -54
  9. data/lib/opal/nodes/helpers.rb +3 -3
  10. data/lib/opal/nodes/iter.rb +32 -3
  11. data/lib/opal/nodes/logic.rb +5 -5
  12. data/lib/opal/nodes/node_with_args.rb +31 -0
  13. data/lib/opal/parser/lexer.rb +9 -7
  14. data/lib/opal/sprockets/processor.rb +2 -2
  15. data/lib/opal/version.rb +1 -1
  16. data/opal/corelib/array.rb +16 -0
  17. data/opal/corelib/basic_object.rb +1 -1
  18. data/opal/corelib/class.rb +15 -0
  19. data/opal/corelib/constants.rb +1 -1
  20. data/opal/corelib/enumerable.rb +32 -62
  21. data/opal/corelib/file.rb +2 -0
  22. data/opal/corelib/helpers.rb +41 -1
  23. data/opal/corelib/module.rb +26 -10
  24. data/opal/corelib/runtime.js +47 -12
  25. data/spec/filters/bugs/date.rb +0 -9
  26. data/spec/filters/bugs/hash.rb +0 -2
  27. data/spec/filters/bugs/kernel.rb +0 -5
  28. data/spec/filters/bugs/language.rb +4 -19
  29. data/spec/filters/bugs/module.rb +0 -30
  30. data/spec/filters/bugs/pathname.rb +5 -0
  31. data/spec/filters/bugs/proc.rb +0 -6
  32. data/spec/filters/unsupported/thread.rb +1 -0
  33. data/spec/lib/compiler_spec.rb +29 -29
  34. data/spec/opal/core/runtime/truthy_spec.rb +26 -0
  35. data/spec/ruby_specs +0 -3
  36. data/stdlib/date.rb +21 -0
  37. data/stdlib/native.rb +1 -1
  38. data/stdlib/nodejs/file.rb +36 -11
  39. data/stdlib/nodejs/io.rb +55 -0
  40. data/stdlib/pathname.rb +43 -0
  41. data/stdlib/promise.rb +1 -1
  42. data/tasks/testing.rake +55 -31
  43. data/test/nodejs/test_file.rb +30 -0
  44. metadata +6 -2
@@ -120,14 +120,14 @@ module Opal
120
120
 
121
121
  # @deprecated
122
122
  def self.stubbed_files
123
- warn "Deprecated: use `::Opal::Config.stubbed_files` instead"
123
+ warn "Deprecated: `::Opal::Processor.stubbed_files' is deprecated, use `::Opal::Config.stubbed_files' instead"
124
124
  puts caller(5)
125
125
  ::Opal::Config.stubbed_files
126
126
  end
127
127
 
128
128
  # @deprecated
129
129
  def self.stub_file(name)
130
- warn "Deprecated: use `::Opal::Config.stubbed_files << #{name.inspect}.to_s` instead"
130
+ warn "Deprecated: `::Opal::Processor.stub_file' is deprecated, use `::Opal::Config.stubbed_files << #{name.inspect}.to_s' instead"
131
131
  puts caller(5)
132
132
  ::Opal::Config.stubbed_files << name.to_s
133
133
  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.10.0.beta3'
4
+ VERSION = '0.10.0.beta4'
5
5
  end
@@ -795,6 +795,19 @@ class Array < `Array`
795
795
  }
796
796
  end
797
797
 
798
+ def dup
799
+ %x{
800
+ if (
801
+ self.$$class === Opal.Array &&
802
+ self.$allocate.$$pristine &&
803
+ self.$copy_instance_variables.$$pristine &&
804
+ self.$initialize_dup.$$pristine
805
+ ) return self.slice(0);
806
+ }
807
+
808
+ super
809
+ end
810
+
798
811
  def each(&block)
799
812
  return enum_for(:each){self.size} unless block_given?
800
813
 
@@ -2231,4 +2244,7 @@ class Array < `Array`
2231
2244
  def instance_variables
2232
2245
  super.reject { |ivar| `/^@\d+$/.test(#{ivar})` || ivar == '@length' }
2233
2246
  end
2247
+
2248
+ Opal.pristine self, :allocate, :copy_instance_variables, :initialize_dup
2234
2249
  end
2250
+
@@ -54,7 +54,7 @@ class BasicObject
54
54
  default_eval_options = { file: (file || '(eval)'), eval: true }
55
55
  compiling_options = __OPAL_COMPILER_CONFIG__.merge(default_eval_options)
56
56
  compiled = Opal.compile string, compiling_options
57
- block = Kernel.lambda do
57
+ block = Kernel.proc do
58
58
  %x{
59
59
  return (function(self) {
60
60
  return eval(compiled);
@@ -47,4 +47,19 @@ class Class
47
47
  def superclass
48
48
  `self.$$super || nil`
49
49
  end
50
+
51
+ def to_s
52
+ %x{
53
+ var singleton_of = self.$$singleton_of;
54
+
55
+ if (singleton_of && (singleton_of.$$is_class || singleton_of.$$is_module)) {
56
+ return #{"#<Class:#{`singleton_of`.name}>"};
57
+ }
58
+ else if (singleton_of) {
59
+ // a singleton class created from an object
60
+ return #{"#<Class:#<#{`singleton_of.$$class`.name}:0x#{`singleton_of.$$id`.to_s(16)}>>"};
61
+ }
62
+ return #{super()};
63
+ }
64
+ end
50
65
  end
@@ -1,7 +1,7 @@
1
1
  RUBY_PLATFORM = 'opal'
2
2
  RUBY_ENGINE = 'opal'
3
3
  RUBY_VERSION = '2.2.3'
4
- RUBY_ENGINE_VERSION = '0.10.0.beta3'
4
+ RUBY_ENGINE_VERSION = '0.10.0.beta4'
5
5
  RUBY_RELEASE_DATE = '2015-12-20'
6
6
  RUBY_PATCHLEVEL = 0
7
7
  RUBY_REVISION = 0
@@ -1,13 +1,10 @@
1
1
  module Enumerable
2
2
  def all?(&block)
3
- result = true
4
-
5
3
  if block_given?
6
4
 
7
5
  each do |*value|
8
6
  unless yield(*value)
9
- result = false
10
- break
7
+ return false
11
8
  end
12
9
  end
13
10
 
@@ -15,25 +12,21 @@ module Enumerable
15
12
 
16
13
  each do |*value|
17
14
  unless Opal.destructure(value)
18
- result = false
19
- break
15
+ return false
20
16
  end
21
17
  end
22
18
 
23
19
  end
24
20
 
25
- result
21
+ true
26
22
  end
27
23
 
28
24
  def any?(&block)
29
- result = false
30
-
31
25
  if block_given?
32
26
 
33
27
  each do |*value|
34
28
  if yield(*value)
35
- result = true
36
- break
29
+ return true
37
30
  end
38
31
  end
39
32
 
@@ -41,14 +34,13 @@ module Enumerable
41
34
 
42
35
  each do |*value|
43
36
  if Opal.destructure(value)
44
- result = true
45
- break
37
+ return true
46
38
  end
47
39
  end
48
40
 
49
41
  end
50
42
 
51
- result
43
+ false
52
44
  end
53
45
 
54
46
  def chunk(state = undefined, &original_block)
@@ -204,28 +196,25 @@ module Enumerable
204
196
 
205
197
  def detect(ifnone = undefined, &block)
206
198
  return enum_for :detect, ifnone unless block_given?
207
- result = `undefined`
208
199
 
209
200
  each do |*args|
210
201
  value = Opal.destructure(args)
211
202
  if yield(value)
212
- result = value
213
- break
203
+ return value
214
204
  end
215
205
  end
216
206
 
217
207
  %x{
218
- if (result === undefined && ifnone !== undefined) {
208
+ if (ifnone !== undefined) {
219
209
  if (typeof(ifnone) === 'function') {
220
- result = ifnone();
221
- }
222
- else {
223
- result = ifnone;
210
+ return ifnone();
211
+ } else {
212
+ return ifnone;
224
213
  }
225
214
  }
226
-
227
- return result === undefined ? nil : result;
228
215
  }
216
+
217
+ nil
229
218
  end
230
219
 
231
220
  def drop(number)
@@ -470,14 +459,12 @@ module Enumerable
470
459
  def find_index(object = undefined, &block)
471
460
  return enum_for :find_index if `object === undefined && block === nil`
472
461
 
473
- result = nil
474
462
  index = 0
475
463
 
476
464
  if `object != null`
477
465
  each do |*value|
478
466
  if Opal.destructure(value) == object
479
- result = index
480
- break
467
+ return index
481
468
  end
482
469
 
483
470
  `index += 1`
@@ -485,23 +472,20 @@ module Enumerable
485
472
  else
486
473
  each do |*value|
487
474
  if yield(*value)
488
- result = index
489
- break
475
+ return index
490
476
  end
491
477
 
492
478
  `index += 1`
493
479
  end
494
480
  end
495
481
 
496
- result
482
+ nil
497
483
  end
498
484
 
499
485
  def first(number = undefined)
500
486
  if `number === undefined`
501
- result = nil
502
487
  each do |value|
503
- result = value
504
- break
488
+ return value
505
489
  end
506
490
  else
507
491
  result = []
@@ -521,12 +505,12 @@ module Enumerable
521
505
  `result.push(#{Opal.destructure(args)})`
522
506
 
523
507
  if `number <= ++current`
524
- break
508
+ return result
525
509
  end
526
510
  end
527
- end
528
511
 
529
- result
512
+ result
513
+ end
530
514
  end
531
515
 
532
516
  alias flat_map collect_concat
@@ -590,15 +574,13 @@ module Enumerable
590
574
  end
591
575
 
592
576
  def include?(obj)
593
- result = false
594
577
  each do |*args|
595
578
  if Opal.destructure(args) == obj
596
- result = true
597
- break
579
+ return true
598
580
  end
599
581
  end
600
582
 
601
- result
583
+ false
602
584
  end
603
585
 
604
586
  def inject(object = undefined, sym = undefined, &block)
@@ -848,14 +830,11 @@ module Enumerable
848
830
  end
849
831
 
850
832
  def none?(&block)
851
- result = true
852
-
853
833
  if block_given?
854
834
 
855
835
  each do |*value|
856
836
  if yield(*value)
857
- result = false
858
- break
837
+ return false
859
838
  end
860
839
  end
861
840
 
@@ -863,29 +842,25 @@ module Enumerable
863
842
 
864
843
  each do |*value|
865
844
  if Opal.destructure(value)
866
- result = false
867
- break
845
+ return false
868
846
  end
869
847
  end
870
848
 
871
849
  end
872
850
 
873
- result
851
+ true
874
852
  end
875
853
 
876
854
  def one?(&block)
877
- result = false
855
+ count = 0
878
856
 
879
857
  if block_given?
880
858
 
881
859
  each do |*value|
882
860
  if yield(*value)
883
- if result
884
- result = false
885
- break
886
- end
861
+ count += 1
887
862
 
888
- result = true
863
+ return false if count > 1
889
864
  end
890
865
  end
891
866
 
@@ -893,18 +868,15 @@ module Enumerable
893
868
 
894
869
  each do |*value|
895
870
  if Opal.destructure(value)
896
- if result
897
- result = false
898
- break
899
- end
871
+ count += 1
900
872
 
901
- result = true
873
+ return false if count > 1
902
874
  end
903
875
  end
904
876
 
905
877
  end
906
878
 
907
- result
879
+ count == 1
908
880
  end
909
881
 
910
882
  def partition(&block)
@@ -1066,13 +1038,11 @@ module Enumerable
1066
1038
  value = Opal.destructure(args)
1067
1039
 
1068
1040
  unless yield(value)
1069
- break
1041
+ return result
1070
1042
  end
1071
1043
 
1072
1044
  `result.push(value)`
1073
1045
  end
1074
-
1075
- result
1076
1046
  end
1077
1047
 
1078
1048
  alias to_a entries
data/opal/corelib/file.rb CHANGED
@@ -2,6 +2,8 @@ class File < IO
2
2
  Separator = SEPARATOR = '/'
3
3
  ALT_SEPARATOR = nil
4
4
  PATH_SEPARATOR = ':'
5
+ # Assuming case insenstive filesystem
6
+ FNM_SYSCASE = 0
5
7
 
6
8
  class << self
7
9
  def expand_path(path, basedir = nil)
@@ -72,7 +72,10 @@ module Opal
72
72
  return args;
73
73
  }
74
74
  else {
75
- return $slice.call(args);
75
+ var args_ary = new Array(args.length);
76
+ for(var i = 0, l = args_ary.length; i < l; i++) { args_ary[i] = args[i]; }
77
+
78
+ return args_ary;
76
79
  }
77
80
  }
78
81
  end
@@ -123,4 +126,41 @@ module Opal
123
126
 
124
127
  const_name
125
128
  end
129
+
130
+ # @private
131
+ # Mark some methods as pristine in order to apply optimizations when they
132
+ # are still in their original form. This could probably be moved to
133
+ # the `Opal.def()` JS API, but for now it will stay manual.
134
+ #
135
+ # @example
136
+ #
137
+ # Opal.pristine Array, :allocate, :copy_instance_variables, :initialize_dup
138
+ #
139
+ # class Array
140
+ # def dup
141
+ # %x{
142
+ # if (
143
+ # self.$allocate.$$pristine &&
144
+ # self.$copy_instance_variables.$$pristine &&
145
+ # self.$initialize_dup.$$pristine
146
+ # ) return self.slice(0);
147
+ # }
148
+ #
149
+ # super
150
+ # end
151
+ # end
152
+ #
153
+ # @param owner_class [Class] the class owning the methods
154
+ # @param method_names [Array<Symbol>] the list of methods names to mark
155
+ # @return [nil]
156
+ def self.pristine owner_class, *method_names
157
+ %x{
158
+ var method_name;
159
+ for (var i = method_names.length - 1; i >= 0; i--) {
160
+ method_name = method_names[i];
161
+ owner_class.$$proto['$'+method_name].$$pristine = true
162
+ }
163
+ }
164
+ nil
165
+ end
126
166
  end
@@ -389,32 +389,32 @@ class Module
389
389
 
390
390
  self
391
391
  end
392
-
392
+
393
393
  def included_modules
394
394
  %x{
395
395
  var results;
396
-
396
+
397
397
  var module_chain = function(klass) {
398
398
  var included = [];
399
-
399
+
400
400
  for (var i = 0; i != klass.$$inc.length; i++) {
401
401
  var mod_or_class = klass.$$inc[i];
402
402
  included.push(mod_or_class);
403
403
  included = included.concat(module_chain(mod_or_class));
404
404
  }
405
-
405
+
406
406
  return included;
407
407
  };
408
-
408
+
409
409
  results = module_chain(self);
410
-
410
+
411
411
  // need superclass's modules
412
412
  if (self.$$is_class) {
413
413
  for (var cls = self; cls; cls = cls.$$super) {
414
414
  results = results.concat(module_chain(cls));
415
415
  }
416
416
  }
417
-
417
+
418
418
  return results;
419
419
  }
420
420
  end
@@ -486,7 +486,7 @@ class Module
486
486
 
487
487
  def included(mod)
488
488
  end
489
-
489
+
490
490
  def extended(mod)
491
491
  end
492
492
 
@@ -499,8 +499,24 @@ class Module
499
499
  def method_undefined(*)
500
500
  end
501
501
 
502
- def module_eval(&block)
503
- raise ArgumentError, 'no block given' unless block
502
+ def module_eval(*args, &block)
503
+ if block.nil? && `!!Opal.compile`
504
+ Kernel.raise ArgumentError, "wrong number of arguments (0 for 1..3)" unless (1..3).cover? args.size
505
+
506
+ string, file, _lineno = *args
507
+ default_eval_options = { file: (file || '(eval)'), eval: true }
508
+ compiling_options = __OPAL_COMPILER_CONFIG__.merge(default_eval_options)
509
+ compiled = Opal.compile string, compiling_options
510
+ block = Kernel.proc do
511
+ %x{
512
+ return (function(self) {
513
+ return eval(compiled);
514
+ })(self)
515
+ }
516
+ end
517
+ elsif args.size > 0
518
+ Kernel.raise ArgumentError, "wrong number of arguments (#{args.size} for 0)"
519
+ end
504
520
 
505
521
  %x{
506
522
  var old = block.$$s,