Merge branch 'pr-5035'

This commit is contained in:
Juan Martín Sotuyo Dodero
2024-05-23 09:47:04 -03:00
3 changed files with 31 additions and 8 deletions

View File

@ -36,6 +36,7 @@ Since this release, PMD will also expose any getter returning a collection of an
* [#4988](https://github.com/pmd/pmd/pull/4988): \[java] Fix impl of ASTVariableId::isResourceDeclaration / VariableId/@<!-- -->ResourceDeclaration
* [#4990](https://github.com/pmd/pmd/issues/4990): \[java] Add an attribute @<!-- -->PackageQualifier to ASTClassType
* [#5006](https://github.com/pmd/pmd/issues/5006): \[java] Bad intersection, unrelated class types Child and Parent<? extends Child>
* [#5029](https://github.com/pmd/pmd/issues/5029): \[java] PMD 7.x throws stack overflow in TypeOps$ProjectionVisitor while parsing a Java class
* java-bestpractices
* [#4278](https://github.com/pmd/pmd/issues/4278): \[java] UnusedPrivateMethod FP with Junit 5 @MethodSource and default factory method name
* [#4852](https://github.com/pmd/pmd/issues/4852): \[java] ReplaceVectorWithList false-positive (neither Vector nor List usage)

View File

@ -1091,14 +1091,10 @@ public final class TypeOps {
<T extends JTypeMirror> JTypeMirror recurseIfNotDone(T t, BiFunction<T, RecursionStop, JTypeMirror> body) {
if (t instanceof JTypeVar) {
JTypeVar var = (JTypeVar) t;
try {
if (isAbsent(var)) {
return body.apply(t, this);
} else {
return t;
}
} finally {
set.remove(var);
if (isAbsent(var)) {
return body.apply(t, this);
} else {
return t;
}
} else {
return body.apply(t, this);

View File

@ -69,6 +69,32 @@ class TypeOpsTest : FunSpec({
output = listOf(`t_List{String}`, `t_List{Integer}`))
}
test("Bug #5029: Recursive type projection") {
val (acu, spy) = javaParser.parseWithTypeInferenceSpy(
"""
class Job<J extends Job<J, R>, R extends Run<J, R>> {
J getLast() { return null; }
}
class Run<J extends Job<J, R>, R extends Run<J, R>> {}
class Foo {
static Job<?, ?> foo(Job<?,?> job) {
var x = job.getLast();
return x;
}
}
""".trimIndent()
)
val (jobt, runt) = acu.declaredTypeSignatures()
val xVar = acu.varId("x")
spy.shouldBeOk {
xVar shouldHaveType jobt[`?` extends jobt[`?`, `?` extends runt[`?`, `?`]], `?`]
}
}
}
}