From 5fef6e0ab3414a21c3274059ec2df5579bf76dd7 Mon Sep 17 00:00:00 2001 From: ghm Date: Thu, 30 May 2024 03:36:25 -0700 Subject: [PATCH] Yet another JUnitIncompatibleType crash fix. Fixes external #4377. PiperOrigin-RevId: 638595224 --- .../JUnitIncompatibleType.java | 12 +++-- .../JUnitIncompatibleTypeTest.java | 47 +++++++++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/collectionincompatibletype/JUnitIncompatibleType.java b/core/src/main/java/com/google/errorprone/bugpatterns/collectionincompatibletype/JUnitIncompatibleType.java index c67b6d84bfe..d1c2a73fa36 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/collectionincompatibletype/JUnitIncompatibleType.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/collectionincompatibletype/JUnitIncompatibleType.java @@ -23,6 +23,7 @@ import static com.google.errorprone.matchers.Matchers.anyOf; import static com.google.errorprone.matchers.method.MethodMatchers.staticMethod; import static com.google.errorprone.util.ASTHelpers.getSymbol; +import static com.google.errorprone.util.ASTHelpers.getUpperBound; import static com.google.errorprone.util.ASTHelpers.isSameType; import com.google.errorprone.BugPattern; @@ -79,10 +80,15 @@ public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState var typeB = ignoringCasts(arguments.get(skip + 1), state); return checkCompatibility(tree, typeA, typeB, state); } else if (ASSERT_ARRAY_EQUALS.matches(tree, state)) { + int skip = argumentsToSkip(tree, state); - var typeA = ((ArrayType) ignoringCasts(arguments.get(skip), state)).elemtype; - var typeB = ((ArrayType) ignoringCasts(arguments.get(skip + 1), state)).elemtype; - return checkCompatibility(tree, typeA, typeB, state); + var expected = getUpperBound(ignoringCasts(arguments.get(skip), state), state.getTypes()); + var actual = getUpperBound(ignoringCasts(arguments.get(skip + 1), state), state.getTypes()); + if (!(expected instanceof ArrayType) || !(actual instanceof ArrayType)) { + return NO_MATCH; + } + return checkCompatibility( + tree, ((ArrayType) expected).elemtype, ((ArrayType) actual).elemtype, state); } return NO_MATCH; } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/collectionincompatibletype/JUnitIncompatibleTypeTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/collectionincompatibletype/JUnitIncompatibleTypeTest.java index b9369dc4d78..91bf23dae27 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/collectionincompatibletype/JUnitIncompatibleTypeTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/collectionincompatibletype/JUnitIncompatibleTypeTest.java @@ -144,4 +144,51 @@ public void fourArgumentOverload() { "}") .doTest(); } + + @Test + public void arrayNullComparison() { + compilationHelper + .addSourceLines( + "Test.java", + "import static org.junit.Assert.assertArrayEquals;", + "class Test {", + " public void test() {", + " assertArrayEquals(null, new Object[] {2});", + " }", + "}") + .doTest(); + } + + @Test + public void typeVariables_incompatible() { + compilationHelper + .addSourceLines( + "Test.java", + "import static org.junit.Assert.assertArrayEquals;", + "import java.util.Map;", + "class Test {", + " public void test(Map xs) {", + " T[] x = xs.get(1);", + " // BUG: Diagnostic contains:", + " assertArrayEquals(x, new Double[] {1d});", + " }", + "}") + .doTest(); + } + + @Test + public void typeVariables_compatible() { + compilationHelper + .addSourceLines( + "Test.java", + "import static org.junit.Assert.assertArrayEquals;", + "import java.util.Map;", + "class Test {", + " public void test(Map xs) {", + " T[] x = xs.get(1);", + " assertArrayEquals(x, new Double[] {1d});", + " }", + "}") + .doTest(); + } }