opal 1.4.1 → 1.5.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.js +5 -3
  3. data/.rubocop.yml +1 -0
  4. data/UNRELEASED.md +37 -2
  5. data/benchmark-ips/bm_js_symbols_vs_strings.rb +39 -14
  6. data/docs/releasing.md +10 -2
  7. data/lib/opal/ast/matcher.rb +77 -0
  8. data/lib/opal/cache.rb +1 -1
  9. data/lib/opal/cli_runners/applescript.rb +2 -0
  10. data/lib/opal/compiler.rb +18 -9
  11. data/lib/opal/nodes/call.rb +73 -28
  12. data/lib/opal/nodes/def.rb +31 -27
  13. data/lib/opal/nodes/definitions.rb +2 -0
  14. data/lib/opal/nodes/helpers.rb +4 -23
  15. data/lib/opal/nodes/if.rb +222 -0
  16. data/lib/opal/nodes/iter.rb +41 -37
  17. data/lib/opal/nodes/literal.rb +2 -2
  18. data/lib/opal/nodes/masgn.rb +15 -17
  19. data/lib/opal/nodes/node_with_args/shortcuts.rb +100 -0
  20. data/lib/opal/nodes/node_with_args.rb +1 -0
  21. data/lib/opal/nodes/top.rb +26 -10
  22. data/lib/opal/nodes.rb +0 -1
  23. data/lib/opal/parser/default_config.rb +3 -2
  24. data/lib/opal/repl.rb +1 -1
  25. data/lib/opal/rewriter.rb +13 -6
  26. data/lib/opal/rewriters/base.rb +12 -1
  27. data/lib/opal/rewriters/rubyspec/filters_rewriter.rb +1 -0
  28. data/lib/opal/version.rb +1 -1
  29. data/opal/corelib/array.rb +23 -28
  30. data/opal/corelib/binding.rb +14 -4
  31. data/opal/corelib/constants.rb +3 -3
  32. data/opal/corelib/hash.rb +2 -2
  33. data/opal/corelib/irb.rb +192 -0
  34. data/opal/corelib/math/polyfills.rb +127 -0
  35. data/opal/corelib/math.rb +14 -194
  36. data/opal/corelib/module.rb +23 -25
  37. data/opal/corelib/number.rb +63 -14
  38. data/opal/corelib/regexp.rb +2 -0
  39. data/opal/corelib/runtime.js +56 -20
  40. data/opal/corelib/string.rb +38 -59
  41. data/opal/corelib/time.rb +106 -68
  42. data/opal/opal/full.rb +0 -1
  43. data/opal/opal.rb +4 -1
  44. data/spec/filters/bugs/date.rb +0 -3
  45. data/spec/filters/bugs/datetime.rb +65 -0
  46. data/spec/filters/bugs/float.rb +0 -18
  47. data/spec/filters/bugs/hash.rb +0 -2
  48. data/spec/filters/bugs/language.rb +0 -3
  49. data/spec/filters/bugs/marshal.rb +0 -1
  50. data/spec/filters/bugs/string.rb +0 -30
  51. data/spec/filters/bugs/time.rb +18 -8
  52. data/spec/lib/cli_spec.rb +2 -2
  53. data/spec/lib/compiler_spec.rb +8 -8
  54. data/spec/lib/rewriters/base_spec.rb +1 -1
  55. data/spec/lib/rewriters/binary_operator_assignment_spec.rb +34 -59
  56. data/spec/lib/rewriters/block_to_iter_spec.rb +3 -6
  57. data/spec/lib/rewriters/dot_js_syntax_spec.rb +2 -5
  58. data/spec/lib/rewriters/for_rewriter_spec.rb +0 -1
  59. data/spec/lib/rewriters/forward_args_spec.rb +2 -3
  60. data/spec/lib/rewriters/js_reserved_words_spec.rb +2 -15
  61. data/spec/lib/rewriters/logical_operator_assignment_spec.rb +64 -89
  62. data/spec/lib/rewriters/numblocks_spec.rb +3 -5
  63. data/spec/lib/rewriters/opal_engine_check_spec.rb +2 -14
  64. data/spec/lib/rewriters/rubyspec/filters_rewriter_spec.rb +10 -2
  65. data/spec/opal/compiler/irb_spec.rb +4 -0
  66. data/spec/opal/core/language/super_spec.rb +26 -0
  67. data/spec/opal/core/regexp/assertions_spec.rb +19 -0
  68. data/spec/opal/core/string/to_proc_spec.rb +19 -0
  69. data/spec/ruby_specs +4 -0
  70. data/spec/support/rewriters_helper.rb +43 -23
  71. data/stdlib/date/date_time.rb +71 -0
  72. data/stdlib/date/formatters.rb +28 -0
  73. data/stdlib/date/infinity.rb +73 -0
  74. data/stdlib/date.rb +77 -214
  75. data/stdlib/opal/repl_js.rb +1 -1
  76. data/stdlib/{opal/replutils.rb → opal-replutils.rb} +3 -3
  77. data/stdlib/time.rb +39 -2
  78. data/stdlib/uri.rb +53 -0
  79. data/tasks/performance/asciidoctor_test.rb.erb +3 -1
  80. data/tasks/performance/optimization_status.rb +3 -2
  81. data/tasks/performance.rake +69 -35
  82. data/tasks/testing.rake +1 -0
  83. data/test/opal/test_uri.rb +35 -0
  84. data/yarn.lock +27 -5
  85. metadata +31 -18
  86. data/lib/opal/nodes/csend.rb +0 -24
  87. data/lib/opal/rewriters/explicit_writer_return.rb +0 -59
  88. data/spec/lib/rewriters/explicit_writer_return_spec.rb +0 -186
  89. data/stdlib/nodejs/irb.rb +0 -43
