/
endless_method.rb
101 lines (89 loc) · 2.83 KB
/
endless_method.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# frozen_string_literal: true
module RuboCop
module Cop
module Style
# Checks for endless methods.
#
# It can enforce either the use of endless methods definitions
# for single-lined method bodies, or disallow endless methods.
#
# Other method definition types are not considered by this cop.
#
# The supported styles are:
#
# * allow_single_line (default) - only single line endless method definitions are allowed.
# * allow_always - all endless method definitions are allowed.
# * disallow - all endless method definitions are disallowed.
#
# NOTE: Incorrect endless method definitions will always be
# corrected to a multi-line definition.
#
# @example EnforcedStyle: allow_single_line (default)
# # good
# def my_method() = x
#
# # bad, multi-line endless method
# def my_method() = x.foo
# .bar
# .baz
#
# @example EnforcedStyle: allow_always
# # good
# def my_method() = x
#
# # good
# def my_method() = x.foo
# .bar
# .baz
#
# @example EnforcedStyle: disallow
# # bad
# def my_method() = x
#
# # bad
# def my_method() = x.foo
# .bar
# .baz
#
class EndlessMethod < Base
include ConfigurableEnforcedStyle
extend TargetRubyVersion
extend AutoCorrector
minimum_target_ruby_version 3.0
CORRECTION_STYLES = %w[multiline single_line].freeze
MSG = 'Avoid endless method definitions.'
MSG_MULTI_LINE = 'Avoid endless method definitions with multiple lines.'
def on_def(node)
if style == :disallow
handle_disallow_style(node)
else
handle_allow_style(node)
end
end
private
def handle_allow_style(node)
return unless node.endless?
return if node.single_line? || style == :allow_always
add_offense(node, message: MSG_MULTI_LINE) do |corrector|
correct_to_multiline(corrector, node)
end
end
def handle_disallow_style(node)
return unless node.endless?
add_offense(node) { |corrector| correct_to_multiline(corrector, node) }
end
def correct_to_multiline(corrector, node)
replacement = <<~RUBY.strip
def #{node.method_name}#{arguments(node)}
#{node.body.source}
end
RUBY
corrector.replace(node, replacement)
end
def arguments(node, missing = '')
node.arguments.any? ? node.arguments.source : missing
end
end
end
end
end