rubocop-fourshark 0.7.1 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/lib/rubocop/cop/style/disallow_delegate.rb +56 -12
- data/lib/rubocop/fourshark/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 31d77a73abb724b68a4c2d187cc780899067d2ef82564e50bcce0d6b09dbffeb
|
|
4
|
+
data.tar.gz: fd2eda214bf001b848e18be1f68df32463d70272be3f7ce999ac7cb3b1be8f8f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 61aabc197c8224de85d39c9f150cb0fb1b73916a8882fd35cb3241b4b5ca330eb44f4098a12eff4fc934b918ea2ccf75a81bd150c1eac96193678ef620ae734c
|
|
7
|
+
data.tar.gz: b0b7426b78afa3a99f028eb84b4dd78479c153d219997d55611e7e1ab3544ddfe99ead0b323306c24220c9806715ddf413b1ace76bdb19df8ccad9bb43391562
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [0.8.1] - 2026-08-06
|
|
2
|
+
|
|
3
|
+
### Fixed
|
|
4
|
+
|
|
5
|
+
- `Style/DisallowDelegate` — a method answering about its own class is no longer flagged
|
|
6
|
+
|
|
7
|
+
## [0.8.0] - 2026-08-05
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- `Style/DisallowDelegate` — a method that forwards its own name to a collaborator is flagged
|
|
12
|
+
|
|
1
13
|
## [0.7.1] - 2026-08-05
|
|
2
14
|
|
|
3
15
|
### Removed
|
|
@@ -5,31 +5,75 @@ require 'rubocop'
|
|
|
5
5
|
module RuboCop
|
|
6
6
|
module Cop
|
|
7
7
|
module Style
|
|
8
|
-
# Forbids
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
8
|
+
# Forbids delegation — a class answering a question that belongs to a
|
|
9
|
+
# collaborator. The community name for the smell is Fowler's Middle Man,
|
|
10
|
+
# and the prescribed refactoring is Remove Middle Man: delete the
|
|
11
|
+
# forwarder and let the caller navigate to the object that knows.
|
|
12
|
+
#
|
|
13
|
+
# Two shapes are flagged. The macro family (`delegate`,
|
|
14
|
+
# `delegate_missing_to`, `def_delegator`/`def_delegators`,
|
|
15
|
+
# `DelegateClass`) and an instance method whose entire body forwards the
|
|
16
|
+
# same message to a collaborator. The second is the same defect: writing
|
|
17
|
+
# the forwarder by hand changes what `grep` finds, not what the class
|
|
18
|
+
# claims to be responsible for.
|
|
19
|
+
#
|
|
20
|
+
# `self.class` is not a collaborator — it is the object's own class. An
|
|
21
|
+
# instance method that composes its own attributes into a same-named class
|
|
22
|
+
# method answers for a domain it owns, so it is not delegation and is not
|
|
23
|
+
# flagged.
|
|
14
24
|
#
|
|
15
25
|
# @example
|
|
16
26
|
# # bad
|
|
17
|
-
# delegate :
|
|
27
|
+
# delegate :name, to: :commission
|
|
28
|
+
#
|
|
29
|
+
# # bad — same promise, written by hand
|
|
30
|
+
# def name
|
|
31
|
+
# commission.name
|
|
32
|
+
# end
|
|
18
33
|
#
|
|
19
|
-
# # good
|
|
20
|
-
#
|
|
21
|
-
#
|
|
34
|
+
# # good — the caller navigates
|
|
35
|
+
# statement.commission.name
|
|
36
|
+
#
|
|
37
|
+
# # good — the object answers about itself, not for a collaborator
|
|
38
|
+
# def lock_key
|
|
39
|
+
# self.class.lock_key(company_id: company_id)
|
|
22
40
|
# end
|
|
23
41
|
#
|
|
24
42
|
class DisallowDelegate < ::RuboCop::Cop::Base
|
|
25
|
-
|
|
43
|
+
MACRO_MSG = 'Do not use automatic delegation. Delete the forwarder and let the caller navigate.'
|
|
44
|
+
FORWARDER_MSG = 'Do not forward a collaborator\'s message. Delete the forwarder and let the caller navigate.'
|
|
26
45
|
|
|
27
46
|
RESTRICT_ON_SEND = %i[delegate delegate_missing_to def_delegator def_delegators DelegateClass].freeze
|
|
28
47
|
|
|
29
48
|
def on_send(node)
|
|
30
49
|
return unless node.receiver.nil?
|
|
31
50
|
|
|
32
|
-
add_offense(node)
|
|
51
|
+
add_offense(node, message: MACRO_MSG)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def on_def(node)
|
|
55
|
+
return unless forwards_own_message?(node.body, node.method_name)
|
|
56
|
+
|
|
57
|
+
add_offense(node.loc.name, message: FORWARDER_MSG)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
def forwards_own_message?(body, method_name)
|
|
63
|
+
return false if body.nil?
|
|
64
|
+
return false unless body.send_type?
|
|
65
|
+
return false if body.receiver.nil?
|
|
66
|
+
return false if own_class?(body.receiver)
|
|
67
|
+
|
|
68
|
+
body.method?(method_name)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def own_class?(receiver)
|
|
72
|
+
return false unless receiver.send_type?
|
|
73
|
+
return false unless receiver.method?(:class)
|
|
74
|
+
return false if receiver.receiver.nil?
|
|
75
|
+
|
|
76
|
+
receiver.receiver.self_type?
|
|
33
77
|
end
|
|
34
78
|
end
|
|
35
79
|
end
|