Merge branch 'pr-2111'
[java] False positive MissingStaticMethodInNonInstantiatableClass ... when inheritors are instantiable
This commit is contained in:
@ -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]
|
||||
)]
|
||||
)
|
||||
]
|
||||
]]>
|
||||
|
@ -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>
|
||||
|
Reference in New Issue
Block a user