terryyin / lizard

A simple code complexity analyser without caring about the C/C++ header files or Java imports, supports most of the popular languages.
Other
1.81k stars 246 forks source link

Ruby and modified complexity #347

Open wjonessmd opened 2 years ago

wjonessmd commented 2 years ago

For modified complexity (-m) in Ruby Lizard is counting all the 'when' statements and not counting the 'case' statements. It needs to be the other way round.

Ruby to analyse,

def case y = 0 x = 3 case x when 1 y = 1 when 2 y = 2 when 3 y = 3 when 4 y = 3 when 5 y = 3 when 6 y = 3 when 7 y = 3 when 8 y = 3 when 9 y = 3 when 10 y = 3 when 11 y = 3 when 12 y = 3 else y = 4 end end

Lizard modified complexity command and result, C:\Users\wjones\lizard>lizard -m -C 10

NLOC CCN token PARAM length location

  23      5     87      0      23 generate_charts@1-23@.\real ruby.rb
  31     12     74      0      31 case@1-31@.\ruby case.rb

Lizard standard complexity command and result, C:\Users\wjones\lizard>lizard -C 10

NLOC CCN token PARAM length location

  23      6     87      0      23 generate_charts@1-23@.\real ruby.rb
  31     13     74      0      31 case@1-31@.\ruby case.rb
wjonessmd commented 2 years ago

I think the problem is in lizard/lizard-ext/lizardmodified.py. The code from that file is,

''' This is an extension of lizard, It lets lizard to use modified cyclomatic complexity number, where the whole switch/case will be counted as 1. '''

class LizardExtension(object): # pylint: disable=R0903

def __call__(self, tokens, reader):
    for token in tokens:
        if token == 'switch':
            reader.context.add_condition()
            if hasattr(reader.context, "add_nd_condition"):
                reader.context.add_nd_condition()
        elif token == 'case':
            reader.context.add_condition(-1)
            if hasattr(reader.context, "add_nd_condition"):
                reader.context.add_nd_condition(-1)
        yield token

This works for Swift, but not for Ruby. 'case' is the Ruby equivalent of 'switch' in Swift. There does not appear to be any reference to language in this file. Only languages that use a switch/case structure will work for modified complexity in Lizard. Ruby's case/when structure will reduce the complexity count by one for the 'case'. The 'when's will all count towards complexity. This is obviously incorrect.

terryyin commented 1 year ago

Could you please send a pull request?

On 25 Mar 2022, at 2:12 AM, wjonessmd @.***> wrote:

I think the problem is in lizard/lizard-ext/lizardmodified.py. The code from that file is,

''' This is an extension of lizard, It lets lizard to use modified cyclomatic complexity number, where the whole switch/case will be counted as 1. '''

class LizardExtension(object): # pylint: disable=R0903

def call(self, tokens, reader): for token in tokens: if token == 'switch': reader.context.add_condition() if hasattr(reader.context, "add_nd_condition"): reader.context.add_nd_condition() elif token == 'case': reader.context.add_condition(-1) if hasattr(reader.context, "add_nd_condition"): reader.context.add_nd_condition(-1) yield token This works for Swift, but not for Ruby. 'case' is the Ruby equivalent of 'switch' in Swift. There does not appear to be any reference to language in this file. Only languages that use a switch/case structure will work for modified complexity in Lizard. Ruby's case/when structure will reduce the complexity count by one for the 'case'. The 'when's will all count towards complexity. This is obviously incorrect.

— Reply to this email directly, view it on GitHub https://github.com/terryyin/lizard/issues/347#issuecomment-1077905916, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAGASYSUR7VMV3JU3EXPEFTVBSWAVANCNFSM5RRB6TRQ. You are receiving this because you are subscribed to this thread.