Skip to content

Commit

Permalink
Merge pull request #10959 from ydah/fix_space_inside_block_braces
Browse files Browse the repository at this point in the history
[Fix #10958] Fix an infinite loop for `Layout/SpaceInsideBlockBraces` when multiline block
  • Loading branch information
koic committed Aug 26, 2022
2 parents eb3acca + 6a8b7e9 commit 40381f1
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 10 deletions.
@@ -0,0 +1 @@
* [#10958](https://github.com/rubocop/rubocop/issues/10958): Fix an infinite loop for `Layout/SpaceInsideBlockBraces` when `EnforcedStyle` is `no_space` and using multiline block. ([@ydah][])
34 changes: 25 additions & 9 deletions lib/rubocop/cop/layout/space_inside_block_braces.rb
Expand Up @@ -131,7 +131,7 @@ def braces_with_contents_inside(node, inner)
args_delimiter = node.arguments.loc.begin if node.block_type? # Can be ( | or nil.

check_left_brace(inner, node.loc.begin, args_delimiter)
check_right_brace(inner, node.loc.begin, node.loc.end, node.single_line?)
check_right_brace(node, inner, node.loc.begin, node.loc.end, node.single_line?)
end

def check_left_brace(inner, left_brace, args_delimiter)
Expand All @@ -142,23 +142,28 @@ def check_left_brace(inner, left_brace, args_delimiter)
end
end

def check_right_brace(inner, left_brace, right_brace, single_line)
def check_right_brace(node, inner, left_brace, right_brace, single_line)
if single_line && /\S$/.match?(inner)
no_space(right_brace.begin_pos, right_brace.end_pos, 'Space missing inside }.')
else
column = node.loc.expression.column
return if multiline_block?(left_brace, right_brace) &&
aligned_braces?(left_brace, right_brace)
aligned_braces?(inner, right_brace, column)

space_inside_right_brace(right_brace)
space_inside_right_brace(inner, right_brace, column)
end
end

def multiline_block?(left_brace, right_brace)
left_brace.first_line != right_brace.first_line
end

def aligned_braces?(left_brace, right_brace)
left_brace.first_line == right_brace.last_column
def aligned_braces?(inner, right_brace, column)
column == right_brace.column || column == inner_last_space_count(inner)
end

def inner_last_space_count(inner)
inner.split("\n").last.count(' ')
end

def no_space_inside_left_brace(left_brace, args_delimiter)
Expand Down Expand Up @@ -197,10 +202,21 @@ def pipe?(args_delimiter)
args_delimiter&.is?('|')
end

def space_inside_right_brace(right_brace)
def space_inside_right_brace(inner, right_brace, column)
brace_with_space = range_with_surrounding_space(right_brace, side: :left)
space(brace_with_space.begin_pos, brace_with_space.end_pos - 1,
'Space inside } detected.')
begin_pos = brace_with_space.begin_pos
end_pos = brace_with_space.end_pos - 1

if brace_with_space.source.match?(/\R/)
begin_pos = end_pos - (right_brace.column - column)
end

if inner.end_with?(']')
end_pos -= 1
begin_pos = end_pos - (inner_last_space_count(inner) - column)
end

space(begin_pos, end_pos, 'Space inside } detected.')
end

def no_space(begin_pos, end_pos, msg)
Expand Down
31 changes: 30 additions & 1 deletion spec/rubocop/cop/layout/space_inside_block_braces_spec.rb
Expand Up @@ -387,8 +387,37 @@
expect_offense(<<~RUBY)
items.map {|item|
item.do_something
^{} Space inside } detected.
}
^^ Space inside } detected.
RUBY

expect_correction(<<~RUBY)
items.map {|item|
item.do_something
}
RUBY
end

it 'accepts when braces are aligned in multiline block with bracket' do
expect_no_offenses(<<~RUBY)
foo {[
bar
]}
RUBY
end

it 'registers an offense when braces are not aligned in multiline block with bracket' do
expect_offense(<<~RUBY)
foo {[
bar
]}
^^ Space inside } detected.
RUBY

expect_correction(<<~RUBY)
foo {[
bar
]}
RUBY
end
end
Expand Down

0 comments on commit 40381f1

Please sign in to comment.