Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A new CC metric that takes nesting into account #35

Open
aaghamohammadi opened this issue Feb 12, 2020 · 9 comments
Open

A new CC metric that takes nesting into account #35

aaghamohammadi opened this issue Feb 12, 2020 · 9 comments

Comments

@aaghamohammadi
Copy link
Contributor

By definition, the CC metric does not take into account the nesting levels of the method. For example, consider the following Python source code:

public int getPayAmount() {
  int result = 0;
  if (isDead)
    result = deadAmount();
  else {
    if (isSeparated)
      result = separatedAmount();
    else {
      if (isRetired)
        result = retiredAmount();
      else
        result = normalPayAmount();
    }
  }
  return result;
}

By refactoring this code, we get:

public void getPayAmount() {
  if (isDead) return deadAmount();
  if (isSeparated) return separatedAmount();
  if (isRetired) return retiredAmount();
  return normalPayAmount();
}

As you can see, By applying a popular technique named Replace Nested Conditional with Guard Clauses, the source code structure would improve a lot. However, the CC metric does not change (by definition).
Some researchers have proposed a few solutions. Surprisingly, the best solution (in my opinion) has the minimum citation link .

@mauricioaniche
Copy link
Owner

I will not classify this as a bug, as I think this is actually a possible new metric to CK!

Would you be willing to implement it yourself? I can help you by giving you tips and feedback in a PR!

@mauricioaniche mauricioaniche changed the title Nesting Problem of Cyclomatic Complexity A different CC metric that takes nesting into account Feb 12, 2020
@mauricioaniche mauricioaniche changed the title A different CC metric that takes nesting into account A new CC metric that takes nesting into account Feb 12, 2020
@aaghamohammadi
Copy link
Contributor Author

@mauricioaniche
I have tried this before but I failed. I don't know how can I access the depth of a method. The new metric is computed as follows:

MWMC(m) = d(m) + WMC(m)

where d(m) denotes the depth of the method m. For example, consider the following code:

public int getPayAmount() {
  int result = 0;
  if (isDead)
    result = deadAmount();
  else {
    if (isSeparated)
      result = separatedAmount();
    else {
      if (isRetired)
        result = retiredAmount();
      else
        result = normalPayAmount();
    }
  }
  return result;
}

The depth of the method (d(m)) is 3. Indeed, if the depth of a method is implemented as a new metric, the modified WMC will be automatically computed.

@mauricioaniche
Copy link
Owner

Is d(m) the max depth that can be found in a method? If so, we have the MaxNumberOfNestedBlocks as a metric already: https://github.com/mauricioaniche/ck/blob/master/src/main/java/com/github/mauricioaniche/ck/metric/NumberOfMaxNestedBlock.java

Is that it?

@aaghamohammadi
Copy link
Contributor Author

aaghamohammadi commented Feb 13, 2020

Not exactly. For any nested blocks, the max depth of that block added to d(m) . Consider the following code:

public int m1(){
     statement 1;
     for(int i=0; i< 10; i++){
         statement 2;
         if(cond)
             statement 3;
     }

    statement 4;

    if(cond2) {
        statement 5;
        statement 6;
       if(cond3) {
           statement 7;
       }
    }

   if(cond4) {
        statement 8;
        statement 9;
       if(cond5) {
           statement 10;
       }
    }
    statement 11;
    return 100;
}

The max depth is 2. However, the d(m) is 3 (see statement 3,7,10).

@aaghamohammadi
Copy link
Contributor Author

@mauricioaniche
In fact, the aforementioned paper says:
"Identify the second, the third, the fourth, and subsequent levels of nesting constructs and assign each occurrence with one unit of complexity. "

@mauricioaniche
Copy link
Owner

mauricioaniche commented Feb 13, 2020

I did not read the paper yet, so, sorry for my questions!

But isn't then d(m) = max_nested_blocks + 1?

@aaghamohammadi
Copy link
Contributor Author

No. Although most of the cases are true, there are some situations that d(m) != max_nested_blocks + 1.
When a method consists of two independent nesting blocks, that equation does not hold anymore.

@mauricioaniche
Copy link
Owner

From the paper, it seems that, all we need to do in the WMC implementation is to give a weight of 1, if the nesting(node) = 1, or a weight of 2, if the node is nesting(node)>1.

(There's also the corner case of a block returning early, then, next ones in that nested block should be considered 1 again)

Does that make sense to you?

@aaghamohammadi
Copy link
Contributor Author

Yes. This is exactly what I understood from the paper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants