Menu

Does the reportLevel restriction for CyclomaticComplexity in CodeSize only apply to methods (and not classes)?

Help
2015-07-10
2015-07-14
  • Jimmy Philps

    Jimmy Philps - 2015-07-10

    I am generating html files that report cyclomatic complexity. I am using the default settings, which include a reportLevel of 10.

    In my results, the method complexities abide by the restriction of only reporting those over 10, but the classes seem to report all complexities (even those as low as 3). Is there an easy workaround to this or is this something that shouldn't be happening?

     
  • Andreas Dangel

    Andreas Dangel - 2015-07-12

    Hi!
    Yes, reportLevel of 10 should only report classes that have a complexity greater than 10.

    Can you double check your ruleset file, that you did not accidentally redefine the rule and have overridden the default somewhere later in the file?
    If this is not the case, could you please narrow it down to a class and provide this as a sample/bug report? That would be great!

    Thanks,
    Andreas

     
  • Jimmy Philps

    Jimmy Philps - 2015-07-13

    Hi, thanks for getting back.

    I just quickly made a test to demonstrate this.

    Here's the java file:

    package Tests;

    public class Testing {

    public static void main(String args[]){
        new Testing();  
    }
    
    public Testing(){
        int a = 0;
        if(a == 1){
            uncommentedMethod();
        }
        if (a == 2){
            singleCommentedMethod();
        }
        if (a == 3){
            multiCommentedMethod();
        }
        if (a == 4){
            System.out.println(a);
        }
        if (a == 5){
            System.out.println(a);
        }
        if (a == 6){
            System.out.println(a);
        }
        if (a == 7){
            System.out.println(a);
        }
        if (a == 8){
            System.out.println(a);
        }
        if (a == 9){
            System.out.println(a);
        }
        if (a == 10){
            System.out.println(a);
        }
        if (a == 11){
            System.out.println(a);
        }
    }
    
    public void uncommentedMethod(){
        System.out.println("No Comments");
    }
    
    // This method has a single comment line.
    public void singleCommentedMethod(){
        System.out.println("Single Comment");
    }
    
    /*
     * This method has multiple
     * comment lines.
     */
    public void multiCommentedMethod(){
        System.out.println("Multiple Comments");
    }
    

    }

    And I run my custom ruleset against it (and use default reportLevel)

    Here is my custom ruleset:

    <ruleset name="Custom ruleset" xmlns="http://pmd.sf.net/ruleset/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd" xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">

    <description>
    This ruleset checks Cyclomatic Complexity, Excessive Method Length, and Non-commented Methods
    </description>

    <rule ref="rulesets/java/codesize.xml/CyclomaticComplexity"/>
    <rule ref="rulesets/java/codesize.xml/ExcessiveMethodLength"/>
    <rule ref="rulesets/java/comments.xml/CommentRequired">
    <properties>
    <property name="enumCommentRequirement" value="Ignored"/>
    <property name="fieldCommentRequirement" value="Ignored"/>
    <property name="headerCommentRequirement" value="Ignored"/>
    </properties>
    </rule>

    </ruleset>

    And here is the output:

    TestingPMD/src/Tests/Testing.java:3: The class 'Testing' has a Cyclomatic Complexity of 3 (Highest = 12).
    TestingPMD/src/Tests/Testing.java:5: publicMethodCommentRequirement Required
    TestingPMD/src/Tests/Testing.java:9: The constructor 'Testing' has a Cyclomatic Complexity of 12.
    TestingPMD/src/Tests/Testing.java:9: publicMethodCommentRequirement Required
    TestingPMD/src/Tests/Testing.java:46: publicMethodCommentRequirement Required
    TestingPMD/src/Tests/Testing.java:51: publicMethodCommentRequirement Required
    TestingPMD/src/Tests/Testing.java:59: publicMethodCommentRequirement Required

    So it appears that if the class contains a method with a cyclomatic complexity above 10, then even though the class's overall cyclomatic complexity is 3 it still gets reported.

     
  • Andreas Dangel

    Andreas Dangel - 2015-07-13

    Thanks for the example. I can confirm/reproduce this behavior :)

    So - looking at the code, I understand now, what "Highest = 12" means: That's the highest method/constructor in the class - this this is also taken into consideration, not only the average complexity of the class, which is in the example 3.

    I need to revise my earlier answer. It turns out, that this rule highlights these classes, that have either an average complexity > reportLevel or have at least one method/constructor with complexity > reportLevel (which is reported as "highest").

    Does this make sense?

    There are two options for this rule, see here: http://pmd.sourceforge.net/pmd-5.3.2/pmd-java/rules/java/codesize.html#CyclomaticComplexity

    However: setting showMethodsComplexity to false only removes the violation for the constructor, but the class still violations with the same message ("The class 'Testing' has a Cyclomatic Complexity of 3 (Highest = 12).").

    Would it be helpful to introduce another property, which would have the effect, that only the average class complexity is considered?

     
  • Jimmy Philps

    Jimmy Philps - 2015-07-14

    Ok that makes sense. It would be nice if there was a separate parameter for reportLevel for classes, where even if there are methods with complexities greater than ten within the class, the class complexity only gets reported if its average is greater than 10 (or whatever you set the class's report level to be).

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.