-
Notifications
You must be signed in to change notification settings - Fork 363
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
US: Add explanation for cognitive/cyclomatic complexity checks #1494
Comments
@ivangalkin maybe interesting to align it with Java, but I don't need it. |
Hi @guwirth, I used Java as example, but I believe that other plugins (incl. By the way, while writing this comment I found the duplicate US #1297. It contains a good illustration, how such issue should look like. It looks, like I am not the only person, who misses this feature. |
* minor performance findings while looking at SonarOpenCommunity#1494
* minor findings while looking at SonarOpenCommunity#1494 * test doesn show the actual values because of a wrong written assertion
* implement multi-line messages for squidsensor
* this class is used for all scoped cyclomatic complexity checks * ClassComplexityCheck * FileComplexityCheck * FunctionComplexityCheck * it respects the scopes (important for nested classes) * it provides detailed information about complexity sources
* replace custom recursive algorithm with the standard AstVisitor approach * no risk of StackOverflowError anymore * no need to track set of visited `AstNode`s - decrease run-time and memory footprint * code simplification and clean-up * the new code calcualtes an equal value for the cognitive complexity metric this change is required for SonarOpenCommunity#1494
1. implement multi-location messages for squidsensor * move CxxReportIssue and CxxReportLocation from cxx-sensors to cxx-squid in order to satisfy dependencies 2. introduce CxxCyclomaticComplexityCheck * this class is used for all scoped cyclomatic complexity checks * implement * ClassComplexityCheck * FileComplexityCheck * FunctionComplexityCheck * they respect the scopes (important for nested classes) * they provide detailed information about complexity sources * FileComplexityCheck previously had a wrong calculation: cyclomatic complexity of functions was always <correct score> + 1 -> fixed now This change addresses SonarOpenCommunity#1494: * cyclomatic complexity checks (done) * cognitive complexity checks (todo, depends on SonarOpenCommunity#1535
1. implement multi-location messages for squidsensor * move CxxReportIssue and CxxReportLocation from cxx-sensors to cxx-squid in order to satisfy dependencies 2. introduce CxxCyclomaticComplexityCheck * this class is used for all scoped cyclomatic complexity checks * implement * ClassComplexityCheck * FileComplexityCheck * FunctionComplexityCheck * they respect the scopes (important for nested classes) * they provide detailed information about complexity sources * FileComplexityCheck previously had a wrong calculation: cyclomatic complexity of functions was always <correct score> + 1 -> fixed now This change addresses SonarOpenCommunity#1494: * cyclomatic complexity checks (done) * cognitive complexity checks (todo, depends on SonarOpenCommunity#1535
+ fix some quality flows closes SonarOpenCommunity#1494
* partial solution for SonarOpenCommunity#1547 MOTIVATION: * SonarOpenCommunity#1494 made visible the fact, that preprocessor affects the complexity metric. E.g. if function uses macros, the underlying (hidden) complexity of theses macros increases the complexity of the function. This is wrong because of many reasons: 1. Cognitive complexity: Macros do not increase the cognitive complexity of the source code. To the reader they are similar to the function invocations. Example ASSERT_XX/EXPECT_XX macros of GTest. 2. Cyclomatic complexity: Similar logic might be applied to the cyclomatic complexity: macro expansions are similar to the function calls (which become inlined). In this case the cyclomatic complexity of the caller should not be increased. [Cyclomatic] complexity of the callee must be calculated separately. 3. Preprocessor doesn't distinguish between the macros, which were declared inside of the analyzed project or were included from the external header. Obviously the external source code (e.g. again very complex GTest macros) should not affect the complexity of someone's custom SonarQube project. SOLUTION: In general it's impossible to build a valid C/C++ AST without performing of preprocessor step. The original source code might be syntactically incorrect (e.g. if macros are used to "invent" some domain specific language out of C/C++). All metrics of sonar-cxx are however AST-based. (This is a very questionably decision e.g. because #if/#ifdef etc might affect the resulting complexity or [NC]LOC in dramatic way). So we cannot skip preprocessor step entirely and/or perform metrics calculation/checks on the non-preprocessed code. Sonar SSLR has a possibility to mark some tokens as generated. This property (`Token::isGeneratedCode()`) is for example used in order to ignore generated while * [NC]LOC counting (see `AbstractLineLengthCheck<>`) * CDP analysis (see `CxxCpdVisitor`) or * Highlighting (see `CxxHighlighterVisitor`) This patch ensures, that * all `AstNode`s, which were created while macro expansion are marked as generated * all complexity related visitors ignore generated `AstNode`s RESULT: PRO: 1. The complexity of "callers" is not affected by macro anymore. This fact makes the complexity check look logical again. CON: 1. the complexity of "callees" is not calculated at all. This is correct in case of external macros, but wrong w.r.t. to the project intern macros. Possible solution: preprocessor must try to extract the function-like macro declaration into some special AST-subtree. Afterwards complexity metrics/check will be able to calculate/check macros as separate language construct. By the way: it must be analyzed if and how macros affect other metrics. For example LOC etc. 2. This patch might change the complexity related metrics. Depending on how many macros were used in the analyzed project, the reduction can be radical.
* complete list of `overloadable-operator`s (yes, alternative operators can be used for operator overloading too) * complete `equalityExpression`, `andExpression`, `exclusiveOrExpression`, `inclusiveOrExpression`, `logicalAndExpression`, `logicalOrExpression` fixes SonarOpenCommunity#1569 * add missing support of alternative operators to the complexity metrics (see # SonarOpenCommunity#1494)
Hi All,
while reviewing of the #1398, I've noticed that the complexity checks create an issues without any explanation.
E.g.
ClassComplexityCheck
,FileComplexityCheck
,FunctionCognitiveComplexityCheck
orFunctionComplexityCheck
create an issue on the class/file/function with a message likeThe Java plugin breaks X into several summands, each of them is a secondary location, pointing to the complexity source (nesting, switch/case, loops, try/catch, inner declarations of classes or lambdas etc).
The resulting message looks like:
Implementation in Java plugin:
https://github.com/SonarSource/sonar-java/blob/master/java-checks/src/main/java/org/sonar/java/checks/CognitiveComplexityMethodCheck.java
https://github.com/SonarSource/sonar-java/blob/master/java-frontend/src/main/java/org/sonar/java/ast/visitors/CognitiveComplexityVisitor.java
Example of working with multiple/secondary issue locations: #1447
The text was updated successfully, but these errors were encountered: