diff --git a/changelog/new_support_one_line_pattern_matching.md b/changelog/new_support_one_line_pattern_matching.md new file mode 100644 index 00000000000..02576397750 --- /dev/null +++ b/changelog/new_support_one_line_pattern_matching.md @@ -0,0 +1 @@ +* [#9873](https://github.com/rubocop/rubocop/pull/9873): Support one-line pattern matching syntax for `Layout/SpaceAroundKeyword` and `Layout/SpaceAroundOperators`. ([@koic][]) diff --git a/lib/rubocop/cop/layout/space_around_keyword.rb b/lib/rubocop/cop/layout/space_around_keyword.rb index d968cdd89af..60749bdb8f8 100644 --- a/lib/rubocop/cop/layout/space_around_keyword.rb +++ b/lib/rubocop/cop/layout/space_around_keyword.rb @@ -81,6 +81,18 @@ def on_kwbegin(node) check(node, %i[begin end].freeze, nil) end + # Handle one-line pattern matching syntax (`in`) with `Parser::Ruby27`. + def on_match_pattern(node) + return if target_ruby_version >= 3.0 + + check(node, [:operator].freeze) + end + + # Handle one-line pattern matching syntax (`in`) with `Parser::Ruby30`. + def on_match_pattern_p(node) + check(node, [:operator].freeze) + end + def on_next(node) check(node, [:keyword].freeze) end diff --git a/lib/rubocop/cop/layout/space_around_operators.rb b/lib/rubocop/cop/layout/space_around_operators.rb index 00384d3cbcb..3e826463402 100644 --- a/lib/rubocop/cop/layout/space_around_operators.rb +++ b/lib/rubocop/cop/layout/space_around_operators.rb @@ -120,6 +120,12 @@ def on_special_asgn(node) check_operator(:special_asgn, node.loc.operator, right.source_range) end + def on_match_pattern(node) + return if target_ruby_version < 3.0 + + check_operator(:match_pattern, node.loc.operator, node.source_range) + end + alias on_or on_binary alias on_and on_binary alias on_lvasgn on_assignment diff --git a/spec/rubocop/cop/layout/space_around_keyword_spec.rb b/spec/rubocop/cop/layout/space_around_keyword_spec.rb index 5a54df070f0..a37ed6069bc 100644 --- a/spec/rubocop/cop/layout/space_around_keyword_spec.rb +++ b/spec/rubocop/cop/layout/space_around_keyword_spec.rb @@ -133,6 +133,14 @@ # The answer will determine whether to enable or discard the test in the future. # it_behaves_like 'missing before', 'in', 'case ""in a; end', 'case "" in a; end' it_behaves_like 'missing after', 'in', 'case a; in""; end', 'case a; in ""; end' + + it_behaves_like 'missing before', 'in', '""in a', '"" in a' + it_behaves_like 'missing after', 'in', 'a in""', 'a in ""' + end + + context '>= Ruby 3.0', :ruby30 do + it_behaves_like 'accept before', '=>', '""=> a' + it_behaves_like 'accept after', '=>', 'a =>""' end it_behaves_like 'missing before', 'while', '1while ""', '1 while ""' diff --git a/spec/rubocop/cop/layout/space_around_operators_spec.rb b/spec/rubocop/cop/layout/space_around_operators_spec.rb index 5c6de08e5ed..8cbe15701fe 100644 --- a/spec/rubocop/cop/layout/space_around_operators_spec.rb +++ b/spec/rubocop/cop/layout/space_around_operators_spec.rb @@ -4,6 +4,7 @@ let(:config) do RuboCop::Config .new( + 'AllCops' => { 'TargetRubyVersion' => target_ruby_version }, 'Layout/HashAlignment' => { 'EnforcedHashRocketStyle' => hash_style }, 'Layout/SpaceAroundOperators' => { 'AllowForAlignment' => allow_for_alignment, @@ -11,6 +12,7 @@ } ) end + let(:target_ruby_version) { 2.5 } let(:hash_style) { 'key' } let(:allow_for_alignment) { true } let(:exponent_operator_style) { nil } @@ -204,6 +206,32 @@ def self.===(other); end expect_no_offenses('x = a * b**2') end + context '>= Ruby 2.7', :ruby27 do + let(:target_ruby_version) { 2.7 } + + # NOTE: It is `Layout/SpaceAroundKeyword` cop's role to detect this offense. + it 'does not register an offenses for one-line pattern matching syntax (`in`)' do + expect_no_offenses(<<~RUBY) + ""in foo + RUBY + end + end + + context '>= Ruby 3.0', :ruby30 do + let(:target_ruby_version) { 3.0 } + + it 'registers an offenses for one-line pattern matching syntax (`=>`)' do + expect_offense(<<~RUBY) + ""=>foo + ^^ Surrounding space missing for operator `=>`. + RUBY + + expect_correction(<<~RUBY) + "" => foo + RUBY + end + end + context 'when EnforcedStyleForExponentOperator is space' do let(:exponent_operator_style) { 'space' }