rubocop 1.88.2 → 1.89.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/config/default.yml +67 -11
- data/lib/rubocop/comment_config.rb +35 -19
- data/lib/rubocop/config.rb +53 -0
- data/lib/rubocop/config_validator.rb +38 -1
- data/lib/rubocop/cop/badge.rb +8 -0
- data/lib/rubocop/cop/base.rb +6 -4
- data/lib/rubocop/cop/bundler.rb +19 -0
- data/lib/rubocop/cop/corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +55 -5
- data/lib/rubocop/cop/gemspec.rb +22 -0
- data/lib/rubocop/cop/generator/registration_injector.rb +188 -0
- data/lib/rubocop/cop/generator.rb +4 -0
- data/lib/rubocop/cop/layout/class_structure.rb +8 -2
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +3 -1
- data/lib/rubocop/cop/layout/leading_comment_space.rb +27 -0
- data/lib/rubocop/cop/layout/line_length.rb +85 -12
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +12 -2
- data/lib/rubocop/cop/layout/redundant_line_break.rb +77 -0
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +33 -34
- data/lib/rubocop/cop/layout.rb +114 -0
- data/lib/rubocop/cop/lazy_loader.rb +41 -0
- data/lib/rubocop/cop/lint/ambiguous_assignment.rb +9 -7
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +71 -0
- data/lib/rubocop/cop/lint/constant_reassignment.rb +1 -10
- data/lib/rubocop/cop/lint/constant_resolution.rb +25 -0
- data/lib/rubocop/cop/lint/deprecated_reference.rb +185 -0
- data/lib/rubocop/cop/lint/duplicate_methods.rb +202 -22
- data/lib/rubocop/cop/lint/inherit_exception.rb +53 -7
- data/lib/rubocop/cop/lint/literal_as_condition.rb +5 -0
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/missing_super.rb +31 -1
- data/lib/rubocop/cop/lint/name_typo.rb +223 -0
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +0 -4
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +7 -0
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +37 -1
- data/lib/rubocop/cop/lint/unused_private_method.rb +157 -0
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -0
- data/lib/rubocop/cop/lint/void.rb +17 -6
- data/lib/rubocop/cop/lint.rb +176 -0
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics.rb +31 -0
- data/lib/rubocop/cop/migration/department_name.rb +0 -4
- data/lib/rubocop/cop/migration.rb +13 -0
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +23 -5
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +13 -5
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +23 -6
- data/lib/rubocop/cop/mixin/project_index_help.rb +140 -0
- data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +171 -0
- data/lib/rubocop/cop/mixin/statement_modifier.rb +42 -6
- data/lib/rubocop/cop/mixin.rb +78 -77
- data/lib/rubocop/cop/naming/accessor_method_name.rb +24 -0
- data/lib/rubocop/cop/naming/predicate_prefix.rb +33 -5
- data/lib/rubocop/cop/naming/variable_number.rb +3 -1
- data/lib/rubocop/cop/naming.rb +31 -0
- data/lib/rubocop/cop/offense.rb +10 -6
- data/lib/rubocop/cop/registry.rb +153 -43
- data/lib/rubocop/cop/security.rb +19 -0
- data/lib/rubocop/cop/style/array_intersect.rb +24 -5
- data/lib/rubocop/cop/style/class_and_module_children.rb +78 -18
- data/lib/rubocop/cop/style/conditional_assignment.rb +22 -0
- data/lib/rubocop/cop/style/copyright.rb +6 -1
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +41 -3
- data/lib/rubocop/cop/style/documentation.rb +47 -0
- data/lib/rubocop/cop/style/endless_method.rb +0 -10
- data/lib/rubocop/cop/style/if_unless_modifier.rb +7 -48
- data/lib/rubocop/cop/style/lambda.rb +4 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +20 -3
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +30 -0
- data/lib/rubocop/cop/style/multiline_if_then.rb +7 -1
- data/lib/rubocop/cop/style/multiple_comparison.rb +33 -22
- data/lib/rubocop/cop/style/mutable_constant.rb +5 -0
- data/lib/rubocop/cop/style/negative_array_index.rb +3 -1
- data/lib/rubocop/cop/style/redundant_assignment.rb +11 -0
- data/lib/rubocop/cop/style/redundant_constant_base.rb +37 -1
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +9 -0
- data/lib/rubocop/cop/style/redundant_format.rb +12 -3
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +78 -135
- data/lib/rubocop/cop/style/redundant_parentheses.rb +63 -63
- data/lib/rubocop/cop/style/safe_navigation.rb +10 -0
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +20 -3
- data/lib/rubocop/cop/style/static_class.rb +21 -0
- data/lib/rubocop/cop/style.rb +310 -0
- data/lib/rubocop/cop/team.rb +48 -3
- data/lib/rubocop/cop/variable_force/variable.rb +18 -6
- data/lib/rubocop/cops_documentation_generator.rb +1 -1
- data/lib/rubocop/directive_comment.rb +2 -0
- data/lib/rubocop/feature_loader.rb +0 -6
- data/lib/rubocop/lsp/routes.rb +41 -3
- data/lib/rubocop/lsp/runtime.rb +4 -0
- data/lib/rubocop/lsp/server.rb +4 -0
- data/lib/rubocop/lsp/stdin_runner.rb +20 -0
- data/lib/rubocop/pending_cops_reporter.rb +1 -6
- data/lib/rubocop/project_index_loader.rb +16 -0
- data/lib/rubocop/result_cache.rb +6 -4
- data/lib/rubocop/rspec/shared_contexts.rb +14 -2
- data/lib/rubocop/runner.rb +45 -20
- data/lib/rubocop/server/cache.rb +10 -5
- data/lib/rubocop/target_ruby.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +17 -626
- metadata +18 -3
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
# Cops for the `Lint` department. The department's cops are registered for lazy loading
|
|
6
|
+
# and their files are loaded on demand.
|
|
7
|
+
module Lint
|
|
8
|
+
extend LazyLoader
|
|
9
|
+
|
|
10
|
+
register_cop :AmbiguousAssignment, "#{__dir__}/lint/ambiguous_assignment"
|
|
11
|
+
register_cop :AmbiguousBlockAssociation, "#{__dir__}/lint/ambiguous_block_association"
|
|
12
|
+
register_cop :AmbiguousOperator, "#{__dir__}/lint/ambiguous_operator"
|
|
13
|
+
register_cop :AmbiguousOperatorPrecedence, "#{__dir__}/lint/ambiguous_operator_precedence"
|
|
14
|
+
register_cop :AmbiguousRange, "#{__dir__}/lint/ambiguous_range"
|
|
15
|
+
register_cop :AmbiguousRegexpLiteral, "#{__dir__}/lint/ambiguous_regexp_literal"
|
|
16
|
+
register_cop :ArrayLiteralInRegexp, "#{__dir__}/lint/array_literal_in_regexp"
|
|
17
|
+
register_cop :AssignmentInCondition, "#{__dir__}/lint/assignment_in_condition"
|
|
18
|
+
register_cop :BigDecimalNew, "#{__dir__}/lint/big_decimal_new"
|
|
19
|
+
register_cop :BinaryOperatorWithIdenticalOperands, "#{__dir__}/lint/binary_operator_with_identical_operands"
|
|
20
|
+
register_cop :BooleanSymbol, "#{__dir__}/lint/boolean_symbol"
|
|
21
|
+
register_cop :CircularArgumentReference, "#{__dir__}/lint/circular_argument_reference"
|
|
22
|
+
register_cop :ConstantDefinitionInBlock, "#{__dir__}/lint/constant_definition_in_block"
|
|
23
|
+
register_cop :ConstantOverwrittenInRescue, "#{__dir__}/lint/constant_overwritten_in_rescue"
|
|
24
|
+
register_cop :ConstantReassignment, "#{__dir__}/lint/constant_reassignment"
|
|
25
|
+
register_cop :ConstantResolution, "#{__dir__}/lint/constant_resolution"
|
|
26
|
+
register_cop :CopDirectiveSyntax, "#{__dir__}/lint/cop_directive_syntax"
|
|
27
|
+
register_cop :DataDefineOverride, "#{__dir__}/lint/data_define_override"
|
|
28
|
+
register_cop :Debugger, "#{__dir__}/lint/debugger"
|
|
29
|
+
register_cop :DeprecatedClassMethods, "#{__dir__}/lint/deprecated_class_methods"
|
|
30
|
+
register_cop :DeprecatedConstants, "#{__dir__}/lint/deprecated_constants"
|
|
31
|
+
register_cop :DeprecatedOpenSSLConstant, "#{__dir__}/lint/deprecated_open_ssl_constant"
|
|
32
|
+
register_cop :DeprecatedReference, "#{__dir__}/lint/deprecated_reference"
|
|
33
|
+
register_cop :DisjunctiveAssignmentInConstructor, "#{__dir__}/lint/disjunctive_assignment_in_constructor"
|
|
34
|
+
register_cop :DuplicateBranch, "#{__dir__}/lint/duplicate_branch"
|
|
35
|
+
register_cop :DuplicateCaseCondition, "#{__dir__}/lint/duplicate_case_condition"
|
|
36
|
+
register_cop :DuplicateElsifCondition, "#{__dir__}/lint/duplicate_elsif_condition"
|
|
37
|
+
register_cop :DuplicateHashKey, "#{__dir__}/lint/duplicate_hash_key"
|
|
38
|
+
register_cop :DuplicateMagicComment, "#{__dir__}/lint/duplicate_magic_comment"
|
|
39
|
+
register_cop :DuplicateMatchPattern, "#{__dir__}/lint/duplicate_match_pattern"
|
|
40
|
+
register_cop :DuplicateMethods, "#{__dir__}/lint/duplicate_methods"
|
|
41
|
+
register_cop :DuplicateRegexpCharacterClassElement, "#{__dir__}/lint/duplicate_regexp_character_class_element"
|
|
42
|
+
register_cop :DuplicateRequire, "#{__dir__}/lint/duplicate_require"
|
|
43
|
+
register_cop :DuplicateRescueException, "#{__dir__}/lint/duplicate_rescue_exception"
|
|
44
|
+
register_cop :DuplicateSetElement, "#{__dir__}/lint/duplicate_set_element"
|
|
45
|
+
register_cop :EachWithObjectArgument, "#{__dir__}/lint/each_with_object_argument"
|
|
46
|
+
register_cop :ElseLayout, "#{__dir__}/lint/else_layout"
|
|
47
|
+
register_cop :EmptyBlock, "#{__dir__}/lint/empty_block"
|
|
48
|
+
register_cop :EmptyClass, "#{__dir__}/lint/empty_class"
|
|
49
|
+
register_cop :EmptyConditionalBody, "#{__dir__}/lint/empty_conditional_body"
|
|
50
|
+
register_cop :EmptyEnsure, "#{__dir__}/lint/empty_ensure"
|
|
51
|
+
register_cop :EmptyExpression, "#{__dir__}/lint/empty_expression"
|
|
52
|
+
register_cop :EmptyFile, "#{__dir__}/lint/empty_file"
|
|
53
|
+
register_cop :EmptyInPattern, "#{__dir__}/lint/empty_in_pattern"
|
|
54
|
+
register_cop :EmptyInterpolation, "#{__dir__}/lint/empty_interpolation"
|
|
55
|
+
register_cop :EmptyWhen, "#{__dir__}/lint/empty_when"
|
|
56
|
+
register_cop :EnsureReturn, "#{__dir__}/lint/ensure_return"
|
|
57
|
+
register_cop :SharedMutableDefault, "#{__dir__}/lint/shared_mutable_default"
|
|
58
|
+
register_cop :ErbNewArguments, "#{__dir__}/lint/erb_new_arguments"
|
|
59
|
+
register_cop :FlipFlop, "#{__dir__}/lint/flip_flop"
|
|
60
|
+
register_cop :FloatComparison, "#{__dir__}/lint/float_comparison"
|
|
61
|
+
register_cop :FloatOutOfRange, "#{__dir__}/lint/float_out_of_range"
|
|
62
|
+
register_cop :FormatParameterMismatch, "#{__dir__}/lint/format_parameter_mismatch"
|
|
63
|
+
register_cop :HashCompareByIdentity, "#{__dir__}/lint/hash_compare_by_identity"
|
|
64
|
+
register_cop :HashNewWithKeywordArgumentsAsDefault, "#{__dir__}/lint/hash_new_with_keyword_arguments_as_default"
|
|
65
|
+
register_cop :HeredocMethodCallPosition, "#{__dir__}/lint/heredoc_method_call_position"
|
|
66
|
+
register_cop :IdentityComparison, "#{__dir__}/lint/identity_comparison"
|
|
67
|
+
register_cop :ImplicitStringConcatenation, "#{__dir__}/lint/implicit_string_concatenation"
|
|
68
|
+
register_cop :IncompatibleIoSelectWithFiberScheduler, "#{__dir__}/lint/incompatible_io_select_with_fiber_scheduler"
|
|
69
|
+
register_cop :IneffectiveAccessModifier, "#{__dir__}/lint/ineffective_access_modifier"
|
|
70
|
+
register_cop :InheritException, "#{__dir__}/lint/inherit_exception"
|
|
71
|
+
register_cop :InterpolationCheck, "#{__dir__}/lint/interpolation_check"
|
|
72
|
+
register_cop :ItWithoutArgumentsInBlock, "#{__dir__}/lint/it_without_arguments_in_block"
|
|
73
|
+
register_cop :LambdaWithoutLiteralBlock, "#{__dir__}/lint/lambda_without_literal_block"
|
|
74
|
+
register_cop :LiteralAsCondition, "#{__dir__}/lint/literal_as_condition"
|
|
75
|
+
register_cop :LiteralAssignmentInCondition, "#{__dir__}/lint/literal_assignment_in_condition"
|
|
76
|
+
register_cop :LiteralInInterpolation, "#{__dir__}/lint/literal_in_interpolation"
|
|
77
|
+
register_cop :Loop, "#{__dir__}/lint/loop"
|
|
78
|
+
register_cop :MissingCopEnableDirective, "#{__dir__}/lint/missing_cop_enable_directive"
|
|
79
|
+
register_cop :MissingSuper, "#{__dir__}/lint/missing_super"
|
|
80
|
+
register_cop :MixedCaseRange, "#{__dir__}/lint/mixed_case_range"
|
|
81
|
+
register_cop :MixedRegexpCaptureTypes, "#{__dir__}/lint/mixed_regexp_capture_types"
|
|
82
|
+
register_cop :MultipleComparison, "#{__dir__}/lint/multiple_comparison"
|
|
83
|
+
register_cop :NameTypo, "#{__dir__}/lint/name_typo"
|
|
84
|
+
register_cop :NestedMethodDefinition, "#{__dir__}/lint/nested_method_definition"
|
|
85
|
+
register_cop :NestedPercentLiteral, "#{__dir__}/lint/nested_percent_literal"
|
|
86
|
+
register_cop :NextWithoutAccumulator, "#{__dir__}/lint/next_without_accumulator"
|
|
87
|
+
register_cop :NoReturnInBeginEndBlocks, "#{__dir__}/lint/no_return_in_begin_end_blocks"
|
|
88
|
+
register_cop :NonAtomicFileOperation, "#{__dir__}/lint/non_atomic_file_operation"
|
|
89
|
+
register_cop :NonDeterministicRequireOrder, "#{__dir__}/lint/non_deterministic_require_order"
|
|
90
|
+
register_cop :NonLocalExitFromIterator, "#{__dir__}/lint/non_local_exit_from_iterator"
|
|
91
|
+
register_cop :NumberConversion, "#{__dir__}/lint/number_conversion"
|
|
92
|
+
register_cop :NumberedParameterAssignment, "#{__dir__}/lint/numbered_parameter_assignment"
|
|
93
|
+
register_cop :NumericOperationWithConstantResult, "#{__dir__}/lint/numeric_operation_with_constant_result"
|
|
94
|
+
register_cop :OrAssignmentToConstant, "#{__dir__}/lint/or_assignment_to_constant"
|
|
95
|
+
register_cop :OrderedMagicComments, "#{__dir__}/lint/ordered_magic_comments"
|
|
96
|
+
register_cop :OutOfRangeRegexpRef, "#{__dir__}/lint/out_of_range_regexp_ref"
|
|
97
|
+
register_cop :ParenthesesAsGroupedExpression, "#{__dir__}/lint/parentheses_as_grouped_expression"
|
|
98
|
+
register_cop :PercentStringArray, "#{__dir__}/lint/percent_string_array"
|
|
99
|
+
register_cop :PercentSymbolArray, "#{__dir__}/lint/percent_symbol_array"
|
|
100
|
+
register_cop :RaiseException, "#{__dir__}/lint/raise_exception"
|
|
101
|
+
register_cop :RandOne, "#{__dir__}/lint/rand_one"
|
|
102
|
+
register_cop :RedundantCopDisableDirective, "#{__dir__}/lint/redundant_cop_disable_directive"
|
|
103
|
+
register_cop :RedundantCopEnableDirective, "#{__dir__}/lint/redundant_cop_enable_directive"
|
|
104
|
+
register_cop :RedundantDirGlobSort, "#{__dir__}/lint/redundant_dir_glob_sort"
|
|
105
|
+
register_cop :RedundantRegexpQuantifiers, "#{__dir__}/lint/redundant_regexp_quantifiers"
|
|
106
|
+
register_cop :RedundantRequireStatement, "#{__dir__}/lint/redundant_require_statement"
|
|
107
|
+
register_cop :RedundantSafeNavigation, "#{__dir__}/lint/redundant_safe_navigation"
|
|
108
|
+
register_cop :RedundantSplatExpansion, "#{__dir__}/lint/redundant_splat_expansion"
|
|
109
|
+
register_cop :RedundantStringCoercion, "#{__dir__}/lint/redundant_string_coercion"
|
|
110
|
+
register_cop :RedundantTypeConversion, "#{__dir__}/lint/redundant_type_conversion"
|
|
111
|
+
register_cop :RedundantWithIndex, "#{__dir__}/lint/redundant_with_index"
|
|
112
|
+
register_cop :RedundantWithObject, "#{__dir__}/lint/redundant_with_object"
|
|
113
|
+
register_cop :RefinementImportMethods, "#{__dir__}/lint/refinement_import_methods"
|
|
114
|
+
register_cop :RegexpAsCondition, "#{__dir__}/lint/regexp_as_condition"
|
|
115
|
+
register_cop :RequireParentheses, "#{__dir__}/lint/require_parentheses"
|
|
116
|
+
register_cop :RequireRangeParentheses, "#{__dir__}/lint/require_range_parentheses"
|
|
117
|
+
register_cop :RequireRelativeSelfPath, "#{__dir__}/lint/require_relative_self_path"
|
|
118
|
+
register_cop :RescueException, "#{__dir__}/lint/rescue_exception"
|
|
119
|
+
register_cop :RescueType, "#{__dir__}/lint/rescue_type"
|
|
120
|
+
register_cop :ReturnInVoidContext, "#{__dir__}/lint/return_in_void_context"
|
|
121
|
+
register_cop :SafeNavigationConsistency, "#{__dir__}/lint/safe_navigation_consistency"
|
|
122
|
+
register_cop :SafeNavigationChain, "#{__dir__}/lint/safe_navigation_chain"
|
|
123
|
+
register_cop :SafeNavigationWithEmpty, "#{__dir__}/lint/safe_navigation_with_empty"
|
|
124
|
+
register_cop :ScriptPermission, "#{__dir__}/lint/script_permission"
|
|
125
|
+
register_cop :SelfAssignment, "#{__dir__}/lint/self_assignment"
|
|
126
|
+
register_cop :SendWithMixinArgument, "#{__dir__}/lint/send_with_mixin_argument"
|
|
127
|
+
register_cop :ShadowedArgument, "#{__dir__}/lint/shadowed_argument"
|
|
128
|
+
register_cop :ShadowedException, "#{__dir__}/lint/shadowed_exception"
|
|
129
|
+
register_cop :ShadowingOuterLocalVariable, "#{__dir__}/lint/shadowing_outer_local_variable"
|
|
130
|
+
register_cop :StructNewOverride, "#{__dir__}/lint/struct_new_override"
|
|
131
|
+
register_cop :SuppressedException, "#{__dir__}/lint/suppressed_exception"
|
|
132
|
+
register_cop :SuppressedExceptionInNumberConversion, "#{__dir__}/lint/suppressed_exception_in_number_conversion"
|
|
133
|
+
register_cop :SymbolConversion, "#{__dir__}/lint/symbol_conversion"
|
|
134
|
+
register_cop :Syntax, "#{__dir__}/lint/syntax"
|
|
135
|
+
register_cop :ToEnumArguments, "#{__dir__}/lint/to_enum_arguments"
|
|
136
|
+
register_cop :ToJSON, "#{__dir__}/lint/to_json"
|
|
137
|
+
register_cop :TopLevelReturnWithArgument, "#{__dir__}/lint/top_level_return_with_argument"
|
|
138
|
+
register_cop :TrailingCommaInAttributeDeclaration, "#{__dir__}/lint/trailing_comma_in_attribute_declaration"
|
|
139
|
+
register_cop :TripleQuotes, "#{__dir__}/lint/triple_quotes"
|
|
140
|
+
register_cop :UnderscorePrefixedVariableName, "#{__dir__}/lint/underscore_prefixed_variable_name"
|
|
141
|
+
register_cop :UnescapedBracketInRegexp, "#{__dir__}/lint/unescaped_bracket_in_regexp"
|
|
142
|
+
register_cop :UnexpectedBlockArity, "#{__dir__}/lint/unexpected_block_arity"
|
|
143
|
+
register_cop :UnifiedInteger, "#{__dir__}/lint/unified_integer"
|
|
144
|
+
register_cop :UnmodifiedReduceAccumulator, "#{__dir__}/lint/unmodified_reduce_accumulator"
|
|
145
|
+
register_cop :UnreachableCode, "#{__dir__}/lint/unreachable_code"
|
|
146
|
+
register_cop :UnreachableLoop, "#{__dir__}/lint/unreachable_loop"
|
|
147
|
+
register_cop :UnreachablePatternBranch, "#{__dir__}/lint/unreachable_pattern_branch"
|
|
148
|
+
register_cop :UnusedBlockArgument, "#{__dir__}/lint/unused_block_argument"
|
|
149
|
+
register_cop :UnusedMethodArgument, "#{__dir__}/lint/unused_method_argument"
|
|
150
|
+
register_cop :UnusedPrivateMethod, "#{__dir__}/lint/unused_private_method"
|
|
151
|
+
register_cop :UriEscapeUnescape, "#{__dir__}/lint/uri_escape_unescape"
|
|
152
|
+
register_cop :UriRegexp, "#{__dir__}/lint/uri_regexp"
|
|
153
|
+
register_cop :UselessAccessModifier, "#{__dir__}/lint/useless_access_modifier"
|
|
154
|
+
register_cop :UselessAssignment, "#{__dir__}/lint/useless_assignment"
|
|
155
|
+
register_cop :UselessConstantScoping, "#{__dir__}/lint/useless_constant_scoping"
|
|
156
|
+
register_cop :UselessDefaultValueArgument, "#{__dir__}/lint/useless_default_value_argument"
|
|
157
|
+
register_cop :UselessDefined, "#{__dir__}/lint/useless_defined"
|
|
158
|
+
register_cop :UselessElseWithoutRescue, "#{__dir__}/lint/useless_else_without_rescue"
|
|
159
|
+
register_cop :UselessMethodDefinition, "#{__dir__}/lint/useless_method_definition"
|
|
160
|
+
register_cop :UselessNumericOperation, "#{__dir__}/lint/useless_numeric_operation"
|
|
161
|
+
register_cop :UselessOr, "#{__dir__}/lint/useless_or"
|
|
162
|
+
register_cop :UselessRescue, "#{__dir__}/lint/useless_rescue"
|
|
163
|
+
register_cop :UselessRuby2Keywords, "#{__dir__}/lint/useless_ruby2_keywords"
|
|
164
|
+
register_cop :UselessSetterCall, "#{__dir__}/lint/useless_setter_call"
|
|
165
|
+
register_cop :UselessTimes, "#{__dir__}/lint/useless_times"
|
|
166
|
+
register_cop :Void, "#{__dir__}/lint/void"
|
|
167
|
+
|
|
168
|
+
autoload :UnusedArgument, "#{__dir__}/mixin/unused_argument"
|
|
169
|
+
|
|
170
|
+
# Utility classes for `Lint` department cops.
|
|
171
|
+
module Utils
|
|
172
|
+
autoload :NilReceiverChecker, "#{__dir__}/lint/utils/nil_receiver_checker"
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
@@ -189,7 +189,7 @@ module RuboCop
|
|
|
189
189
|
def source_from_node_with_heredoc(node)
|
|
190
190
|
last_line = -1
|
|
191
191
|
node.each_descendant do |descendant|
|
|
192
|
-
next
|
|
192
|
+
next if descendant.loc.nil? || descendant.source_range.nil?
|
|
193
193
|
|
|
194
194
|
descendant_last_line =
|
|
195
195
|
if heredoc_node?(descendant)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
# Cops for the `Metrics` department. The department's cops are registered for lazy loading
|
|
6
|
+
# and their files are loaded on demand.
|
|
7
|
+
module Metrics
|
|
8
|
+
extend LazyLoader
|
|
9
|
+
|
|
10
|
+
register_cop :CyclomaticComplexity, "#{__dir__}/metrics/cyclomatic_complexity"
|
|
11
|
+
register_cop :AbcSize, "#{__dir__}/metrics/abc_size"
|
|
12
|
+
register_cop :BlockLength, "#{__dir__}/metrics/block_length"
|
|
13
|
+
register_cop :BlockNesting, "#{__dir__}/metrics/block_nesting"
|
|
14
|
+
register_cop :ClassLength, "#{__dir__}/metrics/class_length"
|
|
15
|
+
register_cop :CollectionLiteralLength, "#{__dir__}/metrics/collection_literal_length"
|
|
16
|
+
register_cop :MethodLength, "#{__dir__}/metrics/method_length"
|
|
17
|
+
register_cop :ModuleLength, "#{__dir__}/metrics/module_length"
|
|
18
|
+
register_cop :ParameterLists, "#{__dir__}/metrics/parameter_lists"
|
|
19
|
+
register_cop :PerceivedComplexity, "#{__dir__}/metrics/perceived_complexity"
|
|
20
|
+
|
|
21
|
+
# Utility classes for `Metrics` department cops.
|
|
22
|
+
module Utils
|
|
23
|
+
autoload :AbcSizeCalculator, "#{__dir__}/metrics/utils/abc_size_calculator"
|
|
24
|
+
autoload :CodeLengthCalculator, "#{__dir__}/metrics/utils/code_length_calculator"
|
|
25
|
+
autoload :IteratingBlock, "#{__dir__}/metrics/utils/iterating_block"
|
|
26
|
+
autoload :RepeatedAttributeDiscount, "#{__dir__}/metrics/utils/repeated_attribute_discount"
|
|
27
|
+
autoload :RepeatedCsendDiscount, "#{__dir__}/metrics/utils/repeated_csend_discount"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
# Cops for the `Migration` department. The department's cops are registered for lazy loading
|
|
6
|
+
# and their files are loaded on demand.
|
|
7
|
+
module Migration
|
|
8
|
+
extend LazyLoader
|
|
9
|
+
|
|
10
|
+
register_cop :DepartmentName, "#{__dir__}/migration/department_name"
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -61,11 +61,13 @@ module RuboCop
|
|
|
61
61
|
# @api private
|
|
62
62
|
def extract_breakable_node_from_elements(node, elements, max)
|
|
63
63
|
return unless breakable_collection?(node, elements)
|
|
64
|
-
return if safe_to_ignore?(node)
|
|
65
64
|
|
|
65
|
+
# Check the cheap conditions first, `safe_to_ignore?` may traverse all elements of
|
|
66
|
+
# a containing collection.
|
|
66
67
|
line = processed_source.lines[node.first_line - 1]
|
|
68
|
+
return if max && line.length <= max
|
|
67
69
|
return if processed_source.line_with_comment?(node.loc.line)
|
|
68
|
-
return if
|
|
70
|
+
return if safe_to_ignore?(node)
|
|
69
71
|
|
|
70
72
|
extract_first_element_over_column_limit(node, elements, max)
|
|
71
73
|
end
|
|
@@ -173,20 +175,36 @@ module RuboCop
|
|
|
173
175
|
node.each_ancestor.find do |ancestor|
|
|
174
176
|
if ancestor.type?(:hash, :array) &&
|
|
175
177
|
breakable_collection?(ancestor, ancestor.children)
|
|
176
|
-
return children_could_be_broken_up?(ancestor.children)
|
|
178
|
+
return children_could_be_broken_up?(ancestor, ancestor.children)
|
|
177
179
|
end
|
|
178
180
|
|
|
179
181
|
next unless ancestor.call_type?
|
|
180
182
|
|
|
181
183
|
args = process_args(ancestor.arguments)
|
|
182
|
-
|
|
184
|
+
if breakable_collection?(ancestor, args)
|
|
185
|
+
return children_could_be_broken_up?(ancestor, args)
|
|
186
|
+
end
|
|
183
187
|
end
|
|
184
188
|
|
|
185
189
|
false
|
|
186
190
|
end
|
|
187
191
|
|
|
188
192
|
# @api private
|
|
189
|
-
|
|
193
|
+
# The result depends only on the given node, but the check may traverse all children of
|
|
194
|
+
# a large collection and is repeated for each contained element, so memoize it per node.
|
|
195
|
+
def children_could_be_broken_up?(node, children)
|
|
196
|
+
if @check_line_breakable_processed_source != processed_source
|
|
197
|
+
@check_line_breakable_processed_source = processed_source
|
|
198
|
+
@children_could_be_broken_up_cache = {}.compare_by_identity
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
@children_could_be_broken_up_cache.fetch(node) do
|
|
202
|
+
@children_could_be_broken_up_cache[node] = compute_children_could_be_broken_up?(children)
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# @api private
|
|
207
|
+
def compute_children_could_be_broken_up?(children)
|
|
190
208
|
return false if all_on_same_line?(children)
|
|
191
209
|
|
|
192
210
|
last_seen_line = -1
|
|
@@ -5,20 +5,28 @@ module RuboCop
|
|
|
5
5
|
# Common functionality for rewriting endless methods to normal method definitions
|
|
6
6
|
module EndlessMethodRewriter
|
|
7
7
|
def correct_to_multiline(corrector, node)
|
|
8
|
-
replacement =
|
|
9
|
-
def #{node.method_name}#{arguments(node)}
|
|
10
|
-
|
|
11
|
-
end
|
|
12
|
-
|
|
8
|
+
replacement = [
|
|
9
|
+
"def #{receiver(node)}#{node.method_name}#{arguments(node)}",
|
|
10
|
+
"#{indent(node, offset: configured_indentation_width)}#{node.body.source}",
|
|
11
|
+
"#{indent(node)}end"
|
|
12
|
+
].join("\n")
|
|
13
13
|
|
|
14
14
|
corrector.replace(node, replacement)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
private
|
|
18
18
|
|
|
19
|
+
def receiver(node)
|
|
20
|
+
node.receiver ? "#{node.receiver.source}#{node.loc.operator.source}" : ''
|
|
21
|
+
end
|
|
22
|
+
|
|
19
23
|
def arguments(node, missing = '')
|
|
20
24
|
node.arguments.any? ? node.arguments.source : missing
|
|
21
25
|
end
|
|
26
|
+
|
|
27
|
+
def configured_indentation_width
|
|
28
|
+
cop_config['IndentationWidth'] || config.for_cop('Layout/IndentationWidth')['Width'] || 2
|
|
29
|
+
end
|
|
22
30
|
end
|
|
23
31
|
end
|
|
24
32
|
end
|
|
@@ -96,20 +96,37 @@ module RuboCop
|
|
|
96
96
|
end
|
|
97
97
|
|
|
98
98
|
def hash_rocket_delta(first_pair, current_pair)
|
|
99
|
-
first_pair.loc.column
|
|
100
|
-
current_pair.loc.operator.column
|
|
99
|
+
target_operator_column(first_pair) - current_pair.loc.operator.column
|
|
101
100
|
end
|
|
102
101
|
|
|
103
102
|
def value_delta(first_pair, current_pair)
|
|
104
|
-
correct_value_column = first_pair
|
|
105
|
-
|
|
106
|
-
max_delimiter_width(first_pair.parent)
|
|
103
|
+
correct_value_column = target_operator_column(first_pair) +
|
|
104
|
+
max_delimiter_width(first_pair.parent) - 1
|
|
107
105
|
|
|
108
106
|
current_pair.value_omission? ? 0 : correct_value_column - current_pair.value.loc.column
|
|
109
107
|
end
|
|
110
108
|
|
|
109
|
+
# The column the separator should land on: the shared key margin
|
|
110
|
+
# plus the widest single-line key, or, if larger, a multiline key's
|
|
111
|
+
# own last-line end column. The latter can't be measured from a
|
|
112
|
+
# multiline key's (newline-including) source length, so it's a
|
|
113
|
+
# separate candidate rather than folded into `max_key_width`.
|
|
114
|
+
def target_operator_column(first_pair)
|
|
115
|
+
hash_node = first_pair.parent
|
|
116
|
+
candidates = multiline_key_end_columns(hash_node)
|
|
117
|
+
|
|
118
|
+
key_width = max_key_width(hash_node)
|
|
119
|
+
candidates << (first_pair.loc.column + key_width + 1) if key_width.positive?
|
|
120
|
+
|
|
121
|
+
candidates.max
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def multiline_key_end_columns(hash_node)
|
|
125
|
+
hash_node.keys.reject(&:single_line?).map { |key| key.source_range.end.column + 1 }
|
|
126
|
+
end
|
|
127
|
+
|
|
111
128
|
def max_key_width(hash_node)
|
|
112
|
-
hash_node.keys.map { |key| key.source.length }.max
|
|
129
|
+
hash_node.keys.select(&:single_line?).map { |key| key.source.length }.max || 0
|
|
113
130
|
end
|
|
114
131
|
|
|
115
132
|
def max_delimiter_width(hash_node)
|
|
@@ -17,6 +17,14 @@ module RuboCop
|
|
|
17
17
|
# remains after stripping `file://` from a `file:///C:/...` URI.
|
|
18
18
|
WINDOWS_DRIVE_PREFIX = %r{\A/(?=[A-Za-z]:[/\\])}.freeze
|
|
19
19
|
|
|
20
|
+
class << self
|
|
21
|
+
# The signature is a property of the index, not of the cop, and computing
|
|
22
|
+
# it stats every indexed file, so all cops sharing an index share one
|
|
23
|
+
# computation. A single-entry cache (instead of a hash keyed by index)
|
|
24
|
+
# avoids retaining stale graphs in long-lived processes.
|
|
25
|
+
attr_accessor :cached_index_signature
|
|
26
|
+
end
|
|
27
|
+
|
|
20
28
|
def external_dependency_checksum
|
|
21
29
|
return nil unless project_index
|
|
22
30
|
|
|
@@ -27,7 +35,139 @@ module RuboCop
|
|
|
27
35
|
|
|
28
36
|
private
|
|
29
37
|
|
|
38
|
+
# Returns the definitions among `definitions` that live in a file other than the
|
|
39
|
+
# one being inspected, ordered by path and line. Definitions without a `file://`
|
|
40
|
+
# URI (e.g. Rubydex's built-in declarations) are ignored.
|
|
41
|
+
def definitions_in_other_files(definitions)
|
|
42
|
+
current = processed_source.file_path
|
|
43
|
+
|
|
44
|
+
definitions
|
|
45
|
+
.select { |definition| definition.location.uri.start_with?(FILE_URI_PREFIX) }
|
|
46
|
+
.reject { |definition| File.identical?(definition.location.to_file_path, current) }
|
|
47
|
+
.sort_by do |definition|
|
|
48
|
+
[definition.location.to_file_path,
|
|
49
|
+
definition.location.start_line]
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def prior_definition_in_other_file(definitions)
|
|
54
|
+
definitions_in_other_files(definitions).first
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Resolves a constant node the way Ruby does: the first segment through
|
|
58
|
+
# the lexical nesting and every following segment inside the previous
|
|
59
|
+
# one. (Qualified names cannot be passed to `resolve_constant` as a
|
|
60
|
+
# whole, since it only applies the nesting to the full name. Later
|
|
61
|
+
# segments use `find_member` — the namespace and its ancestors — since
|
|
62
|
+
# `resolve_constant` cannot take an already-resolved namespace as the
|
|
63
|
+
# scope, only names as they appear in source.)
|
|
64
|
+
def resolve_constant_in_index(const_node)
|
|
65
|
+
segments = const_node.const_name.split('::')
|
|
66
|
+
nesting = const_node.absolute? ? [] : lexical_nesting_of(const_node)
|
|
67
|
+
|
|
68
|
+
declaration = project_index.resolve_constant(segments.first, nesting)
|
|
69
|
+
segments.drop(1).each do |segment|
|
|
70
|
+
return nil unless declaration.is_a?(Rubydex::Namespace)
|
|
71
|
+
|
|
72
|
+
declaration = declaration.find_member(segment)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
declaration
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# The lexical nesting the node's constants resolve through, outermost
|
|
79
|
+
# first. Only scopes whose *body* contains the node count: a class or
|
|
80
|
+
# module's identifier and superclass expression are evaluated before its
|
|
81
|
+
# scope exists, so ancestors reached through them are excluded.
|
|
82
|
+
def lexical_nesting_of(node)
|
|
83
|
+
nesting = []
|
|
84
|
+
child = node
|
|
85
|
+
|
|
86
|
+
node.each_ancestor do |ancestor|
|
|
87
|
+
if ancestor.type?(:class, :module) && child.equal?(ancestor.body)
|
|
88
|
+
nesting << ancestor.identifier.const_name
|
|
89
|
+
end
|
|
90
|
+
child = ancestor
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
nesting.reverse
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# The declaration of `declaration`'s singleton class, or nil when no
|
|
97
|
+
# singleton method is defined on it anywhere in the project.
|
|
98
|
+
def indexed_singleton_of(declaration)
|
|
99
|
+
project_index["#{declaration.name}::<#{declaration.name.split('::').last}>"]
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# A namespace without any singleton method has no singleton-class
|
|
103
|
+
# declaration of its own, so the lookup starts from the first ancestor
|
|
104
|
+
# that has one; its `find_member` covers the rest of the chain.
|
|
105
|
+
def indexed_singleton_member(namespace, member_name)
|
|
106
|
+
namespace.ancestors.each do |ancestor|
|
|
107
|
+
singleton = indexed_singleton_of(ancestor)
|
|
108
|
+
return singleton.find_member(member_name) if singleton
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
nil
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Whether an ancestor of `scope` other than `scope` itself defines
|
|
115
|
+
# `member_name`.
|
|
116
|
+
def inherited_index_member?(scope, member_name)
|
|
117
|
+
scope.ancestors.any? do |ancestor|
|
|
118
|
+
ancestor.name != scope.name && ancestor.member(member_name)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Whether every link of the declaration's ancestry is resolved in the
|
|
123
|
+
# index: no definition of any ancestor has an unresolved superclass or
|
|
124
|
+
# mixin reference. Unresolved links silently vanish from `ancestors`,
|
|
125
|
+
# so this is the completeness check that must pass before reasoning
|
|
126
|
+
# about what an ancestry does or does not define. `extend` mixins only
|
|
127
|
+
# affect the singleton class; pass `ignore_extend: true` when reasoning
|
|
128
|
+
# about instance-side ancestry only.
|
|
129
|
+
def fully_resolved_index_ancestry?(declaration, ignore_extend: false)
|
|
130
|
+
declaration.ancestors.all? do |ancestor|
|
|
131
|
+
ancestor.definitions.all? do |definition|
|
|
132
|
+
resolved_superclass_reference?(definition) &&
|
|
133
|
+
resolved_mixin_references?(definition, ignore_extend: ignore_extend)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def resolved_superclass_reference?(definition)
|
|
139
|
+
return true unless definition.is_a?(Rubydex::ClassDefinition)
|
|
140
|
+
|
|
141
|
+
!definition.superclass.is_a?(Rubydex::UnresolvedConstantReference)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def resolved_mixin_references?(definition, ignore_extend: false)
|
|
145
|
+
return true unless definition.respond_to?(:mixins)
|
|
146
|
+
|
|
147
|
+
definition.mixins.none? do |mixin|
|
|
148
|
+
next false if ignore_extend && mixin.is_a?(Rubydex::Extend)
|
|
149
|
+
|
|
150
|
+
mixin.constant_reference.is_a?(Rubydex::UnresolvedConstantReference)
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def same_file?(path, other)
|
|
155
|
+
return true if File.identical?(path, other)
|
|
156
|
+
|
|
157
|
+
normalized = [path, other].map { |p| File.expand_path(p).tr('\\', '/') }
|
|
158
|
+
normalized.uniq.one? || (Platform.windows? && normalized[0].casecmp?(normalized[1]))
|
|
159
|
+
end
|
|
160
|
+
|
|
30
161
|
def project_index_signature
|
|
162
|
+
index, signature = ProjectIndexHelp.cached_index_signature
|
|
163
|
+
return signature if index.equal?(project_index)
|
|
164
|
+
|
|
165
|
+
compute_project_index_signature.tap do |computed|
|
|
166
|
+
ProjectIndexHelp.cached_index_signature = [project_index, computed]
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def compute_project_index_signature
|
|
31
171
|
project_index.documents.filter_map do |doc|
|
|
32
172
|
uri = doc.uri
|
|
33
173
|
next if uri == BUILTIN_DOCUMENT_URI
|