rubocop-callbacksystems 0.1.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 +7 -0
- data/LICENSE +21 -0
- data/README.md +78 -0
- data/config/default.yml +590 -0
- data/docs/cops.md +111 -0
- data/lib/rubocop/callbacksystems/autocorrection/batch.rb +135 -0
- data/lib/rubocop/callbacksystems/autocorrection/comment_rescue.rb +112 -0
- data/lib/rubocop/callbacksystems/autocorrection/rehearsal.rb +65 -0
- data/lib/rubocop/callbacksystems/autocorrection/rewrite_permit.rb +14 -0
- data/lib/rubocop/callbacksystems/class_structure/builder_assignment.rb +48 -0
- data/lib/rubocop/callbacksystems/class_structure/class_body.rb +50 -0
- data/lib/rubocop/callbacksystems/class_structure/divergence.rb +31 -0
- data/lib/rubocop/callbacksystems/class_structure/node_visibility.rb +82 -0
- data/lib/rubocop/callbacksystems/class_structure/reference_order.rb +36 -0
- data/lib/rubocop/callbacksystems/class_structure/statement_rank.rb +84 -0
- data/lib/rubocop/callbacksystems/class_structure/statement_run.rb +42 -0
- data/lib/rubocop/callbacksystems/class_structure/visibility.rb +84 -0
- data/lib/rubocop/callbacksystems/cops_document.rb +78 -0
- data/lib/rubocop/callbacksystems/execution/deferred_local_variables.rb +138 -0
- data/lib/rubocop/callbacksystems/execution/discarded_expression.rb +45 -0
- data/lib/rubocop/callbacksystems/execution/eager_evaluation_path.rb +73 -0
- data/lib/rubocop/callbacksystems/execution/immediate.rb +71 -0
- data/lib/rubocop/callbacksystems/execution/local_variable_occurrences.rb +112 -0
- data/lib/rubocop/callbacksystems/hashes/key_transform_detection.rb +108 -0
- data/lib/rubocop/callbacksystems/hashes/keyword_options.rb +37 -0
- data/lib/rubocop/callbacksystems/helpers/bodies.rb +150 -0
- data/lib/rubocop/callbacksystems/helpers/builders.rb +103 -0
- data/lib/rubocop/callbacksystems/helpers/comments.rb +56 -0
- data/lib/rubocop/callbacksystems/helpers/corrections.rb +15 -0
- data/lib/rubocop/callbacksystems/helpers/methods.rb +46 -0
- data/lib/rubocop/callbacksystems/helpers/names.rb +65 -0
- data/lib/rubocop/callbacksystems/helpers/node_types.rb +154 -0
- data/lib/rubocop/callbacksystems/helpers/rails.rb +52 -0
- data/lib/rubocop/callbacksystems/helpers/ranges.rb +107 -0
- data/lib/rubocop/callbacksystems/helpers/recursion.rb +29 -0
- data/lib/rubocop/callbacksystems/helpers/variables.rb +44 -0
- data/lib/rubocop/callbacksystems/helpers/visibility.rb +121 -0
- data/lib/rubocop/callbacksystems/helpers.rb +43 -0
- data/lib/rubocop/callbacksystems/methods/calls.rb +38 -0
- data/lib/rubocop/callbacksystems/methods/definitions.rb +218 -0
- data/lib/rubocop/callbacksystems/methods/delegate_macro.rb +144 -0
- data/lib/rubocop/callbacksystems/methods/delegation_target.rb +55 -0
- data/lib/rubocop/callbacksystems/methods/domain.rb +77 -0
- data/lib/rubocop/callbacksystems/methods/implicit_invocations.rb +17 -0
- data/lib/rubocop/callbacksystems/methods/macro_references.rb +238 -0
- data/lib/rubocop/callbacksystems/methods/reference_evidence.rb +74 -0
- data/lib/rubocop/callbacksystems/methods/siblings.rb +24 -0
- data/lib/rubocop/callbacksystems/methods/statement_definitions.rb +68 -0
- data/lib/rubocop/callbacksystems/offense.rb +13 -0
- data/lib/rubocop/callbacksystems/plugin.rb +27 -0
- data/lib/rubocop/callbacksystems/project_index/cache.rb +16 -0
- data/lib/rubocop/callbacksystems/project_index/confinement_cache.rb +40 -0
- data/lib/rubocop/callbacksystems/project_index/constant_references.rb +74 -0
- data/lib/rubocop/callbacksystems/project_index/corrections.rb +35 -0
- data/lib/rubocop/callbacksystems/project_index/coverage.rb +56 -0
- data/lib/rubocop/callbacksystems/project_index/diagnostics.rb +60 -0
- data/lib/rubocop/callbacksystems/project_index/freshness.rb +104 -0
- data/lib/rubocop/callbacksystems/project_index/loader.rb +9 -0
- data/lib/rubocop/callbacksystems/project_index/location.rb +29 -0
- data/lib/rubocop/callbacksystems/project_index/nested_class_confinement.rb +297 -0
- data/lib/rubocop/callbacksystems/project_index/nested_class_method_dispatch.rb +50 -0
- data/lib/rubocop/callbacksystems/project_index/reading.rb +129 -0
- data/lib/rubocop/callbacksystems/project_index/source_file.rb +59 -0
- data/lib/rubocop/callbacksystems/project_index/source_file_match.rb +57 -0
- data/lib/rubocop/callbacksystems/project_index/support.rb +46 -0
- data/lib/rubocop/callbacksystems/source/comment_blocks.rb +43 -0
- data/lib/rubocop/callbacksystems/source/comments.rb +141 -0
- data/lib/rubocop/callbacksystems/source/file_ast.rb +15 -0
- data/lib/rubocop/callbacksystems/source/files_checksum.rb +43 -0
- data/lib/rubocop/callbacksystems/source/single_line_call.rb +181 -0
- data/lib/rubocop/callbacksystems/source/statement_with_comments.rb +131 -0
- data/lib/rubocop/callbacksystems/testing/cop_helpers.rb +42 -0
- data/lib/rubocop/callbacksystems/testing/fixture_call.rb +30 -0
- data/lib/rubocop/callbacksystems/testing/fixture_names.rb +62 -0
- data/lib/rubocop/callbacksystems/testing/path_mapping.rb +104 -0
- data/lib/rubocop/cop/callbacksystems/application_controller_method_definition.rb +44 -0
- data/lib/rubocop/cop/callbacksystems/assert_with_expected_argument.rb +60 -0
- data/lib/rubocop/cop/callbacksystems/base.rb +134 -0
- data/lib/rubocop/cop/callbacksystems/body_order.rb +478 -0
- data/lib/rubocop/cop/callbacksystems/builder_method_parentheses.rb +74 -0
- data/lib/rubocop/cop/callbacksystems/collapse_multiline_expression.rb +140 -0
- data/lib/rubocop/cop/callbacksystems/comment_block_length.rb +137 -0
- data/lib/rubocop/cop/callbacksystems/complex_conditional.rb +75 -0
- data/lib/rubocop/cop/callbacksystems/controller_test_response_assertion.rb +105 -0
- data/lib/rubocop/cop/callbacksystems/controller_test_response_first_assertion.rb +123 -0
- data/lib/rubocop/cop/callbacksystems/data_clump.rb +339 -0
- data/lib/rubocop/cop/callbacksystems/declarative_method_naming.rb +350 -0
- data/lib/rubocop/cop/callbacksystems/delegate_requires_private_option.rb +81 -0
- data/lib/rubocop/cop/callbacksystems/eager_loading_scope_naming.rb +386 -0
- data/lib/rubocop/cop/callbacksystems/early_return.rb +215 -0
- data/lib/rubocop/cop/callbacksystems/empty_line_before_method.rb +168 -0
- data/lib/rubocop/cop/callbacksystems/empty_line_between_sections.rb +169 -0
- data/lib/rubocop/cop/callbacksystems/empty_private_section.rb +107 -0
- data/lib/rubocop/cop/callbacksystems/expanded_empty_class_or_module.rb +71 -0
- data/lib/rubocop/cop/callbacksystems/inline_memoized_computation.rb +110 -0
- data/lib/rubocop/cop/callbacksystems/job_enqueue_methods.rb +93 -0
- data/lib/rubocop/cop/callbacksystems/max_safe_navigation_depth.rb +118 -0
- data/lib/rubocop/cop/callbacksystems/method_invocation_order.rb +261 -0
- data/lib/rubocop/cop/callbacksystems/nested_class_order.rb +255 -0
- data/lib/rubocop/cop/callbacksystems/no_abbreviations.rb +197 -0
- data/lib/rubocop/cop/callbacksystems/no_anemic_delegation.rb +101 -0
- data/lib/rubocop/cop/callbacksystems/no_anemic_record.rb +309 -0
- data/lib/rubocop/cop/callbacksystems/no_assert_select.rb +31 -0
- data/lib/rubocop/cop/callbacksystems/no_bang_method_without_counterpart.rb +451 -0
- data/lib/rubocop/cop/callbacksystems/no_call_method.rb +73 -0
- data/lib/rubocop/cop/callbacksystems/no_comments_in_test_class_body.rb +159 -0
- data/lib/rubocop/cop/callbacksystems/no_consecutive_appends.rb +261 -0
- data/lib/rubocop/cop/callbacksystems/no_custom_route_actions.rb +124 -0
- data/lib/rubocop/cop/callbacksystems/no_direct_eager_loading.rb +90 -0
- data/lib/rubocop/cop/callbacksystems/no_each_with_early_return.rb +58 -0
- data/lib/rubocop/cop/callbacksystems/no_explicit_public_modifier.rb +81 -0
- data/lib/rubocop/cop/callbacksystems/no_hash_with_default_block.rb +68 -0
- data/lib/rubocop/cop/callbacksystems/no_local_variable_return.rb +173 -0
- data/lib/rubocop/cop/callbacksystems/no_manual_accumulation.rb +188 -0
- data/lib/rubocop/cop/callbacksystems/no_mixed_memoization.rb +145 -0
- data/lib/rubocop/cop/callbacksystems/no_nested_modules_in_classes.rb +78 -0
- data/lib/rubocop/cop/callbacksystems/no_nil_at_end_of_method.rb +74 -0
- data/lib/rubocop/cop/callbacksystems/no_redundant_validation_name.rb +37 -0
- data/lib/rubocop/cop/callbacksystems/no_redundant_wrapper_method.rb +161 -0
- data/lib/rubocop/cop/callbacksystems/no_section_divider_comments.rb +105 -0
- data/lib/rubocop/cop/callbacksystems/no_send_in_tests.rb +75 -0
- data/lib/rubocop/cop/callbacksystems/no_service_objects.rb +64 -0
- data/lib/rubocop/cop/callbacksystems/no_single_letter_names.rb +47 -0
- data/lib/rubocop/cop/callbacksystems/no_singleton_class_in_modules.rb +43 -0
- data/lib/rubocop/cop/callbacksystems/no_tap_collection_building.rb +173 -0
- data/lib/rubocop/cop/callbacksystems/no_turbo_stream_in_controllers.rb +52 -0
- data/lib/rubocop/cop/callbacksystems/no_typographic_clutter.rb +159 -0
- data/lib/rubocop/cop/callbacksystems/no_writes_in_get_actions.rb +149 -0
- data/lib/rubocop/cop/callbacksystems/ordered_mixin_arguments.rb +78 -0
- data/lib/rubocop/cop/callbacksystems/plural_controller_names.rb +103 -0
- data/lib/rubocop/cop/callbacksystems/prefer_attr_reader_over_instance_variable.rb +86 -0
- data/lib/rubocop/cop/callbacksystems/prefer_backslash_continuation.rb +478 -0
- data/lib/rubocop/cop/callbacksystems/prefer_class_for_state.rb +532 -0
- data/lib/rubocop/cop/callbacksystems/prefer_class_new_for_empty_nested_class.rb +247 -0
- data/lib/rubocop/cop/callbacksystems/prefer_class_over_builder_block.rb +124 -0
- data/lib/rubocop/cop/callbacksystems/prefer_default_argument.rb +225 -0
- data/lib/rubocop/cop/callbacksystems/prefer_delegate.rb +242 -0
- data/lib/rubocop/cop/callbacksystems/prefer_delegate_over_instance_variable_assignment.rb +175 -0
- data/lib/rubocop/cop/callbacksystems/prefer_excluding.rb +204 -0
- data/lib/rubocop/cop/callbacksystems/prefer_extract_associated.rb +54 -0
- data/lib/rubocop/cop/callbacksystems/prefer_it_block_parameter.rb +156 -0
- data/lib/rubocop/cop/callbacksystems/prefer_many.rb +57 -0
- data/lib/rubocop/cop/callbacksystems/prefer_method_over_lambda.rb +211 -0
- data/lib/rubocop/cop/callbacksystems/prefer_method_over_variable.rb +172 -0
- data/lib/rubocop/cop/callbacksystems/prefer_module_for_static_class.rb +286 -0
- data/lib/rubocop/cop/callbacksystems/prefer_ordinal_array_access.rb +136 -0
- data/lib/rubocop/cop/callbacksystems/prefer_positive_wrap.rb +265 -0
- data/lib/rubocop/cop/callbacksystems/prefer_squish.rb +47 -0
- data/lib/rubocop/cop/callbacksystems/prefer_stringify_keys.rb +24 -0
- data/lib/rubocop/cop/callbacksystems/prefer_symbolize_keys.rb +24 -0
- data/lib/rubocop/cop/callbacksystems/prefer_turbo_page_refresh_broadcasts.rb +40 -0
- data/lib/rubocop/cop/callbacksystems/private_constants_in_private_section.rb +160 -0
- data/lib/rubocop/cop/callbacksystems/private_delegate_placement.rb +342 -0
- data/lib/rubocop/cop/callbacksystems/private_methods_in_private_section.rb +70 -0
- data/lib/rubocop/cop/callbacksystems/private_nested_class_method_visibility.rb +269 -0
- data/lib/rubocop/cop/callbacksystems/private_nested_classes.rb +94 -0
- data/lib/rubocop/cop/callbacksystems/public_methods_must_have_tests.rb +190 -0
- data/lib/rubocop/cop/callbacksystems/redundant_concern_extend.rb +157 -0
- data/lib/rubocop/cop/callbacksystems/redundant_constant_freeze.rb +57 -0
- data/lib/rubocop/cop/callbacksystems/redundant_constant_namespace.rb +134 -0
- data/lib/rubocop/cop/callbacksystems/reflow_comments.rb +133 -0
- data/lib/rubocop/cop/callbacksystems/repeated_fixture_in_tests.rb +106 -0
- data/lib/rubocop/cop/callbacksystems/restricted_controller_actions.rb +85 -0
- data/lib/rubocop/cop/callbacksystems/routes_module_scope.rb +336 -0
- data/lib/rubocop/cop/callbacksystems/single_line_setup_block.rb +107 -0
- data/lib/rubocop/cop/callbacksystems/single_singleton_class.rb +49 -0
- data/lib/rubocop/cop/callbacksystems/single_top_level_class_or_module.rb +160 -0
- data/lib/rubocop/cop/callbacksystems/single_use_fixture_variable.rb +211 -0
- data/lib/rubocop/cop/callbacksystems/single_use_setup_variable.rb +684 -0
- data/lib/rubocop/cop/callbacksystems/singular_scope_names.rb +47 -0
- data/lib/rubocop/cop/callbacksystems/space_inside_percent_literal.rb +73 -0
- data/lib/rubocop/cop/callbacksystems/system_test_browser_driver.rb +30 -0
- data/lib/rubocop/cop/callbacksystems/test_method_definition.rb +86 -0
- data/lib/rubocop/cop/callbacksystems/test_method_order.rb +319 -0
- data/lib/rubocop/cop/callbacksystems/too_many_instance_variables.rb +78 -0
- data/lib/rubocop/cop/callbacksystems/too_many_local_variables.rb +77 -0
- data/lib/rubocop/cop/callbacksystems/too_many_validation_guards.rb +84 -0
- data/lib/rubocop/cop/callbacksystems/unnecessary_local_variable.rb +176 -0
- data/lib/rubocop/cop/callbacksystems/unused_private_method_in_nested_class.rb +203 -0
- data/lib/rubocop-callbacksystems.rb +21 -0
- data/rubocop.yml +685 -0
- metadata +337 -0
data/docs/cops.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Cops
|
|
2
|
+
|
|
3
|
+
<!-- Generated by `bin/docs`. Do not edit by hand. -->
|
|
4
|
+
|
|
5
|
+
Every cop lives under the `Callbacksystems/` namespace and ships enabled. Each one links to its source, where an `@example` block contrasts the code it rejects with the code it asks for, and `config/default.yml` holds its options and default scope.
|
|
6
|
+
|
|
7
|
+
| Cop | Autocorrect | Description |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| [`Callbacksystems/ApplicationControllerMethodDefinition`](../lib/rubocop/cop/callbacksystems/application_controller_method_definition.rb) | | Prohibits defining methods directly in ApplicationController. |
|
|
10
|
+
| [`Callbacksystems/AssertWithExpectedArgument`](../lib/rubocop/cop/callbacksystems/assert_with_expected_argument.rb) | | Flags a two-argument `assert` whose second argument is not a failure message. |
|
|
11
|
+
| [`Callbacksystems/BodyOrder`](../lib/rubocop/cop/callbacksystems/body_order.rb) | yes | Orders a class body: mixins, constants, class declarations, state declarations, associations, delegates, macros, methods, nested classes. |
|
|
12
|
+
| [`Callbacksystems/BuilderMethodParentheses`](../lib/rubocop/cop/callbacksystems/builder_method_parentheses.rb) | yes | Requires parentheses on builder method calls that take arguments. |
|
|
13
|
+
| [`Callbacksystems/CollapseMultilineExpression`](../lib/rubocop/cop/callbacksystems/collapse_multiline_expression.rb) | yes | Collapses multiline expressions that fit on a single line. |
|
|
14
|
+
| [`Callbacksystems/CommentBlockLength`](../lib/rubocop/cop/callbacksystems/comment_block_length.rb) | | Limits how many lines a comment block takes. |
|
|
15
|
+
| [`Callbacksystems/ComplexConditional`](../lib/rubocop/cop/callbacksystems/complex_conditional.rb) | | Limits boolean operators in a conditional, so predicates get extracted. |
|
|
16
|
+
| [`Callbacksystems/ControllerTestResponseAssertion`](../lib/rubocop/cop/callbacksystems/controller_test_response_assertion.rb) | | Requires every controller test that makes a request to assert the response. |
|
|
17
|
+
| [`Callbacksystems/ControllerTestResponseFirstAssertion`](../lib/rubocop/cop/callbacksystems/controller_test_response_first_assertion.rb) | | Requires the response assertion to come first after a request in controller tests. |
|
|
18
|
+
| [`Callbacksystems/DataClump`](../lib/rubocop/cop/callbacksystems/data_clump.rb) | | Detects parameter names that travel together across private methods and belong in an object of their own. |
|
|
19
|
+
| [`Callbacksystems/DeclarativeMethodNaming`](../lib/rubocop/cop/callbacksystems/declarative_method_naming.rb) | | Requires a value-returning method to be named for the value, not the action. |
|
|
20
|
+
| [`Callbacksystems/DelegateRequiresPrivateOption`](../lib/rubocop/cop/callbacksystems/delegate_requires_private_option.rb) | yes | Requires `private: true` on a `delegate` that stands in the private section. |
|
|
21
|
+
| [`Callbacksystems/EagerLoadingScopeNaming`](../lib/rubocop/cop/callbacksystems/eager_loading_scope_naming.rb) | | Reserves `with_*` for eager loading scopes and requires specific association names. |
|
|
22
|
+
| [`Callbacksystems/EarlyReturn`](../lib/rubocop/cop/callbacksystems/early_return.rb) | | Allows a single guard clause on the first line as the only early exit. |
|
|
23
|
+
| [`Callbacksystems/EmptyLineBeforeMethod`](../lib/rubocop/cop/callbacksystems/empty_line_before_method.rb) | yes | Requires an empty line before a method definition. |
|
|
24
|
+
| [`Callbacksystems/EmptyLineBetweenSections`](../lib/rubocop/cop/callbacksystems/empty_line_between_sections.rb) | yes | Requires a blank line between two adjacent statements of different sections of a class body. |
|
|
25
|
+
| [`Callbacksystems/EmptyPrivateSection`](../lib/rubocop/cop/callbacksystems/empty_private_section.rb) | yes | Flags a `private` keyword that declares an empty section. |
|
|
26
|
+
| [`Callbacksystems/ExpandedEmptyClassOrModule`](../lib/rubocop/cop/callbacksystems/expanded_empty_class_or_module.rb) | yes | Requires an empty class or module to keep its `end` on a line of its own. |
|
|
27
|
+
| [`Callbacksystems/InlineMemoizedComputation`](../lib/rubocop/cop/callbacksystems/inline_memoized_computation.rb) | | Requires the computation to be inlined in the method that memoizes it. |
|
|
28
|
+
| [`Callbacksystems/JobEnqueueMethods`](../lib/rubocop/cop/callbacksystems/job_enqueue_methods.rb) | | Requires a method that enqueues a job to carry the `_later` suffix. |
|
|
29
|
+
| [`Callbacksystems/MaxSafeNavigationDepth`](../lib/rubocop/cop/callbacksystems/max_safe_navigation_depth.rb) | | Limits the depth of a chain of safe navigation calls. |
|
|
30
|
+
| [`Callbacksystems/MethodInvocationOrder`](../lib/rubocop/cop/callbacksystems/method_invocation_order.rb) | yes | Requires methods to be ordered by invocation, each caller before its callees. |
|
|
31
|
+
| [`Callbacksystems/NestedClassOrder`](../lib/rubocop/cop/callbacksystems/nested_class_order.rb) | yes | Requires nested classes to be ordered by reference, each before the ones it names. |
|
|
32
|
+
| [`Callbacksystems/NoAbbreviations`](../lib/rubocop/cop/callbacksystems/no_abbreviations.rb) | | Requires full words in declared names, including CamelCase, while preserving Ruby and Rails vocabulary. |
|
|
33
|
+
| [`Callbacksystems/NoAnemicDelegation`](../lib/rubocop/cop/callbacksystems/no_anemic_delegation.rb) | | Flags a private method that only delegates to a freshly built object. |
|
|
34
|
+
| [`Callbacksystems/NoAnemicRecord`](../lib/rubocop/cop/callbacksystems/no_anemic_record.rb) | | Detects a hash literal of several fields read across methods, which reads better as a class. |
|
|
35
|
+
| [`Callbacksystems/NoAssertSelect`](../lib/rubocop/cop/callbacksystems/no_assert_select.rb) | | Prohibits `assert_select` in tests. |
|
|
36
|
+
| [`Callbacksystems/NoBangMethodWithoutCounterpart`](../lib/rubocop/cop/callbacksystems/no_bang_method_without_counterpart.rb) | | Prohibits a bang method without a non-bang counterpart. |
|
|
37
|
+
| [`Callbacksystems/NoCallMethod`](../lib/rubocop/cop/callbacksystems/no_call_method.rb) | | Prohibits defining a method named `call`, except for Rack middleware endpoints. |
|
|
38
|
+
| [`Callbacksystems/NoCommentsInTestClassBody`](../lib/rubocop/cop/callbacksystems/no_comments_in_test_class_body.rb) | | Prohibits comments in the direct body of a test class. |
|
|
39
|
+
| [`Callbacksystems/NoConsecutiveAppends`](../lib/rubocop/cop/callbacksystems/no_consecutive_appends.rb) | yes | Collapses consecutive appends to one collection into a single `push`. |
|
|
40
|
+
| [`Callbacksystems/NoCustomRouteActions`](../lib/rubocop/cop/callbacksystems/no_custom_route_actions.rb) | | Keeps routes on the standard resource actions. |
|
|
41
|
+
| [`Callbacksystems/NoDirectEagerLoading`](../lib/rubocop/cop/callbacksystems/no_direct_eager_loading.rb) | | Keeps `preload`, `eager_load`, and `includes` inside `app/models` behind named scopes. |
|
|
42
|
+
| [`Callbacksystems/NoEachWithEarlyReturn`](../lib/rubocop/cop/callbacksystems/no_each_with_early_return.rb) | | Prefers `find` over an `each` block with a conditional early return. |
|
|
43
|
+
| [`Callbacksystems/NoExplicitPublicModifier`](../lib/rubocop/cop/callbacksystems/no_explicit_public_modifier.rb) | yes | Prohibits the explicit `public` modifier. |
|
|
44
|
+
| [`Callbacksystems/NoHashWithDefaultBlock`](../lib/rubocop/cop/callbacksystems/no_hash_with_default_block.rb) | | Prefers declarative grouping over `Hash.new` with a default block. |
|
|
45
|
+
| [`Callbacksystems/NoLocalVariableReturn`](../lib/rubocop/cop/callbacksystems/no_local_variable_return.rb) | yes | Prohibits returning a local variable as the last statement of a method. |
|
|
46
|
+
| [`Callbacksystems/NoManualAccumulation`](../lib/rubocop/cop/callbacksystems/no_manual_accumulation.rb) | | Prefers declarative collection methods over filling an empty array or hash inside `each`. |
|
|
47
|
+
| [`Callbacksystems/NoMixedMemoization`](../lib/rubocop/cop/callbacksystems/no_mixed_memoization.rb) | | Prohibits mixing memoization with other statements in the same method. |
|
|
48
|
+
| [`Callbacksystems/NoNestedModulesInClasses`](../lib/rubocop/cop/callbacksystems/no_nested_modules_in_classes.rb) | | Prohibits a module nested inside a class. |
|
|
49
|
+
| [`Callbacksystems/NoNilAtEndOfMethod`](../lib/rubocop/cop/callbacksystems/no_nil_at_end_of_method.rb) | | Prohibits a trailing `nil` at the end of a method. |
|
|
50
|
+
| [`Callbacksystems/NoRedundantValidationName`](../lib/rubocop/cop/callbacksystems/no_redundant_validation_name.rb) | | Requires a validation callback to name its condition without repeating `valid` or `validate`. |
|
|
51
|
+
| [`Callbacksystems/NoRedundantWrapperMethod`](../lib/rubocop/cop/callbacksystems/no_redundant_wrapper_method.rb) | | Flags a private method that only forwards to another call. |
|
|
52
|
+
| [`Callbacksystems/NoSectionDividerComments`](../lib/rubocop/cop/callbacksystems/no_section_divider_comments.rb) | yes | Prohibits ASCII-art section divider comments. |
|
|
53
|
+
| [`Callbacksystems/NoSendInTests`](../lib/rubocop/cop/callbacksystems/no_send_in_tests.rb) | | Prohibits `send` and `__send__` in tests. |
|
|
54
|
+
| [`Callbacksystems/NoServiceObjects`](../lib/rubocop/cop/callbacksystems/no_service_objects.rb) | | Prohibits service object directories under `app/`. |
|
|
55
|
+
| [`Callbacksystems/NoSingleLetterNames`](../lib/rubocop/cop/callbacksystems/no_single_letter_names.rb) | | Prohibits single-letter variable, block argument, and parameter names. |
|
|
56
|
+
| [`Callbacksystems/NoSingletonClassInModules`](../lib/rubocop/cop/callbacksystems/no_singleton_class_in_modules.rb) | | Prefers `extend self` over `class << self` in a module. |
|
|
57
|
+
| [`Callbacksystems/NoTapCollectionBuilding`](../lib/rubocop/cop/callbacksystems/no_tap_collection_building.rb) | | Prohibits building a collection imperatively with `tap`. |
|
|
58
|
+
| [`Callbacksystems/NoTurboStreamInControllers`](../lib/rubocop/cop/callbacksystems/no_turbo_stream_in_controllers.rb) | | Keeps Turbo Stream markup out of controllers. |
|
|
59
|
+
| [`Callbacksystems/NoTypographicClutter`](../lib/rubocop/cop/callbacksystems/no_typographic_clutter.rb) | yes | Prohibits typographic punctuation and double-hyphen dashes in comments, and invisible characters in comments and strings. |
|
|
60
|
+
| [`Callbacksystems/NoWritesInGetActions`](../lib/rubocop/cop/callbacksystems/no_writes_in_get_actions.rb) | | Keeps GET actions free of writes and enqueued side effects. |
|
|
61
|
+
| [`Callbacksystems/OrderedMixinArguments`](../lib/rubocop/cop/callbacksystems/ordered_mixin_arguments.rb) | yes | Requires mixin arguments to be sorted alphabetically. |
|
|
62
|
+
| [`Callbacksystems/PluralControllerNames`](../lib/rubocop/cop/callbacksystems/plural_controller_names.rb) | | Requires controller names to be plural. |
|
|
63
|
+
| [`Callbacksystems/PreferAttrReaderOverInstanceVariable`](../lib/rubocop/cop/callbacksystems/prefer_attr_reader_over_instance_variable.rb) | | Prefers an `attr_reader` over reading an instance variable assigned in `initialize`. |
|
|
64
|
+
| [`Callbacksystems/PreferBackslashContinuation`](../lib/rubocop/cop/callbacksystems/prefer_backslash_continuation.rb) | yes | Prefers backslash continuation over parentheses for a multiline call that cannot fit on one line. |
|
|
65
|
+
| [`Callbacksystems/PreferClassForState`](../lib/rubocop/cop/callbacksystems/prefer_class_for_state.rb) | | Detects a value threaded through many methods that reads better as class state. |
|
|
66
|
+
| [`Callbacksystems/PreferClassNewForEmptyNestedClass`](../lib/rubocop/cop/callbacksystems/prefer_class_new_for_empty_nested_class.rb) | yes | Prefers a `Class.new` constant over a nested class with no body. |
|
|
67
|
+
| [`Callbacksystems/PreferClassOverBuilderBlock`](../lib/rubocop/cop/callbacksystems/prefer_class_over_builder_block.rb) | yes | Prefers a class over a `Data.define`, `Struct.new`, or `Class.new` given a block. |
|
|
68
|
+
| [`Callbacksystems/PreferDefaultArgument`](../lib/rubocop/cop/callbacksystems/prefer_default_argument.rb) | | Prefers a default in the signature over a fallback assigned at the top of the method. |
|
|
69
|
+
| [`Callbacksystems/PreferDelegate`](../lib/rubocop/cop/callbacksystems/prefer_delegate.rb) | yes | Prefers `delegate` over a method that only forwards to a same-named method. |
|
|
70
|
+
| [`Callbacksystems/PreferDelegateOverInstanceVariableAssignment`](../lib/rubocop/cop/callbacksystems/prefer_delegate_over_instance_variable_assignment.rb) | | Prefers `delegate` over an `initialize` assignment that mirrors a method call. |
|
|
71
|
+
| [`Callbacksystems/PreferExcluding`](../lib/rubocop/cop/callbacksystems/prefer_excluding.rb) | yes | Prefers `excluding` for collection subtraction and suggests it for record-ID exclusions. |
|
|
72
|
+
| [`Callbacksystems/PreferExtractAssociated`](../lib/rubocop/cop/callbacksystems/prefer_extract_associated.rb) | yes | Prefers `extract_associated` over preloading and collecting the same association in a model. |
|
|
73
|
+
| [`Callbacksystems/PreferItBlockParameter`](../lib/rubocop/cop/callbacksystems/prefer_it_block_parameter.rb) | yes | Prefers `it` over a single named parameter in a single-line block. |
|
|
74
|
+
| [`Callbacksystems/PreferMany`](../lib/rubocop/cop/callbacksystems/prefer_many.rb) | yes | Prefers `many?` over comparing `size` with one. |
|
|
75
|
+
| [`Callbacksystems/PreferMethodOverLambda`](../lib/rubocop/cop/callbacksystems/prefer_method_over_lambda.rb) | | Prefers a method over a lambda or proc held in a local that captures nothing from its method. |
|
|
76
|
+
| [`Callbacksystems/PreferMethodOverVariable`](../lib/rubocop/cop/callbacksystems/prefer_method_over_variable.rb) | | Prefers a method over a local variable that repeats the name it calls. |
|
|
77
|
+
| [`Callbacksystems/PreferModuleForStaticClass`](../lib/rubocop/cop/callbacksystems/prefer_module_for_static_class.rb) | | Prefers a module with `extend self` over a class holding only class-level code. |
|
|
78
|
+
| [`Callbacksystems/PreferOrdinalArrayAccess`](../lib/rubocop/cop/callbacksystems/prefer_ordinal_array_access.rb) | yes | Prefers an ordinal method such as `first` over a numeric array index. |
|
|
79
|
+
| [`Callbacksystems/PreferPositiveWrap`](../lib/rubocop/cop/callbacksystems/prefer_positive_wrap.rb) | yes | Prefers wrapping the happy path in `if` over a leading negative guard. |
|
|
80
|
+
| [`Callbacksystems/PreferSquish`](../lib/rubocop/cop/callbacksystems/prefer_squish.rb) | yes | Prefers `squish` over stripping and collapsing whitespace by hand. |
|
|
81
|
+
| [`Callbacksystems/PreferStringifyKeys`](../lib/rubocop/cop/callbacksystems/prefer_stringify_keys.rb) | yes | Prefers `stringify_keys` over `transform_keys(&:to_s)`. |
|
|
82
|
+
| [`Callbacksystems/PreferSymbolizeKeys`](../lib/rubocop/cop/callbacksystems/prefer_symbolize_keys.rb) | yes | Prefers `symbolize_keys` over `transform_keys(&:to_sym)`. |
|
|
83
|
+
| [`Callbacksystems/PreferTurboPageRefreshBroadcasts`](../lib/rubocop/cop/callbacksystems/prefer_turbo_page_refresh_broadcasts.rb) | | Prefers Turbo page refreshes over targeted stream broadcasts. |
|
|
84
|
+
| [`Callbacksystems/PrivateConstantsInPrivateSection`](../lib/rubocop/cop/callbacksystems/private_constants_in_private_section.rb) | | Requires a constant that serves the implementation to live in the private section. |
|
|
85
|
+
| [`Callbacksystems/PrivateDelegatePlacement`](../lib/rubocop/cop/callbacksystems/private_delegate_placement.rb) | yes | Requires a `delegate ... private: true` to sit in the private section. |
|
|
86
|
+
| [`Callbacksystems/PrivateMethodsInPrivateSection`](../lib/rubocop/cop/callbacksystems/private_methods_in_private_section.rb) | | Requires a private method to be defined in the private section, not marked afterwards. |
|
|
87
|
+
| [`Callbacksystems/PrivateNestedClassMethodVisibility`](../lib/rubocop/cop/callbacksystems/private_nested_class_method_visibility.rb) | | Requires a method in a nested class placed below `private` to be private when nothing outside calls it. |
|
|
88
|
+
| [`Callbacksystems/PrivateNestedClasses`](../lib/rubocop/cop/callbacksystems/private_nested_classes.rb) | | Requires a nested class to be declared in the private section. |
|
|
89
|
+
| [`Callbacksystems/PublicMethodsMustHaveTests`](../lib/rubocop/cop/callbacksystems/public_methods_must_have_tests.rb) | | Requires every public method to have a test. |
|
|
90
|
+
| [`Callbacksystems/RedundantConcernExtend`](../lib/rubocop/cop/callbacksystems/redundant_concern_extend.rb) | yes | Flags an unnecessary `extend ActiveSupport::Concern`. |
|
|
91
|
+
| [`Callbacksystems/RedundantConstantFreeze`](../lib/rubocop/cop/callbacksystems/redundant_constant_freeze.rb) | yes | Flags a `freeze` on a constant assignment. |
|
|
92
|
+
| [`Callbacksystems/RedundantConstantNamespace`](../lib/rubocop/cop/callbacksystems/redundant_constant_namespace.rb) | yes | Flags a constant reference that repeats the namespace it is written inside. |
|
|
93
|
+
| [`Callbacksystems/ReflowComments`](../lib/rubocop/cop/callbacksystems/reflow_comments.rb) | yes | Refills a comment block wrapped short of the maximum line length. |
|
|
94
|
+
| [`Callbacksystems/RepeatedFixtureInTests`](../lib/rubocop/cop/callbacksystems/repeated_fixture_in_tests.rb) | | Requires a fixture used by several tests to move to `setup`. |
|
|
95
|
+
| [`Callbacksystems/RestrictedControllerActions`](../lib/rubocop/cop/callbacksystems/restricted_controller_actions.rb) | | Restricts a controller to the seven standard Rails actions. |
|
|
96
|
+
| [`Callbacksystems/RoutesModuleScope`](../lib/rubocop/cop/callbacksystems/routes_module_scope.rb) | yes | Requires repeated `module:` options in routes to be extracted to a scope block. |
|
|
97
|
+
| [`Callbacksystems/SingleLineSetupBlock`](../lib/rubocop/cop/callbacksystems/single_line_setup_block.rb) | yes | Requires braces for a single-line `setup` or `teardown` block. |
|
|
98
|
+
| [`Callbacksystems/SingleSingletonClass`](../lib/rubocop/cop/callbacksystems/single_singleton_class.rb) | | Requires class-level methods to live in a single `class << self` section. |
|
|
99
|
+
| [`Callbacksystems/SingleTopLevelClassOrModule`](../lib/rubocop/cop/callbacksystems/single_top_level_class_or_module.rb) | | Prohibits more than one top-level class or module per file. |
|
|
100
|
+
| [`Callbacksystems/SingleUseFixtureVariable`](../lib/rubocop/cop/callbacksystems/single_use_fixture_variable.rb) | yes | Requires a fixture used once to be inlined. |
|
|
101
|
+
| [`Callbacksystems/SingleUseSetupVariable`](../lib/rubocop/cop/callbacksystems/single_use_setup_variable.rb) | yes | Requires a setup variable used by at most one test to be inlined. |
|
|
102
|
+
| [`Callbacksystems/SingularScopeNames`](../lib/rubocop/cop/callbacksystems/singular_scope_names.rb) | | Requires scope names to be singular unless they use a `with_` prefix. |
|
|
103
|
+
| [`Callbacksystems/SpaceInsidePercentLiteral`](../lib/rubocop/cop/callbacksystems/space_inside_percent_literal.rb) | yes | Requires a space inside the delimiters of a percent literal. |
|
|
104
|
+
| [`Callbacksystems/SystemTestBrowserDriver`](../lib/rubocop/cop/callbacksystems/system_test_browser_driver.rb) | | Keeps system tests on a real browser driver. |
|
|
105
|
+
| [`Callbacksystems/TestMethodDefinition`](../lib/rubocop/cop/callbacksystems/test_method_definition.rb) | | Requires `test` and block syntax over `def test_*` and setup method definitions. |
|
|
106
|
+
| [`Callbacksystems/TestMethodOrder`](../lib/rubocop/cop/callbacksystems/test_method_order.rb) | yes | Requires tests to follow the method order of the file they cover. |
|
|
107
|
+
| [`Callbacksystems/TooManyInstanceVariables`](../lib/rubocop/cop/callbacksystems/too_many_instance_variables.rb) | | Limits instance variable assignments in a private method. |
|
|
108
|
+
| [`Callbacksystems/TooManyLocalVariables`](../lib/rubocop/cop/callbacksystems/too_many_local_variables.rb) | | Limits local variable assignments in a method. |
|
|
109
|
+
| [`Callbacksystems/TooManyValidationGuards`](../lib/rubocop/cop/callbacksystems/too_many_validation_guards.rb) | | Limits the validation guards standing at the start of a method. |
|
|
110
|
+
| [`Callbacksystems/UnnecessaryLocalVariable`](../lib/rubocop/cop/callbacksystems/unnecessary_local_variable.rb) | yes | Flags a local variable that aliases a method call already reading as a name. |
|
|
111
|
+
| [`Callbacksystems/UnusedPrivateMethodInNestedClass`](../lib/rubocop/cop/callbacksystems/unused_private_method_in_nested_class.rb) | | Flags an unused private method in a nested class placed below `private`. |
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Corrections from one cop rehearsed together. The common path parses the rewritten file once. When preserving comments
|
|
2
|
+
# fails, every entry must have a safe form and their exact aggregate must pass a second rehearsal. A batch is atomic
|
|
3
|
+
# because its entries may depend on each other in ways syntax and comment checks cannot see.
|
|
4
|
+
class RuboCop::Callbacksystems::Autocorrection::Batch
|
|
5
|
+
BYPASS_DEPTH = :rubocop_callbacksystems_correction_batch_bypass_depth
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
# The audit reads what a correction does on its own, so a cop that declines can be told from one held back.
|
|
9
|
+
def bypassing
|
|
10
|
+
Thread.current.thread_variable_set(BYPASS_DEPTH, bypass_depth + 1)
|
|
11
|
+
yield
|
|
12
|
+
ensure
|
|
13
|
+
Thread.current.thread_variable_set(BYPASS_DEPTH, bypass_depth - 1)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def bypassed?
|
|
17
|
+
bypass_depth.positive?
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
def bypass_depth
|
|
22
|
+
Thread.current.thread_variable_get(BYPASS_DEPTH).to_i
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def initialize(entries, processed_source)
|
|
27
|
+
@entries = entries
|
|
28
|
+
@processed_source = processed_source
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def correction_for(entry)
|
|
32
|
+
corrections[entry]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
attr_reader :entries, :processed_source
|
|
37
|
+
|
|
38
|
+
def corrections
|
|
39
|
+
self.class.bypassed? ? bypassed_corrections : accepted_corrections
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def bypassed_corrections
|
|
43
|
+
@bypassed_corrections ||= selected_corrections
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def selected_corrections
|
|
47
|
+
Selection.new(entries, processed_source).corrections
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def accepted_corrections
|
|
51
|
+
@accepted_corrections ||= selected_corrections
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
class Selection
|
|
55
|
+
attr_reader :corrections
|
|
56
|
+
|
|
57
|
+
def initialize(entries, processed_source)
|
|
58
|
+
@entries = entries
|
|
59
|
+
@processed_source = processed_source
|
|
60
|
+
@corrections = {}.compare_by_identity
|
|
61
|
+
selected.each { |entry, correction| corrections[entry] = correction }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
attr_reader :entries, :processed_source
|
|
66
|
+
|
|
67
|
+
def selected
|
|
68
|
+
if accepts?(as_written) then as_written
|
|
69
|
+
elsif rescued_corrections_accepted? then rescued
|
|
70
|
+
else []
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def accepts?(candidates)
|
|
75
|
+
rehearsal = RuboCop::Callbacksystems::Autocorrection::Rehearsal.new \
|
|
76
|
+
combined_correction(candidates), processed_source
|
|
77
|
+
RuboCop::Callbacksystems::Autocorrection::Batch.bypassed? || rehearsal.empty? ||
|
|
78
|
+
(rehearsal.parses? && (rewrites_comments? || rehearsal.keeps_comments?))
|
|
79
|
+
rescue Parser::ClobberingError
|
|
80
|
+
false
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def combined_correction(candidates)
|
|
84
|
+
->(corrector) { candidates.each { it.last.call(corrector) } }
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def rewrites_comments?
|
|
88
|
+
entries.all? { it.respond_to?(:rewrites_comments?) && it.rewrites_comments? }
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def as_written
|
|
92
|
+
@as_written ||= entries.map { [ it, it.correction ] }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def rescued_corrections_accepted?
|
|
96
|
+
!rewrites_comments? && rescued && accepts?(rescued)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def rescued
|
|
100
|
+
@rescued ||= RehearsedCandidates.new(entries, processed_source).to_a
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
class RehearsedCandidates
|
|
104
|
+
def initialize(entries, processed_source)
|
|
105
|
+
@entries = entries
|
|
106
|
+
@processed_source = processed_source
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def to_a
|
|
110
|
+
candidates if candidates.size == entries.size
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
private
|
|
114
|
+
attr_reader :entries, :processed_source
|
|
115
|
+
|
|
116
|
+
def candidates
|
|
117
|
+
@candidates ||= entries.lazy.map { candidate_for(it) }.take_while(&:last).to_a
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def candidate_for(entry)
|
|
121
|
+
[ entry, preserving_comments_in(entry) ]
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def preserving_comments_in(entry)
|
|
125
|
+
comment_rescue_for(entry).preserving(entry.correction)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def comment_rescue_for(entry)
|
|
129
|
+
RuboCop::Callbacksystems::Autocorrection::CommentRescue.new \
|
|
130
|
+
RuboCop::Callbacksystems::Autocorrection::Rehearsal.new(entry.correction, processed_source),
|
|
131
|
+
processed_source
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# The edits of a rehearsed correction with the comments they swallowed written back in: trailing the rewritten line they
|
|
2
|
+
# were on, or standing on lines of their own where the code around them went away.
|
|
3
|
+
class RuboCop::Callbacksystems::Autocorrection::CommentRescue
|
|
4
|
+
def initialize(rehearsal, processed_source)
|
|
5
|
+
@rehearsal = rehearsal
|
|
6
|
+
@processed_source = processed_source
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def preserving(original_correction)
|
|
10
|
+
replacements.none?(&:rescues?) ? original_correction : correction
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def correction
|
|
14
|
+
if replacements.any?(&:rescues?) && replacements.none?(&:rescues_tooling?)
|
|
15
|
+
->(corrector) { replacements.each { corrector.replace(it.range, it.rescued_text) } }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
attr_reader :rehearsal, :processed_source
|
|
21
|
+
|
|
22
|
+
def replacements
|
|
23
|
+
@replacements ||= rehearsal.as_replacements.map do |range, text|
|
|
24
|
+
Replacement.new(range, text, source_comments)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def source_comments
|
|
29
|
+
@source_comments ||= RuboCop::Callbacksystems::Source::Comments.for(processed_source)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class Replacement
|
|
33
|
+
include RuboCop::Callbacksystems::Helpers
|
|
34
|
+
|
|
35
|
+
attr_reader :range
|
|
36
|
+
|
|
37
|
+
def initialize(range, text, source_comments)
|
|
38
|
+
@range = range
|
|
39
|
+
@text = text
|
|
40
|
+
@source_comments = source_comments
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def rescues?
|
|
44
|
+
comments.any?
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def rescues_tooling?
|
|
48
|
+
comments.any? { tooling_comment?(it) }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def rescued_text
|
|
52
|
+
if comments.empty? then text
|
|
53
|
+
elsif text.empty? then standing_lines
|
|
54
|
+
else trailing_text
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
attr_reader :text, :source_comments
|
|
60
|
+
|
|
61
|
+
def comments
|
|
62
|
+
@comments ||= source_comments.within(range).reject { text.include?(it.text) }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def standing_lines
|
|
66
|
+
comments.map.with_index { |comment, index| index.zero? ? opening_line_for(comment) : own_line_for(comment) }
|
|
67
|
+
.join + closing
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def opening_line_for(comment)
|
|
71
|
+
before = range.begin.source_line[0...range.begin.column]
|
|
72
|
+
if before.strip.present? then " #{comment.text}"
|
|
73
|
+
elsif range.begin.column.zero? then own_line_for(comment).delete_prefix("\n")
|
|
74
|
+
else comment.text
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def own_line_for(comment)
|
|
79
|
+
"\n#{line_indentation_of(comment)}#{comment.text}"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# A comment that trailed code takes the indentation of its line, not the column it sat at.
|
|
83
|
+
def line_indentation_of(comment)
|
|
84
|
+
comment.source_range.source_line[/\A[ \t]*/]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def closing
|
|
88
|
+
after = range.end.source_line[range.end.column..]
|
|
89
|
+
after.strip.empty? ? "" : "\n#{" " * range.end.column}"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def trailing_text
|
|
93
|
+
"#{opened(text.chomp)}#{trailing_below_first}#{standing}#{"\n" if text.end_with?("\n")}"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def opened(body)
|
|
97
|
+
body.sub(/$/) { on_first_line.map { " #{it.text}" }.join }
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def on_first_line
|
|
101
|
+
comments.select { it.loc.line == range.line && !own_line_comment?(it) }
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def trailing_below_first
|
|
105
|
+
comments.reject { it.loc.line == range.line || own_line_comment?(it) }.map { " #{it.text}" }.join
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def standing
|
|
109
|
+
comments.select { own_line_comment?(it) }.map { own_line_for(it) }.join
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require "prism"
|
|
2
|
+
|
|
3
|
+
# A correction run on a corrector of its own, so what it would do to the source can be read before it is offered.
|
|
4
|
+
class RuboCop::Callbacksystems::Autocorrection::Rehearsal
|
|
5
|
+
delegate :empty?, :as_replacements, to: :corrector
|
|
6
|
+
|
|
7
|
+
def initialize(correction, processed_source)
|
|
8
|
+
@correction = correction
|
|
9
|
+
@processed_source = processed_source
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def parses?
|
|
13
|
+
prism_parser? ? parsed_rewrite.success? : processed_rewrite.valid_syntax?
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def keeps_comments?
|
|
17
|
+
comment_counts.all? { |text, count| rewritten_comment_counts.fetch(text, 0) >= count }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
attr_reader :correction, :processed_source
|
|
22
|
+
|
|
23
|
+
def prism_parser?
|
|
24
|
+
processed_source.parser_engine == :parser_prism
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def parsed_rewrite
|
|
28
|
+
@parsed_rewrite ||= Prism.parse \
|
|
29
|
+
rewritten,
|
|
30
|
+
filepath: processed_source.path,
|
|
31
|
+
version: processed_source.ruby_version.to_s
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def rewritten
|
|
35
|
+
@rewritten ||= corrector.rewrite
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def corrector
|
|
39
|
+
@corrector ||= RuboCop::Cop::Corrector.new(processed_source).tap { correction.call(it) }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def processed_rewrite
|
|
43
|
+
@processed_rewrite ||= RuboCop::ProcessedSource.new \
|
|
44
|
+
rewritten,
|
|
45
|
+
processed_source.ruby_version,
|
|
46
|
+
processed_source.path,
|
|
47
|
+
parser_engine: processed_source.parser_engine
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def comment_counts
|
|
51
|
+
@comment_counts ||= processed_source.comments.map(&:text).tally
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def rewritten_comment_counts
|
|
55
|
+
@rewritten_comment_counts ||= rewritten_comment_texts.tally
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def rewritten_comment_texts
|
|
59
|
+
if prism_parser?
|
|
60
|
+
parsed_rewrite.comments.map { it.location.slice }
|
|
61
|
+
else
|
|
62
|
+
processed_rewrite.comments.map(&:text)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# The single rewrite a pass may spend. A statement carrying a body travels with everything written inside it, so a
|
|
2
|
+
# second rewrite reaching into that same text would clobber it, and the pass that follows takes the next one.
|
|
3
|
+
class RuboCop::Callbacksystems::Autocorrection::RewritePermit
|
|
4
|
+
def initialize(granted: true)
|
|
5
|
+
@granted = granted
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def claim
|
|
9
|
+
granted.tap { @granted = false }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
attr_reader :granted
|
|
14
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# A constant assignment whose expression uses one of Ruby's root class or module builders.
|
|
2
|
+
class RuboCop::Callbacksystems::ClassStructure::BuilderAssignment
|
|
3
|
+
include RuboCop::Callbacksystems::Helpers
|
|
4
|
+
|
|
5
|
+
CLASS_BUILDERS = { Data: :define, Struct: :new, Class: :new }
|
|
6
|
+
MODULE_BUILDERS = { Module: :new }
|
|
7
|
+
|
|
8
|
+
def initialize(node)
|
|
9
|
+
@node = node
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def builds_class_with_body?
|
|
13
|
+
builds_class? && block_with_body?
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def builds_class?
|
|
17
|
+
builds?(CLASS_BUILDERS)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def builds_module_with_body?
|
|
21
|
+
builds_module? && block_with_body?
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def builds_module?
|
|
25
|
+
builds?(MODULE_BUILDERS)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
attr_reader :node
|
|
30
|
+
|
|
31
|
+
def builds?(builders)
|
|
32
|
+
builder_named_in?(builders)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def builder_named_in?(builders)
|
|
36
|
+
builder_call&.receiver.then do |receiver|
|
|
37
|
+
core_constant?(receiver) && builders[receiver.short_name] == builder_call.method_name
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def builder_call
|
|
42
|
+
@builder_call ||= call_of(node.expression) if node&.casgn_type?
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def block_with_body?
|
|
46
|
+
any_block_type?(node.expression) && node.expression.body.present?
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
class RuboCop::Callbacksystems::ClassStructure::ClassBody
|
|
2
|
+
include RuboCop::Callbacksystems::Helpers
|
|
3
|
+
|
|
4
|
+
def initialize(body)
|
|
5
|
+
@body = body
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def public_method_nodes
|
|
9
|
+
public_children.select(&:def_type?)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def public_children
|
|
13
|
+
each_child_with_visibility.filter_map { |child, level| child if level == :public }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def each_child_with_visibility
|
|
17
|
+
if block_given?
|
|
18
|
+
visibility.each_statement { |child, level| yield child, level }
|
|
19
|
+
else
|
|
20
|
+
visibility.each_statement
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def private_method_nodes
|
|
25
|
+
private_children.select(&:def_type?)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def private_nested_classes
|
|
29
|
+
private_children.select(&:class_type?)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def in_private_section?(node)
|
|
33
|
+
visibility.level_at(node) == :private
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def private_modifier
|
|
37
|
+
statements_in(body).find { visibility_modifier_of(it) == :private }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
attr_reader :body
|
|
42
|
+
|
|
43
|
+
def visibility
|
|
44
|
+
@visibility ||= RuboCop::Callbacksystems::ClassStructure::Visibility.for(body)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def private_children
|
|
48
|
+
each_child_with_visibility.filter_map { |child, level| child if level == :private }
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# The first place a sequence of names departs from the order expected of it, read as the index, the name the order
|
|
2
|
+
# expects there and the name found instead.
|
|
3
|
+
class RuboCop::Callbacksystems::ClassStructure::Divergence
|
|
4
|
+
def initialize(names, from:)
|
|
5
|
+
@names = names
|
|
6
|
+
@order = from
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def found?
|
|
10
|
+
index.present?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def index
|
|
14
|
+
@index ||= names.each_index.find { names[it] != order[it] } if comparable?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def expected
|
|
18
|
+
order[index]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def actual
|
|
22
|
+
names[index]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
attr_reader :names, :order
|
|
27
|
+
|
|
28
|
+
def comparable?
|
|
29
|
+
names.size == order.size && names.tally == order.tally
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
class RuboCop::Callbacksystems::ClassStructure::NodeVisibility
|
|
2
|
+
include RuboCop::Callbacksystems::Helpers
|
|
3
|
+
|
|
4
|
+
def initialize(node)
|
|
5
|
+
@node = node
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def public?
|
|
9
|
+
level == :public
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def level
|
|
13
|
+
level_of_wrapping_modifier || explicitly_assigned_level || default_level
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def enclosing_body
|
|
17
|
+
visibility_owner&.body&.then { it if it.type?(:begin, :kwbegin) }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def enclosing_definition
|
|
21
|
+
node.each_ancestor(:class, :module, :sclass).first
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def level_in(body)
|
|
25
|
+
RuboCop::Callbacksystems::ClassStructure::Visibility.for(body).level_at(node)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def private?
|
|
29
|
+
level == :private
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def protected?
|
|
33
|
+
level == :protected
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def private_non_predicate?
|
|
37
|
+
level != :public && !node.predicate_method?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
attr_reader :node
|
|
42
|
+
|
|
43
|
+
def level_of_wrapping_modifier
|
|
44
|
+
visibility_applied_to(node.parent, node)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def explicitly_assigned_level
|
|
48
|
+
assignment_bodies.filter_map do |body|
|
|
49
|
+
RuboCop::Callbacksystems::ClassStructure::Visibility.for(body).assignment_after \
|
|
50
|
+
node, singleton: node.defs_type? || body.equal?(singleton_owner_body)
|
|
51
|
+
end.max_by(&:position)&.level
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def assignment_bodies
|
|
55
|
+
[ enclosing_body, singleton_owner_body ].compact.uniq(&:object_id)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def singleton_owner_body
|
|
59
|
+
singleton_class&.each_ancestor&.find { visibility_owner?(it) }&.body
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def singleton_class
|
|
63
|
+
@singleton_class ||= visibility_owner if visibility_owner&.sclass_type? &&
|
|
64
|
+
visibility_owner.children.first.self_type?
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def visibility_owner
|
|
68
|
+
@visibility_owner ||= node.each_ancestor.find { visibility_owner?(it) }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def visibility_owner?(candidate)
|
|
72
|
+
candidate.type?(:class, :module, :sclass) || any_block_type?(candidate)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def default_level
|
|
76
|
+
if !node.defs_type? && enclosing_body
|
|
77
|
+
level_in(enclosing_body)
|
|
78
|
+
else
|
|
79
|
+
:public
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|