opal 1.4.0.alpha1 → 1.5.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.eslintrc.js +5 -3
- data/.github/workflows/build.yml +20 -18
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +98 -7
- data/UNRELEASED.md +31 -59
- data/benchmark-ips/bm_js_symbols_vs_strings.rb +39 -14
- data/docs/releasing.md +11 -4
- data/lib/opal/ast/matcher.rb +77 -0
- data/lib/opal/cache.rb +1 -1
- data/lib/opal/cli_runners/applescript.rb +2 -0
- data/lib/opal/compiler.rb +18 -9
- data/lib/opal/nodes/call.rb +73 -28
- data/lib/opal/nodes/def.rb +31 -27
- data/lib/opal/nodes/definitions.rb +2 -0
- data/lib/opal/nodes/helpers.rb +4 -23
- data/lib/opal/nodes/if.rb +226 -0
- data/lib/opal/nodes/iter.rb +41 -37
- data/lib/opal/nodes/literal.rb +2 -2
- data/lib/opal/nodes/masgn.rb +15 -17
- data/lib/opal/nodes/node_with_args/shortcuts.rb +100 -0
- data/lib/opal/nodes/node_with_args.rb +1 -0
- data/lib/opal/nodes/super.rb +9 -9
- data/lib/opal/nodes/top.rb +26 -10
- data/lib/opal/nodes/x_string.rb +27 -28
- data/lib/opal/nodes.rb +0 -1
- data/lib/opal/parser/default_config.rb +3 -2
- data/lib/opal/repl.rb +1 -1
- data/lib/opal/rewriter.rb +13 -6
- data/lib/opal/rewriters/base.rb +12 -1
- data/lib/opal/rewriters/rubyspec/filters_rewriter.rb +1 -0
- data/lib/opal/version.rb +1 -1
- data/opal/corelib/array.rb +23 -28
- data/opal/corelib/binding.rb +14 -4
- data/opal/corelib/constants.rb +3 -3
- data/opal/corelib/hash.rb +2 -2
- data/opal/corelib/irb.rb +192 -0
- data/opal/corelib/math/polyfills.rb +127 -0
- data/opal/corelib/math.rb +14 -194
- data/opal/corelib/module.rb +25 -40
- data/opal/corelib/number.rb +63 -14
- data/opal/corelib/regexp.rb +2 -0
- data/opal/corelib/runtime.js +56 -20
- data/opal/corelib/string.rb +38 -59
- data/opal/corelib/time.rb +106 -68
- data/opal/opal/full.rb +0 -1
- data/opal/opal.rb +4 -1
- data/spec/filters/bugs/date.rb +0 -3
- data/spec/filters/bugs/datetime.rb +65 -0
- data/spec/filters/bugs/float.rb +0 -18
- data/spec/filters/bugs/hash.rb +0 -2
- data/spec/filters/bugs/language.rb +0 -3
- data/spec/filters/bugs/marshal.rb +0 -1
- data/spec/filters/bugs/string.rb +0 -30
- data/spec/filters/bugs/time.rb +18 -8
- data/spec/lib/cli_spec.rb +2 -2
- data/spec/lib/compiler_spec.rb +8 -8
- data/spec/lib/rewriters/base_spec.rb +1 -1
- data/spec/lib/rewriters/binary_operator_assignment_spec.rb +34 -59
- data/spec/lib/rewriters/block_to_iter_spec.rb +3 -6
- data/spec/lib/rewriters/dot_js_syntax_spec.rb +2 -5
- data/spec/lib/rewriters/for_rewriter_spec.rb +0 -1
- data/spec/lib/rewriters/forward_args_spec.rb +2 -3
- data/spec/lib/rewriters/js_reserved_words_spec.rb +2 -15
- data/spec/lib/rewriters/logical_operator_assignment_spec.rb +64 -89
- data/spec/lib/rewriters/numblocks_spec.rb +3 -5
- data/spec/lib/rewriters/opal_engine_check_spec.rb +2 -14
- data/spec/lib/rewriters/rubyspec/filters_rewriter_spec.rb +10 -2
- data/spec/opal/compiler/irb_spec.rb +4 -0
- data/spec/opal/core/language/super_spec.rb +40 -17
- data/spec/opal/core/language/xstring_spec.rb +13 -0
- data/spec/opal/core/regexp/assertions_spec.rb +19 -0
- data/spec/opal/core/string/to_proc_spec.rb +19 -0
- data/spec/ruby_specs +4 -0
- data/spec/support/rewriters_helper.rb +43 -23
- data/stdlib/date/date_time.rb +71 -0
- data/stdlib/date/formatters.rb +28 -0
- data/stdlib/date/infinity.rb +73 -0
- data/stdlib/date.rb +77 -214
- data/stdlib/opal/repl_js.rb +1 -1
- data/stdlib/{opal/replutils.rb → opal-replutils.rb} +3 -3
- data/stdlib/promise/v2.rb +0 -7
- data/stdlib/time.rb +39 -2
- data/stdlib/uri.rb +53 -0
- data/tasks/performance/asciidoctor_test.rb.erb +3 -1
- data/tasks/performance/optimization_status.rb +3 -2
- data/tasks/performance.rake +69 -35
- data/tasks/testing.rake +1 -0
- data/test/opal/test_uri.rb +35 -0
- data/yarn.lock +27 -5
- metadata +30 -16
- data/lib/opal/nodes/csend.rb +0 -24
- data/lib/opal/rewriters/explicit_writer_return.rb +0 -59
- data/spec/lib/rewriters/explicit_writer_return_spec.rb +0 -186
- data/stdlib/nodejs/irb.rb +0 -43
data/spec/filters/bugs/time.rb
CHANGED
@@ -25,7 +25,6 @@ opal_filter "Time" do
|
|
25
25
|
fails "Time#getlocal with a timezone argument subject's class implements .find_timezone method does not call .find_timezone if passed any not string/numeric/timezone timezone argument" # Expected TypeError (/can't convert \w+ into an exact number/) but got: NoMethodError (undefined method `getlocal' for 2000-01-01 12:00:00 UTC)
|
26
26
|
fails "Time#gmtime converts self to UTC, modifying the receiver" # Expected 2007-01-09 03:00:00 UTC to equal 2007-01-09 12:00:00 UTC
|
27
27
|
fails "Time#hash returns an Integer" # Expected "Time:100000" (String) to be an instance of Integer
|
28
|
-
fails "Time#inspect formats the fixed offset time following the pattern 'yyyy-MM-dd HH:mm:ss +/-HHMM'"
|
29
28
|
fails "Time#inspect omits trailing zeros from microseconds" # Expected "2007-11-01 15:25:00 UTC" == "2007-11-01 15:25:00.1 UTC" to be truthy but was false
|
30
29
|
fails "Time#inspect preserves microseconds" # Expected "2007-11-01 15:25:00 UTC" == "2007-11-01 15:25:00.123456 UTC" to be truthy but was false
|
31
30
|
fails "Time#inspect preserves nanoseconds" # Expected "2007-11-01 15:25:00 UTC" == "2007-11-01 15:25:00.123456789 UTC" to be truthy but was false
|
@@ -44,7 +43,6 @@ opal_filter "Time" do
|
|
44
43
|
fails "Time#strftime should be able to show default Logger format" # Expected "2001-12-03T04:05:06.000000 " == "2001-12-03T04:05:06.100000 " to be truthy but was false
|
45
44
|
fails "Time#strftime should be able to show the commercial week day"
|
46
45
|
fails "Time#strftime should be able to show the number of seconds since the unix epoch" # fails under FIJI et al TZs
|
47
|
-
fails "Time#strftime should be able to show the timezone if available"
|
48
46
|
fails "Time#strftime should be able to show the timezone of the date with a : separator"
|
49
47
|
fails "Time#strftime should be able to show the week number with the week starting on Sunday (%U) and Monday (%W)"
|
50
48
|
fails "Time#strftime with %N formats the microseconds of the second with %6N"
|
@@ -53,9 +51,13 @@ opal_filter "Time" do
|
|
53
51
|
fails "Time#strftime with %N formats the nanoseconds of the second with %N"
|
54
52
|
fails "Time#strftime with %N formats the picoseconds of the second with %12N"
|
55
53
|
fails "Time#subsec returns 0 as an Integer for a Time with a whole number of seconds" # NoMethodError: undefined method `subsec' for 1970-01-01 01:01:40 +0100
|
54
|
+
fails "Time#to_date yields accurate julian date for Julian-Gregorian gap value" # Expected 2299170 == 2299160 to be truthy but was false
|
55
|
+
fails "Time#to_date yields accurate julian date for ambiguous pre-Gregorian reform value" # Expected 2299160 == 2299150 to be truthy but was false
|
56
|
+
fails "Time#to_date yields accurate julian date for post-Gregorian reform value" # Expected 2299171 == 2299161 to be truthy but was false
|
57
|
+
fails "Time#to_date yields same julian day regardless of UTC time value" # Expected 2299171 == 2299161 to be truthy but was false
|
58
|
+
fails "Time#to_date yields same julian day regardless of local time or zone" # Expected 2299171 == 2299161 to be truthy but was false
|
56
59
|
fails "Time#to_f returns the float number of seconds + usecs since the epoch"
|
57
60
|
fails "Time#to_i rounds fractional seconds toward zero" # Expected -315619200 == -315619199 to be truthy but was false
|
58
|
-
fails "Time#to_s formats the fixed offset time following the pattern 'yyyy-MM-dd HH:mm:ss +/-HHMM'"
|
59
61
|
fails "Time#tv_sec rounds fractional seconds toward zero" # Expected -315619200 == -315619199 to be truthy but was false
|
60
62
|
fails "Time#usec returns a positive value for dates before the epoch" # Expected 0 to equal 404240
|
61
63
|
fails "Time#utc converts self to UTC, modifying the receiver" # Expected 2007-01-09 03:00:00 UTC to equal 2007-01-09 12:00:00 UTC
|
@@ -77,6 +79,7 @@ opal_filter "Time" do
|
|
77
79
|
fails "Time.at passed non-Time, non-Numeric with an argument that responds to #to_r needs for the argument to respond to #to_int too" # Mock 'rational-but-no-to_int' expected to receive to_r("any_args") exactly 1 times but received it 0 times
|
78
80
|
fails "Time.gm handles fractional usec close to rounding limit" # NoMethodError: undefined method `nsec' for 2000-01-01 12:30:00 UTC:Time
|
79
81
|
fails "Time.gm raises an ArgumentError for out of range microsecond" # Expected ArgumentError but no exception was raised (2000-01-01 20:15:01 UTC was returned)
|
82
|
+
fails "Time.httpdate parses RFC-2616 strings" # NoMethodError: undefined method `httpdate' for Time
|
80
83
|
fails "Time.local raises an ArgumentError for out of range microsecond" # Expected ArgumentError but no exception was raised (2000-01-01 20:15:01 +0200 was returned)
|
81
84
|
fails "Time.mktime raises an ArgumentError for out of range microsecond" # Expected ArgumentError but no exception was raised (2000-01-01 20:15:01 +0200 was returned)
|
82
85
|
fails "Time.new has at least microsecond precision" # NoMethodError: undefined method `nsec' for 2019-05-16 23:25:01 +0200
|
@@ -85,12 +88,12 @@ opal_filter "Time" do
|
|
85
88
|
fails "Time.new with a timezone argument #name method uses the optional #name method for marshaling" # ArgumentError: Opal does not support explicitly specifying UTC offset for Time
|
86
89
|
fails "Time.new with a timezone argument Time-like argument of #utc_to_local and #local_to_utc methods has attribute values the same as a Time object in UTC" # ArgumentError: Opal does not support explicitly specifying UTC offset for Time
|
87
90
|
fails "Time.new with a timezone argument Time-like argument of #utc_to_local and #local_to_utc methods implements subset of Time methods" # ArgumentError: Opal does not support explicitly specifying UTC offset for Time
|
88
|
-
fails "Time.new with a timezone argument accepts timezone argument that must have #local_to_utc and #utc_to_local methods" # Expected to not get Exception but got: ArgumentError (Opal
|
89
|
-
fails "Time.new with a timezone argument does not raise exception if timezone does not implement #utc_to_local method" # Expected to not get Exception but got: ArgumentError (Opal
|
91
|
+
fails "Time.new with a timezone argument accepts timezone argument that must have #local_to_utc and #utc_to_local methods" # Expected to not get Exception but got: ArgumentError (Opal doesn't support other types for a timezone argument than Integer and String)
|
92
|
+
fails "Time.new with a timezone argument does not raise exception if timezone does not implement #utc_to_local method" # Expected to not get Exception but got: ArgumentError (Opal doesn't support other types for a timezone argument than Integer and String)
|
90
93
|
fails "Time.new with a timezone argument raises TypeError if timezone does not implement #local_to_utc method" # Expected TypeError (/can't convert \w+ into an exact number/) but got: ArgumentError (Opal does not support explicitly specifying UTC offset for Time)
|
91
|
-
fails "Time.new with a timezone argument returned value by #utc_to_local and #local_to_utc methods could be Time instance" # Expected to not get Exception but got: ArgumentError (Opal
|
92
|
-
fails "Time.new with a timezone argument returned value by #utc_to_local and #local_to_utc methods could be Time subclass instance" # Expected to not get Exception but got: ArgumentError (Opal
|
93
|
-
fails "Time.new with a timezone argument returned value by #utc_to_local and #local_to_utc methods could be any object with #to_i method" # Expected to not get Exception but got: ArgumentError (Opal
|
94
|
+
fails "Time.new with a timezone argument returned value by #utc_to_local and #local_to_utc methods could be Time instance" # Expected to not get Exception but got: ArgumentError (Opal doesn't support other types for a timezone argument than Integer and String)
|
95
|
+
fails "Time.new with a timezone argument returned value by #utc_to_local and #local_to_utc methods could be Time subclass instance" # Expected to not get Exception but got: ArgumentError (Opal doesn't support other types for a timezone argument than Integer and String)
|
96
|
+
fails "Time.new with a timezone argument returned value by #utc_to_local and #local_to_utc methods could be any object with #to_i method" # Expected to not get Exception but got: ArgumentError (Opal doesn't support other types for a timezone argument than Integer and String)
|
94
97
|
fails "Time.new with a timezone argument returned value by #utc_to_local and #local_to_utc methods could have any #zone and #utc_offset because they are ignored" # ArgumentError: Opal does not support explicitly specifying UTC offset for Time
|
95
98
|
fails "Time.new with a timezone argument returned value by #utc_to_local and #local_to_utc methods leads to raising Argument error if difference between argument and result is too large" # Expected ArgumentError (utc_offset out of range) but got: ArgumentError (Opal does not support explicitly specifying UTC offset for Time)
|
96
99
|
fails "Time.new with a timezone argument returns a Time in the timezone" # ArgumentError: Opal does not support explicitly specifying UTC offset for Time
|
@@ -98,10 +101,17 @@ opal_filter "Time" do
|
|
98
101
|
fails "Time.new with a timezone argument subject's class implements .find_timezone method calls .find_timezone to build a time object if passed zone name as a timezone argument" # ArgumentError: Opal does not support explicitly specifying UTC offset for Time
|
99
102
|
fails "Time.new with a timezone argument subject's class implements .find_timezone method does not call .find_timezone if passed any not string/numeric/timezone timezone argument" # Expected TypeError (/can't convert \w+ into an exact number/) but got: ArgumentError (Opal does not support explicitly specifying UTC offset for Time)
|
100
103
|
fails "Time.new with a timezone argument the #abbr method is used by '%Z' in #strftime" # ArgumentError: Opal does not support explicitly specifying UTC offset for Time
|
104
|
+
fails "Time.new with a utc_offset argument raises ArgumentError if the String argument is not in an ASCII-compatible encoding" # Expected ArgumentError but no exception was raised (1999-12-31 18:50:00 -0410.000000000000028 was returned)
|
101
105
|
fails "Time.new with a utc_offset argument raises ArgumentError if the month is greater than 12" # Expected ArgumentError (/(mon|argument) out of range/) but got: ArgumentError (Opal does not support explicitly specifying UTC offset for Time)
|
106
|
+
fails "Time.new with a utc_offset argument raises ArgumentError if the utc_offset argument is greater than or equal to 10e9" # Expected ArgumentError but no exception was raised (2031-09-09 00:46:40 +27777746.66666666418314 was returned)
|
102
107
|
fails "Time.new with a utc_offset argument returns a Time with a UTC offset specified as +HH:MM:SS" # ArgumentError: Opal does not support explicitly specifying UTC offset for Time
|
103
108
|
fails "Time.now has at least microsecond precision" # NoMethodError: undefined method `nsec' for 2019-05-16 23:25:03 +0200
|
104
109
|
fails "Time.now uses the local timezone" # Expected 10800 to equal -28800
|
110
|
+
fails "Time.rfc2822 parses RFC-2822 strings" # NoMethodError: undefined method `rfc2822' for Time
|
111
|
+
fails "Time.rfc2822 parses RFC-822 strings" # NoMethodError: undefined method `rfc2822' for Time
|
112
|
+
fails "Time.rfc822 parses RFC-2822 strings" # NoMethodError: undefined method `rfc2822' for Time
|
113
|
+
fails "Time.rfc822 parses RFC-822 strings" # NoMethodError: undefined method `rfc2822' for Time
|
105
114
|
fails "Time.utc handles fractional usec close to rounding limit" # NoMethodError: undefined method `nsec' for 2000-01-01 12:30:00 UTC:Time
|
106
115
|
fails "Time.utc raises an ArgumentError for out of range microsecond" # Expected ArgumentError but no exception was raised (2000-01-01 20:15:01 UTC was returned)
|
116
|
+
fails "Time.xmlschema parses ISO-8601 strings" # NoMethodError: undefined method `xmlschema' for Time
|
107
117
|
end
|
data/spec/lib/cli_spec.rb
CHANGED
@@ -84,7 +84,7 @@ RSpec.describe Opal::CLI do
|
|
84
84
|
context 'when false' do
|
85
85
|
let(:options) { {lib_only: false, runner: :compiler, evals: [''], skip_opal_require: true, no_exit: true} }
|
86
86
|
it 'appends an empty code block at the end of the source' do
|
87
|
-
expect_output_of{ subject.run }.to include("
|
87
|
+
expect_output_of{ subject.run }.to include("Opal.nil")
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
@@ -207,7 +207,7 @@ RSpec.describe Opal::CLI do
|
|
207
207
|
describe ':sexp option' do
|
208
208
|
let(:options) { {evals: ['puts 4'], sexp: true} }
|
209
209
|
it 'prints syntax expressions for the given code' do
|
210
|
-
expect_output_of{ subject.run }.to eq("s(:send, nil, :puts,\n
|
210
|
+
expect_output_of{ subject.run }.to eq("s(:top,\n s(:send, nil, :puts,\n s(:int, 4)))\n")
|
211
211
|
end
|
212
212
|
end
|
213
213
|
|
data/spec/lib/compiler_spec.rb
CHANGED
@@ -17,15 +17,15 @@ RSpec.describe Opal::Compiler do
|
|
17
17
|
|
18
18
|
describe 'requirable' do
|
19
19
|
it 'executes the file' do
|
20
|
-
expect_compiled("").to include('(function(Opal) {')
|
21
|
-
expect_compiled("").to start_with('Opal.queue(function(Opal) {')
|
22
|
-
expect_compiled("").to end_with("});\n")
|
20
|
+
expect_compiled("true").to include('(function(Opal) {')
|
21
|
+
expect_compiled("true").to start_with('Opal.queue(function(Opal) {')
|
22
|
+
expect_compiled("true").to end_with("});\n")
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'puts the compiled into "Opal.modules"' do
|
26
26
|
options = { :requirable => true, :file => "pippo" }
|
27
|
-
expect_compiled("", options).to include('Opal.modules["pippo"] = function(Opal) {')
|
28
|
-
expect_compiled("", options).to end_with("};\n")
|
27
|
+
expect_compiled("true", options).to include('Opal.modules["pippo"] = function(Opal) {')
|
28
|
+
expect_compiled("true", options).to end_with("};\n")
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -89,18 +89,18 @@ RSpec.describe Opal::Compiler do
|
|
89
89
|
|
90
90
|
describe "method names" do
|
91
91
|
it "generates a named function for method" do
|
92
|
-
expect_compiled("def test_method; end").to include("function $$test_method()")
|
92
|
+
expect_compiled("def test_method; []; end").to include("function $$test_method()")
|
93
93
|
end
|
94
94
|
|
95
95
|
context "when function name is reserved" do
|
96
96
|
it "generates a valid named function for method" do
|
97
|
-
expect_compiled("def Array; end").to include("function $$Array()")
|
97
|
+
expect_compiled("def Array; []; end").to include("function $$Array()")
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
101
|
context "when function name is not valid" do
|
102
102
|
it "generates a name in a safe way" do
|
103
|
-
expect_compiled("def test_method?; end").to include("function $test_method$ques$1()")
|
103
|
+
expect_compiled("def test_method?; []; end").to include("function $test_method$ques$1()")
|
104
104
|
end
|
105
105
|
end
|
106
106
|
end
|
@@ -6,7 +6,7 @@ RSpec.describe Opal::Rewriters::Base do
|
|
6
6
|
include RewritersHelper
|
7
7
|
|
8
8
|
def body_ast_of(method_source)
|
9
|
-
def_ast = parse_without_rewriting(method_source)
|
9
|
+
def_ast = parse_without_rewriting(method_source).children.first
|
10
10
|
_, _, body_ast = *def_ast
|
11
11
|
body_ast
|
12
12
|
end
|
@@ -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
|
-
|
5
|
-
::Opal::AST::Node.new(type, children)
|
6
|
-
end
|
7
|
-
|
8
|
-
let(:rewriter) { Opal::Rewriters::BinaryOperatorAssignment.new }
|
5
|
+
include RewritersHelper
|
9
6
|
|
10
|
-
|
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
|
-
|
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,
|
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
|
-
|
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,
|
97
|
-
s(:if, s(:send, cached, :nil?),
|
98
|
-
s(:nil),
|
99
|
-
|
100
|
-
s(:send, 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),
|
77
|
+
s(:send, cached, :meth), # cached.meth +
|
103
78
|
:+,
|
104
|
-
|
105
|
-
))
|
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
|
-
|
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(
|
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
|
-
|
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/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.(
|
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.(
|
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
|
-
|
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
|