Skip to content

Commit

Permalink
Merge pull request #6749 from hoshinotsuyoshi/aware_safe_navigator_in…
Browse files Browse the repository at this point in the history
…_some_cops

Make some cops aware of safe navigation operator
  • Loading branch information
pocke committed Feb 10, 2019
2 parents e9206b7 + 48415e2 commit 548bf43
Show file tree
Hide file tree
Showing 58 changed files with 485 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -26,6 +26,7 @@
* [#6597](https://github.com/rubocop-hq/rubocop/issues/6597): `Style/LineEndConcatenation` is now known to be unsafe for auto-correct. ([@jaredbeck][])
* [#6725](https://github.com/rubocop-hq/rubocop/issues/6725): Mark `Style/SymbolProc` as unsafe for auto-correct. ([@drenmi][])
* [#6708](https://github.com/rubocop-hq/rubocop/issues/6708): Make `Style/CommentedKeyword` allow the `:yields:` RDoc comment. ([@bquorning][])
* [#6749](https://github.com/rubocop-hq/rubocop/pull/6749): Make some cops aware of safe navigation operator. ([@hoshinotsuyoshi][])

## 0.63.1 (2019-01-22)

Expand Down
7 changes: 6 additions & 1 deletion lib/rubocop/cop/layout/align_parameters.rb
Expand Up @@ -42,6 +42,7 @@ def on_send(node)

check_alignment(node.arguments, base_column(node, node.arguments))
end
alias on_csend on_send
alias on_def on_send
alias on_defs on_send

Expand All @@ -52,7 +53,11 @@ def autocorrect(node)
private

def message(node)
type = node && node.parent.send_type? ? 'call' : 'definition'
type = if node && (node.parent.send_type? || node.parent.csend_type?)
'call'
else
'definition'
end
msg = fixed_indentation? ? FIXED_INDENT_MSG : ALIGN_PARAMS_MSG

format(msg, type: type)
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/layout/closing_parenthesis_indentation.rb
Expand Up @@ -78,6 +78,7 @@ class ClosingParenthesisIndentation < Cop
def on_send(node)
check(node, node.arguments)
end
alias on_csend on_send

def on_begin(node)
check(node, node.children)
Expand Down
17 changes: 12 additions & 5 deletions lib/rubocop/cop/layout/dot_position.rb
Expand Up @@ -26,31 +26,34 @@ class DotPosition < Cop
include ConfigurableEnforcedStyle

def on_send(node)
return unless node.dot?
return unless node.dot? || ampersand_dot?(node)

if proper_dot_position?(node)
correct_style_detected
else
add_offense(node, location: :dot) { opposite_style_detected }
end
end
alias on_csend on_send

def autocorrect(node)
lambda do |corrector|
dot = node.loc.dot.source
corrector.remove(node.loc.dot)
case style
when :leading
corrector.insert_before(selector_range(node), '.')
corrector.insert_before(selector_range(node), dot)
when :trailing
corrector.insert_after(node.receiver.source_range, '.')
corrector.insert_after(node.receiver.source_range, dot)
end
end
end

private

def message(_node)
'Place the . on the ' +
def message(node)
dot = node.loc.dot.source
"Place the #{dot} on the " +
case style
when :leading
'next line, together with the method name.'
Expand Down Expand Up @@ -92,6 +95,10 @@ def selector_range(node)
# l.(1) has no selector, so we use the opening parenthesis instead
node.loc.selector || node.loc.begin
end

def ampersand_dot?(node)
node.loc.respond_to?(:dot) && node.loc.dot && node.loc.dot.is?('&.')
end
end
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/layout/empty_lines_around_arguments.rb
Expand Up @@ -48,6 +48,7 @@ def on_send(node)

extra_lines(node) { |range| add_offense(node, location: range) }
end
alias on_csend on_send

def autocorrect(node)
lambda do |corrector|
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/layout/first_method_argument_line_break.rb
Expand Up @@ -43,6 +43,7 @@ def on_send(node)

check_method_line_break(node, args)
end
alias on_csend on_send

def autocorrect(node)
EmptyLineCorrector.insert_before(node)
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/layout/first_parameter_indentation.rb
Expand Up @@ -154,6 +154,7 @@ def on_send(node)

check_alignment([node.first_argument], indent)
end
alias on_csend on_send

def autocorrect(node)
AlignmentCorrector.correct(processed_source, node, column_delta)
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/layout/indent_array.rb
Expand Up @@ -96,6 +96,7 @@ def on_send(node)
check(array_node, left_parenthesis)
end
end
alias on_csend on_send

def autocorrect(node)
AlignmentCorrector.correct(processed_source, node, @column_delta)
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/layout/indent_hash.rb
Expand Up @@ -94,6 +94,7 @@ def on_send(node)
check(hash_node, left_parenthesis)
end
end
alias on_csend on_send

def autocorrect(node)
AlignmentCorrector.correct(processed_source, node, @column_delta)
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/layout/indentation_width.rb
Expand Up @@ -119,6 +119,7 @@ def on_send(node)
check_indentation(base.source_range, body)
ignore_node(node.first_argument)
end
alias on_csend on_send

def on_def(node)
return if ignored_node?(node)
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/layout/space_before_first_arg.rb
Expand Up @@ -40,6 +40,7 @@ def on_send(node)

add_offense(space, location: space) if space.length != 1
end
alias on_csend on_send

def autocorrect(range)
->(corrector) { corrector.replace(range, ' ') }
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/lint/ambiguous_block_association.rb
Expand Up @@ -37,6 +37,7 @@ def on_send(node)

add_offense(node)
end
alias on_csend on_send

private

Expand Down
5 changes: 4 additions & 1 deletion lib/rubocop/cop/lint/each_with_object_argument.rb
Expand Up @@ -24,7 +24,9 @@ module Lint
class EachWithObjectArgument < Cop
MSG = 'The argument to each_with_object can not be immutable.'.freeze

def_node_matcher :each_with_object?, '(send _ :each_with_object $_)'
def_node_matcher :each_with_object?, <<-PATTERN
({send csend} _ :each_with_object $_)
PATTERN

def on_send(node)
each_with_object?(node) do |arg|
Expand All @@ -33,6 +35,7 @@ def on_send(node)
add_offense(node)
end
end
alias on_csend on_send
end
end
end
Expand Down
3 changes: 2 additions & 1 deletion lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb
Expand Up @@ -35,6 +35,7 @@ def on_send(node)

add_offense(nil, location: range)
end
alias on_csend on_send

private

Expand All @@ -50,7 +51,7 @@ def spaces_before_left_parenthesis(node)
# Escape question mark if any.
method_regexp = Regexp.escape(node.method_name)

match = without_receiver.match(/^\s*\.?\s*#{method_regexp}(\s+)\(/)
match = without_receiver.match(/^\s*&?\.?\s*#{method_regexp}(\s+)\(/)
match ? match.captures[0].length : 0
end

Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/lint/require_parentheses.rb
Expand Up @@ -42,6 +42,7 @@ def on_send(node)
check_predicate(node.last_argument, node)
end
end
alias on_csend on_send

private

Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/mixin/check_assignment.rb
Expand Up @@ -31,7 +31,7 @@ def extract_rhs(node)
_scope, _lhs, rhs = *node
elsif node.op_asgn_type?
_lhs, _op, rhs = *node
elsif node.send_type?
elsif node.send_type? || node.csend_type?
rhs = node.last_argument
elsif node.assignment?
_lhs, rhs = *node
Expand Down
2 changes: 2 additions & 0 deletions lib/rubocop/cop/rails/active_record_aliases.rb
Expand Up @@ -32,6 +32,8 @@ def on_send(node)
end
end

alias on_csend on_send

def autocorrect(node)
lambda do |corrector|
corrector.replace(
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/rails/date.rb
Expand Up @@ -79,6 +79,7 @@ def on_send(node)
add_offense(node, location: :selector,
message: format(MSG_SEND, method: node.method_name))
end
alias on_csend on_send

private

Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/rails/dynamic_find_by.rb
Expand Up @@ -42,6 +42,7 @@ def on_send(node)
message: format(MSG, static_name: static_name,
method: node.method_name))
end
alias on_csend on_send

def autocorrect(node)
keywords = column_keywords(node.method_name)
Expand Down
3 changes: 2 additions & 1 deletion lib/rubocop/cop/rails/find_by.rb
Expand Up @@ -20,7 +20,7 @@ class FindBy < Cop
TARGET_SELECTORS = %i[first take].freeze

def_node_matcher :where_first?, <<-PATTERN
(send (send _ :where ...) {:first :take})
(send ({send csend} _ :where ...) {:first :take})
PATTERN

def on_send(node)
Expand All @@ -32,6 +32,7 @@ def on_send(node)
add_offense(node, location: range,
message: format(MSG, method: node.method_name))
end
alias on_csend on_send

def autocorrect(node)
# Don't autocorrect where(...).first, because it can return different
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/rails/save_bang.rb
Expand Up @@ -146,6 +146,7 @@ def on_send(node) # rubocop:disable Metrics/CyclomaticComplexity

add_offense_for_node(node)
end
alias on_csend on_send

def autocorrect(node)
save_loc = node.loc.selector
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/rails/skips_model_validations.rb
Expand Up @@ -67,6 +67,7 @@ def on_send(node)

add_offense(node, location: :selector)
end
alias on_csend on_send

private

Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/style/braces_around_hash_parameters.rb
Expand Up @@ -53,6 +53,7 @@ def on_send(node)

check(node.last_argument, node.arguments)
end
alias on_csend on_send

# We let AutocorrectUnlessChangingAST#autocorrect work with the send
# node, because that context is needed. When parsing the code to see if
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/style/method_call_with_args_parentheses.rb
Expand Up @@ -142,6 +142,7 @@ def on_send(node)
add_offense_for_omit_parentheses(node)
end
end
alias on_csend on_send
alias on_super on_send
alias on_yield on_send

Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/style/method_called_on_do_end_block.rb
Expand Up @@ -39,6 +39,7 @@ def on_send(node)

add_offense(nil, location: range)
end
alias on_csend on_send
end
end
end
Expand Down
3 changes: 2 additions & 1 deletion lib/rubocop/cop/style/nested_parenthesized_calls.rb
Expand Up @@ -20,14 +20,15 @@ class NestedParenthesizedCalls < Cop
def on_send(node)
return unless node.parenthesized?

node.each_child_node(:send) do |nested|
node.each_child_node(:send, :csend) do |nested|
next if allowed_omission?(nested)

add_offense(nested,
location: nested.source_range,
message: format(MSG, source: nested.source))
end
end
alias on_csend on_send

def autocorrect(nested)
first_arg = nested.first_argument.source_range
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/style/preferred_hash_methods.rb
Expand Up @@ -41,6 +41,7 @@ def on_send(node)

add_offense(node, location: :selector)
end
alias on_csend on_send

def autocorrect(node)
lambda do |corrector|
Expand Down
3 changes: 2 additions & 1 deletion lib/rubocop/cop/style/send.rb
Expand Up @@ -17,13 +17,14 @@ class Send < Cop
MSG = 'Prefer `Object#__send__` or `Object#public_send` to ' \
'`send`.'.freeze

def_node_matcher :sending?, '(send _ :send ...)'
def_node_matcher :sending?, '({send csend} _ :send ...)'

def on_send(node)
return unless sending?(node) && node.arguments?

add_offense(node, location: :selector)
end
alias on_csend on_send
end
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/style/string_methods.rb
Expand Up @@ -24,6 +24,7 @@ def on_send(node)

add_offense(node, location: :selector)
end
alias on_csend on_send

def autocorrect(node)
lambda do |corrector|
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/style/trailing_comma_in_arguments.rb
Expand Up @@ -59,6 +59,7 @@ def on_send(node)
node.last_argument.source_range.end_pos,
node.source_range.end_pos)
end
alias on_csend on_send

def autocorrect(range)
PunctuationCorrector.swap_comma(range)
Expand Down
10 changes: 10 additions & 0 deletions spec/rubocop/cop/layout/align_parameters_spec.rb
Expand Up @@ -421,6 +421,16 @@ class MyModel < ActiveRecord::Base
end
RUBY
end

context 'when using safe navigation operator', :ruby23 do
it 'registers an offense for parameters with single indent' do
expect_offense(<<-RUBY.strip_indent)
receiver&.function(a,
if b then c else d end)
^^^^^^^^^^^^^^^^^^^^^^ Align the parameters of a method call if they span more than one line.
RUBY
end
end
end

context 'aligned with fixed indentation' do
Expand Down
11 changes: 11 additions & 0 deletions spec/rubocop/cop/layout/closing_parenthesis_indentation_spec.rb
Expand Up @@ -387,6 +387,17 @@
.methC
RUBY
end

context 'when using safe navigation operator', :ruby23 do
it 'registers an offense for misaligned )' do
expect_offense(<<-RUBY.strip_indent)
receiver&.some_method(
a
)
^ Indent `)` to column 0 (not 2)
RUBY
end
end
end

context 'for method definitions' do
Expand Down

0 comments on commit 548bf43

Please sign in to comment.