123456789_123456789_123456789_123456789_123456789_

Class: RuboCop::Cop::Offense

Relationships & Source Files
Namespace Children
Classes:
Super Chains via Extension / Inclusion / Inheritance
Instance Chain:
self, Comparable
Inherits: Object
Defined in: lib/rubocop/cop/offense.rb

Overview

An offense represents a style violation detected by RuboCop.

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(severity, location, message, cop_name, status = :uncorrected, corrector = nil, justification: nil, corrections: nil, correction_safe: true) ⇒ Offense

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 136

def initialize(severity, location, message, cop_name, # rubocop:disable Metrics/ParameterLists
               status = :uncorrected, corrector = nil, justification: nil,
               corrections: nil, correction_safe: true)
  @severity = RuboCop::Cop::Severity.new(severity)
  @location = location

  # Pre-compute the position eagerly because the offense is frozen and
  # `location.line` / `location.column` are expensive to compute; sorting
  # many offenses calls them repeatedly through `#<=>`.
  @line = location.line
  @column = location.column
  @message = message.freeze
  @cop_name = cop_name.freeze
  @status = status
  @corrector = corrector
  @justification = justification.freeze
  @corrections = (corrections || corrections_from(corrector)).freeze
  @correction_safe = correction_safe
  freeze
end

Instance Attribute Details

#column (readonly)

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 237

attr_reader :column

#cop_name ⇒ String (readonly)

Examples:

'Layout/LineLength'

Returns:

  • (String) —

    the cop name as a String for which this offense is for.

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 50

attr_reader :cop_name

#correctable? ⇒ Boolean (readonly)

Returns:

  • (Boolean) —

    whether this offense can be automatically corrected via autocorrect. This includes todo comments, for example when requested with --disable-uncorrectable. An offense suppressed by a directive comment is not correctable - autocorrect will not touch it.

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 180

def correctable?
  @status != :unsupported && @status != :disabled
end

#corrected? ⇒ Boolean (readonly)

Returns:

  • (Boolean) —

    whether this offense is automatically corrected via autocorrect or a todo.

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 191

def corrected?
  @status == :corrected || @status == :corrected_with_todo
end

#corrected_with_todo? ⇒ Boolean (readonly)

Returns:

  • (Boolean) —

    whether this offense is automatically disabled via a todo.

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 201

def corrected_with_todo?
  @status == :corrected_with_todo
end

#correction_safe ⇒ Boolean (readonly)

Returns:

  • (Boolean) —

    whether autocorrection would apply #corrections in a normal -a run. A cop marked Safe: false or SafeAutoCorrect: false still builds its correction, but only -A applies it, so a consumer that applies edits itself has to make the same distinction.

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 122

attr_reader :correction_safe

#corrections ⇒ Array<Correction> (readonly)

Returns:

  • (Array<Correction>) —

    the individual edits that autocorrecting this offense would make, in source order. Empty when the offense has no correction. Unlike #corrector, this survives serialization, so it is available on a cache hit and in parallel runs.

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 111

attr_reader :corrections

#corrector ⇒ Corrector | nil (readonly)

Returns:

  • (Corrector | nil) —

    the autocorrection for this offense, or nil when not available

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 61

attr_reader :corrector

#disabled? ⇒ Boolean (readonly)

Returns:

  • (Boolean) —

    whether this offense was locally disabled with a disable or todo where it occurred.

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 212

def disabled?
  @status == :disabled || @status == :todo
end

#justification ⇒ String? (readonly)

Returns:

  • (String, nil) —

    the reason given on the directive that suppressed this offense (the text after --), or nil when the offense is not suppressed or the directive carries no reason

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 100

attr_reader :justification

#line (readonly)

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 234

attr_reader :line

#location ⇒ Parser::Source::Range (readonly)

Returns:

  • (Parser::Source::Range) —

    the location where the violation is detected.

See Also:

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 28

attr_reader :location

#message ⇒ String (readonly)

Examples:

'Line is too long. [90/80]'

Returns:

  • (String) —

    human-readable message

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 39

attr_reader :message

#severity ⇒ RuboCop::Cop::Severity (readonly)

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 17

attr_reader :severity

#status (readonly)

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 53

attr_reader :status

Instance Method Details

#<=>(other) ⇒ Integer

Returns -1, 0, or +1 if this offense is less than, equal to, or greater than other.

Returns:

  • (Integer) —

    comparison result

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 315

def <=>(other)
  COMPARISON_ATTRIBUTES.each do |attribute|
    result = public_send(attribute) <=> other.public_send(attribute)
    return result unless result.zero?
  end
  0
end

#==(other) ⇒ Boolean Also known as: #eql?

Returns:

  • (Boolean) —

    returns true if two offenses contain same attributes

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 296

def ==(other)
  COMPARISON_ATTRIBUTES.all? do |attribute|
    public_send(attribute) == other.public_send(attribute)
  end
end

#column_length

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 245

def column_length
  if first_line == last_line
    column_range.count
  else
    source_line.length - column
  end
end

#column_range

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 269

def column_range
  location.column_range
end

#corrections_from(corrector) (private)

Extracted eagerly rather than on demand because the offense is frozen, and because a corrector cannot be serialized - the cache and parallel workers would otherwise hand back offenses that have lost their edits.

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 328

def corrections_from(corrector)
  return EMPTY_CORRECTIONS unless corrector

  corrector.as_replacements.map do |range, replacement|
    Correction.new(range.begin_pos, range.end_pos, replacement.freeze).freeze
  end
end

#eql?(other)

Alias for #==.

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 302

alias eql? ==

#first_line

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 254

def first_line
  location.first_line
end

#hash

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 304

def hash
  COMPARISON_ATTRIBUTES.map { |attribute| public_send(attribute) }.hash
end

#highlighted_area ⇒ Parser::Source::Range

Returns:

  • (Parser::Source::Range) —

    the range of the code that is highlighted

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 220

def highlighted_area
  source_buffer = Parser::Source::Buffer.new(location.source_buffer.name, source: source_line)
  Parser::Source::Range.new(source_buffer, column, column + column_length)
end

#last_column

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 264

def last_column
  location.last_column
end

#last_line

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 259

def last_line
  location.last_line
end

#marshal_dump

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 157

def marshal_dump
  [@severity, @location, @message, @cop_name, @status, @justification, @corrections,
   @correction_safe]
end

#marshal_load(array)

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 162

def marshal_load(array)
  @severity, @location, @message, @cop_name, @status, @justification, @corrections,
    @correction_safe = array
  @corrections ||= EMPTY_CORRECTIONS
  @correction_safe = true if @correction_safe.nil?
  @line = @location.line
  @column = @location.column
end

#real_column

Internally we use column number that start at 0, but when outputting column numbers, we want them to start at 1. One reason is that editors, such as Emacs, expect this.

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 278

def real_column
  column + 1
end

#real_last_column

The minimum value of #real_column is 1, so the minimum value of real_last_column is also 1. A non-zero #last_column is used as is, because the 0-based end-exclusive column is the same as the 1-based column of the last character.

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 288

def real_last_column
  last_column.zero? ? 1 : last_column
end

#source_line

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 240

def source_line
  location.source_line
end

#to_s

This is just for debugging purpose.

[ GitHub ]

  
# File 'lib/rubocop/cop/offense.rb', line 227

def to_s
  format('%<severity>s:%3<line>d:%3<column>d: %<message>s',
         severity: severity.code, line: line,
         column: real_column, message: message)
end