From 15886e39c556701913ddab553bb745465d2ed330 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Tue, 3 Aug 2021 20:33:11 +0900 Subject: [PATCH] [Fix #9973] Fix a false positive for `Layout/RescueEnsureAlignment` Fixes #9973. This PR fixes a false positive for `Layout/RescueEnsureAlignment` when aligned `rescue` keyword and leading dot. --- ...tive_for_layout_rescue_ensure_alignment.md | 1 + .../cop/layout/rescue_ensure_alignment.rb | 20 +++++++++++++++++ .../layout/rescue_ensure_alignment_spec.rb | 22 +++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 changelog/fix_false_positive_for_layout_rescue_ensure_alignment.md diff --git a/changelog/fix_false_positive_for_layout_rescue_ensure_alignment.md b/changelog/fix_false_positive_for_layout_rescue_ensure_alignment.md new file mode 100644 index 00000000000..6186e0ed124 --- /dev/null +++ b/changelog/fix_false_positive_for_layout_rescue_ensure_alignment.md @@ -0,0 +1 @@ +* [#9973](https://github.com/rubocop/rubocop/issues/9973): Fix a false positive for `Layout/RescueEnsureAlignment` when aligned `rescue` keyword and leading dot. ([@koic][]) diff --git a/lib/rubocop/cop/layout/rescue_ensure_alignment.rb b/lib/rubocop/cop/layout/rescue_ensure_alignment.rb index ef5f86326c8..276a52d81d1 100644 --- a/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +++ b/lib/rubocop/cop/layout/rescue_ensure_alignment.rb @@ -117,6 +117,8 @@ def alignment_node(node) ancestor_node = ancestor_node(node) return ancestor_node if ancestor_node.nil? || ancestor_node.kwbegin_type? + return if ancestor_node.respond_to?(:send_node) && + aligned_with_line_break_method?(ancestor_node, node) assignment_node = assignment_node(ancestor_node) return assignment_node if same_line?(ancestor_node, assignment_node) @@ -131,6 +133,24 @@ def ancestor_node(node) node.each_ancestor(*ANCESTOR_TYPES).first end + def aligned_with_line_break_method?(ancestor_node, node) + send_node_loc = ancestor_node.send_node.loc + do_keyword_line = ancestor_node.loc.begin.line + rescue_keyword_column = node.loc.keyword.column + selector = send_node_loc.selector + + if send_node_loc.respond_to?(:dot) && (dot = send_node_loc.dot) && + aligned_with_leading_dot?(do_keyword_line, dot, rescue_keyword_column) + return true + end + + do_keyword_line == selector.line && rescue_keyword_column == selector.column + end + + def aligned_with_leading_dot?(do_keyword_line, dot, rescue_keyword_column) + do_keyword_line == dot.line && rescue_keyword_column == dot.column + end + def assignment_node(node) assignment_node = node.ancestors.first return nil unless diff --git a/spec/rubocop/cop/layout/rescue_ensure_alignment_spec.rb b/spec/rubocop/cop/layout/rescue_ensure_alignment_spec.rb index 6ecc1884729..0882160c774 100644 --- a/spec/rubocop/cop/layout/rescue_ensure_alignment_spec.rb +++ b/spec/rubocop/cop/layout/rescue_ensure_alignment_spec.rb @@ -449,6 +449,28 @@ def foo RUBY end + it 'accepts aligned rescue with do-end block that line break with leading dot for method calls' do + expect_no_offenses(<<~RUBY) + [1, 2, 3] + .each do |el| + el.to_s + rescue StandardError => _exception + next + end + RUBY + end + + it 'accepts aligned rescue with do-end block that line break with trailing dot for method calls' do + expect_no_offenses(<<~RUBY) + [1, 2, 3]. + each do |el| + el.to_s + rescue StandardError => _exception + next + end + RUBY + end + it 'accepts aligned rescue do-end block assigned to local variable' do expect_no_offenses(<<~RUBY) result = [1, 2, 3].map do |el|