Class: Shirobai::Cop::Metrics::ClassLength

Inherits:
RuboCop::Cop::Base
  • Object
show all
Extended by:
RuboCop::ExcludeLimit
Defined in:
lib/shirobai/cop/metrics/class_length.rb

Overview

Drop-in Rust reimplementation of Metrics/ClassLength.

Rust parses the source, finds every class definition (class nodes, class << self outside a class, and Class.new / Struct.new blocks assigned to a constant), measures each with the shared CodeLength calculator's classlike / body paths and returns those exceeding Max. There is no autocorrect; the wrapper only builds ranges and messages.

Constant Summary collapse

LABEL =
"Class"
MSG =
"%<label>s has too many lines. [%<length>d/%<max>d]"
FOLDABLE_TYPES =
%w[array hash heredoc method_call].freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.badgeObject



23
# File 'lib/shirobai/cop/metrics/class_length.rb', line 23

def self.badge = RuboCop::Cop::Badge.parse("Metrics/ClassLength")

.bundle_args(config) ⇒ Object

Packed args for the bundled run: [max, count_comments, count_as_one]. Max defaults to 100 (default.yml) so a config that does not mention this cop still packs cleanly; the computed slice is discarded in that case.



29
30
31
32
33
34
35
36
# File 'lib/shirobai/cop/metrics/class_length.rb', line 29

def self.bundle_args(config)
  cop_config = config.for_badge(badge)
  [
    cop_config["Max"] || 100,
    !!cop_config["CountComments"],
    Array(cop_config["CountAsOne"]).map(&:to_s)
  ]
end

.cop_nameObject



22
# File 'lib/shirobai/cop/metrics/class_length.rb', line 22

def self.cop_name = "Metrics/ClassLength"

Instance Method Details

#on_new_investigationObject



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/shirobai/cop/metrics/class_length.rb', line 38

def on_new_investigation
  candidates = Dispatch.offenses_for(processed_source, config, :class_length)
  off = SourceOffsets.for(processed_source.raw_source)
  candidates.each do |start, fin, head_end, length, sclass|
    validate_count_as_one!

    # Stock's LSP location reads `node.loc.begin` for a
    # `class << self`, which `Parser::Source::Map::Definition` does
    # not define — stock raises (a swallowed cop error) and reports
    # nothing, so report nothing here too.
    next if sclass && RuboCop::LSP.enabled?

    stop = RuboCop::LSP.enabled? ? head_end : fin
    range = Parser::Source::Range.new(processed_source.buffer, off[start], off[stop])
    add_offense(range, message: format(MSG, label: LABEL, length: length, max: max_length)) do
      self.max = length
    end
  end
end