Merge branch 'pr-2111'

[java] False positive MissingStaticMethodInNonInstantiatableClass ...
when inheritors are instantiable
This commit is contained in:
Andreas Dangel
2019-11-21 20:05:20 +01:00
3 changed files with 53 additions and 3 deletions

View File

@ -2435,20 +2435,28 @@ See the property `annotations`.
../Annotation/MarkerAnnotation/Name[pmd-java:typeIs($x)]))
)
and
(: no static methods :)
not(.//MethodDeclaration[@Static=true()])
and
(: no (public, package-private, protected) static fields :)
not(.//FieldDeclaration[@Private=false()][@Static=true()])
and
(: no nested classes, that are public and static, and have no constructors at all or a public constructor :)
(: and have a method returning the outer class type :)
(: or the inner class extends the outer class :)
not(.//ClassOrInterfaceDeclaration[@Nested=true()]
[@Public=true()]
[@Static=true()]
[not(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration) or ./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration[@Public=true()]]
[./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/MethodDeclaration
[not(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration)
or ./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration[@Public=true()]]
[(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/MethodDeclaration
[@Public=true()]
[./ResultType/Type/ReferenceType/ClassOrInterfaceType
[@Image = //ClassOrInterfaceDeclaration[@Nested=false()]/@Image]
]
]
) or (
./ExtendsList/ClassOrInterfaceType[@Image = //ClassOrInterfaceDeclaration[@Nested=false()]/@Image]
)]
)
]
]]>

View File

@ -319,5 +319,45 @@ public class Foo {
]]></code>
</test-code>
<test-code>
<description>#2102 [java] False positive MissingStaticMethodInNonInstantiatableClass when inheritors are instantiable</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public abstract class MyADT {
private MyADT() {
}
public abstract <R> R map(
Function<String, ? extends R> onString,
Function<Integer, ? extends R> onInt
);
public static final class StringHolder extends MyADT {
private final String string;
public StringHolder(String string) {
this.string = string;
}
@Override
public <R> R map(Function<String, ? extends R> onString, Function<Integer, ? extends R> onInt) {
return onString.apply(string);
}
}
public static final class IntHolder extends MyADT {
private final Integer integer;
public IntHolder(Integer integer) {
this.integer = integer;
}
@Override
public <R> R map(Function<String, ? extends R> onString, Function<Integer, ? extends R> onInt) {
return onInt.apply(integer);
}
}
}
]]></code>
</test-code>
</test-data>