rubocop 1.66.0 → 1.72.1
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 +160 -14
- data/config/internal_affairs.yml +11 -0
- data/lib/rubocop/cached_data.rb +12 -4
- data/lib/rubocop/cli/command/auto_generate_config.rb +6 -7
- data/lib/rubocop/cli/command/execute_runner.rb +4 -4
- data/lib/rubocop/cli/command/lsp.rb +2 -2
- data/lib/rubocop/cli/command/show_cops.rb +24 -2
- data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
- data/lib/rubocop/cli/command/version.rb +2 -2
- data/lib/rubocop/comment_config.rb +6 -10
- data/lib/rubocop/config.rb +21 -20
- data/lib/rubocop/config_loader.rb +62 -16
- data/lib/rubocop/config_loader_resolver.rb +36 -11
- data/lib/rubocop/config_validator.rb +25 -18
- data/lib/rubocop/cop/autocorrect_logic.rb +36 -19
- data/lib/rubocop/cop/base.rb +13 -3
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
- data/lib/rubocop/cop/bundler/gem_version.rb +1 -0
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
- data/lib/rubocop/cop/cop.rb +8 -0
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
- data/lib/rubocop/cop/generator.rb +6 -0
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +0 -4
- data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
- data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +2 -2
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +229 -0
- data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
- data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
- data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
- data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
- data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +11 -2
- data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +7 -1
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +0 -5
- data/lib/rubocop/cop/internal_affairs.rb +6 -0
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +6 -2
- data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
- data/lib/rubocop/cop/layout/class_structure.rb +9 -9
- data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +1 -1
- data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +3 -3
- data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +3 -8
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/hash_alignment.rb +6 -4
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +11 -12
- data/lib/rubocop/cop/layout/leading_comment_space.rb +71 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/line_length.rb +119 -4
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -3
- data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
- data/lib/rubocop/cop/layout/redundant_line_break.rb +10 -41
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -3
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
- data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +19 -20
- data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
- data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +6 -0
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +4 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +4 -0
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_range.rb +4 -1
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +119 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
- data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
- data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +6 -0
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
- data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
- data/lib/rubocop/cop/lint/debugger.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -1
- data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_set_element.rb +87 -0
- data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
- data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
- data/lib/rubocop/cop/lint/empty_file.rb +0 -2
- data/lib/rubocop/cop/lint/ensure_return.rb +1 -4
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/float_comparison.rb +20 -9
- data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
- data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +11 -5
- data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +8 -14
- data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -0
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +49 -8
- data/lib/rubocop/cop/lint/missing_super.rb +2 -2
- data/lib/rubocop/cop/lint/mixed_case_range.rb +3 -6
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +9 -5
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -2
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +6 -11
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +13 -8
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +231 -0
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +109 -41
- data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +65 -0
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +2 -2
- data/lib/rubocop/cop/lint/syntax.rb +4 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +1 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +51 -2
- data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
- data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
- data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -4
- data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +74 -0
- data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
- data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
- data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
- data/lib/rubocop/cop/lint/void.rb +8 -11
- data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
- data/lib/rubocop/cop/metrics/class_length.rb +9 -9
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
- data/lib/rubocop/cop/metrics/method_length.rb +8 -1
- data/lib/rubocop/cop/metrics/module_length.rb +1 -1
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -3
- data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
- data/lib/rubocop/cop/mixin/alignment.rb +2 -2
- data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +20 -10
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
- data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
- data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -2
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
- data/lib/rubocop/cop/mixin/hash_subset.rb +188 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
- data/lib/rubocop/cop/mixin/line_length_help.rb +5 -4
- data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +5 -9
- data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
- data/lib/rubocop/cop/mixin/range_help.rb +3 -4
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +11 -5
- data/lib/rubocop/cop/mixin/string_help.rb +2 -2
- data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +3 -3
- data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
- data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
- data/lib/rubocop/cop/naming/constant_name.rb +6 -7
- data/lib/rubocop/cop/naming/file_name.rb +0 -2
- data/lib/rubocop/cop/naming/inclusive_language.rb +12 -3
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +11 -12
- data/lib/rubocop/cop/naming/predicate_name.rb +45 -1
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
- data/lib/rubocop/cop/naming/variable_name.rb +3 -4
- data/lib/rubocop/cop/naming/variable_number.rb +2 -3
- data/lib/rubocop/cop/offense.rb +4 -5
- data/lib/rubocop/cop/security/compound_hash.rb +2 -0
- data/lib/rubocop/cop/security/yaml_load.rb +3 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +96 -28
- data/lib/rubocop/cop/style/accessor_grouping.rb +10 -2
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +78 -22
- data/lib/rubocop/cop/style/array_first_last.rb +18 -2
- data/lib/rubocop/cop/style/array_intersect.rb +5 -4
- data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
- data/lib/rubocop/cop/style/block_delimiters.rb +49 -19
- data/lib/rubocop/cop/style/case_like_if.rb +8 -11
- data/lib/rubocop/cop/style/class_and_module_children.rb +6 -3
- data/lib/rubocop/cop/style/collection_compact.rb +10 -10
- data/lib/rubocop/cop/style/collection_methods.rb +1 -1
- data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +9 -2
- data/lib/rubocop/cop/style/commented_keyword.rb +17 -1
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +26 -26
- data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
- data/lib/rubocop/cop/style/data_inheritance.rb +1 -1
- data/lib/rubocop/cop/style/dig_chain.rb +89 -0
- data/lib/rubocop/cop/style/documentation.rb +1 -1
- data/lib/rubocop/cop/style/double_negation.rb +3 -3
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
- data/lib/rubocop/cop/style/each_with_object.rb +2 -3
- data/lib/rubocop/cop/style/empty_else.rb +5 -2
- data/lib/rubocop/cop/style/empty_literal.rb +2 -2
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/endless_method.rb +1 -14
- data/lib/rubocop/cop/style/eval_with_location.rb +2 -2
- data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
- data/lib/rubocop/cop/style/explicit_block_argument.rb +15 -2
- data/lib/rubocop/cop/style/exponential_notation.rb +1 -1
- data/lib/rubocop/cop/style/fetch_env_var.rb +2 -1
- data/lib/rubocop/cop/style/file_null.rb +89 -0
- data/lib/rubocop/cop/style/file_touch.rb +75 -0
- data/lib/rubocop/cop/style/float_division.rb +8 -4
- data/lib/rubocop/cop/style/for.rb +0 -1
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
- data/lib/rubocop/cop/style/global_vars.rb +1 -3
- data/lib/rubocop/cop/style/guard_clause.rb +16 -3
- data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +9 -6
- data/lib/rubocop/cop/style/hash_except.rb +35 -147
- data/lib/rubocop/cop/style/hash_slice.rb +80 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +8 -5
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
- data/lib/rubocop/cop/style/if_inside_else.rb +1 -2
- data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -3
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -3
- data/lib/rubocop/cop/style/if_with_semicolon.rb +28 -6
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +6 -7
- data/lib/rubocop/cop/style/it_assignment.rb +36 -0
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -1
- data/lib/rubocop/cop/style/lambda.rb +1 -1
- data/lib/rubocop/cop/style/lambda_call.rb +3 -2
- data/lib/rubocop/cop/style/magic_comment_format.rb +3 -8
- data/lib/rubocop/cop/style/map_into_array.rb +61 -12
- data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
- data/lib/rubocop/cop/style/map_to_set.rb +3 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +32 -20
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -4
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/missing_else.rb +2 -0
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
- data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
- data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
- data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
- data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
- data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -2
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
- data/lib/rubocop/cop/style/not.rb +1 -1
- data/lib/rubocop/cop/style/object_then.rb +14 -15
- data/lib/rubocop/cop/style/one_line_conditional.rb +29 -4
- data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
- data/lib/rubocop/cop/style/operator_method_call.rb +25 -7
- data/lib/rubocop/cop/style/or_assignment.rb +3 -6
- data/lib/rubocop/cop/style/parallel_assignment.rb +9 -18
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/proc.rb +1 -2
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +7 -5
- data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
- data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
- data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +5 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +39 -24
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +2 -1
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
- data/lib/rubocop/cop/style/redundant_each.rb +1 -1
- data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
- data/lib/rubocop/cop/style/redundant_format.rb +222 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
- data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +1 -1
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +56 -17
- data/lib/rubocop/cop/style/redundant_parentheses.rb +38 -24
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
- data/lib/rubocop/cop/style/redundant_return.rb +2 -2
- data/lib/rubocop/cop/style/redundant_self.rb +8 -15
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
- data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
- data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
- data/lib/rubocop/cop/style/require_order.rb +1 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +15 -4
- data/lib/rubocop/cop/style/return_nil.rb +1 -1
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +54 -12
- data/lib/rubocop/cop/style/safe_navigation.rb +105 -51
- data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +10 -7
- data/lib/rubocop/cop/style/self_assignment.rb +11 -17
- data/lib/rubocop/cop/style/semicolon.rb +2 -2
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
- data/lib/rubocop/cop/style/signal_exception.rb +2 -3
- data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +12 -3
- data/lib/rubocop/cop/style/single_line_methods.rb +3 -4
- data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -5
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +14 -13
- data/lib/rubocop/cop/style/string_literals.rb +1 -1
- data/lib/rubocop/cop/style/string_methods.rb +1 -1
- data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
- data/lib/rubocop/cop/style/super_arguments.rb +65 -17
- data/lib/rubocop/cop/style/swap_values.rb +4 -15
- data/lib/rubocop/cop/style/ternary_parentheses.rb +26 -5
- data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -1
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
- data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
- data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
- data/lib/rubocop/cop/team.rb +8 -1
- data/lib/rubocop/cop/util.rb +12 -5
- data/lib/rubocop/cop/utils/format_string.rb +7 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +18 -3
- data/lib/rubocop/cop/variable_force/branch.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +18 -2
- data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
- data/lib/rubocop/cop/variable_force.rb +4 -10
- data/lib/rubocop/cops_documentation_generator.rb +100 -51
- data/lib/rubocop/directive_comment.rb +44 -10
- data/lib/rubocop/file_finder.rb +9 -4
- data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/lsp/diagnostic.rb +189 -0
- data/lib/rubocop/lsp/logger.rb +2 -2
- data/lib/rubocop/lsp/routes.rb +7 -23
- data/lib/rubocop/lsp/runtime.rb +18 -48
- data/lib/rubocop/lsp/server.rb +0 -3
- data/lib/rubocop/lsp/stdin_runner.rb +83 -0
- data/lib/rubocop/magic_comment.rb +3 -3
- data/lib/rubocop/options.rb +28 -12
- data/lib/rubocop/path_util.rb +15 -8
- data/lib/rubocop/plugin/configuration_integrator.rb +141 -0
- data/lib/rubocop/plugin/load_error.rb +26 -0
- data/lib/rubocop/plugin/loader.rb +100 -0
- data/lib/rubocop/plugin/not_supported_error.rb +29 -0
- data/lib/rubocop/plugin.rb +39 -0
- data/lib/rubocop/rake_task.rb +4 -1
- data/lib/rubocop/result_cache.rb +13 -13
- data/lib/rubocop/rspec/cop_helper.rb +7 -0
- data/lib/rubocop/rspec/expect_offense.rb +7 -2
- data/lib/rubocop/rspec/shared_contexts.rb +4 -1
- data/lib/rubocop/rspec/support.rb +1 -2
- data/lib/rubocop/runner.rb +22 -12
- data/lib/rubocop/server/cache.rb +39 -1
- data/lib/rubocop/server/cli.rb +2 -2
- data/lib/rubocop/server/core.rb +1 -0
- data/lib/rubocop/target_finder.rb +1 -0
- data/lib/rubocop/target_ruby.rb +28 -13
- data/lib/rubocop/version.rb +42 -6
- data/lib/rubocop/yaml_duplication_checker.rb +20 -26
- data/lib/rubocop.rb +29 -0
- data/lib/ruby_lsp/rubocop/addon.rb +75 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +47 -0
- metadata +75 -19
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -5,15 +5,16 @@ module RuboCop
|
|
5
5
|
module Utils
|
6
6
|
# Parses {Kernel#sprintf} format strings.
|
7
7
|
class FormatString
|
8
|
-
DIGIT_DOLLAR = /(
|
8
|
+
DIGIT_DOLLAR = /(?<arg_number>\d+)\$/.freeze
|
9
|
+
INTERPOLATION = /#\{.*?\}/.freeze
|
9
10
|
FLAG = /[ #0+-]|#{DIGIT_DOLLAR}/.freeze
|
10
11
|
NUMBER_ARG = /\*#{DIGIT_DOLLAR}?/.freeze
|
11
|
-
NUMBER = /\d+|#{NUMBER_ARG}/.freeze
|
12
|
+
NUMBER = /\d+|#{NUMBER_ARG}|#{INTERPOLATION}/.freeze
|
12
13
|
WIDTH = /(?<width>#{NUMBER})/.freeze
|
13
|
-
PRECISION = /\.(?<precision>#{NUMBER})/.freeze
|
14
|
+
PRECISION = /\.(?<precision>#{NUMBER}?)/.freeze
|
14
15
|
TYPE = /(?<type>[bBdiouxXeEfgGaAcps])/.freeze
|
15
16
|
NAME = /<(?<name>\w+)>/.freeze
|
16
|
-
TEMPLATE_NAME =
|
17
|
+
TEMPLATE_NAME = /(?<!#)\{(?<name>\w+)\}/.freeze
|
17
18
|
|
18
19
|
SEQUENCE = /
|
19
20
|
% (?<type>%)
|
@@ -41,7 +42,7 @@ module RuboCop
|
|
41
42
|
#
|
42
43
|
# @see https://ruby-doc.org/core-2.6.3/Kernel.html#method-i-format
|
43
44
|
class FormatSequence
|
44
|
-
attr_reader :begin_pos, :end_pos, :flags, :width, :precision, :name, :type
|
45
|
+
attr_reader :begin_pos, :end_pos, :flags, :width, :precision, :name, :type, :arg_number
|
45
46
|
|
46
47
|
def initialize(match)
|
47
48
|
@source = match[0]
|
@@ -52,6 +53,7 @@ module RuboCop
|
|
52
53
|
@precision = match[:precision]
|
53
54
|
@name = match[:name]
|
54
55
|
@type = match[:type]
|
56
|
+
@arg_number = match[:arg_number]
|
55
57
|
end
|
56
58
|
|
57
59
|
def percent?
|
@@ -9,9 +9,10 @@ module RuboCop
|
|
9
9
|
|
10
10
|
MULTIPLE_LEFT_HAND_SIDE_TYPE = :mlhs
|
11
11
|
|
12
|
-
attr_reader :node, :variable, :referenced, :references
|
12
|
+
attr_reader :node, :variable, :referenced, :references, :reassigned
|
13
13
|
|
14
14
|
alias referenced? referenced
|
15
|
+
alias reassigned? reassigned
|
15
16
|
|
16
17
|
def initialize(node, variable)
|
17
18
|
unless VARIABLE_ASSIGNMENT_TYPES.include?(node.type)
|
@@ -24,6 +25,7 @@ module RuboCop
|
|
24
25
|
@variable = variable
|
25
26
|
@referenced = false
|
26
27
|
@references = []
|
28
|
+
@reassigned = false
|
27
29
|
end
|
28
30
|
|
29
31
|
def name
|
@@ -39,8 +41,14 @@ module RuboCop
|
|
39
41
|
@referenced = true
|
40
42
|
end
|
41
43
|
|
44
|
+
def reassigned!
|
45
|
+
return if referenced?
|
46
|
+
|
47
|
+
@reassigned = true
|
48
|
+
end
|
49
|
+
|
42
50
|
def used?
|
43
|
-
@variable.captured_by_block? || @referenced
|
51
|
+
(!reassigned? && @variable.captured_by_block?) || @referenced
|
44
52
|
end
|
45
53
|
|
46
54
|
def regexp_named_capture?
|
@@ -102,6 +110,7 @@ module RuboCop
|
|
102
110
|
end
|
103
111
|
|
104
112
|
def multiple_assignment_node
|
113
|
+
return nil unless node.parent&.mlhs_type?
|
105
114
|
return nil unless (grandparent_node = node.parent&.parent)
|
106
115
|
if (node = find_multiple_assignment_node(grandparent_node))
|
107
116
|
return node
|
@@ -119,7 +128,13 @@ module RuboCop
|
|
119
128
|
end
|
120
129
|
|
121
130
|
def for_assignment_node
|
122
|
-
node.
|
131
|
+
return unless (parent_node = node.parent)
|
132
|
+
return parent_node if parent_node.for_type?
|
133
|
+
|
134
|
+
grandparent_node = parent_node.parent
|
135
|
+
return grandparent_node if parent_node.mlhs_type? && grandparent_node&.for_type?
|
136
|
+
|
137
|
+
nil
|
123
138
|
end
|
124
139
|
|
125
140
|
def find_multiple_assignment_node(grandparent_node)
|
@@ -6,6 +6,8 @@ module RuboCop
|
|
6
6
|
# A Variable represents existence of a local variable.
|
7
7
|
# This holds a variable declaration node and some states of the variable.
|
8
8
|
class Variable
|
9
|
+
extend NodePattern::Macros
|
10
|
+
|
9
11
|
VARIABLE_DECLARATION_TYPES = (VARIABLE_ASSIGNMENT_TYPES + ARGUMENT_DECLARATION_TYPES).freeze
|
10
12
|
|
11
13
|
attr_reader :name, :declaration_node, :scope, :assignments, :references, :captured_by_block
|
@@ -29,9 +31,23 @@ module RuboCop
|
|
29
31
|
end
|
30
32
|
|
31
33
|
def assign(node)
|
32
|
-
|
34
|
+
assignment = Assignment.new(node, self)
|
35
|
+
|
36
|
+
mark_last_as_reassigned!(assignment)
|
37
|
+
|
38
|
+
@assignments << assignment
|
33
39
|
end
|
34
40
|
|
41
|
+
def mark_last_as_reassigned!(assignment)
|
42
|
+
return if captured_by_block?
|
43
|
+
return if candidate_condition?(assignment.node.parent)
|
44
|
+
|
45
|
+
@assignments.last&.reassigned!
|
46
|
+
end
|
47
|
+
|
48
|
+
# @!method candidate_condition?(node)
|
49
|
+
def_node_matcher :candidate_condition?, '[{if case case_match when}]'
|
50
|
+
|
35
51
|
def referenced?
|
36
52
|
!@references.empty?
|
37
53
|
end
|
@@ -68,7 +84,7 @@ module RuboCop
|
|
68
84
|
parent = parent.parent if parent&.begin_type?
|
69
85
|
return false if parent.nil?
|
70
86
|
|
71
|
-
|
87
|
+
parent.type?(:if, :while, :until) && parent.modifier_form?
|
72
88
|
end
|
73
89
|
|
74
90
|
def capture_with_block!
|
@@ -61,8 +61,8 @@ module RuboCop
|
|
61
61
|
"at #{node.source_range}, #{node.inspect}"
|
62
62
|
end
|
63
63
|
|
64
|
-
variable.assign(node)
|
65
64
|
mark_variable_as_captured_by_block_if_so(variable)
|
65
|
+
variable.assign(node)
|
66
66
|
end
|
67
67
|
|
68
68
|
def reference_variable(name, node)
|
@@ -87,8 +87,8 @@ module RuboCop
|
|
87
87
|
# So just skip.
|
88
88
|
return unless variable
|
89
89
|
|
90
|
-
variable.reference!(node)
|
91
90
|
mark_variable_as_captured_by_block_if_so(variable)
|
91
|
+
variable.reference!(node)
|
92
92
|
end
|
93
93
|
|
94
94
|
def find_variable(name)
|
@@ -100,7 +100,7 @@ module RuboCop
|
|
100
100
|
|
101
101
|
# Only block scope allows referencing outer scope variables.
|
102
102
|
node = scope.node
|
103
|
-
return nil unless node.
|
103
|
+
return nil unless node.any_block_type?
|
104
104
|
end
|
105
105
|
|
106
106
|
nil
|
@@ -113,14 +113,14 @@ module RuboCop
|
|
113
113
|
def accessible_variables
|
114
114
|
scope_stack.reverse_each.with_object([]) do |scope, variables|
|
115
115
|
variables.concat(scope.variables.values)
|
116
|
-
break variables unless scope.node.
|
116
|
+
break variables unless scope.node.any_block_type?
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
120
|
private
|
121
121
|
|
122
122
|
def mark_variable_as_captured_by_block_if_so(variable)
|
123
|
-
return unless current_scope.node.
|
123
|
+
return unless current_scope.node.any_block_type?
|
124
124
|
return if variable.scope == current_scope
|
125
125
|
|
126
126
|
variable.capture_with_block!
|
@@ -194,15 +194,10 @@ module RuboCop
|
|
194
194
|
end
|
195
195
|
|
196
196
|
def process_variable_operator_assignment(node)
|
197
|
-
|
198
|
-
asgn_node, rhs_node = *node
|
199
|
-
else
|
200
|
-
asgn_node, _operator, rhs_node = *node
|
201
|
-
end
|
202
|
-
|
197
|
+
asgn_node = node.lhs
|
203
198
|
return unless asgn_node.lvasgn_type?
|
204
199
|
|
205
|
-
name = asgn_node.
|
200
|
+
name = asgn_node.name
|
206
201
|
|
207
202
|
variable_table.declare_variable(name, asgn_node) unless variable_table.variable_exist?(name)
|
208
203
|
|
@@ -222,7 +217,7 @@ module RuboCop
|
|
222
217
|
# before processing rhs nodes.
|
223
218
|
|
224
219
|
variable_table.reference_variable(name, node)
|
225
|
-
process_node(
|
220
|
+
process_node(node.rhs)
|
226
221
|
variable_table.assign_to_variable(name, asgn_node)
|
227
222
|
|
228
223
|
skip_children!
|
@@ -355,8 +350,7 @@ module RuboCop
|
|
355
350
|
when :lvasgn
|
356
351
|
AssignmentReference.new(node)
|
357
352
|
when *OPERATOR_ASSIGNMENT_TYPES
|
358
|
-
|
359
|
-
VariableReference.new(asgn_node.children.first) if asgn_node.lvasgn_type?
|
353
|
+
VariableReference.new(node.lhs.name) if node.lhs.lvasgn_type?
|
360
354
|
end
|
361
355
|
end
|
362
356
|
|
@@ -1,23 +1,49 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
|
+
require 'yard'
|
4
5
|
|
5
6
|
# Class for generating documentation of all cops departments
|
6
7
|
# @api private
|
7
8
|
class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
8
9
|
include ::RuboCop::Cop::Documentation
|
10
|
+
CopData = Struct.new(
|
11
|
+
:cop, :description, :example_objects, :safety_objects, :see_objects, :config, keyword_init: true
|
12
|
+
)
|
13
|
+
|
14
|
+
STRUCTURE = {
|
15
|
+
name: ->(data) { cop_header(data.cop) },
|
16
|
+
required_ruby_version: ->(data) { required_ruby_version(data.cop) },
|
17
|
+
properties: ->(data) { properties(data.cop) },
|
18
|
+
description: ->(data) { "#{data.description}\n" },
|
19
|
+
safety: ->(data) { safety_object(data.safety_objects, data.cop) },
|
20
|
+
examples: ->(data) { examples(data.example_objects, data.cop) },
|
21
|
+
configuration: ->(data) { configurations(data.cop.department, data.cop, data.config) },
|
22
|
+
references: ->(data) { references(data.cop, data.see_objects) }
|
23
|
+
}.freeze
|
24
|
+
|
9
25
|
# This class will only generate documentation for cops that belong to one of
|
10
26
|
# the departments given in the `departments` array. E.g. if we only wanted
|
11
27
|
# documentation for Lint cops:
|
12
28
|
#
|
13
29
|
# CopsDocumentationGenerator.new(departments: ['Lint']).call
|
14
30
|
#
|
15
|
-
|
31
|
+
# You can append additional information:
|
32
|
+
#
|
33
|
+
# callback = ->(data) { required_rails_version(data.cop) }
|
34
|
+
# CopsDocumentationGenerator.new(extra_info: { ruby_version: callback }).call
|
35
|
+
#
|
36
|
+
# This will insert the string returned from the lambda _after_ the section from RuboCop itself.
|
37
|
+
# See `CopsDocumentationGenerator::STRUCTURE` for available sections.
|
38
|
+
#
|
39
|
+
def initialize(departments: [], extra_info: {}, base_dir: Dir.pwd)
|
16
40
|
@departments = departments.map(&:to_sym).sort!
|
41
|
+
@extra_info = extra_info
|
17
42
|
@cops = RuboCop::Cop::Registry.global
|
18
43
|
@config = RuboCop::ConfigLoader.default_configuration
|
19
|
-
@
|
20
|
-
|
44
|
+
@base_dir = base_dir
|
45
|
+
@docs_path = "#{base_dir}/docs/modules/ROOT"
|
46
|
+
FileUtils.mkdir_p("#{@docs_path}/pages")
|
21
47
|
end
|
22
48
|
|
23
49
|
def call
|
@@ -37,24 +63,21 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
37
63
|
cops.with_department(department).sort!
|
38
64
|
end
|
39
65
|
|
40
|
-
def cops_body(
|
41
|
-
check_examples_to_have_the_default_enforced_style!(
|
42
|
-
|
43
|
-
content =
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
content << examples(examples_objects) if examples_objects.any?
|
49
|
-
content << configurations(cop.department, pars)
|
50
|
-
content << references(cop, see_objects)
|
66
|
+
def cops_body(data)
|
67
|
+
check_examples_to_have_the_default_enforced_style!(data.example_objects, data.cop)
|
68
|
+
|
69
|
+
content = +''
|
70
|
+
STRUCTURE.each do |section, block|
|
71
|
+
content << instance_exec(data, &block)
|
72
|
+
content << @extra_info[section].call(data) if @extra_info[section]
|
73
|
+
end
|
51
74
|
content
|
52
75
|
end
|
53
76
|
|
54
|
-
def check_examples_to_have_the_default_enforced_style!(
|
55
|
-
return if
|
77
|
+
def check_examples_to_have_the_default_enforced_style!(example_objects, cop)
|
78
|
+
return if example_objects.none?
|
56
79
|
|
57
|
-
examples_describing_enforced_style =
|
80
|
+
examples_describing_enforced_style = example_objects.map(&:name).grep(/EnforcedStyle:/)
|
58
81
|
return if examples_describing_enforced_style.none?
|
59
82
|
|
60
83
|
if examples_describing_enforced_style.index { |name| name.match?('default') }.nonzero?
|
@@ -66,16 +89,20 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
66
89
|
raise "Specify the default EnforcedStyle for #{cop.cop_name}"
|
67
90
|
end
|
68
91
|
|
69
|
-
def examples(
|
70
|
-
|
92
|
+
def examples(example_objects, cop)
|
93
|
+
return '' if example_objects.none?
|
94
|
+
|
95
|
+
example_objects.each_with_object(cop_subsection('Examples', cop).dup) do |example, content|
|
71
96
|
content << "\n" unless content.end_with?("\n\n")
|
72
|
-
content <<
|
97
|
+
content << example_header(example.name, cop) unless example.name == ''
|
73
98
|
content << code_example(example)
|
74
99
|
end
|
75
100
|
end
|
76
101
|
|
77
|
-
def safety_object(
|
78
|
-
|
102
|
+
def safety_object(safety_objects, cop)
|
103
|
+
return '' if safety_objects.all? { |s| s.text.blank? }
|
104
|
+
|
105
|
+
safety_objects.each_with_object(cop_subsection('Safety', cop).dup) do |safety_object, content|
|
79
106
|
next if safety_object.text.blank?
|
80
107
|
|
81
108
|
content << "\n" unless content.end_with?("\n\n")
|
@@ -87,7 +114,15 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
87
114
|
def required_ruby_version(cop)
|
88
115
|
return '' unless cop.respond_to?(:required_minimum_ruby_version)
|
89
116
|
|
90
|
-
|
117
|
+
if cop.required_minimum_ruby_version
|
118
|
+
requirement = cop.required_minimum_ruby_version
|
119
|
+
elsif cop.required_maximum_ruby_version
|
120
|
+
requirement = "<= #{cop.required_maximum_ruby_version}"
|
121
|
+
else
|
122
|
+
return ''
|
123
|
+
end
|
124
|
+
|
125
|
+
"NOTE: Requires Ruby version #{requirement}\n\n"
|
91
126
|
end
|
92
127
|
|
93
128
|
# rubocop:disable Metrics/MethodLength
|
@@ -115,22 +150,25 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
115
150
|
end
|
116
151
|
# rubocop:enable Metrics/MethodLength
|
117
152
|
|
118
|
-
def
|
153
|
+
def cop_header(cop)
|
119
154
|
content = +"\n"
|
120
|
-
content << "
|
155
|
+
content << "[##{to_anchor(cop.cop_name)}]\n"
|
156
|
+
content << "== #{cop.cop_name}\n"
|
121
157
|
content << "\n"
|
122
158
|
content
|
123
159
|
end
|
124
160
|
|
125
|
-
def
|
161
|
+
def cop_subsection(title, cop)
|
126
162
|
content = +"\n"
|
163
|
+
content << "[##{to_anchor(title)}-#{to_anchor(cop.cop_name)}]\n"
|
127
164
|
content << "=== #{title}\n"
|
128
165
|
content << "\n"
|
129
166
|
content
|
130
167
|
end
|
131
168
|
|
132
|
-
def
|
133
|
-
content = +"
|
169
|
+
def example_header(title, cop)
|
170
|
+
content = +"[##{to_anchor(title)}-#{to_anchor(cop.cop_name)}]\n"
|
171
|
+
content << "==== #{title}\n"
|
134
172
|
content << "\n"
|
135
173
|
content
|
136
174
|
end
|
@@ -142,22 +180,22 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
142
180
|
content
|
143
181
|
end
|
144
182
|
|
145
|
-
def configurations(department,
|
146
|
-
return '' if pars.empty?
|
147
|
-
|
183
|
+
def configurations(department, cop, cop_config)
|
148
184
|
header = ['Name', 'Default value', 'Configurable values']
|
149
|
-
configs =
|
185
|
+
configs = cop_config
|
150
186
|
.each_key
|
151
187
|
.reject { |key| key.start_with?('Supported') }
|
152
188
|
.reject { |key| key.start_with?('AllowMultipleStyles') }
|
189
|
+
return '' if configs.empty?
|
190
|
+
|
153
191
|
content = configs.map do |name|
|
154
|
-
configurable = configurable_values(
|
155
|
-
default = format_table_value(
|
192
|
+
configurable = configurable_values(cop_config, name)
|
193
|
+
default = format_table_value(cop_config[name])
|
156
194
|
|
157
195
|
[configuration_name(department, name), default, configurable]
|
158
196
|
end
|
159
197
|
|
160
|
-
|
198
|
+
cop_subsection('Configurable attributes', cop) + to_table(header, content)
|
161
199
|
end
|
162
200
|
|
163
201
|
def configuration_name(department, name)
|
@@ -168,17 +206,17 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
168
206
|
end
|
169
207
|
|
170
208
|
# rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength
|
171
|
-
def configurable_values(
|
209
|
+
def configurable_values(cop_config, name)
|
172
210
|
case name
|
173
211
|
when /^Enforced/
|
174
212
|
supported_style_name = RuboCop::Cop::Util.to_supported_styles(name)
|
175
|
-
format_table_value(
|
213
|
+
format_table_value(cop_config[supported_style_name])
|
176
214
|
when 'IndentationWidth'
|
177
215
|
'Integer'
|
178
216
|
when 'Database'
|
179
|
-
format_table_value(
|
217
|
+
format_table_value(cop_config['SupportedDatabases'])
|
180
218
|
else
|
181
|
-
case
|
219
|
+
case cop_config[name]
|
182
220
|
when String
|
183
221
|
'String'
|
184
222
|
when Integer
|
@@ -218,7 +256,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
218
256
|
else
|
219
257
|
wrap_backtick(val.nil? ? '<none>' : val)
|
220
258
|
end
|
221
|
-
value.gsub("#{
|
259
|
+
value.gsub("#{@base_dir}/", '').rstrip
|
222
260
|
end
|
223
261
|
|
224
262
|
def wrap_backtick(value)
|
@@ -235,7 +273,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
235
273
|
urls = RuboCop::Cop::MessageAnnotator.new(config, cop.name, cop_config, {}).urls
|
236
274
|
return '' if urls.empty? && see_objects.empty?
|
237
275
|
|
238
|
-
content =
|
276
|
+
content = cop_subsection('References', cop)
|
239
277
|
content << urls.map { |url| "* #{url}" }.join("\n")
|
240
278
|
content << "\n" unless urls.empty?
|
241
279
|
content << see_objects.map { |see| "* #{see.name}" }.join("\n")
|
@@ -247,7 +285,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
247
285
|
return '' unless department == :Layout
|
248
286
|
|
249
287
|
filename = "#{department_to_basename(department)}_footer.adoc"
|
250
|
-
file = "#{
|
288
|
+
file = "#{docs_path}/partials/#{filename}"
|
251
289
|
return '' unless File.exist?(file)
|
252
290
|
|
253
291
|
"\ninclude::../partials/#{filename}[]\n"
|
@@ -267,7 +305,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
267
305
|
HEADER
|
268
306
|
selected_cops.each { |cop| content << print_cop_with_doc(cop) }
|
269
307
|
content << footer_for_department(department)
|
270
|
-
file_name = "#{docs_path}/#{department_to_basename(department)}.adoc"
|
308
|
+
file_name = "#{docs_path}/pages/#{department_to_basename(department)}.adoc"
|
271
309
|
File.open(file_name, 'w') do |file|
|
272
310
|
puts "* generated #{file_name}"
|
273
311
|
file.write("#{content.strip}\n")
|
@@ -281,16 +319,18 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
281
319
|
AutoCorrect Description Enabled StyleGuide Reference Safe SafeAutoCorrect VersionAdded
|
282
320
|
VersionChanged
|
283
321
|
]
|
284
|
-
|
322
|
+
parameters = cop_config.reject { |k| non_display_keys.include? k }
|
285
323
|
description = 'No documentation'
|
286
|
-
|
324
|
+
example_objects = safety_objects = see_objects = []
|
287
325
|
cop_code(cop) do |code_object|
|
288
326
|
description = code_object.docstring unless code_object.docstring.blank?
|
289
|
-
|
290
|
-
|
291
|
-
|
327
|
+
example_objects = code_object.tags('example')
|
328
|
+
safety_objects = code_object.tags('safety')
|
329
|
+
see_objects = code_object.tags('see')
|
292
330
|
end
|
293
|
-
|
331
|
+
data = CopData.new(cop: cop, description: description, example_objects: example_objects,
|
332
|
+
safety_objects: safety_objects, see_objects: see_objects, config: parameters)
|
333
|
+
cops_body(data)
|
294
334
|
end
|
295
335
|
|
296
336
|
def cop_code(cop)
|
@@ -306,7 +346,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
306
346
|
filename = "#{department_to_basename(department)}.adoc"
|
307
347
|
content = +"=== Department xref:#{filename}[#{type_title}]\n\n"
|
308
348
|
cops_of_department(department).each do |cop|
|
309
|
-
anchor = cop.cop_name
|
349
|
+
anchor = to_anchor(cop.cop_name)
|
310
350
|
content << "* xref:#{filename}##{anchor}[#{cop.cop_name}]\n"
|
311
351
|
end
|
312
352
|
|
@@ -314,7 +354,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
314
354
|
end
|
315
355
|
|
316
356
|
def print_table_of_contents
|
317
|
-
path = "#{docs_path}/cops.adoc"
|
357
|
+
path = "#{docs_path}/pages/cops.adoc"
|
318
358
|
|
319
359
|
File.write(path, table_contents) and return unless File.exist?(path)
|
320
360
|
|
@@ -338,4 +378,13 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
338
378
|
|
339
379
|
status == 'pending' ? 'Pending' : 'Enabled'
|
340
380
|
end
|
381
|
+
|
382
|
+
# HTML anchor are somewhat limited in what characters they can contain, just
|
383
|
+
# accept a known-good subset. As long as it's consistent it doesn't matter.
|
384
|
+
#
|
385
|
+
# Style/AccessModifierDeclarations => styleaccessmodifierdeclarations
|
386
|
+
# OnlyFor: [] (default) => onlyfor_-__-_default_
|
387
|
+
def to_anchor(title)
|
388
|
+
title.delete('/').tr(' ', '-').gsub(/[^a-zA-Z0-9-]/, '_').downcase
|
389
|
+
end
|
341
390
|
end
|
@@ -18,10 +18,24 @@ module RuboCop
|
|
18
18
|
# @api private
|
19
19
|
COPS_PATTERN = "(all|#{COP_NAMES_PATTERN})"
|
20
20
|
# @api private
|
21
|
+
AVAILABLE_MODES = %w[disable enable todo].freeze
|
22
|
+
# @api private
|
23
|
+
DIRECTIVE_MARKER_PATTERN = '# rubocop : '
|
24
|
+
# @api private
|
25
|
+
DIRECTIVE_MARKER_REGEXP = Regexp.new(DIRECTIVE_MARKER_PATTERN.gsub(' ', '\s*'))
|
26
|
+
# @api private
|
27
|
+
DIRECTIVE_HEADER_PATTERN = "#{DIRECTIVE_MARKER_PATTERN}((?:#{AVAILABLE_MODES.join('|')}))\\b"
|
28
|
+
# @api private
|
21
29
|
DIRECTIVE_COMMENT_REGEXP = Regexp.new(
|
22
|
-
"#
|
30
|
+
"#{DIRECTIVE_HEADER_PATTERN} #{COPS_PATTERN}"
|
23
31
|
.gsub(' ', '\s*')
|
24
32
|
)
|
33
|
+
# @api private
|
34
|
+
TRAILING_COMMENT_MARKER = '--'
|
35
|
+
# @api private
|
36
|
+
MALFORMED_DIRECTIVE_WITHOUT_COP_NAME_REGEXP = Regexp.new(
|
37
|
+
"\\A#{DIRECTIVE_HEADER_PATTERN}\\s*\\z".gsub(' ', '\s*')
|
38
|
+
)
|
25
39
|
|
26
40
|
def self.before_comment(line)
|
27
41
|
line.split(DIRECTIVE_COMMENT_REGEXP).first
|
@@ -32,9 +46,28 @@ module RuboCop
|
|
32
46
|
def initialize(comment, cop_registry = Cop::Registry.global)
|
33
47
|
@comment = comment
|
34
48
|
@cop_registry = cop_registry
|
49
|
+
@match_data = comment.text.match(DIRECTIVE_COMMENT_REGEXP)
|
35
50
|
@mode, @cops = match_captures
|
36
51
|
end
|
37
52
|
|
53
|
+
# Checks if the comment starts with `# rubocop:` marker
|
54
|
+
def start_with_marker?
|
55
|
+
comment.text.start_with?(DIRECTIVE_MARKER_REGEXP)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Checks if the comment is malformed as a `# rubocop:` directive
|
59
|
+
def malformed?
|
60
|
+
return true if !start_with_marker? || @match_data.nil?
|
61
|
+
|
62
|
+
tail = @match_data.post_match.lstrip
|
63
|
+
!(tail.empty? || tail.start_with?(TRAILING_COMMENT_MARKER))
|
64
|
+
end
|
65
|
+
|
66
|
+
# Checks if the directive comment is missing a cop name
|
67
|
+
def missing_cop_name?
|
68
|
+
MALFORMED_DIRECTIVE_WITHOUT_COP_NAME_REGEXP.match?(comment.text)
|
69
|
+
end
|
70
|
+
|
38
71
|
# Checks if this directive relates to single line
|
39
72
|
def single_line?
|
40
73
|
!comment.text.start_with?(DIRECTIVE_COMMENT_REGEXP)
|
@@ -55,7 +88,7 @@ module RuboCop
|
|
55
88
|
|
56
89
|
# Returns match captures to directive comment pattern
|
57
90
|
def match_captures
|
58
|
-
@match_captures ||=
|
91
|
+
@match_captures ||= @match_data&.captures
|
59
92
|
end
|
60
93
|
|
61
94
|
# Checks if this directive disables cops
|
@@ -88,10 +121,15 @@ module RuboCop
|
|
88
121
|
@cop_names ||= all_cops? ? all_cop_names : parsed_cop_names
|
89
122
|
end
|
90
123
|
|
124
|
+
# Returns an array of cops for this directive comment, without resolving departments
|
125
|
+
def raw_cop_names
|
126
|
+
@raw_cop_names ||= (cops || '').split(/,\s*/)
|
127
|
+
end
|
128
|
+
|
91
129
|
# Returns array of specified in this directive department names
|
92
130
|
# when all department disabled
|
93
131
|
def department_names
|
94
|
-
|
132
|
+
raw_cop_names.select { |cop| department?(cop) }
|
95
133
|
end
|
96
134
|
|
97
135
|
# Checks if directive departments include cop
|
@@ -101,11 +139,11 @@ module RuboCop
|
|
101
139
|
|
102
140
|
# Checks if cop department has already used in directive comment
|
103
141
|
def overridden_by_department?(cop)
|
104
|
-
in_directive_department?(cop) &&
|
142
|
+
in_directive_department?(cop) && raw_cop_names.include?(cop)
|
105
143
|
end
|
106
144
|
|
107
145
|
def directive_count
|
108
|
-
|
146
|
+
raw_cop_names.count
|
109
147
|
end
|
110
148
|
|
111
149
|
# Returns line number for directive
|
@@ -115,12 +153,8 @@ module RuboCop
|
|
115
153
|
|
116
154
|
private
|
117
155
|
|
118
|
-
def splitted_cops_string
|
119
|
-
(cops || '').split(/,\s*/)
|
120
|
-
end
|
121
|
-
|
122
156
|
def parsed_cop_names
|
123
|
-
cops =
|
157
|
+
cops = raw_cop_names.map do |name|
|
124
158
|
department?(name) ? cop_names_for_department(name) : name
|
125
159
|
end.flatten
|
126
160
|
cops - [LINT_SYNTAX_COP]
|
data/lib/rubocop/file_finder.rb
CHANGED
@@ -23,15 +23,20 @@ module RuboCop
|
|
23
23
|
last_file
|
24
24
|
end
|
25
25
|
|
26
|
+
def traverse_directories_upwards(start_dir, stop_dir = nil)
|
27
|
+
Pathname.new(start_dir).expand_path.ascend do |dir|
|
28
|
+
yield(dir)
|
29
|
+
dir = dir.to_s
|
30
|
+
break if dir == stop_dir || dir == FileFinder.root_level
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
26
34
|
private
|
27
35
|
|
28
36
|
def traverse_files_upwards(filename, start_dir, stop_dir)
|
29
|
-
|
37
|
+
traverse_directories_upwards(start_dir, stop_dir) do |dir|
|
30
38
|
file = dir + filename
|
31
39
|
yield(file.to_s) if file.exist?
|
32
|
-
|
33
|
-
dir = dir.to_s
|
34
|
-
break if dir == stop_dir || dir == FileFinder.root_level
|
35
40
|
end
|
36
41
|
end
|
37
42
|
end
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
HEADING = <<~COMMENTS
|
11
11
|
# This configuration was generated by
|
12
12
|
# `%<command>s`
|
13
|
-
# %<timestamp>susing RuboCop version #{Version
|
13
|
+
# %<timestamp>susing RuboCop version #{Version::STRING}.
|
14
14
|
# The point is for the user to remove these configuration records
|
15
15
|
# one by one as the offenses are removed from the code base.
|
16
16
|
# Note that changes in the inspected code, or installation of new
|