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
@@ -1,71 +1,46 @@
1
1
  require 'lib/spec_helper'
2
+ require 'support/rewriters_helper'
2
3
 
3
4
  RSpec.describe Opal::Rewriters::BinaryOperatorAssignment do
4
- def s(type, *children)
5
- ::Opal::AST::Node.new(type, children)
6
- end
7
-
8
- let(:rewriter) { Opal::Rewriters::BinaryOperatorAssignment.new }
5
+ include RewritersHelper
9
6
 
10
- def parse(source)
11
- parser = Opal::Parser.default_parser
12
- buffer = ::Opal::Parser::SourceBuffer.new('(eval)')
13
- buffer.source = source
14
- parser.parse(buffer)
15
- end
16
-
17
- def rewrite(ast)
18
- rewriter.process(ast)
19
- end
7
+ use_only_described_rewriter!
20
8
 
21
- around(:each) do |e|
22
- Opal::Rewriters::BinaryOperatorAssignment.reset_tmp_counter!
23
- Opal::Rewriter.disable { e.run }
24
- end
9
+ before(:each) { Opal::Rewriters::BinaryOperatorAssignment.reset_tmp_counter! }
25
10
  let(:cache_tmp_name) { :$binary_op_recvr_tmp_1 }
26
11
  let(:cached) { s(:js_tmp, cache_tmp_name) }
27
12
 
28
- shared_examples 'it rewrites' do |from, to|
29
- it "rewrites #{from.inspect} to #{to.inspect}" do
30
- input = parse(from)
31
- rewritten = rewrite(input)
32
- expected = parse(to)
33
-
34
- expect(rewritten).to eq(expected)
35
- end
36
- end
37
-
38
13
  context 'rewriting or_asgn and and_asgn nodes' do
39
14
  context 'local variable' do
40
- include_examples 'it rewrites', 'a = 1; a += 2', 'a = 1; a = a + 2'
15
+ include_examples 'it rewrites source-to-source', 'a = 1; a += 2', 'a = 1; a = a + 2'
41
16
  end
42
17
 
43
18
  context 'instance variable' do
44
- include_examples 'it rewrites', '@a += 1', '@a = @a + 1'
19
+ include_examples 'it rewrites source-to-source', '@a += 1', '@a = @a + 1'
45
20
  end
46
21
 
47
22
  context 'constant' do
48
- include_examples 'it rewrites', 'CONST += 1', 'CONST = CONST + 1'
23
+ include_examples 'it rewrites source-to-source', 'CONST += 1', 'CONST = CONST + 1'
49
24
  end
50
25
 
51
26
  context 'global variable' do
52
- include_examples 'it rewrites', '$g += 1', '$g = $g + 1'
27
+ include_examples 'it rewrites source-to-source', '$g += 1', '$g = $g + 1'
53
28
  end
54
29
 
55
30
  context 'class variable' do
56
- include_examples 'it rewrites', '@@a += 1', '@@a = @@a + 1'
31
+ include_examples 'it rewrites source-to-source', '@@a += 1', '@@a = @@a + 1'
57
32
  end
58
33
 
59
34
  context 'simple method call' do
60
- include_examples 'it rewrites', 'recvr = 1; recvr.meth += rhs', 'recvr = 1; recvr.meth = recvr.meth + rhs'
35
+ include_examples 'it rewrites source-to-source', 'recvr = 1; recvr.meth += rhs', 'recvr = 1; recvr.meth = recvr.meth + rhs'
61
36
  end
62
37
 
63
38
  context '[] / []= method call' do
64
- include_examples 'it rewrites', 'recvr = 1; recvr[idx] += rhs', 'recvr = 1; recvr[idx] = recvr[idx] + rhs'
39
+ include_examples 'it rewrites source-to-source', 'recvr = 1; recvr[idx] += rhs', 'recvr = 1; recvr[idx] = recvr[idx] + rhs'
65
40
  end
66
41
 
67
42
  context '[] / []= method call with multiple arguments' do
68
- include_examples 'it rewrites',
43
+ include_examples 'it rewrites source-to-source',
69
44
  'recvr = 1; recvr[idx1, idx2] += rhs',
70
45
  'recvr = 1; recvr[idx1, idx2] = recvr[idx1, idx2] + rhs'
71
46
  end
@@ -73,15 +48,15 @@ RSpec.describe Opal::Rewriters::BinaryOperatorAssignment do
73
48
  context 'chain of method calls' do
