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.85k stars 250 forks source link

Swift: nil coalescing operator `??` measuring by mistake #269

Closed kijuky closed 5 years ago

kijuky commented 5 years ago

I feel that ?? is being measured incorrectly in some cases.

Case 1

func f0() {
  print(optionalValue ?? "nil")
}

I think ccn is 2. The reason is that it is equivalent to the following code, and one control code (if) is included.

func f0() {
  if let value = optionalValue {
    print(value)
  } else {
    print("nil")
  }
}

Case 2

func f0() {
  print(optionalValue?.value ?? "nil")
}

I think ccn is 2. The reason is that it is equivalent to the following code, and one control code (if) is included.

func f0() {
  if let value = optionalValue {
    print(value.value)
  } else {
    print("nil")
  }
}

Case 3

func f0() {
  print(optionalValue?.optionalValue?.value ?? "nil")
}

I think ccn is 3. The reason is that it is equivalent to the following code, and two control code (if) is included.

func f0() {
  if let value = optionalValue {
    if let value2 = value.optionalValue {
      print(value2.value)
    } else {
      print("nil")
    }
  } else {
    print("nil")
  }
}

Remark

terryyin commented 5 years ago

I would count the Case 1 as ccn 2, too.

But in the case of 2 and 3, I think it will be quite hard for Lizard to identify the redundancy of ~?.value ?? ~ in a smart way. Unless we just ignore the sequence ?.value ???

terryyin commented 5 years ago

or just count ?.value ?? as +1 ccn only.

kijuky commented 5 years ago

Thank you for your comment!

I think implementing case 2 and case 3 with lizard would be a big fix.

So I want to confirm lizard's policy. Should it be measured accurately even if the processing becomes complicated to some extent? (However, I believe that the only change will be swift.py.) Is this case accurate to measure?

kijuky commented 5 years ago

I found a case where the lizard parser had limitations...

Case 2-1

func f0() {
  print(optionalValue?.optionalValue ?? "nil")
}

I think ccn is 3. The reason is that it is equivalent to the following code, and two control code (if) is included.

func f0() {
  if let value = optionalValue {
    if let value2 = value.optionalValue {
      print(value2)
    } else {
      print("nil")
    }
  } else {
    print("nil")
  }
}

Comparing Case 2 and Case 2-1, CCN differs depending on whether the last value is optional or not for expressions including unwrapping. However, lizard can not detect this.

kijuky commented 5 years ago

I believe that the consent for Case 1 has been obtained. So I want to add ?? to _conditions.

kijuky commented 5 years ago

I'm sorry. I was misunderstood.

In Swift, CCN does not increase because ? And ?? are method calls.

This issue is closed.