Module: RuboCop::Cop::Style::RbsInline::DataStructHelper

Includes:
RangeHelp, ASTUtils, SourceCodeHelper
Included in:
ClassCommentAlignment, MissingClassAnnotation
Defined in:
lib/rubocop/cop/style/rbs_inline/data_struct_helper.rb,
sig/rubocop/cop/style/rbs_inline/data_struct_helper.rbs

Overview

Shared logic for cops that check inline type annotations on struct-like class definitions such as Data.define and Struct.new.

Including cops decide which nodes to check by defining their own matcher (e.g. struct_like_class?); this module only provides helpers that operate on an already-matched definition node. Cops may override #attr_argument? when the set of attribute arguments differs from the default (e.g. Struct.new treats a leading string argument as the struct name rather than an attribute).

Instance Method Summary collapse

Methods included from SourceCodeHelper

#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

#annotation_column(node) ⇒ Integer

Parameters:

  • node (RuboCop::AST::SendNode)

Returns:

  • (Integer)


61
62
63
64
65
66
67
68
69
# File 'lib/rubocop/cop/style/rbs_inline/data_struct_helper.rb', line 61

def annotation_column(node) #: Integer
  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

#attr_argument?(arg) ⇒ Boolean

Parameters:

  • arg (RuboCop::AST::Node)

Returns:

  • (Boolean)


24
25
26
# File 'lib/rubocop/cop/style/rbs_inline/data_struct_helper.rb', line 24

def attr_argument?(arg) #: bool
  arg.sym_type? || arg.str_type?
end

#attr_arguments(node) ⇒ Array[RuboCop::AST::Node]

Parameters:

  • node (RuboCop::AST::SendNode)

Returns:

  • (Array[RuboCop::AST::Node])


29
30
31
# File 'lib/rubocop/cop/style/rbs_inline/data_struct_helper.rb', line 29

def attr_arguments(node) #: Array[RuboCop::AST::Node]
  node.arguments.select { attr_argument?(_1) }
end

#build_multiline_replacement(node) ⇒ String

Parameters:

  • node (RuboCop::AST::SendNode)

Returns:

  • (String)


79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/rubocop/cop/style/rbs_inline/data_struct_helper.rb', line 79

def build_multiline_replacement(node) #: String # rubocop:disable Metrics/AbcSize
  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)
    attr_argument?(arg) ? "#{prefix}#{padding}#: untyped" : prefix
  end.join("\n")

  "(\n#{args_source}\n#{base_indent})"
end

#find_regular_comment(line) ⇒ Parser::Source::Comment?

Parameters:

  • line (Integer)

Returns:



55
56
57
58
# File 'lib/rubocop/cop/style/rbs_inline/data_struct_helper.rb', line 55

def find_regular_comment(line) #: Parser::Source::Comment?
  comment = comment_at(line)
  comment unless comment&.text&.match?(/\A#:/)
end

#folded?(node) ⇒ Boolean

Parameters:

  • node (RuboCop::AST::SendNode)

Returns:

  • (Boolean)


34
35
36
37
38
39
40
# File 'lib/rubocop/cop/style/rbs_inline/data_struct_helper.rb', line 34

def folded?(node) #: bool
  attrs = attr_arguments(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

Parameters:

  • line (Integer)

Returns:

  • (boolish)


43
44
45
46
# File 'lib/rubocop/cop/style/rbs_inline/data_struct_helper.rb', line 43

def inline_type_annotation?(line) #: boolish
  comment = comment_at(line)
  comment&.text&.match?(/\A#:/)
end

#inline_type_comment(line) ⇒ Parser::Source::Comment?

Parameters:

  • line (Integer)

Returns:



49
50
51
52
# File 'lib/rubocop/cop/style/rbs_inline/data_struct_helper.rb', line 49

def inline_type_comment(line) #: Parser::Source::Comment?
  comment = comment_at(line)
  comment if comment&.text&.match?(/\A#:/)
end

#longest_argname(node) ⇒ String

Parameters:

  • node (RuboCop::AST::SendNode)

Returns:

  • (String)


72
73
74
75
76
# File 'lib/rubocop/cop/style/rbs_inline/data_struct_helper.rb', line 72

def longest_argname(node) #: String
  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