74
49
  it 'rewrites += by caching receiver to a temporary local variable' do
75
50
  input = parse('recvr.a.b += rhs')
76
- rewritten = rewrite(input)
51
+ rewritten = rewrite(input).children.first
77
52
 
78
53
  expected = s(:begin,
79
- s(:lvasgn, cache_tmp_name, parse('recvr.a')), # cached = recvr.a
54
+ s(:lvasgn, cache_tmp_name, ast_of('recvr.a')), # cached = recvr.a
80
55
  s(:send, cached, :b=,
81
56
  s(:send,
82
57
  s(:send, cached, :b),
83
58
  :+,
84
- parse('rhs'))))
59
+ ast_of('rhs'))))
85
60
 
86
61
  expect(rewritten).to eq(expected)
87
62
  end
@@ -90,19 +65,19 @@ RSpec.describe Opal::Rewriters::BinaryOperatorAssignment do
90
65
  context 'method call using safe nafigator' do
91
66
  it 'rewrites += by caching receiver and rewriting it to if and or_asgn' do
92
67
  input = parse('recvr&.meth += rhs')
93
- rewritten = rewrite(input)
68
+ rewritten = rewrite(input).children.first
94
69
 
95
70
  expected = s(:begin,
96
- s(:lvasgn, cache_tmp_name, parse('recvr')), # cached = recvr
97
- s(:if, s(:send, cached, :nil?), # if cached.nil?
98
- s(:nil), # nil
99
- # else
100
- s(:send, cached, :meth=, # cached.meth =
71
+ s(:lvasgn, cache_tmp_name, ast_of('recvr')), # cached = recvr
72
+ s(:if, s(:send, cached, :nil?), # if cached.nil?
73
+ s(:nil), # nil
74
+ # else
75
+ s(:send, cached, :meth=, # cached.meth =
101
76
  s(:send,
102
- s(:send, cached, :meth), # cached.meth +
77
+ s(:send, cached, :meth), # cached.meth +
103
78
  :+,
104
- parse('rhs'))) # rhs
105
- )) # end
79
+ ast_of('rhs'))) # rhs
80
+ )) # end
106
81
 
107
82
  expect(rewritten).to eq(expected)
108
83
  end
@@ -111,43 +86,43 @@ RSpec.describe Opal::Rewriters::BinaryOperatorAssignment do
111
86
 
112
87
  context 'rewriting defined?(or_asgn) and defined?(and_asgn)' do
113
88
  context 'local variable' do
114
- include_examples 'it rewrites', 'a = nil; defined?(a += 1)', 'a = nil; "assignment"'
89
+ include_examples 'it rewrites source-to-source', 'a = nil; defined?(a += 1)', 'a = nil; "assignment"'
115
90
  end
116
91
 
117
92
  context 'instance variable' do
118
- include_examples 'it rewrites', 'defined?(@a += 1)', %q("assignment")
93
+ include_examples 'it rewrites source-to-source', 'defined?(@a += 1)', %q("assignment")
119
94
  end
120
95
 
121
96
  context 'constant' do
122
- include_examples 'it rewrites', 'defined?(CONST += 1)', %q("assignment")
97
+ include_examples 'it rewrites source-to-source', 'defined?(CONST += 1)', %q("assignment")
123
98
  end
124
99
 
125
100
  context 'global variable' do
126
- include_examples 'it rewrites', 'defined?($g += 1)', %q("assignment")
101
+ include_examples 'it rewrites source-to-source', 'defined?($g += 1)', %q("assignment")
127
102
  end
128
103
 
129
104
  context 'class variable' do
130
- include_examples 'it rewrites', 'defined?(@@a += 1)', %q("assignment")
105
+ include_examples 'it rewrites source-to-source', 'defined?(@@a += 1)', %q("assignment")
131
106
  end
132
107
 
133
108
  context 'simple method call' do
134
- include_examples 'it rewrites', 'defined?(recvr.meth += rhs)', %q("assignment")
109
+ include_examples 'it rewrites source-to-source', 'defined?(recvr.meth += rhs)', %q("assignment")
135
110
  end
136
111
 
137
112
  context '[] / []= method call' do
138
- include_examples 'it rewrites', 'defined?(recvr[idx] += rhs)', %q("assignment")
113
+ include_examples 'it rewrites source-to-source', 'defined?(recvr[idx] += rhs)', %q("assignment")
139
114
  end
