diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/MissingDefault.java b/core/src/main/java/com/google/errorprone/bugpatterns/MissingDefault.java index f633a4b231d..c7b610913cb 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/MissingDefault.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/MissingDefault.java @@ -30,8 +30,10 @@ import com.google.errorprone.util.ASTHelpers; import com.google.errorprone.util.Reachability; import com.sun.source.tree.CaseTree; +import com.sun.source.tree.StatementTree; import com.sun.source.tree.SwitchTree; import com.sun.tools.javac.code.Type; +import java.util.List; import java.util.Optional; import javax.lang.model.element.ElementKind; @@ -62,8 +64,10 @@ public Description matchSwitch(SwitchTree tree, VisitorState state) { // for the switch statement. Hopefully we don't often see switches with zero cases. CaseTree lastCase = getLast(tree.getCases()); String replacement; - if (lastCase.getStatements().isEmpty() - || Reachability.canCompleteNormally(Iterables.getLast(lastCase.getStatements()))) { + List statements = lastCase.getStatements(); + if (statements == null + || statements.isEmpty() + || Reachability.canCompleteNormally(Iterables.getLast(statements))) { replacement = "\nbreak;\ndefault: // fall out\n"; } else { replacement = "\ndefault: // fall out\n"; @@ -73,7 +77,8 @@ public Description matchSwitch(SwitchTree tree, VisitorState state) { return description.build(); } CaseTree defaultCase = maybeDefault.get(); - if (!defaultCase.getStatements().isEmpty()) { + List statements = defaultCase.getStatements(); + if (statements != null && !statements.isEmpty()) { return NO_MATCH; } // If `default` case is empty, and last in switch, add `// fall out` comment diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/MissingDefaultTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/MissingDefaultTest.java index ac77bfad793..0387701cf75 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/MissingDefaultTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/MissingDefaultTest.java @@ -20,6 +20,7 @@ import com.google.errorprone.BugCheckerRefactoringTestHelper; import com.google.errorprone.CompilationTestHelper; +import com.google.errorprone.util.RuntimeVersion; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -225,4 +226,40 @@ public void multipleStatementsInGroup() { "}") .doTest(TEXT_MATCH); } + + @Test + public void arrowSwitch() { + assumeTrue(RuntimeVersion.isAtLeast14()); + compilationHelper + .addSourceLines( + "Test.java", + "class Test {", + " void m(int i) {", + " // BUG: Diagnostic contains:", + " switch (i) {", + " case 1 -> {}", + " case 2 -> {}", + " }", + " }", + "}") + .doTest(); + } + + @Test + public void arrowSwitchNegative() { + assumeTrue(RuntimeVersion.isAtLeast14()); + compilationHelper + .addSourceLines( + "Test.java", + "class Test {", + " void m(int i) {", + " switch (i) {", + " case 1 -> {}", + " case 2 -> {}", + " default -> {} // fall out", + " }", + " }", + "}") + .doTest(); + } } diff --git a/test_helpers/src/main/java/com/google/errorprone/FileObjects.java b/test_helpers/src/main/java/com/google/errorprone/FileObjects.java index f5ad2399c3d..2569ecd0937 100644 --- a/test_helpers/src/main/java/com/google/errorprone/FileObjects.java +++ b/test_helpers/src/main/java/com/google/errorprone/FileObjects.java @@ -23,6 +23,7 @@ import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import com.google.common.io.ByteStreams; +import com.google.errorprone.annotations.MustBeClosed; import java.io.IOException; import java.io.InputStream; import java.io.UncheckedIOException; @@ -47,8 +48,8 @@ public static JavaFileObject forResource(Class clazz, String resourceName) { URI.create( "file:///" + clazz.getPackage().getName().replace('.', '/') + "/" + resourceName); String content; - try { - content = new String(ByteStreams.toByteArray(findResource(clazz, resourceName)), UTF_8); + try (InputStream inputStream = findResource(clazz, resourceName)) { + content = new String(ByteStreams.toByteArray(inputStream), UTF_8); } catch (IOException e) { throw new UncheckedIOException(e); } @@ -61,6 +62,7 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept } // TODO(b/176096448): the testdata/ fallback is a hack, fix affected tests and remove it + @MustBeClosed private static InputStream findResource(Class clazz, String name) { InputStream is = clazz.getResourceAsStream(name); if (is != null) {