From 6c635c5ddbe20cfa82dfb10acd087d1b4ec8bcbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 12 May 2023 12:21:51 +0200 Subject: [PATCH 1/3] Add test case --- .../rule/codestyle/xml/UnnecessaryImport.xml | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml index c20ee2d2a8..e22a37a6b3 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml @@ -1143,4 +1143,29 @@ public class Sample { } ]]> + + #4557 - UnnecessaryImport FP with static imports of overloaded methods + 0 + + From 3aea46cbd06bdaebf252a83c0cde3f89be9c19b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 12 May 2023 12:45:58 +0200 Subject: [PATCH 2/3] Fix #4457 - overload ambiguity --- .../internal/infer/PhaseOverloadSet.java | 17 +++++ .../internal/infer/OverloadResolutionTest.kt | 72 ++++++++++++++++++- 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/PhaseOverloadSet.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/PhaseOverloadSet.java index a71882e53f..86604eac85 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/PhaseOverloadSet.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/PhaseOverloadSet.java @@ -167,6 +167,23 @@ final class PhaseOverloadSet extends OverloadSet { JMethodSig sfun = TypeOps.findFunctionalInterfaceMethod(si); JMethodSig tfun = TypeOps.findFunctionalInterfaceMethod(ti); if (sfun == null || tfun == null) { + if (phase.canBox()) { + JTypeMirror stdExprTy = ei.getStandaloneType(); + if (stdExprTy != null + // there is a boxing or unboxing conversion happening + && stdExprTy.isPrimitive() != si.isPrimitive() + && stdExprTy.isPrimitive() != ti.isPrimitive()) { + // si or ti is more specific if it only involves + // the boxing/unboxing conversion, without widening + // afterwards. + if (stdExprTy.box().equals(si.box())) { + return true; + } else if (stdExprTy.box().equals(ti.box())) { + return false; + } + } + } + infer.checkConvertibleOrDefer(ctx, si, ti, ei, phase, site); continue; } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadResolutionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadResolutionTest.kt index 5f2d8797da..43c5863b97 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadResolutionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadResolutionTest.kt @@ -5,6 +5,7 @@ package net.sourceforge.pmd.lang.java.types.internal.infer +import io.kotest.matchers.should import io.kotest.matchers.shouldBe import net.sourceforge.pmd.lang.ast.test.shouldBe import net.sourceforge.pmd.lang.ast.test.shouldMatchN @@ -283,7 +284,7 @@ class OverloadResolutionTest : ProcessorTestSpec({ void foo(long i) { foo('c'); } - + void foo(String other) {} } """) @@ -307,10 +308,77 @@ class OverloadResolutionTest : ProcessorTestSpec({ } } + parserTest("#4557 two overloads with boxed types") { + + val acu = parser.parse( + """ + package p; + + import static p.Static.assertThat; + + class Klass { + static { + // This is assertThat(Integer) + // Integer is more specific than Long because int -> Integer + // only involves boxing, while int -> Long needs widening and + // then boxing. + assertThat(1); + } + } + class Static { + + public static Object assertThat(Integer actual) { + return null; + } + + public static Object assertThat(Long actual) { + return null; + } + + } + """.trimIndent() + ) + + val fooM = acu.methodDeclarations().firstOrThrow() + val call = acu.firstMethodCall() + + call.overloadSelectionInfo.should { + it.isFailed shouldBe false + it.methodType.symbol shouldBe fooM.symbol + } + } + parserTest("Two overloads with boxed types, widening required, ambiguous") { + + val (acu, spy) = parser.parseWithTypeInferenceSpy( + """ + class Static { + static { + // ambiguous: 1 is int, and neither Double nor Long is more + // specific because they both involve boxing + widening + assertThat(1); + } + + public static Object assertThat(Double actual) { + return null; + } + + public static Object assertThat(Long actual) { + return null; + } + + } + """.trimIndent() + ) + + val call = acu.firstMethodCall() + spy.shouldBeAmbiguous(call) + } + parserTest("Overload selection must identify fallbacks if any") { - val acu = parser.parse(""" + val acu = parser.parse( + """ import java.util.Arrays; import java.util.stream.Collectors; import java.lang.reflect.Type; From c5790f177cc7ba6f9c339e810213ba8a26e35c7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 12 May 2023 19:33:08 +0200 Subject: [PATCH 3/3] Update release notes Fix #4557 --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index d5609e8ff0..dabddf22b7 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -473,6 +473,7 @@ Language specific fixes: * [#4487](https://github.com/pmd/pmd/issues/4487): \[java] UnnecessaryConstructor: false-positive with @Inject and @Autowired * [#4511](https://github.com/pmd/pmd/issues/4511): \[java] LocalVariableCouldBeFinal shouldn't report unused variables * [#4512](https://github.com/pmd/pmd/issues/4512): \[java] MethodArgumentCouldBeFinal shouldn't report unused parameters + * [#4557](https://github.com/pmd/pmd/issues/4557): \[java] UnnecessaryImport FP with static imports of overloaded methods * java-design * [#1014](https://github.com/pmd/pmd/issues/1014): \[java] LawOfDemeter: False positive with lambda expression * [#1605](https://github.com/pmd/pmd/issues/1605): \[java] LawOfDemeter: False positive for standard UTF-8 charset name