Compare commits

...

13 Commits

Author SHA1 Message Date
Stephan Schroevers
fd9c248777 WIP 2: Other spec ideation 2024-08-23 22:43:27 +02:00
Stephan Schroevers
9954663bd5 WIP: Doodles 2024-08-23 22:43:27 +02:00
Picnic-DevPla-Bot
f6e9dbb996 Upgrade Byte Buddy 1.14.18 -> 1.14.19 (#1292)
See:
- https://github.com/raphw/byte-buddy/releases/tag/byte-buddy-1.14.19
- https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.18...byte-buddy-1.14.19
2024-08-23 19:39:59 +02:00
Picnic-DevPla-Bot
260021c961 Upgrade NullAway 0.11.1 -> 0.11.2 (#1299)
See:
- https://github.com/uber/NullAway/blob/master/CHANGELOG.md
- https://github.com/uber/NullAway/releases/tag/v0.11.2
- https://github.com/uber/NullAway/compare/v0.11.1...v0.11.2
2024-08-23 19:31:03 +02:00
Stephan Schroevers
ec54e79f3e Introduce {Max,Min}Of{Array,Collection} Refaster rules (#1276)
While there, generalize the `{Max,Min}OfVarargs` rules.
2024-08-23 08:47:35 +02:00
Stephan Schroevers
4cbfdba521 Introduce additional File and Path Refaster rules (#1282) 2024-08-22 09:58:09 +02:00
Picnic-DevPla-Bot
d94f65a1f0 Upgrade JUnit 5 5.10.3 -> 5.11.0 (#1289)
See:
- https://junit.org/junit5/docs/current/release-notes/
- https://github.com/junit-team/junit5/releases/tag/r5.11.0-M1
- https://github.com/junit-team/junit5/releases/tag/r5.11.0-M2
- https://github.com/junit-team/junit5/releases/tag/r5.11.0-RC1
- https://github.com/junit-team/junit5/releases/tag/r5.11.0
- https://github.com/junit-team/junit5/compare/r5.10.3...r5.11.0
2024-08-15 09:21:45 +02:00
Picnic-DevPla-Bot
9afdf2ddf3 Upgrade OpenRewrite Templating 1.12.3 -> 1.13.0 (#1287)
See:
- https://github.com/openrewrite/rewrite-templating/releases/tag/v1.13.0
- https://github.com/openrewrite/rewrite-templating/compare/v1.12.3...v1.13.0
2024-08-14 11:35:36 +02:00
Picnic-DevPla-Bot
060c901479 Upgrade maven-gpg-plugin 3.2.4 -> 3.2.5 (#1284)
See:
- https://github.com/apache/maven-gpg-plugin/releases/tag/maven-gpg-plugin-3.2.5
- https://github.com/apache/maven-gpg-plugin/compare/maven-gpg-plugin-3.2.4...maven-gpg-plugin-3.2.5
2024-08-14 08:56:02 +02:00
Picnic-DevPla-Bot
1feee4f64a Upgrade Project Reactor 2023.0.8 -> 2023.0.9 (#1285)
See:
- https://github.com/reactor/reactor/releases/tag/2023.0.9
- https://github.com/reactor/reactor/compare/2023.0.8...2023.0.9
2024-08-14 08:26:16 +02:00
Picnic-Bot
552ddf6a7d Upgrade Maven API 3.9.5 -> 3.9.8 (#701)
See:
- https://maven.apache.org/release-notes-all.html
- https://github.com/apache/maven/releases/tag/maven-3.9.6
- https://github.com/apache/maven/releases/tag/maven-3.9.7
- https://github.com/apache/maven/releases/tag/maven-3.9.8
- https://github.com/apache/maven/compare/maven-3.9.5...maven-3.9.8
2024-08-12 16:14:46 +02:00
Stephan Schroevers
5d92c6c6ce Update Error Prone compatibility matrix (#1281) 2024-08-12 08:28:56 +02:00
Stephan Schroevers
fa8ca80040 [maven-release-plugin] prepare for next development iteration 2024-08-11 15:05:54 +02:00
28 changed files with 514 additions and 34 deletions

View File

@@ -46,7 +46,7 @@ jobs:
with:
java-version: ${{ matrix.jdk }}
java-distribution: ${{ matrix.distribution }}
maven-version: 3.9.6
maven-version: 3.9.8
- name: Display build environment details
run: mvn --version
- name: Build project against vanilla Error Prone, compile Javadoc

View File

@@ -38,7 +38,7 @@ jobs:
with:
java-version: 17.0.10
java-distribution: temurin
maven-version: 3.9.6
maven-version: 3.9.8
- name: Initialize CodeQL
uses: github/codeql-action/init@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1
with:

View File

@@ -27,7 +27,7 @@ jobs:
checkout-fetch-depth: 2
java-version: 17.0.10
java-distribution: temurin
maven-version: 3.9.6
maven-version: 3.9.8
- name: Run Pitest
# By running with features `+GIT(from[HEAD~1]), +gitci`, Pitest only
# analyzes lines changed in the associated pull request, as GitHub

View File

@@ -35,7 +35,7 @@ jobs:
with:
java-version: 17.0.10
java-distribution: temurin
maven-version: 3.9.6
maven-version: 3.9.8
- name: Download Pitest analysis artifact
uses: dawidd6/action-download-artifact@09f2f74827fd3a8607589e5ad7f9398816f540fe # v3.1.4
with:

View File

@@ -38,7 +38,7 @@ jobs:
checkout-ref: "refs/pull/${{ github.event.issue.number }}/head"
java-version: 17.0.10
java-distribution: temurin
maven-version: 3.9.6
maven-version: 3.9.8
- name: Install project to local Maven repository
run: mvn -T1C install -DskipTests -Dverification.skip
- name: Run integration test

View File

@@ -40,7 +40,7 @@ jobs:
checkout-fetch-depth: 0
java-version: 17.0.10
java-distribution: temurin
maven-version: 3.9.6
maven-version: 3.9.8
- name: Create missing `test` directory
# XXX: Drop this step in favour of actually having a test.
run: mkdir refaster-compiler/src/test

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.18.0</version>
<version>0.18.1-SNAPSHOT</version>
</parent>
<artifactId>documentation-support</artifactId>

View File

@@ -14,7 +14,6 @@ import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ServiceLoader;
import javax.tools.JavaFileObject;
@@ -87,6 +86,6 @@ final class DocumentationGeneratorTaskListener implements TaskListener {
}
private static String getSimpleClassName(URI path) {
return Paths.get(path).getFileName().toString().replace(".java", "");
return Path.of(path).getFileName().toString().replace(".java", "");
}
}

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.18.0</version>
<version>0.18.1-SNAPSHOT</version>
</parent>
<artifactId>error-prone-contrib</artifactId>

View File

@@ -51,6 +51,7 @@ import tech.picnic.errorprone.utils.SourceCode;
// is effectively the identity operation.
// XXX: Also flag nullary instance method invocations that represent an identity conversion, such as
// `Boolean#booleanValue()`, `Byte#byteValue()` and friends.
// XXX: Also flag redundant round-trip conversions such as `path.toFile().toPath()`.
@AutoService(BugChecker.class)
@BugPattern(
summary = "Avoid or clarify identity conversions",

View File

@@ -24,6 +24,7 @@ import com.google.errorprone.refaster.annotation.Placeholder;
import com.google.errorprone.refaster.annotation.Repeated;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Optional;
@@ -247,14 +248,46 @@ final class ComparatorRules {
* Avoid unnecessary creation of a {@link Stream} to determine the minimum of a known collection
* of values.
*/
static final class MinOfVarargs<T> {
static final class MinOfArray<S, T extends S> {
@BeforeTemplate
T before(@Repeated T value, Comparator<T> cmp) {
T before(T[] array, Comparator<S> cmp) {
return Arrays.stream(array).min(cmp).orElseThrow();
}
@AfterTemplate
T after(T[] array, Comparator<S> cmp) {
return Collections.min(Arrays.asList(array), cmp);
}
}
/**
* Avoid unnecessary creation of a {@link Stream} to determine the minimum of a known collection
* of values.
*/
static final class MinOfCollection<S, T extends S> {
@BeforeTemplate
T before(Collection<T> collection, Comparator<S> cmp) {
return collection.stream().min(cmp).orElseThrow();
}
@AfterTemplate
T after(Collection<T> collection, Comparator<S> cmp) {
return Collections.min(collection, cmp);
}
}
/**
* Avoid unnecessary creation of a {@link Stream} to determine the minimum of a known collection
* of values.
*/
static final class MinOfVarargs<S, T extends S> {
@BeforeTemplate
T before(@Repeated T value, Comparator<S> cmp) {
return Stream.of(Refaster.asVarargs(value)).min(cmp).orElseThrow();
}
@AfterTemplate
T after(@Repeated T value, Comparator<T> cmp) {
T after(@Repeated T value, Comparator<S> cmp) {
return Collections.min(Arrays.asList(value), cmp);
}
}
@@ -314,14 +347,46 @@ final class ComparatorRules {
* Avoid unnecessary creation of a {@link Stream} to determine the maximum of a known collection
* of values.
*/
static final class MaxOfVarargs<T> {
static final class MaxOfArray<S, T extends S> {
@BeforeTemplate
T before(@Repeated T value, Comparator<T> cmp) {
T before(T[] array, Comparator<S> cmp) {
return Arrays.stream(array).max(cmp).orElseThrow();
}
@AfterTemplate
T after(T[] array, Comparator<S> cmp) {
return Collections.max(Arrays.asList(array), cmp);
}
}
/**
* Avoid unnecessary creation of a {@link Stream} to determine the maximum of a known collection
* of values.
*/
static final class MaxOfCollection<S, T extends S> {
@BeforeTemplate
T before(Collection<T> collection, Comparator<S> cmp) {
return collection.stream().max(cmp).orElseThrow();
}
@AfterTemplate
T after(Collection<T> collection, Comparator<S> cmp) {
return Collections.max(collection, cmp);
}
}
/**
* Avoid unnecessary creation of a {@link Stream} to determine the maximum of a known collection
* of values.
*/
static final class MaxOfVarargs<S, T extends S> {
@BeforeTemplate
T before(@Repeated T value, Comparator<S> cmp) {
return Stream.of(Refaster.asVarargs(value)).max(cmp).orElseThrow();
}
@AfterTemplate
T after(@Repeated T value, Comparator<T> cmp) {
T after(@Repeated T value, Comparator<S> cmp) {
return Collections.max(Arrays.asList(value), cmp);
}
}

View File

@@ -5,11 +5,14 @@ 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.BeforeTemplate;
import com.google.errorprone.refaster.annotation.Repeated;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileAttribute;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@@ -18,6 +21,49 @@ import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
final class FileRules {
private FileRules() {}
/** Prefer the more idiomatic {@link Path#of(URI)} over {@link Paths#get(URI)}. */
static final class PathOfUri {
@BeforeTemplate
Path before(URI uri) {
return Paths.get(uri);
}
@AfterTemplate
Path after(URI uri) {
return Path.of(uri);
}
}
/**
* Prefer the more idiomatic {@link Path#of(String, String...)} over {@link Paths#get(String,
* String...)}.
*/
static final class PathOfString {
@BeforeTemplate
Path before(String first, @Repeated String more) {
return Paths.get(first, more);
}
@AfterTemplate
Path after(String first, @Repeated String more) {
return Path.of(first, more);
}
}
/** Avoid redundant conversions from {@link Path} to {@link File}. */
// XXX: Review whether a rule such as this one is better handled by the `IdentityConversion` rule.
static final class PathInstance {
@BeforeTemplate
Path before(Path path) {
return path.toFile().toPath();
}
@AfterTemplate
Path after(Path path) {
return path;
}
}
/** Prefer {@link Files#readString(Path, Charset)} over more contrived alternatives. */
static final class FilesReadStringWithCharset {
@BeforeTemplate
@@ -50,7 +96,11 @@ final class FileRules {
*/
static final class FilesCreateTempFileToFile {
@BeforeTemplate
@SuppressWarnings("java:S5443" /* This violation will be rewritten. */)
@SuppressWarnings({
"FilesCreateTempFileInCustomDirectoryToFile" /* This is a more specific template. */,
"java:S5443" /* This violation will be rewritten. */,
"key-to-resolve-AnnotationUseStyle-and-TrailingComment-check-conflict"
})
File before(String prefix, String suffix) throws IOException {
return Refaster.anyOf(
File.createTempFile(prefix, suffix), File.createTempFile(prefix, suffix, null));
@@ -63,4 +113,20 @@ final class FileRules {
return Files.createTempFile(prefix, suffix).toFile();
}
}
/**
* Prefer {@link Files#createTempFile(Path, String, String, FileAttribute[])} over alternatives
* that create files with more liberal permissions.
*/
static final class FilesCreateTempFileInCustomDirectoryToFile {
@BeforeTemplate
File before(File directory, String prefix, String suffix) throws IOException {
return File.createTempFile(prefix, suffix, directory);
}
@AfterTemplate
File after(File directory, String prefix, String suffix) throws IOException {
return Files.createTempFile(directory.toPath(), prefix, suffix).toFile();
}
}
}

View File

@@ -2,6 +2,7 @@ package tech.picnic.errorprone.refasterrules;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Streams;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.refaster.Refaster;
@@ -11,6 +12,10 @@ import com.google.errorprone.refaster.annotation.MayOptionallyUse;
import com.google.errorprone.refaster.annotation.NotMatches;
import com.google.errorprone.refaster.annotation.Placeholder;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Optional;
@@ -27,6 +32,23 @@ import tech.picnic.errorprone.refaster.matchers.IsLikelyTrivialComputation;
final class OptionalRules {
private OptionalRules() {}
// XXX: Move or drop.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
@interface BeforeExample {}
// XXX: Move or drop.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
@interface AfterExample {}
// XXX: Move or drop.
interface RefasterExpressionExamples<T> {
ImmutableList<T> before();
ImmutableList<T> after();
}
/** Prefer {@link Optional#empty()} over the more contrived alternative. */
static final class OptionalEmpty<T> {
@BeforeTemplate
@@ -53,6 +75,40 @@ final class OptionalRules {
Optional<T> after(T object) {
return Optional.ofNullable(object);
}
@BeforeExample
@SuppressWarnings({
"TernaryOperatorOptionalNegativeFiltering",
"TernaryOperatorOptionalPositiveFiltering"
} /* Special cases. */)
ImmutableList<Optional<String>> input() {
return ImmutableList.of(
toString() == null ? Optional.empty() : Optional.of(toString()),
toString() != null ? Optional.of(toString()) : Optional.empty());
}
@AfterExample
ImmutableList<Optional<String>> output() {
return ImmutableList.of(Optional.ofNullable(toString()), Optional.ofNullable(toString()));
}
static final class Examples implements RefasterExpressionExamples<Optional<String>> {
@Override
@SuppressWarnings({
"TernaryOperatorOptionalNegativeFiltering",
"TernaryOperatorOptionalPositiveFiltering"
} /* Special cases. */)
public ImmutableList<Optional<String>> before() {
return ImmutableList.of(
toString() == null ? Optional.empty() : Optional.of(toString()),
toString() != null ? Optional.of(toString()) : Optional.empty());
}
@Override
public ImmutableList<Optional<String>> after() {
return ImmutableList.of(Optional.ofNullable(toString()), Optional.ofNullable(toString()));
}
}
}
/** Prefer {@link Optional#isEmpty()} over the more verbose alternative. */
@@ -66,6 +122,16 @@ final class OptionalRules {
boolean after(Optional<T> optional) {
return optional.isEmpty();
}
@BeforeExample
ImmutableList<Boolean> input() {
return ImmutableList.of(!Optional.empty().isPresent(), !Optional.of("foo").isPresent());
}
@AfterExample
ImmutableList<Boolean> output() {
return ImmutableList.of(Optional.empty().isEmpty(), Optional.of("foo").isEmpty());
}
}
/** Prefer {@link Optional#isPresent()} over the inverted alternative. */
@@ -79,6 +145,16 @@ final class OptionalRules {
boolean after(Optional<T> optional) {
return optional.isPresent();
}
@BeforeExample
ImmutableList<Boolean> input() {
return ImmutableList.of(!Optional.empty().isEmpty(), !Optional.of("foo").isEmpty());
}
@AfterExample
ImmutableList<Boolean> output() {
return ImmutableList.of(Optional.empty().isPresent(), Optional.of("foo").isPresent());
}
}
/** Prefer {@link Optional#orElseThrow()} over the less explicit {@link Optional#get()}. */

View File

@@ -107,6 +107,14 @@ final class ComparatorRulesTest implements RefasterRuleCollectionTestCase {
Comparator.<String>reverseOrder().compare("baz", "qux"));
}
String testMinOfArray() {
return Arrays.stream(new String[0]).min(naturalOrder()).orElseThrow();
}
String testMinOfCollection() {
return ImmutableSet.of("foo", "bar").stream().min(naturalOrder()).orElseThrow();
}
int testMinOfVarargs() {
return Stream.of(1, 2).min(naturalOrder()).orElseThrow();
}
@@ -135,6 +143,14 @@ final class ComparatorRulesTest implements RefasterRuleCollectionTestCase {
Collections.min(ImmutableSet.of("a", "b"), (a, b) -> 1));
}
String testMaxOfArray() {
return Arrays.stream(new String[0]).max(naturalOrder()).orElseThrow();
}
String testMaxOfCollection() {
return ImmutableSet.of("foo", "bar").stream().max(naturalOrder()).orElseThrow();
}
int testMaxOfVarargs() {
return Stream.of(1, 2).max(naturalOrder()).orElseThrow();
}

View File

@@ -98,6 +98,14 @@ final class ComparatorRulesTest implements RefasterRuleCollectionTestCase {
return ImmutableSet.of("foo".compareTo("bar"), "qux".compareTo("baz"));
}
String testMinOfArray() {
return Collections.min(Arrays.asList(new String[0]), naturalOrder());
}
String testMinOfCollection() {
return Collections.min(ImmutableSet.of("foo", "bar"), naturalOrder());
}
int testMinOfVarargs() {
return Collections.min(Arrays.asList(1, 2), naturalOrder());
}
@@ -126,6 +134,14 @@ final class ComparatorRulesTest implements RefasterRuleCollectionTestCase {
Comparators.min("a", "b", (a, b) -> 1));
}
String testMaxOfArray() {
return Collections.max(Arrays.asList(new String[0]), naturalOrder());
}
String testMaxOfCollection() {
return Collections.max(ImmutableSet.of("foo", "bar"), naturalOrder());
}
int testMaxOfVarargs() {
return Collections.max(Arrays.asList(1, 2), naturalOrder());
}

View File

@@ -3,12 +3,26 @@ package tech.picnic.errorprone.refasterrules;
import com.google.common.collect.ImmutableSet;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class FileRulesTest implements RefasterRuleCollectionTestCase {
Path testPathOfUri() {
return Paths.get(URI.create("foo"));
}
ImmutableSet<Path> testPathOfString() {
return ImmutableSet.of(Paths.get("foo"), Paths.get("bar", "baz", "qux"));
}
Path testPathInstance() {
return Path.of("foo").toFile().toPath();
}
String testFilesReadStringWithCharset() throws IOException {
return new String(Files.readAllBytes(Paths.get("foo")), StandardCharsets.ISO_8859_1);
}
@@ -21,4 +35,8 @@ final class FileRulesTest implements RefasterRuleCollectionTestCase {
return ImmutableSet.of(
File.createTempFile("foo", "bar"), File.createTempFile("baz", "qux", null));
}
File testFilesCreateTempFileInCustomDirectoryToFile() throws IOException {
return File.createTempFile("foo", "bar", new File("baz"));
}
}

View File

@@ -3,12 +3,26 @@ package tech.picnic.errorprone.refasterrules;
import com.google.common.collect.ImmutableSet;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class FileRulesTest implements RefasterRuleCollectionTestCase {
Path testPathOfUri() {
return Path.of(URI.create("foo"));
}
ImmutableSet<Path> testPathOfString() {
return ImmutableSet.of(Path.of("foo"), Path.of("bar", "baz", "qux"));
}
Path testPathInstance() {
return Path.of("foo");
}
String testFilesReadStringWithCharset() throws IOException {
return Files.readString(Paths.get("foo"), StandardCharsets.ISO_8859_1);
}
@@ -21,4 +35,8 @@ final class FileRulesTest implements RefasterRuleCollectionTestCase {
return ImmutableSet.of(
Files.createTempFile("foo", "bar").toFile(), Files.createTempFile("baz", "qux").toFile());
}
File testFilesCreateTempFileInCustomDirectoryToFile() throws IOException {
return Files.createTempFile(new File("baz").toPath(), "foo", "bar").toFile();
}
}

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.18.0</version>
<version>0.18.1-SNAPSHOT</version>
</parent>
<artifactId>error-prone-experimental</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.18.0</version>
<version>0.18.1-SNAPSHOT</version>
</parent>
<artifactId>error-prone-guidelines</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.18.0</version>
<version>0.18.1-SNAPSHOT</version>
</parent>
<artifactId>error-prone-utils</artifactId>

20
pom.xml
View File

@@ -4,7 +4,7 @@
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.18.0</version>
<version>0.18.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Picnic :: Error Prone Support</name>
@@ -52,7 +52,7 @@
<scm child.scm.developerConnection.inherit.append.path="false" child.scm.url.inherit.append.path="false">
<developerConnection>scm:git:git@github.com:PicnicSupermarket/error-prone-support.git</developerConnection>
<tag>v0.18.0</tag>
<tag>HEAD</tag>
<url>https://github.com/PicnicSupermarket/error-prone-support</url>
</scm>
<issueManagement>
@@ -148,7 +148,7 @@
<groupId.error-prone>com.google.errorprone</groupId.error-prone>
<!-- The build timestamp is derived from the most recent commit
timestamp in support of reproducible builds. -->
<project.build.outputTimestamp>2024-08-11T13:04:41Z</project.build.outputTimestamp>
<project.build.outputTimestamp>2024-08-11T13:05:54Z</project.build.outputTimestamp>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Glob pattern identifying Refaster rule definition files. These
Java classes don't contain "regular" code, and thus require special
@@ -212,12 +212,12 @@
<version.error-prone-slf4j>0.1.25</version.error-prone-slf4j>
<version.guava-beta-checker>1.0</version.guava-beta-checker>
<version.jdk>17</version.jdk>
<version.maven>3.9.5</version.maven>
<version.maven>3.9.8</version.maven>
<version.mockito>5.12.0</version.mockito>
<version.nopen-checker>1.0.1</version.nopen-checker>
<version.nullaway>0.11.1</version.nullaway>
<version.nullaway>0.11.2</version.nullaway>
<version.pitest-git>1.1.4</version.pitest-git>
<version.rewrite-templating>1.12.3</version.rewrite-templating>
<version.rewrite-templating>1.13.0</version.rewrite-templating>
<version.surefire>3.2.3</version.surefire>
</properties>
@@ -360,7 +360,7 @@
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-bom</artifactId>
<version>2023.0.8</version>
<version>2023.0.9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -412,7 +412,7 @@
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.14.18</version>
<version>1.14.19</version>
</dependency>
<!-- Specified so that Renovate will file Maven upgrade PRs, which
subsequently will cause `maven-enforcer-plugin` to require that
@@ -457,7 +457,7 @@
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.10.3</version>
<version>5.11.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -1109,7 +1109,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.2.4</version>
<version>3.2.5</version>
<executions>
<execution>
<id>sign-artifacts</id>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.18.0</version>
<version>0.18.1-SNAPSHOT</version>
</parent>
<artifactId>refaster-compiler</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.18.0</version>
<version>0.18.1-SNAPSHOT</version>
</parent>
<artifactId>refaster-runner</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.18.0</version>
<version>0.18.1-SNAPSHOT</version>
</parent>
<artifactId>refaster-support</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.18.0</version>
<version>0.18.1-SNAPSHOT</version>
</parent>
<artifactId>refaster-test-support</artifactId>

View File

@@ -0,0 +1,20 @@
package tech.picnic.errorprone.refaster.test;
import java.util.stream.Stream;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
// XXX: Drop these annotations.
@Disabled
@SuppressWarnings("all")
abstract class MyAbstractTest {
@TestFactory
Stream<DynamicTest> dynamicTests() {
MatchInWrongMethodRules.class.getDeclaredClasses();
return Stream.of(
DynamicTest.dynamicTest("A " + getClass(), () -> {}),
DynamicTest.dynamicTest("A", () -> {}));
}
}

View File

@@ -0,0 +1,168 @@
package tech.picnic.errorprone.refaster.test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.google.common.collect.ImmutableSet;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.Extension;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.TestInstanceFactory;
import org.junit.jupiter.api.extension.TestInstanceFactoryContext;
import org.junit.jupiter.api.extension.TestInstantiationException;
// XXX: Drop these annotations.
@Disabled
@SuppressWarnings("all")
public class MyTest extends MyAbstractTest {
public static final class MyTestInstanceFactory implements TestInstanceFactory {
@Override
public Object createTestInstance(
TestInstanceFactoryContext factoryContext, ExtensionContext extensionContext)
throws TestInstantiationException {
return new MySubTest();
}
}
// XXX: Name
@Test
void foo() {
// Options:
// 1. Add examples to the Refaster rule, generate the tests from those
//
// 2. Define as test, and use a custom test annotation, which:
// - Generates the relevant test resources
// - Executes them.
// ^ Might be nicer to generate a subclass and use a `TestInstanceFactory` to instantiate that.
// XXX: That turns out not to work.
//
// ^ Other option: provide super class that declares a `TestFactory` based on the subclass name.
}
// Extensions can be defined at any level. TBD how useful.
// static final class MyExtension implements Extension, {
//
// }
// @ExtendWith(MyExtension.class)
static class MySubTest extends MyTest {}
@TestFactory
Stream<DynamicTest> dynamicTestsFromStreamInJava8() {
Function<String, String> resolver = s -> s;
List<String> domainNames =
Arrays.asList("www.somedomain.com", "www.anotherdomain.com", "www.yetanotherdomain.com");
List<String> outputList = Arrays.asList("154.174.10.56", "211.152.104.132", "178.144.120.156");
return domainNames.stream()
.map(
dom ->
DynamicTest.dynamicTest(
"Resolving: " + dom,
() -> {
int id = domainNames.indexOf(dom);
assertEquals(outputList.get(id), resolver.apply(dom));
}));
}
static final class PrimitiveOrReferenceEquality
implements ExpressionTestCase<ImmutableSet<Boolean>> {
public ImmutableSet<Boolean> before() {
return ImmutableSet.of(
RoundingMode.UP.equals(RoundingMode.DOWN),
Objects.equals(RoundingMode.UP, RoundingMode.DOWN),
!RoundingMode.UP.equals(RoundingMode.DOWN),
!Objects.equals(RoundingMode.UP, RoundingMode.DOWN));
}
public ImmutableSet<Boolean> after() {
return ImmutableSet.of(
RoundingMode.UP == RoundingMode.DOWN,
RoundingMode.UP == RoundingMode.DOWN,
RoundingMode.UP != RoundingMode.DOWN,
RoundingMode.UP != RoundingMode.DOWN);
}
}
// XXX: This variant can verify that the values are equal.
static final class PrimitiveOrReferenceEquality2 implements ExpressionTestCase2<Boolean> {
public void before(Consumer<Boolean> sink) {
sink.accept(RoundingMode.UP.equals(RoundingMode.DOWN));
sink.accept(Objects.equals(RoundingMode.UP, RoundingMode.DOWN));
sink.accept(!RoundingMode.UP.equals(RoundingMode.DOWN));
sink.accept(!Objects.equals(RoundingMode.UP, RoundingMode.DOWN));
}
public void after(Consumer<Boolean> sink) {
sink.accept(RoundingMode.UP == RoundingMode.DOWN);
sink.accept(RoundingMode.UP == RoundingMode.DOWN);
sink.accept(RoundingMode.UP != RoundingMode.DOWN);
sink.accept(RoundingMode.UP != RoundingMode.DOWN);
}
}
// With this setup we could validate equality, and (in theory) even report the exact source in
// case of an error.
// @Test
void primitiveOrReferenceEquality(BiConsumer<Boolean, Boolean> testCase) {
testCase.accept(
RoundingMode.UP.equals(RoundingMode.DOWN), RoundingMode.UP == RoundingMode.DOWN);
testCase.accept(
Objects.equals(RoundingMode.UP, RoundingMode.DOWN), RoundingMode.UP == RoundingMode.DOWN);
testCase.accept(
!RoundingMode.UP.equals(RoundingMode.DOWN), RoundingMode.UP != RoundingMode.DOWN);
testCase.accept(
!Objects.equals(RoundingMode.UP, RoundingMode.DOWN), RoundingMode.UP != RoundingMode.DOWN);
}
// With this setup we could validate equality, and (in theory) even report the exact source in
// case of an error.
// @Test
void primitiveOrReferenceEquality2(BiConsumer<Supplier<Boolean>, Supplier<Boolean>> testCase) {
testCase.accept(
() -> RoundingMode.UP.equals(RoundingMode.DOWN),
() -> RoundingMode.UP == RoundingMode.DOWN);
testCase.accept(
() -> Objects.equals(RoundingMode.UP, RoundingMode.DOWN),
() -> RoundingMode.UP == RoundingMode.DOWN);
testCase.accept(
() -> !RoundingMode.UP.equals(RoundingMode.DOWN),
() -> RoundingMode.UP != RoundingMode.DOWN);
testCase.accept(
() -> !Objects.equals(RoundingMode.UP, RoundingMode.DOWN),
() -> RoundingMode.UP != RoundingMode.DOWN);
}
interface ExpressionTestCase<T> {
T before();
T after();
}
interface ExpressionTestCase2<T> {
void before(Consumer<T> sink);
void after(Consumer<T> sink);
}
// record ExpressionTestCaseX<T>(Supplier<T> before, Supplier<T> after);
}

View File

@@ -1,6 +1,23 @@
# An overview of Error Prone Support releases, along with compatible Error
# Prone releases. This data was generated by `generate-version-compatibility-overview.sh`.
releases:
- version: 0.18.0
compatible:
- "2.30.0"
- version: 0.17.0
compatible:
- "2.29.2"
- "2.29.1"
- "2.29.0"
- "2.28.0"
- "2.27.1"
- "2.27.0"
- "2.26.1"
- "2.26.0"
- "2.25.0"
- "2.24.1"
- "2.24.0"
- "2.23.0"
- version: 0.16.1
compatible:
- "2.29.2"