From 9602343b0bd421395f63b085c9817a7ee779fe84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 26 Jul 2022 16:39:31 +0200 Subject: [PATCH] [java] improve test coverage a bit --- .../pmd/lang/java/types/MapFunction.java | 2 + .../pmd/lang/java/types/SubstTest.kt | 18 ++++ .../internal/infer/OverloadSpecificityTest.kt | 84 +++++++++++++++++-- 3 files changed, 95 insertions(+), 9 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/MapFunction.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/MapFunction.java index cd85884be7..6819a7ccc1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/MapFunction.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/MapFunction.java @@ -5,6 +5,7 @@ package net.sourceforge.pmd.lang.java.types; +import java.util.Comparator; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; @@ -32,6 +33,7 @@ abstract class MapFunction implements Function { @Override public String toString() { return map.entrySet().stream() + .sorted(Comparator.comparing(e -> e.getKey().toString())) .map(it -> it.getKey() + " => " + it.getValue()) .collect(Collectors.joining("; ", getClass().getSimpleName() + "[", "]")); } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubstTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubstTest.kt index e35cf01251..d41de8f08a 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubstTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubstTest.kt @@ -112,6 +112,24 @@ class SubstTest : ProcessorTestSpec({ } + parserTest("Test subst toString") { + + + val (a, b, c) = makeDummyTVars("A", "B", "C") + + with(TypeDslOf(a.typeSystem)) { + val `t_Iter{B}` = Iterable::class[b] + val `t_Coll{C}` = Collection::class[c] + + + val sub1 = subOf(a to `t_Iter{B}`, b to `t_Coll{C}`) + + sub1.toString() shouldBe "Substitution[A => java.lang.Iterable; B => java.util.Collection]" + } + + + } + }) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSpecificityTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSpecificityTest.kt index d94a518ac5..b936f608d5 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSpecificityTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSpecificityTest.kt @@ -190,6 +190,7 @@ class F { val (acu, spy) = parser.parseWithTypeInferenceSpy( """ +interface Collection {} class Sup { static void m(Collection e) {} } @@ -379,19 +380,84 @@ class Scratch { spy.shouldBeOk { ctor.methodType.shouldBeSomeInstantiationOf(withSupplier) - } - - spy.shouldBeOk { voidM.methodType.shouldBeSomeInstantiationOf(withRunnable) - } - - spy.shouldBeOk { stdM.methodType.shouldBeSomeInstantiationOf(withSupplier) - } - - spy.shouldBeOk { polyM.methodType.shouldBeSomeInstantiationOf(withSupplier) } } + parserTest("Test specificity between exact mrefs") { + + val (acu, spy) = parser.parseWithTypeInferenceSpy( + """ +class Scratch { + + interface Runnable { void run(); } + interface Supplier { E get(); } + + static void bench(String label, Runnable runnable) { } + static T bench(String label, Supplier runnable) { return null; } + + static void voidMethod() {} + static Scratch standaloneMethod() { return null; } + static T polyMethod() { return null; } + + static { + bench("foo", Scratch::new); // selects the supplier + bench("foo", Scratch::voidMethod); // selects the runnable + bench("foo", Scratch::standaloneMethod); // selects the supplier + bench("foo", Scratch::polyMethod); // selects the supplier + bench("foo", Scratch::polyMethod); // ambiguous + } +} + + """.trimIndent() + ) + + val (_, _, withRunnable, withSupplier) = acu.declaredMethodSignatures() + + val (ctor, voidM, stdM, polyM, ambigM) = acu.methodCalls().toList() + + spy.shouldBeAmbiguous(ambigM) + + ctor.methodType.shouldBeSomeInstantiationOf(withSupplier) + voidM.methodType.shouldBeSomeInstantiationOf(withRunnable) + stdM.methodType.shouldBeSomeInstantiationOf(withSupplier) + polyM.methodType.shouldBeSomeInstantiationOf(withSupplier) + } + + parserTest("Test specificity between implicitly typed lamdbas (ambiguous)") { + + val (acu, spy) = parser.parseWithTypeInferenceSpy( + """ +class Scratch { + + interface Runnable { void run(Object o); } + interface Supplier { E get(Object u); } + + static void bench(String label, Runnable runnable) { } + static T bench(String label, Supplier runnable) { return null; } + + static void voidMethod() {} + static Scratch standaloneMethod() { return null; } + static T polyMethod() { return null; } + + static { + bench("foo", o -> new Scratch()); // selects the supplier + bench("foo", o -> voidMethod()); // selects the runnable + bench("foo", o -> standaloneMethod()); // selects the supplier + bench("foo", o -> polyMethod()); // selects the supplier + } +} + + """.trimIndent() + ) + + val (ctor, voidM, stdM, polyM) = acu.methodCalls().toList() + spy.shouldBeAmbiguous(ctor) + spy.shouldBeAmbiguous(voidM) + spy.shouldBeAmbiguous(stdM) + spy.shouldBeAmbiguous(polyM) + } + })