diff --git a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/FileRules.java b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/FileRules.java index 065b63c4..f6fb1695 100644 --- a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/FileRules.java +++ b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/FileRules.java @@ -4,6 +4,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; import com.google.errorprone.refaster.Refaster; import com.google.errorprone.refaster.annotation.AfterTemplate; +import com.google.errorprone.refaster.annotation.AlsoNegation; import com.google.errorprone.refaster.annotation.BeforeTemplate; import com.google.errorprone.refaster.annotation.Repeated; import java.io.File; @@ -11,6 +12,7 @@ import java.io.IOException; import java.net.URI; import java.nio.charset.Charset; import java.nio.file.Files; +import java.nio.file.LinkOption; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.FileAttribute; @@ -141,4 +143,35 @@ final class FileRules { return Files.createTempFile(directory.toPath(), prefix, suffix).toFile(); } } + + /** + * Invoke {@link File#mkdirs()} before {@link Files#exists(Path, LinkOption...)} to avoid + * concurrency issues. + */ + static final class PathToFileMkDirsFilesExists { + @BeforeTemplate + boolean before(Path path) { + return Files.exists(path) || path.toFile().mkdirs(); + } + + @AfterTemplate + @AlsoNegation + boolean after(Path path) { + return path.toFile().mkdirs() || Files.exists(path); + } + } + + /** Invoke {@link File#mkdirs()} before {@link File#exists()} to avoid concurrency issues. */ + static final class FileMkDirsFileExists { + @BeforeTemplate + boolean before(File file) { + return file.exists() || file.mkdirs(); + } + + @AfterTemplate + @AlsoNegation + boolean after(File file) { + return file.mkdirs() || file.exists(); + } + } } diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/FileRulesTestInput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/FileRulesTestInput.java index 4863bb1a..5425fb2e 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/FileRulesTestInput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/FileRulesTestInput.java @@ -39,4 +39,16 @@ final class FileRulesTest implements RefasterRuleCollectionTestCase { File testFilesCreateTempFileInCustomDirectoryToFile() throws IOException { return File.createTempFile("foo", "bar", new File("baz")); } + + ImmutableSet testPathToFileMkDirsFilesExists() { + return ImmutableSet.of( + Files.exists(Path.of("foo")) || Path.of("foo").toFile().mkdirs(), + !Files.exists(Path.of("bar")) && !Path.of("bar").toFile().mkdirs()); + } + + ImmutableSet testFileMkDirsFileExists() { + return ImmutableSet.of( + new File("foo").exists() || new File("foo").mkdirs(), + !new File("bar").exists() && !new File("bar").mkdirs()); + } } diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/FileRulesTestOutput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/FileRulesTestOutput.java index 0e987bcf..2f4ecfab 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/FileRulesTestOutput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/FileRulesTestOutput.java @@ -39,4 +39,16 @@ final class FileRulesTest implements RefasterRuleCollectionTestCase { File testFilesCreateTempFileInCustomDirectoryToFile() throws IOException { return Files.createTempFile(new File("baz").toPath(), "foo", "bar").toFile(); } + + ImmutableSet testPathToFileMkDirsFilesExists() { + return ImmutableSet.of( + Path.of("foo").toFile().mkdirs() || Files.exists(Path.of("foo")), + !Path.of("bar").toFile().mkdirs() && !Files.exists(Path.of("bar"))); + } + + ImmutableSet testFileMkDirsFileExists() { + return ImmutableSet.of( + new File("foo").mkdirs() || new File("foo").exists(), + !new File("bar").mkdirs() && !new File("bar").exists()); + } }