Compare commits

..

9 Commits

Author SHA1 Message Date
Gijs de Jong
2890bb983f [WIP] Expiriment with jq parsing 2022-10-07 14:23:10 +02:00
Gijs de Jong
f7165a84b6 Remove duplicate check 2022-10-07 10:36:23 +02:00
Gijs de Jong
b0ad824db8 Clean up doc extractor 2022-10-07 10:09:58 +02:00
Rick Ossendrijver
e2b79dac47 Support extracting Refaster Test Data 2022-10-06 18:16:39 +02:00
Rick Ossendrijver
dada0f23f1 Move all Refaster template test resources to respective .input and .output packages 2022-10-06 15:55:04 +02:00
Rick Ossendrijver
20ed8568c2 Improve interface and let BugPatternData also implement it 2022-10-06 13:16:39 +02:00
Rick Ossendrijver
546d3e3739 Add support for collecting BugPatternTestData 2022-10-06 08:56:11 +02:00
Rick Ossendrijver
eca96a76d2 Introduce RefasterTemplateData 2022-10-05 10:02:44 +02:00
Rick Ossendrijver
530fd8da1f Introduce Docgen module 2022-10-05 10:02:39 +02:00
272 changed files with 1367 additions and 3453 deletions

2
.github/release.yml vendored
View File

@@ -3,7 +3,7 @@ changelog:
labels:
- "ignore-changelog"
categories:
- title: ":rocket: New Error Prone checks and Refaster rules"
- title: ":rocket: New Error Prone checks and Refaster templates"
labels:
- "new feature"
- title: ":sparkles: Improvements"

View File

@@ -2,7 +2,7 @@ name: Build and verify
on:
pull_request:
push:
branches: [ master ]
branches: [$default-branch]
permissions:
contents: read
jobs:
@@ -18,7 +18,7 @@ jobs:
# additionally enabling all checks defined in this project and any
# Error Prone checks available only from other artifact repositories.
- name: Check out code
uses: actions/checkout@v3.1.0
uses: actions/checkout@v3.0.2
- name: Set up JDK
uses: actions/setup-java@v3.5.1
with:

View File

@@ -2,7 +2,7 @@ name: Update `error-prone.picnic.tech` website content
on:
pull_request:
push:
branches: [ master, website ]
branches: [$default-branch]
permissions:
contents: read
id-token: write
@@ -15,28 +15,25 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Check out code
uses: actions/checkout@v3.1.0
- uses: ruby/setup-ruby@v1.117.0
with:
working-directory: ./website
bundler-cache: true
uses: actions/checkout@v3.0.2
- name: Configure Github Pages
uses: actions/configure-pages@v2.1.1
# XXX: Run website/generate-docs.rb instead.
- name: Generate documentation
working-directory: ./website
run: bundle exec ruby generate-docs.rb
run: ./generate-docs.sh
- name: Build website with Jekyll
uses: actions/jekyll-build-pages@v1.0.5
with:
source: website/
destination: ./_site
- name: Validate HTML output
working-directory: ./website
# XXX: Drop `--disable_external true` once we fully adopted the
# "Refaster rules" terminology on our website and in the code.
run: bundle exec htmlproofer --disable_external true --check-external-hash false ./_site
uses: anishathalye/proof-html@v1.4.1
with:
directory: ./_site
check_external_hash: false
- name: Upload website as artifact
uses: actions/upload-pages-artifact@v1.0.4
with:
path: ./website/_site
deploy:
if: github.ref == 'refs/heads/website'
if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
needs: build
runs-on: ubuntu-22.04
environment:

View File

