opal 0.10.0.beta3 → 0.10.0.beta4

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