Monday, November 22, 2010

Groovy CodeNarc 0.11 Unofficial Guide


Groovy CodeNarc is a static analysis tool for the Groovy language and does for Groovy what PMD and FindBugs does for Java: it analyses Groovy code for defects, mistakes, and bad practices. The new version 0.11 is a huge release for us. We’ve added over 50 new rules to the product (bringing the total to 130+ rules) and a few really great features. This is THE new look CodeNarc, and it’s ready to use today in beta form using the CodeNarc Web Console with the release coming by Monday, and we’ll be updating the Grails, Gradle, and Griffon plugins shortly. This post explains a few of my favorite new rules and features, and explains how you can help out. You can play with all the new rules today in the CodeNarc Web Console, so if you find any rule misses, false positives, or just new ideas then save the script and drop us an email! So here is my list:


@SuppressWarnings Support

All rules now recognize the java.lang.SuppressWarnings annotation on fields, methods, and classes. If this annotation is added then there will be no violations produced. This is great for the times when you really do want to ignore a rule or in the rare case where you find a false positive. Just as in Java, the annotation requires a String or List parameter. For example, annotating a class with @SuppressWarnings(‘UnusedPrivateField’) will ignore the rule for that class. Annotating a method with @SuppressWarnings(['UnusedPrivateField', 'UnnecessaryIfStatementRule']) will ignore both rules for the annotated method.


New Rules: Should use Operator not Method Call

Groovy supports Operator Overloading. “a.plus(b)” should be written as “a + b”. Likewise “a.minus(b)” should be “a – b”. Every single operator overloading in Groovy is supported: And, or, CompareTo, GetAt, etc., etc. This is great for newcomers (and old-timers) who often revert back to the Java way of doing things without realizing it. Check out these rules in the basic ruleset of the CodeNarc docs for more information: ExplicitCallToAndMethod, ExplicitCallToCompareToMethod, ExplicitCallToDivMethod, ExplicitCallToEqualsMethod, ExplicitCallToGetAtMethod, ExplicitCallToLeftShiftMethod, ExplicitCallToMinusMethod, ExplicitCallToMultiplyMethod, ExplicitCallToModMethod, ExplicitCallToOrMethod, ExplicitCallToPlusMethod, ExplicitCallToPowerMethod, ExplicitCallToRightShiftMethod, and ExplicitCallToXorMethod,


New Rules: Explicit Creation of Collection Types

We all know the “[]” is an ArrayList and “[:]” is a HashMap. Do you know the syntax for Sets, HashSets, LinkedList, Stack, and TreeSet as well? CodeNarc does, and will tell you when you explicitly create an object of this type instead of using the Groovy shorthand. You’d be surprised how often it catches you out. Check out these rules in the basic ruleset of the CodeNarc docs for more information: ExplicitCreationOfArrayList, ExplicitCreationOfHashMap, ExplicitCreationOfHashSet, ExplicitCreationOfLinkedList, ExplicitCreationOfStack, and ExplicitCreationOfTreeSet


New Rules: Null Safety

Null stinks, don’t use it. Easier said then done and hand-rolling an option type will raise the eyebrow of even the most hardened Scalar. So here are some rules: if your method returns a collection or map, then never return null. Return an empty collection instead. It makes the calling code a lot prettier to not worry about the null checks. Likewise, don’t return null from Boolean methods or CatchBlocks. They are accidents waiting to happen. The cool thing about these rules is that they analyze methods and closures to infer return types. It doesn’t just look at the method signatures it discovers the return type using type inference. We’re trying to make this more powerful and have even swapped some ideas with the groovy++ guys to see what we can share. In the meantime, check out these rules: BooleanMethodReturnsNull, ReturnsNullInsteadOfEmptyArray, ReturnsNullInsteadOfEmptyCollection, and ReturnNullFromCatchBlock


New Rules: Useless Constructs and Dead Code

