mirror of
https://github.com/jlengrand/error-prone-support.git
synced 2026-03-10 08:11:25 +00:00
Compare commits
99 Commits
sschroever
...
workshop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90fb015fa0 | ||
|
|
1d457c73e1 | ||
|
|
06aa53e9b9 | ||
|
|
f45899fba8 | ||
|
|
7b8a53ca9b | ||
|
|
e5045b0fdc | ||
|
|
d028146bd6 | ||
|
|
2843f47d67 | ||
|
|
c87db5536d | ||
|
|
561c8caf77 | ||
|
|
a279585a02 | ||
|
|
6312386ce2 | ||
|
|
f1c76411a3 | ||
|
|
f773f6e686 | ||
|
|
fe3e065394 | ||
|
|
bedf588e2a | ||
|
|
3a629b11ec | ||
|
|
fc2eb57b40 | ||
|
|
1c429f0d1c | ||
|
|
ac6ffc72e9 | ||
|
|
07399bb4ef | ||
|
|
aa988ef2b0 | ||
|
|
b58be2b89b | ||
|
|
8fa90f6121 | ||
|
|
6ba03c6352 | ||
|
|
912e06885d | ||
|
|
e803a5d333 | ||
|
|
4a1ad1b991 | ||
|
|
80d433f051 | ||
|
|
afd9703ce6 | ||
|
|
f9d310bc4b | ||
|
|
a3a9ca0bf0 | ||
|
|
0e609aeb1c | ||
|
|
e9dae1d66c | ||
|
|
f0ad9d21e6 | ||
|
|
7138aa2100 | ||
|
|
de4667628f | ||
|
|
5e958fe20b | ||
|
|
baa921caac | ||
|
|
ba040bd191 | ||
|
|
a3a20b52e5 | ||
|
|
5d8d27176b | ||
|
|
d878a57a8e | ||
|
|
eaec12f460 | ||
|
|
da7dafb6e7 | ||
|
|
5a7aaf12d6 | ||
|
|
92e4d74e4b | ||
|
|
4a0bc0c210 | ||
|
|
53152499d6 | ||
|
|
61d92fb33f | ||
|
|
8690f49c35 | ||
|
|
d808f664ec | ||
|
|
7f5f4820e9 | ||
|
|
f7a4427852 | ||
|
|
0e956bcd44 | ||
|
|
5395fc60e1 | ||
|
|
d8cae04a98 | ||
|
|
7b14711ecf | ||
|
|
c3351b9ee1 | ||
|
|
40b3c87b72 | ||
|
|
726db5ce5b | ||
|
|
99d359c548 | ||
|
|
4744113411 | ||
|
|
ae8f940f55 | ||
|
|
8d7633df2d | ||
|
|
4a351cfbe3 | ||
|
|
bb01447760 | ||
|
|
f12ed17b96 | ||
|
|
854e05f044 | ||
|
|
82c22682c0 | ||
|
|
25b3817876 | ||
|
|
e2a2b086ad | ||
|
|
5f9a0c5e17 | ||
|
|
2a0ae0af13 | ||
|
|
7a051146b6 | ||
|
|
d9398001cb | ||
|
|
0be99cb12a | ||
|
|
70e2d3d43f | ||
|
|
441258f9f2 | ||
|
|
b96efb533c | ||
|
|
5af067cc23 | ||
|
|
0c84665e38 | ||
|
|
9316d81fe3 | ||
|
|
ec96c044d5 | ||
|
|
ae4ed9273f | ||
|
|
0ec882e62e | ||
|
|
fef9ba23f4 | ||
|
|
3bd415b910 | ||
|
|
2128624261 | ||
|
|
c53fcace76 | ||
|
|
ff3759984c | ||
|
|
6358d1e2e1 | ||
|
|
db53631e76 | ||
|
|
86b2d929ab | ||
|
|
0db4462a64 | ||
|
|
f8667fc655 | ||
|
|
d91f94e879 | ||
|
|
ad6c8593f2 | ||
|
|
873ee47e8d |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
|
||||
6
.github/workflows/codeql.yml
vendored
6
.github/workflows/codeql.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
@@ -40,13 +40,13 @@ jobs:
|
||||
java-distribution: temurin
|
||||
maven-version: 3.9.9
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@f6091c0113d1dcf9b98e269ee48e8a7e51b7bdd4 # v3.28.5
|
||||
uses: github/codeql-action/init@5f8171a638ada777af81d42b55959a643bb29017 # v3.28.12
|
||||
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@f6091c0113d1dcf9b98e269ee48e8a7e51b7bdd4 # v3.28.5
|
||||
uses: github/codeql-action/analyze@5f8171a638ada777af81d42b55959a643bb29017 # v3.28.12
|
||||
with:
|
||||
category: /language:${{ matrix.language }}
|
||||
|
||||
6
.github/workflows/deploy-website.yml
vendored
6
.github/workflows/deploy-website.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: ruby/setup-ruby@28c4deda893d5a96a6b2d958c5b47fc18d65c9d3 # v1.213.0
|
||||
- uses: ruby/setup-ruby@1a615958ad9d422dd932dc1d5823942ee002799f # v1.227.0
|
||||
with:
|
||||
working-directory: ./website
|
||||
bundler-cache: true
|
||||
@@ -75,7 +75,7 @@ jobs:
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
|
||||
6
.github/workflows/openssf-scorecard.yml
vendored
6
.github/workflows/openssf-scorecard.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
@@ -42,12 +42,12 @@ jobs:
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run OpenSSF Scorecard analysis
|
||||
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
|
||||
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.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@f6091c0113d1dcf9b98e269ee48e8a7e51b7bdd4 # v3.28.5
|
||||
uses: github/codeql-action/upload-sarif@5f8171a638ada777af81d42b55959a643bb29017 # v3.28.12
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
4
.github/workflows/pitest-analyze-pr.yml
vendored
4
.github/workflows/pitest-analyze-pr.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
@@ -38,7 +38,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@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: pitest-reports
|
||||
path: ./target/pit-reports-ci
|
||||
|
||||
2
.github/workflows/pitest-update-pr.yml
vendored
2
.github/workflows/pitest-update-pr.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
|
||||
4
.github/workflows/run-integration-tests.yml
vendored
4
.github/workflows/run-integration-tests.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
integration-test: [ "checkstyle", "metrics", "prometheus-java-client" ]
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
run: xvfb-run "./integration-tests/${{ matrix.integration-test }}.sh" "${{ runner.temp }}/artifacts"
|
||||
- name: Upload artifacts on failure
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: "integration-test-${{ matrix.integration-test }}"
|
||||
path: "${{ runner.temp }}/artifacts"
|
||||
|
||||
2
.github/workflows/sonarcloud.yml
vendored
2
.github/workflows/sonarcloud.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
--batch-mode
|
||||
--errors
|
||||
--strict-checksums
|
||||
-Dstyle.color=always
|
||||
|
||||
BIN
.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
BIN
.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
Binary file not shown.
18
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
18
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip
|
||||
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.20.1-SNAPSHOT</version>
|
||||
<version>0.22.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>documentation-support</artifactId>
|
||||
|
||||
@@ -2,6 +2,7 @@ package tech.picnic.errorprone.documentation;
|
||||
|
||||
import static com.google.errorprone.matchers.Matchers.instanceMethod;
|
||||
import static com.google.errorprone.matchers.method.MethodMatchers.staticMethod;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.function.Predicate.not;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
@@ -167,7 +168,10 @@ public final class BugPatternTestExtractor implements Extractor<BugPatternTestCa
|
||||
* is safe, because this code is guarded by an earlier call to `#getClassUnderTest(..)`,
|
||||
* which ensures that `tree` is part of a longer method invocation chain.
|
||||
*/
|
||||
MethodInvocationTree inputTree = (MethodInvocationTree) ASTHelpers.getReceiver(tree);
|
||||
MethodInvocationTree inputTree =
|
||||
(MethodInvocationTree)
|
||||
requireNonNull(
|
||||
ASTHelpers.getReceiver(tree), "Instance method invocation must have receiver");
|
||||
|
||||
String path = ASTHelpers.constValue(inputTree.getArguments().get(0), String.class);
|
||||
Optional<String> inputCode = getSourceCode(inputTree);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.20.1-SNAPSHOT</version>
|
||||
<version>0.22.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>error-prone-contrib</artifactId>
|
||||
@@ -62,6 +62,16 @@
|
||||
<artifactId>auto-value-annotations</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- XXX: JSR-305 (meta-)annotation usage by some dependencies triggers
|
||||
NullAway to attempt to load said annotations. As such some modules
|
||||
require these annotations to be on the classpath. Periodically review
|
||||
whether we can drop this dependeny declaration. See
|
||||
https://github.com/uber/NullAway/issues/1171. -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_annotation</artifactId>
|
||||
@@ -303,9 +313,6 @@
|
||||
<version>${project.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
<compilerArgs combine.children="append">
|
||||
<arg>-Xplugin:DocumentationGenerator -XoutputDirectory=${project.build.directory}/docs</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
<executions>
|
||||
<!-- The Refaster input/output test classes used by
|
||||
|
||||
@@ -11,6 +11,7 @@ import static com.google.errorprone.matchers.Matchers.not;
|
||||
import static com.google.errorprone.matchers.Matchers.returnStatement;
|
||||
import static com.google.errorprone.matchers.Matchers.staticMethod;
|
||||
import static com.google.errorprone.matchers.Matchers.toType;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static tech.picnic.errorprone.utils.Documentation.BUG_PATTERNS_BASE_URL;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
@@ -79,7 +80,10 @@ public final class DirectReturn extends BugChecker implements BlockTreeMatcher {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
Symbol variableSymbol = ASTHelpers.getSymbol(((ReturnTree) finalStatement).getExpression());
|
||||
Symbol variableSymbol =
|
||||
requireNonNull(
|
||||
ASTHelpers.getSymbol(((ReturnTree) finalStatement).getExpression()),
|
||||
"Missing symbol for returned variable");
|
||||
StatementTree precedingStatement = statements.get(statements.size() - 2);
|
||||
|
||||
return tryMatchAssignment(variableSymbol, precedingStatement)
|
||||
|
||||
@@ -18,6 +18,7 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMultiset;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableTable;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
@@ -33,6 +34,8 @@ import com.sun.source.tree.MethodInvocationTree;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
import com.sun.tools.javac.code.Symbol.MethodSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.VarSymbol;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.code.Types;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -178,30 +181,45 @@ public final class ExplicitArgumentEnumeration extends BugChecker
|
||||
state.getTypes())
|
||||
.collect(toImmutableList());
|
||||
|
||||
/*
|
||||
* If all overloads have a single parameter, and at least one of them is a varargs method, then
|
||||
* we assume that unwrapping the iterable argument will cause a suitable overload to be invoked.
|
||||
* (Note that there may be multiple varargs overloads, either with different parameter types, or
|
||||
* due to method overriding; this check does not attempt to determine which exact method or
|
||||
* overload will be invoked as a result of the suggested simplification.)
|
||||
*
|
||||
* Note that this is a (highly!) imperfect heuristic, but it is sufficient to prevent e.g.
|
||||
* unwrapping of arguments to `org.jooq.impl.DSL#row`, which can cause the expression's return
|
||||
* type to change from `RowN` to (e.g.) `Row2`.
|
||||
*/
|
||||
// XXX: There are certainly cases where it _would_ be nice to unwrap the arguments to
|
||||
// `org.jooq.impl.DSL#row(Collection<?>)`. Look into this.
|
||||
// XXX: Ideally we do check that one of the overloads accepts the unwrapped arguments.
|
||||
// XXX: Ideally we validate that eligible overloads have compatible return types.
|
||||
boolean hasLikelySuitableVarargsOverload =
|
||||
overloads.stream().allMatch(m -> m.params().size() == 1)
|
||||
&& overloads.stream().anyMatch(MethodSymbol::isVarArgs);
|
||||
|
||||
return hasLikelySuitableVarargsOverload
|
||||
return hasLikelySuitableVarargsOverload(method, overloads, state)
|
||||
? Optional.of(SourceCode.unwrapMethodInvocation(argument, state))
|
||||
: Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether it is likely that, if the argument to the given method is unwrapped, a suitable
|
||||
* varargs overload will be invoked instead.
|
||||
*
|
||||
* <p>If all overloads have a single parameter, and at least one of them is a suitably-typed
|
||||
* varargs method, then we assume that unwrapping the iterable argument will cause a suitable
|
||||
* overload to be invoked. (Note that there may be multiple varargs overloads due to method
|
||||
* overriding; this check does not attempt to determine which exact method or overload will be
|
||||
* invoked as a result of the suggested simplification.)
|
||||
*
|
||||
* <p>Note that this is a (highly!) imperfect heuristic, but it is sufficient to prevent e.g.
|
||||
* unwrapping of arguments to `org.jooq.impl.DSL#row`, which can cause the expression's return
|
||||
* type to change from `RowN` to (e.g.) `Row2`.
|
||||
*/
|
||||
// XXX: There are certainly cases where it _would_ be nice to unwrap the arguments to
|
||||
// `org.jooq.impl.DSL#row(Collection<?>)`. Look into this.
|
||||
// XXX: Ideally we validate that eligible overloads have compatible return types.
|
||||
private static boolean hasLikelySuitableVarargsOverload(
|
||||
MethodSymbol method, ImmutableList<MethodSymbol> overloads, VisitorState state) {
|
||||
Types types = state.getTypes();
|
||||
// XXX: This logic is fragile, as it assumes that the method parameter's type is of the form
|
||||
// `X<T>`, where `T` is the type of the explicitly enumerated values passed to the expression to
|
||||
// be unwrapped. This should generally hold, given the types returned by the
|
||||
// `EXPLICIT_ITERABLE_CREATOR` expressions: `Iterable<T>`, `List<T>`, `Set<T>`, etc.
|
||||
Type parameterType =
|
||||
Iterables.getOnlyElement(
|
||||
Iterables.getOnlyElement(method.getParameters()).type.getTypeArguments());
|
||||
return overloads.stream().allMatch(m -> m.params().size() == 1)
|
||||
&& overloads.stream()
|
||||
.filter(MethodSymbol::isVarArgs)
|
||||
.map(m -> types.elemtype(Iterables.getOnlyElement(m.getParameters()).type))
|
||||
.anyMatch(varArgsType -> types.containsType(parameterType, varArgsType));
|
||||
}
|
||||
|
||||
private static Optional<SuggestedFix> trySuggestCallingCustomAlternative(
|
||||
MethodInvocationTree tree, MethodInvocationTree argument, VisitorState state) {
|
||||
return ALTERNATIVE_METHODS.rowMap().entrySet().stream()
|
||||
|
||||
@@ -17,6 +17,7 @@ import static com.google.errorprone.matchers.Matchers.isSameType;
|
||||
import static com.google.errorprone.matchers.Matchers.methodHasParameters;
|
||||
import static com.google.errorprone.matchers.Matchers.staticMethod;
|
||||
import static com.google.errorprone.matchers.Matchers.toType;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.function.Predicate.not;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static tech.picnic.errorprone.utils.Documentation.BUG_PATTERNS_BASE_URL;
|
||||
@@ -129,7 +130,10 @@ public final class JUnitValueSource extends BugChecker implements MethodTreeMatc
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
Type parameterType = ASTHelpers.getType(Iterables.getOnlyElement(tree.getParameters()));
|
||||
Type parameterType =
|
||||
requireNonNull(
|
||||
ASTHelpers.getType(Iterables.getOnlyElement(tree.getParameters())),
|
||||
"Missing type for method parameter");
|
||||
|
||||
return findMethodSourceAnnotation(tree, state)
|
||||
.flatMap(
|
||||
@@ -173,7 +177,9 @@ public final class JUnitValueSource extends BugChecker implements MethodTreeMatc
|
||||
|
||||
private static Optional<MethodTree> findMatchingSibling(
|
||||
MethodTree tree, Predicate<? super MethodTree> predicate, VisitorState state) {
|
||||
return state.findEnclosing(ClassTree.class).getMembers().stream()
|
||||
return requireNonNull(state.findEnclosing(ClassTree.class), "No class enclosing method")
|
||||
.getMembers()
|
||||
.stream()
|
||||
.filter(MethodTree.class::isInstance)
|
||||
.map(MethodTree.class::cast)
|
||||
.filter(not(tree::equals))
|
||||
|
||||
@@ -5,6 +5,7 @@ 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.instanceMethod;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static tech.picnic.errorprone.utils.Documentation.BUG_PATTERNS_BASE_URL;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
@@ -86,7 +87,9 @@ public final class NonEmptyMono extends BugChecker implements MethodInvocationTr
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
ExpressionTree receiver = ASTHelpers.getReceiver(tree);
|
||||
ExpressionTree receiver =
|
||||
requireNonNull(
|
||||
ASTHelpers.getReceiver(tree), "Instance method invocation must have receiver");
|
||||
if (!NON_EMPTY_MONO.matches(receiver, state)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
@@ -204,6 +204,11 @@ final class AssertJEnumerableRules {
|
||||
return enumAssert.hasSize(iterable.length);
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
EnumerableAssert<?, S> before(EnumerableAssert<?, S> enumAssert, CharSequence iterable) {
|
||||
return enumAssert.hasSize(iterable.length());
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
EnumerableAssert<?, S> after(EnumerableAssert<?, S> enumAssert, Iterable<E> iterable) {
|
||||
return enumAssert.hasSameSizeAs(iterable);
|
||||
|
||||
@@ -4,6 +4,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.google.errorprone.refaster.Refaster;
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.AlsoNegation;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
import com.google.errorprone.refaster.annotation.Repeated;
|
||||
import java.io.File;
|
||||
@@ -11,6 +12,7 @@ import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.LinkOption;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.attribute.FileAttribute;
|
||||
@@ -141,4 +143,35 @@ final class FileRules {
|
||||
return Files.createTempFile(directory.toPath(), prefix, suffix).toFile();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke {@link File#mkdirs()} before {@link Files#exists(Path, LinkOption...)} to avoid
|
||||
* concurrency issues.
|
||||
*/
|
||||
static final class PathToFileMkDirsFilesExists {
|
||||
@BeforeTemplate
|
||||
boolean before(Path path) {
|
||||
return Files.exists(path) || path.toFile().mkdirs();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@AlsoNegation
|
||||
boolean after(Path path) {
|
||||
return path.toFile().mkdirs() || Files.exists(path);
|
||||
}
|
||||
}
|
||||
|
||||
/** Invoke {@link File#mkdirs()} before {@link File#exists()} to avoid concurrency issues. */
|
||||
static final class FileMkDirsFileExists {
|
||||
@BeforeTemplate
|
||||
boolean before(File file) {
|
||||
return file.exists() || file.mkdirs();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@AlsoNegation
|
||||
boolean after(File file) {
|
||||
return file.mkdirs() || file.exists();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,9 +489,16 @@ final class ReactorRules {
|
||||
return Flux.range(value, 1);
|
||||
}
|
||||
|
||||
// XXX: Consider generalizing part of this template using an Error Prone check that covers any
|
||||
// sequence of explicitly enumerated values passed to an iteration order-preserving collection
|
||||
// factory method.
|
||||
@BeforeTemplate
|
||||
Flux<T> before(T value) {
|
||||
return Mono.just(value).repeat().take(1);
|
||||
return Refaster.anyOf(
|
||||
Mono.just(value).flux(),
|
||||
Mono.just(value).repeat().take(1),
|
||||
Flux.fromIterable(ImmutableList.of(value)),
|
||||
Flux.fromIterable(ImmutableSet.of(value)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -508,8 +515,14 @@ final class ReactorRules {
|
||||
mono.switchIfEmpty(Mono.empty()), mono.flux().next(), mono.flux().singleOrEmpty());
|
||||
}
|
||||
|
||||
// XXX: Consider filing a SonarCloud issue for the S2637 false positive.
|
||||
@BeforeTemplate
|
||||
Mono<@Nullable Void> before2(Mono<@Nullable Void> mono) {
|
||||
@SuppressWarnings({
|
||||
"java:S2637" /* False positive: result is never `null`. */,
|
||||
"java:S4968" /* Result may be `Mono<Void>`. */,
|
||||
"key-to-resolve-AnnotationUseStyle-and-TrailingComment-check-conflict"
|
||||
})
|
||||
Mono<? extends @Nullable Void> before2(Mono<@Nullable Void> mono) {
|
||||
return Refaster.anyOf(mono.ignoreElement(), mono.then());
|
||||
}
|
||||
|
||||
@@ -938,12 +951,18 @@ final class ReactorRules {
|
||||
/** Prefer direct invocation of {@link Mono#then()}} over more contrived alternatives. */
|
||||
static final class MonoThen<T> {
|
||||
@BeforeTemplate
|
||||
Mono<@Nullable Void> before(Mono<T> mono) {
|
||||
return Refaster.anyOf(mono.ignoreElement().then(), mono.flux().then());
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> before(Mono<T> mono) {
|
||||
return Refaster.anyOf(
|
||||
mono.ignoreElement().then(),
|
||||
mono.flux().then(),
|
||||
Mono.when(mono),
|
||||
Mono.whenDelayError(mono));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Mono<@Nullable Void> after(Mono<T> mono) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> after(Mono<T> mono) {
|
||||
return mono.then();
|
||||
}
|
||||
}
|
||||
@@ -951,17 +970,25 @@ final class ReactorRules {
|
||||
/** Avoid vacuous invocations of {@link Flux#ignoreElements()}. */
|
||||
static final class FluxThen<T> {
|
||||
@BeforeTemplate
|
||||
Mono<@Nullable Void> before(Flux<T> flux) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> before(Flux<T> flux) {
|
||||
return flux.ignoreElements().then();
|
||||
}
|
||||
|
||||
// XXX: Consider filing a SonarCloud issue for the S2637 false positive.
|
||||
@BeforeTemplate
|
||||
Mono<@Nullable Void> before2(Flux<@Nullable Void> flux) {
|
||||
@SuppressWarnings({
|
||||
"java:S2637" /* False positive: result is never `null`. */,
|
||||
"java:S4968" /* Result may be `Mono<Void>`. */,
|
||||
"key-to-resolve-AnnotationUseStyle-and-TrailingComment-check-conflict"
|
||||
})
|
||||
Mono<? extends @Nullable Void> before2(Flux<@Nullable Void> flux) {
|
||||
return flux.ignoreElements();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Mono<@Nullable Void> after(Flux<T> flux) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> after(Flux<T> flux) {
|
||||
return flux.then();
|
||||
}
|
||||
}
|
||||
@@ -969,12 +996,14 @@ final class ReactorRules {
|
||||
/** Avoid vacuous invocations of {@link Mono#ignoreElement()}. */
|
||||
static final class MonoThenEmpty<T> {
|
||||
@BeforeTemplate
|
||||
Mono<@Nullable Void> before(Mono<T> mono, Publisher<@Nullable Void> publisher) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> before(Mono<T> mono, Publisher<@Nullable Void> publisher) {
|
||||
return mono.ignoreElement().thenEmpty(publisher);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Mono<@Nullable Void> after(Mono<T> mono, Publisher<@Nullable Void> publisher) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> after(Mono<T> mono, Publisher<@Nullable Void> publisher) {
|
||||
return mono.thenEmpty(publisher);
|
||||
}
|
||||
}
|
||||
@@ -982,12 +1011,14 @@ final class ReactorRules {
|
||||
/** Avoid vacuous invocations of {@link Flux#ignoreElements()}. */
|
||||
static final class FluxThenEmpty<T> {
|
||||
@BeforeTemplate
|
||||
Mono<@Nullable Void> before(Flux<T> flux, Publisher<@Nullable Void> publisher) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> before(Flux<T> flux, Publisher<@Nullable Void> publisher) {
|
||||
return flux.ignoreElements().thenEmpty(publisher);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Mono<@Nullable Void> after(Flux<T> flux, Publisher<@Nullable Void> publisher) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> after(Flux<T> flux, Publisher<@Nullable Void> publisher) {
|
||||
return flux.thenEmpty(publisher);
|
||||
}
|
||||
}
|
||||
@@ -1043,7 +1074,8 @@ final class ReactorRules {
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
Mono<@Nullable Void> before2(Mono<T> mono1, Mono<@Nullable Void> mono2) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> before2(Mono<T> mono1, Mono<@Nullable Void> mono2) {
|
||||
return mono1.thenEmpty(mono2);
|
||||
}
|
||||
|
||||
@@ -1061,7 +1093,8 @@ final class ReactorRules {
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
Mono<@Nullable Void> before2(Flux<T> flux, Mono<@Nullable Void> mono) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> before2(Flux<T> flux, Mono<@Nullable Void> mono) {
|
||||
return flux.thenEmpty(mono);
|
||||
}
|
||||
|
||||
@@ -1078,10 +1111,12 @@ final class ReactorRules {
|
||||
// rule. Consider introducing an Error Prone check for this.
|
||||
static final class MonoSingleOptional<T> {
|
||||
@BeforeTemplate
|
||||
Mono<Optional<T>> before(Mono<T> mono) {
|
||||
Mono<Optional<T>> before(Mono<T> mono, Optional<T> optional, Mono<Optional<T>> alternate) {
|
||||
return Refaster.anyOf(
|
||||
mono.flux().collect(toOptional()),
|
||||
mono.map(Optional::of).defaultIfEmpty(Optional.empty()),
|
||||
mono.map(Optional::of),
|
||||
mono.singleOptional().defaultIfEmpty(optional),
|
||||
mono.singleOptional().switchIfEmpty(alternate),
|
||||
mono.transform(Mono::singleOptional));
|
||||
}
|
||||
|
||||
|
||||
@@ -23,14 +23,16 @@ final class RxJava2AdapterRules {
|
||||
/** Use the fluent API style when using {@link RxJava2Adapter#completableToMono}. */
|
||||
static final class CompletableToMono {
|
||||
@BeforeTemplate
|
||||
Mono<@Nullable Void> before(Completable completable) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> before(Completable completable) {
|
||||
return Refaster.anyOf(
|
||||
RxJava2Adapter.completableToMono(completable),
|
||||
completable.to(RxJava2Adapter::completableToMono));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Mono<@Nullable Void> after(Completable completable) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> after(Completable completable) {
|
||||
return completable.as(RxJava2Adapter::completableToMono);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.fixes.SuggestedFix;
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
@@ -65,16 +66,18 @@ final class SuggestedFixRules {
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link SuggestedFix#swap(Tree, Tree)} over more contrived alternatives. */
|
||||
/**
|
||||
* Prefer {@link SuggestedFix#swap(Tree, Tree, VisitorState)} over more contrived alternatives.
|
||||
*/
|
||||
static final class SuggestedFixSwap {
|
||||
@BeforeTemplate
|
||||
SuggestedFix before(Tree tree1, Tree tree2) {
|
||||
return SuggestedFix.builder().swap(tree1, tree2).build();
|
||||
SuggestedFix before(Tree tree1, Tree tree2, VisitorState state) {
|
||||
return SuggestedFix.builder().swap(tree1, tree2, state).build();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
SuggestedFix after(Tree tree1, Tree tree2) {
|
||||
return SuggestedFix.swap(tree1, tree2);
|
||||
SuggestedFix after(Tree tree1, Tree tree2, VisitorState state) {
|
||||
return SuggestedFix.swap(tree1, tree2, state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ final class ExplicitArgumentEnumerationTest {
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"import io.micrometer.core.instrument.Counter;",
|
||||
"import io.micrometer.core.instrument.Tag;",
|
||||
"import org.jooq.impl.DSL;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"import reactor.test.StepVerifier;",
|
||||
@@ -32,6 +34,8 @@ final class ExplicitArgumentEnumerationTest {
|
||||
"",
|
||||
" DSL.row(ImmutableList.of(1, 2));",
|
||||
"",
|
||||
" Counter.builder(\"foo\").tags(ImmutableList.of(Tag.of(\"bar\", \"baz\")));",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" unaryMethod(ImmutableList.of(1, 2));",
|
||||
" unaryMethodWithLessVisibleOverload(ImmutableList.of(1, 2));",
|
||||
|
||||
@@ -67,10 +67,11 @@ final class AssertJEnumerableRulesTest implements RefasterRuleCollectionTestCase
|
||||
assertThat(ImmutableSet.of(4)).size().isBetween(5, 6));
|
||||
}
|
||||
|
||||
ImmutableSet<EnumerableAssert<?, Integer>> testEnumerableAssertHasSameSizeAs() {
|
||||
ImmutableSet<EnumerableAssert<?, Character>> testEnumerableAssertHasSameSizeAs() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(ImmutableSet.of(1)).hasSize(Iterables.size(ImmutableSet.of(2))),
|
||||
assertThat(ImmutableSet.of(3)).hasSize(ImmutableSet.of(4).size()),
|
||||
assertThat(ImmutableSet.of(5)).hasSize(new Integer[0].length));
|
||||
assertThat("foo").hasSize(Iterables.size(ImmutableSet.of(1))),
|
||||
assertThat("bar").hasSize(ImmutableSet.of(2).size()),
|
||||
assertThat("baz").hasSize(new Integer[0].length),
|
||||
assertThat("qux").hasSize("quux".length()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,10 +66,11 @@ final class AssertJEnumerableRulesTest implements RefasterRuleCollectionTestCase
|
||||
assertThat(ImmutableSet.of(4)).hasSizeBetween(5, 6));
|
||||
}
|
||||
|
||||
ImmutableSet<EnumerableAssert<?, Integer>> testEnumerableAssertHasSameSizeAs() {
|
||||
ImmutableSet<EnumerableAssert<?, Character>> testEnumerableAssertHasSameSizeAs() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(ImmutableSet.of(1)).hasSameSizeAs(ImmutableSet.of(2)),
|
||||
assertThat(ImmutableSet.of(3)).hasSameSizeAs(ImmutableSet.of(4)),
|
||||
assertThat(ImmutableSet.of(5)).hasSameSizeAs(new Integer[0]));
|
||||
assertThat("foo").hasSameSizeAs(ImmutableSet.of(1)),
|
||||
assertThat("bar").hasSameSizeAs(ImmutableSet.of(2)),
|
||||
assertThat("baz").hasSameSizeAs(new Integer[0]),
|
||||
assertThat("qux").hasSameSizeAs("quux"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,4 +39,16 @@ final class FileRulesTest implements RefasterRuleCollectionTestCase {
|
||||
File testFilesCreateTempFileInCustomDirectoryToFile() throws IOException {
|
||||
return File.createTempFile("foo", "bar", new File("baz"));
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testPathToFileMkDirsFilesExists() {
|
||||
return ImmutableSet.of(
|
||||
Files.exists(Path.of("foo")) || Path.of("foo").toFile().mkdirs(),
|
||||
!Files.exists(Path.of("bar")) && !Path.of("bar").toFile().mkdirs());
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testFileMkDirsFileExists() {
|
||||
return ImmutableSet.of(
|
||||
new File("foo").exists() || new File("foo").mkdirs(),
|
||||
!new File("bar").exists() && !new File("bar").mkdirs());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,4 +39,16 @@ final class FileRulesTest implements RefasterRuleCollectionTestCase {
|
||||
File testFilesCreateTempFileInCustomDirectoryToFile() throws IOException {
|
||||
return Files.createTempFile(new File("baz").toPath(), "foo", "bar").toFile();
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testPathToFileMkDirsFilesExists() {
|
||||
return ImmutableSet.of(
|
||||
Path.of("foo").toFile().mkdirs() || Files.exists(Path.of("foo")),
|
||||
!Path.of("bar").toFile().mkdirs() && !Files.exists(Path.of("bar")));
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testFileMkDirsFileExists() {
|
||||
return ImmutableSet.of(
|
||||
new File("foo").mkdirs() || new File("foo").exists(),
|
||||
!new File("bar").mkdirs() && !new File("bar").exists());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +188,12 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
}
|
||||
|
||||
ImmutableSet<Flux<Integer>> testFluxJust() {
|
||||
return ImmutableSet.of(Flux.range(0, 1), Mono.just(2).repeat().take(1));
|
||||
return ImmutableSet.of(
|
||||
Flux.range(0, 1),
|
||||
Mono.just(2).flux(),
|
||||
Mono.just(3).repeat().take(1),
|
||||
Flux.fromIterable(ImmutableList.of(4)),
|
||||
Flux.fromIterable(ImmutableSet.of(5)));
|
||||
}
|
||||
|
||||
ImmutableSet<Mono<?>> testMonoIdentity() {
|
||||
@@ -342,7 +347,11 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
}
|
||||
|
||||
ImmutableSet<Mono<Void>> testMonoThen() {
|
||||
return ImmutableSet.of(Mono.just("foo").ignoreElement().then(), Mono.just("bar").flux().then());
|
||||
return ImmutableSet.of(
|
||||
Mono.just("foo").ignoreElement().then(),
|
||||
Mono.just("bar").flux().then(),
|
||||
Mono.when(Mono.just("baz")),
|
||||
Mono.whenDelayError(Mono.just("qux")));
|
||||
}
|
||||
|
||||
ImmutableSet<Mono<Void>> testFluxThen() {
|
||||
@@ -388,8 +397,10 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
ImmutableSet<Mono<Optional<String>>> testMonoSingleOptional() {
|
||||
return ImmutableSet.of(
|
||||
Mono.just("foo").flux().collect(toOptional()),
|
||||
Mono.just("bar").map(Optional::of).defaultIfEmpty(Optional.empty()),
|
||||
Mono.just("baz").transform(Mono::singleOptional));
|
||||
Mono.just("bar").map(Optional::of),
|
||||
Mono.just("baz").singleOptional().defaultIfEmpty(Optional.empty()),
|
||||
Mono.just("quux").singleOptional().switchIfEmpty(Mono.just(Optional.empty())),
|
||||
Mono.just("quuz").transform(Mono::singleOptional));
|
||||
}
|
||||
|
||||
Mono<Number> testMonoCast() {
|
||||
|
||||
@@ -192,7 +192,7 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
}
|
||||
|
||||
ImmutableSet<Flux<Integer>> testFluxJust() {
|
||||
return ImmutableSet.of(Flux.just(0), Flux.just(2));
|
||||
return ImmutableSet.of(Flux.just(0), Flux.just(2), Flux.just(3), Flux.just(4), Flux.just(5));
|
||||
}
|
||||
|
||||
ImmutableSet<Mono<?>> testMonoIdentity() {
|
||||
@@ -340,7 +340,11 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
}
|
||||
|
||||
ImmutableSet<Mono<Void>> testMonoThen() {
|
||||
return ImmutableSet.of(Mono.just("foo").then(), Mono.just("bar").then());
|
||||
return ImmutableSet.of(
|
||||
Mono.just("foo").then(),
|
||||
Mono.just("bar").then(),
|
||||
Mono.just("baz").then(),
|
||||
Mono.just("qux").then());
|
||||
}
|
||||
|
||||
ImmutableSet<Mono<Void>> testFluxThen() {
|
||||
@@ -384,7 +388,9 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
return ImmutableSet.of(
|
||||
Mono.just("foo").singleOptional(),
|
||||
Mono.just("bar").singleOptional(),
|
||||
Mono.just("baz").singleOptional());
|
||||
Mono.just("baz").singleOptional(),
|
||||
Mono.just("quux").singleOptional(),
|
||||
Mono.just("quuz").singleOptional());
|
||||
}
|
||||
|
||||
Mono<Number> testMonoCast() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.fixes.SuggestedFix;
|
||||
import com.sun.source.tree.ExpressionTree;
|
||||
import com.sun.source.tree.Tree;
|
||||
@@ -23,7 +24,9 @@ final class SuggestedFixRulesTest implements RefasterRuleCollectionTestCase {
|
||||
}
|
||||
|
||||
SuggestedFix testSuggestedFixSwap() {
|
||||
return SuggestedFix.builder().swap((Tree) null, (ExpressionTree) null).build();
|
||||
return SuggestedFix.builder()
|
||||
.swap((Tree) null, (ExpressionTree) null, (VisitorState) null)
|
||||
.build();
|
||||
}
|
||||
|
||||
SuggestedFix testSuggestedFixPrefixWith() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.fixes.SuggestedFix;
|
||||
import com.sun.source.tree.ExpressionTree;
|
||||
import com.sun.source.tree.Tree;
|
||||
@@ -23,7 +24,7 @@ final class SuggestedFixRulesTest implements RefasterRuleCollectionTestCase {
|
||||
}
|
||||
|
||||
SuggestedFix testSuggestedFixSwap() {
|
||||
return SuggestedFix.swap((Tree) null, (ExpressionTree) null);
|
||||
return SuggestedFix.swap((Tree) null, (ExpressionTree) null, (VisitorState) null);
|
||||
}
|
||||
|
||||
SuggestedFix testSuggestedFixPrefixWith() {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.20.1-SNAPSHOT</version>
|
||||
<version>0.22.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>error-prone-experimental</artifactId>
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.sun.source.tree.ReturnTree;
|
||||
import com.sun.source.tree.Tree;
|
||||
import com.sun.source.tree.VariableTree;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.code.Symbol.PackageSymbol;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -126,7 +127,7 @@ public final class MethodReferenceUsage extends BugChecker implements LambdaExpr
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
Symbol sym = ASTHelpers.getSymbol(methodSelect);
|
||||
Symbol sym = ASTHelpers.getSymbol(subTree);
|
||||
return ASTHelpers.isStatic(sym)
|
||||
? constructFix(lambdaExpr, sym.owner, methodSelect)
|
||||
: constructFix(lambdaExpr, "this", methodSelect);
|
||||
@@ -200,7 +201,8 @@ public final class MethodReferenceUsage extends BugChecker implements LambdaExpr
|
||||
Name sName = target.getSimpleName();
|
||||
Optional<SuggestedFix.Builder> fix = constructFix(lambdaExpr, sName, methodName);
|
||||
|
||||
if (!"java.lang".equals(ASTHelpers.enclosingPackage(target).toString())) {
|
||||
PackageSymbol pkg = ASTHelpers.enclosingPackage(target);
|
||||
if (pkg != null && !"java.lang".equals(pkg.toString())) {
|
||||
Name fqName = target.getQualifiedName();
|
||||
if (!sName.equals(fqName)) {
|
||||
return fix.map(b -> b.addImport(fqName.toString()));
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.20.1-SNAPSHOT</version>
|
||||
<version>0.22.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>error-prone-guidelines</artifactId>
|
||||
@@ -118,9 +118,6 @@
|
||||
<version>${project.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
<compilerArgs combine.children="append">
|
||||
<arg>-Xplugin:DocumentationGenerator -XoutputDirectory=${project.build.directory}/docs</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
@@ -46,7 +46,6 @@ import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.AnnotationValue;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import tech.picnic.errorprone.utils.SourceCode;
|
||||
|
||||
@@ -102,7 +101,8 @@ public final class ExhaustiveRefasterTypeMigration extends BugChecker implements
|
||||
AnnotationTree migrationAnnotation = migrationAnnotations.onlyMatchingNode();
|
||||
AnnotationMirror annotationMirror = ASTHelpers.getAnnotationMirror(migrationAnnotation);
|
||||
TypeSymbol migratedType = getMigratedType(annotationMirror);
|
||||
if (migratedType.asType().isPrimitive() || !(migratedType instanceof ClassSymbol)) {
|
||||
if (migratedType.asType().isPrimitive()
|
||||
|| !(migratedType instanceof ClassSymbol migratedClass)) {
|
||||
return buildDescription(migrationAnnotation)
|
||||
.setMessage(String.format("Migration of type '%s' is unsupported", migratedType))
|
||||
.build();
|
||||
@@ -111,7 +111,7 @@ public final class ExhaustiveRefasterTypeMigration extends BugChecker implements
|
||||
ImmutableList<String> methodsClaimedUnmigrated = getMethodsClaimedUnmigrated(annotationMirror);
|
||||
ImmutableList<String> unmigratedMethods =
|
||||
getMethodsDefinitelyUnmigrated(
|
||||
tree, (ClassSymbol) migratedType, signatureOrder(methodsClaimedUnmigrated), state);
|
||||
tree, migratedClass, signatureOrder(methodsClaimedUnmigrated), state);
|
||||
|
||||
if (unmigratedMethods.equals(methodsClaimedUnmigrated)) {
|
||||
return Description.NO_MATCH;
|
||||
@@ -160,17 +160,11 @@ public final class ExhaustiveRefasterTypeMigration extends BugChecker implements
|
||||
.getValue().stream().map(a -> a.getValue().toString()).collect(toImmutableList());
|
||||
}
|
||||
|
||||
// XXX: Once only JDK 14 and above are supported, change the
|
||||
// `m.getModifiers().contains(Modifier.PUBLIC)` check to just `m.isPublic()`.
|
||||
private static ImmutableList<String> getMethodsDefinitelyUnmigrated(
|
||||
ClassTree tree, ClassSymbol migratedType, Comparator<String> comparator, VisitorState state) {
|
||||
Set<MethodSymbol> publicMethods =
|
||||
Streams.stream(
|
||||
ASTHelpers.scope(migratedType.members())
|
||||
.getSymbols(
|
||||
m ->
|
||||
m.getModifiers().contains(Modifier.PUBLIC)
|
||||
&& m instanceof MethodSymbol))
|
||||
migratedType.members().getSymbols(m -> m.isPublic() && m instanceof MethodSymbol))
|
||||
.map(MethodSymbol.class::cast)
|
||||
.collect(toCollection(HashSet::new));
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.20.1-SNAPSHOT</version>
|
||||
<version>0.22.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>error-prone-utils</artifactId>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package tech.picnic.errorprone.utils;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
@@ -115,9 +117,15 @@ public final class AnnotationAttributeMatcher implements Serializable {
|
||||
}
|
||||
|
||||
private static String extractAttributeName(ExpressionTree expr) {
|
||||
return (expr instanceof AssignmentTree assignment)
|
||||
? ASTHelpers.getSymbol(assignment.getVariable()).getSimpleName().toString()
|
||||
: "value";
|
||||
if (!(expr instanceof AssignmentTree assignment)) {
|
||||
return "value";
|
||||
}
|
||||
|
||||
return requireNonNull(
|
||||
ASTHelpers.getSymbol(assignment.getVariable()),
|
||||
"Missing symbol for annotation attribute")
|
||||
.getSimpleName()
|
||||
.toString();
|
||||
}
|
||||
|
||||
// XXX: The caller of this method can be implemented more efficiently in case of a "wholeTypes"
|
||||
|
||||
@@ -303,14 +303,7 @@ final class SourceCodeTest {
|
||||
|
||||
@Override
|
||||
public Description matchLiteral(LiteralTree tree, VisitorState state) {
|
||||
// XXX: The character conversion is a workaround for the fact that `ASTHelpers#constValue`
|
||||
// returns an `Integer` value for `char` constants.
|
||||
return Optional.ofNullable(ASTHelpers.constValue(tree))
|
||||
.map(
|
||||
constant ->
|
||||
ASTHelpers.isSubtype(ASTHelpers.getType(tree), state.getSymtab().charType, state)
|
||||
? (char) (int) constant
|
||||
: constant)
|
||||
.map(constant -> describeMatch(tree, addComment(tree, constant, state)))
|
||||
.orElse(Description.NO_MATCH);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ additional_source_directories='${project.basedir}${file.separator}src${file.sepa
|
||||
shared_error_prone_flags='-XepExcludedPaths:(\Q${project.basedir}${file.separator}src${file.separator}\E(it|test|xdocs-examples)\Q${file.separator}resources\E|\Q${project.build.directory}${file.separator}\E).*'
|
||||
patch_error_prone_flags=''
|
||||
validation_error_prone_flags=''
|
||||
patch_error_prone_flags='-XepOpt:Refaster:NamePattern=.*Workshop.*"'
|
||||
validation_error_prone_flags='-XepOpt:Refaster:NamePattern=.*Workshop.*"'
|
||||
# Validation skips some tests:
|
||||
# - The `metadataFilesGenerationAllFiles` test is skipped because it makes line
|
||||
# number assertions that will fail when the code is formatted or patched.
|
||||
|
||||
@@ -89,15 +89,63 @@
|
||||
}
|
||||
return new CollectdReporter(
|
||||
registry,
|
||||
@@ -302,7 +297,7 @@ public class CollectdReporter extends ScheduledReporter {
|
||||
@@ -177,7 +172,7 @@ public class CollectdReporter extends ScheduledReporter {
|
||||
}
|
||||
}
|
||||
|
||||
- private static final Logger LOG = LoggerFactory.getLogger(CollectdReporter.class);
|
||||
+ private static final Logger LOGGER = LoggerFactory.getLogger(CollectdReporter.class);
|
||||
private static final String REPORTER_NAME = "collectd-reporter";
|
||||
private static final String FALLBACK_HOST_NAME = "localhost";
|
||||
private static final String COLLECTD_TYPE_GAUGE = "gauge";
|
||||
@@ -224,7 +219,7 @@ public class CollectdReporter extends ScheduledReporter {
|
||||
try {
|
||||
return InetAddress.getLocalHost().getHostName();
|
||||
} catch (Exception e) {
|
||||
- LOG.error("Failed to lookup local host name: {}", e.getMessage(), e);
|
||||
+ LOGGER.error("Failed to lookup local host name: {}", e.getMessage(), e);
|
||||
return FALLBACK_HOST_NAME;
|
||||
}
|
||||
}
|
||||
@@ -263,7 +258,7 @@ public class CollectdReporter extends ScheduledReporter {
|
||||
serializeTimer(metaData.plugin(entry.getKey().getKey()), entry.getValue());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
- LOG.warn("Unable to report to Collectd", e);
|
||||
+ LOGGER.warn("Unable to report to Collectd", e);
|
||||
} finally {
|
||||
disconnect(sender);
|
||||
}
|
||||
@@ -279,7 +274,7 @@ public class CollectdReporter extends ScheduledReporter {
|
||||
try {
|
||||
sender.disconnect();
|
||||
} catch (Exception e) {
|
||||
- LOG.warn("Error disconnecting from Collectd", e);
|
||||
+ LOGGER.warn("Error disconnecting from Collectd", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,9 +297,9 @@ public class CollectdReporter extends ScheduledReporter {
|
||||
try {
|
||||
writer.write(metaData, value);
|
||||
} catch (RuntimeException e) {
|
||||
- LOG.warn("Failed to process metric '" + metaData.getPlugin() + "': " + e.getMessage());
|
||||
+ LOG.warn("Failed to process metric '{}': {}", metaData.getPlugin(), e.getMessage());
|
||||
+ LOGGER.warn("Failed to process metric '{}': {}", metaData.getPlugin(), e.getMessage());
|
||||
} catch (IOException e) {
|
||||
LOG.error("Failed to send metric to collectd", e);
|
||||
- LOG.error("Failed to send metric to collectd", e);
|
||||
+ LOGGER.error("Failed to send metric to collectd", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,7 +309,7 @@ public class CollectdReporter extends ScheduledReporter {
|
||||
} else if (metric.getValue() instanceof Boolean) {
|
||||
write(metaData.typeInstance("value").get(), ((Boolean) metric.getValue()) ? 1 : 0);
|
||||
} else {
|
||||
- LOG.warn(
|
||||
+ LOGGER.warn(
|
||||
"Failed to process metric '{}'. Unsupported gauge of type: {} ",
|
||||
metaData.get().getPlugin(),
|
||||
metric.getValue().getClass().getName());
|
||||
@@ -336,9 +331,9 @@ public class CollectdReporter extends ScheduledReporter {
|
||||
private void serializeHistogram(MetaData.Builder metaData, Histogram metric) {
|
||||
final Snapshot snapshot = metric.getSnapshot();
|
||||
@@ -476,26 +524,6 @@
|
||||
}
|
||||
|
||||
/**
|
||||
--- a/metrics-core/src/main/java/io/dropwizard/metrics5/CsvReporter.java
|
||||
+++ b/metrics-core/src/main/java/io/dropwizard/metrics5/CsvReporter.java
|
||||
@@ -179,7 +179,7 @@ public class CsvReporter extends ScheduledReporter {
|
||||
}
|
||||
}
|
||||
|
||||
- private static final Logger LOGGER = LoggerFactory.getLogger(CsvReporter.class);
|
||||
+ private static final Logger LOG = LoggerFactory.getLogger(CsvReporter.class);
|
||||
|
||||
private final File directory;
|
||||
private final Locale locale;
|
||||
@@ -391,7 +391,7 @@ public class CsvReporter extends ScheduledReporter {
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
- LOGGER.warn("Error writing to {}", name, e);
|
||||
+ LOG.warn("Error writing to {}", name, e);
|
||||
}
|
||||
}
|
||||
|
||||
--- a/metrics-core/src/main/java/io/dropwizard/metrics5/ExponentialMovingAverages.java
|
||||
+++ b/metrics-core/src/main/java/io/dropwizard/metrics5/ExponentialMovingAverages.java
|
||||
@@ -17,9 +17,9 @@ public class ExponentialMovingAverages implements MovingAverages {
|
||||
@@ -990,6 +1018,15 @@
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
@@ -24,7 +27,7 @@ import org.slf4j.LoggerFactory;
|
||||
*/
|
||||
public abstract class ScheduledReporter implements Closeable, Reporter {
|
||||
|
||||
- private static final Logger LOG = LoggerFactory.getLogger(ScheduledReporter.class);
|
||||
+ private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledReporter.class);
|
||||
|
||||
/** A simple named thread factory. */
|
||||
@SuppressWarnings("NullableProblems")
|
||||
@@ -128,7 +131,7 @@ public abstract class ScheduledReporter implements Closeable, Reporter {
|
||||
durationUnit,
|
||||
executor,
|
||||
@@ -1040,6 +1077,33 @@
|
||||
protected ScheduledFuture<?> getScheduledFuture(
|
||||
long initialDelay, long period, TimeUnit unit, Runnable runnable) {
|
||||
return getScheduledFuture(initialDelay, period, unit, runnable, this.executor);
|
||||
@@ -225,7 +224,7 @@ public abstract class ScheduledReporter implements Closeable, Reporter {
|
||||
try {
|
||||
report();
|
||||
} catch (Throwable ex) {
|
||||
- LOG.error(
|
||||
+ LOGGER.error(
|
||||
"Exception thrown from {}#report. Exception was suppressed.",
|
||||
ScheduledReporter.this.getClass().getSimpleName(),
|
||||
ex);
|
||||
@@ -250,7 +249,7 @@ public abstract class ScheduledReporter implements Closeable, Reporter {
|
||||
try {
|
||||
report();
|
||||
} catch (Exception e) {
|
||||
- LOG.warn("Final reporting of metrics failed.", e);
|
||||
+ LOGGER.warn("Final reporting of metrics failed.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,7 +260,7 @@ public abstract class ScheduledReporter implements Closeable, Reporter {
|
||||
executor.shutdownNow(); // Cancel currently executing tasks
|
||||
// Wait a while for tasks to respond to being cancelled
|
||||
if (!executor.awaitTermination(1, TimeUnit.SECONDS)) {
|
||||
- LOG.warn("ScheduledExecutorService did not terminate.");
|
||||
+ LOGGER.warn("ScheduledExecutorService did not terminate.");
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException ie) {
|
||||
--- a/metrics-core/src/main/java/io/dropwizard/metrics5/SharedMetricRegistries.java
|
||||
+++ b/metrics-core/src/main/java/io/dropwizard/metrics5/SharedMetricRegistries.java
|
||||
@@ -1,5 +1,7 @@
|
||||
@@ -1200,32 +1264,15 @@
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -15,8 +14,8 @@ import org.junit.jupiter.api.Test;
|
||||
@@ -15,7 +14,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
-class CachedGaugeTest {
|
||||
- private static final Logger LOGGER = LoggerFactory.getLogger(CachedGaugeTest.class);
|
||||
+final class CachedGaugeTest {
|
||||
+ private static final Logger LOG = LoggerFactory.getLogger(CachedGaugeTest.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(CachedGaugeTest.class);
|
||||
private static final int THREAD_COUNT = 10;
|
||||
private static final long RUNNING_TIME_MILLIS = TimeUnit.SECONDS.toMillis(10);
|
||||
|
||||
@@ -100,12 +99,12 @@ class CachedGaugeTest {
|
||||
Integer newValue = shortTimeoutGauge.getValue();
|
||||
|
||||
if (newValue == null) {
|
||||
- LOGGER.warn("Cached gauge returned null value");
|
||||
+ LOG.warn("Cached gauge returned null value");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (newValue < lastValue) {
|
||||
- LOGGER.error(
|
||||
+ LOG.error(
|
||||
"Cached gauge returned stale value, last: {}, new: {}",
|
||||
lastValue,
|
||||
newValue);
|
||||
@@ -122,7 +121,7 @@ class CachedGaugeTest {
|
||||
}
|
||||
|
||||
@@ -1899,29 +1946,16 @@
|
||||
assertThat(histogram.getSnapshot()).isEqualTo(snapshot);
|
||||
--- a/metrics-core/src/test/java/io/dropwizard/metrics5/InstrumentedExecutorServiceTest.java
|
||||
+++ b/metrics-core/src/test/java/io/dropwizard/metrics5/InstrumentedExecutorServiceTest.java
|
||||
@@ -19,10 +19,9 @@ import org.junit.jupiter.api.Test;
|
||||
@@ -19,7 +19,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
-class InstrumentedExecutorServiceTest {
|
||||
+final class InstrumentedExecutorServiceTest {
|
||||
|
||||
- private static final Logger LOGGER =
|
||||
- LoggerFactory.getLogger(InstrumentedExecutorServiceTest.class);
|
||||
+ private static final Logger LOG = LoggerFactory.getLogger(InstrumentedExecutorServiceTest.class);
|
||||
private ExecutorService executor;
|
||||
private MetricRegistry registry;
|
||||
private InstrumentedExecutorService instrumentedExecutorService;
|
||||
@@ -48,7 +47,7 @@ class InstrumentedExecutorServiceTest {
|
||||
void tearDown() throws Exception {
|
||||
instrumentedExecutorService.shutdown();
|
||||
if (!instrumentedExecutorService.awaitTermination(2, TimeUnit.SECONDS)) {
|
||||
- LOGGER.error("InstrumentedExecutorService did not terminate.");
|
||||
+ LOG.error("InstrumentedExecutorService did not terminate.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,8 +114,8 @@ class InstrumentedExecutorServiceTest {
|
||||
private static final Logger LOGGER =
|
||||
LoggerFactory.getLogger(InstrumentedExecutorServiceTest.class);
|
||||
@@ -115,8 +115,8 @@ class InstrumentedExecutorServiceTest {
|
||||
assertThat(idle.getSnapshot().size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@@ -1931,7 +1965,7 @@
|
||||
void reportsTasksInformationForThreadPoolExecutor() throws Exception {
|
||||
executor =
|
||||
new ThreadPoolExecutor(4, 16, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(32));
|
||||
@@ -180,7 +179,7 @@ class InstrumentedExecutorServiceTest {
|
||||
@@ -180,7 +180,7 @@ class InstrumentedExecutorServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1940,7 +1974,7 @@
|
||||
executor =
|
||||
new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1));
|
||||
instrumentedExecutorService = new InstrumentedExecutorService(executor, registry, "tp");
|
||||
@@ -207,7 +206,7 @@ class InstrumentedExecutorServiceTest {
|
||||
@@ -207,7 +207,7 @@ class InstrumentedExecutorServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1949,7 +1983,7 @@
|
||||
executor =
|
||||
new ThreadPoolExecutor(4, 16, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(32));
|
||||
instrumentedExecutorService = new InstrumentedExecutorService(executor, registry, "stp");
|
||||
@@ -236,8 +235,8 @@ class InstrumentedExecutorServiceTest {
|
||||
@@ -236,8 +236,8 @@ class InstrumentedExecutorServiceTest {
|
||||
MetricRegistry.name("stp", "tasks.capacity"));
|
||||
}
|
||||
|
||||
@@ -1959,7 +1993,7 @@
|
||||
void reportsTasksInformationForForkJoinPool() throws Exception {
|
||||
executor = Executors.newWorkStealingPool(4);
|
||||
instrumentedExecutorService = new InstrumentedExecutorService(executor, registry, "fjp");
|
||||
@@ -291,7 +290,7 @@ class InstrumentedExecutorServiceTest {
|
||||
@@ -291,7 +291,7 @@ class InstrumentedExecutorServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1970,17 +2004,15 @@
|
||||
|
||||
--- a/metrics-core/src/test/java/io/dropwizard/metrics5/InstrumentedScheduledExecutorServiceTest.java
|
||||
+++ b/metrics-core/src/test/java/io/dropwizard/metrics5/InstrumentedScheduledExecutorServiceTest.java
|
||||
@@ -13,8 +13,8 @@ import org.junit.jupiter.api.Test;
|
||||
@@ -13,7 +13,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
-class InstrumentedScheduledExecutorServiceTest {
|
||||
- private static final Logger LOGGER =
|
||||
+final class InstrumentedScheduledExecutorServiceTest {
|
||||
+ private static final Logger LOG =
|
||||
private static final Logger LOGGER =
|
||||
LoggerFactory.getLogger(InstrumentedScheduledExecutorServiceTest.class);
|
||||
|
||||
private final ScheduledExecutorService scheduledExecutor =
|
||||
@@ -35,17 +35,17 @@ class InstrumentedScheduledExecutorServiceTest {
|
||||
private final Histogram percentOfPeriod = registry.histogram("xs.scheduled.percent-of-period");
|
||||
|
||||
@@ -2338,15 +2370,6 @@
|
||||
assertThat(completed.getCount()).isNotEqualTo(0);
|
||||
assertThat(duration.getCount()).isNotEqualTo(0);
|
||||
assertThat(duration.getSnapshot().size()).isNotEqualTo(0);
|
||||
@@ -322,7 +322,7 @@ class InstrumentedScheduledExecutorServiceTest {
|
||||
void tearDown() throws Exception {
|
||||
instrumentedScheduledExecutor.shutdown();
|
||||
if (!instrumentedScheduledExecutor.awaitTermination(2, TimeUnit.SECONDS)) {
|
||||
- LOGGER.error("InstrumentedScheduledExecutorService did not terminate.");
|
||||
+ LOG.error("InstrumentedScheduledExecutorService did not terminate.");
|
||||
}
|
||||
}
|
||||
}
|
||||
--- a/metrics-core/src/test/java/io/dropwizard/metrics5/InstrumentedThreadFactoryTest.java
|
||||
+++ b/metrics-core/src/test/java/io/dropwizard/metrics5/InstrumentedThreadFactoryTest.java
|
||||
@@ -11,7 +11,7 @@ import java.util.concurrent.TimeUnit;
|
||||
@@ -3801,15 +3824,6 @@
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
@@ -29,7 +32,7 @@ public class Graphite implements GraphiteSender {
|
||||
private Writer writer;
|
||||
private int failures;
|
||||
|
||||
- private static final Logger LOGGER = LoggerFactory.getLogger(Graphite.class);
|
||||
+ private static final Logger LOG = LoggerFactory.getLogger(Graphite.class);
|
||||
|
||||
/**
|
||||
* Creates a new client which connects to the given address using the default {@link
|
||||
@@ -63,13 +66,9 @@ public class Graphite implements GraphiteSender {
|
||||
* @param charset the character set used by the server
|
||||
*/
|
||||
@@ -3837,24 +3851,6 @@
|
||||
InetSocketAddress address = this.address;
|
||||
// the previous dns retry logic did not work, as address.getAddress would always return the
|
||||
// cached value
|
||||
@@ -178,7 +175,7 @@ public class Graphite implements GraphiteSender {
|
||||
writer.close();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
- LOGGER.debug("Error closing writer", ex);
|
||||
+ LOG.debug("Error closing writer", ex);
|
||||
} finally {
|
||||
this.writer = null;
|
||||
}
|
||||
@@ -188,7 +185,7 @@ public class Graphite implements GraphiteSender {
|
||||
socket.close();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
- LOGGER.debug("Error closing socket", ex);
|
||||
+ LOG.debug("Error closing socket", ex);
|
||||
} finally {
|
||||
this.socket = null;
|
||||
}
|
||||
--- a/metrics-graphite/src/main/java/io/dropwizard/metrics5/graphite/GraphiteRabbitMQ.java
|
||||
+++ b/metrics-graphite/src/main/java/io/dropwizard/metrics5/graphite/GraphiteRabbitMQ.java
|
||||
@@ -1,5 +1,6 @@
|
||||
@@ -3923,39 +3919,7 @@
|
||||
this.addMetricAttributesAsTags = false;
|
||||
this.floatingPointFormatter = DEFAULT_FP_FORMATTER;
|
||||
}
|
||||
@@ -249,7 +247,7 @@ public class GraphiteReporter extends ScheduledReporter {
|
||||
}
|
||||
}
|
||||
|
||||
- private static final Logger LOGGER = LoggerFactory.getLogger(GraphiteReporter.class);
|
||||
+ private static final Logger LOG = LoggerFactory.getLogger(GraphiteReporter.class);
|
||||
// the Carbon plaintext format is pretty underspecified, but it seems like it just wants
|
||||
// US-formatted digits
|
||||
private static final DoubleFunction<String> DEFAULT_FP_FORMATTER =
|
||||
@@ -430,12 +428,12 @@ public class GraphiteReporter extends ScheduledReporter {
|
||||
}
|
||||
graphite.flush();
|
||||
} catch (IOException e) {
|
||||
- LOGGER.warn("Unable to report to Graphite", graphite, e);
|
||||
+ LOG.warn("Unable to report to Graphite", graphite, e);
|
||||
} finally {
|
||||
try {
|
||||
graphite.close();
|
||||
} catch (IOException e1) {
|
||||
- LOGGER.warn("Error closing Graphite", graphite, e1);
|
||||
+ LOG.warn("Error closing Graphite", graphite, e1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -448,16 +446,16 @@ public class GraphiteReporter extends ScheduledReporter {
|
||||
try {
|
||||
graphite.close();
|
||||
} catch (IOException e) {
|
||||
- LOGGER.debug("Error disconnecting from Graphite", graphite, e);
|
||||
+ LOG.debug("Error disconnecting from Graphite", graphite, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -455,9 +453,9 @@ public class GraphiteReporter extends ScheduledReporter {
|
||||
|
||||
private void reportTimer(MetricName name, Timer timer, long timestamp) throws IOException {
|
||||
final Snapshot snapshot = timer.getSnapshot();
|
||||
@@ -4017,15 +3981,6 @@
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
@@ -48,7 +49,7 @@ public class PickledGraphite implements GraphiteSender {
|
||||
QUOTE = '\'',
|
||||
LF = '\n';
|
||||
|
||||
- private static final Logger LOGGER = LoggerFactory.getLogger(PickledGraphite.class);
|
||||
+ private static final Logger LOG = LoggerFactory.getLogger(PickledGraphite.class);
|
||||
private static final int DEFAULT_BATCH_SIZE = 100;
|
||||
|
||||
private int batchSize;
|
||||
@@ -173,9 +174,7 @@ public class PickledGraphite implements GraphiteSender {
|
||||
|
||||
@Override
|
||||
@@ -4046,17 +4001,6 @@
|
||||
try {
|
||||
byte[] payload = pickleMetrics(metrics);
|
||||
byte[] header = ByteBuffer.allocate(4).putInt(payload.length).array();
|
||||
@@ -260,8 +259,8 @@ public class PickledGraphite implements GraphiteSender {
|
||||
outputStream.write(payload);
|
||||
outputStream.flush();
|
||||
|
||||
- if (LOGGER.isDebugEnabled()) {
|
||||
- LOGGER.debug("Wrote {} metrics", metrics.size());
|
||||
+ if (LOG.isDebugEnabled()) {
|
||||
+ LOG.debug("Wrote {} metrics", metrics.size());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
this.failures++;
|
||||
--- a/metrics-graphite/src/test/java/io/dropwizard/metrics5/graphite/GraphiteRabbitMQTest.java
|
||||
+++ b/metrics-graphite/src/test/java/io/dropwizard/metrics5/graphite/GraphiteRabbitMQTest.java
|
||||
@@ -8,7 +8,6 @@ import static org.mockito.Mockito.anyString;
|
||||
@@ -4475,15 +4419,6 @@
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -27,7 +29,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
/** A registry for health checks. */
|
||||
public class HealthCheckRegistry {
|
||||
- private static final Logger LOGGER = LoggerFactory.getLogger(HealthCheckRegistry.class);
|
||||
+ private static final Logger LOG = LoggerFactory.getLogger(HealthCheckRegistry.class);
|
||||
private static final int ASYNC_EXECUTOR_POOL_SIZE = 2;
|
||||
|
||||
private final ConcurrentMap<String, HealthCheck> healthChecks;
|
||||
@@ -92,9 +94,8 @@ public class HealthCheckRegistry {
|
||||
public void register(String name, HealthCheck healthCheck) {
|
||||
HealthCheck registered;
|
||||
@@ -4514,13 +4449,7 @@
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -217,12 +218,12 @@ public class HealthCheckRegistry {
|
||||
try {
|
||||
results.put(entry.getKey(), entry.getValue().get());
|
||||
} catch (Exception e) {
|
||||
- LOGGER.warn("Error executing health check {}", entry.getKey(), e);
|
||||
+ LOG.warn("Error executing health check {}", entry.getKey(), e);
|
||||
results.put(entry.getKey(), HealthCheck.Result.unhealthy(e));
|
||||
@@ -222,7 +223,7 @@ public class HealthCheckRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5357,39 +5286,6 @@
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,7 +196,7 @@ public class InfluxDbReporter extends GarbageFreeScheduledReporter {
|
||||
}
|
||||
}
|
||||
|
||||
- private static final Logger LOGGER = LoggerFactory.getLogger(InfluxDbReporter.class);
|
||||
+ private static final Logger LOG = LoggerFactory.getLogger(InfluxDbReporter.class);
|
||||
private static final String VALUE = "value";
|
||||
|
||||
private final Clock clock;
|
||||
@@ -279,12 +279,12 @@ public class InfluxDbReporter extends GarbageFreeScheduledReporter {
|
||||
}
|
||||
sender.flush();
|
||||
} catch (IOException e) {
|
||||
- LOGGER.warn("Unable to report to InfluxDb", sender, e);
|
||||
+ LOG.warn("Unable to report to InfluxDb", sender, e);
|
||||
} finally {
|
||||
try {
|
||||
sender.disconnect();
|
||||
} catch (IOException e) {
|
||||
- LOGGER.warn("Error disconnecting InfluxDb", sender, e);
|
||||
+ LOG.warn("Error disconnecting InfluxDb", sender, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -297,7 +297,7 @@ public class InfluxDbReporter extends GarbageFreeScheduledReporter {
|
||||
try {
|
||||
sender.close();
|
||||
} catch (IOException e) {
|
||||
- LOGGER.debug("Error disconnecting from InfluxDb", e);
|
||||
+ LOG.debug("Error disconnecting from InfluxDb", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
--- a/metrics-influxdb/src/main/java/io/dropwizard/metrics5/influxdb/InfluxDbUdpSender.java
|
||||
+++ b/metrics-influxdb/src/main/java/io/dropwizard/metrics5/influxdb/InfluxDbUdpSender.java
|
||||
@@ -1,5 +1,7 @@
|
||||
@@ -6065,15 +5961,6 @@
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -33,7 +33,7 @@ public class JCacheGaugeSet implements MetricSet {
|
||||
private static final String M_BEAN_COORDINATES =
|
||||
"javax.cache:type=CacheStatistics,CacheManager=*,Cache=*";
|
||||
|
||||
- private static final Logger LOGGER = LoggerFactory.getLogger(JCacheGaugeSet.class);
|
||||
+ private static final Logger LOG = LoggerFactory.getLogger(JCacheGaugeSet.class);
|
||||
|
||||
@Override
|
||||
public Map<MetricName, Metric> getMetrics() {
|
||||
@@ -52,7 +52,7 @@ public class JCacheGaugeSet implements MetricSet {
|
||||
}
|
||||
}
|
||||
@@ -6083,15 +5970,6 @@
|
||||
}
|
||||
|
||||
private Set<ObjectInstance> getCacheBeans() {
|
||||
@@ -60,7 +60,7 @@ public class JCacheGaugeSet implements MetricSet {
|
||||
return ManagementFactory.getPlatformMBeanServer()
|
||||
.queryMBeans(ObjectName.getInstance(M_BEAN_COORDINATES), null);
|
||||
} catch (MalformedObjectNameException e) {
|
||||
- LOGGER.error("Unable to retrieve {}. Are JCache statistics enabled?", M_BEAN_COORDINATES);
|
||||
+ LOG.error("Unable to retrieve {}. Are JCache statistics enabled?", M_BEAN_COORDINATES);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
--- a/metrics-jcache/src/test/java/JCacheGaugeSetTest.java
|
||||
+++ b/metrics-jcache/src/test/java/JCacheGaugeSetTest.java
|
||||
@@ -11,7 +11,7 @@ import org.junit.jupiter.api.AfterEach;
|
||||
@@ -8461,11 +8339,11 @@
|
||||
|
||||
private static final char[] QUOTABLE_CHARS = new char[] {',', '=', ':', '"'};
|
||||
- private static final Logger LOGGER = LoggerFactory.getLogger(JmxReporter.class);
|
||||
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultObjectNameFactory.class);
|
||||
+ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultObjectNameFactory.class);
|
||||
|
||||
@Override
|
||||
public ObjectName createName(String type, String domain, MetricName name) {
|
||||
@@ -38,14 +38,13 @@ public class DefaultObjectNameFactory implements ObjectNameFactory {
|
||||
@@ -38,9 +38,8 @@ public class DefaultObjectNameFactory implements ObjectNameFactory {
|
||||
|| shouldQuote(objectName.getKeyProperty("type"))) {
|
||||
properties.put("type", ObjectName.quote(type));
|
||||
}
|
||||
@@ -8476,12 +8354,6 @@
|
||||
} catch (MalformedObjectNameException e) {
|
||||
try {
|
||||
return new ObjectName(domain, "name", ObjectName.quote(name.getKey()));
|
||||
} catch (MalformedObjectNameException e1) {
|
||||
- LOGGER.warn("Unable to register {} {}", type, name, e1);
|
||||
+ LOG.warn("Unable to register {} {}", type, name, e1);
|
||||
throw new RuntimeException(e1);
|
||||
}
|
||||
}
|
||||
--- a/metrics-jmx/src/main/java/io/dropwizard/metrics5/jmx/JmxReporter.java
|
||||
+++ b/metrics-jmx/src/main/java/io/dropwizard/metrics5/jmx/JmxReporter.java
|
||||
@@ -1,5 +1,9 @@
|
||||
@@ -8542,147 +8414,6 @@
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -159,7 +160,7 @@ public class JmxReporter implements Reporter, Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
- private static final Logger LOGGER = LoggerFactory.getLogger(JmxReporter.class);
|
||||
+ private static final Logger LOG = LoggerFactory.getLogger(JmxReporter.class);
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public interface MetricMBean {
|
||||
@@ -570,9 +571,9 @@ public class JmxReporter implements Reporter, Closeable {
|
||||
registerMBean(new JmxGauge(gauge, objectName), objectName);
|
||||
}
|
||||
} catch (InstanceAlreadyExistsException e) {
|
||||
- LOGGER.debug("Unable to register gauge", e);
|
||||
+ LOG.debug("Unable to register gauge", e);
|
||||
} catch (JMException e) {
|
||||
- LOGGER.warn("Unable to register gauge", e);
|
||||
+ LOG.warn("Unable to register gauge", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -582,9 +583,9 @@ public class JmxReporter implements Reporter, Closeable {
|
||||
final ObjectName objectName = createName("gauges", name);
|
||||
unregisterMBean(objectName);
|
||||
} catch (InstanceNotFoundException e) {
|
||||
- LOGGER.debug("Unable to unregister gauge", e);
|
||||
+ LOG.debug("Unable to unregister gauge", e);
|
||||
} catch (MBeanRegistrationException e) {
|
||||
- LOGGER.warn("Unable to unregister gauge", e);
|
||||
+ LOG.warn("Unable to unregister gauge", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -596,9 +597,9 @@ public class JmxReporter implements Reporter, Closeable {
|
||||
registerMBean(new JmxCounter(counter, objectName), objectName);
|
||||
}
|
||||
} catch (InstanceAlreadyExistsException e) {
|
||||
- LOGGER.debug("Unable to register counter", e);
|
||||
+ LOG.debug("Unable to register counter", e);
|
||||
} catch (JMException e) {
|
||||
- LOGGER.warn("Unable to register counter", e);
|
||||
+ LOG.warn("Unable to register counter", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -608,9 +609,9 @@ public class JmxReporter implements Reporter, Closeable {
|
||||
final ObjectName objectName = createName("counters", name);
|
||||
unregisterMBean(objectName);
|
||||
} catch (InstanceNotFoundException e) {
|
||||
- LOGGER.debug("Unable to unregister counter", e);
|
||||
+ LOG.debug("Unable to unregister counter", e);
|
||||
} catch (MBeanRegistrationException e) {
|
||||
- LOGGER.warn("Unable to unregister counter", e);
|
||||
+ LOG.warn("Unable to unregister counter", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -622,9 +623,9 @@ public class JmxReporter implements Reporter, Closeable {
|
||||
registerMBean(new JmxHistogram(histogram, objectName), objectName);
|
||||
}
|
||||
} catch (InstanceAlreadyExistsException e) {
|
||||
- LOGGER.debug("Unable to register histogram", e);
|
||||
+ LOG.debug("Unable to register histogram", e);
|
||||
} catch (JMException e) {
|
||||
- LOGGER.warn("Unable to register histogram", e);
|
||||
+ LOG.warn("Unable to register histogram", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -634,9 +635,9 @@ public class JmxReporter implements Reporter, Closeable {
|
||||
final ObjectName objectName = createName("histograms", name);
|
||||
unregisterMBean(objectName);
|
||||
} catch (InstanceNotFoundException e) {
|
||||
- LOGGER.debug("Unable to unregister histogram", e);
|
||||
+ LOG.debug("Unable to unregister histogram", e);
|
||||
} catch (MBeanRegistrationException e) {
|
||||
- LOGGER.warn("Unable to unregister histogram", e);
|
||||
+ LOG.warn("Unable to unregister histogram", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -649,9 +650,9 @@ public class JmxReporter implements Reporter, Closeable {
|
||||
new JmxMeter(meter, objectName, timeUnits.rateFor(name.getKey())), objectName);
|
||||
}
|
||||
} catch (InstanceAlreadyExistsException e) {
|
||||
- LOGGER.debug("Unable to register meter", e);
|
||||
+ LOG.debug("Unable to register meter", e);
|
||||
} catch (JMException e) {
|
||||
- LOGGER.warn("Unable to register meter", e);
|
||||
+ LOG.warn("Unable to register meter", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -661,9 +662,9 @@ public class JmxReporter implements Reporter, Closeable {
|
||||
final ObjectName objectName = createName("meters", name);
|
||||
unregisterMBean(objectName);
|
||||
} catch (InstanceNotFoundException e) {
|
||||
- LOGGER.debug("Unable to unregister meter", e);
|
||||
+ LOG.debug("Unable to unregister meter", e);
|
||||
} catch (MBeanRegistrationException e) {
|
||||
- LOGGER.warn("Unable to unregister meter", e);
|
||||
+ LOG.warn("Unable to unregister meter", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -681,9 +682,9 @@ public class JmxReporter implements Reporter, Closeable {
|
||||
objectName);
|
||||
}
|
||||
} catch (InstanceAlreadyExistsException e) {
|
||||
- LOGGER.debug("Unable to register timer", e);
|
||||
+ LOG.debug("Unable to register timer", e);
|
||||
} catch (JMException e) {
|
||||
- LOGGER.warn("Unable to register timer", e);
|
||||
+ LOG.warn("Unable to register timer", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -693,9 +694,9 @@ public class JmxReporter implements Reporter, Closeable {
|
||||
final ObjectName objectName = createName("timers", name);
|
||||
unregisterMBean(objectName);
|
||||
} catch (InstanceNotFoundException e) {
|
||||
- LOGGER.debug("Unable to unregister timer", e);
|
||||
+ LOG.debug("Unable to unregister timer", e);
|
||||
} catch (MBeanRegistrationException e) {
|
||||
- LOGGER.warn("Unable to unregister timer", e);
|
||||
+ LOG.warn("Unable to unregister timer", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -708,9 +709,9 @@ public class JmxReporter implements Reporter, Closeable {
|
||||
try {
|
||||
unregisterMBean(name);
|
||||
} catch (InstanceNotFoundException e) {
|
||||
- LOGGER.debug("Unable to unregister metric", e);
|
||||
+ LOG.debug("Unable to unregister metric", e);
|
||||
} catch (MBeanRegistrationException e) {
|
||||
- LOGGER.warn("Unable to unregister metric", e);
|
||||
+ LOG.warn("Unable to unregister metric", e);
|
||||
}
|
||||
}
|
||||
registered.clear();
|
||||
--- a/metrics-jmx/src/test/java/io/dropwizard/metrics5/jmx/DefaultObjectNameFactoryTest.java
|
||||
+++ b/metrics-jmx/src/test/java/io/dropwizard/metrics5/jmx/DefaultObjectNameFactoryTest.java
|
||||
@@ -7,7 +7,7 @@ import io.dropwizard.metrics5.MetricName;
|
||||
@@ -9002,21 +8733,7 @@
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.management.JMException;
|
||||
@@ -19,7 +20,7 @@ import org.slf4j.LoggerFactory;
|
||||
* <p>These JMX objects are only available on Java 7 and above.
|
||||
*/
|
||||
public class BufferPoolMetricSet implements MetricSet {
|
||||
- private static final Logger LOGGER = LoggerFactory.getLogger(BufferPoolMetricSet.class);
|
||||
+ private static final Logger LOG = LoggerFactory.getLogger(BufferPoolMetricSet.class);
|
||||
private static final String[] ATTRIBUTES = {"Count", "MemoryUsed", "TotalCapacity"};
|
||||
private static final String[] NAMES = {"count", "used", "capacity"};
|
||||
private static final String[] POOLS = {"direct", "mapped"};
|
||||
@@ -43,10 +44,10 @@ public class BufferPoolMetricSet implements MetricSet {
|
||||
gauges.put(
|
||||
MetricRegistry.name(pool, name), new JmxAttributeGauge(mBeanServer, on, attribute));
|
||||
} catch (JMException ignored) {
|
||||
- LOGGER.debug("Unable to load buffer pool MBeans, possibly running on Java 6");
|
||||
+ LOG.debug("Unable to load buffer pool MBeans, possibly running on Java 6");
|
||||
@@ -47,6 +48,6 @@ public class BufferPoolMetricSet implements MetricSet {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ metrics-collectd/src/main/java/io/dropwizard/metrics5/collectd/PacketWriter.java
|
||||
metrics-core/src/main/java/io/dropwizard/metrics5/CsvReporter.java:[390,35] [FormatStringConcatenation] Defer string concatenation to the invoked method
|
||||
metrics-core/src/main/java/io/dropwizard/metrics5/InstrumentedExecutorService.java:[244,25] [try] auto-closeable resource durationContext is never referenced in body of corresponding try statement
|
||||
metrics-core/src/main/java/io/dropwizard/metrics5/InstrumentedExecutorService.java:[266,25] [try] auto-closeable resource context is never referenced in body of corresponding try statement
|
||||
metrics-graphite/src/main/java/io/dropwizard/metrics5/graphite/GraphiteReporter.java:[431,14] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
|
||||
metrics-graphite/src/main/java/io/dropwizard/metrics5/graphite/GraphiteReporter.java:[436,16] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
|
||||
metrics-graphite/src/main/java/io/dropwizard/metrics5/graphite/GraphiteReporter.java:[449,17] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
|
||||
metrics-graphite/src/main/java/io/dropwizard/metrics5/graphite/GraphiteReporter.java:[431,17] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
|
||||
metrics-graphite/src/main/java/io/dropwizard/metrics5/graphite/GraphiteReporter.java:[436,19] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
|
||||
metrics-graphite/src/main/java/io/dropwizard/metrics5/graphite/GraphiteReporter.java:[449,20] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
|
||||
metrics-healthchecks/src/test/java/io/dropwizard/metrics5/health/HealthCheckTest.java:[189,46] [TimeZoneUsage] Derive the current time from an existing `Clock` Spring bean, and don't rely on a `Clock`'s time zone
|
||||
metrics-healthchecks/src/test/java/io/dropwizard/metrics5/health/HealthCheckTest.java:[203,46] [TimeZoneUsage] Derive the current time from an existing `Clock` Spring bean, and don't rely on a `Clock`'s time zone
|
||||
metrics-httpclient/src/test/java/io/dropwizard/metrics5/httpclient/HttpClientMetricNameStrategiesTest.java:[124,22] [deprecation] rewriteURI(URI,HttpHost,boolean) in URIUtils has been deprecated
|
||||
@@ -26,8 +26,8 @@ metrics-httpclient5/src/main/java/io/dropwizard/metrics5/httpclient5/Instrumente
|
||||
metrics-httpclient5/src/main/java/io/dropwizard/metrics5/httpclient5/InstrumentedHttpRequestExecutor.java:[49,4] [deprecation] HttpRequestExecutor(Timeout,ConnectionReuseStrategy,Http1StreamListener) in HttpRequestExecutor has been deprecated
|
||||
metrics-httpclient5/src/test/java/io/dropwizard/metrics5/httpclient5/InstrumentedHttpClientsTest.java:[46,10] [deprecation] execute(ClassicHttpRequest) in HttpClient has been deprecated
|
||||
metrics-httpclient5/src/test/java/io/dropwizard/metrics5/httpclient5/InstrumentedHttpClientsTest.java:[68,12] [deprecation] execute(ClassicHttpRequest) in HttpClient has been deprecated
|
||||
metrics-influxdb/src/main/java/io/dropwizard/metrics5/influxdb/InfluxDbReporter.java:[282,14] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
|
||||
metrics-influxdb/src/main/java/io/dropwizard/metrics5/influxdb/InfluxDbReporter.java:[287,16] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
|
||||
metrics-influxdb/src/main/java/io/dropwizard/metrics5/influxdb/InfluxDbReporter.java:[282,17] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
|
||||
metrics-influxdb/src/main/java/io/dropwizard/metrics5/influxdb/InfluxDbReporter.java:[287,19] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
|
||||
metrics-jakarta-servlets/src/test/java/io/dropwizard/metrics5/servlets/HealthCheckServletTest.java:[31,67] [TimeZoneUsage] Derive the current time from an existing `Clock` Spring bean, and don't rely on a `Clock`'s time zone
|
||||
metrics-jdbi3/src/test/java/io/dropwizard/metrics5/jdbi3/strategies/SmartNameStrategyTest.java:[18,10] [deprecation] InstrumentedTimingCollector in io.dropwizard.metrics5.jdbi3 has been deprecated
|
||||
metrics-jdbi3/src/test/java/io/dropwizard/metrics5/jdbi3/strategies/SmartNameStrategyTest.java:[24,20] [deprecation] InstrumentedTimingCollector in io.dropwizard.metrics5.jdbi3 has been deprecated
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
+ <dependency>
|
||||
+ <groupId>com.google.guava</groupId>
|
||||
+ <artifactId>guava</artifactId>
|
||||
+ <version>33.4.0-jre<!-- Renovate: com.google.guava:guava-bom --></version>
|
||||
+ <version>33.4.7-jre<!-- Renovate: com.google.guava:guava-bom --></version>
|
||||
+ </dependency>
|
||||
+ </dependencies>
|
||||
+ </dependencyManagement>
|
||||
|
||||
@@ -8,11 +8,7 @@ repository='https://github.com/dropwizard/metrics.git'
|
||||
revision='v5.0.0-rc22'
|
||||
additional_build_flags=''
|
||||
additional_source_directories=''
|
||||
# XXX: Minimize the diff by including
|
||||
# `-XepOpt:Slf4jLoggerDeclaration:CanonicalStaticLoggerName=LOGGER` once such
|
||||
# flags are supported in patch mode. See
|
||||
# https://github.com/google/error-prone/pull/4699.
|
||||
shared_error_prone_flags='-XepExcludedPaths:.*/target/generated-sources/.*'
|
||||
shared_error_prone_flags='-XepExcludedPaths:.*/target/generated-sources/.* -XepOpt:Slf4jLoggerDeclaration:CanonicalStaticLoggerName=LOGGER'
|
||||
patch_error_prone_flags=''
|
||||
validation_error_prone_flags=''
|
||||
validation_build_flags=''
|
||||
|
||||
308
mvnw
vendored
Executable file
308
mvnw
vendored
Executable file
@@ -0,0 +1,308 @@
|
||||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Apache Maven Wrapper startup batch script, version 3.2.0
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||
|
||||
if [ -f /usr/local/etc/mavenrc ] ; then
|
||||
. /usr/local/etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f /etc/mavenrc ] ; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ] ; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false;
|
||||
darwin=false;
|
||||
mingw=false
|
||||
case "$(uname)" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -x "/usr/libexec/java_home" ]; then
|
||||
JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME
|
||||
else
|
||||
JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
if [ -r /etc/gentoo-release ] ; then
|
||||
JAVA_HOME=$(java-config --jre-home)
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
|
||||
fi
|
||||
|
||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)"
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="$(which javac)"
|
||||
if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=$(which readlink)
|
||||
if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
|
||||
if $darwin ; then
|
||||
javaHome="$(dirname "\"$javaExecutable\"")"
|
||||
javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac"
|
||||
else
|
||||
javaExecutable="$(readlink -f "\"$javaExecutable\"")"
|
||||
fi
|
||||
javaHome="$(dirname "\"$javaExecutable\"")"
|
||||
javaHome=$(expr "$javaHome" : '\(.*\)/bin')
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Path not specified to find_maven_basedir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
basedir="$1"
|
||||
wdir="$1"
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||
if [ -d "${wdir}" ]; then
|
||||
wdir=$(cd "$wdir/.." || exit 1; pwd)
|
||||
fi
|
||||
# end of workaround
|
||||
done
|
||||
printf '%s' "$(cd "$basedir" || exit 1; pwd)"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
# Remove \r in case we run on Windows within Git Bash
|
||||
# and check out the repository with auto CRLF management
|
||||
# enabled. Otherwise, we may read lines that are delimited with
|
||||
# \r\n and produce $'-Xarg\r' rather than -Xarg due to word
|
||||
# splitting rules.
|
||||
tr -s '\r\n' ' ' < "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
log() {
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
printf '%s\n' "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
|
||||
if [ -z "$BASE_DIR" ]; then
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
|
||||
log "$MAVEN_PROJECTBASEDIR"
|
||||
|
||||
##########################################################################################
|
||||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
##########################################################################################
|
||||
wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
|
||||
if [ -r "$wrapperJarPath" ]; then
|
||||
log "Found $wrapperJarPath"
|
||||
else
|
||||
log "Couldn't find $wrapperJarPath, downloading it ..."
|
||||
|
||||
if [ -n "$MVNW_REPOURL" ]; then
|
||||
wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||
else
|
||||
wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||
fi
|
||||
while IFS="=" read -r key value; do
|
||||
# Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
|
||||
safeValue=$(echo "$value" | tr -d '\r')
|
||||
case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;;
|
||||
esac
|
||||
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
log "Downloading from: $wrapperUrl"
|
||||
|
||||
if $cygwin; then
|
||||
wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
|
||||
fi
|
||||
|
||||
if command -v wget > /dev/null; then
|
||||
log "Found wget ... using wget"
|
||||
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
||||
else
|
||||
wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
||||
fi
|
||||
elif command -v curl > /dev/null; then
|
||||
log "Found curl ... using curl"
|
||||
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
|
||||
else
|
||||
curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
|
||||
fi
|
||||
else
|
||||
log "Falling back to using Java to download"
|
||||
javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||
javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
|
||||
# For Cygwin, switch paths to Windows format before running javac
|
||||
if $cygwin; then
|
||||
javaSource=$(cygpath --path --windows "$javaSource")
|
||||
javaClass=$(cygpath --path --windows "$javaClass")
|
||||
fi
|
||||
if [ -e "$javaSource" ]; then
|
||||
if [ ! -e "$javaClass" ]; then
|
||||
log " - Compiling MavenWrapperDownloader.java ..."
|
||||
("$JAVA_HOME/bin/javac" "$javaSource")
|
||||
fi
|
||||
if [ -e "$javaClass" ]; then
|
||||
log " - Running MavenWrapperDownloader.java ..."
|
||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
##########################################################################################
|
||||
# End of extension
|
||||
##########################################################################################
|
||||
|
||||
# If specified, validate the SHA-256 sum of the Maven wrapper jar file
|
||||
wrapperSha256Sum=""
|
||||
while IFS="=" read -r key value; do
|
||||
case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;
|
||||
esac
|
||||
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
if [ -n "$wrapperSha256Sum" ]; then
|
||||
wrapperSha256Result=false
|
||||
if command -v sha256sum > /dev/null; then
|
||||
if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then
|
||||
wrapperSha256Result=true
|
||||
fi
|
||||
elif command -v shasum > /dev/null; then
|
||||
if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then
|
||||
wrapperSha256Result=true
|
||||
fi
|
||||
else
|
||||
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available."
|
||||
echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties."
|
||||
exit 1
|
||||
fi
|
||||
if [ $wrapperSha256Result = false ]; then
|
||||
echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
|
||||
echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
|
||||
echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
|
||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||
MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
# shellcheck disable=SC2086 # safe args
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
$MAVEN_DEBUG_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
||||
205
mvnw.cmd
vendored
Normal file
205
mvnw.cmd
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Apache Maven Wrapper startup batch script, version 3.2.0
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM set title of command window
|
||||
title %0
|
||||
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
|
||||
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||
|
||||
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||
IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
|
||||
)
|
||||
|
||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
if exist %WRAPPER_JAR% (
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Found %WRAPPER_JAR%
|
||||
)
|
||||
) else (
|
||||
if not "%MVNW_REPOURL%" == "" (
|
||||
SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||
)
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||
echo Downloading from: %WRAPPER_URL%
|
||||
)
|
||||
|
||||
powershell -Command "&{"^
|
||||
"$webclient = new-object System.Net.WebClient;"^
|
||||
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
|
||||
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
|
||||
"}"^
|
||||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
|
||||
"}"
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Finished downloading %WRAPPER_JAR%
|
||||
)
|
||||
)
|
||||
@REM End of extension
|
||||
|
||||
@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
|
||||
SET WRAPPER_SHA_256_SUM=""
|
||||
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||
IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
|
||||
)
|
||||
IF NOT %WRAPPER_SHA_256_SUM%=="" (
|
||||
powershell -Command "&{"^
|
||||
"$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
|
||||
"If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
|
||||
" Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
|
||||
" Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
|
||||
" Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
|
||||
" exit 1;"^
|
||||
"}"^
|
||||
"}"
|
||||
if ERRORLEVEL 1 goto error
|
||||
)
|
||||
|
||||
@REM Provide a "standardized" way to retrieve the CLI args that will
|
||||
@REM work with both Windows and non-Windows executions.
|
||||
set MAVEN_CMD_LINE_ARGS=%*
|
||||
|
||||
%MAVEN_JAVA_EXE% ^
|
||||
%JVM_CONFIG_MAVEN_PROPS% ^
|
||||
%MAVEN_OPTS% ^
|
||||
%MAVEN_DEBUG_OPTS% ^
|
||||
-classpath %WRAPPER_JAR% ^
|
||||
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
|
||||
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
|
||||
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%"=="on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
|
||||
|
||||
cmd /C exit /B %ERROR_CODE%
|
||||
238
pom.xml
238
pom.xml
@@ -4,7 +4,7 @@
|
||||
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.20.1-SNAPSHOT</version>
|
||||
<version>0.22.1-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Picnic :: Error Prone Support</name>
|
||||
@@ -48,6 +48,7 @@
|
||||
<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">
|
||||
@@ -146,7 +147,7 @@
|
||||
<error-prone.self-check-args />
|
||||
<!-- The build timestamp is derived from the most recent commit
|
||||
timestamp in support of reproducible builds. -->
|
||||
<project.build.outputTimestamp>2025-02-02T12:19:40Z</project.build.outputTimestamp>
|
||||
<project.build.outputTimestamp>2025-04-14T09:36:15Z</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,17 +206,17 @@
|
||||
<version.auto-service>1.1.1</version.auto-service>
|
||||
<version.auto-value>1.11.0</version.auto-value>
|
||||
<version.error-prone>${version.error-prone-orig}</version.error-prone>
|
||||
<version.error-prone-fork>${version.error-prone-orig}-picnic-2</version.error-prone-fork>
|
||||
<version.error-prone-orig>2.36.0</version.error-prone-orig>
|
||||
<version.error-prone-fork>${version.error-prone-orig}-picnic-1</version.error-prone-fork>
|
||||
<version.error-prone-orig>2.37.0</version.error-prone-orig>
|
||||
<version.error-prone-slf4j>0.1.28</version.error-prone-slf4j>
|
||||
<version.guava-beta-checker>1.0</version.guava-beta-checker>
|
||||
<version.jdk>17</version.jdk>
|
||||
<version.maven>3.9.9</version.maven>
|
||||
<version.mockito>5.15.2</version.mockito>
|
||||
<version.mockito>5.17.0</version.mockito>
|
||||
<version.nopen-checker>1.0.1</version.nopen-checker>
|
||||
<version.nullaway>0.12.3</version.nullaway>
|
||||
<version.pitest-git>1.1.4</version.pitest-git>
|
||||
<version.rewrite-templating>1.22.1</version.rewrite-templating>
|
||||
<version.nullaway>0.12.6</version.nullaway>
|
||||
<version.pitest-git>2.2.1</version.pitest-git>
|
||||
<version.rewrite-templating>1.25.1</version.rewrite-templating>
|
||||
<version.surefire>3.2.3</version.surefire>
|
||||
</properties>
|
||||
|
||||
@@ -269,7 +270,7 @@
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson</groupId>
|
||||
<artifactId>jackson-bom</artifactId>
|
||||
<version>2.18.2</version>
|
||||
<version>2.18.3</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -303,6 +304,16 @@
|
||||
<artifactId>auto-value-annotations</artifactId>
|
||||
<version>${version.auto-value}</version>
|
||||
</dependency>
|
||||
<!-- XXX: JSR-305 (meta-)annotation usage by some dependencies
|
||||
triggers NullAway to attempt to load said annotations. As such
|
||||
some modules require these annotations to be on the classpath.
|
||||
Periodically review whether we can drop this dependeny version
|
||||
declaration. See https://github.com/uber/NullAway/issues/1171. -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_annotation</artifactId>
|
||||
@@ -331,7 +342,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.googlejavaformat</groupId>
|
||||
<artifactId>google-java-format</artifactId>
|
||||
<version>1.25.2</version>
|
||||
<version>1.26.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
@@ -341,7 +352,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava-bom</artifactId>
|
||||
<version>33.4.0-jre</version>
|
||||
<version>33.4.7-jre</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -363,14 +374,14 @@
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-bom</artifactId>
|
||||
<version>1.14.4</version>
|
||||
<version>1.14.6</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-bom</artifactId>
|
||||
<version>2024.0.3</version>
|
||||
<version>2024.0.4</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -387,7 +398,7 @@
|
||||
<dependency>
|
||||
<groupId>io.swagger.core.v3</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
<version>2.2.28</version>
|
||||
<version>2.2.30</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.servlet</groupId>
|
||||
@@ -422,20 +433,12 @@
|
||||
<dependency>
|
||||
<groupId>net.bytebuddy</groupId>
|
||||
<artifactId>byte-buddy</artifactId>
|
||||
<version>1.17.1</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.17.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>1.9.22.1</version>
|
||||
<version>1.9.24</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
@@ -447,7 +450,7 @@
|
||||
<dependency>
|
||||
<groupId>org.checkerframework</groupId>
|
||||
<artifactId>checker-qual</artifactId>
|
||||
<version>3.49.0</version>
|
||||
<version>3.49.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
@@ -472,7 +475,7 @@
|
||||
<dependency>
|
||||
<groupId>org.junit</groupId>
|
||||
<artifactId>junit-bom</artifactId>
|
||||
<version>5.11.4</version>
|
||||
<version>5.12.2</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -485,8 +488,10 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-core</artifactId>
|
||||
<version>5.3.1</version>
|
||||
<artifactId>mongodb-driver-bom</artifactId>
|
||||
<version>5.4.0</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openrewrite</groupId>
|
||||
@@ -496,33 +501,33 @@
|
||||
<dependency>
|
||||
<groupId>org.openrewrite.recipe</groupId>
|
||||
<artifactId>rewrite-recipe-bom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.6.1</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-bom</artifactId>
|
||||
<version>2.0.16</version>
|
||||
<version>2.0.17</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>6.2.3</version>
|
||||
<version>6.2.5</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-test</artifactId>
|
||||
<version>3.4.3</version>
|
||||
<version>3.4.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-bom</artifactId>
|
||||
<version>6.4.3</version>
|
||||
<version>6.4.4</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -548,6 +553,16 @@
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.arcmutate</groupId>
|
||||
<artifactId>pitest-git-maven-plugin</artifactId>
|
||||
<version>${version.pitest-git}</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.arcmutate</groupId>
|
||||
<artifactId>pitest-github-maven-plugin</artifactId>
|
||||
<version>${version.pitest-git}</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.github.ekryd.sortpom</groupId>
|
||||
<artifactId>sortpom-maven-plugin</artifactId>
|
||||
@@ -575,16 +590,6 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.groupcdg</groupId>
|
||||
<artifactId>pitest-git-maven-plugin</artifactId>
|
||||
<version>${version.pitest-git}</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.groupcdg</groupId>
|
||||
<artifactId>pitest-github-maven-plugin</artifactId>
|
||||
<version>${version.pitest-git}</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.spotify.fmt</groupId>
|
||||
<artifactId>fmt-maven-plugin</artifactId>
|
||||
@@ -608,7 +613,7 @@
|
||||
<plugin>
|
||||
<groupId>de.thetaphi</groupId>
|
||||
<artifactId>forbiddenapis</artifactId>
|
||||
<version>3.8</version>
|
||||
<version>3.9</version>
|
||||
<configuration>
|
||||
<bundledSignatures>
|
||||
<bundledSignature>jdk-internal</bundledSignature>
|
||||
@@ -923,7 +928,7 @@
|
||||
<dependency>
|
||||
<groupId>com.puppycrawl.tools</groupId>
|
||||
<artifactId>checkstyle</artifactId>
|
||||
<version>10.21.2</version>
|
||||
<version>10.23.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.spring.nohttp</groupId>
|
||||
@@ -948,7 +953,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.13.0</version>
|
||||
<version>3.14.0</version>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<!-- XXX: Inline and drop the version
|
||||
@@ -1056,7 +1061,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>3.1.3</version>
|
||||
<version>3.1.4</version>
|
||||
<configuration>
|
||||
<retryFailedDeploymentCount>3</retryFailedDeploymentCount>
|
||||
</configuration>
|
||||
@@ -1122,9 +1127,6 @@
|
||||
<requireMatchingCoordinates>
|
||||
<moduleNameMustMatchArtifactId>true</moduleNameMustMatchArtifactId>
|
||||
</requireMatchingCoordinates>
|
||||
<requireMavenVersion>
|
||||
<version>${version.maven}</version>
|
||||
</requireMavenVersion>
|
||||
<requireNoRepositories />
|
||||
<requirePluginVersions />
|
||||
<requireUpperBoundDeps />
|
||||
@@ -1134,7 +1136,7 @@
|
||||
<dependency>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>extra-enforcer-rules</artifactId>
|
||||
<version>1.9.0</version>
|
||||
<version>1.10.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
@@ -1162,7 +1164,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-install-plugin</artifactId>
|
||||
<version>3.1.3</version>
|
||||
<version>3.1.4</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@@ -1298,7 +1300,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.5.2</version>
|
||||
<version>3.5.3</version>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
@@ -1306,6 +1308,7 @@
|
||||
<properties>
|
||||
<configurationParameters>junit.jupiter.execution.parallel.enabled=true
|
||||
junit.jupiter.execution.parallel.mode.default=concurrent
|
||||
junit.jupiter.execution.timeout.threaddump.enabled=true
|
||||
junit.platform.stacktrace.pruning.enabled=false</configurationParameters>
|
||||
</properties>
|
||||
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
||||
@@ -1442,7 +1445,7 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>tidy-maven-plugin</artifactId>
|
||||
<version>1.3.0</version>
|
||||
<version>1.4.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>check-pom</id>
|
||||
@@ -1460,41 +1463,10 @@
|
||||
<updateBuildOutputTimestampPolicy>never</updateBuildOutputTimestampPolicy>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.gaul</groupId>
|
||||
<artifactId>modernizer-maven-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<exclusionPatterns>
|
||||
<!-- The plugin suggests replacing usages of
|
||||
Guava's `Iterables` class with
|
||||
`java.util.stream.Stream` equivalents, but the
|
||||
alternative is often more verbose, requiring
|
||||
unnecessary conversions to and from streams. -->
|
||||
<exclusionPattern>com/google/common/collect/Iterables\..*</exclusionPattern>
|
||||
</exclusionPatterns>
|
||||
<failOnViolations>false</failOnViolations>
|
||||
<ignorePackages>
|
||||
<!-- Some Refaster rules purposefully use outdated
|
||||
patterns in their `@BeforeTemplate` methods. -->
|
||||
<ignorePackage>tech.picnic.errorprone.refasterrules</ignorePackage>
|
||||
</ignorePackages>
|
||||
<javaVersion>${version.jdk}</javaVersion>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>run-modernizer</id>
|
||||
<goals>
|
||||
<goal>modernizer</goal>
|
||||
</goals>
|
||||
<phase>process-test-classes</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.8.12</version>
|
||||
<version>0.8.13</version>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<!-- Refaster rules are tested using a custom method
|
||||
@@ -1503,28 +1475,10 @@
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.kordamp.maven</groupId>
|
||||
<artifactId>pomchecker-maven-plugin</artifactId>
|
||||
<version>1.14.0</version>
|
||||
<configuration>
|
||||
<failOnError>false</failOnError>
|
||||
<release>false</release>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>check-maven-central-compliance</id>
|
||||
<goals>
|
||||
<goal>check-maven-central</goal>
|
||||
</goals>
|
||||
<phase>verify</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.pitest</groupId>
|
||||
<artifactId>pitest-maven</artifactId>
|
||||
<version>1.18.1</version>
|
||||
<version>1.19.1</version>
|
||||
<configuration>
|
||||
<excludedClasses>
|
||||
<!-- AutoValue generated classes. -->
|
||||
@@ -1546,24 +1500,24 @@
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.groupcdg</groupId>
|
||||
<groupId>com.arcmutate</groupId>
|
||||
<artifactId>base</artifactId>
|
||||
<version>1.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.arcmutate</groupId>
|
||||
<artifactId>pitest-accelerator-junit5</artifactId>
|
||||
<version>1.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.arcmutate</groupId>
|
||||
<artifactId>pitest-git-plugin</artifactId>
|
||||
<version>${version.pitest-git}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.groupcdg.arcmutate</groupId>
|
||||
<artifactId>base</artifactId>
|
||||
<version>1.2.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.groupcdg.pitest</groupId>
|
||||
<artifactId>pitest-accelerator-junit5</artifactId>
|
||||
<version>1.0.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.pitest</groupId>
|
||||
<artifactId>pitest-junit5-plugin</artifactId>
|
||||
<version>1.2.1</version>
|
||||
<version>1.2.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
@@ -1578,7 +1532,7 @@
|
||||
<plugin>
|
||||
<groupId>org.sonarsource.scanner.maven</groupId>
|
||||
<artifactId>sonar-maven-plugin</artifactId>
|
||||
<version>5.0.0.4389</version>
|
||||
<version>5.1.0.4751</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
@@ -1699,11 +1653,6 @@
|
||||
profile. Necessary for dealing with plugins that default to failing
|
||||
the build upon encountering a violation. -->
|
||||
<id>avoid-errors</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>verification.warn</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
@@ -1724,11 +1673,6 @@
|
||||
that they can be disabled during development. See also the
|
||||
`error-prone` profile defined below. -->
|
||||
<id>build-checks</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>!verification.skip</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
@@ -1820,14 +1764,6 @@
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>tidy-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.gaul</groupId>
|
||||
<artifactId>modernizer-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.kordamp.maven</groupId>
|
||||
<artifactId>pomchecker-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
@@ -1937,10 +1873,9 @@
|
||||
-XepOpt:NullAway:AnnotatedPackages=tech.picnic
|
||||
-XepOpt:NullAway:AssertsEnabled=true
|
||||
-XepOpt:NullAway:CheckOptionalEmptiness=true
|
||||
-XepOpt:NullAway:JSpecifyMode=true
|
||||
-XepOpt:Nullness:Conservative=false
|
||||
-XepOpt:StatementSwitchToExpressionSwitch:EnableAssignmentSwitchConversion=true
|
||||
-XepOpt:StatementSwitchToExpressionSwitch:EnableDirectConversion=true
|
||||
-XepOpt:StatementSwitchToExpressionSwitch:EnableReturnSwitchConversion=true
|
||||
<!-- Append additional custom arguments. -->
|
||||
${error-prone.patch-args}
|
||||
${error-prone.self-check-args}
|
||||
@@ -1985,11 +1920,6 @@
|
||||
This profile allows one to collect all violations without failing
|
||||
the build. -->
|
||||
<id>disallow-warnings</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>!verification.warn</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
@@ -2058,21 +1988,6 @@
|
||||
<failOnMissing>true</failOnMissing>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.gaul</groupId>
|
||||
<artifactId>modernizer-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<failOnViolations>true</failOnViolations>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.kordamp.maven</groupId>
|
||||
<artifactId>pomchecker-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<failOnError>true</failOnError>
|
||||
<failOnWarning>true</failOnWarning>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
@@ -2144,13 +2059,6 @@
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
</plugin>
|
||||
<?SORTPOM RESUME?>
|
||||
<plugin>
|
||||
<groupId>org.kordamp.maven</groupId>
|
||||
<artifactId>pomchecker-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<release>true</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.20.1-SNAPSHOT</version>
|
||||
<version>0.22.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>refaster-compiler</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.20.1-SNAPSHOT</version>
|
||||
<version>0.22.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>refaster-runner</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.20.1-SNAPSHOT</version>
|
||||
<version>0.22.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>refaster-support</artifactId>
|
||||
|
||||
@@ -118,11 +118,12 @@ public final class IsEmpty implements Matcher<ExpressionTree> {
|
||||
}
|
||||
|
||||
private boolean isEmptyCollectionConstructor(ExpressionTree tree, VisitorState state) {
|
||||
if (!(tree instanceof NewClassTree) || !MUTABLE_COLLECTION_TYPE.matches(tree, state)) {
|
||||
if (!(tree instanceof NewClassTree newClassTree)
|
||||
|| !MUTABLE_COLLECTION_TYPE.matches(tree, state)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<? extends ExpressionTree> arguments = ((NewClassTree) tree).getArguments();
|
||||
List<? extends ExpressionTree> arguments = newClassTree.getArguments();
|
||||
if (arguments.stream().allMatch(a -> EMPTY_COLLECTION_CONSTRUCTOR_ARGUMENT.matches(a, state))) {
|
||||
/*
|
||||
* This is a default constructor, or a constructor that creates an empty collection using
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.20.1-SNAPSHOT</version>
|
||||
<version>0.22.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>refaster-test-support</artifactId>
|
||||
|
||||
@@ -6,6 +6,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet;
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.ERROR;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.Comparator.naturalOrder;
|
||||
import static tech.picnic.errorprone.refaster.runner.Refaster.INCLUDED_RULES_PATTERN_FLAG;
|
||||
|
||||
@@ -17,6 +18,7 @@ import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Range;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.io.Resources;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
|
||||
import com.google.errorprone.BugPattern;
|
||||
@@ -38,6 +40,9 @@ import com.sun.source.util.TreeScanner;
|
||||
import com.sun.tools.javac.tree.EndPosTable;
|
||||
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
|
||||
import com.sun.tools.javac.util.Position;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -124,13 +129,15 @@ public final class RefasterRuleCollection extends BugChecker implements Compilat
|
||||
*/
|
||||
public static void validate(Class<?> clazz) {
|
||||
String className = clazz.getSimpleName();
|
||||
String inputResource = className + "TestInput.java";
|
||||
String outputResource = className + "TestOutput.java";
|
||||
|
||||
BugCheckerRefactoringTestHelper.newInstance(RefasterRuleCollection.class, clazz)
|
||||
.setArgs(
|
||||
"--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
|
||||
"-XepOpt:" + RULE_COLLECTION_FLAG + '=' + className)
|
||||
.addInput(className + "TestInput.java")
|
||||
.addOutput(className + "TestOutput.java")
|
||||
.addInputLines(inputResource, loadResource(clazz, inputResource))
|
||||
.addOutputLines(outputResource, loadResource(clazz, outputResource))
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
|
||||
@@ -247,6 +254,15 @@ public final class RefasterRuleCollection extends BugChecker implements Compilat
|
||||
return value.substring(index + 1);
|
||||
}
|
||||
|
||||
private static String loadResource(Class<?> contextClass, String resource) {
|
||||
URL url = Resources.getResource(contextClass, resource);
|
||||
try {
|
||||
return Resources.toString(url, UTF_8);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Cannot find resource: " + url, e);
|
||||
}
|
||||
}
|
||||
|
||||
private class UnexpectedMatchReporter extends TreeScanner<@Nullable Void, VisitorState> {
|
||||
private final ImmutableRangeMap<Integer, String> indexedMatches;
|
||||
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
# An overview of Error Prone Support releases, along with compatible Error
|
||||
# Prone releases. This data was generated by `generate-version-compatibility-overview.sh`.
|
||||
releases:
|
||||
- version: 0.22.0
|
||||
compatible:
|
||||
- "2.37.0"
|
||||
- version: 0.21.0
|
||||
compatible:
|
||||
- "2.37.0"
|
||||
- version: 0.20.0
|
||||
compatible:
|
||||
- "2.36.0"
|
||||
|
||||
104
workshop/README.md
Normal file
104
workshop/README.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# Error Prone Workshop
|
||||
|
||||
Download the slides [here][eps-workshop-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 _File -> Settings... -> Build, Execution, Deployment ->
|
||||
Compiler -> Java Compiler_ and deselect the option _Use '--release' option for
|
||||
cross-compilation (Java 9 and later)_.
|
||||
|
||||
If you encounter any other bugs when running `mvn clean install`, make sure you
|
||||
are using a recent release of JDK 17.
|
||||
|
||||
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 navigate to the
|
||||
`tech.picnic.errorprone.workshop.refasterrules` package. There you can find one
|
||||
example and five different exercises to do. Make sure to open the
|
||||
`WorkshopRefasterRulesTest` class where you can enable tests. Per assignment
|
||||
there is a test in this class that you 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 explain what needs to happen.
|
||||
* Find the test case 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.
|
||||
|
||||
### Tips and tricks
|
||||
|
||||
If you are working from the command line, it is suggested to run commands in
|
||||
the `workshop` directory. To do this, navigate to the root of the repository
|
||||
and run:
|
||||
|
||||
```bash
|
||||
cd workshop
|
||||
```
|
||||
|
||||
In case you want to do a fast build to just compile the project, run:
|
||||
|
||||
```bash
|
||||
mvn clean install -DskipTests -Dverification.skip
|
||||
```
|
||||
|
||||
In case you want to run one test from the command line, run the following
|
||||
commands:
|
||||
|
||||
```bash
|
||||
mvn clean install -Dtest=WorkshopRefasterRulesTest -Dverification.skip
|
||||
```
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
Make sure to use the latest version of JDK 21 or 17.
|
||||
|
||||
In some specific cases the `-Dverification.skip` is not correctly processed. In
|
||||
that case, use `-D"verification.skip"`.
|
||||
|
||||
In case there is an error mentioning the `BetaApi` check, please rebuild or try
|
||||
to `Reload All Maven projects`.
|
||||
|
||||
|
||||
[eps-github]: https://github.com/PicnicSupermarket/error-prone-support
|
||||
|
||||
[eps-workshop-slides]: https://docs.google.com/presentation/d/16MnDk6eW5dxKrLfG7TNUKAX-UVDJwbMz55UvKUkzeHc/edit?usp=sharing
|
||||
155
workshop/pom.xml
Normal file
155
workshop/pom.xml
Normal file
@@ -0,0 +1,155 @@
|
||||
<?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.22.1-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>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_annotation</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_annotations</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_check_api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</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>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</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
|
||||
boolean before(String str) {
|
||||
return str.length() == 0;
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
boolean after(String str) {
|
||||
return str.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,18 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/** Refaster rules for the second assignment of the workshop. */
|
||||
@SuppressWarnings("UnusedTypeParameter" /* Ignore this for demo purposes. */)
|
||||
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> {
|
||||
// XXX: Implement this Refaster rule, preferably by using only one `@BeforeTemplate`.
|
||||
// Tip: use the type argument.
|
||||
}
|
||||
}
|
||||
@@ -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 Assignment0DeleteEmptyMethodTest {
|
||||
@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,42 @@
|
||||
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);
|
||||
}
|
||||
|
||||
@Disabled("Needs to be implemented in `WorkshopAssignment1Rules.java`.")
|
||||
@Test
|
||||
void validateFirstWorkshopAssignment() {
|
||||
RefasterRuleCollection.validate(WorkshopAssignment1Rules.class);
|
||||
}
|
||||
|
||||
@Disabled("Needs to be implemented in `WorkshopAssignment2Rules.java`.")
|
||||
@Test
|
||||
void validateSecondWorkshopAssignment() {
|
||||
RefasterRuleCollection.validate(WorkshopAssignment2Rules.class);
|
||||
}
|
||||
|
||||
@Disabled("Needs to be implemented in `WorkshopAssignment3Rules.java`.")
|
||||
@Test
|
||||
void validateThirdWorkshopAssignment() {
|
||||
RefasterRuleCollection.validate(WorkshopAssignment3Rules.class);
|
||||
}
|
||||
|
||||
@Disabled("Needs to be implemented in `WorkshopAssignment4Rules.java`.")
|
||||
@Test
|
||||
void validateFourthWorkshopAssignment() {
|
||||
RefasterRuleCollection.validate(WorkshopAssignment4Rules.class);
|
||||
}
|
||||
|
||||
@Disabled("Needs to be implemented in `WorkshopAssignment5Rules.java`.")
|
||||
@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,25 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class WorkshopAssignment3RulesTest implements RefasterRuleCollectionTestCase {
|
||||
void testCheckArgumentWithoutMessage() {
|
||||
if (!"foo".isEmpty()) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (!ThreadLocalRandom.current().nextBoolean()) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
void testCheckArgumentWithMessage() {
|
||||
if (!"foo".isEmpty()) {
|
||||
throw new IllegalArgumentException("The string is not empty");
|
||||
}
|
||||
if (!ThreadLocalRandom.current().nextBoolean()) {
|
||||
throw new IllegalArgumentException(
|
||||
"The rule should be able rewrite all kinds of messages ;).");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package tech.picnic.errorprone.workshop.refasterrules;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class WorkshopAssignment3RulesTest implements RefasterRuleCollectionTestCase {
|
||||
void testCheckArgumentWithoutMessage() {
|
||||
checkArgument("foo".isEmpty());
|
||||
checkArgument(ThreadLocalRandom.current().nextBoolean());
|
||||
}
|
||||
|
||||
void testCheckArgumentWithMessage() {
|
||||
checkArgument("foo".isEmpty(), "The string is not empty");
|
||||
checkArgument(
|
||||
ThreadLocalRandom.current().nextBoolean(),
|
||||
"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