Compare commits

...

7 Commits

Author SHA1 Message Date
Stephan Schroevers
36654883e5 [maven-release-plugin] prepare release v0.2.0 2022-08-23 08:33:02 +02:00
Picnic-Bot
d5372934ec Upgrade pitest-maven-plugin 1.9.4 -> 1.9.5 (#211)
See:
- https://github.com/hcoles/pitest/releases/tag/1.9.5
- https://github.com/hcoles/pitest/compare/1.9.4...1.9.5
2022-08-23 07:55:01 +02:00
Stephan Schroevers
f810530599 Fix several RxJava2Adapter Refaster templates (#205)
This reverts some changes from d2bbee3ed9
and instead drops some invalid `Flowable#compose` and `Flux#transform`
rewrite rules.
2022-08-22 11:05:24 +02:00
Stephan Schroevers
6928381403 Drop unnecessary dependency declarations (#208) 2022-08-22 10:49:40 +02:00
Stephan Schroevers
5657a48552 Prefer String#valueOf over Objects#toString (#192)
While there, drop obsolete `NoFunctionalReturnType` warning suppressions.
2022-08-22 10:29:23 +02:00
Stephan Schroevers
50aaf77a9e Enable nohttp-checkstyle (#206)
While this Checkstyle configuration only flags `http://` usages in
Maven-managed source files (thus not in e.g. `pom.xml` or `README.md`
files), this is a low-effort improvement.
2022-08-22 09:39:19 +02:00
Cernat Catalin Stefan
b8e22ffef0 Introduce NonEmptyMono check (#200) 2022-08-20 12:47:56 +02:00
17 changed files with 349 additions and 84 deletions

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.1.1-SNAPSHOT</version>
<version>0.2.0</version>
</parent>
<artifactId>error-prone-contrib</artifactId>
@@ -128,11 +128,6 @@
<artifactId>jaxb-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>

View File

@@ -0,0 +1,91 @@
package tech.picnic.errorprone.bugpatterns;
import static com.google.errorprone.BugPattern.LinkType.NONE;
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 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.MethodInvocationTreeMatcher;
import com.google.errorprone.fixes.SuggestedFix;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.matchers.Matcher;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.MethodInvocationTree;
import java.util.function.BiFunction;
import reactor.core.publisher.Mono;
import tech.picnic.errorprone.bugpatterns.util.SourceCode;
/**
* A {@link BugChecker} which flags {@link Mono} operations that are known to be vacuous, given that
* they are invoked on a {@link Mono} that is known not to complete empty.
*/
@AutoService(BugChecker.class)
@BugPattern(
summary = "Avoid vacuous operations on known non-empty `Mono`s",
linkType = NONE,
severity = WARNING,
tags = SIMPLIFICATION)
// XXX: This check does not simplify `someFlux.defaultIfEmpty(T).{defaultIfEmpty(T),hasElements()}`,
// as `someFlux.defaultIfEmpty(T)` yields a `Flux` rather than a `Mono`. Consider adding support for
// these cases.
// XXX: Given more advanced analysis many more expressions could be flagged. Consider
// `Mono.just(someValue)`, `Flux.just(someNonEmptySequence)`,
// `someMono.switchIfEmpty(someProvablyNonEmptyMono)` and many other variants.
// XXX: Consider implementing a similar check for `Publisher`s that are known to complete without
// emitting a value (e.g. `Mono.empty()`, `someFlux.then()`, ...), or known not to complete normally
// (`Mono.never()`, `someFlux.repeat()`, `Mono.error(...)`, ...). The latter category could
// potentially be split out further.
public final class NonEmptyMono extends BugChecker implements MethodInvocationTreeMatcher {
private static final long serialVersionUID = 1L;
private static final Matcher<ExpressionTree> MONO_SIZE_CHECK =
instanceMethod()
.onDescendantOf("reactor.core.publisher.Mono")
.namedAnyOf("defaultIfEmpty", "single", "switchIfEmpty");
private static final Matcher<ExpressionTree> NON_EMPTY_MONO =
anyOf(
instanceMethod()
.onDescendantOf("reactor.core.publisher.Flux")
.namedAnyOf(
"all",
"any",
"collect",
"collectList",
"collectMap",
"collectMultimap",
"collectSortedList",
"count",
"elementAt",
"hasElement",
"hasElements",
"last",
"reduceWith",
"single"),
instanceMethod()
.onDescendantOf("reactor.core.publisher.Flux")
.named("reduce")
.withParameters(Object.class.getName(), BiFunction.class.getName()),
instanceMethod()
.onDescendantOf("reactor.core.publisher.Mono")
.namedAnyOf("defaultIfEmpty", "hasElement", "single"));
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
if (!MONO_SIZE_CHECK.matches(tree, state)) {
return Description.NO_MATCH;
}
ExpressionTree receiver = ASTHelpers.getReceiver(tree);
if (!NON_EMPTY_MONO.matches(receiver, state)) {
return Description.NO_MATCH;
}
return describeMatch(
tree, SuggestedFix.replace(tree, SourceCode.treeToString(receiver, state)));
}
}

View File

@@ -41,13 +41,11 @@ final class EqualityTemplates {
// non-null.
static final class EqualsPredicate<T> {
@BeforeTemplate
@SuppressWarnings("NoFunctionalReturnType")
Predicate<T> before(T v) {
return e -> v.equals(e);
}
@AfterTemplate
@SuppressWarnings("NoFunctionalReturnType")
Predicate<T> after(T v) {
return v::equals;
}

View File

@@ -33,13 +33,11 @@ final class NullTemplates {
/** Prefer {@link Objects#isNull(Object)} over the equivalent lambda function. */
static final class IsNullFunction<T> {
@BeforeTemplate
@SuppressWarnings("NoFunctionalReturnType")
Predicate<T> before() {
return o -> o == null;
}
@AfterTemplate
@SuppressWarnings("NoFunctionalReturnType")
Predicate<T> after() {
return Objects::isNull;
}
@@ -48,13 +46,11 @@ final class NullTemplates {
/** Prefer {@link Objects#nonNull(Object)} over the equivalent lambda function. */
static final class NonNullFunction<T> {
@BeforeTemplate
@SuppressWarnings("NoFunctionalReturnType")
Predicate<T> before() {
return o -> o != null;
}
@AfterTemplate
@SuppressWarnings("NoFunctionalReturnType")
Predicate<T> after() {
return Objects::nonNull;
}

View File

@@ -81,13 +81,11 @@ final class OptionalTemplates {
// generalization. If/when Refaster is extended to understand this, delete the template above.
static final class OptionalOrElseThrowMethodReference<T> {
@BeforeTemplate
@SuppressWarnings("NoFunctionalReturnType")
Function<Optional<T>, T> before() {
return Optional::get;
}
@AfterTemplate
@SuppressWarnings("NoFunctionalReturnType")
Function<Optional<T>, T> after() {
return Optional::orElseThrow;
}

View File

@@ -9,7 +9,6 @@ import io.reactivex.Flowable;
import io.reactivex.Maybe;
import io.reactivex.Observable;
import io.reactivex.Single;
import org.reactivestreams.Publisher;
import reactor.adapter.rxjava.RxJava2Adapter;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -39,12 +38,12 @@ final class RxJava2AdapterTemplates {
*/
static final class FlowableToFlux<T> {
@BeforeTemplate
Publisher<T> before(Flowable<T> flowable) {
Flux<T> before(Flowable<T> flowable) {
return Refaster.anyOf(
flowable.compose(Flux::from),
Flux.from(flowable),
flowable.to(Flux::from),
flowable.as(Flux::from),
flowable.compose(RxJava2Adapter::flowableToFlux),
RxJava2Adapter.flowableToFlux(flowable),
flowable.to(RxJava2Adapter::flowableToFlux));
}
@@ -60,12 +59,11 @@ final class RxJava2AdapterTemplates {
*/
static final class FluxToFlowable<T> {
@BeforeTemplate
Publisher<T> before(Flux<T> flux) {
Flowable<T> before(Flux<T> flux) {
return Refaster.anyOf(
Flowable.fromPublisher(flux),
flux.transform(Flowable::fromPublisher),
flux.as(Flowable::fromPublisher),
flux.transform(RxJava2Adapter::fluxToFlowable));
RxJava2Adapter.fluxToFlowable(flux));
}
@AfterTemplate
@@ -132,12 +130,11 @@ final class RxJava2AdapterTemplates {
*/
static final class MonoToFlowable<T> {
@BeforeTemplate
Publisher<T> before(Mono<T> mono) {
Flowable<T> before(Mono<T> mono) {
return Refaster.anyOf(
Flowable.fromPublisher(mono),
mono.transform(Flowable::fromPublisher),
mono.as(Flowable::fromPublisher),
mono.transform(RxJava2Adapter::monoToFlowable));
RxJava2Adapter.monoToFlowable(mono));
}
@AfterTemplate

View File

@@ -13,7 +13,9 @@ import com.google.errorprone.refaster.annotation.AlsoNegation;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import java.util.Arrays;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import javax.annotation.Nullable;
/** Refaster templates related to expressions dealing with {@link String}s. */
@@ -106,6 +108,40 @@ final class StringTemplates {
}
}
/**
* Prefer direct invocation of {@link String#valueOf(Object)} over the indirection introduced by
* {@link Objects#toString(Object)}.
*/
static final class StringValueOf {
@BeforeTemplate
String before(Object object) {
return Objects.toString(object);
}
@AfterTemplate
String after(Object object) {
return String.valueOf(object);
}
}
/**
* Prefer direct delegation to {@link String#valueOf(Object)} over the indirection introduced by
* {@link Objects#toString(Object)}.
*/
// XXX: This template is analogous to `StringValueOf` above. Arguably this is its generalization.
// If/when Refaster is extended to understand this, delete the template above.
static final class StringValueOfMethodReference<T> {
@BeforeTemplate
Function<Object, String> before() {
return Objects::toString;
}
@AfterTemplate
Function<Object, String> after() {
return String::valueOf;
}
}
/** Don't unnecessarily use the two-argument {@link String#substring(int, int)}. */
static final class SubstringRemainder {
@BeforeTemplate

View File

@@ -0,0 +1,155 @@
package tech.picnic.errorprone.bugpatterns;
import static com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode.TEXT_MATCH;
import com.google.errorprone.BugCheckerRefactoringTestHelper;
import com.google.errorprone.CompilationTestHelper;
import org.junit.jupiter.api.Test;
final class NonEmptyMonoTest {
private final CompilationTestHelper compilationTestHelper =
CompilationTestHelper.newInstance(NonEmptyMono.class, getClass());
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
BugCheckerRefactoringTestHelper.newInstance(NonEmptyMono.class, getClass());
@Test
void identification() {
compilationTestHelper
.addSourceLines(
"A.java",
"import static com.google.common.collect.ImmutableList.toImmutableList;",
"import static java.util.function.Function.identity;",
"",
"import com.google.common.collect.ImmutableList;",
"import com.google.common.collect.ImmutableMap;",
"import java.util.ArrayList;",
"import java.util.HashMap;",
"import java.util.List;",
"import reactor.core.publisher.Flux;",
"import reactor.core.publisher.Mono;",
"",
"class A {",
" void m() {",
" Mono.just(1).defaultIfEmpty(2);",
" Mono.just(1).single();",
" Mono.just(1).switchIfEmpty(Mono.just(2));",
"",
" // BUG: Diagnostic contains:",
" Flux.just(1).all(x -> true).defaultIfEmpty(true);",
"",
" // BUG: Diagnostic contains:",
" Flux.just(1).any(x -> true).single();",
"",
" // BUG: Diagnostic contains:",
" Flux.just(1).collect(toImmutableList()).switchIfEmpty(Mono.just(ImmutableList.of()));",
" // BUG: Diagnostic contains:",
" Flux.just(1).collect(ArrayList::new, List::add).defaultIfEmpty(new ArrayList<>());",
"",
" // BUG: Diagnostic contains:",
" Flux.just(1).collectList().single();",
"",
" // BUG: Diagnostic contains:",
" Flux.just(1).collectMap(identity()).switchIfEmpty(Mono.just(ImmutableMap.of()));",
" // BUG: Diagnostic contains:",
" Flux.just(1).collectMap(identity(), identity()).defaultIfEmpty(ImmutableMap.of());",
" // BUG: Diagnostic contains:",
" Flux.just(1).collectMap(identity(), identity(), HashMap::new).single();",
"",
" // BUG: Diagnostic contains:",
" Flux.just(1).collectMultimap(identity()).switchIfEmpty(Mono.just(ImmutableMap.of()));",
" // BUG: Diagnostic contains:",
" Flux.just(1).collectMultimap(identity(), identity()).defaultIfEmpty(ImmutableMap.of());",
" // BUG: Diagnostic contains:",
" Flux.just(1).collectMultimap(identity(), identity(), HashMap::new).single();",
"",
" // BUG: Diagnostic contains:",
" Flux.just(1).collectSortedList().defaultIfEmpty(ImmutableList.of());",
" // BUG: Diagnostic contains:",
" Flux.just(1).collectSortedList((o1, o2) -> 0).single();",
"",
" // BUG: Diagnostic contains:",
" Flux.just(1).count().switchIfEmpty(Mono.just(2L));",
"",
" // BUG: Diagnostic contains:",
" Flux.just(1).elementAt(0).defaultIfEmpty(1);",
" // BUG: Diagnostic contains:",
" Flux.just(1).elementAt(0, 2).single();",
"",
" // BUG: Diagnostic contains:",
" Flux.just(1).hasElement(2).switchIfEmpty(Mono.just(true));",
"",
" // BUG: Diagnostic contains:",
" Flux.just(1).hasElements().defaultIfEmpty(true);",
"",
" // BUG: Diagnostic contains:",
" Flux.just(1).last().single();",
" // BUG: Diagnostic contains:",
" Flux.just(1).last(2).switchIfEmpty(Mono.just(3));",
"",
" // BUG: Diagnostic contains:",
" Flux.just(1).reduceWith(() -> 0, Integer::sum).defaultIfEmpty(2);",
"",
" // BUG: Diagnostic contains:",
" Flux.just(1).single().single();",
" // BUG: Diagnostic contains:",
" Flux.just(1).single(2).switchIfEmpty(Mono.just(3));",
"",
" Flux.just(1).reduce(Integer::sum).defaultIfEmpty(2);",
" // BUG: Diagnostic contains:",
" Flux.just(1).reduce(2, Integer::sum).single();",
"",
" // BUG: Diagnostic contains:",
" Mono.just(1).defaultIfEmpty(1).switchIfEmpty(Mono.just(2));",
" // BUG: Diagnostic contains:",
" Mono.just(1).hasElement().defaultIfEmpty(true);",
" // BUG: Diagnostic contains:",
" Mono.just(1).single().single();",
" }",
"}")
.doTest();
}
@Test
void replacement() {
refactoringTestHelper
.addInputLines(
"A.java",
"import static com.google.common.collect.ImmutableList.toImmutableList;",
"",
"import com.google.common.collect.ImmutableList;",
"import reactor.core.publisher.Flux;",
"import reactor.core.publisher.Mono;",
"",
"class A {",
" void m() {",
" Flux.just(1).collect(toImmutableList()).single();",
" Flux.just(1).collect(toImmutableList()).defaultIfEmpty(ImmutableList.of());",
" Flux.just(1).collect(toImmutableList()).switchIfEmpty(Mono.just(ImmutableList.of()));",
"",
" Mono.just(2).hasElement().single();",
" Mono.just(2).hasElement().defaultIfEmpty(true);",
" Mono.just(2).hasElement().switchIfEmpty(Mono.just(true));",
" }",
"}")
.addOutputLines(
"A.java",
"import static com.google.common.collect.ImmutableList.toImmutableList;",
"",
"import com.google.common.collect.ImmutableList;",
"import reactor.core.publisher.Flux;",
"import reactor.core.publisher.Mono;",
"",
"class A {",
" void m() {",
" Flux.just(1).collect(toImmutableList());",
" Flux.just(1).collect(toImmutableList());",
" Flux.just(1).collect(toImmutableList());",
"",
" Mono.just(2).hasElement();",
" Mono.just(2).hasElement();",
" Mono.just(2).hasElement();",
" }",
"}")
.doTest(TEXT_MATCH);
}
}

View File

@@ -7,8 +7,6 @@ import io.reactivex.Flowable;
import io.reactivex.Maybe;
import io.reactivex.Observable;
import io.reactivex.Single;
import java.util.Arrays;
import org.reactivestreams.Publisher;
import reactor.adapter.rxjava.RxJava2Adapter;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -21,24 +19,20 @@ final class RxJava2AdapterTemplatesTest implements RefasterTemplateTestCase {
Completable.complete().to(RxJava2Adapter::completableToMono));
}
ImmutableSet<Publisher<Integer>> testFlowableToFlux() {
// The `Arrays.asList` is to avoid confusing `javac`; `ImmutableSet.of` uses varargs from the
// seventh parameter onwards.
return ImmutableSet.copyOf(
Arrays.asList(
Flowable.just(1).compose(Flux::from),
Flowable.just(2).to(Flux::from),
Flowable.just(3).as(Flux::from),
Flowable.just(4).compose(RxJava2Adapter::flowableToFlux),
Flowable.just(5).<Publisher<Integer>>to(RxJava2Adapter::flowableToFlux)));
ImmutableSet<Flux<Integer>> testFlowableToFlux() {
return ImmutableSet.of(
Flux.from(Flowable.just(1)),
Flowable.just(2).to(Flux::from),
Flowable.just(3).as(Flux::from),
RxJava2Adapter.flowableToFlux(Flowable.just(4)),
Flowable.just(5).to(RxJava2Adapter::flowableToFlux));
}
ImmutableSet<Publisher<String>> testFluxToFlowable() {
ImmutableSet<Flowable<String>> testFluxToFlowable() {
return ImmutableSet.of(
Flowable.fromPublisher(Flux.just("foo")),
Flux.just("bar").transform(Flowable::fromPublisher),
Flux.just("baz").as(Flowable::fromPublisher),
Flux.just("qux").transform(RxJava2Adapter::fluxToFlowable));
Flux.just("bar").as(Flowable::fromPublisher),
RxJava2Adapter.fluxToFlowable(Flux.just("baz")));
}
ImmutableSet<Observable<Integer>> testFluxToObservable() {
@@ -61,12 +55,11 @@ final class RxJava2AdapterTemplatesTest implements RefasterTemplateTestCase {
RxJava2Adapter.monoToCompletable(Mono.empty()));
}
ImmutableSet<Publisher<Integer>> testMonoToFlowable() {
ImmutableSet<Flowable<Integer>> testMonoToFlowable() {
return ImmutableSet.of(
Flowable.fromPublisher(Mono.just(1)),
Mono.just(2).transform(Flowable::fromPublisher),
Mono.just(3).as(Flowable::fromPublisher),
Mono.just(4).transform(RxJava2Adapter::monoToFlowable));
Mono.just(2).as(Flowable::fromPublisher),
RxJava2Adapter.monoToFlowable(Mono.just(3)));
}
Maybe<String> testMonoToMaybe() {

View File

@@ -7,8 +7,6 @@ import io.reactivex.Flowable;
import io.reactivex.Maybe;
import io.reactivex.Observable;
import io.reactivex.Single;
import java.util.Arrays;
import org.reactivestreams.Publisher;
import reactor.adapter.rxjava.RxJava2Adapter;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -21,24 +19,20 @@ final class RxJava2AdapterTemplatesTest implements RefasterTemplateTestCase {
Completable.complete().as(RxJava2Adapter::completableToMono));
}
ImmutableSet<Publisher<Integer>> testFlowableToFlux() {
// The `Arrays.asList` is to avoid confusing `javac`; `ImmutableSet.of` uses varargs from the
// seventh parameter onwards.
return ImmutableSet.copyOf(
Arrays.asList(
Flowable.just(1).as(RxJava2Adapter::flowableToFlux),
Flowable.just(2).as(RxJava2Adapter::flowableToFlux),
Flowable.just(3).as(RxJava2Adapter::flowableToFlux),
Flowable.just(4).as(RxJava2Adapter::flowableToFlux),
Flowable.just(5).as(RxJava2Adapter::flowableToFlux)));
ImmutableSet<Flux<Integer>> testFlowableToFlux() {
return ImmutableSet.of(
Flowable.just(1).as(RxJava2Adapter::flowableToFlux),
Flowable.just(2).as(RxJava2Adapter::flowableToFlux),
Flowable.just(3).as(RxJava2Adapter::flowableToFlux),
Flowable.just(4).as(RxJava2Adapter::flowableToFlux),
Flowable.just(5).as(RxJava2Adapter::flowableToFlux));
}
ImmutableSet<Publisher<String>> testFluxToFlowable() {
ImmutableSet<Flowable<String>> testFluxToFlowable() {
return ImmutableSet.of(
Flux.just("foo").as(RxJava2Adapter::fluxToFlowable),
Flux.just("bar").as(RxJava2Adapter::fluxToFlowable),
Flux.just("baz").as(RxJava2Adapter::fluxToFlowable),
Flux.just("qux").as(RxJava2Adapter::fluxToFlowable));
Flux.just("baz").as(RxJava2Adapter::fluxToFlowable));
}
ImmutableSet<Observable<Integer>> testFluxToObservable() {
@@ -61,12 +55,11 @@ final class RxJava2AdapterTemplatesTest implements RefasterTemplateTestCase {
Mono.empty().as(RxJava2Adapter::monoToCompletable));
}
ImmutableSet<Publisher<Integer>> testMonoToFlowable() {
ImmutableSet<Flowable<Integer>> testMonoToFlowable() {
return ImmutableSet.of(
Mono.just(1).as(RxJava2Adapter::monoToFlowable),
Mono.just(2).as(RxJava2Adapter::monoToFlowable),
Mono.just(3).as(RxJava2Adapter::monoToFlowable),
Mono.just(4).as(RxJava2Adapter::monoToFlowable));
Mono.just(3).as(RxJava2Adapter::monoToFlowable));
}
Maybe<String> testMonoToMaybe() {

View File

@@ -10,7 +10,9 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Streams;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.test.RefasterTemplateTestCase;
@@ -18,7 +20,7 @@ final class StringTemplatesTest implements RefasterTemplateTestCase {
@Override
public ImmutableSet<?> elidedTypesAndStaticImports() {
return ImmutableSet.of(
Arrays.class, Joiner.class, Stream.class, Streams.class, joining(), UTF_8);
Arrays.class, Joiner.class, Objects.class, Stream.class, Streams.class, joining(), UTF_8);
}
ImmutableSet<Boolean> testStringIsEmpty() {
@@ -59,6 +61,14 @@ final class StringTemplatesTest implements RefasterTemplateTestCase {
ImmutableList.of("foo", "bar").stream().collect(joining("f")));
}
String testStringValueOf() {
return Objects.toString("foo");
}
Function<Object, String> testStringValueOfMethodReference() {
return Objects::toString;
}
String testSubstringRemainder() {
return "foo".substring(1, "foo".length());
}

View File

@@ -11,7 +11,9 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Streams;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.test.RefasterTemplateTestCase;
@@ -19,7 +21,7 @@ final class StringTemplatesTest implements RefasterTemplateTestCase {
@Override
public ImmutableSet<?> elidedTypesAndStaticImports() {
return ImmutableSet.of(
Arrays.class, Joiner.class, Stream.class, Streams.class, joining(), UTF_8);
Arrays.class, Joiner.class, Objects.class, Stream.class, Streams.class, joining(), UTF_8);
}
ImmutableSet<Boolean> testStringIsEmpty() {
@@ -59,6 +61,14 @@ final class StringTemplatesTest implements RefasterTemplateTestCase {
String.join("f", ImmutableList.of("foo", "bar")));
}
String testStringValueOf() {
return String.valueOf("foo");
}
Function<Object, String> testStringValueOfMethodReference() {
return String::valueOf;
}
String testSubstringRemainder() {
return "foo".substring(1);
}

25
pom.xml
View File

@@ -4,7 +4,7 @@
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.1.1-SNAPSHOT</version>
<version>0.2.0</version>
<packaging>pom</packaging>
<name>Picnic :: Error Prone Support</name>
@@ -48,7 +48,7 @@
<scm>
<developerConnection>scm:git:git@github.com:PicnicSupermarket/error-prone-support.git</developerConnection>
<tag>HEAD</tag>
<tag>v0.2.0</tag>
<url>https://github.com/PicnicSupermarket/error-prone-support</url>
</scm>
<issueManagement>
@@ -147,7 +147,6 @@
<version.error-prone-fork>v${version.error-prone-orig}-picnic-2</version.error-prone-fork>
<version.error-prone-orig>2.14.0</version.error-prone-orig>
<version.error-prone-slf4j>0.1.13</version.error-prone-slf4j>
<version.findbugs-format-string>3.0.0</version.findbugs-format-string>
<version.guava-beta-checker>1.0</version.guava-beta-checker>
<version.jdk>11</version.jdk>
<version.maven>3.8.6</version.maven>
@@ -240,13 +239,6 @@
<artifactId>auto-value-annotations</artifactId>
<version>${version.auto-value}</version>
</dependency>
<!-- Specified as a workaround for
https://github.com/mojohaus/versions-maven-plugin/issues/244. -->
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jFormatString</artifactId>
<version>${version.findbugs-format-string}</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
@@ -405,11 +397,6 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.reactivestreams</groupId>
<artifactId>reactive-streams</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
@@ -746,6 +733,7 @@
<module name="VisibilityModifier" />
</module>
<module name="UniqueProperties" />
<module name="io.spring.nohttp.checkstyle.check.NoHttpCheck" />
</module>
</checkstyleRules>
<failOnViolation>false</failOnViolation>
@@ -771,6 +759,11 @@
<artifactId>checkstyle</artifactId>
<version>10.3.2</version>
</dependency>
<dependency>
<groupId>io.spring.nohttp</groupId>
<artifactId>nohttp-checkstyle</artifactId>
<version>0.0.10</version>
</dependency>
</dependencies>
<executions>
<execution>
@@ -1245,7 +1238,7 @@
<plugin>
<groupId>org.pitest</groupId>
<artifactId>pitest-maven</artifactId>
<version>1.9.4</version>
<version>1.9.5</version>
<configuration>
<!-- Use multiple threads to speed things up. Extend
timeouts to prevent false positives as a result of

View File

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

View File

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

View File

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

View File

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