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
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
class RuboCop::Callbacksystems::Methods::Definitions
|
|
2
|
+
include Enumerable
|
|
3
|
+
include RuboCop::Callbacksystems::Helpers
|
|
4
|
+
|
|
5
|
+
delegate :each, to: :definitions
|
|
6
|
+
|
|
7
|
+
def initialize(ast)
|
|
8
|
+
@ast = ast
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
Definition = Data.define(:node, :name)
|
|
13
|
+
|
|
14
|
+
attr_reader :ast
|
|
15
|
+
|
|
16
|
+
def definitions
|
|
17
|
+
bodies = top_level_definitions_in(ast).map { Body.new(it.body, depth: 0, context: :owner) }
|
|
18
|
+
|
|
19
|
+
Traversal.new(bodies).to_a
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Definition-bearing body and statement entries walked depth first without recursive object calls.
|
|
23
|
+
class Traversal
|
|
24
|
+
include Enumerable
|
|
25
|
+
|
|
26
|
+
def initialize(entries)
|
|
27
|
+
@entries = entries
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def each
|
|
31
|
+
if block_given?
|
|
32
|
+
pending = entries.reverse
|
|
33
|
+
until pending.empty?
|
|
34
|
+
entry = pending.pop
|
|
35
|
+
entry.definitions.each { yield it }
|
|
36
|
+
pending.concat(entry.children.reverse)
|
|
37
|
+
end
|
|
38
|
+
else
|
|
39
|
+
to_enum(__method__)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
attr_reader :entries
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
class Body
|
|
48
|
+
include RuboCop::Callbacksystems::Helpers
|
|
49
|
+
|
|
50
|
+
def initialize(node, depth:, context:, singleton_owner_body: nil)
|
|
51
|
+
@node = node
|
|
52
|
+
@depth = depth
|
|
53
|
+
@context = context
|
|
54
|
+
@singleton_owner_body = singleton_owner_body
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def definitions
|
|
58
|
+
[]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def children
|
|
62
|
+
statements_in(node).map { Statement.new(it, body: self) }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def public_definition?(definition)
|
|
66
|
+
DefinitionVisibility.new(definition, node, singleton_owner_body:).public?
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def target_definition?(definition)
|
|
70
|
+
depth_of(definition) <= 1
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def target_scope?
|
|
74
|
+
depth.zero?
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def body_within_singleton_section(child)
|
|
78
|
+
if depth.zero?
|
|
79
|
+
self.class.new(child, depth: 1, context: :singleton, singleton_owner_body: node)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def body_within_definition_block(child, kind:)
|
|
84
|
+
unless context == :singleton
|
|
85
|
+
self.class.new(child, depth: kind == :class_methods ? 1 : 0, context: :definition_block)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
attr_reader :node, :depth, :context, :singleton_owner_body
|
|
91
|
+
|
|
92
|
+
def depth_of(definition)
|
|
93
|
+
depth + (definition.defs_type? ? 1 : 0)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
class DefinitionVisibility
|
|
97
|
+
include RuboCop::Callbacksystems::Helpers
|
|
98
|
+
|
|
99
|
+
def initialize(definition, body, singleton_owner_body:)
|
|
100
|
+
@definition = definition
|
|
101
|
+
@body = body
|
|
102
|
+
@singleton_owner_body = singleton_owner_body
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def public?
|
|
106
|
+
level == :public
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
private
|
|
110
|
+
attr_reader :definition, :body, :singleton_owner_body
|
|
111
|
+
|
|
112
|
+
def level
|
|
113
|
+
if definition.location
|
|
114
|
+
assigned_level || visibility_applied_to(definition.parent, definition) || default_level
|
|
115
|
+
else
|
|
116
|
+
:public
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def assigned_level
|
|
121
|
+
assignments.max_by(&:position)&.level
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def assignments
|
|
125
|
+
[
|
|
126
|
+
visibility.assignment_after(definition, singleton: definition.defs_type?),
|
|
127
|
+
singleton_owner_visibility&.assignment_after(definition, singleton: true)
|
|
128
|
+
].compact
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def visibility
|
|
132
|
+
@visibility ||= RuboCop::Callbacksystems::ClassStructure::Visibility.for(body)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def singleton_owner_visibility
|
|
136
|
+
if singleton_owner_body
|
|
137
|
+
RuboCop::Callbacksystems::ClassStructure::Visibility.for(singleton_owner_body)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def default_level
|
|
142
|
+
definition.defs_type? ? :public : visibility.level_at(definition)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
class Statement
|
|
148
|
+
include RuboCop::Callbacksystems::Helpers
|
|
149
|
+
|
|
150
|
+
DEFINITION_BLOCKS = %i[ class_methods included prepended ].to_set
|
|
151
|
+
|
|
152
|
+
def initialize(node, body:)
|
|
153
|
+
@node = node
|
|
154
|
+
@body = body
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def definitions
|
|
158
|
+
explicit_definitions + scope_entry
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def children
|
|
162
|
+
if singleton_section?(node)
|
|
163
|
+
singleton_body.then { [ it ].compact }
|
|
164
|
+
elsif known_definition_block?
|
|
165
|
+
definition_block_body.then { [ it ].compact }
|
|
166
|
+
else
|
|
167
|
+
[]
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
private
|
|
172
|
+
attr_reader :node, :body
|
|
173
|
+
|
|
174
|
+
def explicit_definitions
|
|
175
|
+
method_definitions.filter_map do |definition|
|
|
176
|
+
if owned_definition?(definition) && body.public_definition?(definition)
|
|
177
|
+
Definition.new(definition, definition.method_name)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def method_definitions
|
|
183
|
+
if node.any_def_type?
|
|
184
|
+
[ node ]
|
|
185
|
+
elsif node.call_type?
|
|
186
|
+
node.arguments.select(&:any_def_type?)
|
|
187
|
+
else
|
|
188
|
+
[]
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def owned_definition?(definition)
|
|
193
|
+
body.target_definition?(definition) && (!definition.defs_type? || definition.receiver.self_type?)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def scope_entry
|
|
197
|
+
call = call_of(node)
|
|
198
|
+
|
|
199
|
+
if body.target_scope? && scope_definition?(call)
|
|
200
|
+
[ Definition.new(call, call.first_argument.value) ]
|
|
201
|
+
else
|
|
202
|
+
[]
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def singleton_body
|
|
207
|
+
body.body_within_singleton_section(node.body)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def known_definition_block?
|
|
211
|
+
any_block_type?(node) && call_on_self?(call_of(node)) && DEFINITION_BLOCKS.include?(node.method_name)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def definition_block_body
|
|
215
|
+
body.body_within_definition_block(node.body, kind: node.method_name)
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
class RuboCop::Callbacksystems::Methods::DelegateMacro
|
|
2
|
+
include RuboCop::Callbacksystems::Helpers
|
|
3
|
+
|
|
4
|
+
MISSING_DELEGATE_METHODS = %i[ method_missing respond_to_missing? ]
|
|
5
|
+
|
|
6
|
+
def initialize(node)
|
|
7
|
+
@node = node
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def macro?
|
|
11
|
+
delegate_macro?(node) && !options.nil?
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def target
|
|
15
|
+
value_of(:to)&.then { name_of(it) }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# The methods read on the delegation target, before a prefix changes the methods this macro defines.
|
|
19
|
+
def target_method_names
|
|
20
|
+
literal_method_names if node.method?(:delegate)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Nothing is returned when a dynamic argument or option leaves the names unknowable without executing the file.
|
|
24
|
+
def defined_method_names
|
|
25
|
+
if node.method?(:delegate_missing_to)
|
|
26
|
+
MISSING_DELEGATE_METHODS
|
|
27
|
+
elsif node.method?(:delegate)
|
|
28
|
+
prefixed_method_names
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def private?
|
|
33
|
+
visibility == :private
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def plain?(private:)
|
|
37
|
+
visibility == (private ? :private : :public) && inactive_option?(:prefix) && inactive_option?(:allow_nil)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def private_option_known?
|
|
41
|
+
options && option_known?(:private)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def private_option
|
|
45
|
+
option_for(:private)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def first_option
|
|
49
|
+
keyword_options.elements.first || options
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def last_option
|
|
53
|
+
keyword_options.elements.last || options
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
attr_reader :node
|
|
58
|
+
|
|
59
|
+
def options
|
|
60
|
+
node.last_argument if node.last_argument&.hash_type?
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def value_of(key)
|
|
64
|
+
option_for(key)&.value
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def option_for(key)
|
|
68
|
+
keyword_options.option_for(key) if options
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def keyword_options
|
|
72
|
+
@keyword_options ||= RuboCop::Callbacksystems::Hashes::KeywordOptions.new(options)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def name_of(value)
|
|
76
|
+
literal_name_of(value) if value.type?(:sym, :str, :const)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def literal_method_names
|
|
80
|
+
method_arguments.filter_map { literal_method_name_of(it) }.then do |names|
|
|
81
|
+
names if names.size == method_arguments.size
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def method_arguments
|
|
86
|
+
@method_arguments ||= node.arguments.reject { it.equal?(options) }
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def literal_method_name_of(argument)
|
|
90
|
+
argument.value.to_sym if argument.type?(:sym, :str)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def prefixed_method_names
|
|
94
|
+
if target_method_names && option_known?(:prefix)
|
|
95
|
+
prefix = prefix_name
|
|
96
|
+
|
|
97
|
+
if prefix || !prefix_active?
|
|
98
|
+
target_method_names.map { prefix ? :"#{prefix}_#{it}" : it }
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def option_known?(key)
|
|
104
|
+
options.nil? || keyword_options.known?(key)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def prefix_name
|
|
108
|
+
value = value_of(:prefix)
|
|
109
|
+
|
|
110
|
+
if value&.true_type?
|
|
111
|
+
target if target&.match?(/\A[a-z_]/)
|
|
112
|
+
elsif value&.type?(:sym, :str)
|
|
113
|
+
value.value.to_s
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def prefix_active?
|
|
118
|
+
value = value_of(:prefix)
|
|
119
|
+
|
|
120
|
+
value && !value.falsey_literal?
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def visibility
|
|
124
|
+
if private_option
|
|
125
|
+
literal_visibility
|
|
126
|
+
elsif options && keyword_options.known?(:private)
|
|
127
|
+
:public
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def literal_visibility
|
|
132
|
+
if private_option.value.true_type?
|
|
133
|
+
:private
|
|
134
|
+
elsif private_option.value.falsey_literal?
|
|
135
|
+
:public
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def inactive_option?(key)
|
|
140
|
+
option = option_for(key)
|
|
141
|
+
|
|
142
|
+
option ? option.value.falsey_literal? : options && keyword_options.known?(key)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# The receiver of a hand-written delegation, read as the target a `delegate` macro would name. A constant stands for
|
|
2
|
+
# itself (`to: Currency`), a call on self becomes a symbol (`to: :registry`), and a chain of them becomes a dotted
|
|
3
|
+
# string (`to: "config.postgres"`). Anything else in the chain gives up the whole reading.
|
|
4
|
+
class RuboCop::Callbacksystems::Methods::DelegationTarget
|
|
5
|
+
def initialize(receiver)
|
|
6
|
+
@receiver = receiver
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def delegable?
|
|
10
|
+
constant? || chain_names.any?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def source
|
|
14
|
+
constant? ? name : quoted_name
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def name
|
|
18
|
+
constant? ? receiver.source : chain_names.join(".")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def nested?
|
|
22
|
+
chain_names.many?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
attr_reader :receiver
|
|
27
|
+
|
|
28
|
+
def constant?
|
|
29
|
+
receiver&.const_type? || false
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def chain_names
|
|
33
|
+
@chain_names ||= names_in(receiver) || []
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def names_in(node)
|
|
37
|
+
names = []
|
|
38
|
+
current = node
|
|
39
|
+
|
|
40
|
+
while chained_call?(current)
|
|
41
|
+
names << current.method_name
|
|
42
|
+
current = current.receiver
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
names.reverse if current.nil? || current.self_type?
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def chained_call?(node)
|
|
49
|
+
node&.send_type? && node.arguments.empty?
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def quoted_name
|
|
53
|
+
nested? ? "\"#{name}\"" : ":#{name}"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# The class or module and instance/singleton side where a method definition or receiverless call resolves.
|
|
2
|
+
class RuboCop::Callbacksystems::Methods::Domain
|
|
3
|
+
include RuboCop::Callbacksystems::Helpers
|
|
4
|
+
|
|
5
|
+
def initialize(node)
|
|
6
|
+
@node = node
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def container
|
|
10
|
+
@container ||= domain_node.each_ancestor.find { method_owner_boundary?(it) }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def scope
|
|
14
|
+
singleton? ? :singleton : :instance
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def singleton?
|
|
18
|
+
singleton_depth.positive?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def singleton_depth
|
|
22
|
+
identity.size
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def identity
|
|
26
|
+
@identity ||= singleton_path.freeze
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
attr_reader :node
|
|
31
|
+
|
|
32
|
+
def domain_node
|
|
33
|
+
method_node || node
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def method_node
|
|
37
|
+
node.any_def_type? ? node : enclosing_method_of(node)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# A block around a definition may establish its receiver only when it runs (`Class.new`, `included`, `class_eval`,
|
|
41
|
+
# and user macros). Treat it as an opaque owner rather than attributing the definition to the named outer class.
|
|
42
|
+
def method_owner_boundary?(candidate)
|
|
43
|
+
candidate.type?(:class, :module) || any_block_type?(candidate)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def singleton_path
|
|
47
|
+
lexical_singleton_classes.reverse_each.map { singleton_class_identity(it) }.tap do |path|
|
|
48
|
+
path << explicit_singleton_identity if explicit_singleton?
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def lexical_singleton_classes
|
|
53
|
+
domain_node.each_ancestor(:sclass, :class, :module).take_while { !it.type?(:class, :module) }.to_a
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def singleton_class_identity(singleton_class)
|
|
57
|
+
singleton_class.children.first.self_type? ? :self : [ :expression, singleton_class.source_range.begin_pos ]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def explicit_singleton?
|
|
61
|
+
if method_node
|
|
62
|
+
method_node.defs_type?
|
|
63
|
+
else
|
|
64
|
+
!container.nil?
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# A definition on some other object does not belong to the container's class side. Its own body still shares this
|
|
69
|
+
# identity with the receiverless calls it holds, while definitions on unrelated expressions remain separate.
|
|
70
|
+
def explicit_singleton_identity
|
|
71
|
+
if method_node&.defs_type? && !method_node.receiver.self_type?
|
|
72
|
+
[ :expression, method_node.receiver.source_range.begin_pos ]
|
|
73
|
+
else
|
|
74
|
+
:self
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module RuboCop::Callbacksystems::Methods::ImplicitInvocations
|
|
2
|
+
# These hooks supplement the smaller runtime set shipped by RuboCop 1.89.
|
|
3
|
+
RUNTIME_METHODS = %i[
|
|
4
|
+
coerce instance_variables_to_inspect
|
|
5
|
+
inherited included extended prepended
|
|
6
|
+
append_features extend_object prepend_features
|
|
7
|
+
const_missing const_added
|
|
8
|
+
method_added method_removed method_undefined
|
|
9
|
+
singleton_method_added singleton_method_removed singleton_method_undefined
|
|
10
|
+
].to_set | RuboCop::Cop::Lint::UnusedPrivateMethod::IMPLICITLY_INVOKED_METHODS
|
|
11
|
+
PROTOCOL_METHODS = %i[
|
|
12
|
+
initialize to_hash to_h to_str to_s to_ary to_a to_proc to_int to_i to_path
|
|
13
|
+
== eql? hash <=> === each call inspect as_json to_json
|
|
14
|
+
deconstruct deconstruct_keys encode_with init_with yaml_initialize
|
|
15
|
+
].to_set
|
|
16
|
+
METHOD_NAMES = RUNTIME_METHODS | PROTOCOL_METHODS
|
|
17
|
+
end
|