Class: RuboCop::Cop::Style::RbsInline::MissingDataClassAnnotation
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::Style::RbsInline::MissingDataClassAnnotation
show all
- Extended by:
- AutoCorrector
- Includes:
- RangeHelp, ASTUtils, SourceCodeHelper
- Defined in:
- lib/rubocop/cop/style/rbs_inline/missing_data_class_annotation.rb,
sig/rubocop/cop/style/rbs_inline/missing_data_class_annotation.rbs
Overview
Checks that Data.define attributes have inline type annotations.
Each attribute passed to Data.define should have a trailing #: type
annotation comment on the same line.
Constant Summary
collapse
- MSG =
'Missing inline type annotation for Data attribute (e.g., `#: Type`).'
Instance Method Summary
collapse
#annotation_range, #blank_line?, #char_at, #character_offset, #comment_at, #comment_range, #line_range, #location_to_range, #source_code_at
Methods included from ASTUtils
#end_line, #name_location, #source!, #value_to_sym
Instance Method Details
#add_offenses_for_folded_data_class(node) ⇒ void
This method returns an undefined value.
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
# File 'lib/rubocop/cop/style/rbs_inline/missing_data_class_annotation.rb', line 82
def add_offenses_for_folded_data_class(node) corrected = false
data_attributes(node).each do |arg|
if corrected
add_offense(arg)
else
replacement = build_multiline_replacement(node)
loc = node.loc
if loc.begin && loc.end
add_offense(arg) { _1.replace(loc.begin.join(loc.end), replacement) }
corrected = true
end
end
end
end
|
#annotation_column(node) ⇒ Integer
159
160
161
162
163
164
165
166
167
|
# File 'lib/rubocop/cop/style/rbs_inline/missing_data_class_annotation.rb', line 159
def annotation_column(node) last_arg = node.arguments.last
max_end_col = node.arguments.map do |arg|
comma_length = arg.equal?(last_arg) ? 0 : 1
arg.location.column + source!(arg).length + comma_length
end.max || 0
max_end_col + 2
end
|
#build_multiline_replacement(node) ⇒ String
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
# File 'lib/rubocop/cop/style/rbs_inline/missing_data_class_annotation.rb', line 106
def build_multiline_replacement(node) base_indent = source_code_at(node.location.line)[/\A\s*/]
last_index = node.arguments.size - 1
longest = longest_argname(node)
args_source = node.arguments.each_with_index.map do |arg, i|
comma = i < last_index ? ',' : ''
prefix = "#{base_indent} #{arg.source}#{comma}"
padding = ' ' * (longest.length - source!(arg).length - comma.length + 2)
data_attribute?(arg) ? "#{prefix}#{padding}#: untyped" : prefix
end.join("\n")
"(\n#{args_source}\n#{base_indent})"
end
|
#check_multiline_data_class(node) ⇒ void
This method returns an undefined value.
122
123
124
125
126
127
128
|
# File 'lib/rubocop/cop/style/rbs_inline/missing_data_class_annotation.rb', line 122
def check_multiline_data_class(node) data_attributes(node).each do |arg|
next if inline_type_annotation?(arg.location.line)
add_offense(arg) { |corrector| correct_multiline(corrector, node, arg) }
end
end
|
#correct_multiline(corrector, node, arg) ⇒ void
This method returns an undefined value.
133
134
135
136
137
138
139
140
141
142
|
# File 'lib/rubocop/cop/style/rbs_inline/missing_data_class_annotation.rb', line 133
def correct_multiline(corrector, node, arg) = (arg.location.line)
if
= .text.sub(/\A#\s*/, '')
corrector.replace(.source_range, "#: untyped -- #{}")
else
insert_annotation(corrector, node, arg)
end
end
|
#data_attribute?(arg) ⇒ Boolean
57
58
59
|
# File 'lib/rubocop/cop/style/rbs_inline/missing_data_class_annotation.rb', line 57
def data_attribute?(arg) arg.sym_type? || arg.str_type?
end
|
#data_attributes(node) ⇒ Array[RuboCop::AST::Node]
62
63
64
|
# File 'lib/rubocop/cop/style/rbs_inline/missing_data_class_annotation.rb', line 62
def data_attributes(node) node.arguments.select { data_attribute?(_1) }
end
|
#data_define?(node) ⇒ Boolean
45
46
47
48
49
50
51
52
53
54
|
# File 'lib/rubocop/cop/style/rbs_inline/missing_data_class_annotation.rb', line 45
def data_define?(node) return false unless node.method_name == :define
case (r = node.receiver)
when RuboCop::AST::ConstNode
r.short_name == :Data
else
false
end
end
|
170
171
172
173
|
# File 'lib/rubocop/cop/style/rbs_inline/missing_data_class_annotation.rb', line 170
def (line) = (line)
unless &.text&.match?(/\A#:/)
end
|
#folded_data_class?(node) ⇒ Boolean
73
74
75
76
77
78
79
|
# File 'lib/rubocop/cop/style/rbs_inline/missing_data_class_annotation.rb', line 73
def folded_data_class?(node) attrs = data_attributes(node)
return false if attrs.empty?
lines = attrs.map { _1.location.line }
lines.uniq.length < attrs.length || lines.include?(node.location.line)
end
|
#inline_type_annotation?(line) ⇒ boolish
67
68
69
70
|
# File 'lib/rubocop/cop/style/rbs_inline/missing_data_class_annotation.rb', line 67
def inline_type_annotation?(line) = (line)
&.text&.match?(/\A#:/)
end
|
#insert_annotation(corrector, node, arg) ⇒ void
This method returns an undefined value.
147
148
149
150
151
152
153
154
155
156
|
# File 'lib/rubocop/cop/style/rbs_inline/missing_data_class_annotation.rb', line 147
def insert_annotation(corrector, node, arg) line = arg.location.line
line_source = source_code_at(line)
content_end_col = line_source.rstrip.length
padding = [annotation_column(node) - content_end_col, 1].max || raise
line_begin = processed_source.buffer.line_range(line).begin_pos
insert_pos = line_begin + content_end_col
corrector.insert_before(range_between(insert_pos, insert_pos), "#{' ' * padding}#: untyped")
end
|
#longest_argname(node) ⇒ String
99
100
101
102
103
|
# File 'lib/rubocop/cop/style/rbs_inline/missing_data_class_annotation.rb', line 99
def longest_argname(node) last_index = node.arguments.size - 1
args = node.arguments.each_with_index.map { |a, i| i < last_index ? "#{a.source}," : a.source.to_s }
args.max_by(&:length) || ''
end
|
#on_send(node) ⇒ void
This method returns an undefined value.
32
33
34
35
36
37
38
39
40
|
# File 'lib/rubocop/cop/style/rbs_inline/missing_data_class_annotation.rb', line 32
def on_send(node) return unless data_define?(node)
if folded_data_class?(node)
add_offenses_for_folded_data_class(node)
else
check_multiline_data_class(node)
end
end
|