140
115
 
141
116
  context '[] / []= method call with multiple arguments' do
142
- include_examples 'it rewrites', 'defined?(recvr[idx1, idx2] += rhs)', %q("assignment")
117
+ include_examples 'it rewrites source-to-source', 'defined?(recvr[idx1, idx2] += rhs)', %q("assignment")
143
118
  end
144
119
 
145
120
  context 'chain of method calls' do
146
- include_examples 'it rewrites', 'defined?(recvr.a.b.c += rhs)', %q("assignment")
121
+ include_examples 'it rewrites source-to-source', 'defined?(recvr.a.b.c += rhs)', %q("assignment")
147
122
  end
148
123
 
149
124
  context 'method call using safe nafigator' do
150
- include_examples 'it rewrites', 'defined?(recvr&.meth += rhs)', %q("assignment")
125
+ include_examples 'it rewrites source-to-source', 'defined?(recvr&.meth += rhs)', %q("assignment")
151
126
  end
152
127
  end
153
128
  end
@@ -1,11 +1,8 @@
1
1
  require 'lib/spec_helper'
2
+ require 'support/rewriters_helper'
2
3
 
3
4
  RSpec.describe Opal::Rewriters::BlockToIter do
4
- def s(type, *children)
5
- ::Opal::AST::Node.new(type, children)
6
- end
7
-
8
- let(:rewriter) { Opal::Rewriters::BlockToIter.new }
5
+ include RewritersHelper
9
6
 
10
7
  let(:block_node) do
11
8
  # m { |arg1| 1 }
@@ -23,6 +20,6 @@ RSpec.describe Opal::Rewriters::BlockToIter do
23
20
  end
24
21
 
25
22
  it 'rewriters s(:block) to s(:iter)' do
26
- expect(rewriter.process(block_node)).to eq(iter_node)
23
+ expect(rewritten(block_node)).to eq(iter_node)
27
24
  end
28
25
  end
@@ -1,11 +1,8 @@
1
1
  require 'lib/spec_helper'
2
+ require 'support/rewriters_helper'
2
3
 
3
4
  RSpec.describe Opal::Rewriters::DotJsSyntax do
4
- def s(type, *children)
5
- ::Opal::AST::Node.new(type, children)
6
- end
7
-
8
- let(:rewriter) { Opal::Rewriters::DotJsSyntax.new }
5
+ include RewritersHelper
9
6
 
10
7
  context '.JS. syntax' do
11
8
  let(:send_node) do
@@ -4,7 +4,6 @@ require 'opal/rewriters/for_rewriter'
4
4
 
5
5
  RSpec.describe Opal::Rewriters::ForRewriter do
6
6
  include RewritersHelper
7
- extend RewritersHelper
8
7
 
9
8
  before(:each) { Opal::Rewriters::ForRewriter.reset_tmp_counter! }
10
9
 
@@ -4,7 +4,6 @@ require 'opal/rewriters/forward_args'
4
4
 
5
5
  RSpec.describe Opal::Rewriters::ForwardArgs do
6
6
  include RewritersHelper
7
- extend RewritersHelper
8
7
 
9
8
  before(:each) { Opal::Rewriters::ForRewriter.reset_tmp_counter! }
10
9
 
@@ -23,7 +22,7 @@ RSpec.describe Opal::Rewriters::ForwardArgs do
23
22
  end
24
23
  end
25
24
 
26
- include_examples 'it rewrites source-to-AST', <<~ENDSOURCE, correct_names.(parse(<<~ENDDEST))
25
+ include_examples 'it rewrites source-to-AST', <<~ENDSOURCE, correct_names.(ast_of(<<~ENDDEST))
27
26
  def forward(...)
28
27
  other(...)
29
28
  end
@@ -33,7 +32,7 @@ RSpec.describe Opal::Rewriters::ForwardArgs do
33
32
  end
34
33
  ENDDEST
35
34
 
36
- include_examples 'it rewrites source-to-AST', <<~ENDSOURCE, correct_names.(parse(<<~ENDDEST))
35
+ include_examples 'it rewrites source-to-AST', <<~ENDSOURCE, correct_names.(ast_of(<<~ENDDEST))
37
36
  def forward(first_arg, ...)
38
37
  other(first_arg, second_arg, ...)
