Merge branch 'pr-5340'

This commit is contained in:
Juan Martín Sotuyo Dodero 2024-11-15 18:40:37 -03:00
commit e60f460e02
5 changed files with 80 additions and 3 deletions

View File

@ -27,6 +27,7 @@ This is a {{ site.pmd.release_type }} release.
* [#5329](https://github.com/pmd/pmd/issues/5329): \[java] Type inference issue with unknown method ref in call chain * [#5329](https://github.com/pmd/pmd/issues/5329): \[java] Type inference issue with unknown method ref in call chain
* java-bestpractices * java-bestpractices
* [#5083](https://github.com/pmd/pmd/issues/5083): \[java] UnusedPrivateMethod false positive when method reference has no target type * [#5083](https://github.com/pmd/pmd/issues/5083): \[java] UnusedPrivateMethod false positive when method reference has no target type
* [#5097](https://github.com/pmd/pmd/issues/5097): \[java] UnusedPrivateMethod FP with raw type missing from the classpath
* [#5318](https://github.com/pmd/pmd/issues/5318): \[java] PreserveStackTraceRule: false-positive on Pattern Matching with instanceof * [#5318](https://github.com/pmd/pmd/issues/5318): \[java] PreserveStackTraceRule: false-positive on Pattern Matching with instanceof
* java-performance * java-performance
* [#5287](https://github.com/pmd/pmd/issues/5287): \[java] TooFewBranchesForSwitch false-positive with switch using list of case constants * [#5287](https://github.com/pmd/pmd/issues/5287): \[java] TooFewBranchesForSwitch false-positive with switch using list of case constants

View File

@ -717,6 +717,12 @@ public final class TypeOps {
// no unchecked warning. // no unchecked warning.
return allArgsAreUnboundedWildcards(sargs) ? Convertibility.UNCHECKED_NO_WARNING return allArgsAreUnboundedWildcards(sargs) ? Convertibility.UNCHECKED_NO_WARNING
: Convertibility.UNCHECKED_WARNING; : Convertibility.UNCHECKED_WARNING;
} else if (sargs.isEmpty()) {
// C<T1...TN> <: |C|
// JLS 4.10.2
// unchecked conversion converts a raw type to a generic type
// subtyping converts a generic type to its raw type
return Convertibility.SUBTYPING;
} }
if (targs.size() != sargs.size()) { if (targs.size() != sargs.size()) {

View File

@ -13,14 +13,14 @@ import io.kotest.property.Exhaustive
import io.kotest.property.checkAll import io.kotest.property.checkAll
import io.kotest.property.exhaustive.ints import io.kotest.property.exhaustive.ints
import io.kotest.property.forAll import io.kotest.property.forAll
import net.sourceforge.pmd.lang.test.ast.shouldBeA
import net.sourceforge.pmd.lang.java.ast.ParserTestCtx import net.sourceforge.pmd.lang.java.ast.ParserTestCtx
import net.sourceforge.pmd.lang.java.symbols.internal.UnresolvedClassStore import net.sourceforge.pmd.lang.java.symbols.internal.UnresolvedClassStore
import net.sourceforge.pmd.lang.java.symbols.internal.asm.createUnresolvedAsmSymbol import net.sourceforge.pmd.lang.java.symbols.internal.asm.createUnresolvedAsmSymbol
import net.sourceforge.pmd.lang.java.types.TypeConversion.* import net.sourceforge.pmd.lang.java.types.TypeConversion.capture
import net.sourceforge.pmd.lang.java.types.TypeOps.Convertibility.* import net.sourceforge.pmd.lang.java.types.TypeOps.Convertibility.UNCHECKED_NO_WARNING
import net.sourceforge.pmd.lang.java.types.testdata.ComparableList import net.sourceforge.pmd.lang.java.types.testdata.ComparableList
import net.sourceforge.pmd.lang.java.types.testdata.SomeEnum import net.sourceforge.pmd.lang.java.types.testdata.SomeEnum
import net.sourceforge.pmd.lang.test.ast.shouldBeA
import kotlin.test.assertTrue import kotlin.test.assertTrue
/** /**
@ -187,6 +187,9 @@ class SubtypingTest : FunSpec({
Class shouldBeUncheckedSubtypeOf `Class{String}` Class shouldBeUncheckedSubtypeOf `Class{String}`
ts.STRING shouldBeSubtypeOf `Comparable{Wildcard}` ts.STRING shouldBeSubtypeOf `Comparable{Wildcard}`
val unresolvedT = ts.createUnresolvedAsmSymbol("foo")
unresolvedT[`?`] shouldBeSubtypeOf ts.rawType(unresolvedT)
} }
test("Test wildcard subtyping") { test("Test wildcard subtyping") {

View File

@ -704,4 +704,39 @@ class C {
buildItem.methodType.symbol shouldBe buildItemDecl buildItem.methodType.symbol shouldBe buildItemDecl
} }
} }
parserTest("Unresolved type should also allow unchecked conversion") {
// The problem here is that ConstraintViolation<?> is not convertible to ConstraintViolation,
// because ConstraintViolation is not on the classpath.
val (acu, _) = parser.parseWithTypeInferenceSpy(
"""
import java.util.Set;
class Foo {
private void foo(ConstraintViolation constraintViolation) {
constraintViolation.toString();
}
public void foos(Set<ConstraintViolation<?>> constraintViolations) {
constraintViolations.forEach(this::foo);
}
}
"""
)
// val (foreach) = acu.methodCalls().toList()
val constraintViolationT = acu.descendants(ASTClassType::class.java)
.filter { it.simpleName == "ConstraintViolation" }
.firstOrThrow().typeMirror.symbol as JClassSymbol
val (fooDecl) = acu.methodDeclarations().toList { it.symbol }
val (mref) = acu.descendants(ASTMethodReference::class.java).toList()
acu.withTypeDsl {
mref.referencedMethod.symbol shouldBe fooDecl
mref shouldHaveType java.util.function.Consumer::class[constraintViolationT[`?`]]
}
}
}) })

View File

@ -2218,6 +2218,38 @@ public class ObtainViaTest {
} }
]]></code> ]]></code>
</test-code> </test-code>
<test-code>
<description>#5097 UnusedPrivateMethod with unresolved target for method reference</description>
<expected-problems>0</expected-problems>
<code><![CDATA[package com.mytest;
import jakarta.validation.ConstraintViolation; //imported from jakarta.validation:jakarta.validation-api:3.0.2
import java.util.List;
import java.util.Set;
public class UnusedPrivateMethodFalsePositive {
//this does not trigger UnusedPrivateMethod
private void doWork(List obj) {
obj.toString();
}
public void execute(Set<List<?>> listOfLists) {
listOfLists.forEach(this::doWork);
}
//BUT this does???
//UnusedPrivateMethod - this as a false positive - but what is different?
private void addValidationError(ConstraintViolation constraintViolation) {
constraintViolation.toString();
}
public void addValidationErrors(Set<ConstraintViolation<?>> constraintViolations) {
constraintViolations.forEach(this::addValidationError);
}
}
]]></code>
</test-code>
<test-code> <test-code>
<description>UnusedPrivateMethod #5113</description> <description>UnusedPrivateMethod #5113</description>