mirror of
https://github.com/jlengrand/error-prone-support.git
synced 2026-03-10 15:49:33 +00:00
Compare commits
9 Commits
pdsoels/do
...
gdejong/do
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2890bb983f | ||
|
|
f7165a84b6 | ||
|
|
b0ad824db8 | ||
|
|
e2b79dac47 | ||
|
|
dada0f23f1 | ||
|
|
20ed8568c2 | ||
|
|
546d3e3739 | ||
|
|
eca96a76d2 | ||
|
|
530fd8da1f |
2
.github/release.yml
vendored
2
.github/release.yml
vendored
@@ -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"
|
||||
|
||||
4
.github/workflows/build.yaml
vendored
4
.github/workflows/build.yaml
vendored
@@ -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:
|
||||
|
||||
29
.github/workflows/deploy-website.yaml
vendored
29
.github/workflows/deploy-website.yaml
vendored
@@ -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:
|
||||
|
||||
19
README.md
19
README.md
@@ -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/
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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?
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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> {
|
||||
@@ -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(
|
||||
@@ -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) {
|
||||
@@ -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 {
|
||||
@@ -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
|
||||
@@ -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>> {
|
||||
@@ -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 {
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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() {
|
||||
@@ -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)))
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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() {
|
||||
@@ -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()`.
|
||||
@@ -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.
|
||||
@@ -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> {
|
||||
@@ -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 {
|
||||
@@ -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> {
|
||||
@@ -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 {
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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> {
|
||||
@@ -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 {
|
||||
@@ -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() {
|
||||
@@ -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 {
|
||||
@@ -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
|
||||
@@ -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 {
|
||||
@@ -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
|
||||
@@ -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() {
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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> {
|
||||
@@ -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;
|
||||
@@ -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})",
|
||||
|
||||
@@ -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\";",
|
||||
" }",
|
||||
" }",
|
||||
"}")
|
||||
|
||||
@@ -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() {
|
||||
@@ -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 =
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
@@ -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));
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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));
|
||||
@@ -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();
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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));
|
||||
@@ -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);
|
||||
@@ -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));
|
||||
@@ -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
Reference in New Issue
Block a user