39
38
  other(other_arg, ...)
@@ -1,21 +1,8 @@
1
1
  require 'lib/spec_helper'
2
+ require 'support/rewriters_helper'
2
3
 
3
4
  RSpec.describe Opal::Rewriters::JsReservedWords do
4
- def s(type, *children)
5
- ::Opal::AST::Node.new(type, children)
6
- end
7
-
8
- def rewrite(sexp)
9
- Opal::Rewriters::JsReservedWords.new.process(sexp)
10
- end
11
-
12
- def expect_rewritten(sexp)
13
- expect(rewrite(sexp))
14
- end
15
-
16
- def expect_no_rewriting_for(sexp)
17
- expect_rewritten(sexp).to eq(sexp)
18
- end
5
+ include RewritersHelper
19
6
 
20
7
  reserved_lvars = %i(
21
8
  do if in for let new try var case else enum eval false
@@ -1,82 +1,57 @@
1
1
  require 'lib/spec_helper'
2
+ require 'support/rewriters_helper'
2
3
 
3
4
  RSpec.describe Opal::Rewriters::LogicalOperatorAssignment do
4
- def s(type, *children)
5
- ::Opal::AST::Node.new(type, children)
6
- end
7
-
8
- let(:rewriter) { Opal::Rewriters::LogicalOperatorAssignment.new }
5
+ include RewritersHelper
9
6
 
10
- def parse(source)
11
- parser = Opal::Parser.default_parser
12
- buffer = ::Opal::Parser::SourceBuffer.new('(eval)')
13
- buffer.source = source
14
- parser.parse(buffer)
15
- end
16
-
17
- def rewrite(ast)
18
- rewriter.process(ast)
19
- end
7
+ use_only_described_rewriter!
20
8
 
21
- around(:each) do |e|
22
- Opal::Rewriters::LogicalOperatorAssignment.reset_tmp_counter!
23
- Opal::Rewriter.disable { e.run }
24
- end
9
+ before(:each) { Opal::Rewriters::LogicalOperatorAssignment.reset_tmp_counter! }
25
10
  let(:cache_tmp_name) { :$logical_op_recvr_tmp_1 }
26
11
  let(:cached) { s(:js_tmp, cache_tmp_name) }
27
12
 
28
- shared_examples 'it rewrites' do |from, to|
29
- it "rewrites #{from.inspect} to #{to.inspect}" do
30
- input = parse(from)
31
- rewritten = rewrite(input)
32
- expected = parse(to)
33
-
34
- expect(rewritten).to eq(expected)
35
- end
36
- end
37
-
38
13
  context 'rewriting or_asgn and and_asgn nodes' do
39
14
  context 'local variable' do
40
- include_examples 'it rewrites', 'a = local; a ||= 1', 'a = local; a = a || 1'
41
- include_examples 'it rewrites', 'a = local; a &&= 1', 'a = local; a = a && 1'
15
+ include_examples 'it rewrites source-to-source', 'a = local; a ||= 1', 'a = local; a = a || 1'
16
+ include_examples 'it rewrites source-to-source', 'a = local; a &&= 1', 'a = local; a = a && 1'
42
17
  end
43
18
 
44
19
  context 'instance variable' do
45
- include_examples 'it rewrites', '@a ||= 1', '@a = @a || 1'
46
- include_examples 'it rewrites', '@a &&= 1', '@a = @a && 1'
20
+ include_examples 'it rewrites source-to-source', '@a ||= 1', '@a = @a || 1'
21
+ include_examples 'it rewrites source-to-source', '@a &&= 1', '@a = @a && 1'
47
22
  end
48
23
 
49
24
  context 'constant' do
50
- include_examples 'it rewrites', 'CONST ||= 1', 'CONST = defined?(CONST) ? (CONST || 1) : 1'
51
- include_examples 'it rewrites', 'CONST &&= 1', 'CONST = CONST && 1'
25
+ include_examples 'it rewrites source-to-source', 'CONST ||= 1', 'CONST = defined?(CONST) ? (CONST || 1) : 1'
26
+ include_examples 'it rewrites source-to-source', 'CONST &&= 1', 'CONST = CONST && 1'
52
27
  end
53
28
 
54
29
  context 'global variable' do
55
- include_examples 'it rewrites', '$g ||= 1', '$g = $g || 1'
56
- include_examples 'it rewrites', '$g &&= 1', '$g = $g && 1'
30
+ include_examples 'it rewrites source-to-source', '$g ||= 1', '$g = $g || 1'
31
+ include_examples 'it rewrites source-to-source', '$g &&= 1', '$g = $g && 1'
57
32
  end
58
33
 
59
34
  context 'class variable' do
60
- include_examples 'it rewrites', '@@a ||= 1', '@@a = defined?(@@a) ? (@@a || 1) : 1'
61
- include_examples 'it rewrites', '@@a &&= 1', '@@a = @@a && 1'
35
+ include_examples 'it rewrites source-to-source', '@@a ||= 1', '@@a = defined?(@@a) ? (@@a || 1) : 1'
36
+ include_examples 'it rewrites source-to-source', '@@a &&= 1', '@@a = @@a && 1'
62
37
  end
63
38
 
64
39
  context 'simple method call' do
65
- include_examples 'it rewrites', 'recvr = 1; recvr.meth ||= rhs', 'recvr = 1; recvr.meth || recvr.meth = rhs'
66
- include_examples 'it rewrites', 'recvr = 1; recvr.meth &&= rhs', 'recvr = 1; recvr.meth && recvr.meth = rhs'
40
+ include_examples 'it rewrites source-to-source', 'recvr = 1; recvr.meth ||= rhs', 'recvr = 1; recvr.meth || recvr.meth = rhs'
41
+ include_examples 'it rewrites source-to-source', 'recvr = 1; recvr.meth &&= rhs', 'recvr = 1; recvr.meth && recvr.meth = rhs'
67
42
  end
68
43
 
69
44
  context '[] / []= method call' do
70
- include_examples 'it rewrites', 'recvr = 1; recvr[idx] ||= rhs', 'recvr = 1; recvr[idx] || recvr[idx] = rhs'
71
- include_examples 'it rewrites', 'recvr = 1; recvr[idx] &&= rhs', 'recvr = 1; recvr[idx] && recvr[idx] = rhs'
45
+ include_examples 'it rewrites source-to-source', 'recvr = 1; recvr[idx] ||= rhs', 'recvr = 1; recvr[idx] || recvr[idx] = rhs'
46
+ include_examples 'it rewrites source-to-source', 'recvr = 1; recvr[idx] &&= rhs', 'recvr = 1; recvr[idx] && recvr[idx] = rhs'
72
47
  end
73
48
 
74
49
  context '[] / []= method call with multiple arguments' do
75
- include_examples 'it rewrites',
50
+ include_examples 'it rewrites source-to-source',
76
51
  'recvr = 1; recvr[idx1, idx2] ||= rhs',
77
52
  'recvr = 1; recvr[idx1, idx2] || recvr[idx1, idx2] = rhs'
78
53
 
79
- include_examples 'it rewrites',
54
+ include_examples 'it rewrites source-to-source',
80
55
  'recvr = 1; recvr[idx1, idx2] &&= rhs',
81
56
  'recvr = 1; recvr[idx1, idx2] && recvr[idx1, idx2] = rhs'
82
57
  end
@@ -84,26 +59,26 @@ RSpec.describe Opal::Rewriters::LogicalOperatorAssignment do
84
59
  context 'chain of method calls' do
85
60
  it 'rewrites ||= by caching receiver to a temporary local variable' do
86
61
  input = parse('recvr.a.b ||= rhs')
87
- rewritten = rewrite(input)
62
+ rewritten = rewrite(input).children.first
88
63
 
89
64
  expected = s(:begin,
90
- s(:lvasgn, cache_tmp_name, parse('recvr.a')), # cached = recvr.a
65
+ s(:lvasgn, cache_tmp_name, ast_of('recvr.a')), # cached = recvr.a
91
66
  s(:or,
92
- s(:send, cached, :b), # cached.b
93
- s(:send, cached, :b=, parse('rhs')))) # cached.b = rhs
67
+ s(:send, cached, :b), # cached.b ||
68
+ s(:send, cached, :b=, ast_of('rhs')))) # cached.b = rhs
94
69
 
