parser 2.4.0.2 → 2.5.0.0
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.
- checksums.yaml +4 -4
- data/.travis.yml +5 -6
- data/CHANGELOG.md +35 -1
- data/Gemfile +2 -0
- data/README.md +1 -2
- data/Rakefile +2 -1
- data/bin/ruby-parse +2 -1
- data/bin/ruby-rewrite +2 -1
- data/lib/gauntlet_parser.rb +2 -0
- data/lib/parser.rb +16 -17
- data/lib/parser/all.rb +2 -0
- data/lib/parser/ast/node.rb +2 -0
- data/lib/parser/ast/processor.rb +2 -0
- data/lib/parser/base.rb +6 -12
- data/lib/parser/builders/default.rb +28 -47
- data/lib/parser/clobbering_error.rb +2 -0
- data/lib/parser/context.rb +42 -0
- data/lib/parser/current.rb +4 -20
- data/lib/parser/deprecation.rb +13 -0
- data/lib/parser/diagnostic.rb +3 -3
- data/lib/parser/diagnostic/engine.rb +2 -0
- data/lib/parser/lexer.rl +122 -60
- data/lib/parser/lexer/dedenter.rb +2 -0
- data/lib/parser/lexer/explanation.rb +2 -0
- data/lib/parser/lexer/literal.rb +4 -9
- data/lib/parser/lexer/stack_state.rb +4 -1
- data/lib/parser/macruby.y +32 -17
- data/lib/parser/messages.rb +14 -0
- data/lib/parser/meta.rb +2 -0
- data/lib/parser/rewriter.rb +30 -44
- data/lib/parser/ruby18.y +20 -13
- data/lib/parser/ruby19.y +32 -17
- data/lib/parser/ruby20.y +33 -18
- data/lib/parser/ruby21.y +32 -17
- data/lib/parser/ruby22.y +32 -17
- data/lib/parser/ruby23.y +32 -17
- data/lib/parser/ruby24.y +63 -46
- data/lib/parser/ruby25.y +72 -48
- data/lib/parser/rubymotion.y +33 -18
- data/lib/parser/runner.rb +4 -7
- data/lib/parser/runner/ruby_parse.rb +10 -0
- data/lib/parser/runner/ruby_rewrite.rb +2 -0
- data/lib/parser/source/buffer.rb +19 -24
- data/lib/parser/source/comment.rb +2 -0
- data/lib/parser/source/comment/associator.rb +2 -0
- data/lib/parser/source/map.rb +2 -0
- data/lib/parser/source/map/collection.rb +2 -0
- data/lib/parser/source/map/condition.rb +2 -0
- data/lib/parser/source/map/constant.rb +2 -0
- data/lib/parser/source/map/definition.rb +2 -0
- data/lib/parser/source/map/for.rb +2 -0
- data/lib/parser/source/map/heredoc.rb +2 -0
- data/lib/parser/source/map/keyword.rb +2 -0
- data/lib/parser/source/map/objc_kwarg.rb +2 -0
- data/lib/parser/source/map/operator.rb +2 -0
- data/lib/parser/source/map/rescue_body.rb +2 -0
- data/lib/parser/source/map/send.rb +2 -0
- data/lib/parser/source/map/ternary.rb +2 -0
- data/lib/parser/source/map/variable.rb +2 -0
- data/lib/parser/source/range.rb +81 -13
- data/lib/parser/source/rewriter.rb +48 -10
- data/lib/parser/source/rewriter/action.rb +2 -0
- data/lib/parser/source/tree_rewriter.rb +301 -0
- data/lib/parser/source/tree_rewriter/action.rb +133 -0
- data/lib/parser/static_environment.rb +2 -0
- data/lib/parser/syntax_error.rb +2 -0
- data/lib/parser/tree_rewriter.rb +133 -0
- data/lib/parser/version.rb +3 -1
- data/parser.gemspec +4 -1
- data/test/bug_163/fixtures/input.rb +2 -0
- data/test/bug_163/fixtures/output.rb +2 -0
- data/test/bug_163/rewriter.rb +2 -0
- data/test/helper.rb +7 -7
- data/test/parse_helper.rb +57 -10
- data/test/racc_coverage_helper.rb +2 -0
- data/test/test_base.rb +2 -0
- data/test/test_current.rb +2 -4
- data/test/test_diagnostic.rb +3 -1
- data/test/test_diagnostic_engine.rb +2 -0
- data/test/test_encoding.rb +61 -49
- data/test/test_lexer.rb +164 -77
- data/test/test_lexer_stack_state.rb +2 -0
- data/test/test_parse_helper.rb +8 -8
- data/test/test_parser.rb +613 -51
- data/test/test_runner_rewrite.rb +47 -0
- data/test/test_source_buffer.rb +22 -10
- data/test/test_source_comment.rb +2 -0
- data/test/test_source_comment_associator.rb +2 -0
- data/test/test_source_map.rb +2 -0
- data/test/test_source_range.rb +92 -45
- data/test/test_source_rewriter.rb +3 -1
- data/test/test_source_rewriter_action.rb +2 -0
- data/test/test_source_tree_rewriter.rb +177 -0
- data/test/test_static_environment.rb +2 -0
- data/test/using_tree_rewriter/fixtures/input.rb +3 -0
- data/test/using_tree_rewriter/fixtures/output.rb +3 -0
- data/test/using_tree_rewriter/using_tree_rewriter.rb +9 -0
- metadata +21 -10
- data/lib/parser/compatibility/ruby1_8.rb +0 -20
- data/lib/parser/compatibility/ruby1_9.rb +0 -32
- data/test/bug_163/test_runner_rewrite.rb +0 -35
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'shellwords'
|
6
|
+
require 'open3'
|
7
|
+
|
8
|
+
BASE_DIR = Pathname.new(__FILE__) + '..'
|
9
|
+
require (BASE_DIR + 'helper').expand_path
|
10
|
+
|
11
|
+
class TestRunnerRewrite < Minitest::Test
|
12
|
+
def assert_rewriter_output(path, args, input: 'input.rb', output: 'output.rb', expected_output: '', expected_error: '')
|
13
|
+
@ruby_rewrite = BASE_DIR.expand_path + '../bin/ruby-rewrite'
|
14
|
+
@test_dir = BASE_DIR + path
|
15
|
+
@fixtures_dir = @test_dir + 'fixtures'
|
16
|
+
|
17
|
+
Dir.mktmpdir("parser", BASE_DIR.expand_path.to_s) do |tmp_dir|
|
18
|
+
tmp_dir = Pathname.new(tmp_dir)
|
19
|
+
sample_file = tmp_dir + "#{path}.rb"
|
20
|
+
sample_file_expanded = sample_file.expand_path
|
21
|
+
expected_file = @fixtures_dir + output
|
22
|
+
|
23
|
+
FileUtils.cp(@fixtures_dir + input, sample_file_expanded)
|
24
|
+
stdout, stderr, exit_code = Dir.chdir @test_dir do
|
25
|
+
Open3.capture3 %Q{
|
26
|
+
#{Shellwords.escape(@ruby_rewrite.to_s)} #{args} \
|
27
|
+
#{Shellwords.escape(sample_file_expanded.to_s)}
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
assert_equal expected_output.chomp, stdout.chomp
|
32
|
+
assert_match expected_error.chomp, stderr.chomp
|
33
|
+
assert_equal File.read(expected_file.expand_path), File.read(sample_file)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_rewriter_bug_163
|
38
|
+
assert_rewriter_output('bug_163',
|
39
|
+
'--modify -l rewriter.rb',
|
40
|
+
expected_error: Parser::Rewriter::DEPRECATION_WARNING
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_tree_rewriter
|
45
|
+
assert_rewriter_output('using_tree_rewriter', '-l using_tree_rewriter.rb --modify')
|
46
|
+
end
|
47
|
+
end
|
data/test/test_source_buffer.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'helper'
|
2
4
|
|
3
5
|
class TestSourceBuffer < Minitest::Test
|
@@ -29,17 +31,15 @@ class TestSourceBuffer < Minitest::Test
|
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
].join("\n")
|
39
|
-
end
|
40
|
-
|
41
|
-
assert_match /invalid byte sequence in UTF\-8/, error.message
|
34
|
+
def test_source_setter_encoding_error
|
35
|
+
error = assert_raises EncodingError do
|
36
|
+
@buffer.source = [
|
37
|
+
'# encoding: utf-8',
|
38
|
+
"# \xf9"
|
39
|
+
].join("\n")
|
42
40
|
end
|
41
|
+
|
42
|
+
assert_match /invalid byte sequence in UTF\-8/, error.message
|
43
43
|
end
|
44
44
|
|
45
45
|
def test_read
|
@@ -117,6 +117,18 @@ class TestSourceBuffer < Minitest::Test
|
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
|
+
def test_source_range
|
121
|
+
@buffer = Parser::Source::Buffer.new('(string)', 5)
|
122
|
+
|
123
|
+
assert_raises RuntimeError do
|
124
|
+
@buffer.source_range
|
125
|
+
end
|
126
|
+
|
127
|
+
@buffer.source = "abc\ndef\nghi\n"
|
128
|
+
|
129
|
+
assert_equal Parser::Source::Range.new(@buffer, 0, @buffer.source.size), @buffer.source_range
|
130
|
+
end
|
131
|
+
|
120
132
|
def test_last_line
|
121
133
|
@buffer.source = "1\nfoo\nbar"
|
122
134
|
assert_equal 3, @buffer.last_line
|
data/test/test_source_comment.rb
CHANGED
data/test/test_source_map.rb
CHANGED
data/test/test_source_range.rb
CHANGED
@@ -1,21 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'helper'
|
2
4
|
|
3
5
|
class TestSourceRange < Minitest::Test
|
4
6
|
def setup
|
5
7
|
@buf = Parser::Source::Buffer.new('(string)')
|
6
8
|
@buf.source = "foobar\nbaz"
|
9
|
+
@sr1_3 = Parser::Source::Range.new(@buf, 1, 3)
|
10
|
+
@sr2_2 = Parser::Source::Range.new(@buf, 2, 2)
|
11
|
+
@sr3_3 = Parser::Source::Range.new(@buf, 3, 3)
|
12
|
+
@sr2_6 = Parser::Source::Range.new(@buf, 2, 6)
|
13
|
+
@sr5_8 = Parser::Source::Range.new(@buf, 5, 8)
|
14
|
+
@sr5_7 = Parser::Source::Range.new(@buf, 5, 7)
|
15
|
+
@sr6_7 = Parser::Source::Range.new(@buf, 6, 7)
|
7
16
|
end
|
8
17
|
|
9
18
|
def test_initialize
|
10
|
-
|
11
|
-
assert_equal
|
12
|
-
|
13
|
-
assert sr.frozen?
|
19
|
+
assert_equal 1, @sr1_3.begin_pos
|
20
|
+
assert_equal 3, @sr1_3.end_pos
|
21
|
+
assert @sr1_3.frozen?
|
14
22
|
end
|
15
23
|
|
16
24
|
def test_size
|
17
|
-
|
18
|
-
assert_equal 2, sr.size
|
25
|
+
assert_equal 4, @sr2_6.size
|
19
26
|
end
|
20
27
|
|
21
28
|
def test_bad_size
|
@@ -25,54 +32,86 @@ class TestSourceRange < Minitest::Test
|
|
25
32
|
end
|
26
33
|
|
27
34
|
def test_join
|
28
|
-
|
29
|
-
sr2 = Parser::Source::Range.new(@buf, 5, 8)
|
30
|
-
sr = sr1.join(sr2)
|
35
|
+
sr = @sr1_3.join(@sr5_8)
|
31
36
|
|
32
37
|
assert_equal 1, sr.begin_pos
|
33
38
|
assert_equal 8, sr.end_pos
|
34
39
|
end
|
35
40
|
|
36
41
|
def test_intersect
|
37
|
-
|
38
|
-
|
39
|
-
|
42
|
+
assert_equal 2, @sr1_3.intersect(@sr2_6).begin_pos
|
43
|
+
assert_equal 3, @sr1_3.intersect(@sr2_6).end_pos
|
44
|
+
assert_equal 5, @sr2_6.intersect(@sr5_8).begin_pos
|
45
|
+
assert_equal 6, @sr2_6.intersect(@sr5_8).end_pos
|
46
|
+
assert @sr1_3.intersect(@sr5_8) == nil
|
47
|
+
assert_equal 2, @sr1_3.intersect(@sr2_2).begin_pos
|
48
|
+
assert_equal 2, @sr1_3.intersect(@sr2_2).end_pos
|
49
|
+
assert_equal 2, @sr2_2.intersect(@sr2_2).begin_pos
|
50
|
+
assert_equal 2, @sr2_2.intersect(@sr2_2).end_pos
|
51
|
+
end
|
40
52
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
assert
|
53
|
+
def test_overlaps
|
54
|
+
assert !@sr1_3.overlaps?(@sr5_8)
|
55
|
+
assert @sr1_3.overlaps?(@sr2_6)
|
56
|
+
assert @sr2_6.overlaps?(@sr5_8)
|
57
|
+
assert @sr1_3.overlaps?(@sr2_2)
|
58
|
+
assert !@sr2_6.overlaps?(@sr2_2)
|
59
|
+
assert @sr2_2.overlaps?(@sr2_2)
|
60
|
+
end
|
61
|
+
|
62
|
+
def check_relationship(relationship, sr1, sr2, reflexive_relationship = relationship)
|
63
|
+
# Double check equality
|
64
|
+
assert_equal true, sr1 == sr1.dup
|
65
|
+
assert_equal true, sr1 != sr2
|
66
|
+
# Check relationships and reflexivity
|
67
|
+
assert_equal true, sr1.send(relationship, sr2)
|
68
|
+
assert_equal true, sr2.send(reflexive_relationship, sr1)
|
69
|
+
# Check it's not true for itself
|
70
|
+
assert_equal false, sr1.send(relationship, sr1)
|
71
|
+
# Check other relationships return false
|
72
|
+
others = %i[disjoint? crossing? contains? contained?] - [relationship, reflexive_relationship]
|
73
|
+
others.each do |other_rel|
|
74
|
+
assert_equal false, sr1.send(other_rel, sr2), other_rel
|
75
|
+
assert_equal false, sr2.send(other_rel, sr1), other_rel
|
76
|
+
end
|
46
77
|
end
|
47
78
|
|
48
79
|
def test_disjoint
|
49
|
-
|
50
|
-
|
51
|
-
|
80
|
+
check_relationship(:disjoint?, @sr1_3, @sr5_8)
|
81
|
+
check_relationship(:disjoint?, @sr2_2, @sr2_6)
|
82
|
+
check_relationship(:disjoint?, @sr2_2, @sr3_3)
|
83
|
+
check_relationship(:disjoint?, @sr2_6, @sr6_7)
|
84
|
+
end
|
52
85
|
|
53
|
-
|
54
|
-
|
55
|
-
assert !sr2.disjoint?(sr3)
|
86
|
+
def test_crossing
|
87
|
+
check_relationship(:crossing?, @sr1_3, @sr2_6)
|
56
88
|
end
|
57
89
|
|
58
|
-
def
|
59
|
-
|
60
|
-
|
61
|
-
|
90
|
+
def test_containment
|
91
|
+
check_relationship(:contained?, @sr2_2, @sr1_3, :contains?)
|
92
|
+
check_relationship(:contained?, @sr5_7, @sr5_8, :contains?)
|
93
|
+
check_relationship(:contained?, @sr6_7, @sr5_8, :contains?)
|
94
|
+
end
|
62
95
|
|
63
|
-
|
64
|
-
|
65
|
-
|
96
|
+
def test_order
|
97
|
+
assert_equal 0, @sr1_3 <=> @sr1_3
|
98
|
+
assert_equal -1, @sr1_3 <=> @sr5_8
|
99
|
+
assert_equal -1, @sr2_2 <=> @sr2_6
|
100
|
+
assert_equal +1, @sr2_6 <=> @sr2_2
|
101
|
+
|
102
|
+
assert_equal -1, @sr1_3 <=> @sr2_6
|
103
|
+
|
104
|
+
assert_equal +1, @sr2_2 <=> @sr1_3
|
105
|
+
assert_equal -1, @sr1_3 <=> @sr2_2
|
106
|
+
assert_equal -1, @sr5_7 <=> @sr5_8
|
107
|
+
|
108
|
+
assert_nil @sr1_3 <=> Parser::Source::Range.new(@buf.dup, 1, 3)
|
109
|
+
assert_nil @sr1_3 <=> 4
|
66
110
|
end
|
67
111
|
|
68
112
|
def test_empty
|
69
|
-
|
70
|
-
|
71
|
-
sr3 = Parser::Source::Range.new(@buf, 7, 8)
|
72
|
-
|
73
|
-
assert !sr1.empty?
|
74
|
-
assert sr2.empty?
|
75
|
-
assert !sr3.empty?
|
113
|
+
assert !@sr1_3.empty?
|
114
|
+
assert @sr2_2.empty?
|
76
115
|
end
|
77
116
|
|
78
117
|
def test_line
|
@@ -93,15 +132,13 @@ class TestSourceRange < Minitest::Test
|
|
93
132
|
end
|
94
133
|
|
95
134
|
def test_begin_end
|
96
|
-
|
135
|
+
sr_beg = @sr2_6.begin
|
136
|
+
assert_equal 2, sr_beg.begin_pos
|
137
|
+
assert_equal 2, sr_beg.end_pos
|
97
138
|
|
98
|
-
|
99
|
-
assert_equal
|
100
|
-
assert_equal
|
101
|
-
|
102
|
-
sr_end = sr.end
|
103
|
-
assert_equal 5, sr_end.begin_pos
|
104
|
-
assert_equal 5, sr_end.end_pos
|
139
|
+
sr_end = @sr2_6.end
|
140
|
+
assert_equal 6, sr_end.begin_pos
|
141
|
+
assert_equal 6, sr_end.end_pos
|
105
142
|
end
|
106
143
|
|
107
144
|
def test_source
|
@@ -122,4 +159,14 @@ class TestSourceRange < Minitest::Test
|
|
122
159
|
sr = Parser::Source::Range.new(@buf, 8, 9)
|
123
160
|
assert_equal '(string):2:2', sr.to_s
|
124
161
|
end
|
162
|
+
|
163
|
+
def test_with
|
164
|
+
sr2 = @sr1_3.with(begin_pos: 2)
|
165
|
+
sr3 = @sr1_3.with(end_pos: 4)
|
166
|
+
|
167
|
+
assert_equal 2, sr2.begin_pos
|
168
|
+
assert_equal 3, sr2.end_pos
|
169
|
+
assert_equal 1, sr3.begin_pos
|
170
|
+
assert_equal 4, sr3.end_pos
|
171
|
+
end
|
125
172
|
end
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'helper'
|
2
4
|
|
3
5
|
class TestSourceRewriter < Minitest::Test
|
4
6
|
def setup
|
5
7
|
@buf = Parser::Source::Buffer.new('(rewriter)')
|
6
8
|
@buf.source = 'foo bar baz'
|
7
|
-
|
9
|
+
Parser::Source::Rewriter.warned_of_deprecation = true
|
8
10
|
@rewriter = Parser::Source::Rewriter.new(@buf)
|
9
11
|
end
|
10
12
|
|
@@ -0,0 +1,177 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'helper'
|
4
|
+
|
5
|
+
class TestSourceTreeRewriter < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@buf = Parser::Source::Buffer.new('(rewriter)')
|
8
|
+
@buf.source = 'puts(:hello, :world)'
|
9
|
+
|
10
|
+
@hello = range(5, 6)
|
11
|
+
@comma_space = range(11,2)
|
12
|
+
@world = range(13,6)
|
13
|
+
end
|
14
|
+
|
15
|
+
def range(from, len)
|
16
|
+
Parser::Source::Range.new(@buf, from, from + len)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns either:
|
20
|
+
# - String (Normal operation)
|
21
|
+
# - [diagnostic, ...] (Diagnostics)
|
22
|
+
# - Parser::ClobberingError
|
23
|
+
#
|
24
|
+
def apply(actions, **policy)
|
25
|
+
diagnostics = []
|
26
|
+
diags = -> { diagnostics.flatten.map(&:strip).join("\n") }
|
27
|
+
rewriter = Parser::Source::TreeRewriter.new(@buf, **policy)
|
28
|
+
rewriter.diagnostics.consumer = -> diag { diagnostics << diag.render }
|
29
|
+
actions.each do |action, range, *args|
|
30
|
+
rewriter.public_send(action, range, *args)
|
31
|
+
end
|
32
|
+
if diagnostics.empty?
|
33
|
+
rewriter.process
|
34
|
+
else
|
35
|
+
diags.call
|
36
|
+
end
|
37
|
+
rescue ::Parser::ClobberingError => e
|
38
|
+
[::Parser::ClobberingError, diags.call]
|
39
|
+
end
|
40
|
+
|
41
|
+
# Expects ordered actions to be grouped together
|
42
|
+
def check_actions(expected, grouped_actions, **policy)
|
43
|
+
grouped_actions.permutation do |sequence|
|
44
|
+
# [action, [action, action]] => [action, action, action]
|
45
|
+
# except we can't use flatten because "action" are arrays themselves
|
46
|
+
actions = sequence.flat_map { |group| group.first.is_a?(Array) ? group : [group] }
|
47
|
+
assert_equal(expected, apply(actions, **policy))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def assert_actions_result(expected, *actions, **rest)
|
52
|
+
if expected == :raise
|
53
|
+
diagnostic = rest.values.first
|
54
|
+
check_actions([::Parser::ClobberingError, diagnostic], actions)
|
55
|
+
elsif rest.empty?
|
56
|
+
check_actions(expected, actions)
|
57
|
+
else
|
58
|
+
policy, diagnostic = rest.first
|
59
|
+
check_actions(expected, actions, policy => :accept)
|
60
|
+
check_actions(diagnostic, actions, policy => :warn)
|
61
|
+
diagnostic.gsub!(/warning: /, 'error: ')
|
62
|
+
check_actions([::Parser::ClobberingError, diagnostic], actions, policy => :raise)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
### Simple cases
|
67
|
+
|
68
|
+
def test_remove
|
69
|
+
assert_actions_result 'puts(, :world)', [:remove, @hello]
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_insert_before
|
73
|
+
assert_actions_result 'puts(:hello, 42, :world)', [:insert_before, @world, '42, ']
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_insert_after
|
77
|
+
assert_actions_result 'puts(:hello, 42, :world)', [:insert_after, @hello, ', 42']
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_wrap
|
81
|
+
assert_actions_result 'puts([:hello], :world)', [:wrap, @hello, '[', ']']
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_replace
|
85
|
+
assert_actions_result 'puts(:hi, :world)', [:replace, @hello, ':hi']
|
86
|
+
end
|
87
|
+
|
88
|
+
#
|
89
|
+
# All other cases, as per doc
|
90
|
+
#
|
91
|
+
|
92
|
+
def test_crossing_non_deletions
|
93
|
+
check = [
|
94
|
+
[:wrap, '(', ')'],
|
95
|
+
[:remove],
|
96
|
+
[:replace, 'xx'],
|
97
|
+
]
|
98
|
+
check.combination(2) do |(action, *args), (action_b, *args_b)|
|
99
|
+
next if action == :remove && action_b == :remove
|
100
|
+
assert_actions_result :raise,
|
101
|
+
[[action, @hello.join(@comma_space), *args],
|
102
|
+
[action_b, @world.join(@comma_space), *args_b]],
|
103
|
+
diagnostic: <<-DIAGNOSTIC.chomp
|
104
|
+
(rewriter):1:12: error: the rewriting action on:
|
105
|
+
(rewriter):1: puts(:hello, :world)
|
106
|
+
(rewriter):1: ^~~~~~~~
|
107
|
+
(rewriter):1:6: error: is crossing that on:
|
108
|
+
(rewriter):1: puts(:hello, :world)
|
109
|
+
(rewriter):1: ^~~~~~~~
|
110
|
+
DIAGNOSTIC
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
def test_crossing_deletions
|
116
|
+
assert_actions_result 'puts()',
|
117
|
+
[[:remove, @hello.join(@comma_space)],
|
118
|
+
[:remove, @world.join(@comma_space)]],
|
119
|
+
crossing_deletions: <<-DIAGNOSTIC.chomp
|
120
|
+
(rewriter):1:12: warning: the deletion of:
|
121
|
+
(rewriter):1: puts(:hello, :world)
|
122
|
+
(rewriter):1: ^~~~~~~~
|
123
|
+
(rewriter):1:6: warning: is crossing:
|
124
|
+
(rewriter):1: puts(:hello, :world)
|
125
|
+
(rewriter):1: ^~~~~~~~
|
126
|
+
DIAGNOSTIC
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_multiple_actions
|
130
|
+
assert_actions_result 'puts({:hello => [:everybody]})',
|
131
|
+
[:replace, @comma_space, ' => '],
|
132
|
+
[:wrap, @hello.join(@world), '{', '}'],
|
133
|
+
[:replace, @world, ':everybody'],
|
134
|
+
[:wrap, @world, '[', ']']
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
def test_multiple_actions
|
139
|
+
assert_actions_result 'puts({:hello => [:everybody]})',
|
140
|
+
[:replace, @comma_space, ' => '],
|
141
|
+
[:wrap, @hello.join(@world), '{', '}'],
|
142
|
+
[:replace, @world, ':everybody'],
|
143
|
+
[:wrap, @world, '[', ']']
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_wraps_same_range
|
147
|
+
assert_actions_result 'puts([(:hello)], :world)',
|
148
|
+
[[:wrap, @hello, '(', ')'],
|
149
|
+
[:wrap, @hello, '[', ']']]
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_replace_same_range
|
153
|
+
assert_actions_result 'puts(:hey, :world)',
|
154
|
+
[[:replace, @hello, ':hi'],
|
155
|
+
[:replace, @hello, ':hey']],
|
156
|
+
different_replacements: <<-DIAGNOSTIC.chomp
|
157
|
+
(rewriter):1:6: warning: different replacements: :hey vs :hi
|
158
|
+
(rewriter):1: puts(:hello, :world)
|
159
|
+
(rewriter):1: ^~~~~~
|
160
|
+
DIAGNOSTIC
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_swallowed_insertions
|
164
|
+
assert_actions_result 'puts(:hi)',
|
165
|
+
[[:wrap, @hello.adjust(begin_pos: 1), '__', '__'],
|
166
|
+
[:replace, @world.adjust(end_pos: -2), 'xx'],
|
167
|
+
[:replace, @hello.join(@world), ':hi']],
|
168
|
+
swallowed_insertions: <<-DIAGNOSTIC.chomp
|
169
|
+
(rewriter):1:6: warning: this replacement:
|
170
|
+
(rewriter):1: puts(:hello, :world)
|
171
|
+
(rewriter):1: ^~~~~~~~~~~~~~
|
172
|
+
(rewriter):1:7: warning: swallows some inner rewriting actions:
|
173
|
+
(rewriter):1: puts(:hello, :world)
|
174
|
+
(rewriter):1: ^~~~~ ~~~~
|
175
|
+
DIAGNOSTIC
|
176
|
+
end
|
177
|
+
end
|