Class: CodeKeeper::Metrics::ClassLength

Inherits:
Object
  • Object
show all
Defined in:
lib/code_keeper/metrics/class_length.rb

Overview

Caluculate Class Length.

Instance Method Summary collapse

Constructor Details

#initialize(file_path) ⇒ ClassLength

Returns a new instance of ClassLength.



7
8
9
10
11
# File 'lib/code_keeper/metrics/class_length.rb', line 7

def initialize(file_path)
  @ps = Parser.parse(file_path)
  @body = @ps.ast
  @score_hash = {}
end

Instance Method Details

#scoreObject

NOTE: This doesn’t exclude foldale sources like Array, Hash and Heredoc.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/code_keeper/metrics/class_length.rb', line 14

def score
  @body.each_node(:class, :casgn, :module) do |node|
    if node.class_type? || node.module_type?
      @score_hash.store(build_namespace(node), calculate(node))
    elsif node.casgn_type?
      parent = node.parent

      if parent&.assignment?
        block_node = node.children[2]
        klass = node.loc.name.source
      elsif parent&.parent&.masgn_type?
        # In the case where `A, B = Struct.new(:a, :b)`,
        # B is always nil.
        assigned = parent.loc.expression.source.split(',').first
        next unless node.loc.name.source == assigned

        block_node = parent.parent.children[1]
        klass = node.loc.name.source
      else
        _scope, klass, block_node = *node
        klass = klass.to_s
      end

      # This is not to raise error on dynamic assignments like `X = Y = Z = Class.new`.
      # the block node is as follows if node is X:
      # `s(:casgn, nil, :Y, s(:casgn, nil, :Z, s(:block, ...`
      # Similarly the block node is `:X` as follows if node is Y.
      next unless block_node.respond_to?(:class_definition?) && block_node.class_definition?

      # NOTE: klass doesn't have a namespace.
      # Only supports namepaces in `class A; end` case.
      if klass
        @score_hash.store(klass, calculate(block_node)) if klass
      else
        @score_hash.store(build_namespace(block_node), calculate(block_node))
      end
    end
  end
  @score_hash
end