95
70
  expect(rewritten).to eq(expected)
96
71
  end
97
72
 
98
73
  it 'rewrites &&= by caching receiver to a temporary local variable' do
99
74
  input = parse('recvr.a.b &&= rhs')
100
- rewritten = rewrite(input)
75
+ rewritten = rewrite(input).children.first
101
76
 
102
77
  expected = s(:begin,
103
- s(:lvasgn, cache_tmp_name, parse('recvr.a')), # cached = recvr.a
78
+ s(:lvasgn, cache_tmp_name, ast_of('recvr.a')), # cached = recvr.a
104
79
  s(:and,
105
- s(:send, cached, :b), # cached.b
106
- s(:send, cached, :b=, parse('rhs')))) # cached.b = rhs
80
+ s(:send, cached, :b), # cached.b ||
81
+ s(:send, cached, :b=, ast_of('rhs')))) # cached.b = rhs
107
82
 
108
83
  expect(rewritten).to eq(expected)
109
84
  end
@@ -112,17 +87,17 @@ RSpec.describe Opal::Rewriters::LogicalOperatorAssignment do
112
87
  context 'method call using safe nafigator' do
113
88
  it 'rewrites ||= by caching receiver and rewriting it to if and or_asgn' do
114
89
  input = parse('recvr&.meth ||= rhs')
