Java: Detect spurious param Javadoc tag of generic classes

This commit is contained in:
Marcono1234
2021-09-09 00:11:02 +02:00
parent 5d58edb3b9
commit a173d9593b
5 changed files with 50 additions and 13 deletions

View File

@@ -39,6 +39,12 @@ public void html(int ordinate){ ... }
*/
public <T> void parameterized(T parameter){ ... }
/**
* BAD: The following param tag refers to a non-existent type parameter.
*
* @param <X> The type of the elements.
*/
class Generic<T> { ...}
/**
* GOOD: A proper Javadoc comment.

View File

@@ -6,15 +6,15 @@
<overview>
<p>
Javadoc comments for public methods and constructors should use the <code>@param</code> tag to describe the available
parameters. If the comment includes any empty, incorrect or outdated parameter names then this will make
Javadoc comments for public methods, constructors and generic classes should use the <code>@param</code> tag to describe the available
parameters and type parameters. If the comment includes any empty, incorrect or outdated parameter names then this will make
the documentation more difficult to read.
</p>
</overview>
<recommendation>
<p>The Javadoc comment for a method or constructor should always use non-empty <code>@param</code> values that match actual parameter or type parameter names.</p>
<p>The Javadoc comment for a method, constructor or generic class should always use non-empty <code>@param</code> values that match actual parameter or type parameter names.</p>
</recommendation>
<example>

View File

@@ -1,6 +1,7 @@
/**
* @name Spurious Javadoc @param tags
* @description Javadoc @param tags that do not match any parameters in the method or constructor are confusing.
* @description Javadoc @param tags that do not match any parameters in the method or constructor or
* any type parameters of the annotated class are confusing.
* @kind problem
* @problem.severity recommendation
* @precision very-high
@@ -10,21 +11,33 @@
import java
from Callable callable, ParamTag paramTag, string what, string msg
from Documentable documentable, ParamTag paramTag, string msg
where
callable.(Documentable).getJavadoc().getAChild() = paramTag and
(if callable instanceof Constructor then what = "constructor" else what = "method") and
documentable.getJavadoc().getAChild() = paramTag and
if exists(paramTag.getParamName())
then
// The tag's value is neither matched by a callable parameter name ...
not callable.getAParameter().getName() = paramTag.getParamName() and
// ... nor by a type parameter name.
not exists(TypeVariable tv | tv.getGenericCallable() = callable |
documentable instanceof Callable and
exists(string what |
if documentable instanceof Constructor then what = "constructor" else what = "method"
|
// The tag's value is neither matched by a callable parameter name ...
not documentable.(Callable).getAParameter().getName() = paramTag.getParamName() and
// ... nor by a type parameter name.
not exists(TypeVariable tv | tv.getGenericCallable() = documentable |
"<" + tv.getName() + ">" = paramTag.getParamName()
) and
msg =
"@param tag \"" + paramTag.getParamName() + "\" does not match any actual parameter of " +
what + " \"" + documentable.getName() + "()\"."
)
or
documentable instanceof ClassOrInterface and
not exists(TypeVariable tv | tv.getGenericType() = documentable |
"<" + tv.getName() + ">" = paramTag.getParamName()
) and
msg =
"@param tag \"" + paramTag.getParamName() + "\" does not match any actual parameter of " +
what + " \"" + callable.getName() + "()\"."
"@param tag \"" + paramTag.getParamName() +
"\" does not match any actual type parameter of type \"" + documentable.getName() + "\"."
else
// The tag has no value at all.
msg = "This @param tag does not have a value."

View File

@@ -105,4 +105,18 @@ public class Test<V> {
*/
SomeClass(int i, int j) {}
}
/**
* @param <T> exists
* @param T wrong syntax
* @param <X> does not exist
*/
class GenericClass<T> {}
/**
* @param <T> exists
* @param T wrong syntax
* @param <X> does not exist
*/
interface GenericInterface<T> {}
}

View File

@@ -8,3 +8,7 @@
| Test.java:91:6:91:12 | @param | This @param tag does not have a value. |
| Test.java:97:6:97:12 | @param | This @param tag does not have a value. |
| Test.java:104:8:104:14 | @param | @param tag "k" does not match any actual parameter of constructor "SomeClass()". |
| Test.java:111:6:111:12 | @param | @param tag "T" does not match any actual type parameter of type "GenericClass". |
| Test.java:112:6:112:12 | @param | @param tag "<X>" does not match any actual type parameter of type "GenericClass". |
| Test.java:118:6:118:12 | @param | @param tag "T" does not match any actual type parameter of type "GenericInterface". |
| Test.java:119:6:119:12 | @param | @param tag "<X>" does not match any actual type parameter of type "GenericInterface". |