A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/pmd/pmd/issues/5568 below:

[java] High NPathComplexity in `switch` expression · Issue #5568 · pmd/pmd · GitHub

Affects PMD Version:
7.11.0

Rule:
NPathComplexity

Description:
This issue is actually more of a question of why PMD reports switch expressions with an incredibly high NPath complexity.

Code Sample demonstrating the issue:
The following code has an NPathComplexity of 1296:

public static byte toByte(final Register8 r) {
  return switch (r) {
    case AL, R8B -> (byte) 0x00;
    case CL, R9B -> (byte) 0x01;
    case DL, R10B -> (byte) 0x02;
    case BL, R11B -> (byte) 0x03;
    case AH, SPL, R12B -> (byte) 0x04;
    case CH, BPL, R13B -> (byte) 0x05;
    case DH, SIL, R14B -> (byte) 0x06;
    case BH, DIL, R15B -> (byte) 0x07;
  };
}

The following code (completely equivalent to the first one) has an NPathComplexity of 21:

public static byte toByte(final Register8 r) {
  if (r == AL || r == R8B) {
    return (byte) 0x00;
  } else if (r == CL || r == R9B) {
    return (byte) 0x01;
  } else if (r == DL || r == R10B) {
    return (byte) 0x02;
  } else if (r == BL || r == R11B) {
    return (byte) 0x03;
  } else if (r == AH || r == SPL || r == R12B) {
    return (byte) 0x04;
  } else if (r == CH || r == BPL || r == R13B) {
    return (byte) 0x05;
  } else if (r == DH || r == SIL || r == R14B) {
    return (byte) 0x06;
  } else if (r == BH || r == DIL || r == R15B) {
    return (byte) 0x07;
  } else {
    throw new NullPointerException();
  }
}

Expected outcome:
I understand where the 1296 comes from: 4 cases with 2 values and 4 cases with 3 values produce 2 * 2 * 2 * 2 * 3 * 3 * 3 * 3 = 1296 possible execution paths. The Register8 enum has only those 20 values (as can be deduced from the switch missing the default case) so I would expect a complexity of 20 (maybe +1 for the hidden null case) like in the second example.
In short, I think PMD is doing the wrong calculation. The value of 1296 would make sense if the switch was a classic one without breaks like the one below. This would explain the use of multiplication in the computation of the NPath complexity but I think in a switch expression (in which each case has its own scope, AFAIK) that computation should be a simple addition of the complexity of each case.

switch(x) {
  case 0, 1:
    // some code...
    // fallthrough
  case 2, 3:
    // some other code...
    // fallthrough
  default:
    return ...;
}

Looking around in older issues I found this one which was apparently fixed in PMD 6.26.0, so this issue may be a duplicate.

Running PMD through: Gradle


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4