rubocop 0.52.1 → 0.53.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/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/config/default.yml +118 -46
- data/config/disabled.yml +8 -8
- data/config/enabled.yml +84 -28
- data/lib/rubocop.rb +28 -8
- data/lib/rubocop/ast/builder.rb +35 -37
- data/lib/rubocop/ast/node.rb +16 -1
- data/lib/rubocop/ast/node/and_node.rb +0 -8
- data/lib/rubocop/ast/node/block_node.rb +1 -9
- data/lib/rubocop/ast/node/case_node.rb +0 -8
- data/lib/rubocop/ast/node/ensure_node.rb +0 -8
- data/lib/rubocop/ast/node/for_node.rb +0 -8
- data/lib/rubocop/ast/node/or_node.rb +0 -8
- data/lib/rubocop/ast/node/pair_node.rb +0 -8
- data/lib/rubocop/ast/node/resbody_node.rb +0 -8
- data/lib/rubocop/ast/node/send_node.rb +0 -8
- data/lib/rubocop/ast/node/symbol_node.rb +0 -8
- data/lib/rubocop/ast/node/until_node.rb +0 -8
- data/lib/rubocop/ast/node/when_node.rb +0 -8
- data/lib/rubocop/ast/node/while_node.rb +0 -8
- data/lib/rubocop/cli.rb +17 -7
- data/lib/rubocop/comment_config.rb +24 -3
- data/lib/rubocop/config.rb +75 -6
- data/lib/rubocop/config_loader.rb +18 -28
- data/lib/rubocop/config_loader_resolver.rb +61 -9
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +3 -1
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +4 -2
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
- data/lib/rubocop/cop/commissioner.rb +2 -2
- data/lib/rubocop/cop/cop.rb +4 -0
- data/lib/rubocop/cop/corrector.rb +11 -1
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -6
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +59 -0
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/space_corrector.rb +13 -0
- data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +1 -1
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +3 -1
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +3 -5
- data/lib/rubocop/cop/generator.rb +29 -8
- data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +2 -0
- data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +2 -0
- data/lib/rubocop/cop/layout/align_hash.rb +106 -37
- data/lib/rubocop/cop/{lint → layout}/block_alignment.rb +8 -5
- data/lib/rubocop/cop/layout/block_end_newline.rb +7 -17
- data/lib/rubocop/cop/layout/case_indentation.rb +1 -0
- data/lib/rubocop/cop/layout/class_structure.rb +6 -7
- data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
- data/lib/rubocop/cop/{lint → layout}/condition_position.rb +3 -3
- data/lib/rubocop/cop/{lint → layout}/def_end_alignment.rb +2 -1
- data/lib/rubocop/cop/layout/else_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_comment.rb +140 -0
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +2 -0
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -0
- data/lib/rubocop/cop/layout/empty_lines.rb +3 -1
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +7 -5
- data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +20 -10
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +20 -0
- data/lib/rubocop/cop/{lint → layout}/end_alignment.rb +37 -6
- data/lib/rubocop/cop/layout/end_of_line.rb +1 -0
- data/lib/rubocop/cop/layout/extra_spacing.rb +30 -37
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -0
- data/lib/rubocop/cop/layout/indent_heredoc.rb +38 -2
- data/lib/rubocop/cop/layout/indentation_consistency.rb +105 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +4 -3
- data/lib/rubocop/cop/layout/initial_indentation.rb +15 -1
- data/lib/rubocop/cop/layout/leading_comment_space.rb +4 -2
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +62 -29
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +74 -33
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +16 -2
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -1
- data/lib/rubocop/cop/layout/space_after_method_name.rb +2 -0
- data/lib/rubocop/cop/layout/space_after_not.rb +2 -0
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -0
- data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +15 -2
- data/lib/rubocop/cop/layout/space_around_operators.rb +15 -13
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +13 -1
- data/lib/rubocop/cop/layout/space_before_comment.rb +6 -4
- data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -0
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -0
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +30 -45
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +3 -2
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +48 -18
- data/lib/rubocop/cop/layout/space_inside_parens.rb +8 -7
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +57 -11
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +1 -0
- data/lib/rubocop/cop/layout/tab.rb +42 -16
- data/lib/rubocop/cop/layout/trailing_blank_lines.rb +46 -13
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +12 -0
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +5 -3
- data/lib/rubocop/cop/lint/big_decimal_new.rb +44 -0
- data/lib/rubocop/cop/lint/boolean_symbol.rb +2 -2
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +2 -2
- data/lib/rubocop/cop/lint/debugger.rb +2 -2
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +5 -4
- data/lib/rubocop/cop/lint/duplicate_methods.rb +20 -9
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +4 -3
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +16 -10
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +5 -4
- data/lib/rubocop/cop/lint/inherit_exception.rb +2 -2
- data/lib/rubocop/cop/lint/interpolation_check.rb +4 -3
- data/lib/rubocop/cop/lint/literal_as_condition.rb +2 -2
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +2 -0
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +7 -5
- data/lib/rubocop/cop/lint/nested_percent_literal.rb +1 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +59 -0
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +86 -0
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +2 -0
- data/lib/rubocop/cop/lint/percent_string_array.rb +0 -2
- data/lib/rubocop/cop/lint/rand_one.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -0
- data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -0
- data/lib/rubocop/cop/lint/require_parentheses.rb +2 -0
- data/lib/rubocop/cop/lint/rescue_type.rb +6 -3
- data/lib/rubocop/cop/lint/return_in_void_context.rb +2 -2
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -21
- data/lib/rubocop/cop/lint/script_permission.rb +30 -10
- data/lib/rubocop/cop/lint/shadowed_argument.rb +3 -3
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +2 -2
- data/lib/rubocop/cop/lint/unified_integer.rb +2 -2
- data/lib/rubocop/cop/lint/{unneeded_disable.rb → unneeded_cop_disable_directive.rb} +13 -7
- data/lib/rubocop/cop/lint/unneeded_cop_enable_directive.rb +97 -0
- data/lib/rubocop/cop/lint/unneeded_require_statement.rb +1 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +3 -3
- data/lib/rubocop/cop/lint/uri_escape_unescape.rb +11 -10
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +7 -5
- data/lib/rubocop/cop/lint/useless_assignment.rb +2 -2
- data/lib/rubocop/cop/lint/useless_setter_call.rb +2 -2
- data/lib/rubocop/cop/lint/void.rb +49 -10
- data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
- data/lib/rubocop/cop/metrics/line_length.rb +5 -2
- data/lib/rubocop/cop/mixin/alignment.rb +4 -0
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -1
- data/lib/rubocop/cop/mixin/def_node.rb +4 -0
- data/lib/rubocop/cop/mixin/documentation_comment.rb +11 -3
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +12 -2
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +20 -1
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -0
- data/lib/rubocop/cop/mixin/hash_alignment.rb +2 -2
- data/lib/rubocop/cop/mixin/match_range.rb +2 -0
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +6 -0
- data/lib/rubocop/cop/mixin/nil_methods.rb +19 -0
- data/lib/rubocop/cop/mixin/percent_literal.rb +57 -9
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -5
- data/lib/rubocop/cop/mixin/range_help.rb +102 -0
- data/lib/rubocop/cop/mixin/rescue_node.rb +1 -1
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +8 -7
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +11 -9
- data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -10
- data/lib/rubocop/cop/mixin/surrounding_space.rb +38 -8
- data/lib/rubocop/cop/mixin/trailing_body.rb +26 -0
- data/lib/rubocop/cop/mixin/trailing_comma.rb +15 -3
- data/lib/rubocop/cop/mixin/uncommunicative_name.rb +104 -0
- data/lib/rubocop/cop/naming/ascii_identifiers.rb +3 -1
- data/lib/rubocop/cop/naming/file_name.rb +5 -10
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +76 -0
- data/lib/rubocop/cop/naming/uncommunicative_block_param_name.rb +48 -0
- data/lib/rubocop/cop/naming/uncommunicative_method_param_name.rb +57 -0
- data/lib/rubocop/cop/offense.rb +3 -2
- data/lib/rubocop/cop/performance/case_when_splat.rb +1 -0
- data/lib/rubocop/cop/performance/casecmp.rb +17 -8
- data/lib/rubocop/cop/performance/compare_with_block.rb +2 -0
- data/lib/rubocop/cop/performance/count.rb +1 -0
- data/lib/rubocop/cop/performance/fixed_size.rb +41 -0
- data/lib/rubocop/cop/performance/flat_map.rb +2 -0
- data/lib/rubocop/cop/performance/lstrip_rstrip.rb +2 -0
- data/lib/rubocop/cop/performance/redundant_merge.rb +1 -1
- data/lib/rubocop/cop/performance/redundant_sort_by.rb +2 -0
- data/lib/rubocop/cop/performance/regexp_match.rb +4 -0
- data/lib/rubocop/cop/performance/reverse_each.rb +2 -0
- data/lib/rubocop/cop/performance/string_replacement.rb +2 -0
- data/lib/rubocop/cop/rails/active_record_aliases.rb +46 -0
- data/lib/rubocop/cop/rails/blank.rb +3 -3
- data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +6 -0
- data/lib/rubocop/cop/rails/delegate.rb +6 -6
- data/lib/rubocop/cop/rails/file_path.rb +7 -1
- data/lib/rubocop/cop/rails/find_by.rb +2 -0
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +17 -5
- data/lib/rubocop/cop/rails/inverse_of.rb +21 -2
- data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +45 -9
- data/lib/rubocop/cop/rails/presence.rb +8 -2
- data/lib/rubocop/cop/rails/present.rb +5 -5
- data/lib/rubocop/cop/rails/read_write_attribute.rb +4 -3
- data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +1 -0
- data/lib/rubocop/cop/rails/relative_date_constant.rb +4 -3
- data/lib/rubocop/cop/rails/request_referer.rb +3 -2
- data/lib/rubocop/cop/rails/reversible_migration.rb +9 -8
- data/lib/rubocop/cop/rails/safe_navigation.rb +3 -2
- data/lib/rubocop/cop/rails/save_bang.rb +11 -12
- data/lib/rubocop/cop/rails/skips_model_validations.rb +2 -2
- data/lib/rubocop/cop/rails/time_zone.rb +38 -16
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +26 -16
- data/lib/rubocop/cop/rails/validation.rb +30 -2
- data/lib/rubocop/cop/security/open.rb +48 -0
- data/lib/rubocop/cop/style/and_or.rb +1 -0
- data/lib/rubocop/cop/style/ascii_comments.rb +3 -1
- data/lib/rubocop/cop/style/attr.rb +2 -0
- data/lib/rubocop/cop/style/block_comments.rb +3 -1
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +2 -5
- data/lib/rubocop/cop/style/class_and_module_children.rb +1 -0
- data/lib/rubocop/cop/style/class_vars.rb +23 -0
- data/lib/rubocop/cop/style/colon_method_call.rb +1 -2
- data/lib/rubocop/cop/style/comment_annotation.rb +6 -4
- data/lib/rubocop/cop/style/commented_keyword.rb +3 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +1 -1
- data/lib/rubocop/cop/style/copyright.rb +3 -1
- data/lib/rubocop/cop/style/each_with_object.rb +15 -1
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -0
- data/lib/rubocop/cop/style/empty_case_condition.rb +2 -0
- data/lib/rubocop/cop/style/empty_else.rb +9 -5
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -0
- data/lib/rubocop/cop/style/empty_line_after_guard_clause.rb +80 -0
- data/lib/rubocop/cop/style/empty_literal.rb +1 -0
- data/lib/rubocop/cop/style/encoding.rb +2 -0
- data/lib/rubocop/cop/style/expand_path_arguments.rb +194 -0
- data/lib/rubocop/cop/style/for.rb +33 -0
- data/lib/rubocop/cop/style/format_string.rb +1 -1
- data/lib/rubocop/cop/style/format_string_token.rb +4 -5
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -1
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -1
- data/lib/rubocop/cop/style/inline_comment.rb +1 -1
- data/lib/rubocop/cop/style/lambda.rb +1 -1
- data/lib/rubocop/cop/style/line_end_concatenation.rb +2 -0
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -0
- data/lib/rubocop/cop/style/missing_else.rb +72 -7
- data/lib/rubocop/cop/style/mixin_usage.rb +3 -5
- data/lib/rubocop/cop/style/module_function.rb +10 -0
- data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -0
- data/lib/rubocop/cop/style/multiline_if_then.rb +1 -0
- data/lib/rubocop/cop/style/nested_modifier.rb +2 -0
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -0
- data/lib/rubocop/cop/style/next.rb +1 -0
- data/lib/rubocop/cop/style/not.rb +2 -0
- data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
- data/lib/rubocop/cop/style/one_line_conditional.rb +2 -2
- data/lib/rubocop/cop/style/redundant_exception.rb +8 -3
- data/lib/rubocop/cop/style/redundant_return.rb +37 -3
- data/lib/rubocop/cop/style/redundant_self.rb +1 -1
- data/lib/rubocop/cop/style/rescue_standard_error.rb +1 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +74 -32
- data/lib/rubocop/cop/style/semicolon.rb +3 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +14 -23
- data/lib/rubocop/cop/style/stderr_puts.rb +2 -0
- data/lib/rubocop/cop/style/string_hash_keys.rb +12 -0
- data/lib/rubocop/cop/style/string_literals.rb +1 -1
- data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +1 -1
- data/lib/rubocop/cop/style/symbol_array.rb +29 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
- data/lib/rubocop/cop/style/trailing_body_on_class.rb +43 -0
- data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +7 -54
- data/lib/rubocop/cop/style/trailing_body_on_module.rb +43 -0
- data/lib/rubocop/cop/style/{trailing_comma_in_literal.rb → trailing_comma_in_array_literal.rb} +2 -20
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +56 -0
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +17 -20
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -0
- data/lib/rubocop/cop/style/unless_else.rb +2 -0
- data/lib/rubocop/cop/style/word_array.rb +0 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +1 -0
- data/lib/rubocop/cop/team.rb +5 -5
- data/lib/rubocop/cop/util.rb +23 -188
- data/lib/rubocop/cop/variable_force.rb +1 -1
- data/lib/rubocop/file_finder.rb +45 -0
- data/lib/rubocop/formatter/disabled_config_formatter.rb +23 -14
- data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/html_formatter.rb +12 -5
- data/lib/rubocop/formatter/json_formatter.rb +1 -1
- data/lib/rubocop/node_pattern.rb +8 -5
- data/lib/rubocop/options.rb +40 -33
- data/lib/rubocop/path_util.rb +5 -8
- data/lib/rubocop/processed_source.rb +53 -0
- data/lib/rubocop/remote_config.rb +1 -1
- data/lib/rubocop/result_cache.rb +1 -1
- data/lib/rubocop/rspec/cop_helper.rb +0 -4
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -4
- data/lib/rubocop/rspec/shared_contexts.rb +3 -1
- data/lib/rubocop/rspec/shared_examples.rb +23 -25
- data/lib/rubocop/rspec/support.rb +5 -0
- data/lib/rubocop/runner.rb +3 -2
- data/lib/rubocop/string_util.rb +10 -9
- data/lib/rubocop/target_finder.rb +4 -1
- data/lib/rubocop/token.rb +26 -16
- data/lib/rubocop/version.rb +6 -4
- metadata +31 -17
- data/lib/rubocop/cop/performance/hash_each_methods.rb +0 -129
@@ -138,7 +138,7 @@ module RuboCop
|
|
138
138
|
else elsif end ensure false for if in module
|
139
139
|
next nil not or redo rescue retry return self
|
140
140
|
super then true undef unless until when while
|
141
|
-
yield].include?(method_name)
|
141
|
+
yield __FILE__ __LINE__ __ENCODING__].include?(method_name)
|
142
142
|
end
|
143
143
|
|
144
144
|
def allow_self(node)
|
@@ -5,7 +5,10 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# This cop transforms usages of a method call safeguarded by a non `nil`
|
7
7
|
# check for the variable whose method is being called to
|
8
|
-
# safe navigation (`&.`).
|
8
|
+
# safe navigation (`&.`). If there is a method chain, all of the methods
|
9
|
+
# in the chain need to be checked for safety, and all of the methods will
|
10
|
+
# need to be changed to use safe navigation. We have limited the cop to
|
11
|
+
# not register an offense for method chains that exceed 2 methods.
|
9
12
|
#
|
10
13
|
# Configuration option: ConvertCodeThatCanStartToReturnNil
|
11
14
|
# The default for this is `false`. When configured to `true`, this will
|
@@ -18,6 +21,7 @@ module RuboCop
|
|
18
21
|
# @example
|
19
22
|
# # bad
|
20
23
|
# foo.bar if foo
|
24
|
+
# foo.bar.baz if foo
|
21
25
|
# foo.bar(param1, param2) if foo
|
22
26
|
# foo.bar { |e| e.something } if foo
|
23
27
|
# foo.bar(param) { |e| e.something } if foo
|
@@ -27,28 +31,40 @@ module RuboCop
|
|
27
31
|
# foo.bar unless foo.nil?
|
28
32
|
#
|
29
33
|
# foo && foo.bar
|
34
|
+
# foo && foo.bar.baz
|
30
35
|
# foo && foo.bar(param1, param2)
|
31
36
|
# foo && foo.bar { |e| e.something }
|
32
37
|
# foo && foo.bar(param) { |e| e.something }
|
33
38
|
#
|
34
39
|
# # good
|
35
40
|
# foo&.bar
|
41
|
+
# foo&.bar&.baz
|
36
42
|
# foo&.bar(param1, param2)
|
37
43
|
# foo&.bar { |e| e.something }
|
38
44
|
# foo&.bar(param) { |e| e.something }
|
45
|
+
# foo && foo.bar.baz.qux # method chain with more than 2 methods
|
46
|
+
# foo && foo.nil? # method that `nil` responds to
|
39
47
|
#
|
48
|
+
# # Method calls that do not use `.`
|
49
|
+
# foo && foo < bar
|
50
|
+
# foo < bar if foo
|
51
|
+
#
|
52
|
+
# # This could start returning `nil` as well as the return of the method
|
40
53
|
# foo.nil? || foo.bar
|
41
54
|
# !foo || foo.bar
|
42
55
|
#
|
43
|
-
# # Methods that
|
44
|
-
# # use safe navigation
|
45
|
-
# foo.
|
56
|
+
# # Methods that are used on assignment, arithmetic operation or
|
57
|
+
# # comparison should not be converted to use safe navigation
|
58
|
+
# foo.baz = bar if foo
|
59
|
+
# foo.baz + bar if foo
|
60
|
+
# foo.bar > 2 if foo
|
46
61
|
class SafeNavigation < Cop
|
47
62
|
extend TargetRubyVersion
|
63
|
+
include NilMethods
|
64
|
+
include RangeHelp
|
48
65
|
|
49
66
|
MSG = 'Use safe navigation (`&.`) instead of checking if an object ' \
|
50
67
|
'exists before calling the method.'.freeze
|
51
|
-
NIL_METHODS = nil.methods.freeze
|
52
68
|
|
53
69
|
minimum_target_ruby_version 2.3
|
54
70
|
|
@@ -81,9 +97,12 @@ module RuboCop
|
|
81
97
|
|
82
98
|
def check_node(node)
|
83
99
|
return if target_ruby_version < 2.3
|
84
|
-
checked_variable, receiver, method = extract_parts(node)
|
100
|
+
checked_variable, receiver, method_chain, method = extract_parts(node)
|
85
101
|
return unless receiver == checked_variable
|
86
|
-
|
102
|
+
# method is already a method call so this is actually checking for a
|
103
|
+
# chain greater than 2
|
104
|
+
return if chain_size(method_chain, method) > 1
|
105
|
+
return if unsafe_method_used?(method_chain, method)
|
87
106
|
|
88
107
|
add_offense(node)
|
89
108
|
end
|
@@ -96,7 +115,9 @@ module RuboCop
|
|
96
115
|
lambda do |corrector|
|
97
116
|
corrector.remove(begin_range(node, body))
|
98
117
|
corrector.remove(end_range(node, body))
|
99
|
-
corrector.insert_before(
|
118
|
+
corrector.insert_before(method_call.loc.dot, '&')
|
119
|
+
|
120
|
+
add_safe_nav_to_all_methods_in_chain(corrector, method_call, body)
|
100
121
|
end
|
101
122
|
end
|
102
123
|
|
@@ -116,10 +137,12 @@ module RuboCop
|
|
116
137
|
end
|
117
138
|
|
118
139
|
def extract_parts_from_if(node)
|
119
|
-
|
140
|
+
variable, receiver =
|
120
141
|
modifier_if_safe_navigation_candidate?(node)
|
121
142
|
|
122
|
-
|
143
|
+
checked_variable, matching_receiver, method =
|
144
|
+
extract_common_parts(receiver, variable)
|
145
|
+
[checked_variable, matching_receiver, receiver, method]
|
123
146
|
end
|
124
147
|
|
125
148
|
def extract_parts_from_and(node)
|
@@ -129,49 +152,56 @@ module RuboCop
|
|
129
152
|
not_nil_check?(checked_variable) || checked_variable
|
130
153
|
end
|
131
154
|
|
132
|
-
|
155
|
+
checked_variable, matching_receiver, method =
|
156
|
+
extract_common_parts(rhs, checked_variable)
|
157
|
+
[checked_variable, matching_receiver, rhs, method]
|
133
158
|
end
|
134
159
|
|
135
|
-
def extract_common_parts(
|
160
|
+
def extract_common_parts(method_chain, checked_variable)
|
136
161
|
matching_receiver =
|
137
|
-
find_matching_receiver_invocation(
|
162
|
+
find_matching_receiver_invocation(method_chain, checked_variable)
|
138
163
|
|
139
164
|
method = matching_receiver.parent if matching_receiver
|
140
165
|
|
141
166
|
[checked_variable, matching_receiver, method]
|
142
167
|
end
|
143
168
|
|
144
|
-
def find_matching_receiver_invocation(
|
145
|
-
return nil unless
|
169
|
+
def find_matching_receiver_invocation(method_chain, checked_variable)
|
170
|
+
return nil unless method_chain
|
146
171
|
|
147
|
-
receiver = if
|
148
|
-
|
172
|
+
receiver = if method_chain.block_type?
|
173
|
+
method_chain.send_node.receiver
|
149
174
|
else
|
150
|
-
|
175
|
+
method_chain.receiver
|
151
176
|
end
|
152
177
|
|
153
|
-
if receiver == checked_variable
|
154
|
-
return nil if assignment_arithmetic_or_comparison?(node)
|
155
|
-
|
156
|
-
return receiver
|
157
|
-
end
|
158
|
-
|
178
|
+
return receiver if receiver == checked_variable
|
159
179
|
find_matching_receiver_invocation(receiver, checked_variable)
|
160
180
|
end
|
161
181
|
|
162
|
-
def
|
163
|
-
|
164
|
-
|
165
|
-
|
182
|
+
def chain_size(method_chain, method)
|
183
|
+
method.each_ancestor(:send).inject(0) do |total, ancestor|
|
184
|
+
break total + 1 if ancestor == method_chain
|
185
|
+
total + 1
|
186
|
+
end
|
166
187
|
end
|
167
188
|
|
168
|
-
def
|
169
|
-
|
189
|
+
def unsafe_method_used?(method_chain, method)
|
190
|
+
return true if unsafe_method?(method)
|
191
|
+
|
192
|
+
method.each_ancestor(:send).any? do |ancestor|
|
193
|
+
unless config.for_cop('Lint/SafeNavigationChain')['Enabled']
|
194
|
+
break true
|
195
|
+
end
|
196
|
+
|
197
|
+
break true if unsafe_method?(ancestor)
|
198
|
+
break true if nil_methods.include?(ancestor.method_name)
|
199
|
+
break false if ancestor == method_chain
|
200
|
+
end
|
170
201
|
end
|
171
202
|
|
172
203
|
def unsafe_method?(send_node)
|
173
|
-
|
174
|
-
negated?(send_node) || !send_node.dot?
|
204
|
+
negated?(send_node) || send_node.assignment? || !send_node.dot?
|
175
205
|
end
|
176
206
|
|
177
207
|
def negated?(send_node)
|
@@ -191,6 +221,18 @@ module RuboCop
|
|
191
221
|
range_between(method_call.loc.expression.end_pos,
|
192
222
|
node.loc.expression.end_pos)
|
193
223
|
end
|
224
|
+
|
225
|
+
def add_safe_nav_to_all_methods_in_chain(corrector,
|
226
|
+
start_method,
|
227
|
+
method_chain)
|
228
|
+
start_method.each_ancestor do |ancestor|
|
229
|
+
break unless %i[send block].include?(ancestor.type)
|
230
|
+
next unless ancestor.send_type?
|
231
|
+
break if ancestor == method_chain
|
232
|
+
|
233
|
+
corrector.insert_before(ancestor.loc.dot, '&')
|
234
|
+
end
|
235
|
+
end
|
194
236
|
end
|
195
237
|
end
|
196
238
|
end
|
@@ -16,10 +16,12 @@ module RuboCop
|
|
16
16
|
# bar = 2
|
17
17
|
# baz = 3
|
18
18
|
class Semicolon < Cop
|
19
|
+
include RangeHelp
|
20
|
+
|
19
21
|
MSG = 'Do not use semicolons to terminate expressions.'.freeze
|
20
22
|
|
21
23
|
def investigate(processed_source)
|
22
|
-
return
|
24
|
+
return if processed_source.blank?
|
23
25
|
@processed_source = processed_source
|
24
26
|
|
25
27
|
check_for_line_terminator_or_opener
|
@@ -31,17 +31,20 @@ module RuboCop
|
|
31
31
|
alias on_defs on_def
|
32
32
|
|
33
33
|
def autocorrect(node)
|
34
|
-
body = node.body
|
35
|
-
|
36
34
|
lambda do |corrector|
|
37
|
-
each_part(body) do |part|
|
38
|
-
break_line_before(
|
35
|
+
each_part(node.body) do |part|
|
36
|
+
LineBreakCorrector.break_line_before(
|
37
|
+
range: part, node: node, corrector: corrector,
|
38
|
+
configured_width: configured_indentation_width
|
39
|
+
)
|
39
40
|
end
|
40
41
|
|
41
|
-
break_line_before(
|
42
|
+
LineBreakCorrector.break_line_before(
|
43
|
+
range: node.loc.end, node: node, corrector: corrector,
|
44
|
+
indent_steps: 0, configured_width: configured_indentation_width
|
45
|
+
)
|
42
46
|
|
43
|
-
|
44
|
-
move_comment(eol_comment, node, corrector) if eol_comment
|
47
|
+
move_comment(node, corrector)
|
45
48
|
end
|
46
49
|
end
|
47
50
|
|
@@ -51,10 +54,6 @@ module RuboCop
|
|
51
54
|
cop_config['AllowIfMethodIsEmpty']
|
52
55
|
end
|
53
56
|
|
54
|
-
def end_of_line_comment(line)
|
55
|
-
processed_source.comments.find { |c| c.loc.line == line }
|
56
|
-
end
|
57
|
-
|
58
57
|
def each_part(body)
|
59
58
|
return unless body
|
60
59
|
|
@@ -65,20 +64,12 @@ module RuboCop
|
|
65
64
|
end
|
66
65
|
end
|
67
66
|
|
68
|
-
def
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
indent_steps * configured_indentation_width)
|
67
|
+
def move_comment(node, corrector)
|
68
|
+
LineBreakCorrector.move_comment(
|
69
|
+
eol_comment: end_of_line_comment(node.source_range.line),
|
70
|
+
node: node, corrector: corrector
|
73
71
|
)
|
74
72
|
end
|
75
|
-
|
76
|
-
def move_comment(eol_comment, node, corrector)
|
77
|
-
text = eol_comment.loc.expression.source
|
78
|
-
corrector.insert_before(node.source_range,
|
79
|
-
text + "\n" + (' ' * node.loc.keyword.column))
|
80
|
-
corrector.remove(eol_comment.loc.expression)
|
81
|
-
end
|
82
73
|
end
|
83
74
|
end
|
84
75
|
end
|
@@ -19,8 +19,20 @@ module RuboCop
|
|
19
19
|
(pair (str _) _)
|
20
20
|
PATTERN
|
21
21
|
|
22
|
+
def_node_matcher :receive_environments_method?, <<-PATTERN
|
23
|
+
{
|
24
|
+
^^(send (const {nil? cbase} :IO) :popen ...)
|
25
|
+
^^(send (const {nil? cbase} :Open3)
|
26
|
+
{:capture2 :capture2e :capture3 :popen2 :popen2e :popen3} ...)
|
27
|
+
^^^(send (const {nil? cbase} :Open3)
|
28
|
+
{:pipeline :pipeline_r :pipeline_rw :pipeline_start :pipeline_w} ...)
|
29
|
+
^^(send {nil? (const {nil? cbase} :Kernel)} {:spawn :system} ...)
|
30
|
+
}
|
31
|
+
PATTERN
|
32
|
+
|
22
33
|
def on_pair(node)
|
23
34
|
return unless string_hash_key?(node)
|
35
|
+
return if receive_environments_method?(node)
|
24
36
|
add_offense(node.key)
|
25
37
|
end
|
26
38
|
|
@@ -75,6 +75,35 @@ module RuboCop
|
|
75
75
|
corrector.replace(node.source_range, "[#{syms.join(', ')}]")
|
76
76
|
end
|
77
77
|
end
|
78
|
+
|
79
|
+
def to_symbol_literal(string)
|
80
|
+
if symbol_without_quote?(string)
|
81
|
+
":#{string}"
|
82
|
+
else
|
83
|
+
":#{to_string_literal(string)}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def symbol_without_quote?(string)
|
88
|
+
special_gvars = %w[
|
89
|
+
$! $" $$ $& $' $* $+ $, $/ $; $: $. $< $= $> $? $@ $\\ $_ $` $~ $0
|
90
|
+
$-0 $-F $-I $-K $-W $-a $-d $-i $-l $-p $-v $-w
|
91
|
+
]
|
92
|
+
redefinable_operators = %w(
|
93
|
+
| ^ & <=> == === =~ > >= < <= << >>
|
94
|
+
+ - * / % ** ~ +@ -@ [] []= ` ! != !~
|
95
|
+
)
|
96
|
+
|
97
|
+
# method name
|
98
|
+
string =~ /\A[a-zA-Z_]\w*[!?]?\z/ ||
|
99
|
+
# instance / class variable
|
100
|
+
string =~ /\A\@\@?[a-zA-Z_]\w*\z/ ||
|
101
|
+
# global variable
|
102
|
+
string =~ /\A\$[1-9]\d*\z/ ||
|
103
|
+
string =~ /\A\$[a-zA-Z_]\w*\z/ ||
|
104
|
+
special_gvars.include?(string) ||
|
105
|
+
redefinable_operators.include?(string)
|
106
|
+
end
|
78
107
|
end
|
79
108
|
end
|
80
109
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for trailing code after the class definition.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # bad
|
10
|
+
# class Foo; def foo; end
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# class Foo
|
15
|
+
# def foo; end
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
class TrailingBodyOnClass < Cop
|
19
|
+
include Alignment
|
20
|
+
include TrailingBody
|
21
|
+
|
22
|
+
MSG = 'Place the first line of class body on its own line.'.freeze
|
23
|
+
|
24
|
+
def on_class(node)
|
25
|
+
return unless trailing_body?(node)
|
26
|
+
|
27
|
+
add_offense(node, location: first_part_of(node.to_a.last))
|
28
|
+
end
|
29
|
+
|
30
|
+
def autocorrect(node)
|
31
|
+
lambda do |corrector|
|
32
|
+
LineBreakCorrector.correct_trailing_body(
|
33
|
+
configured_width: configured_indentation_width,
|
34
|
+
corrector: corrector,
|
35
|
+
node: node,
|
36
|
+
processed_source: processed_source
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -26,6 +26,7 @@ module RuboCop
|
|
26
26
|
#
|
27
27
|
class TrailingBodyOnMethodDefinition < Cop
|
28
28
|
include Alignment
|
29
|
+
include TrailingBody
|
29
30
|
|
30
31
|
MSG = "Place the first line of a multi-line method definition's " \
|
31
32
|
'body on its own line.'.freeze
|
@@ -39,60 +40,12 @@ module RuboCop
|
|
39
40
|
|
40
41
|
def autocorrect(node)
|
41
42
|
lambda do |corrector|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
def trailing_body?(node)
|
51
|
-
node.body && node.multiline? && on_def_line?(node)
|
52
|
-
end
|
53
|
-
|
54
|
-
def on_def_line?(node)
|
55
|
-
node.source_range.first_line == node.body.source_range.first_line
|
56
|
-
end
|
57
|
-
|
58
|
-
def break_line_before_body(node, corrector)
|
59
|
-
corrector.insert_before(
|
60
|
-
first_part_of(node.body),
|
61
|
-
"\n" + ' ' * (node.loc.keyword.column +
|
62
|
-
configured_indentation_width)
|
63
|
-
)
|
64
|
-
end
|
65
|
-
|
66
|
-
def first_part_of(body)
|
67
|
-
if body.begin_type?
|
68
|
-
body.children.first.source_range
|
69
|
-
else
|
70
|
-
body.source_range
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def move_comment(node, corrector)
|
75
|
-
eol_comment = end_of_line_comment(node.source_range.line)
|
76
|
-
return unless eol_comment
|
77
|
-
|
78
|
-
text = eol_comment.loc.expression.source
|
79
|
-
corrector.insert_before(node.source_range,
|
80
|
-
text + "\n" + (' ' * node.loc.keyword.column))
|
81
|
-
corrector.remove(eol_comment.loc.expression)
|
82
|
-
end
|
83
|
-
|
84
|
-
def end_of_line_comment(line)
|
85
|
-
processed_source.comments.find { |c| c.loc.line == line }
|
86
|
-
end
|
87
|
-
|
88
|
-
def remove_semicolon(corrector)
|
89
|
-
return unless semicolon
|
90
|
-
corrector.remove(semicolon.pos)
|
91
|
-
end
|
92
|
-
|
93
|
-
def semicolon
|
94
|
-
@semicolon ||= processed_source.tokens.find do |token|
|
95
|
-
token.line == 1 && token.semicolon?
|
43
|
+
LineBreakCorrector.correct_trailing_body(
|
44
|
+
configured_width: configured_indentation_width,
|
45
|
+
corrector: corrector,
|
46
|
+
node: node,
|
47
|
+
processed_source: processed_source
|
48
|
+
)
|
96
49
|
end
|
97
50
|
end
|
98
51
|
end
|