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/main/java/tech/picnic/errorprone/refasterrules/ReactorRules.java b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ReactorRules.java index 7eb3af75..12c4f39d 100644 --- a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ReactorRules.java +++ b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ReactorRules.java @@ -489,9 +489,16 @@ final class ReactorRules { return Flux.range(value, 1); } + // XXX: Consider generalizing part of this template using an Error Prone check that covers any + // sequence of explicitly enumerated values passed to an iteration order-preserving collection + // factory method. @BeforeTemplate Flux before(T value) { - return Mono.just(value).repeat().take(1); + return Refaster.anyOf( + Mono.just(value).flux(), + Mono.just(value).repeat().take(1), + Flux.fromIterable(ImmutableList.of(value)), + Flux.fromIterable(ImmutableSet.of(value))); } @AfterTemplate 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()); + } } diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestInput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestInput.java index fe4c9dcf..b87e5783 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestInput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestInput.java @@ -188,7 +188,12 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase { } ImmutableSet> testFluxJust() { - return ImmutableSet.of(Flux.range(0, 1), Mono.just(2).repeat().take(1)); + return ImmutableSet.of( + Flux.range(0, 1), + Mono.just(2).flux(), + Mono.just(3).repeat().take(1), + Flux.fromIterable(ImmutableList.of(4)), + Flux.fromIterable(ImmutableSet.of(5))); } ImmutableSet> testMonoIdentity() { diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestOutput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestOutput.java index e48cca28..4aa24950 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestOutput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestOutput.java @@ -192,7 +192,7 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase { } ImmutableSet> testFluxJust() { - return ImmutableSet.of(Flux.just(0), Flux.just(2)); + return ImmutableSet.of(Flux.just(0), Flux.just(2), Flux.just(3), Flux.just(4), Flux.just(5)); } ImmutableSet> testMonoIdentity() { diff --git a/pom.xml b/pom.xml index 929d8371..86e558da 100644 --- a/pom.xml +++ b/pom.xml @@ -529,7 +529,7 @@ org.springframework spring-framework-bom - 6.2.4 + 6.2.5 pom import