FP on javascript:S3776 Incorrect calculation of cognitive complexity

Code given below is part of one JS file being scanned. I have removed some code to make it simple to read and understand. Numbers 1 to 21 indicates cognitive complexity calculated by SonarQube. We expect complexity calculation should reset at " ==> $(document).ready ends here." comment as
$(document).ready ends there and functions coded after that line are not part of $(document).ready but in continues. This is blocking our PR builds.

$(document).ready(function () {
<Some code here>

    1=> if ($("#SearchOnLoad").val().toLowerCase() === "true") {     
    2=>    if (<Removed>) {
            <Removed>
        }
        <Removed>
    }

    searchPanelControls.$searchButton.on('click keypress', function (e) {
     3=>   if (e.type === 'click' 4=> || e.which === 13) {
            <Removed>
        }
    });
    consentControls.$titleSearch.on('keypress', function (e) {
     5=>   if ($.trim(this.value) !== "") {
            var key = e.which;
     6=>       if (key === 13) {
              <Removed>
            }
        }
    });
    consentControls.$removed.on('keypress', function (e) {
    7=>    if ($.trim(this.value) !== "") {
            var key = e.which;
    8=>        if (key === 13) {
                <Removed>
            }
        }
    });
        commonFunctions.toggleModal($Removed, false);
    }); ==> $(document).ready ends here. Complexity calculations still continued. 
 
    function Removed(returnStatus, data) {
     9=>   if (returnStatus === ajaxService.returnStatus.done 10=> && data !== undefined) {           
           <Removed>
        }
    }
    function sendConsentRemindersResultCallback(returnStatus, data) {
     11=>   if (returnStatus === ajaxService.returnStatus.done 12=> && data !== undefined) {
            <Removed>
     13=>       if (data.alert !== undefined) {
               <Removed>
            }          
        }
     14=>   else if (returnStatus === ajaxService.returnStatus.always) {
           <Removed>
        }
    }
    function searchConsents() {
     	<Removed>
     15=>   if (childSsn != "" 16,17=> && (childId === null || childId === "")) {
            <Removed>
     18=>   } else if ((titleSearch !== undefined && titleSearch !== "" 19,20) &&
            (consentId == null || consentId === "")) {
           <Removed>
        }
     21=>  else {
           <Removed>
        ];
    }

SonarQube Version: Developer Edition 9.3.0.51899

Hi,

Could you clarify what version of SonarQube you’re using?

 
Thx,
Ann

It’s already mentioned in post but still as you asked.

SonarQube Version: Developer Edition 9.3.0.51899

1 Like

@ganncamp Could you please confirm if this is bug?

@ganncamp,
Can anyone look into this? This is troubling us a lot. I think it’s unfair to keep customers without purchased support waiting forever.

Hi,

This has been queued for the language experts. Hopefully they’ll be along soon.

 
Ann

1 Like

Hello Rahul,

Sorry for the delay in answering you.

Unfortunately, I am not able to reproduce the false positive you highlighted in the code snippet you shared. I changed your snippet a bit to make it syntactically correct while preserving its structure and semantics as follows:

$(document).ready(function () {
  if ($("#SearchOnLoad").val().toLowerCase() === "true") {
    if (removed()) {
      removed();
    }
    removed();
  }

  searchPanelControls.$searchButton.on("click keypress", function (e) {
    if (e.type === "click" || e.which === 13) {
      removed();
    }
  });
  consentControls.$titleSearch.on("keypress", function (e) {
    if ($.trim(this.value) !== "") {
      var key = e.which;
      if (key === 13) {
        removed();
      }
    }
  });
  consentControls.$removed.on("keypress", function (e) {
    if ($.trim(this.value) !== "") {
      var key = e.which;
      if (key === 13) {
        removed();
      }
    }
  });
  commonFunctions.toggleModal($Removed, false);
}); // $(document).ready ends here. Complexity calculations still continued.

function Removed(returnStatus, data) {
  if (returnStatus === ajaxService.returnStatus.done && data !== undefined) {
    removed();
  }
}
function sendConsentRemindersResultCallback(returnStatus, data) {
  if (returnStatus === ajaxService.returnStatus.done && data !== undefined) {
    removed();
    if (data.alert !== undefined) {
      removed();
    }
  } else if (returnStatus === ajaxService.returnStatus.always) {
    removed();
  }
}
function searchConsents() {
  removed();
  if (childSsn != "" && (childId === null || childId === "")) {
    removed();
  } else if (
    titleSearch !== undefined &&
    titleSearch !== "" &&
    (consentId == null || consentId === "")
  ) {
    removed();
  } else {
    removed();
  }
}

Basically, I replaced every occurrence of <Removed> with removed(), and I got rid of the complexity counts n=>. Then I ran an analysis with the same SonarQube 9.3.0 version, but I don’t get the same complexity:

The complexity calculation that starts from line 1 ends at line 31 as expected. In other words, the calculation does not go beyond the scope of the top-level anonymous function.

It’s hard for me to tell why this is different from what you got. Therefore, I would appreciate it if you could share a minimal, syntactically correct, code snippet reproducing the false positive. You could also point out what I wrongly changed from the original snippet.

Thank you,
Yassin

1 Like

Hi Yassin,
Please accept my apologies apologies as I have given wrong example and my understanding about problem was also wrong.
We are using jquery and having large javascript inside document.ready() is quite normal thing. Do we have any configuration which allows us to ignore document.ready() for cognitive complexity check?
We don’t want to change or suppress the rule.

Regards
Rahul Mahulkar

Hello Rahul,

Good to know that there were no false positives in the provided code snippet. Regarding ignoring the callback’s body of $document.ready() instances, I think we could add an exception to the rule for that particular pattern.

Before creating a ticket, do you think there are other usages of JQuery API that would also deserve an exception? I am just trying to kill two or more birds with one stone here :slight_smile:

Regards,
Yassin

Hi Yassin, Thank you for extending help here.

@empouras Do you know if there are any more patterns which should be considered?

Regards
Rahul Mahulkar

I would say that it is important to take into consideration (when ignoring) all supported and possible syntax ways of jquery for document ready

$(function() {...});

$(document).ready(function() {...});

$().ready(function() {...});

Thanks for the feedback! Ticket created.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.