@@ -19,3 +19,29 @@ describe 'super without explicit argument' do
19
19
  klass.new.test_rest_kwargs(native: 4).should == {native: 4}
20
20
  end
21
21
  end
22
+
23
+ class ABlockWithSuperSpec
24
+ BLOCK = proc {
25
+ return [self, super()]
26
+ }
27
+ def foo; :foo; end
28
+ def bar; :bar; end
29
+ def foo_bar; [foo, bar]; end
30
+ end
31
+
32
+ describe "a block with super" do
33
+ it "can be used to define multiple methods" do
34
+ block = nil
35
+
36
+ c = Class.new(ABlockWithSuperSpec) {
37
+ define_method :foo, ABlockWithSuperSpec::BLOCK
38
+ define_method :bar, ABlockWithSuperSpec::BLOCK
39
+ define_method :foo_bar, ABlockWithSuperSpec::BLOCK
40
+ }
41
+
42
+ obj = c.new
43
+ obj.foo.should == [obj, :foo]
44
+ obj.bar.should == [obj, :bar]
45
+ obj.foo_bar.should == [obj, [[obj, :foo], [obj, :bar]]]
46
+ end
47
+ end
@@ -0,0 +1,19 @@
1
+ describe 'Regexp assertions' do
2
+ it 'matches the beginning of input' do
3
+ /\Atext/.should =~ 'text'
4
+ /\Atext/.should_not =~ 'the text'
5
+
6
+ regexp = Regexp.new('\Atext')
7
+ regexp.should =~ 'text'
8
+ regexp.should_not =~ 'the text'
9
+ end
10
+
11
+ it 'matches the end of input' do
12
+ /text\z/.should =~ 'the text'
13
+ /text\z/.should_not =~ 'text of'
14
+
15
+ regexp = Regexp.new('text\z')
16
+ regexp.should =~ 'the text'
17
+ regexp.should_not =~ 'text of'
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Symbol#to_proc" do
4
+ # bug #2417
5
+ it "correctly passes method name to #method_missing" do
6
+ obj = Object.new
7
+ def obj.method_missing(*args); args; end;
8
+ result = :a.to_proc.call(obj, 6, 7)
9
+ result.should == [:a, 6, 7]
10
+ end
11
+
12
+ it "correctly passes a block to #method_missing" do
13
+ obj = Object.new
14
+ block = ->{}
15
+ def obj.method_missing(*args, &block); block; end;
16
+ result = :a.to_proc.call(obj, 1, 2, 3, &block)
17
+ result.should == block
18
+ end
19
+ end
data/spec/ruby_specs CHANGED
@@ -176,6 +176,7 @@ ruby/library/base64
176
176
  ruby/library/bigdecimal
177
177
  !ruby/library/bigdecimal/util_spec
178
178
  ruby/library/date
