Fix mostSpecific

This commit is contained in:
Clément Fournier
2024-04-05 16:18:08 +02:00
parent 6f1f72de1e
commit 89f7aecab8
2 changed files with 34 additions and 5 deletions

View File

@ -580,6 +580,11 @@ public final class TypeOps {
return this == UNCHECKED_WARNING;
}
/** True if this is {@link #SUBTYPING} or {@link #UNCHECKED_NO_WARNING}. */
public boolean withoutWarnings() {
return this == SUBTYPING || this == UNCHECKED_NO_WARNING;
}
// package:
@ -1739,7 +1744,7 @@ public final class TypeOps {
// This last case covers unchecked conversion. It is made antisymmetric by the
// test for a symbol. eg |G| <~> G<?> so it would fail.
// However, |G| ~> S if |G| <: |S|, so we should consider |G| more specific than S.
|| isConvertible.somehow() && !Objects.equals(w.getSymbol(), v.getSymbol())) {
|| isConvertible.withoutWarnings() && !Objects.equals(w.getSymbol(), v.getSymbol())) {
continue vLoop;
}
}

View File

@ -7,6 +7,7 @@ package net.sourceforge.pmd.lang.java.types
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.collections.shouldContainExactly
import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder
import io.kotest.matchers.nulls.shouldBeNull
import io.kotest.matchers.shouldBe
import io.kotest.property.checkAll
@ -115,8 +116,23 @@ class GlbTest : FunSpec({
}
}
test("test corner case") {
TypeOps.mostSpecific(
setOf(
t_Collection[`?` extends t_Number],
`t_List{?}`,
t_List
)
) shouldBe setOf(t_Collection[`?` extends t_Number], `t_List{?}`)
}
test("Test GLB corner cases") {
// note: intersections are not minimized, or reduced to the null type if they are unsatisfiable.
// note also that in this test we test the components explicitly instead of using the DSL,
// because the DSL operator to create intersections actually calls GLB.
glb(t_Iterable[`?` extends t_Number], t_Iterable[t_String]).shouldBeA<JIntersectionType> {
it.components.shouldContainExactly(t_Iterable[`?` extends t_Number], t_Iterable[t_String])
}
@ -138,13 +154,21 @@ class GlbTest : FunSpec({
it.components.shouldContainExactly(`t_Enum{JPrimitiveType}`, `t_List{? extends Number}`, `t_List{String}`)
}
glb(t_Collection[`?` extends t_Number],
glb(
t_Collection[`?` extends t_Number],
`t_List{?}`,
t_List) shouldBe `t_List{?}` // todo check that
t_List
).shouldBeA<JIntersectionType> {
it.components.shouldContainExactlyInAnyOrder(t_Collection[`?` extends t_Number], `t_List{?}`)
}
glb(t_List, `t_List{?}`) shouldBe `t_List{?}`
glb(t_Collection[`?` extends t_Number], `t_List{?}`) shouldBe `t_List{?}`
glb(
t_Collection[`?` extends t_Number],
`t_List{?}`
).shouldBeA<JIntersectionType> {
it.components.shouldContainExactlyInAnyOrder(t_Collection[`?` extends t_Number], `t_List{?}`)
}
}