Custom java rule using ComplexityVisitor/SubscriptionVisitor

150 views
Skip to first unread message

battl...@gmx.de

unread,
Sep 8, 2015, 6:47:56 AM9/8/15
to SonarQube
Hi everyone,

currently I am trying to "fix" the "Methods should not be too complex" (squid:MethodCyclomaticComplexity) rule for Java.
In our company, we always measured Cyclomatic Complexity NOT counting exit points (cf. StackOverflow), and we want to stick to that mode while introducing SonarQube to everyone here.
I do not want to wait for SONARJAVA-75 or convince the world to change their ways, so I want to implement a custom rule providing the changed calculation.

We already have our own Sonar plugin for external reporting purposes, so it seemed to be no big deal.

My naive approach was:
1. Create a new check class similar to org.sonar.java.checks.MethodComplexityCheck, with few differences:
    • inherit from org.sonar.plugins.java.api.IssuableSubscriptionVisitor instead of org.sonar.java.checks.SubscriptionBaseVisitor
    • include inner class "FixedComplexityVisitor" extending org.sonar.java.ast.visitors.ComplexityVisitor, but removing return and throw statements from nodesToVisit()
    • inline complexity calculation call to use the "FixedComplexityVisitor"
2. Register the rule on server side (using an org.sonar.squidbridge.annotations.AnnotationBasedRulesDefinition) and batch side (using a org.sonar.plugins.java.api.CheckRegistrar like in sonar-examples).
3. Activate the rule in current quality profile.

However I stumble into runtime errors like here, here or here, because parts of the sonar-java-plugin are not part of the api available at runtime for me.

I understand that publishing exactly the right java plugin api is no easy task, so that probably still may take some time. (and that's OK, it should be done right rather than quick)

So please help me: How can I realize my variant of MethodCyclomaticComplexity now?
I hope I do not have to fall back to other plugins like CheckStyle, or re-code all non-published classes of the sonar-java-plugin.

Best regards,
Klaus Lutterjohann

Nicolas Peru

unread,
Oct 7, 2015, 3:33:58 AM10/7/15
to battl...@gmx.de, SonarQube
Hi, 

In order to help, would you mind sharing which classes in particular you are not able to actually use from your plugin ?

Cheers,

Nicolas PERU | SonarSource
Senior Developer
http://sonarsource.com


--
You received this message because you are subscribed to the Google Groups "SonarQube" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sonarqube+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/sonarqube/86ec57da-56d8-4801-9d23-a4abffd5a881%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

battl...@gmx.de

unread,
Oct 13, 2015, 11:27:18 AM10/13/15
to SonarQube, battl...@gmx.de
Hi Nicolas,

thanks for the reply!
Disclaimer: I have been away from that topic since some weeks now, so I am not perfectly familiar anymore with each of the design approaches I tried.

But I think it was org.sonar.java.model.JavaTree and maybe org.sonar.java.ast.visitors.SubscriptionVisitor, too.
In org.sonar.java.ast.visitors.SubscriptionVisitor#visitChildren (which is inherited by ComplexityVisitor) there is an explicit cast to JavaTree, and that will fail for any self-coded subclass of org.sonar.java.ast.visitors.ComplexityVisitor during tree scanning.

I ended up forking several involved classes (ComplexityVisitor and its parent SubscriptionVisitor, plus JavaTree and its runtime implementation MethodTreeImpl) to get it working.
That surely is quite "sledgehammer" style and the opposite of beautiful, but it works for now.

I would love to redesign our check if an extended API becomes available, or even better ditch it completely once org.sonar.java.checks.MethodComplexityCheck can be configured to NOT count "essential complexity statements" (return, throw, break, continue).
(I know the latter two are not counted by now, but someone suggested to include them in SONARJAVA-75)

Best regards,
Klaus Lutterjohann
Reply all
Reply to author
Forward
0 new messages