Code can appear after a return or throw statement, but you should probably delete it. The Dead Code Rule helps you here. But many other things are pointless as well, such as double negatives in boolean expressions (DoubleNegative Rule), supplying a default constructor as your only constructor (UnnecessaryConstructor Rule), various useless calls on collections like “x.containsAll(x)” (UselessCollectionCall Rule), overriding a method only to call super() as your single line implementation (UselessOverridingMethod Rule), and return keywords in general (UnnecessaryReturnKeyword Rule).


New Rules: JUnit Clarity Rules

xUnit Patterns is a great book, but who has time to read the 800 page tome? No worries, we mined the text for good Junit rules. Don’t bother reading, just configure CodeNarc to do the learning for you. The UseAssertEqualsInsteadOfAssertTrue makes sure you use assertEquals instead of assertTrue with an explicit .equals() invocation, and UseAssertTrueInsteadOfAssertEqualsRule does the opposite: use assertTrue instead of assertEquals(true, …). You can guess what the rules UseAssertNullInsteadOfAssertEquals and UseAssertSameInsteadOfAssertTrue do. Also, using the fail() method instead of fail(String) obscures test failures. UseFailWithMessageInsteadOfWithout makes sure you don’t use it. Lastly, you may want to abandon JUnit entirely and use Groovy Power Asserts. We have you covered with JUnitStyleAssertions.


New Rules: Naming and Inheritance Problems

Some simple rules… don’t name a class Exception if it doesn’t extend Exception (ConfusingClassNamedException Rule). Don’t name fields, methods, or closures with names that differ only in capitalization (ConfusingMethodName Rule), and make sure that methods subclassed off Object are spelled correctly (ObjectOverrideMisspelledMethodName Rule).


And many other rules:

OK, I don’t want to leave any out, so here are the other rules included in the release:

The DuplicateCaseStatement Rule check for duplicate case statements in a switch block, such as two equal integers or strings. The GStringAsMapKey Rule checks that GString are not used as a map key since its hashcode is not guaranteed to be stable. The InvertedIfElse Rule checks for an inverted if-else statement, which is where there is a single if statement with a single else branch and the boolean test of the if is negated. The SerialVersionUID Rule checks for a serialVersionUID field that is not long, static, and final. The RemoveAllOnSelf Rule checks that you don’t use removeAll to clear a collection which is unsafe.


The SynchronizedOnGetClass checks for synchronization on getClass() rather than class literal which is again unsafe. The UseOfNotifyMethod Rule Checks for code that calls notify() rather than notifyAll() which is also usually unsafe. And the CatchIllegalMonitorStateException Rule checks for catching IllegalMonitorStateException which is usually a sign of faulty multithreading and interruption logic.


The last few are MethodCount Rule which checks if the number of methods within a class exceeds the maximum (configurable), the DuplicateNumberLiteral Rule which checks for duplicate number literals within the current class, and the DuplicateStringLiteral Rule which checks for duplicate String literals within the current class.


If you turn on all of these rules I am sure you will have hundreds if not thousands of violations. That’s a good thing!


How to Help

Yes, we need your help. We want 50 more rules for the next release. Here’s some ideas to help for those without much time.

Got 2 Seconds? – Vote for the IntelliJ IDEA feature request to support CodeNarc in the IDE.

Got 1 Minute? – When you find a false positive then head to our Bug Tracker and enter a ticket.

Got 2 Minutes? – In your next code review write down one of the problems you found and the correct fix. Email it to me at hamletdrc@gmail.com or just save the script in the CodeNarc Web Console. I’ll create a rule for it. Could be a bug, an idiom, or just a preference.

Got 5 Minutes? – Take the issue from your code review and brainstorm some edge cases. Then head to our Bug Tracker and enter a ticket.

Got an Hour? – Write a rule. It’s simple and automated. Checkout the source, do a “mvn clean install” from the root, and run “groovy codenarc.groovy create-rule”. You’ll be prompted for input and the script creates everything you need, including failing unit tests. If you need help email the mailing lists.

Got Photoshop Skills? – Can you please make us a new logo? Pretty please?


Now go download those bits, run the reports, and see what you learn!