Class: Shirobai::Cop::Metrics::AbcSize
- Inherits:
-
RuboCop::Cop::Base
- Object
- RuboCop::Cop::Base
- Shirobai::Cop::Metrics::AbcSize
- Extended by:
- RuboCop::ExcludeLimit
- Includes:
- RuboCop::Cop::AllowedMethods, RuboCop::Cop::AllowedPattern
- Defined in:
- lib/shirobai/cop/metrics/abc_size.rb
Overview
Drop-in Rust reimplementation of ‘Metrics/AbcSize`.
Rust returns the per-method ‘<assignment, branch, condition>` counts for every method whose squared vector exceeds the configured `Max.floor` (`bundle_args` packs `Max.floor`; a non-natural `Max` packs `-1` so every method is returned and the exact `score > Max` filter below stays the behavioral source of truth). The float score, the vector string and the message are derived here so floats never cross the FFI boundary.
Constant Summary collapse
- MSG =
"Assignment Branch Condition size for `%<method>s` is too high. " \ "[%<abc_vector>s %<complexity>.4g/%<max>.4g]"
Class Method Summary collapse
- .badge ⇒ Object
-
.bundle_args(config) ⇒ Object
Packed args for the bundled run: ‘[max_floor, discount_repeated]`.
- .cop_name ⇒ Object
Instance Method Summary collapse
Class Method Details
.badge ⇒ Object
25 |
# File 'lib/shirobai/cop/metrics/abc_size.rb', line 25 def self.badge = RuboCop::Cop::Badge.parse("Metrics/AbcSize") |
.bundle_args(config) ⇒ Object
Packed args for the bundled run: ‘[max_floor, discount_repeated]`. `max_floor` is the cop’s ‘Max.floor` (conservative prefilter: a float `Max` floors down, an integer one is exact); a non-natural `Max` disables the prefilter with `-1`. `discount_repeated` is `!CountRepeatedAttributes` (default `CountRepeatedAttributes: true`).
32 33 34 35 36 37 38 |
# File 'lib/shirobai/cop/metrics/abc_size.rb', line 32 def self.bundle_args(config) cop_config = config.for_badge(badge) max = cop_config["Max"] max_floor = max.is_a?(Numeric) && max >= 0 ? max.floor : -1 discount = cop_config["CountRepeatedAttributes"] == false [max_floor, discount ? 1 : 0] end |
.cop_name ⇒ Object
24 |
# File 'lib/shirobai/cop/metrics/abc_size.rb', line 24 def self.cop_name = "Metrics/AbcSize" |
Instance Method Details
#on_new_investigation ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/shirobai/cop/metrics/abc_size.rb', line 40 def on_new_investigation max = cop_config["Max"] analysis = Dispatch.offenses_for(processed_source, config, :abc_size) off = SourceOffsets.for(processed_source.raw_source) analysis.each do |start, fin, head_end, name, assignment, branch, condition| next if allowed_method?(name) || matches_allowed_pattern?(name) complexity = Math.sqrt((assignment**2) + (branch**2) + (condition**2)).round(2) next unless complexity > max abc_vector = "<#{assignment}, #{branch}, #{condition}>" stop = RuboCop::LSP.enabled? ? head_end : fin range = Parser::Source::Range.new(processed_source.buffer, off[start], off[stop]) = format(MSG, method: name, complexity: complexity, abc_vector: abc_vector, max: max) add_offense(range, message: ) { self.max = complexity.ceil } end end |