115
- rewritten = rewrite(input)
90
+ rewritten = rewrite(input).children.first
116
91
 
117
92
  expected = s(:begin,
118
- s(:lvasgn, cache_tmp_name, parse('recvr')), # cached = recvr
119
- s(:if, s(:send, cached, :nil?), # if cached.nil?
120
- s(:nil), # nil
121
- # else
93
+ s(:lvasgn, cache_tmp_name, ast_of('recvr')), # cached = recvr
94
+ s(:if, s(:send, cached, :nil?), # if cached.nil?
95
+ s(:nil), # nil
96
+ # else
122
97
  s(:or,
123
- s(:send, cached, :meth), # cached.meth ||
124
- s(:send, cached, :meth=, parse('rhs'))) # cached.meth = rhs
125
- ) # end
98
+ s(:send, cached, :meth), # cached.meth ||
99
+ s(:send, cached, :meth=, ast_of('rhs'))) # cached.meth = rhs
100
+ ) # end
126
101
  )
127
102
 
128
103
  expect(rewritten).to eq(expected)
@@ -130,17 +105,17 @@ RSpec.describe Opal::Rewriters::LogicalOperatorAssignment do
130
105
 
131
106
  it 'rewrites &&= by caching receiver and rewriting it to if and or_asgn' do
132
107
  input = parse('recvr&.meth &&= rhs')
133
- rewritten = rewrite(input)
108
+ rewritten = rewrite(input).children.first
134
109
 
135
110
  expected = s(:begin,
136
- s(:lvasgn, cache_tmp_name, parse('recvr')), # cached = recvr
137
- s(:if, s(:send, cached, :nil?), # if cached.nil?
138
- s(:nil), # nil
139
- # else
111
+ s(:lvasgn, cache_tmp_name, ast_of('recvr')), # cached = recvr
112
+ s(:if, s(:send, cached, :nil?), # if cached.nil?
113
+ s(:nil), # nil
114
+ # else
140
115
  s(:and,
141
- s(:send, cached, :meth), # cached.meth ||
142
- s(:send, cached, :meth=, parse('rhs'))) # cached.meth = rhs
143
- ) # end
116
+ s(:send, cached, :meth), # cached.meth &&
117
+ s(:send, cached, :meth=, ast_of('rhs'))) # cached.meth = rhs
118
+ ) # end
144
119
  )
145
120
 
146
121
  expect(rewritten).to eq(expected)
@@ -150,53 +125,53 @@ RSpec.describe Opal::Rewriters::LogicalOperatorAssignment do
150
125
 
151
126
  context 'rewriting defined?(or_asgn) and defined?(and_asgn)' do
152
127
  context 'local variable' do
153
- include_examples 'it rewrites', 'a = nil; defined?(a ||= 1)', 'a = nil; "assignment"'
154
- include_examples 'it rewrites', 'a = nil; defined?(a &&= 1)', 'a = nil; "assignment"'
128
+ include_examples 'it rewrites source-to-source', 'a = nil; defined?(a ||= 1)', 'a = nil; "assignment"'
129
+ include_examples 'it rewrites source-to-source', 'a = nil; defined?(a &&= 1)', 'a = nil; "assignment"'
155
130
  end
156
131
 
157
132
  context 'instance variable' do