179
+ ruby/library/datetime
179
180
  ruby/library/delegate/delegator/send_spec
180
181
  ruby/library/erb/util/h_spec
181
182
  ruby/library/erb/util/html_escape_spec
@@ -203,4 +204,7 @@ ruby/library/singleton
203
204
  ruby/library/stringio/each_line_spec
204
205
  ruby/library/stringio/each_spec
205
206
  ruby/library/stringscanner
207
+
208
+ ruby/library/time
209
+
206
210
  ruby/library/optionparser
@@ -1,13 +1,47 @@
1
1
  module RewritersHelper
2
- def s(type, *children)
3
- ::Opal::AST::Node.new(type, children)
2
+ module Common
3
+ def s(type, *children)
4
+ ::Opal::AST::Node.new(type, children)
5
+ end
6
+
7
+ def parse(source)
8
+ buffer = Opal::Parser::SourceBuffer.new('(eval)')
9
+ buffer.source = source
10
+ parser = Opal::Parser.default_parser
11
+ parser.parse(buffer)
12
+ end
13
+
14
+ # Parse, but drop the :top node
15
+ def ast_of(source)
16
+ parse(source).children.first
17
+ end
18
+ end
19
+
20
+ module DSL
21
+ def use_only_described_rewriter!
22
+ around(:each) do |e|
23
+ Opal::Rewriter.disable(except: described_class) { e.run }
24
+ end
25
+ end
26
+ end
27
+
28
+ include Common
29
+
30
+ def self.included(klass)
31
+ klass.extend(Common)
32
+ klass.extend(DSL)
33
+ end
34
+
35
+ def rewriter
36
+ described_class.new
4
37
  end
5
38
 
6
- def rewritten(ast)
7
- described_class.new.process(ast)
39
+ def rewritten(ast = input)
40
+ rewriter.process(ast)
8
41
  end
9
42
 
10
- alias :rewrite :rewritten
43
+ alias rewrite rewritten
44
+ alias processed rewritten
11
45
 
12
46
  def expect_rewritten(ast)
13
47
  expect(rewritten(ast))
@@ -17,28 +51,15 @@ module RewritersHelper
17
51
  expect_rewritten(ast).to eq(ast)
18
52
  end
19
53
 
20
- def parse(source)
21
- buffer = Opal::Parser::SourceBuffer.new('(eval)')
22
- buffer.source = source
23
- parser = Opal::Parser.default_parser
24
- parser.parse(buffer)
25
- end
26
-
27
- alias :ast_of :parse
28
-
29
54
  def parse_without_rewriting(source)
30
- buffer = Opal::Parser::SourceBuffer.new('(eval)')
31
- buffer.source = source
32
- parser = Parser::Ruby31.new
33
- parser.parse(buffer)
55
+ Opal::Rewriter.disable { parse(source) }
34
56
  end
35
57
  end
36
58
 
37
59
  RSpec.shared_examples 'it rewrites source-to-source' do |from_source, to_source|
38
60
  it "rewrites source #{from_source} to source #{to_source}" do
39
- initial = ast_of(from_source)
40
- rewritten = self.rewritten(initial)
41
- expected = ast_of(to_source)
61
+ rewritten = parse(from_source)
62
+ expected = parse(to_source)
42
63
 
43
64
  expect(rewritten).to eq(expected)
44
65
  end
@@ -46,8 +67,7 @@ end
46
67
 
47
68
  RSpec.shared_examples 'it rewrites source-to-AST' do |from_source, to_ast|
48
69
  it "rewrites source #{from_source} to AST #{to_ast}" do
49
- initial = ast_of(from_source)
50
- rewritten = self.rewritten(initial)
70
+ rewritten = parse(from_source).children.first
51
71
 
52
72
  expect(rewritten).to eq(to_ast)
53
73
  end
