forked from rubocop/rubocop
/
struct_inheritance.rb
60 lines (51 loc) · 1.58 KB
/
struct_inheritance.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
# frozen_string_literal: true
module RuboCop
module Cop
module Style
# This cop checks for inheritance from Struct.new.
#
# @example
# # bad
# class Person < Struct.new(:first_name, :last_name)
# def age
# 42
# end
# end
#
# # good
# Person = Struct.new(:first_name, :last_name) do
# def age
# 42
# end
# end
class StructInheritance < Cop
include RangeHelp
MSG = "Don't extend an instance initialized by `Struct.new`. " \
'Use a block to customize the struct.'
def on_class(node)
return unless struct_constructor?(node.parent_class)
add_offense(node, location: node.parent_class.source_range)
end
def autocorrect(node)
lambda do |corrector|
corrector.remove(range_with_surrounding_space(range: node.loc.keyword))
corrector.replace(node.loc.operator, '=')
correct_parent(node.parent_class, corrector)
end
end
def_node_matcher :struct_constructor?, <<~PATTERN
{(send (const nil? :Struct) :new ...)
(block (send (const nil? :Struct) :new ...) ...)}
PATTERN
private
def correct_parent(parent, corrector)
if parent.block_type?
corrector.remove(range_with_surrounding_space(range: parent.loc.end, newlines: false))
else
corrector.insert_after(parent.loc.expression, ' do')
end
end
end
end
end
end