mirror of
https://github.com/jlengrand/error-prone-support.git
synced 2026-03-10 15:49:33 +00:00
Compare commits
5 Commits
v0.17.0
...
benhalasi/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
24dbe77522 | ||
|
|
2311bd54b1 | ||
|
|
fcd708e00f | ||
|
|
244ac55a01 | ||
|
|
ec36dcab72 |
7
.github/workflows/build.yml
vendored
7
.github/workflows/build.yml
vendored
@@ -7,6 +7,7 @@ permissions:
|
||||
contents: read
|
||||
jobs:
|
||||
build:
|
||||
if: github.repository == 'PicnicSupermarket/error-prone-support'
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ ubuntu-22.04 ]
|
||||
@@ -26,15 +27,13 @@ jobs:
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
|
||||
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
allowed-endpoints: >
|
||||
api.adoptium.net:443
|
||||
github.com:443
|
||||
jitpack.io:443
|
||||
objects.githubusercontent.com:443
|
||||
repo.maven.apache.org:443
|
||||
# We run the build twice for each supported JDK: once against the
|
||||
# original Error Prone release, using only Error Prone checks available
|
||||
@@ -42,7 +41,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 and set up JDK and Maven
|
||||
uses: s4u/setup-maven-action@489441643219d2b93ee2a127b2402eb640a1b947 # v1.13.0
|
||||
uses: s4u/setup-maven-action@6d44c18d67d9e1549907b8815efa5e4dada1801b # v1.12.0
|
||||
with:
|
||||
java-version: ${{ matrix.jdk }}
|
||||
java-distribution: ${{ matrix.distribution }}
|
||||
|
||||
10
.github/workflows/codeql.yml
vendored
10
.github/workflows/codeql.yml
vendored
@@ -13,6 +13,7 @@ permissions:
|
||||
contents: read
|
||||
jobs:
|
||||
analyze:
|
||||
if: github.repository == 'PicnicSupermarket/error-prone-support'
|
||||
strategy:
|
||||
matrix:
|
||||
language: [ java, ruby ]
|
||||
@@ -22,31 +23,30 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
|
||||
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
allowed-endpoints: >
|
||||
api.adoptium.net:443
|
||||
api.github.com:443
|
||||
github.com:443
|
||||
objects.githubusercontent.com:443
|
||||
repo.maven.apache.org:443
|
||||
uploads.github.com:443
|
||||
- name: Check out code and set up JDK and Maven
|
||||
uses: s4u/setup-maven-action@489441643219d2b93ee2a127b2402eb640a1b947 # v1.13.0
|
||||
uses: s4u/setup-maven-action@6d44c18d67d9e1549907b8815efa5e4dada1801b # v1.12.0
|
||||
with:
|
||||
java-version: 17.0.10
|
||||
java-distribution: temurin
|
||||
maven-version: 3.9.6
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1
|
||||
uses: github/codeql-action/init@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
- name: Perform minimal build
|
||||
if: matrix.language == 'java'
|
||||
run: mvn -T1C clean package -DskipTests -Dverification.skip
|
||||
- name: Perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1
|
||||
uses: github/codeql-action/analyze@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9
|
||||
with:
|
||||
category: /language:${{ matrix.language }}
|
||||
|
||||
9
.github/workflows/deploy-website.yml
vendored
9
.github/workflows/deploy-website.yml
vendored
@@ -9,10 +9,11 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
jobs:
|
||||
build:
|
||||
if: github.repository == 'PicnicSupermarket/error-prone-support'
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
|
||||
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
@@ -39,10 +40,10 @@ jobs:
|
||||
www.youtube.com:443
|
||||
youtrack.jetbrains.com:443
|
||||
- name: Check out code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: ruby/setup-ruby@6bd3d993c602f6b675728ebaecb2b569ff86e99b # v1.174.0
|
||||
- uses: ruby/setup-ruby@5f19ec79cedfadb78ab837f95b87734d0003c899 # v1.173.0
|
||||
with:
|
||||
working-directory: ./website
|
||||
bundler-cache: true
|
||||
@@ -74,7 +75,7 @@ jobs:
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
|
||||
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
|
||||
10
.github/workflows/openssf-scorecard.yml
vendored
10
.github/workflows/openssf-scorecard.yml
vendored
@@ -14,6 +14,7 @@ permissions:
|
||||
contents: read
|
||||
jobs:
|
||||
analyze:
|
||||
if: github.repository == 'PicnicSupermarket/error-prone-support'
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
@@ -21,14 +22,13 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
|
||||
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
allowed-endpoints: >
|
||||
api.github.com:443
|
||||
api.osv.dev:443
|
||||
api.scorecard.dev:443
|
||||
api.securityscorecards.dev:443
|
||||
fulcio.sigstore.dev:443
|
||||
github.com:443
|
||||
@@ -37,16 +37,16 @@ jobs:
|
||||
tuf-repo-cdn.sigstore.dev:443
|
||||
www.bestpractices.dev:443
|
||||
- name: Check out code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run OpenSSF Scorecard analysis
|
||||
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
|
||||
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
publish_results: ${{ github.ref == 'refs/heads/master' }}
|
||||
- name: Update GitHub's code scanning dashboard
|
||||
uses: github/codeql-action/upload-sarif@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1
|
||||
uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
9
.github/workflows/pitest-analyze-pr.yml
vendored
9
.github/workflows/pitest-analyze-pr.yml
vendored
@@ -9,20 +9,19 @@ permissions:
|
||||
contents: read
|
||||
jobs:
|
||||
analyze-pr:
|
||||
if: github.repository == 'PicnicSupermarket/error-prone-support'
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
|
||||
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
allowed-endpoints: >
|
||||
api.adoptium.net:443
|
||||
github.com:443
|
||||
objects.githubusercontent.com:443
|
||||
repo.maven.apache.org:443
|
||||
- name: Check out code and set up JDK and Maven
|
||||
uses: s4u/setup-maven-action@489441643219d2b93ee2a127b2402eb640a1b947 # v1.13.0
|
||||
uses: s4u/setup-maven-action@6d44c18d67d9e1549907b8815efa5e4dada1801b # v1.12.0
|
||||
with:
|
||||
checkout-fetch-depth: 2
|
||||
java-version: 17.0.10
|
||||
@@ -38,7 +37,7 @@ jobs:
|
||||
- name: Aggregate Pitest reports
|
||||
run: mvn pitest-git:aggregate -DkilledEmoji=":tada:" -DmutantEmoji=":zombie:" -DtrailingText="Mutation testing report by [Pitest](https://pitest.org/). Review any surviving mutants by inspecting the line comments under [_Files changed_](${{ github.event.number }}/files)."
|
||||
- name: Upload Pitest reports as artifact
|
||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: pitest-reports
|
||||
path: ./target/pit-reports-ci
|
||||
|
||||
8
.github/workflows/pitest-update-pr.yml
vendored
8
.github/workflows/pitest-update-pr.yml
vendored
@@ -11,7 +11,7 @@ permissions:
|
||||
actions: read
|
||||
jobs:
|
||||
update-pr:
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' && github.repository == 'PicnicSupermarket/error-prone-support' }}
|
||||
permissions:
|
||||
actions: read
|
||||
checks: write
|
||||
@@ -20,18 +20,16 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
|
||||
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
allowed-endpoints: >
|
||||
api.adoptium.net:443
|
||||
api.github.com:443
|
||||
github.com:443
|
||||
objects.githubusercontent.com:443
|
||||
repo.maven.apache.org:443
|
||||
- name: Check out code and set up JDK and Maven
|
||||
uses: s4u/setup-maven-action@489441643219d2b93ee2a127b2402eb640a1b947 # v1.13.0
|
||||
uses: s4u/setup-maven-action@6d44c18d67d9e1549907b8815efa5e4dada1801b # v1.12.0
|
||||
with:
|
||||
java-version: 17.0.10
|
||||
java-distribution: temurin
|
||||
|
||||
12
.github/workflows/run-integration-tests.yml
vendored
12
.github/workflows/run-integration-tests.yml
vendored
@@ -9,31 +9,29 @@ name: "Integration tests"
|
||||
on:
|
||||
issue_comment:
|
||||
types: [ created ]
|
||||
pull_request:
|
||||
push:
|
||||
permissions:
|
||||
contents: read
|
||||
jobs:
|
||||
run-integration-tests:
|
||||
name: On-demand integration test
|
||||
if: |
|
||||
github.event.issue.pull_request && contains(github.event.comment.body, '/integration-test')
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
|
||||
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
allowed-endpoints: >
|
||||
api.adoptium.net:443
|
||||
checkstyle.org:443
|
||||
github.com:443
|
||||
objects.githubusercontent.com:443
|
||||
oss.sonatype.org:443
|
||||
raw.githubusercontent.com:443
|
||||
repo.maven.apache.org:443
|
||||
repository.sonatype.org:443
|
||||
- name: Check out code and set up JDK and Maven
|
||||
uses: s4u/setup-maven-action@489441643219d2b93ee2a127b2402eb640a1b947 # v1.13.0
|
||||
uses: s4u/setup-maven-action@6d44c18d67d9e1549907b8815efa5e4dada1801b # v1.12.0
|
||||
with:
|
||||
checkout-ref: "refs/pull/${{ github.event.issue.number }}/head"
|
||||
java-version: 17.0.10
|
||||
@@ -45,7 +43,7 @@ jobs:
|
||||
run: xvfb-run ./integration-tests/checkstyle.sh "${{ runner.temp }}/artifacts"
|
||||
- name: Upload artifacts on failure
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: integration-test-checkstyle
|
||||
path: "${{ runner.temp }}/artifacts"
|
||||
|
||||
7
.github/workflows/sonarcloud.yml
vendored
7
.github/workflows/sonarcloud.yml
vendored
@@ -19,22 +19,19 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
|
||||
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
allowed-endpoints: >
|
||||
api.adoptium.net:443
|
||||
api.sonarcloud.io:443
|
||||
ea6ne4j2sb.execute-api.eu-central-1.amazonaws.com:443
|
||||
github.com:443
|
||||
objects.githubusercontent.com:443
|
||||
repo.maven.apache.org:443
|
||||
sc-cleancode-sensorcache-eu-central-1-prod.s3.amazonaws.com:443
|
||||
scanner.sonarcloud.io:443
|
||||
sonarcloud.io:443
|
||||
- name: Check out code and set up JDK and Maven
|
||||
uses: s4u/setup-maven-action@489441643219d2b93ee2a127b2402eb640a1b947 # v1.13.0
|
||||
uses: s4u/setup-maven-action@6d44c18d67d9e1549907b8815efa5e4dada1801b # v1.12.0
|
||||
with:
|
||||
checkout-fetch-depth: 0
|
||||
java-version: 17.0.10
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"separateMinorPatch": true
|
||||
},
|
||||
{
|
||||
"matchPackageNames": [
|
||||
"matchDepNames": [
|
||||
"dawidd6/action-download-artifact",
|
||||
"github/codeql-action",
|
||||
"ruby/setup-ruby"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.17.0</version>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>documentation-support</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.17.0</version>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>error-prone-contrib</artifactId>
|
||||
@@ -122,11 +122,6 @@
|
||||
<artifactId>jakarta.servlet-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
|
||||
@@ -232,7 +232,7 @@ public final class JUnitValueSource extends BugChecker implements MethodTreeMatc
|
||||
@Override
|
||||
public @Nullable Void visitReturn(ReturnTree node, @Nullable Void unused) {
|
||||
returnExpressions.add(node.getExpression());
|
||||
return super.visitReturn(node, null);
|
||||
return super.visitReturn(node, unused);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -192,7 +192,7 @@ public final class LexicographicalAnnotationAttributeListing extends BugChecker
|
||||
@Override
|
||||
public @Nullable Void visitIdentifier(IdentifierTree node, @Nullable Void unused) {
|
||||
nodes.add(ImmutableList.of(node.getName().toString()));
|
||||
return super.visitIdentifier(node, null);
|
||||
return super.visitIdentifier(node, unused);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -203,13 +203,13 @@ public final class LexicographicalAnnotationAttributeListing extends BugChecker
|
||||
? STRING_ARGUMENT_SPLITTER.splitToStream(str).collect(toImmutableList())
|
||||
: ImmutableList.of(String.valueOf(value)));
|
||||
|
||||
return super.visitLiteral(node, null);
|
||||
return super.visitLiteral(node, unused);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Void visitPrimitiveType(PrimitiveTypeTree node, @Nullable Void unused) {
|
||||
nodes.add(ImmutableList.of(node.getPrimitiveTypeKind().toString()));
|
||||
return super.visitPrimitiveType(node, null);
|
||||
return super.visitPrimitiveType(node, unused);
|
||||
}
|
||||
}.scan(array, null);
|
||||
|
||||
|
||||
@@ -210,7 +210,7 @@ public final class NonStaticImport extends BugChecker implements CompilationUnit
|
||||
}
|
||||
}
|
||||
|
||||
return super.visitIdentifier(node, null);
|
||||
return super.visitIdentifier(node, unused);
|
||||
}
|
||||
}.scan(tree, null);
|
||||
}
|
||||
|
||||
@@ -290,7 +290,7 @@ final class ComparatorRules {
|
||||
static final class MinOfPairCustomOrder<T> {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("java:S1067" /* The conditional operators are independent. */)
|
||||
T before(T value1, T value2, Comparator<? super T> cmp) {
|
||||
T before(T value1, T value2, Comparator<T> cmp) {
|
||||
return Refaster.anyOf(
|
||||
cmp.compare(value1, value2) <= 0 ? value1 : value2,
|
||||
cmp.compare(value1, value2) > 0 ? value2 : value1,
|
||||
@@ -305,7 +305,7 @@ final class ComparatorRules {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
T after(T value1, T value2, Comparator<? super T> cmp) {
|
||||
T after(T value1, T value2, Comparator<T> cmp) {
|
||||
return Comparators.min(value1, value2, cmp);
|
||||
}
|
||||
}
|
||||
@@ -357,7 +357,7 @@ final class ComparatorRules {
|
||||
static final class MaxOfPairCustomOrder<T> {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("java:S1067" /* The conditional operators are independent. */)
|
||||
T before(T value1, T value2, Comparator<? super T> cmp) {
|
||||
T before(T value1, T value2, Comparator<T> cmp) {
|
||||
return Refaster.anyOf(
|
||||
cmp.compare(value1, value2) >= 0 ? value1 : value2,
|
||||
cmp.compare(value1, value2) < 0 ? value2 : value1,
|
||||
@@ -372,7 +372,7 @@ final class ComparatorRules {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
T after(T value1, T value2, Comparator<? super T> cmp) {
|
||||
T after(T value1, T value2, Comparator<T> cmp) {
|
||||
return Comparators.max(value1, value2, cmp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
|
||||
import static java.util.function.Predicate.isEqual;
|
||||
import static java.util.function.Predicate.not;
|
||||
|
||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||
@@ -20,9 +19,9 @@ import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
|
||||
final class EqualityRules {
|
||||
private EqualityRules() {}
|
||||
|
||||
/** Prefer reference-based equality for enums. */
|
||||
// Primitive value comparisons are not matched, because Error Prone flags those out of the box.
|
||||
static final class EnumReferenceEquality<T extends Enum<T>> {
|
||||
/** Prefer reference-based quality for enums. */
|
||||
// Primitive value comparisons are not listed, because Error Prone flags those out of the box.
|
||||
static final class PrimitiveOrReferenceEquality<T extends Enum<T>> {
|
||||
/**
|
||||
* Enums can be compared by reference. It is safe to do so even in the face of refactorings,
|
||||
* because if the type is ever converted to a non-enum, then Error-Prone will complain about any
|
||||
@@ -44,20 +43,6 @@ final class EqualityRules {
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer reference-based equality for enums. */
|
||||
static final class EnumReferenceEqualityLambda<T extends Enum<T>> {
|
||||
@BeforeTemplate
|
||||
Predicate<T> before(T e) {
|
||||
return Refaster.anyOf(isEqual(e), e::equals);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@SuppressWarnings("java:S1698" /* Reference comparison is valid for enums. */)
|
||||
Predicate<T> after(T e) {
|
||||
return v -> v == e;
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link Object#equals(Object)} over the equivalent lambda function. */
|
||||
// XXX: As it stands, this rule is a special case of what `MethodReferenceUsage` tries to achieve.
|
||||
// If/when `MethodReferenceUsage` becomes production ready, we should simply drop this check.
|
||||
|
||||
@@ -302,22 +302,16 @@ import tech.picnic.errorprone.refaster.annotation.TypeMigration;
|
||||
final class JUnitToAssertJRules {
|
||||
private JUnitToAssertJRules() {}
|
||||
|
||||
static final class Fail<T> {
|
||||
static final class ThrowNewAssertionError {
|
||||
@BeforeTemplate
|
||||
T before() {
|
||||
return Assertions.fail();
|
||||
void before() {
|
||||
Assertions.fail();
|
||||
}
|
||||
|
||||
// XXX: Add `@UseImportPolicy(STATIC_IMPORT_ALWAYS)` once
|
||||
// https://github.com/google/error-prone/pull/3584 is resolved. Until that time, statically
|
||||
// importing AssertJ's `fail` is likely to clash with an existing static import of JUnit's
|
||||
// `fail`. Note that combining Error Prone's `RemoveUnusedImports` and
|
||||
// `UnnecessarilyFullyQualified` checks and our `StaticImport` check will anyway cause the
|
||||
// method to be imported statically if possible; just in a less efficient manner.
|
||||
@AfterTemplate
|
||||
@DoNotCall
|
||||
T after() {
|
||||
return fail();
|
||||
void after() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,7 +321,12 @@ final class JUnitToAssertJRules {
|
||||
return Assertions.fail(message);
|
||||
}
|
||||
|
||||
// XXX: Add `@UseImportPolicy(STATIC_IMPORT_ALWAYS)`. See `Fail` comment.
|
||||
// XXX: Add `@UseImportPolicy(STATIC_IMPORT_ALWAYS)` once
|
||||
// https://github.com/google/error-prone/pull/3584 is resolved. Until that time, statically
|
||||
// importing AssertJ's `fail` is likely to clash with an existing static import of JUnit's
|
||||
// `fail`. Note that combining Error Prone's `RemoveUnusedImports` and
|
||||
// `UnnecessarilyFullyQualified` checks and our `StaticImport` check will anyway cause the
|
||||
// method to be imported statically if possible; just in a less efficient manner.
|
||||
@AfterTemplate
|
||||
T after(String message) {
|
||||
return fail(message);
|
||||
@@ -340,24 +339,28 @@ final class JUnitToAssertJRules {
|
||||
return Assertions.fail(message, throwable);
|
||||
}
|
||||
|
||||
// XXX: Add `@UseImportPolicy(STATIC_IMPORT_ALWAYS)`. See `Fail` comment.
|
||||
// XXX: Add `@UseImportPolicy(STATIC_IMPORT_ALWAYS)` once
|
||||
// https://github.com/google/error-prone/pull/3584 is resolved. Until that time, statically
|
||||
// importing AssertJ's `fail` is likely to clash with an existing static import of JUnit's
|
||||
// `fail`. Note that combining Error Prone's `RemoveUnusedImports` and
|
||||
// `UnnecessarilyFullyQualified` checks and our `StaticImport` check will anyway cause the
|
||||
// method to be imported statically if possible; just in a less efficient manner.
|
||||
@AfterTemplate
|
||||
T after(String message, Throwable throwable) {
|
||||
return fail(message, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
static final class FailWithThrowable<T> {
|
||||
static final class FailWithThrowable {
|
||||
@BeforeTemplate
|
||||
T before(Throwable throwable) {
|
||||
return Assertions.fail(throwable);
|
||||
void before(Throwable throwable) {
|
||||
Assertions.fail(throwable);
|
||||
}
|
||||
|
||||
// XXX: Add `@UseImportPolicy(STATIC_IMPORT_ALWAYS)`. See `Fail` comment.
|
||||
@AfterTemplate
|
||||
@DoNotCall
|
||||
T after(Throwable throwable) {
|
||||
return fail(throwable);
|
||||
void after(Throwable throwable) {
|
||||
throw new AssertionError(throwable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,19 +27,6 @@ import tech.picnic.errorprone.refaster.matchers.IsLikelyTrivialComputation;
|
||||
final class OptionalRules {
|
||||
private OptionalRules() {}
|
||||
|
||||
/** Prefer {@link Optional#empty()} over the more contrived alternative. */
|
||||
static final class OptionalEmpty<T> {
|
||||
@BeforeTemplate
|
||||
Optional<T> before() {
|
||||
return Optional.ofNullable(null);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Optional<T> after() {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
static final class OptionalOfNullable<T> {
|
||||
// XXX: Refaster should be smart enough to also rewrite occurrences in which there are
|
||||
// parentheses around the null check, but that's currently not the case. Try to fix that.
|
||||
|
||||
@@ -3,6 +3,7 @@ package tech.picnic.errorprone.refasterrules;
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.common.collect.MoreCollectors.toOptional;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static java.util.Comparator.naturalOrder;
|
||||
import static java.util.Comparator.reverseOrder;
|
||||
@@ -33,7 +34,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
@@ -52,6 +52,7 @@ import reactor.util.context.Context;
|
||||
import reactor.util.function.Tuple2;
|
||||
import tech.picnic.errorprone.refaster.annotation.Description;
|
||||
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
|
||||
import tech.picnic.errorprone.refaster.annotation.Severity;
|
||||
import tech.picnic.errorprone.refaster.matchers.IsEmpty;
|
||||
import tech.picnic.errorprone.refaster.matchers.IsIdentityOperation;
|
||||
import tech.picnic.errorprone.refaster.matchers.ThrowsCheckedException;
|
||||
@@ -379,23 +380,30 @@ final class ReactorRules {
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link Flux#take(long)} over {@link Flux#take(long, boolean)} where relevant.
|
||||
* Prefer {@link Flux#take(long, boolean)} over {@link Flux#take(long)}.
|
||||
*
|
||||
* <p>In Reactor versions prior to 3.5.0, {@code Flux#take(long)} makes an unbounded request
|
||||
* upstream, and is equivalent to {@code Flux#take(long, false)}. From version 3.5.0 onwards, the
|
||||
* behavior of {@code Flux#take(long)} instead matches {@code Flux#take(long, true)}.
|
||||
* upstream, and is equivalent to {@code Flux#take(long, false)}. In 3.5.0, the behavior of {@code
|
||||
* Flux#take(long)} will change to that of {@code Flux#take(long, true)}.
|
||||
*
|
||||
* <p>The intent with this Refaster rule is to get the new behavior before upgrading to Reactor
|
||||
* 3.5.0.
|
||||
*/
|
||||
// XXX: Drop this rule some time after upgrading to Reactor 3.6.0, or introduce a way to apply
|
||||
// this rule only when an older version of Reactor is on the classpath.
|
||||
// XXX: Once Reactor 3.6.0 is out, introduce a rule that rewrites code in the opposite direction.
|
||||
@Description(
|
||||
"From Reactor 3.5.0 onwards, `take(n)` no longer requests an unbounded number of elements upstream.")
|
||||
"Prior to Reactor 3.5.0, `take(n)` requests and unbounded number of elements upstream.")
|
||||
@Severity(WARNING)
|
||||
static final class FluxTake<T> {
|
||||
@BeforeTemplate
|
||||
Flux<T> before(Flux<T> flux, long n) {
|
||||
return flux.take(n, /* limitRequest= */ true);
|
||||
return flux.take(n);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Flux<T> after(Flux<T> flux, long n) {
|
||||
return flux.take(n);
|
||||
return flux.take(n, /* limitRequest= */ true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -481,20 +489,15 @@ final class ReactorRules {
|
||||
}
|
||||
|
||||
/** Prefer {@link Flux#just(Object)} over more contrived alternatives. */
|
||||
static final class FluxJust<T> {
|
||||
static final class FluxJust {
|
||||
@BeforeTemplate
|
||||
Flux<Integer> before(int value) {
|
||||
return Flux.range(value, 1);
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
Flux<T> before(T value) {
|
||||
return Mono.just(value).repeat().take(1);
|
||||
Flux<Integer> before(int start) {
|
||||
return Flux.range(start, 1);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Flux<T> after(T value) {
|
||||
return Flux.just(value);
|
||||
Flux<Integer> after(int start) {
|
||||
return Flux.just(start);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -563,7 +566,6 @@ final class ReactorRules {
|
||||
@Matches(IsIdentityOperation.class)
|
||||
Function<? super P, ? extends Publisher<? extends S>> identityOperation) {
|
||||
return Refaster.anyOf(
|
||||
flux.concatMap(function, 0),
|
||||
flux.flatMap(function, 1),
|
||||
flux.flatMapSequential(function, 1),
|
||||
flux.map(function).concatMap(identityOperation));
|
||||
@@ -1910,41 +1912,4 @@ final class ReactorRules {
|
||||
return step.verifyTimeout(duration);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link Mono#fromFuture(Supplier)} over {@link Mono#fromFuture(CompletableFuture)}, as
|
||||
* the former may defer initiation of the asynchornous computation until subscription.
|
||||
*/
|
||||
static final class MonoFromFutureSupplier<T> {
|
||||
// XXX: Constrain the `future` parameter using `@NotMatches(IsIdentityOperation.class)` once
|
||||
// `IsIdentityOperation` no longer matches nullary method invocations.
|
||||
@BeforeTemplate
|
||||
Mono<T> before(CompletableFuture<T> future) {
|
||||
return Mono.fromFuture(future);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Mono<T> after(CompletableFuture<T> future) {
|
||||
return Mono.fromFuture(() -> future);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link Mono#fromFuture(Supplier, boolean)} over {@link
|
||||
* Mono#fromFuture(CompletableFuture, boolean)}, as the former may defer initiation of the
|
||||
* asynchornous computation until subscription.
|
||||
*/
|
||||
static final class MonoFromFutureSupplierBoolean<T> {
|
||||
// XXX: Constrain the `future` parameter using `@NotMatches(IsIdentityOperation.class)` once
|
||||
// `IsIdentityOperation` no longer matches nullary method invocations.
|
||||
@BeforeTemplate
|
||||
Mono<T> before(CompletableFuture<T> future, boolean suppressCancel) {
|
||||
return Mono.fromFuture(future, suppressCancel);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Mono<T> after(CompletableFuture<T> future, boolean suppressCancel) {
|
||||
return Mono.fromFuture(() -> future, suppressCancel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,9 +161,8 @@ final class TestNGToAssertJRules {
|
||||
|
||||
@AfterTemplate
|
||||
@DoNotCall
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after() {
|
||||
fail();
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
|
||||
import static java.util.function.Predicate.isEqual;
|
||||
import static java.util.function.Predicate.not;
|
||||
|
||||
import com.google.common.collect.BoundType;
|
||||
@@ -15,10 +14,10 @@ import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
final class EqualityRulesTest implements RefasterRuleCollectionTestCase {
|
||||
@Override
|
||||
public ImmutableSet<Object> elidedTypesAndStaticImports() {
|
||||
return ImmutableSet.of(Objects.class, Optional.class, isEqual(null), not(null));
|
||||
return ImmutableSet.of(Objects.class, Optional.class, not(null));
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testEnumReferenceEquality() {
|
||||
ImmutableSet<Boolean> testPrimitiveOrReferenceEquality() {
|
||||
return ImmutableSet.of(
|
||||
RoundingMode.UP.equals(RoundingMode.DOWN),
|
||||
Objects.equals(RoundingMode.UP, RoundingMode.DOWN),
|
||||
@@ -28,10 +27,6 @@ final class EqualityRulesTest implements RefasterRuleCollectionTestCase {
|
||||
RoundingMode.UP.ordinal() != RoundingMode.DOWN.ordinal());
|
||||
}
|
||||
|
||||
ImmutableSet<Predicate<RoundingMode>> testEnumReferenceEqualityLambda() {
|
||||
return ImmutableSet.of(isEqual(RoundingMode.DOWN), RoundingMode.UP::equals);
|
||||
}
|
||||
|
||||
boolean testEqualsPredicate() {
|
||||
// XXX: When boxing is involved this rule seems to break. Example:
|
||||
// Stream.of(1).anyMatch(e -> Integer.MIN_VALUE.equals(e));
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
|
||||
import static java.util.function.Predicate.isEqual;
|
||||
import static java.util.function.Predicate.not;
|
||||
|
||||
import com.google.common.collect.BoundType;
|
||||
@@ -15,10 +14,10 @@ import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
final class EqualityRulesTest implements RefasterRuleCollectionTestCase {
|
||||
@Override
|
||||
public ImmutableSet<Object> elidedTypesAndStaticImports() {
|
||||
return ImmutableSet.of(Objects.class, Optional.class, isEqual(null), not(null));
|
||||
return ImmutableSet.of(Objects.class, Optional.class, not(null));
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testEnumReferenceEquality() {
|
||||
ImmutableSet<Boolean> testPrimitiveOrReferenceEquality() {
|
||||
return ImmutableSet.of(
|
||||
RoundingMode.UP == RoundingMode.DOWN,
|
||||
RoundingMode.UP == RoundingMode.DOWN,
|
||||
@@ -28,10 +27,6 @@ final class EqualityRulesTest implements RefasterRuleCollectionTestCase {
|
||||
RoundingMode.UP != RoundingMode.DOWN);
|
||||
}
|
||||
|
||||
ImmutableSet<Predicate<RoundingMode>> testEnumReferenceEqualityLambda() {
|
||||
return ImmutableSet.of(v -> v == RoundingMode.DOWN, v -> v == RoundingMode.UP);
|
||||
}
|
||||
|
||||
boolean testEqualsPredicate() {
|
||||
// XXX: When boxing is involved this rule seems to break. Example:
|
||||
// Stream.of(1).anyMatch(e -> Integer.MIN_VALUE.equals(e));
|
||||
|
||||
@@ -32,8 +32,8 @@ final class JUnitToAssertJRulesTest implements RefasterRuleCollectionTestCase {
|
||||
(Runnable) () -> assertTrue(true));
|
||||
}
|
||||
|
||||
Object testFail() {
|
||||
return Assertions.fail();
|
||||
void testThrowNewAssertionError() {
|
||||
Assertions.fail();
|
||||
}
|
||||
|
||||
Object testFailWithMessage() {
|
||||
@@ -44,8 +44,8 @@ final class JUnitToAssertJRulesTest implements RefasterRuleCollectionTestCase {
|
||||
return Assertions.fail("foo", new IllegalStateException());
|
||||
}
|
||||
|
||||
Object testFailWithThrowable() {
|
||||
return Assertions.fail(new IllegalStateException());
|
||||
void testFailWithThrowable() {
|
||||
Assertions.fail(new IllegalStateException());
|
||||
}
|
||||
|
||||
void testAssertThatIsTrue() {
|
||||
|
||||
@@ -35,8 +35,8 @@ final class JUnitToAssertJRulesTest implements RefasterRuleCollectionTestCase {
|
||||
(Runnable) () -> assertTrue(true));
|
||||
}
|
||||
|
||||
Object testFail() {
|
||||
return org.assertj.core.api.Assertions.fail();
|
||||
void testThrowNewAssertionError() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
Object testFailWithMessage() {
|
||||
@@ -47,8 +47,8 @@ final class JUnitToAssertJRulesTest implements RefasterRuleCollectionTestCase {
|
||||
return org.assertj.core.api.Assertions.fail("foo", new IllegalStateException());
|
||||
}
|
||||
|
||||
Object testFailWithThrowable() {
|
||||
return org.assertj.core.api.Assertions.fail(new IllegalStateException());
|
||||
void testFailWithThrowable() {
|
||||
throw new AssertionError(new IllegalStateException());
|
||||
}
|
||||
|
||||
void testAssertThatIsTrue() {
|
||||
|
||||
@@ -13,10 +13,6 @@ final class OptionalRulesTest implements RefasterRuleCollectionTestCase {
|
||||
return ImmutableSet.of(Streams.class);
|
||||
}
|
||||
|
||||
Optional<String> testOptionalEmpty() {
|
||||
return Optional.ofNullable(null);
|
||||
}
|
||||
|
||||
ImmutableSet<Optional<String>> testOptionalOfNullable() {
|
||||
return ImmutableSet.of(
|
||||
toString() == null ? Optional.empty() : Optional.of(toString()),
|
||||
|
||||
@@ -15,10 +15,6 @@ final class OptionalRulesTest implements RefasterRuleCollectionTestCase {
|
||||
return ImmutableSet.of(Streams.class);
|
||||
}
|
||||
|
||||
Optional<String> testOptionalEmpty() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
ImmutableSet<Optional<String>> testOptionalOfNullable() {
|
||||
return ImmutableSet.of(Optional.ofNullable(toString()), Optional.ofNullable(toString()));
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Supplier;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
@@ -143,7 +142,7 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
}
|
||||
|
||||
Flux<Integer> testFluxTake() {
|
||||
return Flux.just(1, 2, 3).take(1, true);
|
||||
return Flux.just(1, 2, 3).take(1);
|
||||
}
|
||||
|
||||
Mono<String> testMonoDefaultIfEmpty() {
|
||||
@@ -183,8 +182,8 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
Flux.range(0, 0));
|
||||
}
|
||||
|
||||
ImmutableSet<Flux<Integer>> testFluxJust() {
|
||||
return ImmutableSet.of(Flux.range(0, 1), Mono.just(2).repeat().take(1));
|
||||
Flux<Integer> testFluxJust() {
|
||||
return Flux.range(0, 1);
|
||||
}
|
||||
|
||||
ImmutableSet<Mono<?>> testMonoIdentity() {
|
||||
@@ -208,12 +207,11 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
|
||||
ImmutableSet<Flux<Integer>> testFluxConcatMap() {
|
||||
return ImmutableSet.of(
|
||||
Flux.just(1).concatMap(Mono::just, 0),
|
||||
Flux.just(2).flatMap(Mono::just, 1),
|
||||
Flux.just(3).flatMapSequential(Mono::just, 1),
|
||||
Flux.just(4).map(Mono::just).concatMap(identity()),
|
||||
Flux.just(5).map(Mono::just).concatMap(v -> v),
|
||||
Flux.just(6).map(Mono::just).concatMap(v -> Mono.empty()));
|
||||
Flux.just(1).flatMap(Mono::just, 1),
|
||||
Flux.just(2).flatMapSequential(Mono::just, 1),
|
||||
Flux.just(3).map(Mono::just).concatMap(identity()),
|
||||
Flux.just(4).map(Mono::just).concatMap(v -> v),
|
||||
Flux.just(5).map(Mono::just).concatMap(v -> Mono.empty()));
|
||||
}
|
||||
|
||||
ImmutableSet<Flux<Integer>> testFluxConcatMapWithPrefetch() {
|
||||
@@ -652,12 +650,4 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
Duration testStepVerifierLastStepVerifyTimeout() {
|
||||
return Mono.empty().as(StepVerifier::create).expectTimeout(Duration.ZERO).verify();
|
||||
}
|
||||
|
||||
Mono<Void> testMonoFromFutureSupplier() {
|
||||
return Mono.fromFuture(CompletableFuture.completedFuture(null));
|
||||
}
|
||||
|
||||
Mono<Void> testMonoFromFutureSupplierBoolean() {
|
||||
return Mono.fromFuture(CompletableFuture.completedFuture(null), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Supplier;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
@@ -148,7 +147,7 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
}
|
||||
|
||||
Flux<Integer> testFluxTake() {
|
||||
return Flux.just(1, 2, 3).take(1);
|
||||
return Flux.just(1, 2, 3).take(1, true);
|
||||
}
|
||||
|
||||
Mono<String> testMonoDefaultIfEmpty() {
|
||||
@@ -187,8 +186,8 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
Flux.empty());
|
||||
}
|
||||
|
||||
ImmutableSet<Flux<Integer>> testFluxJust() {
|
||||
return ImmutableSet.of(Flux.just(0), Flux.just(2));
|
||||
Flux<Integer> testFluxJust() {
|
||||
return Flux.just(0);
|
||||
}
|
||||
|
||||
ImmutableSet<Mono<?>> testMonoIdentity() {
|
||||
@@ -215,8 +214,7 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
Flux.just(2).concatMap(Mono::just),
|
||||
Flux.just(3).concatMap(Mono::just),
|
||||
Flux.just(4).concatMap(Mono::just),
|
||||
Flux.just(5).concatMap(Mono::just),
|
||||
Flux.just(6).map(Mono::just).concatMap(v -> Mono.empty()));
|
||||
Flux.just(5).map(Mono::just).concatMap(v -> Mono.empty()));
|
||||
}
|
||||
|
||||
ImmutableSet<Flux<Integer>> testFluxConcatMapWithPrefetch() {
|
||||
@@ -633,12 +631,4 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
Duration testStepVerifierLastStepVerifyTimeout() {
|
||||
return Mono.empty().as(StepVerifier::create).verifyTimeout(Duration.ZERO);
|
||||
}
|
||||
|
||||
Mono<Void> testMonoFromFutureSupplier() {
|
||||
return Mono.fromFuture(() -> CompletableFuture.completedFuture(null));
|
||||
}
|
||||
|
||||
Mono<Void> testMonoFromFutureSupplierBoolean() {
|
||||
return Mono.fromFuture(() -> CompletableFuture.completedFuture(null), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ final class TestNGToAssertJRulesTest implements RefasterRuleCollectionTestCase {
|
||||
}
|
||||
|
||||
void testFail() {
|
||||
fail();
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
void testFailWithMessage() {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.17.0</version>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>error-prone-experimental</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.17.0</version>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>error-prone-guidelines</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.17.0</version>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>error-prone-utils</artifactId>
|
||||
|
||||
@@ -66,21 +66,23 @@ error_prone_patch_flags="${error_prone_shared_flags} -XepPatchLocation:IN_PLACE
|
||||
-path "*/META-INF/services/com.google.errorprone.bugpatterns.BugChecker" \
|
||||
-not -path "*/error-prone-experimental/*" \
|
||||
-not -path "*/error-prone-guidelines/*" \
|
||||
-not -path "*/error-prone-contrib/*" \
|
||||
-print0 \
|
||||
| xargs -0 "${grep_command}" -hoP '[^.]+$' \
|
||||
| paste -s -d ',' -
|
||||
)"
|
||||
) -XepOpt:Refaster:NamePattern=.*Workshop.*"
|
||||
|
||||
error_prone_validation_flags="${error_prone_shared_flags} -XepDisableAllChecks $(
|
||||
find "${error_prone_support_root}" \
|
||||
-path "*/META-INF/services/com.google.errorprone.bugpatterns.BugChecker" \
|
||||
-not -path "*/error-prone-experimental/*" \
|
||||
-not -path "*/error-prone-guidelines/*" \
|
||||
-not -path "*/error-prone-contrib/*" \
|
||||
-print0 \
|
||||
| xargs -0 "${grep_command}" -hoP '[^.]+$' \
|
||||
| xargs -0 "${grep_command}" -hoP "[^.]+$' \
|
||||
| "${sed_command}" -r 's,(.*),-Xep:\1:WARN,' \
|
||||
| paste -s -d ' ' -
|
||||
)"
|
||||
) -XepOpt:Refaster:NamePattern=.*Workshop.*"
|
||||
|
||||
echo "Shared build flags: ${shared_build_flags}"
|
||||
echo "Error Prone patch flags: ${error_prone_patch_flags}"
|
||||
@@ -168,6 +170,7 @@ mvn ${shared_build_flags} \
|
||||
-Dtest='
|
||||
!MetadataGeneratorUtilTest#metadataFilesGenerationAllFiles,
|
||||
!XdocsJavaDocsTest#allCheckSectionJavaDocs' \
|
||||
-Dstyle.color=always \
|
||||
| tee "${validation_build_log}" \
|
||||
|| failure=1
|
||||
|
||||
@@ -191,12 +194,15 @@ else
|
||||
# XXX: This "diff of diffs" also contains vacuous sections, introduced due to
|
||||
# line offset differences. Try to omit those from the final output.
|
||||
if ! diff -u "${expected_changes}" "${actual_changes}"; then
|
||||
echo 'There are unexpected changes. Inspect the preceding output for details.'
|
||||
echo 'There are unexpected changes.'
|
||||
echo "Inspect the changes here: ${report_directory}/${test_name}-diff-of-diffs-changes.patch"
|
||||
diff -u "${expected_changes}" "${actual_changes}" > "${report_directory}/${test_name}-diff-of-diffs-changes.patch"
|
||||
failure=1
|
||||
fi
|
||||
echo 'Inspecting emitted warnings...'
|
||||
if ! diff -u "${expected_warnings}" "${actual_warnings}"; then
|
||||
echo 'Diagnostics output changed. Inspect the preceding output for details.'
|
||||
echo 'Diagnostics output changed.'
|
||||
diff -u "${expected_warnings}" "${actual_warnings}" > "${report_directory}/${test_name}-diff-of-diffs-warnings.patch"
|
||||
failure=1
|
||||
fi
|
||||
fi
|
||||
|
||||
122
pom.xml
122
pom.xml
@@ -4,7 +4,7 @@
|
||||
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.17.0</version>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Picnic :: Error Prone Support</name>
|
||||
@@ -48,11 +48,12 @@
|
||||
<module>refaster-runner</module>
|
||||
<module>refaster-support</module>
|
||||
<module>refaster-test-support</module>
|
||||
<module>workshop</module>
|
||||
</modules>
|
||||
|
||||
<scm child.scm.developerConnection.inherit.append.path="false" child.scm.url.inherit.append.path="false">
|
||||
<developerConnection>scm:git:git@github.com:PicnicSupermarket/error-prone-support.git</developerConnection>
|
||||
<tag>v0.17.0</tag>
|
||||
<tag>HEAD</tag>
|
||||
<url>https://github.com/PicnicSupermarket/error-prone-support</url>
|
||||
</scm>
|
||||
<issueManagement>
|
||||
@@ -148,7 +149,7 @@
|
||||
<groupId.error-prone>com.google.errorprone</groupId.error-prone>
|
||||
<!-- The build timestamp is derived from the most recent commit
|
||||
timestamp in support of reproducible builds. -->
|
||||
<project.build.outputTimestamp>2024-07-20T12:12:19Z</project.build.outputTimestamp>
|
||||
<project.build.outputTimestamp>2024-03-15T12:04:44Z</project.build.outputTimestamp>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<!-- Glob pattern identifying Refaster rule definition files. These
|
||||
Java classes don't contain "regular" code, and thus require special
|
||||
@@ -205,19 +206,19 @@
|
||||
one place. We use these to keep dependencies in sync. Version numbers
|
||||
that need to be referenced only once should *not* be listed here. -->
|
||||
<version.auto-service>1.1.1</version.auto-service>
|
||||
<version.auto-value>1.11.0</version.auto-value>
|
||||
<version.auto-value>1.10.4</version.auto-value>
|
||||
<version.error-prone>${version.error-prone-orig}</version.error-prone>
|
||||
<version.error-prone-fork>v${version.error-prone-orig}-picnic-1</version.error-prone-fork>
|
||||
<version.error-prone-orig>2.29.2</version.error-prone-orig>
|
||||
<version.error-prone-slf4j>0.1.25</version.error-prone-slf4j>
|
||||
<version.error-prone-fork>v${version.error-prone-orig}-picnic-2</version.error-prone-fork>
|
||||
<version.error-prone-orig>2.26.1</version.error-prone-orig>
|
||||
<version.error-prone-slf4j>0.1.23</version.error-prone-slf4j>
|
||||
<version.guava-beta-checker>1.0</version.guava-beta-checker>
|
||||
<version.jdk>17</version.jdk>
|
||||
<version.maven>3.9.5</version.maven>
|
||||
<version.mockito>5.12.0</version.mockito>
|
||||
<version.mockito>5.11.0</version.mockito>
|
||||
<version.nopen-checker>1.0.1</version.nopen-checker>
|
||||
<version.nullaway>0.11.0</version.nullaway>
|
||||
<version.nullaway>0.10.25</version.nullaway>
|
||||
<version.pitest-git>1.1.4</version.pitest-git>
|
||||
<version.rewrite-templating>1.12.0</version.rewrite-templating>
|
||||
<version.rewrite-templating>1.6.3</version.rewrite-templating>
|
||||
<version.surefire>3.2.3</version.surefire>
|
||||
</properties>
|
||||
|
||||
@@ -296,7 +297,7 @@
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson</groupId>
|
||||
<artifactId>jackson-bom</artifactId>
|
||||
<version>2.17.2</version>
|
||||
<version>2.17.0</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -338,14 +339,14 @@
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava-bom</artifactId>
|
||||
<version>33.2.1-jre</version>
|
||||
<version>33.1.0-jre</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.truth</groupId>
|
||||
<artifactId>truth</artifactId>
|
||||
<version>1.4.4</version>
|
||||
<version>1.4.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jakewharton.nopen</groupId>
|
||||
@@ -360,7 +361,7 @@
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-bom</artifactId>
|
||||
<version>2023.0.8</version>
|
||||
<version>2023.0.4</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -377,17 +378,12 @@
|
||||
<dependency>
|
||||
<groupId>io.swagger.core.v3</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
<version>2.2.22</version>
|
||||
<version>2.2.21</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.servlet</groupId>
|
||||
<artifactId>jakarta.servlet-api</artifactId>
|
||||
<version>6.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>6.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
@@ -412,32 +408,24 @@
|
||||
<dependency>
|
||||
<groupId>net.bytebuddy</groupId>
|
||||
<artifactId>byte-buddy</artifactId>
|
||||
<version>1.14.18</version>
|
||||
</dependency>
|
||||
<!-- Specified so that Renovate will file Maven upgrade PRs, which
|
||||
subsequently will cause `maven-enforcer-plugin` to require that
|
||||
developers build the project using the latest Maven release. -->
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-plugin-api</artifactId>
|
||||
<version>${version.maven}</version>
|
||||
<version>1.14.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>1.9.22.1</version>
|
||||
<version>1.9.22</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-bom</artifactId>
|
||||
<version>3.26.3</version>
|
||||
<version>3.25.3</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.checkerframework</groupId>
|
||||
<artifactId>checker-qual</artifactId>
|
||||
<version>3.45.0</version>
|
||||
<version>3.42.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
@@ -452,12 +440,12 @@
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<version>0.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit</groupId>
|
||||
<artifactId>junit-bom</artifactId>
|
||||
<version>5.10.3</version>
|
||||
<version>5.10.2</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -471,7 +459,7 @@
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-core</artifactId>
|
||||
<version>5.1.2</version>
|
||||
<version>5.0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openrewrite</groupId>
|
||||
@@ -481,40 +469,40 @@
|
||||
<dependency>
|
||||
<groupId>org.openrewrite.recipe</groupId>
|
||||
<artifactId>rewrite-recipe-bom</artifactId>
|
||||
<version>2.15.0</version>
|
||||
<version>2.8.1</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-bom</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.12</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>6.1.11</version>
|
||||
<version>6.1.5</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-test</artifactId>
|
||||
<version>3.3.2</version>
|
||||
<version>3.2.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-bom</artifactId>
|
||||
<version>6.3.1</version>
|
||||
<version>6.2.3</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<version>7.10.2</version>
|
||||
<version>7.9.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
@@ -525,7 +513,7 @@
|
||||
<plugin>
|
||||
<groupId>com.github.ekryd.sortpom</groupId>
|
||||
<artifactId>sortpom-maven-plugin</artifactId>
|
||||
<version>4.0.0</version>
|
||||
<version>3.4.1</version>
|
||||
<configuration>
|
||||
<createBackupFile>false</createBackupFile>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
@@ -629,7 +617,7 @@
|
||||
<plugin>
|
||||
<groupId>io.github.git-commit-id</groupId>
|
||||
<artifactId>git-commit-id-maven-plugin</artifactId>
|
||||
<version>9.0.1</version>
|
||||
<version>8.0.2</version>
|
||||
<configuration>
|
||||
<injectAllReactorProjects>true</injectAllReactorProjects>
|
||||
<runOnlyOnce>true</runOnlyOnce>
|
||||
@@ -648,7 +636,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>3.4.0</version>
|
||||
<version>3.3.1</version>
|
||||
<configuration>
|
||||
<checkstyleRules>
|
||||
<!-- We only enable rules that are not enforced by
|
||||
@@ -684,7 +672,6 @@
|
||||
<property name="allowNonPrintableEscapes" value="true" />
|
||||
</module>
|
||||
<module name="AvoidNoArgumentSuperConstructorCall" />
|
||||
<module name="ConstructorsDeclarationGrouping" />
|
||||
<module name="DeclarationOrder">
|
||||
<!-- We don't enforce sorting fields by
|
||||
their visibility modifier, for two
|
||||
@@ -897,7 +884,7 @@
|
||||
<dependency>
|
||||
<groupId>com.puppycrawl.tools</groupId>
|
||||
<artifactId>checkstyle</artifactId>
|
||||
<version>10.17.0</version>
|
||||
<version>10.15.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.spring.nohttp</groupId>
|
||||
@@ -917,7 +904,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>3.4.0</version>
|
||||
<version>3.3.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@@ -969,7 +956,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>3.7.1</version>
|
||||
<version>3.6.1</version>
|
||||
<configuration>
|
||||
<!-- XXX: Drop `ignoreAllNonTestScoped` once
|
||||
https://issues.apache.org/jira/browse/MNG-6058 is
|
||||
@@ -984,7 +971,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>3.1.2</version>
|
||||
<version>3.1.1</version>
|
||||
<configuration>
|
||||
<retryFailedDeploymentCount>3</retryFailedDeploymentCount>
|
||||
</configuration>
|
||||
@@ -992,7 +979,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<version>3.5.0</version>
|
||||
<version>3.4.1</version>
|
||||
<configuration>
|
||||
<fail>false</fail>
|
||||
<rules>
|
||||
@@ -1047,12 +1034,6 @@
|
||||
<requireJavaVersion>
|
||||
<version>${version.jdk}</version>
|
||||
</requireJavaVersion>
|
||||
<requireMatchingCoordinates>
|
||||
<moduleNameMustMatchArtifactId>true</moduleNameMustMatchArtifactId>
|
||||
</requireMatchingCoordinates>
|
||||
<requireMavenVersion>
|
||||
<version>${version.maven}</version>
|
||||
</requireMavenVersion>
|
||||
<requireNoRepositories />
|
||||
<requirePluginVersions />
|
||||
<requireUpperBoundDeps />
|
||||
@@ -1077,7 +1058,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>3.2.4</version>
|
||||
<version>3.2.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
@@ -1090,12 +1071,12 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-install-plugin</artifactId>
|
||||
<version>3.1.2</version>
|
||||
<version>3.1.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.4.2</version>
|
||||
<version>3.3.0</version>
|
||||
<configuration>
|
||||
<skipIfEmpty>true</skipIfEmpty>
|
||||
<archive>
|
||||
@@ -1123,7 +1104,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<version>3.6.3</version>
|
||||
<configuration>
|
||||
<additionalJOptions>
|
||||
<additionalJOption>--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</additionalJOption>
|
||||
@@ -1152,7 +1133,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-release-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<version>3.0.1</version>
|
||||
<configuration>
|
||||
<autoVersionSubmodules>true</autoVersionSubmodules>
|
||||
<preparationProfiles>release</preparationProfiles>
|
||||
@@ -1179,7 +1160,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.3.1</version>
|
||||
<version>3.3.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-source-jar</id>
|
||||
@@ -1193,7 +1174,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.3.1</version>
|
||||
<version>3.2.5</version>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
@@ -1209,7 +1190,7 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<version>3.5.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
@@ -1305,7 +1286,6 @@
|
||||
<!-- -->
|
||||
GPL-2.0-with-classpath-exception
|
||||
| CDDL/GPLv2+CE
|
||||
| CDDL + GPLv2 with classpath exception
|
||||
| GNU General Public License, version 2 (GPL2), with the classpath exception
|
||||
| GNU General Public License, version 2, with the Classpath Exception
|
||||
| GPL2 w/ CPE
|
||||
@@ -1340,7 +1320,7 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>tidy-maven-plugin</artifactId>
|
||||
<version>1.3.0</version>
|
||||
<version>1.2.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>check-pom</id>
|
||||
@@ -1353,7 +1333,7 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>versions-maven-plugin</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<version>2.16.2</version>
|
||||
<configuration>
|
||||
<updateBuildOutputTimestampPolicy>never</updateBuildOutputTimestampPolicy>
|
||||
</configuration>
|
||||
@@ -1361,7 +1341,7 @@
|
||||
<plugin>
|
||||
<groupId>org.gaul</groupId>
|
||||
<artifactId>modernizer-maven-plugin</artifactId>
|
||||
<version>2.9.0</version>
|
||||
<version>2.8.0</version>
|
||||
<configuration>
|
||||
<exclusionPatterns>
|
||||
<!-- The plugin suggests replacing usages of
|
||||
@@ -1422,7 +1402,7 @@
|
||||
<plugin>
|
||||
<groupId>org.pitest</groupId>
|
||||
<artifactId>pitest-maven</artifactId>
|
||||
<version>1.16.1</version>
|
||||
<version>1.15.8</version>
|
||||
<configuration>
|
||||
<excludedClasses>
|
||||
<!-- AutoValue generated classes. -->
|
||||
@@ -1476,7 +1456,7 @@
|
||||
<plugin>
|
||||
<groupId>org.sonarsource.scanner.maven</groupId>
|
||||
<artifactId>sonar-maven-plugin</artifactId>
|
||||
<version>4.0.0.4121</version>
|
||||
<version>3.11.0.3922</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.17.0</version>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>refaster-compiler</artifactId>
|
||||
|
||||
@@ -112,7 +112,7 @@ final class RefasterRuleCompilerTaskListener implements TaskListener {
|
||||
return (sym != null
|
||||
&& sym.getQualifiedName()
|
||||
.contentEquals(BeforeTemplate.class.getCanonicalName()))
|
||||
|| super.visitAnnotation(node, null);
|
||||
|| super.visitAnnotation(node, unused);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.17.0</version>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>refaster-runner</artifactId>
|
||||
@@ -58,11 +58,6 @@
|
||||
<artifactId>guava</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.17.0</version>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>refaster-support</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.17.0</version>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>refaster-test-support</artifactId>
|
||||
@@ -50,11 +50,6 @@
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
|
||||
@@ -319,7 +319,7 @@ public final class RefasterRuleCollection extends BugChecker implements Compilat
|
||||
return indexedMatches.subRangeMap(Range.closedOpen(startPosition, endPosition));
|
||||
}
|
||||
|
||||
private static ImmutableListMultimap<Long, String> getUnexpectedMatchesByLineNumber(
|
||||
private ImmutableListMultimap<Long, String> getUnexpectedMatchesByLineNumber(
|
||||
ImmutableRangeMap<Integer, String> matches, String ruleUnderTest, VisitorState state) {
|
||||
LineMap lineMap = state.getPath().getCompilationUnit().getLineMap();
|
||||
return matches.asMapOfRanges().entrySet().stream()
|
||||
|
||||
@@ -3,12 +3,6 @@
|
||||
releases:
|
||||
- version: 0.16.1
|
||||
compatible:
|
||||
- "2.29.2"
|
||||
- "2.29.1"
|
||||
- "2.29.0"
|
||||
- "2.28.0"
|
||||
- "2.27.1"
|
||||
- "2.27.0"
|
||||
- "2.26.1"
|
||||
- "2.26.0"
|
||||
- "2.25.0"
|
||||
@@ -17,12 +11,6 @@ releases:
|
||||
- "2.23.0"
|
||||
- version: 0.16.0
|
||||
compatible:
|
||||
- "2.29.2"
|
||||
- "2.29.1"
|
||||
- "2.29.0"
|
||||
- "2.28.0"
|
||||
- "2.27.1"
|
||||
- "2.27.0"
|
||||
- "2.26.1"
|
||||
- "2.26.0"
|
||||
- "2.25.0"
|
||||
@@ -31,12 +19,6 @@ releases:
|
||||
- "2.23.0"
|
||||
- version: 0.15.0
|
||||
compatible:
|
||||
- "2.29.2"
|
||||
- "2.29.1"
|
||||
- "2.29.0"
|
||||
- "2.28.0"
|
||||
- "2.27.1"
|
||||
- "2.27.0"
|
||||
- "2.26.1"
|
||||
- "2.26.0"
|
||||
- "2.25.0"
|
||||
@@ -45,12 +27,6 @@ releases:
|
||||
- "2.23.0"
|
||||
- version: 0.14.0
|
||||
compatible:
|
||||
- "2.29.2"
|
||||
- "2.29.1"
|
||||
- "2.29.0"
|
||||
- "2.28.0"
|
||||
- "2.27.1"
|
||||
- "2.27.0"
|
||||
- "2.26.1"
|
||||
- "2.26.0"
|
||||
- "2.25.0"
|
||||
|
||||
108
workshop/README.md
Normal file
108
workshop/README.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# Error Prone Workshop
|
||||
|
||||
XXX: @Rick update the slides.
|
||||
|
||||
## Initial setup of the workshop
|
||||
|
||||
1. Start by cloning this repository locally from GitHub.
|
||||
2. Checkout the `workshop` branch.
|
||||
3. Make sure to run `mvn clean install` in the root of this repository.
|
||||
4. Open your code editor and familiarize yourself with the project structure.
|
||||
|
||||
In IntelliJ IDEA (or your preferred editor), try to run the
|
||||
`WorkshopRefasterRulesTest` test. You might see the following error:
|
||||
|
||||
```
|
||||
java: exporting a package from system module jdk.compiler is not allowed with --release
|
||||
```
|
||||
|
||||
If this happens, go to _Settings -> Build, Execution, Deployment -> Compiler ->
|
||||
Java Compiler_ and deselect the option _Use '--release' option for
|
||||
cross-compilation (Java 9 and later)_.
|
||||
|
||||
Now the project is ready for the workshop.
|
||||
|
||||
## Part 1: Writing Refaster rules
|
||||
|
||||
During this part of the workshop we will implement multiple Refaster rules.
|
||||
|
||||
Go to the `workshop` module and open the
|
||||
`tech.picnic.errorprone.workshop.refasterrules` package. There you can find one
|
||||
example and 5 different exercises to do. Make sure to check out the
|
||||
`WorkshopRefasterRulesTest.java` class where you can enable tests. Per
|
||||
assignment there is a test in this class that one can enable (by dropping the
|
||||
`@Disabled` annotation) to validate your changes. The goal is to implement or
|
||||
improve the Refaster rules such that the enabled tests pass.
|
||||
|
||||
Tips:
|
||||
|
||||
* Go through the exercises in the proposed order.
|
||||
* The `XXX:` comments explains what needs to happen.
|
||||
* See the test cases for each Refaster rule by looking for the name of the
|
||||
Refaster rule prefixed with `test`. For example, the
|
||||
`WorkshopAssignment0Rules.java` rule collection has a Refaster rule named
|
||||
`ExampleStringIsEmpty`. In the `WorkshopAssignment0RulesTestInput.java` and
|
||||
`WorkshopAssignment0RulesTestOutput.java` files there is a
|
||||
`testExampleStringIsEmpty` method that shows the input and output to test the
|
||||
Refaster rule.
|
||||
|
||||
## Part 2: Writing Error Prone checks
|
||||
|
||||
During this part of the workshop we will implement parts of multiple Error
|
||||
Prone `BugChecker`s. Each of these classes contain `XXX` comments explaining
|
||||
what needs to be implemented. However, before diving in, make sure to first
|
||||
navigate to a check's associated test class to drop the class-level `@Disabled`
|
||||
annotation. Upon initial execution the tests will fail; the goal is to get then
|
||||
to pass.
|
||||
|
||||
Some utility classes that you can use:
|
||||
|
||||
* `com.google.errorprone.util.ASTHelpers`: contains many common operations on
|
||||
the Abstract Syntax Tree.
|
||||
* `com.google.errorprone.fixes.SuggestedFixes`: contains helper methods for
|
||||
creating `Fix`es.
|
||||
|
||||
To see the impact of the newly introduced Error Prone checks [re-trigger the
|
||||
integration test framework](#validating-changes-with-the-integration-tests).
|
||||
|
||||
## Part 3 (optional): Validating changes with the integration tests
|
||||
|
||||
We created an integration testing framework that allows us to see the impact of
|
||||
the rules that are created. This testing framework can be executed locally and
|
||||
via GitHub Actions.
|
||||
|
||||
If you still have more than 10-15 minutes left, and you want to test this
|
||||
locally, run the following commands:
|
||||
|
||||
```sh
|
||||
mvn clean install -DskipTests -Dverification.skip
|
||||
./integration-tests/checkstyle-10.12.4.sh
|
||||
```
|
||||
|
||||
Once the process is complete, and changes are introduced, the following output
|
||||
will be printed:
|
||||
|
||||
```
|
||||
There are unexpected changes.
|
||||
Inspect the changes here: /tmp/tmp.Cmr423L1pA/checkstyle-10.12.4-diff-of-diffs-changes.patch
|
||||
```
|
||||
|
||||
This file is be provided for your review using your preferred text editor.
|
||||
Alternatively, you can also navigate to the repository by going to the
|
||||
`./integration-tests/.repos/checkstyle` directory and executing `git log -p` to
|
||||
view the commit history and associated changes.
|
||||
|
||||
This shows the impact of the rules that you wrote when they are applied to
|
||||
Checkstyle!
|
||||
|
||||
The other option is to execute the integration test via GitHub Actions. You
|
||||
only need to commit and push to the branch. This will trigger execution of the
|
||||
integration tests, which will run for about 10 minutes. When the build is
|
||||
finished, go to the _Actions_ tab in your fork and navigate to your most recent
|
||||
commit and click on it. Then click on _Summary_ and download the artifact
|
||||
`integration-test-checkstyle-10.12.4` at the bottom. Once done, unzip the
|
||||
artifact and inspect the `checkstyle-10.12.4-diff-of-diffs-changes.patch` file
|
||||
to see the changes.
|
||||
|
||||
[eps-github]: https://github.com/PicnicSupermarket/error-prone-support
|
||||
[eps-workshop-jfall]: https://drive.google.com/file/d/1Es1OuSUmPHSt3BjeCWfrXfoF-cJkkA1A/view
|
||||
150
workshop/pom.xml
Normal file
150
workshop/pom.xml
Normal file
@@ -0,0 +1,150 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>workshop</artifactId>
|
||||
|
||||
<name>Picnic :: Error Prone Support :: Workshop</name>
|
||||
<description>Project for the Error Prone Workshop.</description>
|
||||
<url>https://error-prone.picnic.tech</url>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${groupId.error-prone}</groupId>
|
||||
<artifactId>error_prone_annotation</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${groupId.error-prone}</groupId>
|
||||
<artifactId>error_prone_annotations</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${groupId.error-prone}</groupId>
|
||||
<artifactId>error_prone_check_api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${groupId.error-prone}</groupId>
|
||||
<artifactId>error_prone_core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${groupId.error-prone}</groupId>
|
||||
<artifactId>error_prone_test_helpers</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>error-prone-utils</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>refaster-compiler</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>refaster-support</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>refaster-test-support</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.auto.service</groupId>
|
||||
<artifactId>auto-service-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-params</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openrewrite</groupId>
|
||||
<artifactId>rewrite-core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openrewrite</groupId>
|
||||
<artifactId>rewrite-java</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openrewrite</groupId>
|
||||
<artifactId>rewrite-java-11</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openrewrite</groupId>
|
||||
<artifactId>rewrite-templating</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<annotationProcessorPaths combine.children="append">
|
||||
<path>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>refaster-compiler</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>refaster-support</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
<compilerArgs combine.children="append">
|
||||
<arg>-Xplugin:RefasterRuleCompiler</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,33 @@
|
||||
package tech.picnic.errorprone.workshop.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
|
||||
/** A {@link BugChecker} that flags empty methods that seemingly can simply be deleted. */
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
summary = "Empty method can likely be deleted",
|
||||
severity = WARNING,
|
||||
tags = SIMPLIFICATION)
|
||||
public final class Assignment0DeleteEmptyMethod extends BugChecker implements MethodTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** Instantiates a new {@link Assignment0DeleteEmptyMethod} instance. */
|
||||
public Assignment0DeleteEmptyMethod() {}
|
||||
|
||||
@Override
|
||||
public Description matchMethod(MethodTree tree, VisitorState state) {
|
||||
// XXX: Part 1: Ensure that we only delete methods that contain no statements.
|
||||
// XXX: Part 2: Don't delete methods that are annotated with `@Override`.
|
||||
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package tech.picnic.errorprone.workshop.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
import static com.google.errorprone.matchers.Matchers.allOf;
|
||||
import static com.google.errorprone.matchers.Matchers.argument;
|
||||
import static com.google.errorprone.matchers.Matchers.argumentCount;
|
||||
import static com.google.errorprone.matchers.Matchers.instanceMethod;
|
||||
import static com.google.errorprone.matchers.Matchers.nullLiteral;
|
||||
|
||||
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.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
|
||||
* 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.
|
||||
*/
|
||||
@BugPattern(
|
||||
summary = "Prefer `.isNull()` over `.isEqualTo(null)`",
|
||||
severity = SUGGESTION,
|
||||
tags = SIMPLIFICATION)
|
||||
public final class Assignment1AssertJIsNullMethod extends BugChecker
|
||||
implements MethodInvocationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Matcher<MethodInvocationTree> ASSERT_IS_EQUAL_TO_NULL =
|
||||
allOf(
|
||||
instanceMethod().onDescendantOf("org.assertj.core.api.Assert").named("isEqualTo"),
|
||||
argumentCount(1),
|
||||
argument(0, nullLiteral()));
|
||||
|
||||
/** Instantiates a new {@link Assignment1AssertJIsNullMethod} instance. */
|
||||
public Assignment1AssertJIsNullMethod() {}
|
||||
|
||||
@Override
|
||||
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
|
||||
// This statement filters out `MethodInvocation`s that are *not* `assertThat().isEqualTo(null)`
|
||||
// statements.
|
||||
if (!ASSERT_IS_EQUAL_TO_NULL.matches(tree, state)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
SuggestedFix.Builder fix = SuggestedFix.builder();
|
||||
|
||||
// XXX: Using `fix.merge(<some code>);` make sure we rename the method invocation to `isNull`.
|
||||
// See the `SuggestedFixes` class ;).
|
||||
|
||||
tree.getArguments().forEach(arg -> fix.merge(SuggestedFix.delete(arg)));
|
||||
|
||||
return describeMatch(tree, fix.build());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package tech.picnic.errorprone.workshop.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
import static com.google.errorprone.matchers.Matchers.staticMethod;
|
||||
|
||||
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.sun.source.tree.ExpressionTree;
|
||||
import com.sun.source.tree.MethodInvocationTree;
|
||||
import tech.picnic.errorprone.utils.SourceCode;
|
||||
|
||||
/**
|
||||
* A {@link BugChecker} that flags method invocations for which all arguments are wrapped using
|
||||
* {@link org.mockito.Mockito#eq}; this is redundant.
|
||||
*/
|
||||
@BugPattern(
|
||||
summary = "Don't unnecessarily use Mockito's `eq(...)`",
|
||||
severity = SUGGESTION,
|
||||
tags = SIMPLIFICATION)
|
||||
public final class Assignment2DropMockitoEq extends BugChecker
|
||||
implements MethodInvocationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Matcher<ExpressionTree> MOCKITO_EQ_METHOD =
|
||||
staticMethod().onClass("org.mockito.ArgumentMatchers").named("eq");
|
||||
|
||||
/** Instantiates a new {@link Assignment2DropMockitoEq} instance. */
|
||||
public Assignment2DropMockitoEq() {}
|
||||
|
||||
@Override
|
||||
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
|
||||
// XXX: Make sure to return `Description.NO_MATCH` if the `tree` doesn't have arguments, or if
|
||||
// the `isEqInvocation` method below returns `false` for at least one of the arguments.
|
||||
|
||||
SuggestedFix.Builder suggestedFix = SuggestedFix.builder();
|
||||
for (ExpressionTree arg : tree.getArguments()) {
|
||||
suggestedFix.replace(
|
||||
arg,
|
||||
SourceCode.treeToString(
|
||||
Iterables.getOnlyElement(((MethodInvocationTree) arg).getArguments()), state));
|
||||
}
|
||||
|
||||
return describeMatch(tree, suggestedFix.build());
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnusedMethod" /* Recommended to use when implementing this assignment. */)
|
||||
private static boolean isEqInvocation(ExpressionTree tree, VisitorState state) {
|
||||
return tree instanceof MethodInvocationTree && MOCKITO_EQ_METHOD.matches(tree, state);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package tech.picnic.errorprone.workshop.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
import static com.google.errorprone.matchers.ChildMultiMatcher.MatchType.AT_LEAST_ONE;
|
||||
import static com.google.errorprone.matchers.Matchers.annotations;
|
||||
import static com.google.errorprone.matchers.Matchers.isType;
|
||||
|
||||
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.ClassTreeMatcher;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.google.errorprone.matchers.MultiMatcher;
|
||||
import com.google.errorprone.matchers.MultiMatcher.MultiMatchResult;
|
||||
import com.sun.source.tree.AnnotationTree;
|
||||
import com.sun.source.tree.ClassTree;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
import com.sun.source.tree.Tree;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import tech.picnic.errorprone.utils.SourceCode;
|
||||
|
||||
/** A {@link BugChecker} that flags redundant {@code @Autowired} constructor annotations. */
|
||||
@BugPattern(
|
||||
summary = "Omit `@Autowired` on a class' sole constructor, as it is redundant",
|
||||
severity = SUGGESTION,
|
||||
tags = SIMPLIFICATION)
|
||||
public final class Assignment3DropAutowiredConstructorAnnotation extends BugChecker
|
||||
implements ClassTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final MultiMatcher<Tree, AnnotationTree> AUTOWIRED_ANNOTATION =
|
||||
annotations(AT_LEAST_ONE, isType("org.springframework.beans.factory.annotation.Autowired"));
|
||||
|
||||
/** Instantiates a new {@link Assignment3DropAutowiredConstructorAnnotation} instance. */
|
||||
public Assignment3DropAutowiredConstructorAnnotation() {}
|
||||
|
||||
@Override
|
||||
public Description matchClass(ClassTree tree, VisitorState state) {
|
||||
// XXX: Using the `ASTHelpers#getConstructors` method, return `Description.NO_MATCH` if we do
|
||||
// not have exactly 1 constructor (start by dropping `new ArrayList<>()` on the next line).
|
||||
List<MethodTree> constructors = new ArrayList<>();
|
||||
|
||||
MultiMatchResult<AnnotationTree> hasAutowiredAnnotation =
|
||||
AUTOWIRED_ANNOTATION.multiMatchResult(Iterables.getOnlyElement(constructors), state);
|
||||
if (!hasAutowiredAnnotation.matches()) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
AnnotationTree annotation = hasAutowiredAnnotation.onlyMatchingNode();
|
||||
return describeMatch(annotation, SourceCode.deleteWithTrailingWhitespace(annotation, state));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package tech.picnic.errorprone.workshop.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
import static com.google.errorprone.matchers.ChildMultiMatcher.MatchType.AT_LEAST_ONE;
|
||||
import static com.google.errorprone.matchers.Matchers.annotations;
|
||||
import static com.google.errorprone.matchers.Matchers.anyOf;
|
||||
import static com.google.errorprone.matchers.Matchers.isType;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher;
|
||||
import com.google.errorprone.fixes.SuggestedFix;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.google.errorprone.matchers.MultiMatcher;
|
||||
import com.sun.source.tree.AnnotationTree;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
import javax.lang.model.element.Modifier;
|
||||
|
||||
/** A {@link BugChecker} that flags non-canonical JUnit method declarations. */
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
summary = "JUnit method declaration can likely be improved",
|
||||
severity = WARNING,
|
||||
tags = SIMPLIFICATION)
|
||||
@SuppressWarnings({
|
||||
"UnusedMethod",
|
||||
"UnusedVariable"
|
||||
} /* This check is yet to be implemented as part of the demo. */)
|
||||
public final class Assignment4JUnitTestMethodDeclaration extends BugChecker
|
||||
implements MethodTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final ImmutableSet<Modifier> ILLEGAL_MODIFIERS =
|
||||
Sets.immutableEnumSet(Modifier.PRIVATE, Modifier.PROTECTED, Modifier.PUBLIC);
|
||||
private static final MultiMatcher<MethodTree, AnnotationTree> TEST_METHOD =
|
||||
annotations(AT_LEAST_ONE, anyOf(isType("org.junit.jupiter.api.Test")));
|
||||
|
||||
/** Instantiates a new {@link Assignment4JUnitTestMethodDeclaration} instance. */
|
||||
public Assignment4JUnitTestMethodDeclaration() {}
|
||||
|
||||
@Override
|
||||
public Description matchMethod(MethodTree tree, VisitorState state) {
|
||||
// XXX: Part 1: Return `Description.NO_MATCH` if the method is not a `TEST_METHOD`.
|
||||
|
||||
SuggestedFix.Builder fixBuilder = SuggestedFix.builder();
|
||||
|
||||
// XXX: Part 2: Make sure that JUnit test methods don't use any of the modifiers from the
|
||||
// `ILLEGAL_MODIFIERS` field, by using `SuggestedFixes#removeModifiers` and
|
||||
// `SuggestedFix.Builder#merge`.
|
||||
|
||||
if (fixBuilder.isEmpty()) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
return describeMatch(tree, fixBuilder.build());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package tech.picnic.errorprone.workshop.bugpatterns;
|
||||
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
import static com.google.errorprone.matchers.Matchers.anyOf;
|
||||
import static com.google.errorprone.matchers.Matchers.staticMethod;
|
||||
import static com.google.errorprone.suppliers.Suppliers.OBJECT_TYPE;
|
||||
|
||||
import com.google.common.primitives.Primitives;
|
||||
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.bugpatterns.TypesWithUndefinedEquality;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.google.errorprone.matchers.Matcher;
|
||||
import com.google.errorprone.util.ASTHelpers;
|
||||
import com.google.errorprone.util.ASTHelpers.TargetType;
|
||||
import com.sun.source.tree.ExpressionTree;
|
||||
import com.sun.source.tree.MemberSelectTree;
|
||||
import com.sun.source.tree.MethodInvocationTree;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.code.Types;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/** A {@link BugChecker} that flags redundant identity conversions. */
|
||||
@BugPattern(
|
||||
summary = "Avoid or clarify identity conversions",
|
||||
severity = WARNING,
|
||||
tags = SIMPLIFICATION)
|
||||
public final class Assignment5DeleteIdentityConversion extends BugChecker
|
||||
implements MethodInvocationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Matcher<ExpressionTree> IS_CONVERSION_METHOD =
|
||||
anyOf(
|
||||
staticMethod()
|
||||
.onClassAny(
|
||||
Primitives.allWrapperTypes().stream()
|
||||
.map(Class::getName)
|
||||
.collect(toImmutableSet()))
|
||||
.named("valueOf"),
|
||||
staticMethod().onClass(String.class.getName()).named("valueOf"),
|
||||
staticMethod()
|
||||
.onClassAny(
|
||||
"com.google.common.collect.ImmutableBiMap",
|
||||
"com.google.common.collect.ImmutableList",
|
||||
"com.google.common.collect.ImmutableListMultimap",
|
||||
"com.google.common.collect.ImmutableMap",
|
||||
"com.google.common.collect.ImmutableMultimap",
|
||||
"com.google.common.collect.ImmutableMultiset",
|
||||
"com.google.common.collect.ImmutableRangeMap",
|
||||
"com.google.common.collect.ImmutableRangeSet",
|
||||
"com.google.common.collect.ImmutableSet",
|
||||
"com.google.common.collect.ImmutableSetMultimap",
|
||||
"com.google.common.collect.ImmutableTable")
|
||||
.named("copyOf"),
|
||||
staticMethod()
|
||||
.onClass("com.google.errorprone.matchers.Matchers")
|
||||
.namedAnyOf("allOf", "anyOf"));
|
||||
|
||||
/** Instantiates a new {@link Assignment5DeleteIdentityConversion} instance. */
|
||||
public Assignment5DeleteIdentityConversion() {}
|
||||
|
||||
@Override
|
||||
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
|
||||
List<? extends ExpressionTree> arguments = tree.getArguments();
|
||||
// XXX: Make sure we skip invocations that do not pass exactly one argument, by using the
|
||||
// `tree`.
|
||||
if (!IS_CONVERSION_METHOD.matches(tree, state)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
ExpressionTree sourceTree = arguments.get(0);
|
||||
Type sourceType = ASTHelpers.getType(sourceTree);
|
||||
Type resultType = ASTHelpers.getType(tree);
|
||||
TargetType targetType = ASTHelpers.targetType(state);
|
||||
if (sourceType == null || resultType == null || targetType == null) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
if (!state.getTypes().isSameType(sourceType, resultType)
|
||||
&& !isConvertibleWithWellDefinedEquality(sourceType, targetType.type(), state)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
if (sourceType.isPrimitive()
|
||||
&& state.getPath().getParentPath().getLeaf() instanceof MemberSelectTree) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
return buildDescription(tree)
|
||||
// XXX: Use the `.addFix()` to suggest replacing the original `tree` with the `sourceTree`.
|
||||
// Tip: You can get the actual String representation of a Tree by using the
|
||||
// `SourceCode#treeToString`.
|
||||
.build();
|
||||
}
|
||||
|
||||
private static boolean isConvertibleWithWellDefinedEquality(
|
||||
Type sourceType, Type targetType, VisitorState state) {
|
||||
Types types = state.getTypes();
|
||||
return !types.isSameType(targetType, OBJECT_TYPE.get(state))
|
||||
&& types.isConvertible(sourceType, targetType)
|
||||
&& Arrays.stream(TypesWithUndefinedEquality.values())
|
||||
.noneMatch(b -> b.matchesType(sourceType, state) || b.matchesType(targetType, state));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
|
||||
/** Refaster rule used as example for the assignments of the workshop. */
|
||||
final class WorkshopAssignment0Rules {
|
||||
private WorkshopAssignment0Rules() {}
|
||||
|
||||
/** Prefer {@link String#isEmpty()} over alternatives that consult the string's length. */
|
||||
static final class ExampleStringIsEmpty {
|
||||
@BeforeTemplate
|
||||
static boolean before(String string) {
|
||||
return string.length() == 0;
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
static boolean after(String string) {
|
||||
return string.isEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
/** Refaster rules for the first assignment of the workshop. */
|
||||
final class WorkshopAssignment1Rules {
|
||||
private WorkshopAssignment1Rules() {}
|
||||
|
||||
/** Prefer {@link String#String(char[])} over {@link String#copyValueOf(char[])}. */
|
||||
static final class NewStringCharArray {
|
||||
// XXX: Implement this Refaster rule.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.errorprone.refaster.Refaster;
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/** Refaster rules for the second assignment of the workshop. */
|
||||
final class WorkshopAssignment2Rules {
|
||||
private WorkshopAssignment2Rules() {}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableList#of(Object)} over alternatives that don't communicate the
|
||||
* immutability of the resulting list at the type level.
|
||||
*/
|
||||
static final class ImmutableListOfOne<T> {
|
||||
@BeforeTemplate
|
||||
static <T> List<T> before(T t) {
|
||||
return ImmutableList.copyOf(
|
||||
Refaster.anyOf(
|
||||
Collections.singletonList(t),
|
||||
List.of(t))
|
||||
);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
static <T> List<T> after(T t) {
|
||||
return ImmutableList.of(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
/** Refaster rules for the third assignment of the workshop. */
|
||||
@SuppressWarnings("UnusedTypeParameter" /* Ignore this for demo purposes. */)
|
||||
final class WorkshopAssignment3Rules {
|
||||
private WorkshopAssignment3Rules() {}
|
||||
|
||||
// XXX: Tip: check the input and output files to see the *expected* refactoring.
|
||||
|
||||
/** Prefer {@link Preconditions#checkArgument(boolean)} over if statements. */
|
||||
static final class CheckArgumentWithoutMessage {
|
||||
// XXX: Implement the Refaster rule to get the test green.
|
||||
}
|
||||
|
||||
/** Prefer {@link Preconditions#checkArgument(boolean, Object)} over if statements. */
|
||||
static final class CheckArgumentWithMessage {
|
||||
// XXX: Implement the Refaster rule to get the test green.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
/** Refaster rules for the fourth assignment of the workshop. */
|
||||
@SuppressWarnings("java:S1698" /* Reference comparison is valid for enums. */)
|
||||
final class WorkshopAssignment4Rules {
|
||||
private WorkshopAssignment4Rules() {}
|
||||
|
||||
// The test fails because non Enum comparisons are also rewritten.
|
||||
// Fix the test by tweaking the type parameters.
|
||||
|
||||
// XXX: Get the test to pass by improving the Refaster rule (uncommented it first).
|
||||
|
||||
// static final class PrimitiveOrReferenceEqualityEnum<T> {
|
||||
// @BeforeTemplate
|
||||
// boolean before(T a, T b) {
|
||||
// return Refaster.anyOf(a.equals(b), Objects.equals(a, b));
|
||||
// }
|
||||
//
|
||||
// @AfterTemplate
|
||||
// @AlsoNegation
|
||||
// boolean after(T a, T b) {
|
||||
// return a == b;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
/** Refaster rules for the fifth assignment of the workshop. */
|
||||
@SuppressWarnings("UnusedTypeParameter" /* Ignore this for demo purposes. */)
|
||||
final class WorkshopAssignment5Rules {
|
||||
private WorkshopAssignment5Rules() {}
|
||||
|
||||
abstract static class StreamDoAllMatch<T> {
|
||||
// XXX: Implement the Refaster rule to get the test green.
|
||||
// Tip: use the `@Placeholder` annotation.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package tech.picnic.errorprone.workshop.bugpatterns;
|
||||
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@Disabled("Enable this when implementing the BugChecker.")
|
||||
final class Assignment0Assignment0DeleteEmptyMethodTest {
|
||||
@Test
|
||||
void identification() {
|
||||
CompilationTestHelper.newInstance(Assignment0DeleteEmptyMethod.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"class A {",
|
||||
" Object m1() {",
|
||||
" return null;",
|
||||
" }",
|
||||
"",
|
||||
" void m2() {",
|
||||
" System.out.println(42);",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" static void m3() {}",
|
||||
"",
|
||||
" interface F {",
|
||||
" void fun();",
|
||||
" }",
|
||||
"}")
|
||||
.addSourceLines(
|
||||
"B.java",
|
||||
"final class B implements A.F {",
|
||||
" @Override",
|
||||
" public void fun() {}",
|
||||
"",
|
||||
" /** Javadoc. */",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" void m4() {}",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacement() {
|
||||
BugCheckerRefactoringTestHelper.newInstance(Assignment0DeleteEmptyMethod.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"final class A {",
|
||||
"",
|
||||
" void instanceMethod() {}",
|
||||
"",
|
||||
" static void staticMethod() {}",
|
||||
"",
|
||||
" static void staticMethodWithComment() {",
|
||||
" System.out.println(42);",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"final class A {",
|
||||
"",
|
||||
" static void staticMethodWithComment() {",
|
||||
" System.out.println(42);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package tech.picnic.errorprone.workshop.bugpatterns;
|
||||
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@Disabled("Enable this when implementing the BugChecker.")
|
||||
final class Assignment1AssertJIsNullMethodTest {
|
||||
@Test
|
||||
void identification() {
|
||||
CompilationTestHelper.newInstance(Assignment1AssertJIsNullMethod.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import static org.assertj.core.api.Assertions.assertThat;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" assertThat(1).isEqualTo(1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(1).isEqualTo(null);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(\"foo\").isEqualTo(null);",
|
||||
" isEqualTo(null);",
|
||||
" }",
|
||||
"",
|
||||
" private boolean isEqualTo(Object value) {",
|
||||
" return value.equals(\"bar\");",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacement() {
|
||||
BugCheckerRefactoringTestHelper.newInstance(Assignment1AssertJIsNullMethod.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"import static org.assertj.core.api.Assertions.assertThat;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" assertThat(1).isEqualTo(null);",
|
||||
" assertThat(\"foo\").isEqualTo(null);",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"import static org.assertj.core.api.Assertions.assertThat;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" assertThat(1).isNull();",
|
||||
" assertThat(\"foo\").isNull();",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package tech.picnic.errorprone.workshop.bugpatterns;
|
||||
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@Disabled("Enable this when implementing the BugChecker.")
|
||||
final class Assignment2DropMockitoEqTest {
|
||||
@Test
|
||||
void identification() {
|
||||
CompilationTestHelper.newInstance(Assignment2DropMockitoEq.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import static org.mockito.ArgumentMatchers.eq;",
|
||||
"import static org.mockito.ArgumentMatchers.notNull;",
|
||||
"import static org.mockito.Mockito.doAnswer;",
|
||||
"import static org.mockito.Mockito.mock;",
|
||||
"",
|
||||
"import java.util.function.BiConsumer;",
|
||||
"import java.util.function.Consumer;",
|
||||
"import org.mockito.ArgumentMatchers;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Runnable runnable = mock(Runnable.class);",
|
||||
" doAnswer(inv -> null).when(runnable).run();",
|
||||
"",
|
||||
" Consumer<String> consumer = mock(Consumer.class);",
|
||||
" doAnswer(inv -> null).when(consumer).accept(\"foo\");",
|
||||
" doAnswer(inv -> null).when(consumer).accept(notNull());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" doAnswer(inv -> null).when(consumer).accept(ArgumentMatchers.eq(\"foo\"));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" doAnswer(inv -> null).when(consumer).accept(eq(toString()));",
|
||||
"",
|
||||
" BiConsumer<Integer, String> biConsumer = mock(BiConsumer.class);",
|
||||
" doAnswer(inv -> null).when(biConsumer).accept(0, \"foo\");",
|
||||
" doAnswer(inv -> null).when(biConsumer).accept(eq(0), notNull());",
|
||||
" doAnswer(inv -> null).when(biConsumer).accept(notNull(), eq(\"foo\"));",
|
||||
" doAnswer(inv -> null)",
|
||||
" .when(biConsumer)",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" .accept(ArgumentMatchers.eq(0), ArgumentMatchers.eq(\"foo\"));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" doAnswer(inv -> null).when(biConsumer).accept(eq(hashCode()), eq(toString()));",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacement() {
|
||||
BugCheckerRefactoringTestHelper.newInstance(Assignment2DropMockitoEq.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"import static org.mockito.ArgumentMatchers.eq;",
|
||||
"import static org.mockito.Mockito.doAnswer;",
|
||||
"import static org.mockito.Mockito.mock;",
|
||||
"",
|
||||
"import java.util.function.BiConsumer;",
|
||||
"import java.util.function.Consumer;",
|
||||
"import org.mockito.ArgumentMatchers;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Consumer<String> consumer = mock(Consumer.class);",
|
||||
" doAnswer(inv -> null).when(consumer).accept(ArgumentMatchers.eq(\"foo\"));",
|
||||
" doAnswer(inv -> null).when(consumer).accept(eq(toString()));",
|
||||
"",
|
||||
" BiConsumer<Integer, String> biConsumer = mock(BiConsumer.class);",
|
||||
" doAnswer(inv -> null)",
|
||||
" .when(biConsumer)",
|
||||
" .accept(ArgumentMatchers.eq(0), ArgumentMatchers.eq(\"foo\"));",
|
||||
" doAnswer(inv -> null).when(biConsumer).accept(eq(hashCode()), eq(toString()));",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"import static org.mockito.ArgumentMatchers.eq;",
|
||||
"import static org.mockito.Mockito.doAnswer;",
|
||||
"import static org.mockito.Mockito.mock;",
|
||||
"",
|
||||
"import java.util.function.BiConsumer;",
|
||||
"import java.util.function.Consumer;",
|
||||
"import org.mockito.ArgumentMatchers;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Consumer<String> consumer = mock(Consumer.class);",
|
||||
" doAnswer(inv -> null).when(consumer).accept(\"foo\");",
|
||||
" doAnswer(inv -> null).when(consumer).accept(toString());",
|
||||
"",
|
||||
" BiConsumer<Integer, String> biConsumer = mock(BiConsumer.class);",
|
||||
" doAnswer(inv -> null).when(biConsumer).accept(0, \"foo\");",
|
||||
" doAnswer(inv -> null).when(biConsumer).accept(hashCode(), toString());",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package tech.picnic.errorprone.workshop.bugpatterns;
|
||||
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@Disabled("Enable this when implementing the BugChecker.")
|
||||
final class Assignment3DropAutowiredConstructorAnnotationTest {
|
||||
@Test
|
||||
void identification() {
|
||||
CompilationTestHelper.newInstance(
|
||||
Assignment3DropAutowiredConstructorAnnotation.class, getClass())
|
||||
.addSourceLines(
|
||||
"Container.java",
|
||||
"import com.google.errorprone.annotations.Immutable;",
|
||||
"import java.util.List;",
|
||||
"import org.springframework.beans.factory.annotation.Autowired;",
|
||||
"",
|
||||
"interface Container {",
|
||||
" @Immutable",
|
||||
" class A {",
|
||||
" A() {}",
|
||||
" }",
|
||||
"",
|
||||
" class B {",
|
||||
" @Autowired",
|
||||
" void setProperty(Object o) {}",
|
||||
" }",
|
||||
"",
|
||||
" class C {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Autowired",
|
||||
" C() {}",
|
||||
" }",
|
||||
"",
|
||||
" class D {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Autowired",
|
||||
" D(String x) {}",
|
||||
" }",
|
||||
"",
|
||||
" class E {",
|
||||
" @Autowired",
|
||||
" E() {}",
|
||||
"",
|
||||
" E(String x) {}",
|
||||
" }",
|
||||
"",
|
||||
" class F {",
|
||||
" F() {}",
|
||||
"",
|
||||
" @Autowired",
|
||||
" F(String x) {}",
|
||||
" }",
|
||||
"",
|
||||
" class G {",
|
||||
" @Autowired private Object o;",
|
||||
" }",
|
||||
"",
|
||||
" class H {",
|
||||
" @SafeVarargs",
|
||||
" H(List<String>... lists) {}",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacement() {
|
||||
BugCheckerRefactoringTestHelper.newInstance(
|
||||
Assignment3DropAutowiredConstructorAnnotation.class, getClass())
|
||||
.addInputLines(
|
||||
"Container.java",
|
||||
"import org.springframework.beans.factory.annotation.Autowired;",
|
||||
"",
|
||||
"interface Container {",
|
||||
" class A {",
|
||||
" @Autowired",
|
||||
" @Deprecated",
|
||||
" A() {}",
|
||||
" }",
|
||||
"",
|
||||
" class B {",
|
||||
" @Autowired",
|
||||
" B(String x) {}",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"Container.java",
|
||||
"import org.springframework.beans.factory.annotation.Autowired;",
|
||||
"",
|
||||
"interface Container {",
|
||||
" class A {",
|
||||
" @Deprecated",
|
||||
" A() {}",
|
||||
" }",
|
||||
"",
|
||||
" class B {",
|
||||
" B(String x) {}",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package tech.picnic.errorprone.workshop.bugpatterns;
|
||||
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@Disabled("Enable this to validate part 1.")
|
||||
final class Assignment4JUnitTestMethodDeclarationTest {
|
||||
@Test
|
||||
void identificationIllegalModifiers() {
|
||||
CompilationTestHelper.newInstance(Assignment4JUnitTestMethodDeclaration.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"",
|
||||
"class A {",
|
||||
" @Test",
|
||||
" void method1() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" public void method2() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" protected void method3() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private void method4() {}",
|
||||
"",
|
||||
" public void method5() {}",
|
||||
"",
|
||||
" protected void method6() {}",
|
||||
"",
|
||||
" private void method7() {}",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacementIllegalModifiers() {
|
||||
BugCheckerRefactoringTestHelper.newInstance(
|
||||
Assignment4JUnitTestMethodDeclaration.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"",
|
||||
"class A {",
|
||||
" @Test",
|
||||
" void foo() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" public void bar() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" protected void baz() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" private void qux() {}",
|
||||
"",
|
||||
" public void quux() {}",
|
||||
"",
|
||||
" private void quuz() {}",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"",
|
||||
"class A {",
|
||||
" @Test",
|
||||
" void foo() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void bar() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void baz() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void qux() {}",
|
||||
"",
|
||||
" public void quux() {}",
|
||||
"",
|
||||
" private void quuz() {}",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
package tech.picnic.errorprone.workshop.bugpatterns;
|
||||
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@Disabled("Enable this when implementing the BugChecker.")
|
||||
final class Assignment5DeleteIdentityConversionTest {
|
||||
@Test
|
||||
void identification() {
|
||||
CompilationTestHelper.newInstance(Assignment5DeleteIdentityConversion.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import static com.google.errorprone.matchers.Matchers.instanceMethod;",
|
||||
"import static com.google.errorprone.matchers.Matchers.staticMethod;",
|
||||
"",
|
||||
"import com.google.common.collect.ImmutableBiMap;",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableListMultimap;",
|
||||
"import com.google.common.collect.ImmutableMap;",
|
||||
"import com.google.common.collect.ImmutableMultimap;",
|
||||
"import com.google.common.collect.ImmutableMultiset;",
|
||||
"import com.google.common.collect.ImmutableRangeMap;",
|
||||
"import com.google.common.collect.ImmutableRangeSet;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import com.google.common.collect.ImmutableSetMultimap;",
|
||||
"import com.google.common.collect.ImmutableTable;",
|
||||
"import com.google.errorprone.matchers.Matcher;",
|
||||
"import com.google.errorprone.matchers.Matchers;",
|
||||
"",
|
||||
"public final class A {",
|
||||
" public void m() {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Matcher allOf1 = Matchers.allOf(instanceMethod());",
|
||||
" Matcher allOf2 = Matchers.allOf(instanceMethod(), staticMethod());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Matcher anyOf1 = Matchers.anyOf(staticMethod());",
|
||||
" Matcher anyOf2 = Matchers.anyOf(instanceMethod(), staticMethod());",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Boolean b1 = Boolean.valueOf(Boolean.FALSE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Boolean b2 = Boolean.valueOf(false);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" boolean b3 = Boolean.valueOf(Boolean.FALSE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" boolean b4 = Boolean.valueOf(false);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Byte byte1 = Byte.valueOf((Byte) Byte.MIN_VALUE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Byte byte2 = Byte.valueOf(Byte.MIN_VALUE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" byte byte3 = Byte.valueOf((Byte) Byte.MIN_VALUE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" byte byte4 = Byte.valueOf(Byte.MIN_VALUE);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Character c1 = Character.valueOf((Character) 'a');",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Character c2 = Character.valueOf('a');",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" char c3 = Character.valueOf((Character) 'a');",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" char c4 = Character.valueOf('a');",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Double d1 = Double.valueOf((Double) 0.0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Double d2 = Double.valueOf(0.0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" double d3 = Double.valueOf((Double) 0.0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" double d4 = Double.valueOf(0.0);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Float f1 = Float.valueOf((Float) 0.0F);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Float f2 = Float.valueOf(0.0F);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" float f3 = Float.valueOf((Float) 0.0F);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" float f4 = Float.valueOf(0.0F);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Integer i1 = Integer.valueOf((Integer) 1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Integer i2 = Integer.valueOf(1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" int i3 = Integer.valueOf((Integer) 1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" int i4 = Integer.valueOf(1);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Long l1 = Long.valueOf((Long) 1L);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Long l2 = Long.valueOf(1L);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" long l3 = Long.valueOf((Long) 1L);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" long l4 = Long.valueOf(1L);",
|
||||
"",
|
||||
" Long l5 = Long.valueOf((Integer) 1);",
|
||||
" Long l6 = Long.valueOf(1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" long l7 = Long.valueOf((Integer) 1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" long l8 = Long.valueOf(1);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Short s1 = Short.valueOf((Short) Short.MIN_VALUE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Short s2 = Short.valueOf(Short.MIN_VALUE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" short s3 = Short.valueOf((Short) Short.MIN_VALUE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" short s4 = Short.valueOf(Short.MIN_VALUE);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String boolStr = Boolean.valueOf(Boolean.FALSE).toString();",
|
||||
" int boolHash = Boolean.valueOf(false).hashCode();",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" int byteHash = Byte.valueOf((Byte) Byte.MIN_VALUE).hashCode();",
|
||||
" String byteStr = Byte.valueOf(Byte.MIN_VALUE).toString();",
|
||||
"",
|
||||
" String str1 = String.valueOf(0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String str2 = String.valueOf(\"1\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableBiMap<Object, Object> o1 = ImmutableBiMap.copyOf(ImmutableBiMap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableList<Object> o2 = ImmutableList.copyOf(ImmutableList.of());",
|
||||
" ImmutableListMultimap<Object, Object> o3 =",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableListMultimap.copyOf(ImmutableListMultimap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableMap<Object, Object> o4 = ImmutableMap.copyOf(ImmutableMap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableMultimap<Object, Object> o5 = ImmutableMultimap.copyOf(ImmutableMultimap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableMultiset<Object> o6 = ImmutableMultiset.copyOf(ImmutableMultiset.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableRangeMap<String, Object> o7 = ImmutableRangeMap.copyOf(ImmutableRangeMap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableRangeSet<String> o8 = ImmutableRangeSet.copyOf(ImmutableRangeSet.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableSet<Object> o9 = ImmutableSet.copyOf(ImmutableSet.of());",
|
||||
" ImmutableSetMultimap<Object, Object> o10 =",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableSetMultimap.copyOf(ImmutableSetMultimap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableTable<Object, Object, Object> o11 = ImmutableTable.copyOf(ImmutableTable.of());",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacement() {
|
||||
BugCheckerRefactoringTestHelper.newInstance(
|
||||
Assignment5DeleteIdentityConversion.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"import static com.google.errorprone.matchers.Matchers.staticMethod;",
|
||||
"import static org.mockito.Mockito.when;",
|
||||
"",
|
||||
"import com.google.common.collect.ImmutableCollection;",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import java.util.ArrayList;",
|
||||
"import java.util.Collection;",
|
||||
"",
|
||||
"public final class A {",
|
||||
" public void m() {",
|
||||
" ImmutableSet<Object> set1 = ImmutableSet.copyOf(ImmutableSet.of());",
|
||||
" ImmutableSet<Object> set2 = ImmutableSet.copyOf(ImmutableList.of());",
|
||||
"",
|
||||
" ImmutableCollection<Integer> list1 = ImmutableList.copyOf(ImmutableList.of(1));",
|
||||
" ImmutableCollection<Integer> list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));",
|
||||
"",
|
||||
" Collection<Integer> c1 = ImmutableSet.copyOf(ImmutableSet.of(1));",
|
||||
" Collection<Integer> c2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));",
|
||||
"",
|
||||
" Object o1 = ImmutableSet.copyOf(ImmutableList.of());",
|
||||
" Object o2 = ImmutableSet.copyOf(ImmutableSet.of());",
|
||||
"",
|
||||
" when(\"foo\".contains(\"f\")).thenAnswer(inv -> ImmutableSet.copyOf(ImmutableList.of(1)));",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"import static com.google.errorprone.matchers.Matchers.staticMethod;",
|
||||
"import static org.mockito.Mockito.when;",
|
||||
"",
|
||||
"import com.google.common.collect.ImmutableCollection;",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import java.util.ArrayList;",
|
||||
"import java.util.Collection;",
|
||||
"",
|
||||
"public final class A {",
|
||||
" public void m() {",
|
||||
" ImmutableSet<Object> set1 = ImmutableSet.of();",
|
||||
" ImmutableSet<Object> set2 = ImmutableSet.copyOf(ImmutableList.of());",
|
||||
"",
|
||||
" ImmutableCollection<Integer> list1 = ImmutableList.of(1);",
|
||||
" ImmutableCollection<Integer> list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));",
|
||||
"",
|
||||
" Collection<Integer> c1 = ImmutableSet.of(1);",
|
||||
" Collection<Integer> c2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));",
|
||||
"",
|
||||
" Object o1 = ImmutableSet.copyOf(ImmutableList.of());",
|
||||
" Object o2 = ImmutableSet.of();",
|
||||
"",
|
||||
" when(\"foo\".contains(\"f\")).thenAnswer(inv -> ImmutableSet.copyOf(ImmutableList.of(1)));",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollection;
|
||||
|
||||
final class WorkshopRefasterRulesTest {
|
||||
@Test
|
||||
void validateExampleRuleCollection() {
|
||||
RefasterRuleCollection.validate(WorkshopAssignment0Rules.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validateFirstWorkshopAssignment() {
|
||||
RefasterRuleCollection.validate(WorkshopAssignment1Rules.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validateSecondWorkshopAssignment() {
|
||||
RefasterRuleCollection.validate(WorkshopAssignment2Rules.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validateThirdWorkshopAssignment() {
|
||||
RefasterRuleCollection.validate(WorkshopAssignment3Rules.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validateFourthWorkshopAssignment() {
|
||||
RefasterRuleCollection.validate(WorkshopAssignment4Rules.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validateFifthWorkshopAssignment() {
|
||||
RefasterRuleCollection.validate(WorkshopAssignment5Rules.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class WorkshopAssignment0RulesTest implements RefasterRuleCollectionTestCase {
|
||||
boolean testExampleStringIsEmpty() {
|
||||
boolean b = "foo".length() == 0;
|
||||
return "bar".length() == 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class WorkshopAssignment0RulesTest implements RefasterRuleCollectionTestCase {
|
||||
boolean testExampleStringIsEmpty() {
|
||||
boolean b = "foo".isEmpty();
|
||||
return "bar".isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class WorkshopAssignment1RulesTest implements RefasterRuleCollectionTestCase {
|
||||
String testNewStringCharArray() {
|
||||
String.copyValueOf(new char[] {});
|
||||
String.copyValueOf(new char[] {'f', 'o', 'o'});
|
||||
return String.copyValueOf(new char[] {'b', 'a', 'r'});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class WorkshopAssignment1RulesTest implements RefasterRuleCollectionTestCase {
|
||||
String testNewStringCharArray() {
|
||||
new String(new char[] {});
|
||||
new String(new char[] {'f', 'o', 'o'});
|
||||
return new String(new char[] {'b', 'a', 'r'});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class WorkshopAssignment2RulesTest implements RefasterRuleCollectionTestCase {
|
||||
@Override
|
||||
public ImmutableSet<Object> elidedTypesAndStaticImports() {
|
||||
return ImmutableSet.of(Collections.class);
|
||||
}
|
||||
|
||||
List<Object> testImmutableListOfOne() {
|
||||
Collections.singletonList(1);
|
||||
Collections.singletonList("foo");
|
||||
List.of(1);
|
||||
return List.of("bar");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class WorkshopAssignment2RulesTest implements RefasterRuleCollectionTestCase {
|
||||
@Override
|
||||
public ImmutableSet<Object> elidedTypesAndStaticImports() {
|
||||
return ImmutableSet.of(Collections.class);
|
||||
}
|
||||
|
||||
List<Object> testImmutableListOfOne() {
|
||||
ImmutableList.of(1);
|
||||
ImmutableList.of("foo");
|
||||
ImmutableList.of(1);
|
||||
return ImmutableList.of("bar");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class WorkshopAssignment3RulesTest implements RefasterRuleCollectionTestCase {
|
||||
void testCheckArgumentWithoutMessage() {
|
||||
if (!"foo".isEmpty()) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (!"bar".isEmpty()) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
void testCheckArgumentWithMessage() {
|
||||
if (!"foo".isEmpty()) {
|
||||
throw new IllegalArgumentException("The string is not empty");
|
||||
}
|
||||
if (!"bar".isEmpty()) {
|
||||
throw new IllegalArgumentException(
|
||||
"The rule should be able rewrite all kinds of messages ;).");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class WorkshopAssignment3RulesTest implements RefasterRuleCollectionTestCase {
|
||||
void testCheckArgumentWithoutMessage() {
|
||||
checkArgument("foo".isEmpty());
|
||||
checkArgument("bar".isEmpty());
|
||||
}
|
||||
|
||||
void testCheckArgumentWithMessage() {
|
||||
checkArgument("foo".isEmpty(), "The string is not empty");
|
||||
checkArgument("bar".isEmpty(), "The rule should be able rewrite all kinds of messages ;).");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Objects;
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class WorkshopAssignment4RulesTest implements RefasterRuleCollectionTestCase {
|
||||
@Override
|
||||
public ImmutableSet<Object> elidedTypesAndStaticImports() {
|
||||
return ImmutableSet.of(Objects.class);
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testPrimitiveOrReferenceEqualityEnum() {
|
||||
// Don't pay attention to the `ImmutableSet#of` here, it's just syntactical sugar for the
|
||||
// testing framework.
|
||||
return ImmutableSet.of(
|
||||
"foo".equals("bar"),
|
||||
Integer.valueOf(1).equals(2),
|
||||
RoundingMode.UP.equals(RoundingMode.DOWN),
|
||||
Objects.equals(RoundingMode.UP, RoundingMode.DOWN),
|
||||
!RoundingMode.UP.equals(RoundingMode.DOWN),
|
||||
!Objects.equals(RoundingMode.UP, RoundingMode.DOWN));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Objects;
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class WorkshopAssignment4RulesTest implements RefasterRuleCollectionTestCase {
|
||||
@Override
|
||||
public ImmutableSet<Object> elidedTypesAndStaticImports() {
|
||||
return ImmutableSet.of(Objects.class);
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testPrimitiveOrReferenceEqualityEnum() {
|
||||
// Don't pay attention to the `ImmutableSet#of` here, it's just syntactical sugar for the
|
||||
// testing framework.
|
||||
return ImmutableSet.of(
|
||||
"foo".equals("bar"),
|
||||
Integer.valueOf(1).equals(2),
|
||||
RoundingMode.UP == RoundingMode.DOWN,
|
||||
RoundingMode.UP == RoundingMode.DOWN,
|
||||
RoundingMode.UP != RoundingMode.DOWN,
|
||||
RoundingMode.UP != RoundingMode.DOWN);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class WorkshopAssignment5RulesTest implements RefasterRuleCollectionTestCase {
|
||||
boolean testStreamDoAllMatch() {
|
||||
boolean example = Stream.of("foo").noneMatch(s -> !s.isBlank());
|
||||
return Stream.of("bar").noneMatch(b -> !b.startsWith("b"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class WorkshopAssignment5RulesTest implements RefasterRuleCollectionTestCase {
|
||||
boolean testStreamDoAllMatch() {
|
||||
boolean example = Stream.of("foo").allMatch(s -> s.isBlank());
|
||||
return Stream.of("bar").allMatch(b -> b.startsWith("b"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user