158
- include_examples 'it rewrites', 'defined?(@a ||= 1)', %q("assignment")
159
- include_examples 'it rewrites', 'defined?(@a &&= 1)', %q("assignment")
133
+ include_examples 'it rewrites source-to-source', 'defined?(@a ||= 1)', %q("assignment")
134
+ include_examples 'it rewrites source-to-source', 'defined?(@a &&= 1)', %q("assignment")
160
135
  end
161
136
 
162
137
  context 'constant' do
163
- include_examples 'it rewrites', 'defined?(CONST ||= 1)', %q("assignment")
164
- include_examples 'it rewrites', 'defined?(CONST &&= 1)', %q("assignment")
138
+ include_examples 'it rewrites source-to-source', 'defined?(CONST ||= 1)', %q("assignment")
139
+ include_examples 'it rewrites source-to-source', 'defined?(CONST &&= 1)', %q("assignment")
165
140
  end
166
141
 
167
142
  context 'global variable' do
168
- include_examples 'it rewrites', 'defined?($g ||= 1)', %q("assignment")
169
- include_examples 'it rewrites', 'defined?($g &&= 1)', %q("assignment")
143
+ include_examples 'it rewrites source-to-source', 'defined?($g ||= 1)', %q("assignment")
144
+ include_examples 'it rewrites source-to-source', 'defined?($g &&= 1)', %q("assignment")
170
145
  end
171
146
 
172
147
  context 'class variable' do
173
- include_examples 'it rewrites', 'defined?(@@a ||= 1)', %q("assignment")
174
- include_examples 'it rewrites', 'defined?(@@a &&= 1)', %q("assignment")
148
+ include_examples 'it rewrites source-to-source', 'defined?(@@a ||= 1)', %q("assignment")
149
+ include_examples 'it rewrites source-to-source', 'defined?(@@a &&= 1)', %q("assignment")
175
150
  end
176
151
 
177
152
  context 'simple method call' do
178
- include_examples 'it rewrites', 'defined?(recvr.meth ||= rhs)', %q("assignment")
179
- include_examples 'it rewrites', 'defined?(recvr.meth &&= rhs)', %q("assignment")
153
+ include_examples 'it rewrites source-to-source', 'defined?(recvr.meth ||= rhs)', %q("assignment")
154
+ include_examples 'it rewrites source-to-source', 'defined?(recvr.meth &&= rhs)', %q("assignment")
180
155
  end
181
156
 
182
157
  context '[] / []= method call' do
183
- include_examples 'it rewrites', 'defined?(recvr[idx] ||= rhs)', %q("assignment")
184
- include_examples 'it rewrites', 'defined?(recvr[idx] &&= rhs)', %q("assignment")
158
+ include_examples 'it rewrites source-to-source', 'defined?(recvr[idx] ||= rhs)', %q("assignment")
159
+ include_examples 'it rewrites source-to-source', 'defined?(recvr[idx] &&= rhs)', %q("assignment")
185
160
  end
186
161
 
187
162
  context '[] / []= method call with multiple arguments' do
188
- include_examples 'it rewrites', 'defined?(recvr[idx1, idx2] ||= rhs)', %q("assignment")
189
- include_examples 'it rewrites', 'defined?(recvr[idx1, idx2] &&= rhs)', %q("assignment")
163
+ include_examples 'it rewrites source-to-source', 'defined?(recvr[idx1, idx2] ||= rhs)', %q("assignment")
164
+ include_examples 'it rewrites source-to-source', 'defined?(recvr[idx1, idx2] &&= rhs)', %q("assignment")
190
165
  end
191
166
 
192
167
  context 'chain of method calls' do
193
- include_examples 'it rewrites', 'defined?(recvr.a.b.c ||= rhs)', %q("assignment")
194
- include_examples 'it rewrites', 'defined?(recvr.a.b.c &&= rhs)', %q("assignment")
168
+ include_examples 'it rewrites source-to-source', 'defined?(recvr.a.b.c ||= rhs)', %q("assignment")
169
+ include_examples 'it rewrites source-to-source', 'defined?(recvr.a.b.c &&= rhs)', %q("assignment")
195
170
  end
196
171
 
197
172
  context 'method call using safe nafigator' do
198
- include_examples 'it rewrites', 'defined?(recvr&.meth ||= rhs)', %q("assignment")
199
- include_examples 'it rewrites', 'defined?(recvr&.meth &&= rhs)', %q("assignment")
173
+ include_examples 'it rewrites source-to-source', 'defined?(recvr&.meth ||= rhs)', %q("assignment")
174
+ include_examples 'it rewrites source-to-source', 'defined?(recvr&.meth &&= rhs)', %q("assignment")
200
175
  end
