Since CodeNarc 0.12
It is unnecessary to instantiate BigDecimal objects. Instead just use the decimal literal or the 'G' identifier to force the type, such as 123.45 or 123.45G.
Since CodeNarc 0.12
It is unnecessary to instantiate BigInteger objects. Instead just use the literal with the 'G' identifier to force the type, such as 8G or 42G.
Checks for unnecessary boolean expressions, including ANDing (&&) or ORing (||) with true, false, null, or a Map/List/String/Number literal.
This rule also checks for negation (!) of true, false, null, or a Map/List/String/Number literal.
Examples of violations include:
result = value && true // AND or OR with boolean constants if (false || value) { .. } return value && Boolean.FALSE result = null && value // AND or OR with null result = value && "abc" // AND or OR with String literal result = value && 123 // AND or OR with Number literal result = 678.123 || true result = value && [x, y] // AND or OR with List literal result = [a:123] && value // AND or OR with Map literal result = !true // Negation of boolean constants result = !false result = !Boolean.TRUE result = !null // Negation of null result = !"abc" // Negation of String literal result = ![a:123] // Negation of Map literal result = ![a,b] // Negation of List literal
Since CodeNarc 0.12 (formerly BooleanInstantiation Rule in the "basic" rule set)
Checks for direct call to a Boolean constructor. Use Boolean.valueOf() or the Boolean.TRUE and Boolean.FALSE constants instead of calling the Boolean() constructor directly.
Also checks for Boolean.valueOf(true) or Boolean.valueOf(false). Use the Boolean.TRUE or Boolean.FALSE constants instead.
Here is an example of code that produces a violation:
def b1 = new Boolean(true) // violation def b2 = new java.lang.Boolean(false) // violation def b3 = Boolean.valueOf(true) // violation def b4 = Boolean.valueOf(false) // violation
Since CodeNarc 0.12
This rule checks for excessively verbose methods of accessing the last element of an array or list. For instance, it is possible to access the last element of an array by performing array[array.length - 1], in Groovy it is simpler to either call array.last() or array[-1]. The same is true for lists. This violation is triggered whenever a get, getAt, or array-style access is used with an object size check.
Code like this all cause violations.
def x = [0, 1, 2] def a = x.get(x.size() -1) def b = x.get(x.length -1) def c = x.getAt(x.size() -1) def d = x.getAt(x.length -1) def f = x[(x.size() -1] def d = x[(x.length -1]
All of this code is fine though:
def x = [0, 1, 2] def a = x.last() def b = x[-1] def c = x.getAt(-1) def d = x.get(z.size() -1) // different objects def e = x.get(z.length -1) // different objects def f = x.getAt(z.size() -1) // different objects
New in CodeNarc 0.13
Calling String.substring(0) always returns the original string. This code is meaningless.
Examples:
string.substring(0) // violation method().substring(0) // violation prop.substring(1) // OK, not constant 0 prop.substring(0, 1) // OK, end is specified
Since CodeNarc 0.12
Violations are triggered when a catch block does nothing but throw the original exception. In this scenario there is usually no need for a catch block, just let the exception be thrown from the original code. This condition frequently occurs when catching an exception for debugging purposes but then forgetting to take the catch statement out.
Since CodeNarc 0.12
Some method calls to Object.collect(Closure) can be replaced with the spread operator. For instance, list.collect it.multiply(2) can be replaced by list*.multiply(2).
Examples of violations include:
assert [1, 2, 3].collect { it.multiply(2) } assert [1, 2, 3].collect { x -> x.multiply(2) } ["1", "2", "3"].collect { it.bytes }
The following code does not produce violations:
[1, 2, 3].collect { it * it } // OK, closure parameter is referenced twice [1, 2, 3].mapMethod { it.multiply(5) } // OK, method call is not collect [1, 2, 3].collect(5) // OK, collect parameter is not a closure // OK, the closure is not a simple one line statement [1, 2, 3].collect { println it; it.multiply(5) } // OK, closure has too many arguments [1, 2, 3].collect { a, b -> a.multiply(b) } // OK, closure statement references parameter multiple times [1, 2, 3].collect { it.multiply(it) } // OK, it is referenced several times in the closure [1, 2, 3].collect { it.multiply(2).multiply(it) } ["1", "2", "3"].collect { it.bytes.foo(it) } // OK, chained methods are too complex to analyze at this point [1, 2, 3].collect { it.multiply(2).multiply(4) } // in general the above examples can be rewritten like this: [1, 2, 3]*.multiply(2) ["1", "2", "3"]*.bytes
Since CodeNarc 0.11
Checks for useless calls to collections. For any collection c, calling c.containsAll(c) should always be true, and c.retainAll(c) should have no effect.
Since CodeNarc 0.11
This rule detects when a constructor is not necessary; i.e., when there's only one constructor, it's public, has an empty body, and takes no arguments.
New in CodeNarc 0.13 If a method has a visibility modifier, then the def keyword is unneeded. For instance 'def private method() ' is redundant and can be simplified to 'private method() '.
Example of violations:
// private and def are not needed def private method1() { return 4 } // def and protected unneeded def protected method2() { return 4 } // def and protected unneeded def public method3() { return 4 } // static and def are not needed def static method4() { return 4 } // static and def are not needed def Object method5() { return 4 }
Since CodeNarc 0.12
It is unnecessary to instantiate Double objects. Instead just use the double literal with 'D' identifier to force the type, such as 123.45d or 0.42d.
Since CodeNarc 0.12
It is unnecessary to instantiate Float objects. Instead just use the float literal with the 'F' identifier to force the type, such as 123.45F or 0.42f.
Since CodeNarc 0.12
Checks for explicit calls to getter/accessor methods which can, for the most part, be replaced by property access. A getter is defined as a method call that matches get[A-Z] but not getClass() or get[A-Z][A-Z] such as getURL(). Getters do not take method arguments.
These bits of code produce violations:
x.getProperty() x.getFirst() x.getFirstName() x.getA()
These bits of code do not:
x.property x.first x.firstName x.a x.getURL() x.getClass() x.getProperty('key')
New in CodeNarc 0.13
String objects should be created with single quotes, and GString objects created with double quotes. Creating normal String objects with double quotes is confusing to readers.
Example of violations:
def a = "I am a string" // violation // violation def b = """ I am a string """ def c = "I am a ' string" // OK def d = """I am a ' string""" // OK def e = """I am a ' string""" // OK def f = "I am a \$ string" // OK // OK def g = """ I am a \$ string """ // OK def h = """ I am a $string """ def i = 'i am a string' def j = '''i am a string '''
Checks for unnecessary if statements. The entire if statement, or at least the if or else block, are considered unnecessary for the three scenarios described below.
(1) When the if and else blocks contain only an explicit return of true and false constants. These cases can be replaced by a simple return statement. Examples of violations include:
if (someExpression) // can be replaced by: return someExpression return true else return false if (someExpression) { // can be replaced by: return someExpression return true } else { return false } if (someExpression) { // can be replaced by: return someExpression return Boolean.TRUE } else { return Boolean.FALSE }
(2) When the if statement is the last statement in a block and the if and else blocks are only true and false expressions. This is an implicit return of true/false. For example, the if statement in the following code can be replaced by someExpression or someExpression as boolean:
def myMethod() { doSomething() if (someExpression) true else false }
(3) When either the if block or else block of an if statement that is not the last statement in a block contain only a single constant or literal expression. For example, the if statement in the following code has no effect and can be removed:
def myMethod() { if (someExpression) { 123 } doSomething() }
Since in CodeNarc 0.12
Avoid instantiating an object just to call getClass() on it; use the .class public member instead.
public class Foo { // Replace this Class c = new String().getClass(); // with this: Class c = String.class; }
Since CodeNarc 0.12
It is unnecessary to instantiate Integer objects. Instead just use the literal with the 'I' identifier to force the type, such as 8I or 42i.
Since CodeNarc 0.12
It is unnecessary to instantiate Long objects. Instead just use the literal with the 'L' identifier to force the type, such as 8L or 42L.
New in CodeNarc 0.13
Any expression mod 1 (exp % 1) is guaranteed to always return zero. This code is probably an error, and should be either (exp & 1) or (exp % 2).
Examples: ------------------------------------------------------------------------------- if (exp % 1) // violation if (method() % 1) // violation
if (exp & 1) // ok if (exp % 2) // ok -------------------------------------------------------------------------------
Since CodeNarc 0.12
Violations are triggered when an excessive set of consecutive statements all reference the same variable. This can be made more readable by using a with or identity block. By default, 5 references are allowed. You can override this property using the maxReferencesAllowed> property on the rule.
These two bits of code produce violations:
def p1 = new Person() p1.firstName = 'Hamlet' p1.lastName = "D'Arcy" p1.employer = 'Canoo' p1.street = 'Kirschgaraten 5' p1.city = 'Basel' p1.zipCode = '4051' def p2 = new Person() p2.setFirstName('Hamlet') p2.setLastName("D'Arcy") p2.setEmployer('Canoo') p2.setStreet('Kirschgaraten 5') p2.setCity('Basel') p2.setZipCode('4051')
However, these two bits of code do not because they use either a with or identity block.
def p1 = new Person().with { firstName = 'Hamlet' lastName = "D'Arcy" employer = 'Canoo' street = 'Kirschgaraten 5' city = 'Basel' zipCode = '4051' } def p2 = new Person().identity { firstName = 'Hamlet' lastName = "D'Arcy" employer = 'Canoo' street = 'Kirschgaraten 5' city = 'Basel' zipCode = '4051' }
Since CodeNarc 0.12
Groovy contains the safe dereference operator. It can be used in boolean conditional statements to safely replace explicit x == null tests.
Examples of violations:
if (obj != null && obj.method()) { } if (obj != null && obj.prop) { } // this is pointless and won't avoid NullPointerException if (obj.method() && obj != null ) { }
Examples of acceptable code:
// null check it OK if (obj != null) { } // null safe dereference in if is OK if (obj?.method()) { } // null safe dereference in ternary is OK (obj?.prop && obj?.prop2) ? x : y // obj is reused in a parameter list, so OK if (obj != null && obj.method() && isValid(obj)) { } // rule is not so complex yet... (obj != null && obj.prop && obj.method()) ? x : y
Since CodeNarc 0.12
There is no need to check for null before an instanceof; the instanceof keyword returns false when given a null argument.
Example:
if (x != null && x instanceof MyClass) { // should drop the "x != null" check } if (x instanceof MyClass && x != null) { // should drop the "x != null" check } // should drop the "x != null" check (x != null && x instanceof MyClass) ? foo : bar if (x != null && x instanceof MyClass && x.isValid()) { // this is OK and causes no violation because the x.isValid() requires a non null reference }
Since CodeNarc 0.11
Checks for an overriding method that merely calls the same method defined in a superclass. Remove it.
New in CodeNarc 0.13
The 'public' modifier is not required on methods or classes.
Example of violations:
// violation on class public class MyClass { // violation on method public void myMethod() {} }
Since CodeNarc 0.11
In Groovy, the return keyword is often optional. If a statement is the last line in a method or closure then you do not need to have the return keyword.
New in CodeNarc 0.13
Method contains a pointless self-assignment to a variable or property. Either the code is pointless or the equals()/get() method has been overridden to have a side effect, which is a terrible way to code getters and violates the contract of equals().
Examples:
x = x // violation def method(y) { y = y // violation } a.b.c = a.b.c // violation x = y // acceptable a.b = a.zz // acceptable a.b = a().b // acceptable
New in CodeNarc 0.13
Semicolons as line terminators are not required in Groovy: remove them. Do not use a semicolon as a replacement for empty braces on for and while loops; this is a confusing practice.
The rule contains a String property called 'excludePattern'. Any source code line matching this pattern will not trigger a violation. The default value is '\s?\*.*|/\*.*|.*//.*|.*\*/.*' This is to filter out comments. Any source line that even looks like it is a comment is ignored.
\s?*.* == whitespace plus star character plus anything /*.* == any line that contains the /* sequence .*//.* == any line that contains the // sequence .**/.* == any line that contains the */ sequence
Example of violations:
package my.company.server; // violation import java.lang.String; // violation println(value) ; // violation for (def x : list); // violation // this code is OK println(value); println (otherValue)
Since CodeNarc 0.12 (formerly StringInstantiation Rule in the "basic" rule set)
Checks for direct call to the String constructor that accepts a String literal. In almost all cases, this is unnecessary. Use a String literal (e.g., "...") instead of calling the corresponding String constructor (new String("..")) directly.
Here is an example of code that produces a violation:
def s = new String('abc')
Checks for ternary expressions where the conditional expression always evaluates to a boolean and the true and false expressions are merely returning true and false constants. These cases can be replaced by a simple boolean expression. Examples of violations include:
x==99 ? true : false // can be replaced by: x==99 x && y ? true : false // can be replaced by: x && y x||y ? false : true // can be replaced by: !(x||y) x >= 1 ? true: false // can be replaced by: x >= 1 x < 99 ? Boolean.TRUE : Boolean.FALSE // can be replaced by: x < 99 !x ? true : false // can be replaced by: !x
The rule also checks for ternary expressions where the true and false expressions are the same constant or variable. Examples include:
x ? '123' : '123' // can be replaced by: '123' x ? null : null // can be replaced by: null x ? 23 : 23 // can be replaced by: 23 x ? MAX_VALUE : MAX_VALUE // can be replaced by: MAX_VALUE ready ? minValue : minValue // can be replaced by: minValue
New in CodeNarc 0.13
The field is marked as transient, but the class isn't Serializable, so marking it as transient has no effect. This may be leftover marking from a previous version of the code in which the class was transient, or it may indicate a misunderstanding of how serialization works.
Some Java frameworks change the semantics of the transient keyword. For instance, when using Terracotta the transient keyword may have slightly different semantics. You may need to turn this rule off depending on which Java frameworks are in use.
Examples:
class MyClass { // class not serializable, violation occurs transient String property } class MySerializableClass implements Serializable { // OK, class is serializable transient String property }