@@ -0,0 +1,71 @@
1
+ class DateTime < Date
2
+ class << self
3
+ def now
4
+ wrap Time.now
5
+ end
6
+
7
+ def parse(str)
8
+ wrap Time.parse(str)
9
+ end
10
+ end
11
+
12
+ def initialize(year = -4712, month = 1, day = 1, hours = 0, minutes = 0, seconds = 0, offset = 0, start = ITALY)
13
+ %x{
14
+ // Because of Gregorian reform calendar goes from 1582-10-04 to 1582-10-15.
15
+ // All days in between end up as 4 october.
16
+ if (year === 1582 && month === 10 && day > 4 && day < 15) {
17
+ day = 4;
18
+ }
19
+ }
20
+
21
+ @date = Time.new(year, month, day, hours, minutes, seconds, offset)
22
+ @start = start
23
+ end
24
+
25
+ def_delegators :@date, :min, :hour, :sec
26
+ alias minute min
27
+ alias second sec
28
+
29
+ def sec_fraction
30
+ @date.usec / 1_000_000r
31
+ end
32
+
33
+ alias second_fraction sec_fraction
34
+
35
+ def offset
36
+ @date.gmt_offset / (24 * 3600r)
37
+ end
38
+
39
+ def +(other)
40
+ ::DateTime.wrap @date + other
41
+ end
42
+
43
+ def -(other)
44
+ `if (Opal.is_a(other, #{::Date})) other = other.date`
45
+ result = @date - other
46
+ if result.is_a? ::Time
47
+ ::DateTime.wrap result
48
+ else
49
+ result
50
+ end
51
+ end
52
+
53
+ def new_offset(offset)
54
+ new_date = clone
55
+ offset = Time._parse_offset(offset)
56
+ `new_date.date.timezone = offset`
57
+ new_date
58
+ end
59
+
60
+ def to_datetime
61
+ self
62
+ end
63
+
64
+ def to_time
65
+ @date.dup
66
+ end
67
+
68
+ def to_date
69
+ Date.new(year, month, day)
70
+ end
71
+ end
@@ -0,0 +1,28 @@
1
+ class Date
2
+ def self.def_formatter(*args, **kwargs)
3
+ Time.def_formatter(*args, **kwargs, on: self)
4
+ end
5
+
6
+ def_formatter :asctime, '%c'
7
+ alias ctime asctime
8
+ def_formatter :iso8601, '%F'
9
+ alias xmlschema iso8601
10
+ def_formatter :rfc3339, '%FT%T%:z'
11
+ def_formatter :rfc2822, '%a, %-d %b %Y %T %z'
12
+ alias rfc822 rfc2822
13
+ def_formatter :httpdate, '%a, %d %b %Y %T GMT', utc: true
14
+ def_formatter :jisx0301, '%J'
15
+
16
+ alias to_s iso8601
17
+ end
18
+
19
+ class DateTime < Date
20
+ def_formatter :xmlschema, '%FT%T', fractions: true, tz_format: '%:z'
21
+ alias iso8601 xmlschema
22
+ alias rfc3339 xmlschema
23
+ def_formatter :jisx0301, '%JT%T', fractions: true, tz_format: '%:z'
24
+
25
+ alias to_s xmlschema
26
+
27
+ def_formatter :zone, '%:z'
28
+ end
@@ -0,0 +1,73 @@
1
+ class Date
2
+ class Infinity < Numeric
3
+ include Comparable
4
+
5
+ def initialize(d = 1)
6
+ @d = d <=> 0
7
+ end
8
+
9
+ attr_reader :d
10
+
11
+ def zero?
12
+ false
13
+ end
14
+
15
+ def finite?
16
+ false
17
+ end
18
+
19
+ def infinite?
20
+ d.nonzero?
21
+ end
22
+
23
+ def nan?
24
+ d.zero?
25
+ end
26
+
27
+ def abs
28
+ self.class.new
29
+ end
30
+
31
+ def -@
32
+ self.class.new(-d)
33
+ end
34
+
35
+ def +@
36
+ self.class.new(+d)
37
+ end
38
+
39
+ def <=>(other)
40
+ case other
41
+ when Infinity
42
+ d <=> other.d
43
+ when Numeric
44
+ d
45
+ else
46
+ begin
47
+ l, r = other.coerce(self)
48
+ l <=> r
49
+ rescue NoMethodError
50
+ nil
51
+ end
52
+ end
53
+ end
54
+
55
+ def coerce(other)
56
+ case other
57
+ when Numeric
58
+ [-d, d]
59
+ else
60
+ super
61
+ end
62
+ end
63
+
64
+ def to_f
65
+ return 0 if @d == 0
66
+ if @d > 0
67
+ Float::INFINITY
68
+ else
69
+ -Float::INFINITY
70
+ end
71
+ end
72
+ end
73
+ end