I'm looking for a good tool or technique to search a Java code base and find every method that says it returns a collection (List, Set, Map, etc.) but sometimes returns null. This would be a cool IntelliJ IDEA inspection and could work without annotating @NotNull.
1 Answer
This involves a bit of work with pmd, but I believe that this is a valid case for writing a custom rule.
The way that custom rules in pmd work are to "compile" the Java code into the xml version of the abstract symbol tree and then run xpath queries against it.
To get an idea of the structure, the non-tag xml looks something like:
class Example {
void bar() {
while (baz)
buz.doSomething();
}
}
gets 'compiled' to:
CompilationUnit
TypeDeclaration
ClassDeclaration:(package private)
UnmodifiedClassDeclaration(Example)
ClassBody
ClassBodyDeclaration
MethodDeclaration:(package private)
ResultType
MethodDeclarator(bar)
FormalParameters
Block
BlockStatement
Statement
WhileStatement
Expression
PrimaryExpression
PrimaryPrefix
Name:baz
Statement
StatementExpression:null
PrimaryExpression
PrimaryPrefix
Name:buz.doSomething
PrimarySuffix
Arguments
For example: //WhileStatement[not(Statement/Block)] will identify while statements that are not followed by a statement or a block with statements - an empty block.
While it would take a bit more digging into the specifics, it should be possible to write the appropriate xpath query to identify a method deceleration where the type is something and that it has a return statement nested under it that returns a null. Writing one that flags any return null; should be trivial (a starting point to refine for the rule). I have written a pmd rule in the past (don't have it with me anymore) that identified static SimpleDateFormat ... decelerations which could cause problems as SimpleDateFormat isn't thread safe).
If the xpath isn't powerful enough to identify the specific rule, its possible to write a class that gets plugged into pmd that will get the AST and any transformations can be done on that to identify problems. This is a bit more difficult to plug into pmd though (compared to a xpath rule).
@NotNull... oh, wait.