@@ -15,10 +15,6 @@ focussing on maintainability, consistency and avoidance of common pitfalls.
> Error Prone is a static analysis tool for Java that catches common
> programming mistakes at compile-time.
Read more on how Picnic uses Error Prone (Support) in the blog post [_Picnic
loves Error Prone: producing high-quality and consistent Java
code_][picnic-blog-ep-post].
[![Maven Central][maven-central-badge]][maven-central-search]
[![GitHub Actions][github-actions-build-badge]][github-actions-build-master]
[![License][license-badge]][license]
@@ -63,7 +59,7 @@ it:
<artifactId>error-prone-contrib</artifactId>
<version>${error-prone-support.version}</version>
</path>
<!-- Error Prone Support's Refaster rules. -->
<!-- Error Prone Support's Refaster templates. -->
<path>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>refaster-runner</artifactId>
@@ -122,7 +118,7 @@ $ mvn clean install
[INFO] -------------------------------------------------------------
[WARNING] COMPILATION WARNING :
[INFO] -------------------------------------------------------------
[WARNING] Example.java:[9,34] [tech.picnic.errorprone.refasterrules.BigDecimalRules.BigDecimalZero]
[WARNING] Example.java:[9,34] [tech.picnic.errorprone.refastertemplates.BigDecimalTemplates.BigDecimalZero]
Did you mean 'return BigDecimal.ZERO;'?
[WARNING] Example.java:[13,35] [IdentityConversion] This method invocation appears redundant; remove it or suppress this warning and add a comment explaining its purpose
(see https://error-prone.picnic.tech/bugpatterns/IdentityConversion)
@@ -136,12 +132,12 @@ Two things are kicking in here:
1. An Error Prone [`BugChecker`][error-prone-bugchecker] that flags unnecessary
[identity conversions][bug-checks-identity-conversion].
2. A [Refaster][refaster] rule capable of
[rewriting][refaster-rules-bigdecimal] expressions of the form
2. A [Refaster][refaster] template capable of
[rewriting][refaster-templates-bigdecimal] expressions of the form
`BigDecimal.valueOf(0)` and `new BigDecimal(0)` to `BigDecimal.ZERO`.
Be sure to check out all [bug checks][bug-checks] and [refaster
rules][refaster-rules].
templates][refaster-templates].
## 👷 Developing Error Prone Support
@@ -222,10 +218,9 @@ guidelines][contributing].
[maven-central-search]: https://search.maven.org/artifact/tech.picnic.error-prone-support/error-prone-support
[maven]: https://maven.apache.org
[picnic-blog]: https://blog.picnic.nl
[picnic-blog-ep-post]: https://blog.picnic.nl/picnic-loves-error-prone-producing-high-quality-and-consistent-java-code-b8a566be6886
[pitest]: https://pitest.org
[pitest-maven]: https://pitest.org/quickstart/maven
[pr-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg
[refaster]: https://errorprone.info/docs/refaster
[refaster-rules-bigdecimal]: https://github.com/PicnicSupermarket/error-prone-support/blob/master/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/BigDecimalRules.java
[refaster-rules]: https://github.com/PicnicSupermarket/error-prone-support/blob/master/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/
[refaster-templates-bigdecimal]: https://github.com/PicnicSupermarket/error-prone-support/blob/master/error-prone-contrib/src/main/java/tech/picnic/errorprone/refastertemplates/BigDecimalTemplates.java
[refaster-templates]: https://github.com/PicnicSupermarket/error-prone-support/blob/master/error-prone-contrib/src/main/java/tech/picnic/errorprone/refastertemplates/

View File

@@ -1,26 +1,15 @@
package tech.picnic.errorprone.plugin;
import com.google.common.collect.ImmutableList;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.sun.source.tree.ClassTree;
import com.sun.source.util.TaskEvent;
import tech.picnic.errorprone.plugin.models.BugPatternData;
import tech.picnic.errorprone.plugin.objects.BugPatternData;
public final class BugPatternExtractor implements DocExtractor<BugPatternData> {
@Override
public BugPatternData extractData(ClassTree tree, TaskEvent taskEvent, VisitorState state) {
BugPattern annotation = taskEvent.getTypeElement().getAnnotation(BugPattern.class);
return BugPatternData.create(
taskEvent.getTypeElement().getQualifiedName().toString(),
taskEvent.getTypeElement().getSimpleName().toString(),
ImmutableList.copyOf(annotation.altNames()),
annotation.linkType(),
annotation.link(),
ImmutableList.copyOf(annotation.tags()),
annotation.summary(),
annotation.explanation(),
annotation.severity(),
annotation.disableable());
return BugPatternData.create(annotation, taskEvent.getTypeElement().getSimpleName().toString());
}
}

View File

@@ -1,11 +1,12 @@
package tech.picnic.errorprone.plugin;
import static com.google.errorprone.matchers.Matchers.allOf;
import static com.google.errorprone.matchers.Matchers.anyOf;
import static com.google.errorprone.matchers.Matchers.hasAnnotation;
import static com.google.errorprone.matchers.Matchers.instanceMethod;
import static com.google.errorprone.matchers.Matchers.methodIsNamed;
import com.google.errorprone.VisitorState;
import com.google.errorprone.annotations.Var;
import com.google.errorprone.matchers.Matcher;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.ClassTree;
@@ -14,17 +15,15 @@ import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.util.TaskEvent;
import com.sun.source.util.TreeScanner;
import java.util.ArrayList;
import java.util.List;
import tech.picnic.errorprone.plugin.models.BugPatternReplacementTestData;
import tech.picnic.errorprone.plugin.models.BugPatternTestData;
import javax.annotation.Nullable;
import tech.picnic.errorprone.plugin.objects.BugPatternTestData;
/** XXX: Write this. */
// XXX: Take into account `expectUnchanged()`.
public final class BugPatternTestsExtractor implements DocExtractor<BugPatternTestData> {
private static final Matcher<MethodTree> JUNIT_TEST_METHOD =
allOf(hasAnnotation("org.junit.jupiter.api.Test"));
private static final Matcher<MethodTree> BUG_PATTERN_TEST =
allOf(
hasAnnotation("org.junit.jupiter.api.Test"),
anyOf(methodIsNamed("replacement"), methodIsNamed("identification")));
private static final Matcher<ExpressionTree> IDENTIFICATION_SOURCE_LINES =
instanceMethod()
.onDescendantOf("com.google.errorprone.CompilationTestHelper")
@@ -46,48 +45,57 @@ public final class BugPatternTestsExtractor implements DocExtractor<BugPatternTe
tree.getMembers().stream()
.filter(MethodTree.class::isInstance)
.map(MethodTree.class::cast)
.filter(m -> JUNIT_TEST_METHOD.matches(m, state))
.filter(m -> BUG_PATTERN_TEST.matches(m, state))
.forEach(m -> scanner.scan(m, null));
return BugPatternTestData.create(
name, scanner.getIdentificationTests(), scanner.getReplacementTests());
name, scanner.getIdentification(), scanner.getInput(), scanner.getOutput());
}
private static final class ScanBugCheckerTestData extends TreeScanner<Void, Void> {
private final VisitorState state;
private final List<String> identificationTests = new ArrayList<>();
private final List<BugPatternReplacementTestData> replacementTests = new ArrayList<>();
// XXX: Using this output field is a bit hacky. Come up with a better solution.
@Var private String output;
private String identification;
private String input;
private String output;
ScanBugCheckerTestData(VisitorState state) {
this.state = state;
}
public List<String> getIdentificationTests() {
return identificationTests;
public String getIdentification() {
return identification;
}
public List<BugPatternReplacementTestData> getReplacementTests() {
return replacementTests;
public String getInput() {
return input;
}
public String getOutput() {
return output;
}
@Nullable
@Override
public Void visitMethodInvocation(MethodInvocationTree node, Void unused) {
if (IDENTIFICATION_SOURCE_LINES.matches(node, state)) {
identificationTests.add(getSourceLines(node));
identification = getSourceLines(node);
} else if (REPLACEMENT_INPUT.matches(node, state)) {
replacementTests.add(BugPatternReplacementTestData.create(getSourceLines(node), output));
input = getSourceLines(node);
} else if (REPLACEMENT_OUTPUT.matches(node, state)) {
output = getSourceLines(node);
}
return super.visitMethodInvocation(node, unused);
}
private static String getSourceLines(MethodInvocationTree tree) {
private String getSourceLines(MethodInvocationTree tree) {
List<? extends ExpressionTree> sourceLines =
tree.getArguments().subList(1, tree.getArguments().size());
return getConstantSourceCode(sourceLines);
}
private String getConstantSourceCode(List<? extends ExpressionTree> sourceLines) {
StringBuilder source = new StringBuilder();
for (ExpressionTree sourceLine : sourceLines) {
@@ -95,6 +103,7 @@ public final class BugPatternTestsExtractor implements DocExtractor<BugPatternTe
if (value == null) {
return "";
}
source.append(value).append('\n');
}

View File

@@ -1,25 +0,0 @@
package tech.picnic.errorprone.plugin;
public enum DocType {
BUG_PATTERN("bug-pattern", new BugPatternExtractor()),
BUG_PATTERN_TEST("bug-pattern-test", new BugPatternTestsExtractor()),
// REFASTER("refaster", new RefasterExtractor()),
REFASTER_TEMPLATE_TEST_INPUT("refaster-test-input", new RefasterTestExtractor()),
REFASTER_TEMPLATE_TEST_OUTPUT("refaster-test-output", new RefasterTestExtractor());
private final String outputFileNamePrefix;
private final DocExtractor<?> docExtractor;
DocType(String outputFileNamePrefix, DocExtractor<?> docExtractor) {
this.outputFileNamePrefix = outputFileNamePrefix;
this.docExtractor = docExtractor;
}
public String getOutputFileNamePrefix() {
return outputFileNamePrefix;
}
public DocExtractor<?> getDocExtractor() {
return docExtractor;
}
}

View File

@@ -5,7 +5,11 @@ import com.sun.source.util.JavacTask;
import com.sun.source.util.Plugin;
import com.sun.tools.javac.api.BasicJavacTask;
/** XXX: Write. */
/**
* A variant of {@code com.google.errorprone.refaster.RefasterRuleCompiler} that outputs a {@code
* fully/qualified/Class.refaster} file for each compiled {@code fully.qualified.Class} that
* contains a Refaster template.
*/
@AutoService(Plugin.class)
public final class Docgen implements Plugin {
@Override

View File

@@ -0,0 +1,24 @@
package tech.picnic.errorprone.plugin;
public enum DocgenPart {
BUGPATTERN("bug-pattern-test-data.jsonl", new BugPatternExtractor()),
BUGPATTERN_TEST("bug-pattern-data.jsonl", new BugPatternTestsExtractor()),
REFASTER_TEMPLATE_TEST_INPUT("refaster-test-input-data.jsonl", new RefasterTestExtractor()),
REFASTER_TEMPLATE_TEST_OUTPUT("refaster-test-output-data.jsonl", new RefasterTestExtractor());
private final String dataFileName;
private final DocExtractor<?> extractor;
DocgenPart(String dataFileName, DocExtractor<?> extractor) {
this.dataFileName = dataFileName;
this.extractor = extractor;
}
public DocExtractor<?> getExtractor() {
return extractor;
}
public String getDataFileName() {
return dataFileName;
}
}

View File

@@ -1,12 +1,5 @@
package tech.picnic.errorprone.plugin;
import static tech.picnic.errorprone.plugin.DocType.BUG_PATTERN;
import static tech.picnic.errorprone.plugin.DocType.BUG_PATTERN_TEST;
import static tech.picnic.errorprone.plugin.DocType.REFASTER_TEMPLATE_TEST_INPUT;
import static tech.picnic.errorprone.plugin.DocType.REFASTER_TEMPLATE_TEST_OUTPUT;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
@@ -22,8 +15,6 @@ import com.sun.tools.javac.util.Context;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Optional;
import javax.tools.JavaFileObject;
@@ -37,57 +28,49 @@ final class DocgenTaskListener implements TaskListener {
private final ObjectMapper mapper =
new ObjectMapper()
.setVisibility(PropertyAccessor.FIELD, Visibility.ANY)
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
DocgenTaskListener(Context context, String path) {
this.context = context;
this.basePath = path.substring(path.indexOf('=') + 1) + "/docs";
this.basePath = path.substring(path.indexOf('=') + 1);
this.state = VisitorState.createForUtilityPurposes(context);
// XXX: Move this somewhere else?
try {
Files.createDirectories(Paths.get(basePath));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
@SuppressWarnings("SystemOut")
public void finished(TaskEvent taskEvent) {
ClassTree tree = JavacTrees.instance(context).getTree(taskEvent.getTypeElement());
JavaFileObject sourceFile = taskEvent.getSourceFile();
if (tree == null || sourceFile == null || taskEvent.getKind() != TaskEvent.Kind.ANALYZE) {
if (tree == null || taskEvent.getSourceFile() == null) {
return;
}
getDocType(tree, sourceFile)
getDocgenPart(tree, taskEvent)
.ifPresent(
docType ->
docgenPart ->
writeToFile(
docType.getDocExtractor().extractData(tree, taskEvent, state),
docType.getOutputFileNamePrefix(),
getSimpleClassName(sourceFile.getName())));
docgenPart.getExtractor().extractData(tree, taskEvent, state),
docgenPart.getDataFileName()));
}
private static Optional<DocType> getDocType(ClassTree tree, JavaFileObject sourceFile) {
if (isBugPattern(tree)) {
return Optional.of(BUG_PATTERN);
} else if (isBugPatternTest(tree)) {
return Optional.of(BUG_PATTERN_TEST);
private static Optional<DocgenPart> getDocgenPart(ClassTree tree, TaskEvent taskEvent) {
JavaFileObject sourceFile = taskEvent.getSourceFile();
if (isBugPatternTest(tree)) {
return Optional.of(DocgenPart.BUGPATTERN_TEST);
} else if (isBugPattern(tree)) {
return Optional.of(DocgenPart.BUGPATTERN);
} else if (sourceFile.getName().contains("TestInput")) {
return Optional.of(REFASTER_TEMPLATE_TEST_INPUT);
return Optional.of(DocgenPart.REFASTER_TEMPLATE_TEST_INPUT);
} else if (sourceFile.getName().contains("TestOutput")) {
return Optional.of(REFASTER_TEMPLATE_TEST_OUTPUT);
return Optional.of(DocgenPart.REFASTER_TEMPLATE_TEST_OUTPUT);
} else {
return Optional.empty();
}
return Optional.empty();
}
private <T> void writeToFile(T data, String fileName, String name) {
File file = new File(basePath + "/" + fileName + "-" + name + ".json");
// XXX: Use Path instead of File.
private <T> void writeToFile(T data, String fileName) {
File file = new File(basePath + "/" + fileName);
try (FileWriter fileWriter = new FileWriter(file, true)) {
mapper.writeValue(fileWriter, data);
@@ -103,21 +86,10 @@ final class DocgenTaskListener implements TaskListener {
private static boolean isBugPatternTest(ClassTree tree) {
return tree.getSimpleName().toString().endsWith("Test")
// XXX: Instead, omit files from the util directory
&& !tree.getSimpleName().toString().equals("MethodMatcherFactoryTest")
&& tree.getMembers().stream()
.filter(VariableTree.class::isInstance)
.map(VariableTree.class::cast)
.map(vt -> vt.getType().toString())
.anyMatch(
vt ->
vt.equals("BugCheckerRefactoringTestHelper")
|| vt.equals("CompilationTestHelper"));
}
private static String getSimpleClassName(String path) {
int index = path.lastIndexOf('/');
String fileName = path.substring(index + 1);
return fileName.replace(".java", "");
member -> member.getType().toString().equals("BugCheckerRefactoringTestHelper"));
}
}

View File

@@ -7,29 +7,26 @@ import com.google.errorprone.VisitorState;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.util.TaskEvent;
import tech.picnic.errorprone.plugin.models.RefasterTemplateCollectionTestData;
import tech.picnic.errorprone.plugin.models.RefasterTemplateTestData;
import tech.picnic.errorprone.plugin.objects.RefasterTemplateTestData;
public final class RefasterTestExtractor
implements DocExtractor<RefasterTemplateCollectionTestData> {
public class RefasterTestExtractor
implements DocExtractor<ImmutableList<RefasterTemplateTestData>> {
@Override
public RefasterTemplateCollectionTestData extractData(
public ImmutableList<RefasterTemplateTestData> extractData(
ClassTree tree, TaskEvent taskEvent, VisitorState state) {
String templateCollectionName = tree.getSimpleName().toString().replace("Test", "");
boolean isInput = taskEvent.getSourceFile().getName().contains("Input");
ImmutableList<RefasterTemplateTestData> templateTests =
tree.getMembers().stream()
.filter(MethodTree.class::isInstance)
.map(MethodTree.class::cast)
.filter(m -> m.getName().toString().startsWith("test"))
.map(
m ->
RefasterTemplateTestData.create(
m.getName().toString().replace("test", ""), m.toString()))
.collect(toImmutableList());
return RefasterTemplateCollectionTestData.create(
templateCollectionName, isInput, templateTests);
return tree.getMembers().stream()
.filter(MethodTree.class::isInstance)
.map(MethodTree.class::cast)
.filter(m -> m.getName().toString().startsWith("test"))
.map(
m ->
RefasterTemplateTestData.create(
templateCollectionName,
m.getName().toString().replace("test", ""),
m.toString()))
.collect(toImmutableList());
}
}

View File

@@ -1,55 +0,0 @@
package tech.picnic.errorprone.plugin.models;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.errorprone.BugPattern.LinkType;
import com.google.errorprone.BugPattern.SeverityLevel;
/** XXX: Write. */
// XXX: What about `SuppressionAnnotations` and `DocumentSuppression`?
@AutoValue
public abstract class BugPatternData {
public static BugPatternData create(
String fullyQualifiedName,
String name,
ImmutableList<String> altNames,
LinkType linkType,
String link,
ImmutableList<String> tags,
String summary,
String explanation,
SeverityLevel severityLevel,
boolean disableable) {
return new AutoValue_BugPatternData(
fullyQualifiedName,
name,
altNames,
linkType,
link,
tags,
summary,
explanation,
severityLevel,
disableable);
}
abstract String fullyQualifiedName();
abstract String name();
abstract ImmutableList<String> altNames();
abstract LinkType linkType();
abstract String link();
abstract ImmutableList<String> tags();
abstract String summary();
abstract String explanation();
abstract SeverityLevel severityLevel();
abstract boolean disableable();
}

View File

@@ -1,17 +0,0 @@
package tech.picnic.errorprone.plugin.models;
import com.google.auto.value.AutoValue;
import javax.annotation.Nullable;
@AutoValue
public abstract class BugPatternReplacementTestData {
public static BugPatternReplacementTestData create(String inputLines, String outputLines) {
return new AutoValue_BugPatternReplacementTestData(inputLines, outputLines);
}
@Nullable
abstract String inputLines();
@Nullable
abstract String outputLines();
}

View File

@@ -1,23 +0,0 @@
package tech.picnic.errorprone.plugin.models;
import com.google.auto.value.AutoValue;
import java.util.List;
import javax.annotation.Nullable;
@AutoValue
public abstract class BugPatternTestData {
public static BugPatternTestData create(
String name,
List<String> identificationTests,
List<BugPatternReplacementTestData> replacementTests) {
return new AutoValue_BugPatternTestData(name, identificationTests, replacementTests);
}
abstract String name();
@Nullable
abstract List<String> identificationTests();
@Nullable
abstract List<BugPatternReplacementTestData> replacementTests();
}

View File

@@ -1,24 +0,0 @@
package tech.picnic.errorprone.plugin.models;
import com.google.auto.value.AutoValue;
import java.util.List;
/**
* Object containing all data related to a Refaster template collection. This is solely used for
* serialization.
*/
@AutoValue
public abstract class RefasterTemplateCollectionData {
public static RefasterTemplateCollectionData create(
String name, String description, String link, List<RefasterTemplateData> templates) {
return new AutoValue_RefasterTemplateCollectionData(name, description, link, templates);
}
abstract String name();
abstract String description();
abstract String link();
abstract List<RefasterTemplateData> templates();
}

View File

@@ -1,19 +0,0 @@
package tech.picnic.errorprone.plugin.models;
import com.google.auto.value.AutoValue;
import java.util.List;
@AutoValue
public abstract class RefasterTemplateCollectionTestData {
public static RefasterTemplateCollectionTestData create(
String templateCollection, boolean isInput, List<RefasterTemplateTestData> templatesTests) {
return new AutoValue_RefasterTemplateCollectionTestData(
templateCollection, isInput, templatesTests);
}
abstract String templateCollection();
abstract boolean isInput();
abstract List<RefasterTemplateTestData> templateTests();
}

View File

@@ -1,14 +0,0 @@
package tech.picnic.errorprone.plugin.models;
import com.google.auto.value.AutoValue;
@AutoValue
public abstract class RefasterTemplateTestData {
public static RefasterTemplateTestData create(String templateName, String templateTestContent) {
return new AutoValue_RefasterTemplateTestData(templateName, templateTestContent);
}
abstract String templateName();
abstract String templateTestContent();
}

View File

@@ -0,0 +1,56 @@
package tech.picnic.errorprone.plugin.objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.auto.value.AutoValue;
import com.google.errorprone.BugPattern;
import com.google.errorprone.BugPattern.LinkType;
import com.google.errorprone.BugPattern.SeverityLevel;
import java.util.Arrays;
@AutoValue
public abstract class BugPatternData {
public static BugPatternData create(BugPattern annotation, String name) {
return new AutoValue_BugPatternData(
name,
Arrays.toString(annotation.altNames()),
annotation.linkType(),
annotation.link(),
Arrays.toString(annotation.tags()),
annotation.summary(),
annotation.explanation(),
annotation.severity(),
annotation.disableable());
}
@JsonProperty
abstract String name();
// Should be String[]
@JsonProperty
abstract String altNames();
@JsonProperty
abstract LinkType linkType();
@JsonProperty
abstract String link();
@JsonProperty
// Should be String[]
abstract String tags();
@JsonProperty
abstract String summary();
@JsonProperty
abstract String explanation();
@JsonProperty
abstract SeverityLevel severityLevel();
@JsonProperty
abstract boolean disableable();
// SuppressionAnnotations?
// DocumentSuppression?
}

View File

@@ -0,0 +1,28 @@
package tech.picnic.errorprone.plugin.objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.auto.value.AutoValue;
import javax.annotation.Nullable;
@AutoValue
public abstract class BugPatternTestData {
public static BugPatternTestData create(
String name, String identificationLines, String inputLines, String outputLines) {
return new AutoValue_BugPatternTestData(name, identificationLines, inputLines, outputLines);
}
@JsonProperty
abstract String name();
@Nullable
@JsonProperty
abstract String identificationLines();
@Nullable
@JsonProperty
abstract String inputLines();
@Nullable
@JsonProperty
abstract String outputLines();
}

View File

@@ -1,5 +1,6 @@
package tech.picnic.errorprone.plugin.models;
package tech.picnic.errorprone.plugin.objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.auto.value.AutoValue;
import com.google.errorprone.BugPattern.SeverityLevel;
@@ -10,11 +11,15 @@ public abstract class RefasterTemplateData {
return new AutoValue_RefasterTemplateData(name, description, link, severityLevel);
}
@JsonProperty
abstract String name();
@JsonProperty
abstract String description();
@JsonProperty
abstract String link();
@JsonProperty
abstract SeverityLevel severityLevel();
}

View File

@@ -0,0 +1,22 @@
package tech.picnic.errorprone.plugin.objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.auto.value.AutoValue;
@AutoValue
public abstract class RefasterTemplateTestData {
public static RefasterTemplateTestData create(
String templateCollection, String templateName, String templateTestContent) {
return new AutoValue_RefasterTemplateTestData(
templateCollection, templateName, templateTestContent);
}
@JsonProperty
abstract String templateCollection();
@JsonProperty
abstract String templateName();
@JsonProperty
abstract String templateTestContent();
}

View File

@@ -267,7 +267,7 @@ Refaster's expressiveness:
motivating example, see the two subtly different loop definitions in
`CollectionRemoveAllFromCollectionExpression`.
- Figure out why Refaster sometimes doesn't match the correct generic overload.
See the `AssertThatIterableHasOneComparableElementEqualTo` rule for an
See the `AssertThatIterableHasOneComparableElementEqualTo` template for an
example.
[autorefactor]: https://autorefactor.org

View File

@@ -24,7 +24,7 @@ import com.sun.source.tree.MethodInvocationTree;
/**
* A {@link BugChecker} that flags AssertJ {@code isEqualTo(null)} checks for simplification.
*
* <p>This bug checker cannot be replaced with a simple Refaster rule, as the Refaster approach
* <p>This bug checker cannot be replaced with a simple Refaster template, as the Refaster approach
* would require that all overloads of {@link org.assertj.core.api.Assert#isEqualTo(Object)} (such
* as {@link org.assertj.core.api.AbstractStringAssert#isEqualTo(String)}) are explicitly
* enumerated. This bug checker generically matches all such current and future overloads.

View File

@@ -86,6 +86,6 @@ public final class ExplicitEnumOrdering extends BugChecker implements MethodInvo
private static Stream<String> getMissingEnumValues(Type enumType, Set<String> values) {
Symbol.TypeSymbol typeSymbol = enumType.asElement();
return Sets.difference(ASTHelpers.enumValues(typeSymbol), values).stream()
.map(v -> String.join(".", typeSymbol.getSimpleName(), v));
.map(v -> String.format("%s.%s", typeSymbol.getSimpleName(), v));
}
}

View File

@@ -48,7 +48,7 @@ import tech.picnic.errorprone.bugpatterns.util.SourceCode;
// `Formattable#toString` invocation with a `Formattable#formatTo` invocation. But likely that
// should be considered a bug fix, too.
// XXX: Introduce a separate check that adds/removes the `Locale` parameter to `String.format`
// invocations, as necessary. See also a comment in the `StringJoin` check.
// invocations, as necessary.
@AutoService(BugChecker.class)
@BugPattern(
summary = "Defer string concatenation to the invoked method",

View File

@@ -1,6 +1,5 @@
package tech.picnic.errorprone.bugpatterns;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.errorprone.BugPattern.LinkType.CUSTOM;
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
import static com.google.errorprone.BugPattern.StandardTags.STYLE;
@@ -10,7 +9,6 @@ import static java.util.stream.Collectors.joining;
import static tech.picnic.errorprone.bugpatterns.util.Documentation.BUG_PATTERNS_BASE_URL;
import com.google.auto.service.AutoService;
import com.google.common.base.Splitter;
import com.google.common.collect.Comparators;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -73,12 +71,6 @@ public final class LexicographicalAnnotationAttributeListing extends BugChecker
private static final String FLAG_PREFIX = "LexicographicalAnnotationAttributeListing:";
private static final String INCLUDED_ANNOTATIONS_FLAG = FLAG_PREFIX + "Includes";
private static final String EXCLUDED_ANNOTATIONS_FLAG = FLAG_PREFIX + "Excludes";
/**
* The splitter applied to string-typed annotation arguments prior to lexicographical sorting. By
* splitting on {@code =}, strings that represent e.g. inline Spring property declarations are
* properly sorted by key, then value.
*/
private static final Splitter STRING_ARGUMENT_SPLITTER = Splitter.on('=');
private final AnnotationAttributeMatcher matcher;
@@ -134,7 +126,7 @@ public final class LexicographicalAnnotationAttributeListing extends BugChecker
}
List<? extends ExpressionTree> actualOrdering = array.getInitializers();
ImmutableList<? extends ExpressionTree> desiredOrdering = doSort(actualOrdering);
ImmutableList<? extends ExpressionTree> desiredOrdering = doSort(actualOrdering, state);
if (actualOrdering.equals(desiredOrdering)) {
/* In the (presumably) common case the elements are already sorted. */
return Optional.empty();
@@ -164,12 +156,12 @@ public final class LexicographicalAnnotationAttributeListing extends BugChecker
}
private static ImmutableList<? extends ExpressionTree> doSort(
Iterable<? extends ExpressionTree> elements) {
Iterable<? extends ExpressionTree> elements, VisitorState state) {
// XXX: Perhaps we should use `Collator` with `.setStrength(Collator.PRIMARY)` and
// `getCollationKey`. Not clear whether that's worth the hassle at this point.
return ImmutableList.sortedCopyOf(
comparing(
LexicographicalAnnotationAttributeListing::getStructure,
e -> getStructure(e, state),
Comparators.lexicographical(
Comparators.lexicographical(
String.CASE_INSENSITIVE_ORDER.thenComparing(naturalOrder())))),
@@ -181,34 +173,38 @@ public final class LexicographicalAnnotationAttributeListing extends BugChecker
* performed. This approach disregards e.g. irrelevant whitespace. It also allows special
* structure within string literals to be respected.
*/
private static ImmutableList<ImmutableList<String>> getStructure(ExpressionTree array) {
private static ImmutableList<ImmutableList<String>> getStructure(
ExpressionTree array, VisitorState state) {
ImmutableList.Builder<ImmutableList<String>> nodes = ImmutableList.builder();
new TreeScanner<Void, Void>() {
@Nullable
@Override
public Void visitIdentifier(IdentifierTree node, @Nullable Void unused) {
nodes.add(ImmutableList.of(node.getName().toString()));
return super.visitIdentifier(node, unused);
public Void visitIdentifier(IdentifierTree node, @Nullable Void ctx) {
nodes.add(tokenize(node));
return super.visitIdentifier(node, ctx);
}
@Nullable
@Override
public Void visitLiteral(LiteralTree node, @Nullable Void unused) {
Object value = ASTHelpers.constValue(node);
nodes.add(
value instanceof String
? STRING_ARGUMENT_SPLITTER.splitToStream((String) value).collect(toImmutableList())
: ImmutableList.of(String.valueOf(value)));
return super.visitLiteral(node, unused);
public Void visitLiteral(LiteralTree node, @Nullable Void ctx) {
nodes.add(tokenize(node));
return super.visitLiteral(node, ctx);
}
@Nullable
@Override
public Void visitPrimitiveType(PrimitiveTypeTree node, @Nullable Void unused) {
nodes.add(ImmutableList.of(node.getPrimitiveTypeKind().toString()));
return super.visitPrimitiveType(node, unused);
public Void visitPrimitiveType(PrimitiveTypeTree node, @Nullable Void ctx) {
nodes.add(tokenize(node));
return super.visitPrimitiveType(node, ctx);
}
private ImmutableList<String> tokenize(Tree node) {
/*
* Tokens are split on `=` so that e.g. inline Spring property declarations are properly
* sorted by key, then value.
*/
return ImmutableList.copyOf(SourceCode.treeToString(node, state).split("=", -1));
}
}.scan(array, null);

View File

@@ -25,7 +25,7 @@ import com.sun.source.tree.Tree;
/** A {@link BugChecker} that flags likely missing Refaster annotations. */
@AutoService(BugChecker.class)
@BugPattern(
summary = "The Refaster rule contains a method without any Refaster annotations",
summary = "The Refaster template contains a method without any Refaster annotations",
link = BUG_PATTERNS_BASE_URL + "MissingRefasterAnnotation",
linkType = CUSTOM,
severity = WARNING,

View File

@@ -22,8 +22,8 @@ import tech.picnic.errorprone.bugpatterns.util.SourceCode;
/**
* A {@link BugChecker} that flags unnecessary {@link Refaster#anyOf(Object[])} usages.
*
* <p>Note that this logic can't be implemented as a Refaster rule, as the {@link Refaster} class is
* treated specially.
* <p>Note that this logic can't be implemented as a Refaster template, as the {@link Refaster}
* class is treated specially.
*/
@AutoService(BugChecker.class)
@BugPattern(

View File

@@ -35,11 +35,11 @@ import javax.lang.model.element.Modifier;
@AutoService(BugChecker.class)
@BugPattern(
summary = "Refaster class and method definitions should specify a canonical set of modifiers",
link = BUG_PATTERNS_BASE_URL + "RefasterRuleModifiers",
link = BUG_PATTERNS_BASE_URL + "RefasterTemplateModifiers",
linkType = CUSTOM,
severity = SUGGESTION,
tags = STYLE)
public final class RefasterRuleModifiers extends BugChecker
public final class RefasterTemplateModifiers extends BugChecker
implements ClassTreeMatcher, MethodTreeMatcher {
private static final long serialVersionUID = 1L;
private static final Matcher<Tree> BEFORE_TEMPLATE_METHOD = hasAnnotation(BeforeTemplate.class);
@@ -85,8 +85,8 @@ public final class RefasterRuleModifiers extends BugChecker
if (!hasMatchingMember(tree, PLACEHOLDER_METHOD, state)) {
/*
* Rules without a `@Placeholder` method should be `final`. Note that Refaster enforces
* that `@Placeholder` methods are `abstract`, so rules _with_ such a method will
* Templates without a `@Placeholder` method should be `final`. Note that Refaster enforces
* that `@Placeholder` methods are `abstract`, so templates _with_ such a method will
* naturally be `abstract` and non-`final`.
*/
modifiersToAdd.add(Modifier.FINAL);

View File

@@ -29,7 +29,6 @@ import tech.picnic.errorprone.bugpatterns.util.SourceCode;
// XXX: The special-casing of Throwable applies only to SLF4J 1.6.0+; see
// https://www.slf4j.org/faq.html#paramException. That should be documented.
// XXX: Also simplify `LOG.error(String.format("Something %s", arg), throwable)`.
// XXX: Also simplify `LOG.error(String.join("sep", arg1, arg2), throwable)`? Perhaps too obscure.
// XXX: Write a similar checker for Spring RestTemplates, String.format and friends, Guava
// preconditions, ...
@AutoService(BugChecker.class)

View File

@@ -1,182 +0,0 @@
package tech.picnic.errorprone.bugpatterns;
import static com.google.errorprone.BugPattern.LinkType.NONE;
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
import static com.google.errorprone.matchers.method.MethodMatchers.staticMethod;
import com.google.auto.service.AutoService;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher;
import com.google.errorprone.fixes.SuggestedFix;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.matchers.Matcher;
import com.google.errorprone.suppliers.Supplier;
import com.google.errorprone.suppliers.Suppliers;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.util.Convert;
import java.util.Formattable;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Nullable;
import tech.picnic.errorprone.bugpatterns.util.SourceCode;
/**
* A {@link BugChecker} which flags {@link String#format(String, Object...)} invocations which can
* be replaced with a {@link String#join(CharSequence, CharSequence...)} or even a {@link
* String#valueOf} invocation.
*/
// XXX: What about `v1 + "sep" + v2` and similar expressions? Do we want to rewrite those to
// `String.join`, or should some `String.join` invocations be rewritten to use the `+` operator?
// (The latter suggestion would conflict with the `FormatStringConcatenation` check.)
@AutoService(BugChecker.class)
@BugPattern(
summary = "Prefer `String#join` over `String#format`",
linkType = NONE,
severity = SUGGESTION,
tags = SIMPLIFICATION)
public final class StringJoin extends BugChecker implements MethodInvocationTreeMatcher {
private static final long serialVersionUID = 1L;
private static final Splitter FORMAT_SPECIFIER_SPLITTER = Splitter.on("%s");
private static final Matcher<ExpressionTree> STRING_FORMAT_INVOCATION =
staticMethod().onClass(String.class.getName()).named("format");
private static final Supplier<Type> CHAR_SEQUENCE_TYPE =
Suppliers.typeFromClass(CharSequence.class);
private static final Supplier<Type> FORMATTABLE_TYPE = Suppliers.typeFromClass(Formattable.class);
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
if (!STRING_FORMAT_INVOCATION.matches(tree, state)) {
return Description.NO_MATCH;
}
// XXX: This check assumes that if the first argument to `String#format` is a `Locale`, that
// this argument is not vacuous, and that as a result the expression cannot be simplified using
// `#valueOf` or `#join`. Implement a separate check that identifies and drops redundant
// `Locale` arguments. See also a related comment in `FormatStringConcatenation`.
String formatString = ASTHelpers.constValue(tree.getArguments().get(0), String.class);
if (formatString == null) {
return Description.NO_MATCH;
}
List<String> separators = FORMAT_SPECIFIER_SPLITTER.splitToList(formatString);
if (separators.size() < 2) {
/* The format string does not contain `%s` format specifiers. */
return Description.NO_MATCH;
}
if (separators.size() != tree.getArguments().size()) {
/* The number of arguments does not match the number of `%s` format specifiers. */
return Description.NO_MATCH;
}
int lastIndex = separators.size() - 1;
if (!separators.get(0).isEmpty() || !separators.get(lastIndex).isEmpty()) {
/* The format string contains leading or trailing characters. */
return Description.NO_MATCH;
}
ImmutableSet<String> innerSeparators = ImmutableSet.copyOf(separators.subList(1, lastIndex));
if (innerSeparators.size() > 1) {
/* The `%s` format specifiers are not uniformly separated. */
return Description.NO_MATCH;
}
if (innerSeparators.isEmpty()) {
/*
* This `String#format` invocation performs a straightforward string conversion; use
* `String#valueOf` instead.
*/
return trySuggestExplicitStringConversion(tree, state);
}
String separator = Iterables.getOnlyElement(innerSeparators);
if (separator.indexOf('%') >= 0) {
/* The `%s` format specifiers are separated by another format specifier. */
// XXX: Strictly speaking we could support `%%` by mapping it to a literal `%`, but that
// doesn't seem worth the trouble.
return Description.NO_MATCH;
}
return trySuggestExplicitJoin(tree, separator, state);
}
/**
* If guaranteed to be behavior preserving, suggests replacing {@code String.format("%s", arg)}
* with {@code String.valueOf(arg)}.
*
* <p>If {@code arg} is already a string then the resultant conversion is vacuous. The {@link
* IdentityConversion} check will subsequently drop it.
*/
private Description trySuggestExplicitStringConversion(
MethodInvocationTree tree, VisitorState state) {
ExpressionTree argument = tree.getArguments().get(1);
if (isSubtype(ASTHelpers.getType(argument), FORMATTABLE_TYPE, state)) {
/*
* `Formattable` arguments are handled specially; `String#valueOf` is not a suitable
* alternative.
*/
return Description.NO_MATCH;
}
return buildDescription(tree)
.setMessage("Prefer `String#valueOf` over `String#format`")
.addFix(SuggestedFix.replace(tree, withStringConversionExpression(argument, state)))
.build();
}
/**
* Unless the given {@code String.format} expression includes {@link Formattable} arguments,
* suggests replacing it with a {@code String.join} expression using the specified argument
* separator.
*/
private Description trySuggestExplicitJoin(
MethodInvocationTree tree, String separator, VisitorState state) {
Iterator<? extends ExpressionTree> arguments = tree.getArguments().iterator();
SuggestedFix.Builder fix =
SuggestedFix.builder()
.replace(tree.getMethodSelect(), "String.join")
.replace(arguments.next(), String.format("\"%s\"", Convert.quote(separator)));
while (arguments.hasNext()) {
ExpressionTree argument = arguments.next();
Type argumentType = ASTHelpers.getType(argument);
if (isSubtype(argumentType, FORMATTABLE_TYPE, state)) {
/*
* `Formattable` arguments are handled specially; `String#join` is not a suitable
* alternative.
*/
return Description.NO_MATCH;
}
if (!isSubtype(argumentType, CHAR_SEQUENCE_TYPE, state)) {
/*
* The argument was previously implicitly converted to a string; now this must happen
* explicitly.
*/
fix.replace(argument, withStringConversionExpression(argument, state));
}
}
return describeMatch(tree, fix.build());
}
private static boolean isSubtype(
@Nullable Type subType, Supplier<Type> superType, VisitorState state) {
return ASTHelpers.isSubtype(subType, superType.get(state), state);
}
private static String withStringConversionExpression(
ExpressionTree argument, VisitorState state) {
return String.format("String.valueOf(%s)", SourceCode.treeToString(argument, state));
}
}

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static org.assertj.core.data.Offset.offset;
import static org.assertj.core.data.Percentage.withPercentage;
@@ -9,21 +9,19 @@ import com.google.errorprone.refaster.annotation.BeforeTemplate;
import java.math.BigDecimal;
import org.assertj.core.api.AbstractBigDecimalAssert;
import org.assertj.core.api.BigDecimalAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/**
* Refaster rules related to AssertJ assertions over {@link BigDecimal}s.
* Refaster templates related to AssertJ assertions over {@link BigDecimal}s.
*
* <p>Note that, contrary to collections of Refaster rules for other {@link
* org.assertj.core.api.NumberAssert} subtypes, these rules do not rewrite to/from {@link
* <p>Note that, contrary to collections of Refaster templates for other {@link
* org.assertj.core.api.NumberAssert} subtypes, these templates do not rewrite to/from {@link
* BigDecimalAssert#isEqualTo(Object)} and {@link BigDecimalAssert#isNotEqualTo(Object)}. This is
* because {@link BigDecimal#equals(Object)} considers not only the numeric value of compared
* instances, but also their scale. As a result various seemingly straightforward transformations
* would actually subtly change the assertion's semantics.
*/
@OnlineDocumentation
final class AssertJBigDecimalRules {
private AssertJBigDecimalRules() {}
final class AssertJBigDecimalTemplates {
private AssertJBigDecimalTemplates() {}
static final class AbstractBigDecimalAssertIsEqualByComparingTo {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static org.assertj.core.data.Offset.offset;
import static org.assertj.core.data.Percentage.withPercentage;
@@ -8,13 +8,11 @@ import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import java.math.BigInteger;
import org.assertj.core.api.AbstractBigIntegerAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
// XXX: If we add a rule that drops unnecessary `L` suffixes from literal longs, then the `0L`/`1L`
// cases below can go.
@OnlineDocumentation
final class AssertJBigIntegerRules {
private AssertJBigIntegerRules() {}
final class AssertJBigIntegerTemplates {
private AssertJBigIntegerTemplates() {}
static final class AbstractBigIntegerAssertIsEqualTo {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static org.assertj.core.api.Assertions.assertThat;
@@ -8,11 +8,9 @@ import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import org.assertj.core.api.AbstractBooleanAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@OnlineDocumentation
final class AssertJBooleanRules {
private AssertJBooleanRules() {}
final class AssertJBooleanTemplates {
private AssertJBooleanTemplates() {}
static final class AbstractBooleanAssertIsEqualTo {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static org.assertj.core.data.Offset.offset;
import static org.assertj.core.data.Percentage.withPercentage;
@@ -7,11 +7,9 @@ import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import org.assertj.core.api.AbstractByteAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@OnlineDocumentation
final class AssertJByteRules {
private AssertJByteRules() {}
final class AssertJByteTemplates {
private AssertJByteTemplates() {}
static final class AbstractByteAssertIsEqualTo {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static org.assertj.core.api.Assertions.assertThat;
@@ -8,11 +8,9 @@ import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import org.assertj.core.api.AbstractAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@OnlineDocumentation
final class AssertJCharSequenceRules {
private AssertJCharSequenceRules() {}
final class AssertJCharSequenceTemplates {
private AssertJCharSequenceTemplates() {}
static final class AssertThatCharSequenceIsEmpty {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static org.assertj.core.api.Assertions.assertThat;
@@ -8,11 +8,9 @@ import com.google.errorprone.refaster.annotation.BeforeTemplate;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import org.assertj.core.api.AbstractComparableAssert;
import org.assertj.core.api.AbstractIntegerAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@OnlineDocumentation
final class AssertJComparableRules {
private AssertJComparableRules() {}
final class AssertJComparableTemplates {
private AssertJComparableTemplates() {}
static final class AssertThatIsEqualByComparingTo<T extends Comparable<? super T>> {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static org.assertj.core.data.Offset.offset;
import static org.assertj.core.data.Percentage.withPercentage;
@@ -8,11 +8,9 @@ import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import org.assertj.core.api.AbstractDoubleAssert;
import org.assertj.core.data.Offset;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@OnlineDocumentation
final class AssertJDoubleRules {
private AssertJDoubleRules() {}
final class AssertJDoubleTemplates {
private AssertJDoubleTemplates() {}
static final class AbstractDoubleAssertIsCloseToWithOffset {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import com.google.common.collect.Iterables;
import com.google.errorprone.refaster.Refaster;
@@ -6,11 +6,9 @@ import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import java.util.Collection;
import org.assertj.core.api.EnumerableAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@OnlineDocumentation
final class AssertJEnumerableRules {
private AssertJEnumerableRules() {}
final class AssertJEnumerableTemplates {
private AssertJEnumerableTemplates() {}
static final class EnumerableAssertIsEmpty<E> {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static org.assertj.core.data.Offset.offset;
import static org.assertj.core.data.Percentage.withPercentage;
@@ -8,11 +8,9 @@ import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import org.assertj.core.api.AbstractFloatAssert;
import org.assertj.core.data.Offset;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@OnlineDocumentation
final class AssertJFloatRules {
private AssertJFloatRules() {}
final class AssertJFloatTemplates {
private AssertJFloatTemplates() {}
static final class AbstractFloatAssertIsCloseToWithOffset {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static org.assertj.core.data.Offset.offset;
import static org.assertj.core.data.Percentage.withPercentage;
@@ -7,11 +7,9 @@ import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import org.assertj.core.api.AbstractIntegerAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@OnlineDocumentation
final class AssertJIntegerRules {
private AssertJIntegerRules() {}
final class AssertJIntegerTemplates {
private AssertJIntegerTemplates() {}
static final class AbstractIntegerAssertIsEqualTo {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static org.assertj.core.data.Offset.offset;
import static org.assertj.core.data.Percentage.withPercentage;
@@ -7,11 +7,9 @@ import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import org.assertj.core.api.AbstractLongAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@OnlineDocumentation
final class AssertJLongRules {
private AssertJLongRules() {}
final class AssertJLongTemplates {
private AssertJLongTemplates() {}
static final class AbstractLongAssertIsEqualTo {
@BeforeTemplate

View File

@@ -1,15 +1,13 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import com.google.common.collect.ImmutableMap;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import java.util.Map;
import org.assertj.core.api.AbstractMapAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@OnlineDocumentation
final class AssertJMapRules {
private AssertJMapRules() {}
final class AssertJMapTemplates {
private AssertJMapTemplates() {}
static final class AbstractMapAssertContainsExactlyInAnyOrderEntriesOf<K, V> {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static org.assertj.core.api.Assertions.assertThat;
@@ -19,12 +19,10 @@ import org.assertj.core.api.AbstractIntegerAssert;
import org.assertj.core.api.AbstractLongAssert;
import org.assertj.core.api.AbstractShortAssert;
import org.assertj.core.api.NumberAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
import tech.picnic.errorprone.refaster.matchers.IsCharacter;
@OnlineDocumentation
final class AssertJNumberRules {
private AssertJNumberRules() {}
final class AssertJNumberTemplates {
private AssertJNumberTemplates() {}
static final class NumberAssertIsPositive {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static org.assertj.core.api.Assertions.assertThat;
@@ -10,11 +10,9 @@ import com.google.errorprone.refaster.annotation.UseImportPolicy;
import org.assertj.core.api.AbstractBooleanAssert;
import org.assertj.core.api.AbstractStringAssert;
import org.assertj.core.api.ObjectAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@OnlineDocumentation
final class AssertJObjectRules {
private AssertJObjectRules() {}
final class AssertJObjectTemplates {
private AssertJObjectTemplates() {}
static final class AssertThatIsInstanceOf<S, T> {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static org.assertj.core.api.Assertions.assertThat;
@@ -14,11 +14,9 @@ import org.assertj.core.api.AbstractObjectAssert;
import org.assertj.core.api.AbstractOptionalAssert;
import org.assertj.core.api.ObjectAssert;
import org.assertj.core.api.OptionalAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@OnlineDocumentation
final class AssertJOptionalRules {
private AssertJOptionalRules() {}
final class AssertJOptionalTemplates {
private AssertJOptionalTemplates() {}
static final class AssertThatOptional<T> {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static org.assertj.core.api.Assertions.assertThat;
@@ -9,11 +9,9 @@ import com.google.errorprone.refaster.annotation.BeforeTemplate;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import org.assertj.core.api.AbstractBooleanAssert;
import org.assertj.core.api.AbstractDoubleAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@OnlineDocumentation
final class AssertJPrimitiveRules {
private AssertJPrimitiveRules() {}
final class AssertJPrimitiveTemplates {
private AssertJPrimitiveTemplates() {}
static final class AssertThatIsEqualTo {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static org.assertj.core.data.Offset.offset;
import static org.assertj.core.data.Percentage.withPercentage;
@@ -7,11 +7,9 @@ import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import org.assertj.core.api.AbstractShortAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@OnlineDocumentation
final class AssertJShortRules {
private AssertJShortRules() {}
final class AssertJShortTemplates {
private AssertJShortTemplates() {}
static final class AbstractShortAssertIsEqualTo {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static org.assertj.core.api.Assertions.assertThat;
@@ -8,11 +8,9 @@ import com.google.errorprone.refaster.annotation.BeforeTemplate;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.AbstractStringAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@OnlineDocumentation
final class AssertJStringRules {
private AssertJStringRules() {}
final class AssertJStringTemplates {
private AssertJStringTemplates() {}
static final class AbstractStringAssertStringIsEmpty {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static org.assertj.core.api.Assertions.assertThat;
@@ -53,10 +53,9 @@ import org.assertj.core.api.ObjectEnumerableAssert;
import org.assertj.core.api.OptionalDoubleAssert;
import org.assertj.core.api.OptionalIntAssert;
import org.assertj.core.api.OptionalLongAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
import tech.picnic.errorprone.refaster.matchers.IsArray;
/** Refaster rules related to AssertJ expressions and statements. */
/** Refaster templates related to AssertJ expressions and statements. */
// XXX: Most `AbstractIntegerAssert` rules can also be applied for other primitive types. Generate
// these in separate files.
// XXX: Also do for BigInteger/BigDecimal?
@@ -64,7 +63,7 @@ import tech.picnic.errorprone.refaster.matchers.IsArray;
// ^ And variants.
// XXX: Consider splitting this class into multiple classes.
// XXX: Some of these rules may not apply given the updated TestNG rewrite rules. Review.
// XXX: For the rules that "unwrap" explicitly enumerated collections, also introduce variants
// XXX: For the templates that "unwrap" explicitly enumerated collections, also introduce variants
// with explicitly enumerated sorted collections. (Requires that the type bound is Comparable.)
// XXX: Handle `.isEqualTo(explicitlyEnumeratedCollection)`. Can be considered equivalent to
// `.containsOnly(elements)`. (This does mean the auto-generated code needs to be more advanced.
@@ -102,7 +101,7 @@ import tech.picnic.errorprone.refaster.matchers.IsArray;
// (etc.)
// XXX: Look into using Assertions#contentOf(URL url, Charset charset) instead of our own test
// method.
// XXX: Write `Optional` rules also for `OptionalInt` and variants.
// XXX: Write Optional templates also for `OptionalInt` and variants.
// XXX: Write plugin to flag `assertThat(compileTimeConstant)` occurrences. Also other likely
// candidates, such as `assertThat(ImmutableSet(foo, bar)).XXX`
// XXX: Write generic plugin to replace explicit array parameters with varargs (`new int[] {1, 2}`
@@ -119,11 +118,10 @@ import tech.picnic.errorprone.refaster.matchers.IsArray;
// XXX: `assertThat(ImmutableList.sortedCopyOf(cmp, values)).somethingExactOrder` -> just compare
// "in any order".
// XXX: Turns out a lot of this is also covered by https://github.com/palantir/assertj-automation.
// See how we can combine these things. Do note that (at present) their Refaster rules don't
// See how we can combine these things. Do note that (at present) their Refaster templates don't
// show up as Error Prone checks. So we'd have to build an integration for that.
@OnlineDocumentation
final class AssertJRules {
private AssertJRules() {}
final class AssertJTemplates {
private AssertJTemplates() {}
//
// OptionalDouble
@@ -493,7 +491,7 @@ final class AssertJRules {
}
// XXX: This overload is here because `assertThat` has an overload for `Comparable` types.
// Unfortunately this still doesn't convince Refaster to match this rule in the context of
// Unfortunately this still doesn't convince Refaster to match this template in the context of
// Comparable types. Figure out why! Note that this also affects the `AssertThatOptional` rule.
static final class AssertThatIterableHasOneComparableElementEqualTo<
S extends Comparable<? super S>, T extends S> {

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -16,20 +16,18 @@ import java.io.IOException;
import org.assertj.core.api.AbstractObjectAssert;
import org.assertj.core.api.AbstractThrowableAssert;
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/**
* Refaster rules related to AssertJ assertions over expressions that may throw a {@link Throwable}
* subtype.
* Refaster templates related to AssertJ assertions over expressions that may throw a {@link
* Throwable} subtype.
*
* <p>For reasons of consistency we prefer {@link
* org.assertj.core.api.Assertions#assertThatThrownBy} over static methods for specific exception
* types. Note that only the most common assertion expressions are rewritten here; covering all
* cases would require the implementation of an Error Prone check instead.
*/
@OnlineDocumentation
final class AssertJThrowingCallableRules {
private AssertJThrowingCallableRules() {}
final class AssertJThrowingCallableTemplates {
private AssertJThrowingCallableTemplates() {}
static final class AssertThatThrownByIllegalArgumentException {
@BeforeTemplate
@@ -431,8 +429,8 @@ final class AssertJThrowingCallableRules {
}
}
// XXX: Drop this rule in favour of a generic Error Prone check that flags `String.format(...)`
// arguments to a wide range of format methods.
// XXX: Drop this template in favour of a generic Error Prone check that flags
// `String.format(...)` arguments to a wide range of format methods.
static final class AbstractThrowableAssertHasMessage {
@BeforeTemplate
AbstractThrowableAssert<?, ? extends Throwable> before(
@@ -451,8 +449,8 @@ final class AssertJThrowingCallableRules {
}
}
// XXX: Drop this rule in favour of a generic Error Prone check that flags `String.format(...)`
// arguments to a wide range of format methods.
// XXX: Drop this template in favour of a generic Error Prone check that flags
// `String.format(...)` arguments to a wide range of format methods.
static final class AbstractThrowableAssertWithFailMessage {
@BeforeTemplate
AbstractThrowableAssert<?, ? extends Throwable> before(

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.common.base.Preconditions.checkElementIndex;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
@@ -28,15 +28,13 @@ import java.util.Objects;
import java.util.Set;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/**
* Assorted Refaster rules that do not (yet) belong in one of the other classes with more topical
* Refaster rules.
* Assorted Refaster templates that do not (yet) belong in one of the other classes with more
* topical Refaster templates.
*/
@OnlineDocumentation
final class AssortedRules {
private AssortedRules() {}
final class AssortedTemplates {
private AssortedTemplates() {}
/** Prefer {@link Objects#checkIndex(int, int)} over the Guava alternative. */
static final class CheckIndex {
@@ -119,7 +117,7 @@ final class AssortedRules {
}
/** Don't unnecessarily repeat boolean expressions. */
// XXX: This rule captures only the simplest case. `@AlsoNegation` doesn't help. Consider
// XXX: This template captures only the simplest case. `@AlsoNegation` doesn't help. Consider
// contributing a Refaster patch, which handles the negation in the `@BeforeTemplate` more
// intelligently.
static final class LogicalImplication {
@@ -174,8 +172,8 @@ final class AssortedRules {
* Collections#disjoint(Collection, Collection)}.
*/
// XXX: Other copy operations could be elided too, but these are most common after application of
// the `DisjointSets` rule defined above. If we ever introduce a generic "makes a copy" stand-in,
// use it here.
// the `DisjointSets` template defined above. If we ever introduce a generic "makes a copy"
// stand-in, use it here.
static final class DisjointCollections<T> {
@BeforeTemplate
boolean before(Collection<T> collection1, Collection<T> collection2) {

View File

@@ -1,15 +1,13 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import java.math.BigDecimal;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link BigDecimal}s. */
@OnlineDocumentation
final class BigDecimalRules {
private BigDecimalRules() {}
/** Refaster templates related to expressions dealing with {@link BigDecimal}s. */
final class BigDecimalTemplates {
private BigDecimalTemplates() {}
/** Prefer using the constant {@link BigDecimal#ZERO} when possible. */
static final class BigDecimalZero {

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
@@ -19,14 +19,12 @@ import java.util.Set;
import java.util.SortedSet;
import java.util.function.IntFunction;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with (arbitrary) collections. */
/** Refaster templates related to expressions dealing with (arbitrary) collections. */
// XXX: There are other Guava `Iterables` methods that should not be called if the input is known to
// be a `Collection`. Add those here.
@OnlineDocumentation
final class CollectionRules {
private CollectionRules() {}
final class CollectionTemplates {
private CollectionTemplates() {}
/**
* Prefer {@link Collection#isEmpty()} over alternatives that consult the collection's size or are

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static java.util.Comparator.comparing;
@@ -24,12 +24,10 @@ import java.util.function.Function;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link Comparator}s. */
@OnlineDocumentation
final class ComparatorRules {
private ComparatorRules() {}
/** Refaster templates related to expressions dealing with {@link Comparator}s. */
final class ComparatorTemplates {
private ComparatorTemplates() {}
/** Prefer {@link Comparator#naturalOrder()} over more complicated constructs. */
static final class NaturalOrder<T extends Comparable<? super T>> {

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import com.google.common.collect.Streams;
import com.google.errorprone.refaster.Refaster;
@@ -12,12 +12,10 @@ import java.util.function.DoublePredicate;
import java.util.function.DoubleUnaryOperator;
import java.util.stream.DoubleStream;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link DoubleStream}s. */
@OnlineDocumentation
final class DoubleStreamRules {
private DoubleStreamRules() {}
/** Refaster templates related to expressions dealing with {@link DoubleStream}s. */
final class DoubleStreamTemplates {
private DoubleStreamTemplates() {}
/** Don't unnecessarily call {@link Streams#concat(DoubleStream...)}. */
static final class ConcatOneDoubleStream {

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
@@ -6,12 +6,10 @@ import com.google.errorprone.refaster.annotation.AlsoNegation;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import java.util.Objects;
import java.util.function.Predicate;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with (in)equalities. */
@OnlineDocumentation
final class EqualityRules {
private EqualityRules() {}
/** Refaster templates related to expressions dealing with (in)equalities. */
final class EqualityTemplates {
private EqualityTemplates() {}
/** Prefer reference-based quality for enums. */
// Primitive value comparisons are not listed, because Error Prone flags those out of the box.

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.common.collect.ImmutableListMultimap.flatteningToImmutableListMultimap;
import static com.google.common.collect.ImmutableListMultimap.toImmutableListMultimap;
@@ -24,12 +24,10 @@ import java.util.Iterator;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link ImmutableListMultimap}s. */
@OnlineDocumentation
final class ImmutableListMultimapRules {
private ImmutableListMultimapRules() {}
/** Refaster templates related to expressions dealing with {@link ImmutableListMultimap}s. */
final class ImmutableListMultimapTemplates {
private ImmutableListMultimapTemplates() {}
/**
* Prefer {@link ImmutableListMultimap#builder()} over the associated constructor on constructions
@@ -72,7 +70,7 @@ final class ImmutableListMultimapRules {
* alternatives.
*/
// XXX: One can define variants for more than one key-value pair, but at some point the builder
// actually produces nicer code. So it's not clear we should add Refaster rules for those
// actually produces nicer code. So it's not clear we should add Refaster templates for those
// variants.
static final class PairToImmutableListMultimap<K, V> {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
@@ -20,12 +20,10 @@ import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link ImmutableList}s. */
@OnlineDocumentation
final class ImmutableListRules {
private ImmutableListRules() {}
/** Refaster templates related to expressions dealing with {@link ImmutableList}s. */
final class ImmutableListTemplates {
private ImmutableListTemplates() {}
/** Prefer {@link ImmutableList#builder()} over the associated constructor. */
// XXX: This drops generic type information, sometimes leading to non-compilable code. See
@@ -156,7 +154,7 @@ final class ImmutableListRules {
* communicate the immutability of the resulting list at the type level.
*/
// XXX: The `Stream` variant may be too contrived to warrant inclusion. Review its usage if/when
// this and similar Refaster rules are replaced with an Error Prone check.
// this and similar Refaster templates are replaced with an Error Prone check.
static final class ImmutableListOf<T> {
@BeforeTemplate
List<T> before() {

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.common.collect.ImmutableMap.toImmutableMap;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
@@ -21,12 +21,10 @@ import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link ImmutableMap}s. */
@OnlineDocumentation
final class ImmutableMapRules {
private ImmutableMapRules() {}
/** Refaster templates related to expressions dealing with {@link ImmutableMap}s. */
final class ImmutableMapTemplates {
private ImmutableMapTemplates() {}
/** Prefer {@link ImmutableMap#builder()} over the associated constructor. */
// XXX: This drops generic type information, sometimes leading to non-compilable code. See
@@ -315,7 +313,7 @@ final class ImmutableMapRules {
}
}
// XXX: Add a rule for this:
// XXX: Add a template for this:
// Maps.transformValues(streamOfEntries.collect(groupBy(fun)), ImmutableMap::copyOf)
// ->
// streamOfEntries.collect(groupBy(fun, toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)))

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.common.collect.ImmutableMultiset.toImmutableMultiset;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
@@ -13,12 +13,10 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link ImmutableMultiset}s. */
@OnlineDocumentation
final class ImmutableMultisetRules {
private ImmutableMultisetRules() {}
/** Refaster templates related to expressions dealing with {@link ImmutableMultiset}s. */
final class ImmutableMultisetTemplates {
private ImmutableMultisetTemplates() {}
/** Prefer {@link ImmutableMultiset#builder()} over the associated constructor. */
// XXX: This drops generic type information, sometimes leading to non-compilable code. See

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.common.collect.ImmutableSetMultimap.flatteningToImmutableSetMultimap;
import static com.google.common.collect.ImmutableSetMultimap.toImmutableSetMultimap;
@@ -21,12 +21,10 @@ import java.util.Collection;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link ImmutableSetMultimap}s. */
@OnlineDocumentation
final class ImmutableSetMultimapRules {
private ImmutableSetMultimapRules() {}
/** Refaster templates related to expressions dealing with {@link ImmutableSetMultimap}s. */
final class ImmutableSetMultimapTemplates {
private ImmutableSetMultimapTemplates() {}
/** Prefer {@link ImmutableSetMultimap#builder()} over the associated constructor. */
// XXX: This drops generic type information, sometimes leading to non-compilable code. See
@@ -58,7 +56,7 @@ final class ImmutableSetMultimapRules {
/** Prefer {@link ImmutableSetMultimap#of(Object, Object)} over more contrived alternatives. */
// XXX: One can define variants for more than one key-value pair, but at some point the builder
// actually produces nicer code. So it's not clear we should add Refaster rules for those
// actually produces nicer code. So it's not clear we should add Refaster templates for those
// variants.
static final class PairToImmutableSetMultimap<K, V> {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
@@ -17,12 +17,10 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link ImmutableSet}s. */
@OnlineDocumentation
final class ImmutableSetRules {
private ImmutableSetRules() {}
/** Refaster templates related to expressions dealing with {@link ImmutableSet}s. */
final class ImmutableSetTemplates {
private ImmutableSetTemplates() {}
/** Prefer {@link ImmutableSet#builder()} over the associated constructor. */
// XXX: This drops generic type information, sometimes leading to non-compilable code. See
@@ -106,7 +104,7 @@ final class ImmutableSetRules {
* communicate the immutability of the resulting set at the type level.
*/
// XXX: The `Stream` variant may be too contrived to warrant inclusion. Review its usage if/when
// this and similar Refaster rules are replaced with an Error Prone check.
// this and similar Refaster templates are replaced with an Error Prone check.
static final class ImmutableSetOf<T> {
@BeforeTemplate
Set<T> before() {

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.common.collect.ImmutableSortedMap.toImmutableSortedMap;
import static java.util.Comparator.naturalOrder;
@@ -13,12 +13,10 @@ import java.util.Collection;
import java.util.Comparator;
import java.util.Map;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link ImmutableSortedMap}s. */
@OnlineDocumentation
final class ImmutableSortedMapRules {
private ImmutableSortedMapRules() {}
/** Refaster templates related to expressions dealing with {@link ImmutableSortedMap}s. */
final class ImmutableSortedMapTemplates {
private ImmutableSortedMapTemplates() {}
/** Prefer {@link ImmutableSortedMap#orderedBy(Comparator)} over the associated constructor. */
static final class ImmutableSortedMapBuilder<K, V> {
@@ -84,7 +82,7 @@ final class ImmutableSortedMapRules {
/** Prefer {@link ImmutableSortedMap#of(Object, Object)} over more contrived alternatives. */
// XXX: One can define variants for more than one key-value pair, but at some point the builder
// actually produces nicer code. So it's not clear we should add Refaster rules for those
// actually produces nicer code. So it's not clear we should add Refaster templates for those
// variants.
// XXX: We could also rewrite builders with non-natural orders, but that would affect
// `ImmutableSortedMap#comparator()`.

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.common.collect.ImmutableSortedMultiset.toImmutableSortedMultiset;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
@@ -15,12 +15,10 @@ import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link ImmutableSortedMultiset}s. */
@OnlineDocumentation
final class ImmutableSortedMultisetRules {
private ImmutableSortedMultisetRules() {}
/** Refaster templates related to expressions dealing with {@link ImmutableSortedMultiset}s. */
final class ImmutableSortedMultisetTemplates {
private ImmutableSortedMultisetTemplates() {}
/**
* Prefer {@link ImmutableSortedMultiset#orderedBy(Comparator)} over the associated constructor.

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
@@ -15,12 +15,10 @@ import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link ImmutableSortedSet}s. */
@OnlineDocumentation
final class ImmutableSortedSetRules {
private ImmutableSortedSetRules() {}
/** Refaster templates related to expressions dealing with {@link ImmutableSortedSet}s. */
final class ImmutableSortedSetTemplates {
private ImmutableSortedSetTemplates() {}
/** Prefer {@link ImmutableSortedSet#orderedBy(Comparator)} over the associated constructor. */
static final class ImmutableSortedSetBuilder<T> {

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import com.google.common.collect.Streams;
import com.google.errorprone.refaster.Refaster;
@@ -12,12 +12,10 @@ import java.util.function.IntPredicate;
import java.util.function.IntUnaryOperator;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link IntStream}s. */
@OnlineDocumentation
final class IntStreamRules {
private IntStreamRules() {}
/** Refaster templates related to expressions dealing with {@link IntStream}s. */
final class IntStreamTemplates {
private IntStreamTemplates() {}
/** Prefer {@link IntStream#range(int, int)} over the more contrived alternative. */
static final class IntStreamClosedOpenRange {

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static org.junit.jupiter.params.provider.Arguments.arguments;
@@ -8,12 +8,10 @@ import com.google.errorprone.refaster.annotation.BeforeTemplate;
import com.google.errorprone.refaster.annotation.Repeated;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import org.junit.jupiter.params.provider.Arguments;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to JUnit expressions and statements. */
@OnlineDocumentation
final class JUnitRules {
private JUnitRules() {}
/** Refaster templates related to JUnit expressions and statements. */
final class JUnitTemplates {
private JUnitTemplates() {}
/** Prefer statically imported {@link Arguments#arguments} over {@link Arguments#of} calls. */
static final class ArgumentsEnumeration<T> {

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import com.google.common.collect.Streams;
import com.google.errorprone.refaster.Refaster;
@@ -12,12 +12,10 @@ import java.util.function.LongPredicate;
import java.util.function.LongUnaryOperator;
import java.util.stream.LongStream;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link LongStream}s. */
@OnlineDocumentation
final class LongStreamRules {
private LongStreamRules() {}
/** Refaster templates related to expressions dealing with {@link LongStream}s. */
final class LongStreamTemplates {
private LongStreamTemplates() {}
/** Prefer {@link LongStream#range(long, long)} over the more contrived alternative. */
static final class LongStreamClosedOpenRange {

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static java.util.Comparator.comparing;
@@ -14,12 +14,10 @@ import com.google.errorprone.refaster.annotation.UseImportPolicy;
import java.util.AbstractMap;
import java.util.Comparator;
import java.util.Map;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link Map.Entry} instances. */
@OnlineDocumentation
final class MapEntryRules {
private MapEntryRules() {}
/** Refaster templates related to expressions dealing with {@link Map.Entry} instances. */
final class MapEntryTemplates {
private MapEntryTemplates() {}
/**
* Prefer {@link Map#entry(Object, Object)} over alternative ways to create an immutable map

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static org.mockito.Mockito.never;
@@ -10,12 +10,10 @@ import com.google.errorprone.refaster.annotation.BeforeTemplate;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import org.mockito.Mockito;
import org.mockito.verification.VerificationMode;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to Mockito expressions and statements. */
@OnlineDocumentation
final class MockitoRules {
private MockitoRules() {}
/** Refaster templates related to Mockito expressions and statements. */
final class MockitoTemplates {
private MockitoTemplates() {}
/**
* Prefer {@link Mockito#never()}} over explicitly specifying that the associated invocation must

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
@@ -8,12 +8,10 @@ import com.google.errorprone.refaster.annotation.BeforeTemplate;
import java.util.Collection;
import java.util.Set;
import javax.annotation.Nullable;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link Multimap}s. */
@OnlineDocumentation
final class MultimapRules {
private MultimapRules() {}
/** Refaster templates related to expressions dealing with {@link Multimap}s. */
final class MultimapTemplates {
private MultimapTemplates() {}
/** Prefer {@link Multimap#keySet()} over more contrived alternatives. */
static final class MultimapKeySet<K, V> {

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static java.util.Objects.requireNonNullElse;
@@ -10,12 +10,10 @@ import com.google.errorprone.refaster.annotation.UseImportPolicy;
import java.util.Objects;
import java.util.function.Predicate;
import javax.annotation.Nullable;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with (possibly) null values. */
@OnlineDocumentation
final class NullRules {
private NullRules() {}
/** Refaster templates related to expressions dealing with (possibly) null values. */
final class NullTemplates {
private NullTemplates() {}
/** Prefer the {@code ==} operator over {@link Objects#isNull(Object)}. */
static final class IsNull {

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
@@ -17,12 +17,10 @@ import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link Optional}s. */
@OnlineDocumentation
final class OptionalRules {
private OptionalRules() {}
/** Refaster templates related to expressions dealing with {@link Optional}s. */
final class OptionalTemplates {
private OptionalTemplates() {}
static final class OptionalOfNullable<T> {
// XXX: Refaster should be smart enough to also rewrite occurrences in which there are
@@ -80,8 +78,8 @@ final class OptionalRules {
}
/** Prefer {@link Optional#orElseThrow()} over the less explicit {@link Optional#get()}. */
// XXX: This rule is analogous to `OptionalOrElseThrow` above. Arguably this is its
// generalization. If/when Refaster is extended to understand this, delete the rule above.
// XXX: This template is analogous to `OptionalOrElseThrow` above. Arguably this is its
// generalization. If/when Refaster is extended to understand this, delete the template above.
static final class OptionalOrElseThrowMethodReference<T> {
@BeforeTemplate
Function<Optional<T>, T> before() {

View File

@@ -1,14 +1,12 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import com.google.common.primitives.Ints;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with primitives. */
@OnlineDocumentation
final class PrimitiveRules {
private PrimitiveRules() {}
/** Refaster templates related to expressions dealing with primitives. */
final class PrimitiveTemplates {
private PrimitiveTemplates() {}
/** Avoid contrived ways of expressing the "less than" relationship. */
static final class LessThan {

View File

@@ -1,8 +1,7 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.common.collect.MoreCollectors.toOptional;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static java.util.function.Function.identity;
import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.collect.MoreCollectors;
@@ -25,13 +24,11 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import reactor.test.publisher.PublisherProbe;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
import tech.picnic.errorprone.refaster.matchers.ThrowsCheckedException;
/** Refaster rules related to Reactor expressions and statements. */
@OnlineDocumentation
final class ReactorRules {
private ReactorRules() {}
/** Refaster templates related to Reactor expressions and statements. */
final class ReactorTemplates {
private ReactorTemplates() {}
/**
* Prefer {@link Mono#fromSupplier(Supplier)} over {@link Mono#fromCallable(Callable)} where
@@ -97,7 +94,7 @@ final class ReactorRules {
/**
* Don't unnecessarily pass {@link Mono#error(Supplier)} a method reference or lambda expression.
*/
// XXX: Drop this rule once the more general rule `AssortedRules#SupplierAsSupplier` works
// XXX: Drop this rule once the more general rule `AssortedTemplates#SupplierAsSupplier` works
// reliably.
static final class MonoErrorSupplier<T, E extends Throwable> {
@BeforeTemplate
@@ -114,7 +111,7 @@ final class ReactorRules {
/**
* Don't unnecessarily pass {@link Flux#error(Supplier)} a method reference or lambda expression.
*/
// XXX: Drop this rule once the more general rule `AssortedRules#SupplierAsSupplier` works
// XXX: Drop this rule once the more general rule `AssortedTemplates#SupplierAsSupplier` works
// reliably.
static final class FluxErrorSupplier<T, E extends Throwable> {
@BeforeTemplate
@@ -180,26 +177,6 @@ final class ReactorRules {
}
}
/** Prefer {@link Flux#concatMap(Function, int)} over more contrived alternatives. */
static final class FluxConcatMapWithPrefetch<T, S> {
@BeforeTemplate
Flux<S> before(
Flux<T> flux,
Function<? super T, ? extends Publisher<? extends S>> function,
int prefetch) {
return Refaster.anyOf(
flux.flatMap(function, 1, prefetch), flux.flatMapSequential(function, 1, prefetch));
}
@AfterTemplate
Flux<S> after(
Flux<T> flux,
Function<? super T, ? extends Publisher<? extends S>> function,
int prefetch) {
return flux.concatMap(function, prefetch);
}
}
/**
* Prefer {@link Flux#concatMapIterable(Function)} over {@link Flux#flatMapIterable(Function)}, as
* the former has equivalent semantics but a clearer name.
@@ -216,24 +193,6 @@ final class ReactorRules {
}
}
/**
* Prefer {@link Flux#concatMapIterable(Function, int)} over {@link Flux#flatMapIterable(Function,
* int)}, as the former has equivalent semantics but a clearer name.
*/
static final class FluxConcatMapIterableWithPrefetch<T, S> {
@BeforeTemplate
Flux<S> before(
Flux<T> flux, Function<? super T, ? extends Iterable<? extends S>> function, int prefetch) {
return flux.flatMapIterable(function, prefetch);
}
@AfterTemplate
Flux<S> after(
Flux<T> flux, Function<? super T, ? extends Iterable<? extends S>> function, int prefetch) {
return flux.concatMapIterable(function, prefetch);
}
}
/**
* Don't use {@link Mono#flatMapMany(Function)} to implicitly convert a {@link Mono} to a {@link
* Flux}.
@@ -312,74 +271,11 @@ final class ReactorRules {
}
}
/**
* Prefer {@link Flux#concatMapIterable(Function)} over alternatives that require an additional
* subscription.
*/
static final class ConcatMapIterableIdentity<T> {
@BeforeTemplate
Flux<T> before(Flux<? extends Iterable<T>> flux) {
return Refaster.anyOf(
flux.concatMap(list -> Flux.fromIterable(list)), flux.concatMap(Flux::fromIterable));
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
Flux<T> after(Flux<? extends Iterable<T>> flux) {
return flux.concatMapIterable(identity());
}
}
/**
* Prefer {@link Flux#concatMapIterable(Function, int)} over alternatives that require an
* additional subscription.
*/
static final class ConcatMapIterableIdentityWithPrefetch<T> {
@BeforeTemplate
Flux<T> before(Flux<? extends Iterable<T>> flux, int prefetch) {
return Refaster.anyOf(
flux.concatMap(list -> Flux.fromIterable(list), prefetch),
flux.concatMap(Flux::fromIterable, prefetch));
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
Flux<T> after(Flux<? extends Iterable<T>> flux, int prefetch) {
return flux.concatMapIterable(identity(), prefetch);
}
}
/** Prefer {@link Mono#onErrorComplete()} over more contrived alternatives. */
static final class MonoOnErrorComplete<T> {
@BeforeTemplate
Mono<T> before(Mono<T> mono) {
return mono.onErrorResume(e -> Mono.empty());
}
@AfterTemplate
Mono<T> after(Mono<T> mono) {
return mono.onErrorComplete();
}
}
/** Prefer {@link Flux#onErrorComplete()} over more contrived alternatives. */
static final class FluxOnErrorComplete<T> {
@BeforeTemplate
Flux<T> before(Flux<T> flux) {
return flux.onErrorResume(e -> Refaster.anyOf(Mono.empty(), Flux.empty()));
}
@AfterTemplate
Flux<T> after(Flux<T> flux) {
return flux.onErrorComplete();
}
}
/** Prefer {@link PublisherProbe#empty()}} over more verbose alternatives. */
static final class PublisherProbeEmpty<T> {
@BeforeTemplate
PublisherProbe<T> before() {
return PublisherProbe.of(Refaster.anyOf(Mono.empty(), Flux.empty()));
return Refaster.anyOf(PublisherProbe.of(Mono.empty()), PublisherProbe.of(Flux.empty()));
}
@AfterTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
@@ -13,12 +13,10 @@ import org.jspecify.nullness.Nullable;
import reactor.adapter.rxjava.RxJava2Adapter;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link RxJava2Adapter}. */
@OnlineDocumentation
final class RxJava2AdapterRules {
private RxJava2AdapterRules() {}
/** Refaster templates related to expressions dealing with {@link RxJava2Adapter}. */
final class RxJava2AdapterTemplates {
private RxJava2AdapterTemplates() {}
/** Use the fluent API style when using {@link RxJava2Adapter#completableToMono}. */
static final class CompletableToMono {

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static java.util.Comparator.naturalOrder;
@@ -22,12 +22,10 @@ import java.util.function.Predicate;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link Stream}s. */
@OnlineDocumentation
final class StreamRules {
private StreamRules() {}
/** Refaster templates related to expressions dealing with {@link Stream}s. */
final class StreamTemplates {
private StreamTemplates() {}
/**
* Prefer {@link Collectors#joining()} over {@link Collectors#joining(CharSequence)} with an empty

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.stream.Collectors.joining;
@@ -17,13 +17,11 @@ import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import javax.annotation.Nullable;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link String}s. */
/** Refaster templates related to expressions dealing with {@link String}s. */
// XXX: Should we prefer `s -> !s.isEmpty()` or `not(String::isEmpty)`?
@OnlineDocumentation
final class StringRules {
private StringRules() {}
final class StringTemplates {
private StringTemplates() {}
/** Prefer {@link String#isEmpty()} over alternatives that consult the string's length. */
static final class StringIsEmpty {
@@ -130,8 +128,8 @@ final class StringRules {
* Prefer direct delegation to {@link String#valueOf(Object)} over the indirection introduced by
* {@link Objects#toString(Object)}.
*/
// XXX: This rule is analogous to `StringValueOf` above. Arguably this is its generalization.
// If/when Refaster is extended to understand this, delete the rule above.
// XXX: This template is analogous to `StringValueOf` above. Arguably this is its generalization.
// If/when Refaster is extended to understand this, delete the template above.
static final class StringValueOfMethodReference {
@BeforeTemplate
Function<Object, String> before() {

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static org.assertj.core.api.Assertions.assertThat;
@@ -30,7 +30,7 @@ import org.testng.Assert;
import org.testng.Assert.ThrowingRunnable;
/**
* Refaster rules that replace TestNG assertions with equivalent AssertJ assertions.
* Refaster templates that replace TestNG assertions with equivalent AssertJ assertions.
*
* <p>Some of the classes below have TestNG {@code @BeforeTemplate}s that reference wildcard type
* bounds ({@code <?>}), while the associated AssertJ {@code @AfterTemplate}s reference stricter
@@ -69,11 +69,11 @@ import org.testng.Assert.ThrowingRunnable;
* </ul>
* </ul>
*/
// XXX: As-is these rules do not result in a complete migration:
// XXX: As-is these templates do not result in a complete migration:
// - Expressions containing comments are skipped due to a limitation of Refaster.
// - Assertions inside lambda expressions are also skipped. Unclear why.
final class TestNGToAssertJRules {
private TestNGToAssertJRules() {}
final class TestNGToAssertJTemplates {
private TestNGToAssertJTemplates() {}
static final class Fail {
@BeforeTemplate

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static java.time.ZoneOffset.UTC;
@@ -21,12 +21,10 @@ import java.time.chrono.ChronoLocalDateTime;
import java.time.chrono.ChronoZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with time. */
@OnlineDocumentation
final class TimeRules {
private TimeRules() {}
/** Refaster templates related to expressions dealing with time. */
final class TimeTemplates {
private TimeTemplates() {}
/**
* Prefer {@link Clock#instant()} over {@link Instant#now(Clock)}, as it is more concise and more

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;
import static org.springframework.http.HttpMethod.GET;
import static org.springframework.http.HttpMethod.HEAD;
@@ -20,15 +20,13 @@ import org.springframework.web.reactive.function.client.WebClient.RequestBodySpe
import org.springframework.web.reactive.function.client.WebClient.RequestBodyUriSpec;
import org.springframework.web.reactive.function.client.WebClient.RequestHeadersSpec;
import org.springframework.web.reactive.function.client.WebClient.RequestHeadersUriSpec;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/**
* Refaster rules related to expressions dealing with {@link
* Refaster templates related to expressions dealing with {@link
* org.springframework.web.reactive.function.client.WebClient} and related types.
*/
@OnlineDocumentation
final class WebClientRules {
private WebClientRules() {}
final class WebClientTemplates {
private WebClientTemplates() {}
/** Prefer {@link RequestBodySpec#bodyValue(Object)} over more contrived alternatives. */
static final class BodyValue<T> {

View File

@@ -1,4 +1,4 @@
/** Picnic Refaster rules. */
/** Picnic Refaster templates. */
@com.google.errorprone.annotations.CheckReturnValue
@javax.annotation.ParametersAreNonnullByDefault
package tech.picnic.errorprone.refasterrules;
package tech.picnic.errorprone.refastertemplates;

View File

@@ -188,7 +188,7 @@ final class LexicographicalAnnotationAttributeListingTest {
" String[] value() default {};",
" }",
"",
" @Foo({\" \", \"\", \"b\", \"a\"})",
" @Foo({\"b\", \"a\"})",
" A unsortedString();",
"",
" @Foo(cls = {long.class, int.class})",
@@ -225,7 +225,7 @@ final class LexicographicalAnnotationAttributeListingTest {
" String[] value() default {};",
" }",
"",
" @Foo({\"\", \" \", \"a\", \"b\"})",
" @Foo({\"a\", \"b\"})",
" A unsortedString();",
"",
" @Foo(cls = {int.class, long.class})",

View File

@@ -11,7 +11,7 @@ final class MissingRefasterAnnotationTest {
.expectErrorMessage(
"X",
containsPattern(
"The Refaster rule contains a method without any Refaster annotations"));
"The Refaster template contains a method without any Refaster annotations"));
@Test
void identification() {
@@ -74,17 +74,17 @@ final class MissingRefasterAnnotationTest {
" }",
" }",
"",
" static final class ValidRefasterRule {",
" static final class ValidRefasterTemplate {",
" @BeforeTemplate",
" void unusedPureFunctionCall(Object o) {",
" o.toString();",
" }",
" }",
"",
" static final class NotARefasterRule {",
" static final class NotARefasterTemplate {",
" @Override",
" public String toString() {",
" return \"This is not a Refaster rule\";",
" return \"This is not a Refaster template\";",
" }",
" }",
"}")

View File

@@ -5,11 +5,11 @@ import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
import com.google.errorprone.CompilationTestHelper;
import org.junit.jupiter.api.Test;
final class RefasterRuleModifiersTest {
final class RefasterTemplateModifiersTest {
private final CompilationTestHelper compilationTestHelper =
CompilationTestHelper.newInstance(RefasterRuleModifiers.class, getClass());
CompilationTestHelper.newInstance(RefasterTemplateModifiers.class, getClass());
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
BugCheckerRefactoringTestHelper.newInstance(RefasterRuleModifiers.class, getClass());
BugCheckerRefactoringTestHelper.newInstance(RefasterTemplateModifiers.class, getClass());
@Test
void identification() {

View File

@@ -5,7 +5,7 @@ import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
import com.google.errorprone.CompilationTestHelper;
import org.junit.jupiter.api.Test;
final class Slf4jLogStatementTest {
final class Slf4JLogStatementTest {
private final CompilationTestHelper compilationTestHelper =
CompilationTestHelper.newInstance(Slf4jLogStatement.class, getClass());
private final BugCheckerRefactoringTestHelper refactoringTestHelper =

View File

@@ -1,97 +0,0 @@
package tech.picnic.errorprone.bugpatterns;
import static com.google.common.base.Predicates.containsPattern;
import com.google.errorprone.BugCheckerRefactoringTestHelper;
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
import com.google.errorprone.CompilationTestHelper;
import org.junit.jupiter.api.Test;
final class StringJoinTest {
private final CompilationTestHelper compilationHelper =
CompilationTestHelper.newInstance(StringJoin.class, getClass())
.expectErrorMessage(
"valueOf", containsPattern("Prefer `String#valueOf` over `String#format`"))
.expectErrorMessage("join", containsPattern("Prefer `String#join` over `String#format`"));
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
BugCheckerRefactoringTestHelper.newInstance(StringJoin.class, getClass());
@Test
void identification() {
compilationHelper
.addSourceLines(
"A.java",
"import java.util.Formattable;",
"import java.util.Locale;",
"",
"class A {",
" void m() {",
" String.join(\"-\", getClass().getName());",
" String.format(getClass().getName(), getClass().getName());",
" String.format(Locale.ROOT, \"%s\", getClass().getName());",
" String.format(\"%20s\", getClass().getName());",
" // BUG: Diagnostic matches: valueOf",
" String.format(\"%s\", getClass().getName());",
" // BUG: Diagnostic matches: valueOf",
" String.format(\"%s\", hashCode());",
" String.format(\"%s\", (Formattable) null);",
" String.format(\"-%s\", getClass().getName());",
" String.format(\"%s-\", getClass().getName());",
" String.format(\"-%s-\", getClass().getName());",
" // BUG: Diagnostic matches: join",
" String.format(\"%s%s\", getClass().getName(), getClass().getName());",
" // BUG: Diagnostic matches: join",
" String.format(\"%s%s\", getClass().getName(), hashCode());",
" // BUG: Diagnostic matches: join",
" String.format(\"%s%s\", hashCode(), getClass().getName());",
" String.format(\"%s%s\", getClass().getName(), (Formattable) null);",
" String.format(\"%s%s\", (Formattable) null, getClass().getName());",
" String.format(\"%s%s\", getClass().getName());",
" // BUG: Diagnostic matches: join",
" String.format(\"%s-%s\", getClass().getName(), getClass().getName());",
" // BUG: Diagnostic matches: join",
" String.format(\"%saa%s\", getClass().getName(), getClass().getName());",
" String.format(\"%s%%%s\", getClass().getName(), getClass().getName());",
" // BUG: Diagnostic matches: join",
" String.format(\"%s_%s_%s\", getClass().getName(), getClass().getName(), getClass().getName());",
" String.format(\"%s_%s_%s\", getClass().getName(), getClass().getName());",
" String.format(\"%s_%s-%s\", getClass().getName(), getClass().getName(), getClass().getName());",
" }",
"}")
.doTest();
}
@Test
void replacement() {
refactoringTestHelper
.addInputLines(
"A.java",
"class A {",
" void m() {",
" String.format(\"%s\", getClass().getName());",
" String.format(\"%s%s\", getClass().getName(), getClass().getName());",
" String.format(\"%s%s\", getClass().getName(), hashCode());",
" String.format(\"%s%s\", hashCode(), getClass().getName());",
" String.format(\"%s-%s\", getClass().getName(), getClass().getName());",
" String.format(\"%saa%s\", getClass().getName(), getClass().getName());",
" String.format(\"%s\\\"%s\", getClass().getName(), getClass().getName());",
" String.format(\"%s_%s_%s\", getClass().getName(), getClass().getName(), getClass().getName());",
" }",
"}")
.addOutputLines(
"A.java",
"class A {",
" void m() {",
" String.valueOf(getClass().getName());",
" String.join(\"\", getClass().getName(), getClass().getName());",
" String.join(\"\", getClass().getName(), String.valueOf(hashCode()));",
" String.join(\"\", String.valueOf(hashCode()), getClass().getName());",
" String.join(\"-\", getClass().getName(), getClass().getName());",
" String.join(\"aa\", getClass().getName(), getClass().getName());",
" String.join(\"\\\"\", getClass().getName(), getClass().getName());",
" String.join(\"_\", getClass().getName(), getClass().getName(), getClass().getName());",
" }",
"}")
.doTest(TestMode.TEXT_MATCH);
}
}

View File

@@ -1,83 +0,0 @@
package tech.picnic.errorprone.refasterrules;
import static java.util.function.Predicate.not;
import com.google.common.collect.ImmutableSet;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollection;
final class RefasterRulesTest {
/** The names of all Refaster rule groups defined in this module. */
private static final ImmutableSet<Class<?>> RULE_COLLECTIONS =
ImmutableSet.of(
AssertJRules.class,
AssertJBigDecimalRules.class,
AssertJBigIntegerRules.class,
AssertJBooleanRules.class,
AssertJByteRules.class,
AssertJCharSequenceRules.class,
AssertJComparableRules.class,
AssertJDoubleRules.class,
AssertJEnumerableRules.class,
AssertJFloatRules.class,
AssertJIntegerRules.class,
AssertJLongRules.class,
AssertJNumberRules.class,
AssertJMapRules.class,
AssertJObjectRules.class,
AssertJOptionalRules.class,
AssertJPrimitiveRules.class,
AssertJShortRules.class,
AssertJStringRules.class,
AssertJThrowingCallableRules.class,
AssortedRules.class,
BigDecimalRules.class,
CollectionRules.class,
ComparatorRules.class,
DoubleStreamRules.class,
EqualityRules.class,
ImmutableListRules.class,
ImmutableListMultimapRules.class,
ImmutableMapRules.class,
ImmutableMultisetRules.class,
ImmutableSetRules.class,
ImmutableSetMultimapRules.class,
ImmutableSortedMapRules.class,
ImmutableSortedMultisetRules.class,
ImmutableSortedSetRules.class,
IntStreamRules.class,
JUnitRules.class,
LongStreamRules.class,
MapEntryRules.class,
MockitoRules.class,
MultimapRules.class,
NullRules.class,
OptionalRules.class,
PrimitiveRules.class,
ReactorRules.class,
RxJava2AdapterRules.class,
StreamRules.class,
StringRules.class,
TestNGToAssertJRules.class,
TimeRules.class,
WebClientRules.class);
// XXX: Create a JUnit extension to automatically discover the rule collections in a given context
// to make sure the list is exhaustive.
private static Stream<Arguments> validateRuleCollectionTestCases() {
// XXX: Drop the filter once we have added tests for AssertJ! We can then also replace this
// method with `@ValueSource(classes = {...})`.
return RULE_COLLECTIONS.stream()
.filter(not(AssertJRules.class::equals))
.map(Arguments::arguments);
}
@MethodSource("validateRuleCollectionTestCases")
@ParameterizedTest
void validateRuleCollection(Class<?> clazz) {
RefasterRuleCollection.validate(clazz);
}
}

View File

@@ -0,0 +1,83 @@
package tech.picnic.errorprone.refastertemplates;
import static java.util.function.Predicate.not;
import com.google.common.collect.ImmutableSet;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import tech.picnic.errorprone.refaster.test.RefasterTemplateCollection;
final class RefasterTemplatesTest {
/** The names of all Refaster template groups defined in this module. */
private static final ImmutableSet<Class<?>> TEMPLATE_COLLECTIONS =
ImmutableSet.of(
AssertJTemplates.class,
AssertJBigDecimalTemplates.class,
AssertJBigIntegerTemplates.class,
AssertJBooleanTemplates.class,
AssertJByteTemplates.class,
AssertJCharSequenceTemplates.class,
AssertJComparableTemplates.class,
AssertJDoubleTemplates.class,
AssertJEnumerableTemplates.class,
AssertJFloatTemplates.class,
AssertJIntegerTemplates.class,
AssertJLongTemplates.class,
AssertJNumberTemplates.class,
AssertJMapTemplates.class,
AssertJObjectTemplates.class,
AssertJOptionalTemplates.class,
AssertJPrimitiveTemplates.class,
AssertJShortTemplates.class,
AssertJStringTemplates.class,
AssertJThrowingCallableTemplates.class,
AssortedTemplates.class,
BigDecimalTemplates.class,
CollectionTemplates.class,
ComparatorTemplates.class,
DoubleStreamTemplates.class,
EqualityTemplates.class,
ImmutableListTemplates.class,
ImmutableListMultimapTemplates.class,
ImmutableMapTemplates.class,
ImmutableMultisetTemplates.class,
ImmutableSetTemplates.class,
ImmutableSetMultimapTemplates.class,
ImmutableSortedMapTemplates.class,
ImmutableSortedMultisetTemplates.class,
ImmutableSortedSetTemplates.class,
IntStreamTemplates.class,
JUnitTemplates.class,
LongStreamTemplates.class,
MapEntryTemplates.class,
MockitoTemplates.class,
MultimapTemplates.class,
NullTemplates.class,
OptionalTemplates.class,
PrimitiveTemplates.class,
ReactorTemplates.class,
RxJava2AdapterTemplates.class,
StreamTemplates.class,
StringTemplates.class,
TestNGToAssertJTemplates.class,
TimeTemplates.class,
WebClientTemplates.class);
// XXX: Create a JUnit extension to automatically discover the template collections in a given
// context to make sure the list is exhaustive.
private static Stream<Arguments> validateTemplateCollectionTestCases() {
// XXX: Drop the filter once we have added tests for AssertJ! We can then also replace this
// method with `@ValueSource(classes = {...})`.
return TEMPLATE_COLLECTIONS.stream()
.filter(not(AssertJTemplates.class::equals))
.map(Arguments::arguments);
}
@MethodSource("validateTemplateCollectionTestCases")
@ParameterizedTest
void validateTemplateCollection(Class<?> clazz) {
RefasterTemplateCollection.validate(clazz);
}
}

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules.input;
package tech.picnic.errorprone.refastertemplates.input;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.Offset.offset;
@@ -7,9 +7,9 @@ import static org.assertj.core.data.Percentage.withPercentage;
import com.google.common.collect.ImmutableSet;
import java.math.BigDecimal;
import org.assertj.core.api.AbstractBigDecimalAssert;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
import tech.picnic.errorprone.refaster.test.RefasterTemplateTestCase;
final class AssertJBigDecimalRulesTest implements RefasterRuleCollectionTestCase {
final class AssertJBigDecimalTemplatesTest implements RefasterTemplateTestCase {
@Override
public ImmutableSet<?> elidedTypesAndStaticImports() {
return ImmutableSet.of(offset(0), withPercentage(0));

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules.input;
package tech.picnic.errorprone.refastertemplates.input;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.Offset.offset;
@@ -7,9 +7,9 @@ import static org.assertj.core.data.Percentage.withPercentage;
import com.google.common.collect.ImmutableSet;
import java.math.BigInteger;
import org.assertj.core.api.AbstractBigIntegerAssert;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
import tech.picnic.errorprone.refaster.test.RefasterTemplateTestCase;
final class AssertJBigIntegerRulesTest implements RefasterRuleCollectionTestCase {
final class AssertJBigIntegerTemplatesTest implements RefasterTemplateTestCase {
@Override
public ImmutableSet<?> elidedTypesAndStaticImports() {
return ImmutableSet.of(offset(0), withPercentage(0));

View File

@@ -1,12 +1,12 @@
package tech.picnic.errorprone.refasterrules.input;
package tech.picnic.errorprone.refastertemplates.input;
import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.collect.ImmutableSet;
import org.assertj.core.api.AbstractBooleanAssert;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
import tech.picnic.errorprone.refaster.test.RefasterTemplateTestCase;
final class AssertJBooleanRulesTest implements RefasterRuleCollectionTestCase {
final class AssertJBooleanTemplatesTest implements RefasterTemplateTestCase {
AbstractBooleanAssert<?> testAbstractBooleanAssertIsEqualTo() {
return assertThat(true).isNotEqualTo(!Boolean.FALSE);
}

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules.input;
package tech.picnic.errorprone.refastertemplates.input;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.Offset.offset;
@@ -6,9 +6,9 @@ import static org.assertj.core.data.Percentage.withPercentage;
import com.google.common.collect.ImmutableSet;
import org.assertj.core.api.AbstractByteAssert;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
import tech.picnic.errorprone.refaster.test.RefasterTemplateTestCase;
final class AssertJByteRulesTest implements RefasterRuleCollectionTestCase {
final class AssertJByteTemplatesTest implements RefasterTemplateTestCase {
@Override
public ImmutableSet<?> elidedTypesAndStaticImports() {
return ImmutableSet.of(offset(0), withPercentage(0));

View File

@@ -1,12 +1,12 @@
package tech.picnic.errorprone.refasterrules.input;
package tech.picnic.errorprone.refastertemplates.input;
import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.collect.ImmutableSet;
import org.assertj.core.api.AbstractAssert;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
import tech.picnic.errorprone.refaster.test.RefasterTemplateTestCase;
final class AssertJCharSequenceRulesTest implements RefasterRuleCollectionTestCase {
final class AssertJCharSequenceTemplatesTest implements RefasterTemplateTestCase {
void testAssertThatCharSequenceIsEmpty() {
assertThat("foo".length()).isEqualTo(0L);
assertThat("foo".length()).isNotPositive();

View File

@@ -1,12 +1,12 @@
package tech.picnic.errorprone.refasterrules.input;
package tech.picnic.errorprone.refastertemplates.input;
import static org.assertj.core.api.Assertions.assertThat;
import java.math.BigDecimal;
import org.assertj.core.api.AbstractComparableAssert;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
import tech.picnic.errorprone.refaster.test.RefasterTemplateTestCase;
final class AssertJComparableRulesTest implements RefasterRuleCollectionTestCase {
final class AssertJComparableTemplatesTest implements RefasterTemplateTestCase {
AbstractComparableAssert<?, ?> testAssertThatIsEqualByComparingTo() {
return assertThat(BigDecimal.ZERO.compareTo(BigDecimal.ONE)).isEqualTo(0);
}

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules.input;
package tech.picnic.errorprone.refastertemplates.input;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.Offset.offset;
@@ -6,9 +6,9 @@ import static org.assertj.core.data.Percentage.withPercentage;
import com.google.common.collect.ImmutableSet;
import org.assertj.core.api.AbstractDoubleAssert;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
import tech.picnic.errorprone.refaster.test.RefasterTemplateTestCase;
final class AssertJDoubleRulesTest implements RefasterRuleCollectionTestCase {
final class AssertJDoubleTemplatesTest implements RefasterTemplateTestCase {
@Override
public ImmutableSet<?> elidedTypesAndStaticImports() {
return ImmutableSet.of(withPercentage(0));

View File

@@ -1,13 +1,13 @@
package tech.picnic.errorprone.refasterrules.input;
package tech.picnic.errorprone.refastertemplates.input;
import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import org.assertj.core.api.EnumerableAssert;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
import tech.picnic.errorprone.refaster.test.RefasterTemplateTestCase;
final class AssertJEnumerableRulesTest implements RefasterRuleCollectionTestCase {
final class AssertJEnumerableTemplatesTest implements RefasterTemplateTestCase {
@Override
public ImmutableSet<?> elidedTypesAndStaticImports() {
return ImmutableSet.of(Iterables.class);

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules.input;
package tech.picnic.errorprone.refastertemplates.input;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.Offset.offset;
@@ -6,9 +6,9 @@ import static org.assertj.core.data.Percentage.withPercentage;
import com.google.common.collect.ImmutableSet;
import org.assertj.core.api.AbstractFloatAssert;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
import tech.picnic.errorprone.refaster.test.RefasterTemplateTestCase;
final class AssertJFloatRulesTest implements RefasterRuleCollectionTestCase {
final class AssertJFloatTemplatesTest implements RefasterTemplateTestCase {
@Override
public ImmutableSet<?> elidedTypesAndStaticImports() {
return ImmutableSet.of(withPercentage(0));

View File

@@ -1,4 +1,4 @@
package tech.picnic.errorprone.refasterrules.input;
package tech.picnic.errorprone.refastertemplates.input;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.Offset.offset;
@@ -6,9 +6,9 @@ import static org.assertj.core.data.Percentage.withPercentage;
import com.google.common.collect.ImmutableSet;
import org.assertj.core.api.AbstractIntegerAssert;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
import tech.picnic.errorprone.refaster.test.RefasterTemplateTestCase;
final class AssertJIntegerRulesTest implements RefasterRuleCollectionTestCase {
final class AssertJIntegerTemplatesTest implements RefasterTemplateTestCase {
@Override
public ImmutableSet<?> elidedTypesAndStaticImports() {
return ImmutableSet.of(offset(0), withPercentage(0));

Some files were not shown because too many files have changed in this diff Show More