201
176
  end
202
177
  end
@@ -4,9 +4,7 @@ require 'opal/rewriters/numblocks'
4
4
 
5
5
  RSpec.describe Opal::Rewriters::Numblocks do
6
6
  include RewritersHelper
7
- extend RewritersHelper
8
-
9
- before(:each) { Opal::Rewriters::ForRewriter.reset_tmp_counter! }
7
+ extend RewritersHelper # s() in example scope
10
8
 
11
9
  correct_names = proc do |ast|
12
10
  case ast
@@ -22,7 +20,7 @@ RSpec.describe Opal::Rewriters::Numblocks do
22
20
  end
23
21
  end
24
22
 
25
- include_examples 'it rewrites source-to-AST', <<~ENDSOURCE, correct_names.(parse(<<~ENDDEST))
23
+ include_examples 'it rewrites source-to-AST', <<~ENDSOURCE, correct_names.(ast_of(<<~ENDDEST))
26
24
  proc do
27
25
  _1
28
26
  end
@@ -32,7 +30,7 @@ RSpec.describe Opal::Rewriters::Numblocks do
32
30
  end
33
31
  ENDDEST
34
32
 
35
- include_examples 'it rewrites source-to-AST', <<~ENDSOURCE, correct_names.(parse(<<~ENDDEST))
33
+ include_examples 'it rewrites source-to-AST', <<~ENDSOURCE, correct_names.(ast_of(<<~ENDDEST))
36
34
  proc do
37
35
  _3
38
36
  end
@@ -1,20 +1,8 @@
1
1
  require 'lib/spec_helper'
2
+ require 'support/rewriters_helper'
2
3
 
3
4
  RSpec.describe Opal::Rewriters::OpalEngineCheck do
4
- def s(type, *children)
5
- ::Opal::AST::Node.new(type, children)
6
- end
7
-
8
- let(:rewriter) { Opal::Rewriters::OpalEngineCheck.new }
9
-
10
- def expect_rewritten(node)
11
- processed = rewriter.process(node)
12
- expect(processed)
13
- end
14
-
15
- def expect_no_rewriting_for(node)
16
- expect_rewritten(node).to eq(node)
17
- end
5
+ include RewritersHelper
18
6
 
19
7
  let(:opal_str_sexp) { s(:str, 'opal') }
20
8
  let(:true_branch) { s(:int, 1) }
@@ -21,7 +21,7 @@ RSpec.describe Opal::Rubyspec::FiltersRewriter do
21
21
  SOURCE
22
22
  end
23
23
 
24
- let(:ast) { ast_of(source) }
24
+ let(:ast) { parse(source) }
25
25
 
26
26
  context 'when spec is filtered' do
27
27
  around(:each) do |e|
@@ -44,16 +44,24 @@ RSpec.describe Opal::Rubyspec::FiltersRewriter do
44
44
  SOURCE
45
45
  end
46
46
 
47
- let(:expected_ast) { ast_of(rewritten_source) }
47
+ let(:expected_ast) { parse(rewritten_source) }
48
48
 
49
49
  it 'replaces it with nil' do
50
50
  expect_rewritten(ast).to eq(expected_ast)
51
51
  end
52
+
53
+ it 'disables cache' do
54
+ expect(rewritten(ast).meta[:dynamic_cache_result]).to be_truthy
55
+ end
52
56
  end
53
57
 
54
58
  context 'when spec is not filtered' do
55
59
  it 'does not rewrite it' do
56
60
  expect_no_rewriting_for(ast)
57
61
  end
62
+
63
+ it 'disables cache' do
64
+ expect(rewritten(ast).meta[:dynamic_cache_result]).to be_truthy
65
+ end
58
66
  end
59
67
  end
@@ -33,6 +33,10 @@ describe Opal::Compiler do
33
33
  $global["Opal"].irb_vars.bar.should == "HELLO WORLD"
34
34
  end
35
35
 
36
+ it "can reference an outer variable" do
37
+ eval_js("var a = 10;" + compile("a", :irb => true)).should == 10
38
+ end
39
+
36
40
  it "can still call top level methods" do
37
41
  eval_js(compile("to_s", :irb => true)).should == "main"
38
42
  end