Class: RuboCop::Cop::Style::RbsInline::RequireRbsInlineComment

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Includes:
RangeHelp, ModeConfig
Defined in:
lib/rubocop/cop/style/rbs_inline/require_rbs_inline_comment.rb,
sig/rubocop/cop/style/rbs_inline/require_rbs_inline_comment.rbs

Overview

Checks for the presence or absence of # rbs_inline: magic comment.

RBS::Inline supports two modes: opt-in (requires # rbs_inline: enabled) and opt-out (processes all files by default). This cop enforces consistency in which mode your codebase uses.

Examples:

Mode: opt_in

# bad
# (no rbs_inline comment)
class Foo
end

# good
# rbs_inline: enabled
class Foo
end

# good
# rbs_inline: disabled
class Foo
end

Mode: opt_in, AllowMissingComment: true

# good - the cop does not enforce the magic comment
class Foo
end

# good
# rbs_inline: enabled
class Foo
end

Mode: opt_out

# bad
# rbs_inline: enabled
class Foo
end

# good
# rbs_inline: disabled
class Foo
end

# good
# (no rbs_inline comment)
class Foo
end

Constant Summary collapse

MSG_MISSING =

Returns:

  • (::String)
"Missing `# rbs_inline:` magic comment."
MSG_FORBIDDEN =

Returns:

  • (::String)
"Remove `# rbs_inline:` magic comment."

Constants included from ModeConfig

ModeConfig::SUPPORTED_MODES

Instance Method Summary collapse

Methods included from ModeConfig

#configured_mode, #validate_config

Instance Method Details

#allow_missing_comment?Boolean

Signature:

  • bool

Returns:

  • (Boolean)


144
145
146
# File 'lib/rubocop/cop/style/rbs_inline/require_rbs_inline_comment.rb', line 144

def allow_missing_comment? #: bool
  cop_config["AllowMissingComment"] == true
end

#check_opt_in(magic_comment) ⇒ void

This method returns an undefined value.

RBS:

  • magic_comment: Parser::Source::Comment?

Parameters:



89
90
91
92
93
94
95
96
97
98
# File 'lib/rubocop/cop/style/rbs_inline/require_rbs_inline_comment.rb', line 89

def check_opt_in(magic_comment) #: void
  return if magic_comment
  return if allow_missing_comment?

  insert_position = find_insert_position
  add_offense(first_line_range, message: MSG_MISSING) do |corrector|
    insert_range = Parser::Source::Range.new(processed_source.buffer, insert_position, insert_position)
    corrector.insert_before(insert_range, insertion_text(insert_position))
  end
end

#check_opt_out(magic_comment) ⇒ void

This method returns an undefined value.

RBS:

  • magic_comment: Parser::Source::Comment?

Parameters:



101
102
103
104
105
106
107
108
# File 'lib/rubocop/cop/style/rbs_inline/require_rbs_inline_comment.rb', line 101

def check_opt_out(magic_comment) #: void
  return unless magic_comment

  add_offense(magic_comment.source_range, message: MSG_FORBIDDEN) do |corrector|
    range = range_with_surrounding_space(magic_comment.source_range, side: :right, newlines: true)
    corrector.remove(range)
  end
end

#disabled?(magic_comment) ⇒ Boolean

RBS:

  • magic_comment: Parser::Source::Comment?

Parameters:

Returns:

  • (Boolean)


84
85
86
# File 'lib/rubocop/cop/style/rbs_inline/require_rbs_inline_comment.rb', line 84

def disabled?(magic_comment) #: bool
  magic_comment&.text&.match?(/\A# rbs_inline: disabled\R?\z/) || false
end

#find_insert_positionInteger

Signature:

  • Integer

Returns:

  • (Integer)


110
111
112
113
114
115
116
117
118
# File 'lib/rubocop/cop/style/rbs_inline/require_rbs_inline_comment.rb', line 110

def find_insert_position #: Integer
  first_comment = processed_source.comments.first
  return 0 unless first_comment&.source_range&.first_line == 1

  last_comment_in_block = find_last_comment_in_first_block
  # `end_pos` points at the newline terminating the comment, so `+ 1` moves past it.
  # A file without a trailing newline has none, so clamp to the end of the buffer.
  (last_comment_in_block.source_range.end_pos + 1).clamp(0, processed_source.buffer.source.length)
end

#find_last_comment_in_first_blockParser::Source::Comment

Signature:

  • Parser::Source::Comment

Returns:



130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/rubocop/cop/style/rbs_inline/require_rbs_inline_comment.rb', line 130

def find_last_comment_in_first_block #: Parser::Source::Comment
  comments = processed_source.comments
  last_idx = 0

  comments.each_cons(2).with_index do |pair, idx|
    current, following = pair #: [Parser::Source::Comment, Parser::Source::Comment]
    break unless current.source_range.last_line + 1 == following.source_range.first_line

    last_idx = idx + 1
  end

  comments[last_idx] || raise
end

#find_rbs_inline_magic_commentParser::Source::Comment?

Signature:

  • Parser::Source::Comment?

Returns:



77
78
79
80
81
# File 'lib/rubocop/cop/style/rbs_inline/require_rbs_inline_comment.rb', line 77

def find_rbs_inline_magic_comment #: Parser::Source::Comment?
  processed_source.comments.find do |comment|
    comment.text.match?(/\A# rbs_inline: (enabled|disabled)\R?\z/)
  end
end

#first_line_rangeParser::Source::Range

Signature:

  • Parser::Source::Range

Returns:

  • (Parser::Source::Range)


148
149
150
151
# File 'lib/rubocop/cop/style/rbs_inline/require_rbs_inline_comment.rb', line 148

def first_line_range #: Parser::Source::Range
  first_line = processed_source.ast&.source_range&.first_line || 1
  processed_source.buffer.line_range(first_line)
end

#insertion_text(insert_position) ⇒ String

The insert position lands at the end of the buffer when the file has no trailing newline. The magic comment then needs its own newline to stay on a separate line.

RBS:

  • insert_position: Integer

Parameters:

  • insert_position (Integer)

Returns:

  • (String)


123
124
125
126
127
128
# File 'lib/rubocop/cop/style/rbs_inline/require_rbs_inline_comment.rb', line 123

def insertion_text(insert_position) #: String
  source = processed_source.buffer.source
  return "# rbs_inline: enabled\n" if insert_position.zero? || source[insert_position - 1] == "\n"

  "\n# rbs_inline: enabled\n"
end

#on_new_investigationvoid

This method returns an undefined value.

Signature:

  • void



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/rubocop/cop/style/rbs_inline/require_rbs_inline_comment.rb', line 63

def on_new_investigation #: void
  return if processed_source.buffer.source.empty?

  magic_comment = find_rbs_inline_magic_comment
  return if disabled?(magic_comment)

  case configured_mode
  when :opt_in then check_opt_in(magic_comment)
  when :opt_out then check_opt_out(magic_comment)
  end
end