From 6d70c51bc8cba13d6811d52cd89bffb54d1da6ee Mon Sep 17 00:00:00 2001 From: Stephan Schroevers Date: Sun, 13 Nov 2022 14:21:14 +0100 Subject: [PATCH] Use text blocks --- .../bugpatterns/AmbiguousJsonCreatorTest.java | 232 +-- .../bugpatterns/AssertJIsNullTest.java | 70 +- .../bugpatterns/AutowiredConstructorTest.java | 162 +- .../CanonicalAnnotationSyntaxTest.java | 492 +++--- .../bugpatterns/CollectorMutabilityTest.java | 340 ++-- .../bugpatterns/EmptyMethodTest.java | 112 +- .../ErrorProneTestHelperSourceFormatTest.java | 544 +++---- .../bugpatterns/ExplicitEnumOrderingTest.java | 138 +- .../bugpatterns/FluxFlatMapUsageTest.java | 204 +-- .../FormatStringConcatenationTest.java | 770 ++++----- .../bugpatterns/IdentityConversionTest.java | 526 +++---- .../ImmutablesSortedSetComparatorTest.java | 292 ++-- .../IsInstanceLambdaUsageTest.java | 52 +- .../JUnitMethodDeclarationTest.java | 784 +++++----- ...aphicalAnnotationAttributeListingTest.java | 492 +++--- .../LexicographicalAnnotationListingTest.java | 544 +++---- .../bugpatterns/MethodReferenceUsageTest.java | 816 +++++----- .../MissingRefasterAnnotationTest.java | 142 +- .../bugpatterns/MockitoStubbingTest.java | 154 +- .../bugpatterns/NestedOptionalsTest.java | 52 +- .../bugpatterns/NonEmptyMonoTest.java | 252 +-- .../bugpatterns/PrimitiveComparisonTest.java | 1370 +++++++++-------- .../RedundantStringConversionTest.java | 912 +++++------ .../bugpatterns/RefasterAnyOfUsageTest.java | 80 +- .../RefasterRuleModifiersTest.java | 350 +++-- .../RequestMappingAnnotationTest.java | 240 +-- .../bugpatterns/RequestParamTypeTest.java | 100 +- .../ScheduledTransactionTraceTest.java | 146 +- .../bugpatterns/Slf4jLogStatementTest.java | 238 +-- .../bugpatterns/SpringMvcAnnotationTest.java | 250 +-- .../bugpatterns/StaticImportTest.java | 452 +++--- .../bugpatterns/StringJoinTest.java | 128 +- .../bugpatterns/TimeZoneUsageTest.java | 210 +-- .../util/MethodMatcherFactoryTest.java | 286 ++-- .../bugpatterns/util/MoreTypesTest.java | 172 ++- .../util/ThirdPartyLibraryTest.java | 50 +- .../refaster/runner/RefasterTest.java | 120 +- .../refaster/ErrorProneForkTest.java | 12 +- .../refaster/matchers/IsArrayTest.java | 66 +- .../refaster/matchers/IsCharacterTest.java | 66 +- .../matchers/ThrowsCheckedExceptionTest.java | 128 +- 41 files changed, 6426 insertions(+), 6120 deletions(-) diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/AmbiguousJsonCreatorTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/AmbiguousJsonCreatorTest.java index f5a7b641ad6..b0ac04258d8 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/AmbiguousJsonCreatorTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/AmbiguousJsonCreatorTest.java @@ -20,99 +20,101 @@ void identification() { compilationTestHelper .addSourceLines( "Container.java", - "import com.fasterxml.jackson.annotation.JsonCreator;", - "import com.fasterxml.jackson.annotation.JsonValue;", - "", - "interface Container {", - " enum A {", - " FOO(1);", - "", - " private final int i;", - "", - " A(int i) {", - " this.i = i;", - " }", - "", - " // BUG: Diagnostic matches: X", - " @JsonCreator", - " public static A of(int i) {", - " return FOO;", - " }", - " }", - "", - " enum B {", - " FOO(1);", - "", - " private final int i;", - "", - " B(int i) {", - " this.i = i;", - " }", - "", - " @JsonCreator(mode = JsonCreator.Mode.DELEGATING)", - " public static B of(int i) {", - " return FOO;", - " }", - " }", - "", - " enum C {", - " FOO(1, \"s\");", - "", - " @JsonValue private final int i;", - " private final String s;", - "", - " C(int i, String s) {", - " this.i = i;", - " this.s = s;", - " }", - "", - " // BUG: Diagnostic matches: X", - " @JsonCreator", - " public static C of(int i) {", - " return FOO;", - " }", - " }", - "", - " enum D {", - " FOO(1, \"s\");", - "", - " private final int i;", - " private final String s;", - "", - " D(int i, String s) {", - " this.i = i;", - " this.s = s;", - " }", - "", - " @JsonCreator", - " public static D of(int i, String s) {", - " return FOO;", - " }", - " }", - "", - " enum E {", - " FOO;", - "", - " // BUG: Diagnostic matches: X", - " @JsonCreator", - " public static E of(String s) {", - " return FOO;", - " }", - " }", - "", - " class F {", - " private final String s;", - "", - " F(String s) {", - " this.s = s;", - " }", - "", - " @JsonCreator", - " public static F of(String s) {", - " return new F(s);", - " }", - " }", - "}") + """ + import com.fasterxml.jackson.annotation.JsonCreator; + import com.fasterxml.jackson.annotation.JsonValue; + + interface Container { + enum A { + FOO(1); + + private final int i; + + A(int i) { + this.i = i; + } + + // BUG: Diagnostic matches: X + @JsonCreator + public static A of(int i) { + return FOO; + } + } + + enum B { + FOO(1); + + private final int i; + + B(int i) { + this.i = i; + } + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + public static B of(int i) { + return FOO; + } + } + + enum C { + FOO(1, "s"); + + @JsonValue private final int i; + private final String s; + + C(int i, String s) { + this.i = i; + this.s = s; + } + + // BUG: Diagnostic matches: X + @JsonCreator + public static C of(int i) { + return FOO; + } + } + + enum D { + FOO(1, "s"); + + private final int i; + private final String s; + + D(int i, String s) { + this.i = i; + this.s = s; + } + + @JsonCreator + public static D of(int i, String s) { + return FOO; + } + } + + enum E { + FOO; + + // BUG: Diagnostic matches: X + @JsonCreator + public static E of(String s) { + return FOO; + } + } + + class F { + private final String s; + + F(String s) { + this.s = s; + } + + @JsonCreator + public static F of(String s) { + return new F(s); + } + } + } + """) .doTest(); } @@ -121,28 +123,32 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "import com.fasterxml.jackson.annotation.JsonCreator;", - "", - "enum A {", - " FOO;", - "", - " @JsonCreator", - " public static A of(String s) {", - " return FOO;", - " }", - "}") + """ + import com.fasterxml.jackson.annotation.JsonCreator; + + enum A { + FOO; + + @JsonCreator + public static A of(String s) { + return FOO; + } + } + """) .addOutputLines( "A.java", - "import com.fasterxml.jackson.annotation.JsonCreator;", - "", - "enum A {", - " FOO;", - "", - " @JsonCreator(mode = JsonCreator.Mode.DELEGATING)", - " public static A of(String s) {", - " return FOO;", - " }", - "}") + """ + import com.fasterxml.jackson.annotation.JsonCreator; + + enum A { + FOO; + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + public static A of(String s) { + return FOO; + } + } + """) .doTest(BugCheckerRefactoringTestHelper.TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/AssertJIsNullTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/AssertJIsNullTest.java index a0f8242dfb4..0968bbd6c6f 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/AssertJIsNullTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/AssertJIsNullTest.java @@ -17,22 +17,24 @@ void identification() { compilationTestHelper .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\");", - " }", - "}") + """ + 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(); } @@ -41,24 +43,28 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "import static org.assertj.core.api.Assertions.assertThat;", - "", - "class A {", - " void m() {", - " assertThat(1).isEqualTo(null);", - " assertThat(\"foo\").isEqualTo(null);", - " }", - "}") + """ + 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();", - " }", - "}") + """ + import static org.assertj.core.api.Assertions.assertThat; + + class A { + void m() { + assertThat(1).isNull(); + assertThat("foo").isNull(); + } + } + """) .doTest(TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/AutowiredConstructorTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/AutowiredConstructorTest.java index 75d6fc21839..4c1eb823756 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/AutowiredConstructorTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/AutowiredConstructorTest.java @@ -16,56 +16,58 @@ void identification() { compilationTestHelper .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... lists) {}", - " }", - "}") + """ + 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... lists) {} + } + } + """) .doTest(); } @@ -77,36 +79,40 @@ void replacement() { refactoringTestHelper .addInputLines( "Container.java", - "import org.springframework.beans.factory.annotation.Autowired;", - "", - "interface Container {", - " class A {", - " @Autowired", - " @Deprecated", - " A() {}", - " }", - "", - " class B {", - " @Autowired", - " B(String x) {}", - " }", - "}") + """ + 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) {}", - " }", - "}") + """ + import org.springframework.beans.factory.annotation.Autowired; + + interface Container { + class A { + + @Deprecated + A() {} + } + + class B { + + B(String x) {} + } + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/CanonicalAnnotationSyntaxTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/CanonicalAnnotationSyntaxTest.java index e3c9b9e9242..55022bbb01a 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/CanonicalAnnotationSyntaxTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/CanonicalAnnotationSyntaxTest.java @@ -16,118 +16,120 @@ void identification() { compilationTestHelper .addSourceLines( "pkg/A.java", - "package pkg;", - "", - "import pkg.A.Foo;", - "", - "interface A {", - " @interface Foo {", - " int[] value() default {};", - "", - " int[] value2() default {};", - " }", - "", - " @pkg.A.Foo", - " A minimal1();", - "", - " @A.Foo", - " A minimal2();", - "", - " @Foo", - " A minimal3();", - "", - " // BUG: Diagnostic contains:", - " @pkg.A.Foo()", - " A functional1();", - " // BUG: Diagnostic contains:", - " @A.Foo()", - " A functional2();", - " // BUG: Diagnostic contains:", - " @Foo()", - " A functional3();", - "", - " @pkg.A.Foo(1)", - " A simple1();", - "", - " @A.Foo(1)", - " A simple2();", - "", - " @Foo(1)", - " A simple3();", - "", - " // BUG: Diagnostic contains:", - " @pkg.A.Foo({1})", - " A singleton1();", - " // BUG: Diagnostic contains:", - " @A.Foo({1})", - " A singleton2();", - " // BUG: Diagnostic contains:", - " @Foo({1})", - " A singleton3();", - "", - " // BUG: Diagnostic contains:", - " @pkg.A.Foo(value = 1)", - " A verbose1();", - " // BUG: Diagnostic contains:", - " @A.Foo(value = 1)", - " A verbose2();", - " // BUG: Diagnostic contains:", - " @Foo(value = 1)", - " A verbose3();", - "", - " @pkg.A.Foo(value2 = 2)", - " A custom1();", - "", - " @A.Foo(value2 = 2)", - " A custom2();", - "", - " @Foo(value2 = 2)", - " A custom3();", - "", - " // BUG: Diagnostic contains:", - " @pkg.A.Foo(value2 = {2})", - " A customSingleton1();", - " // BUG: Diagnostic contains:", - " @A.Foo(value2 = {2})", - " A customSingleton2();", - " // BUG: Diagnostic contains:", - " @Foo(value2 = {2})", - " A customSingleton3();", - "", - " @pkg.A.Foo(value2 = {2, 2})", - " A customPair1();", - "", - " @A.Foo(value2 = {2, 2})", - " A customPair2();", - "", - " @Foo(value2 = {2, 2})", - " A customPair3();", - "", - " @pkg.A.Foo(value = 1, value2 = 2)", - " A extended1();", - "", - " @A.Foo(value = 1, value2 = 2)", - " A extended2();", - "", - " @Foo(value = 1, value2 = 2)", - " A extended3();", - "", - " // BUG: Diagnostic contains:", - " @pkg.A.Foo({", - " 1, 1,", - " })", - " A trailingComma1();", - " // BUG: Diagnostic contains:", - " @A.Foo({", - " 1, 1,", - " })", - " A trailingComma2();", - " // BUG: Diagnostic contains:", - " @Foo({", - " 1, 1,", - " })", - " A trailingComma3();", - "}") + """ + package pkg; + + import pkg.A.Foo; + + interface A { + @interface Foo { + int[] value() default {}; + + int[] value2() default {}; + } + + @pkg.A.Foo + A minimal1(); + + @A.Foo + A minimal2(); + + @Foo + A minimal3(); + + // BUG: Diagnostic contains: + @pkg.A.Foo() + A functional1(); + // BUG: Diagnostic contains: + @A.Foo() + A functional2(); + // BUG: Diagnostic contains: + @Foo() + A functional3(); + + @pkg.A.Foo(1) + A simple1(); + + @A.Foo(1) + A simple2(); + + @Foo(1) + A simple3(); + + // BUG: Diagnostic contains: + @pkg.A.Foo({1}) + A singleton1(); + // BUG: Diagnostic contains: + @A.Foo({1}) + A singleton2(); + // BUG: Diagnostic contains: + @Foo({1}) + A singleton3(); + + // BUG: Diagnostic contains: + @pkg.A.Foo(value = 1) + A verbose1(); + // BUG: Diagnostic contains: + @A.Foo(value = 1) + A verbose2(); + // BUG: Diagnostic contains: + @Foo(value = 1) + A verbose3(); + + @pkg.A.Foo(value2 = 2) + A custom1(); + + @A.Foo(value2 = 2) + A custom2(); + + @Foo(value2 = 2) + A custom3(); + + // BUG: Diagnostic contains: + @pkg.A.Foo(value2 = {2}) + A customSingleton1(); + // BUG: Diagnostic contains: + @A.Foo(value2 = {2}) + A customSingleton2(); + // BUG: Diagnostic contains: + @Foo(value2 = {2}) + A customSingleton3(); + + @pkg.A.Foo(value2 = {2, 2}) + A customPair1(); + + @A.Foo(value2 = {2, 2}) + A customPair2(); + + @Foo(value2 = {2, 2}) + A customPair3(); + + @pkg.A.Foo(value = 1, value2 = 2) + A extended1(); + + @A.Foo(value = 1, value2 = 2) + A extended2(); + + @Foo(value = 1, value2 = 2) + A extended3(); + + // BUG: Diagnostic contains: + @pkg.A.Foo({ + 1, 1, + }) + A trailingComma1(); + // BUG: Diagnostic contains: + @A.Foo({ + 1, 1, + }) + A trailingComma2(); + // BUG: Diagnostic contains: + @Foo({ + 1, 1, + }) + A trailingComma3(); + } + """) .doTest(); } @@ -136,139 +138,143 @@ void replacement() { refactoringTestHelper .addInputLines( "pkg/A.java", - "package pkg;", - "", - "import pkg.A.Foo;", - "", - "interface A {", - " @interface Foo {", - " String[] value() default {};", - "", - " int[] value2() default {};", - " }", - "", - " @pkg.A.Foo()", - " A functional1();", - "", - " @A.Foo()", - " A functional2();", - "", - " @Foo()", - " A functional3();", - "", - " @pkg.A.Foo(value = \"foo\")", - " A verbose1();", - "", - " @A.Foo(value = \"a'b\")", - " A verbose2();", - "", - " @Foo(value = \"a\" + \"\\nb\")", - " A verbose3();", - "", - " @pkg.A.Foo(value = {\"foo\"})", - " A moreVerbose1();", - "", - " @A.Foo(value = {\"a'b\"})", - " A moreVerbose2();", - "", - " @Foo(value = {\"a\" + \"\\nb\"})", - " A moreVerbose3();", - "", - " @pkg.A.Foo(", - " value = {\"foo\", \"bar\"},", - " value2 = {2})", - " A extended1();", - "", - " @A.Foo(", - " value = {\"a'b\", \"c'd\"},", - " value2 = {2})", - " A extended2();", - "", - " @Foo(", - " value = {\"a\" + \"\\nb\", \"c\" + \"\\nd\"},", - " value2 = {2})", - " A extended3();", - "", - " @pkg.A.Foo({", - " \"foo\", \"bar\",", - " })", - " A trailingComma1();", - "", - " @A.Foo({", - " \"a'b\", \"c'd\",", - " })", - " A trailingComma2();", - "", - " @Foo({", - " \"a\" + \"\\nb\",", - " \"c\" + \"\\nd\",", - " })", - " A trailingComma3();", - "}") + """ + package pkg; + + import pkg.A.Foo; + + interface A { + @interface Foo { + String[] value() default {}; + + int[] value2() default {}; + } + + @pkg.A.Foo() + A functional1(); + + @A.Foo() + A functional2(); + + @Foo() + A functional3(); + + @pkg.A.Foo(value = "foo") + A verbose1(); + + @A.Foo(value = "a'b") + A verbose2(); + + @Foo(value = "a" + "\\nb") + A verbose3(); + + @pkg.A.Foo(value = {"foo"}) + A moreVerbose1(); + + @A.Foo(value = {"a'b"}) + A moreVerbose2(); + + @Foo(value = {"a" + "\\nb"}) + A moreVerbose3(); + + @pkg.A.Foo( + value = {"foo", "bar"}, + value2 = {2}) + A extended1(); + + @A.Foo( + value = {"a'b", "c'd"}, + value2 = {2}) + A extended2(); + + @Foo( + value = {"a" + "\\nb", "c" + "\\nd"}, + value2 = {2}) + A extended3(); + + @pkg.A.Foo({ + "foo", "bar", + }) + A trailingComma1(); + + @A.Foo({ + "a'b", "c'd", + }) + A trailingComma2(); + + @Foo({ + "a" + "\\nb", + "c" + "\\nd", + }) + A trailingComma3(); + } + """) .addOutputLines( "pkg/A.java", - "package pkg;", - "", - "import pkg.A.Foo;", - "", - "interface A {", - " @interface Foo {", - " String[] value() default {};", - "", - " int[] value2() default {};", - " }", - "", - " @pkg.A.Foo", - " A functional1();", - "", - " @A.Foo", - " A functional2();", - "", - " @Foo", - " A functional3();", - "", - " @pkg.A.Foo(\"foo\")", - " A verbose1();", - "", - " @A.Foo(\"a'b\")", - " A verbose2();", - "", - " @Foo(\"a\" + \"\\nb\")", - " A verbose3();", - "", - " @pkg.A.Foo(\"foo\")", - " A moreVerbose1();", - "", - " @A.Foo(\"a'b\")", - " A moreVerbose2();", - "", - " @Foo(\"a\" + \"\\nb\")", - " A moreVerbose3();", - "", - " @pkg.A.Foo(", - " value = {\"foo\", \"bar\"},", - " value2 = 2)", - " A extended1();", - "", - " @A.Foo(", - " value = {\"a'b\", \"c'd\"},", - " value2 = 2)", - " A extended2();", - "", - " @Foo(", - " value = {\"a\" + \"\\nb\", \"c\" + \"\\nd\"},", - " value2 = 2)", - " A extended3();", - "", - " @pkg.A.Foo({\"foo\", \"bar\"})", - " A trailingComma1();", - "", - " @A.Foo({\"a'b\", \"c'd\"})", - " A trailingComma2();", - "", - " @Foo({\"a\" + \"\\nb\", \"c\" + \"\\nd\"})", - " A trailingComma3();", - "}") + """ + package pkg; + + import pkg.A.Foo; + + interface A { + @interface Foo { + String[] value() default {}; + + int[] value2() default {}; + } + + @pkg.A.Foo + A functional1(); + + @A.Foo + A functional2(); + + @Foo + A functional3(); + + @pkg.A.Foo("foo") + A verbose1(); + + @A.Foo("a'b") + A verbose2(); + + @Foo("a" + "\\nb") + A verbose3(); + + @pkg.A.Foo("foo") + A moreVerbose1(); + + @A.Foo("a'b") + A moreVerbose2(); + + @Foo("a" + "\\nb") + A moreVerbose3(); + + @pkg.A.Foo( + value = {"foo", "bar"}, + value2 = 2) + A extended1(); + + @A.Foo( + value = {"a'b", "c'd"}, + value2 = 2) + A extended2(); + + @Foo( + value = {"a" + "\\nb", "c" + "\\nd"}, + value2 = 2) + A extended3(); + + @pkg.A.Foo({"foo", "bar"}) + A trailingComma1(); + + @A.Foo({"a'b", "c'd"}) + A trailingComma2(); + + @Foo({"a" + "\\nb", "c" + "\\nd"}) + A trailingComma3(); + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/CollectorMutabilityTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/CollectorMutabilityTest.java index 1b837e61b57..4cb67e40a2c 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/CollectorMutabilityTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/CollectorMutabilityTest.java @@ -18,50 +18,52 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import static com.google.common.collect.ImmutableList.toImmutableList;", - "import static com.google.common.collect.ImmutableMap.toImmutableMap;", - "import static com.google.common.collect.ImmutableSet.toImmutableSet;", - "import static java.util.stream.Collectors.toCollection;", - "import static java.util.stream.Collectors.toList;", - "import static java.util.stream.Collectors.toMap;", - "import static java.util.stream.Collectors.toSet;", - "", - "import java.util.ArrayList;", - "import java.util.HashMap;", - "import java.util.HashSet;", - "import java.util.stream.Collectors;", - "import java.util.stream.Stream;", - "import reactor.core.publisher.Flux;", - "", - "class A {", - " void m() {", - " // BUG: Diagnostic contains:", - " Flux.just(1).collect(Collectors.toList());", - " // BUG: Diagnostic contains:", - " Flux.just(2).collect(toList());", - " Flux.just(3).collect(toImmutableList());", - " Flux.just(4).collect(toCollection(ArrayList::new));", - "", - " // BUG: Diagnostic contains:", - " Flux.just(\"foo\").collect(Collectors.toMap(String::getBytes, String::length));", - " // BUG: Diagnostic contains:", - " Flux.just(\"bar\").collect(toMap(String::getBytes, String::length));", - " Flux.just(\"baz\").collect(toImmutableMap(String::getBytes, String::length));", - " // BUG: Diagnostic contains:", - " Flux.just(\"qux\").collect(toMap(String::getBytes, String::length, (a, b) -> a));", - " Flux.just(\"quux\").collect(toImmutableMap(String::getBytes, String::length, (a, b) -> a));", - " Flux.just(\"quuz\").collect(toMap(String::getBytes, String::length, (a, b) -> a, HashMap::new));", - "", - " // BUG: Diagnostic contains:", - " Stream.of(1).collect(Collectors.toSet());", - " // BUG: Diagnostic contains:", - " Stream.of(2).collect(toSet());", - " Stream.of(3).collect(toImmutableSet());", - " Stream.of(4).collect(toCollection(HashSet::new));", - "", - " Flux.just(\"foo\").collect(Collectors.joining());", - " }", - "}") + """ + import static com.google.common.collect.ImmutableList.toImmutableList; + import static com.google.common.collect.ImmutableMap.toImmutableMap; + import static com.google.common.collect.ImmutableSet.toImmutableSet; + import static java.util.stream.Collectors.toCollection; + import static java.util.stream.Collectors.toList; + import static java.util.stream.Collectors.toMap; + import static java.util.stream.Collectors.toSet; + + import java.util.ArrayList; + import java.util.HashMap; + import java.util.HashSet; + import java.util.stream.Collectors; + import java.util.stream.Stream; + import reactor.core.publisher.Flux; + + class A { + void m() { + // BUG: Diagnostic contains: + Flux.just(1).collect(Collectors.toList()); + // BUG: Diagnostic contains: + Flux.just(2).collect(toList()); + Flux.just(3).collect(toImmutableList()); + Flux.just(4).collect(toCollection(ArrayList::new)); + + // BUG: Diagnostic contains: + Flux.just("foo").collect(Collectors.toMap(String::getBytes, String::length)); + // BUG: Diagnostic contains: + Flux.just("bar").collect(toMap(String::getBytes, String::length)); + Flux.just("baz").collect(toImmutableMap(String::getBytes, String::length)); + // BUG: Diagnostic contains: + Flux.just("qux").collect(toMap(String::getBytes, String::length, (a, b) -> a)); + Flux.just("quux").collect(toImmutableMap(String::getBytes, String::length, (a, b) -> a)); + Flux.just("quuz").collect(toMap(String::getBytes, String::length, (a, b) -> a, HashMap::new)); + + // BUG: Diagnostic contains: + Stream.of(1).collect(Collectors.toSet()); + // BUG: Diagnostic contains: + Stream.of(2).collect(toSet()); + Stream.of(3).collect(toImmutableSet()); + Stream.of(4).collect(toCollection(HashSet::new)); + + Flux.just("foo").collect(Collectors.joining()); + } + } + """) .doTest(); } @@ -71,14 +73,16 @@ void identificationWithoutGuavaOnClasspath() { .withClasspath() .addSourceLines( "A.java", - "import java.util.stream.Collectors;", - "import java.util.stream.Stream;", - "", - "class A {", - " void m() {", - " Stream.empty().collect(Collectors.toList());", - " }", - "}") + """ + import java.util.stream.Collectors; + import java.util.stream.Stream; + + class A { + void m() { + Stream.empty().collect(Collectors.toList()); + } + } + """) .doTest(); } @@ -87,55 +91,59 @@ void replacementFirstSuggestedFix() { refactoringTestHelper .addInputLines( "A.java", - "import static java.util.stream.Collectors.toList;", - "import static java.util.stream.Collectors.toMap;", - "import static java.util.stream.Collectors.toSet;", - "", - "import java.util.stream.Collectors;", - "import java.util.stream.Stream;", - "import reactor.core.publisher.Flux;", - "", - "class A {", - " void m() {", - " Flux.just(1).collect(Collectors.toList());", - " Flux.just(2).collect(toList());", - "", - " Stream.of(\"foo\").collect(Collectors.toMap(String::getBytes, String::length));", - " Stream.of(\"bar\").collect(toMap(String::getBytes, String::length));", - " Flux.just(\"baz\").collect(Collectors.toMap(String::getBytes, String::length, (a, b) -> b));", - " Flux.just(\"qux\").collect(toMap(String::getBytes, String::length, (a, b) -> b));", - "", - " Stream.of(1).collect(Collectors.toSet());", - " Stream.of(2).collect(toSet());", - " }", - "}") + """ + import static java.util.stream.Collectors.toList; + import static java.util.stream.Collectors.toMap; + import static java.util.stream.Collectors.toSet; + + import java.util.stream.Collectors; + import java.util.stream.Stream; + import reactor.core.publisher.Flux; + + class A { + void m() { + Flux.just(1).collect(Collectors.toList()); + Flux.just(2).collect(toList()); + + Stream.of("foo").collect(Collectors.toMap(String::getBytes, String::length)); + Stream.of("bar").collect(toMap(String::getBytes, String::length)); + Flux.just("baz").collect(Collectors.toMap(String::getBytes, String::length, (a, b) -> b)); + Flux.just("qux").collect(toMap(String::getBytes, String::length, (a, b) -> b)); + + Stream.of(1).collect(Collectors.toSet()); + Stream.of(2).collect(toSet()); + } + } + """) .addOutputLines( "A.java", - "import static com.google.common.collect.ImmutableList.toImmutableList;", - "import static com.google.common.collect.ImmutableMap.toImmutableMap;", - "import static com.google.common.collect.ImmutableSet.toImmutableSet;", - "import static java.util.stream.Collectors.toList;", - "import static java.util.stream.Collectors.toMap;", - "import static java.util.stream.Collectors.toSet;", - "", - "import java.util.stream.Collectors;", - "import java.util.stream.Stream;", - "import reactor.core.publisher.Flux;", - "", - "class A {", - " void m() {", - " Flux.just(1).collect(toImmutableList());", - " Flux.just(2).collect(toImmutableList());", - "", - " Stream.of(\"foo\").collect(toImmutableMap(String::getBytes, String::length));", - " Stream.of(\"bar\").collect(toImmutableMap(String::getBytes, String::length));", - " Flux.just(\"baz\").collect(toImmutableMap(String::getBytes, String::length, (a, b) -> b));", - " Flux.just(\"qux\").collect(toImmutableMap(String::getBytes, String::length, (a, b) -> b));", - "", - " Stream.of(1).collect(toImmutableSet());", - " Stream.of(2).collect(toImmutableSet());", - " }", - "}") + """ + import static com.google.common.collect.ImmutableList.toImmutableList; + import static com.google.common.collect.ImmutableMap.toImmutableMap; + import static com.google.common.collect.ImmutableSet.toImmutableSet; + import static java.util.stream.Collectors.toList; + import static java.util.stream.Collectors.toMap; + import static java.util.stream.Collectors.toSet; + + import java.util.stream.Collectors; + import java.util.stream.Stream; + import reactor.core.publisher.Flux; + + class A { + void m() { + Flux.just(1).collect(toImmutableList()); + Flux.just(2).collect(toImmutableList()); + + Stream.of("foo").collect(toImmutableMap(String::getBytes, String::length)); + Stream.of("bar").collect(toImmutableMap(String::getBytes, String::length)); + Flux.just("baz").collect(toImmutableMap(String::getBytes, String::length, (a, b) -> b)); + Flux.just("qux").collect(toImmutableMap(String::getBytes, String::length, (a, b) -> b)); + + Stream.of(1).collect(toImmutableSet()); + Stream.of(2).collect(toImmutableSet()); + } + } + """) .doTest(TestMode.TEXT_MATCH); } @@ -145,73 +153,77 @@ void replacementSecondSuggestedFix() { .setFixChooser(SECOND) .addInputLines( "A.java", - "import static java.util.stream.Collectors.toList;", - "import static java.util.stream.Collectors.toMap;", - "import static java.util.stream.Collectors.toSet;", - "", - "import java.util.stream.Collectors;", - "import java.util.stream.Stream;", - "import reactor.core.publisher.Flux;", - "", - "class A {", - " void m() {", - " Flux.just(1).collect(Collectors.toList());", - " Flux.just(2).collect(toList());", - "", - " Stream.of(\"foo\").collect(Collectors.toMap(String::getBytes, String::length));", - " Stream.of(\"bar\").collect(toMap(String::getBytes, String::length));", - " Flux.just(\"baz\").collect(Collectors.toMap(String::getBytes, String::length, (a, b) -> b));", - " Flux.just(\"qux\").collect(toMap(String::getBytes, String::length, (a, b) -> b));", - "", - " Stream.of(1).collect(Collectors.toSet());", - " Stream.of(2).collect(toSet());", - " }", - "}") + """ + import static java.util.stream.Collectors.toList; + import static java.util.stream.Collectors.toMap; + import static java.util.stream.Collectors.toSet; + + import java.util.stream.Collectors; + import java.util.stream.Stream; + import reactor.core.publisher.Flux; + + class A { + void m() { + Flux.just(1).collect(Collectors.toList()); + Flux.just(2).collect(toList()); + + Stream.of("foo").collect(Collectors.toMap(String::getBytes, String::length)); + Stream.of("bar").collect(toMap(String::getBytes, String::length)); + Flux.just("baz").collect(Collectors.toMap(String::getBytes, String::length, (a, b) -> b)); + Flux.just("qux").collect(toMap(String::getBytes, String::length, (a, b) -> b)); + + Stream.of(1).collect(Collectors.toSet()); + Stream.of(2).collect(toSet()); + } + } + """) .addOutputLines( "A.java", - "import static java.util.stream.Collectors.toCollection;", - "import static java.util.stream.Collectors.toList;", - "import static java.util.stream.Collectors.toMap;", - "import static java.util.stream.Collectors.toSet;", - "", - "import java.util.ArrayList;", - "import java.util.HashMap;", - "import java.util.HashSet;", - "import java.util.stream.Collectors;", - "import java.util.stream.Stream;", - "import reactor.core.publisher.Flux;", - "", - "class A {", - " void m() {", - " Flux.just(1).collect(toCollection(ArrayList::new));", - " Flux.just(2).collect(toCollection(ArrayList::new));", - "", - " Stream.of(\"foo\")", - " .collect(", - " Collectors.toMap(", - " String::getBytes,", - " String::length,", - " (a, b) -> {", - " throw new IllegalStateException();", - " },", - " HashMap::new));", - " Stream.of(\"bar\")", - " .collect(", - " toMap(", - " String::getBytes,", - " String::length,", - " (a, b) -> {", - " throw new IllegalStateException();", - " },", - " HashMap::new));", - " Flux.just(\"baz\")", - " .collect(Collectors.toMap(String::getBytes, String::length, (a, b) -> b, HashMap::new));", - " Flux.just(\"qux\").collect(toMap(String::getBytes, String::length, (a, b) -> b, HashMap::new));", - "", - " Stream.of(1).collect(toCollection(HashSet::new));", - " Stream.of(2).collect(toCollection(HashSet::new));", - " }", - "}") + """ + import static java.util.stream.Collectors.toCollection; + import static java.util.stream.Collectors.toList; + import static java.util.stream.Collectors.toMap; + import static java.util.stream.Collectors.toSet; + + import java.util.ArrayList; + import java.util.HashMap; + import java.util.HashSet; + import java.util.stream.Collectors; + import java.util.stream.Stream; + import reactor.core.publisher.Flux; + + class A { + void m() { + Flux.just(1).collect(toCollection(ArrayList::new)); + Flux.just(2).collect(toCollection(ArrayList::new)); + + Stream.of("foo") + .collect( + Collectors.toMap( + String::getBytes, + String::length, + (a, b) -> { + throw new IllegalStateException(); + }, + HashMap::new)); + Stream.of("bar") + .collect( + toMap( + String::getBytes, + String::length, + (a, b) -> { + throw new IllegalStateException(); + }, + HashMap::new)); + Flux.just("baz") + .collect(Collectors.toMap(String::getBytes, String::length, (a, b) -> b, HashMap::new)); + Flux.just("qux").collect(toMap(String::getBytes, String::length, (a, b) -> b, HashMap::new)); + + Stream.of(1).collect(toCollection(HashSet::new)); + Stream.of(2).collect(toCollection(HashSet::new)); + } + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/EmptyMethodTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/EmptyMethodTest.java index e1fdbc360e6..ff048532675 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/EmptyMethodTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/EmptyMethodTest.java @@ -16,54 +16,58 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "class A {", - " Object m1() {", - " return null;", - " }", - "", - " void m2() {", - " System.out.println(42);", - " }", - "", - " void m3() {}", - "", - " // BUG: Diagnostic contains:", - " static void m4() {}", - "", - " interface F {", - " void fun();", - " }", - "", - " final class MyTestClass {", - " void helperMethod() {}", - " }", - "}") + """ + class A { + Object m1() { + return null; + } + + void m2() { + System.out.println(42); + } + + void m3() {} + + // BUG: Diagnostic contains: + static void m4() {} + + interface F { + void fun(); + } + + final class MyTestClass { + void helperMethod() {} + } + } + """) .addSourceLines( "B.java", - "import org.aspectj.lang.annotation.Pointcut;", - "", - "final class B implements A.F {", - " @Override", - " public void fun() {}", - "", - " // BUG: Diagnostic contains:", - " void m3() {}", - "", - " /** Javadoc. */", - " // BUG: Diagnostic contains:", - " void m4() {}", - "", - " void m5() {", - " // Single-line comment.", - " }", - "", - " void m6() {", - " /* Multi-line comment. */", - " }", - "", - " @Pointcut", - " void m7() {}", - "}") + """ + import org.aspectj.lang.annotation.Pointcut; + + final class B implements A.F { + @Override + public void fun() {} + + // BUG: Diagnostic contains: + void m3() {} + + /** Javadoc. */ + // BUG: Diagnostic contains: + void m4() {} + + void m5() { + // Single-line comment. + } + + void m6() { + /* Multi-line comment. */ + } + + @Pointcut + void m7() {} + } + """) .doTest(); } @@ -72,12 +76,16 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "final class A {", - " void instanceMethod() {}", - "", - " static void staticMethod() {}", - "}") - .addOutputLines("A.java", "final class A {}") + """ + final class A { + void instanceMethod() {} + + static void staticMethod() {} + } + """) + .addOutputLines("A.java", """ + final class A {} + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ErrorProneTestHelperSourceFormatTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ErrorProneTestHelperSourceFormatTest.java index 58d7fa9e80a..f4e35928ee8 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ErrorProneTestHelperSourceFormatTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ErrorProneTestHelperSourceFormatTest.java @@ -31,63 +31,65 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;", - "import com.google.errorprone.CompilationTestHelper;", - "import tech.picnic.errorprone.bugpatterns.EmptyMethod;", - "", - "class A {", - " private final CompilationTestHelper compilationTestHelper =", - " CompilationTestHelper.newInstance(EmptyMethod.class, getClass());", - " private final BugCheckerRefactoringTestHelper refactoringTestHelper =", - " BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass());", - "", - " void m() {", - " compilationTestHelper", - " // BUG: Diagnostic contains: No source code provided", - " .addSourceLines(\"A.java\")", - " // BUG: Diagnostic contains: Source code is malformed:", - " .addSourceLines(\"B.java\", \"class B {\")", - " // BUG: Diagnostic contains: Test code should be specified using a single text block", - " .addSourceLines(\"C.java\", \"class C {}\")", - " // Malformed code, but not compile-time constant, so not flagged.", - " .addSourceLines(\"D.java\", \"class D {\" + getClass())", - " // BUG: Diagnostic contains: Test code should follow the Google Java style", - " .addSourceLines(\"E.java\", \"class E { }\")", - " // Well-formed code, so not flagged.", - " .addSourceLines(\"F.java\", \"\"\"", - " class F {}", - " \"\"\")", - " // BUG: Diagnostic contains: Test code should follow the Google Java style (pay attention to", - " // trailing newlines)", - " .addSourceLines(\"G.java\", \"\"\"", - " class G {}\"\"\")", - " .doTest();", - "", - " refactoringTestHelper", - " // BUG: Diagnostic contains: Test code should follow the Google Java style", - " .addInputLines(\"in/A.java\", \"class A { }\")", - " // BUG: Diagnostic contains: Test code should follow the Google Java style", - " .addOutputLines(\"out/A.java\", \"class A { }\")", - " // BUG: Diagnostic contains: Test code should follow the Google Java style", - " .addInputLines(", - " \"in/B.java\",", - " \"\"\"", - " import java.util.Map;", - "", - " class B {}", - " \"\"\")", - " // Unused import, but in an output file, so not flagged.", - " .addOutputLines(", - " \"out/B.java\",", - " \"\"\"", - " import java.util.Map;", - "", - " class B {}", - " \"\"\")", - " .doTest(TestMode.TEXT_MATCH);", - " }", - "}") + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode; + import com.google.errorprone.CompilationTestHelper; + import tech.picnic.errorprone.bugpatterns.EmptyMethod; + + class A { + private final CompilationTestHelper compilationTestHelper = + CompilationTestHelper.newInstance(EmptyMethod.class, getClass()); + private final BugCheckerRefactoringTestHelper refactoringTestHelper = + BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass()); + + void m() { + compilationTestHelper + // BUG: Diagnostic contains: No source code provided + .addSourceLines("A.java") + // BUG: Diagnostic contains: Source code is malformed: + .addSourceLines("B.java", "class B {") + // BUG: Diagnostic contains: Test code should be specified using a single text block + .addSourceLines("C.java", "class C {}") + // Malformed code, but not compile-time constant, so not flagged. + .addSourceLines("D.java", "class D {" + getClass()) + // BUG: Diagnostic contains: Test code should follow the Google Java style + .addSourceLines("E.java", "class E { }") + // Well-formed code, so not flagged. + .addSourceLines("F.java", ""\" + class F {} + ""\") + // BUG: Diagnostic contains: Test code should follow the Google Java style (pay attention to + // trailing newlines) + .addSourceLines("G.java", ""\" + class G {}""\") + .doTest(); + + refactoringTestHelper + // BUG: Diagnostic contains: Test code should follow the Google Java style + .addInputLines("in/A.java", "class A { }") + // BUG: Diagnostic contains: Test code should follow the Google Java style + .addOutputLines("out/A.java", "class A { }") + // BUG: Diagnostic contains: Test code should follow the Google Java style + .addInputLines( + "in/B.java", + ""\" + import java.util.Map; + + class B {} + ""\") + // Unused import, but in an output file, so not flagged. + .addOutputLines( + "out/B.java", + ""\" + import java.util.Map; + + class B {} + ""\") + .doTest(TestMode.TEXT_MATCH); + } + } + """) .doTest(); } @@ -97,50 +99,52 @@ void identificationAvoidTextBlocks() { avoidTextBlocksCompilationTestHelper .addSourceLines( "A.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;", - "import com.google.errorprone.CompilationTestHelper;", - "import tech.picnic.errorprone.bugpatterns.EmptyMethod;", - "", - "class A {", - " private final CompilationTestHelper compilationTestHelper =", - " CompilationTestHelper.newInstance(EmptyMethod.class, getClass());", - " private final BugCheckerRefactoringTestHelper refactoringTestHelper =", - " BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass());", - "", - " void m() {", - " compilationTestHelper", - " // BUG: Diagnostic contains: No source code provided", - " .addSourceLines(\"A.java\")", - " // BUG: Diagnostic contains: Source code is malformed:", - " .addSourceLines(\"B.java\", \"class B {\")", - " // Well-formed code, so not flagged.", - " .addSourceLines(\"C.java\", \"class C {}\")", - " // Malformed code, but not compile-time constant, so not flagged.", - " .addSourceLines(\"D.java\", \"class D {\" + getClass())", - " // BUG: Diagnostic contains: Test code should follow the Google Java style", - " .addSourceLines(\"E.java\", \"class E { }\")", - " // BUG: Diagnostic contains: Test code should not be specified using a single text block", - " .addSourceLines(\"F.java\", \"\"\"", - " class F {}", - " \"\"\")", - " // BUG: Diagnostic contains: Test code should follow the Google Java style (pay attention to", - " // trailing newlines)", - " .addSourceLines(\"G.java\", \"class G {}\", \"\")", - " .doTest();", - "", - " refactoringTestHelper", - " // BUG: Diagnostic contains: Test code should follow the Google Java style", - " .addInputLines(\"A.java\", \"class A { }\")", - " // BUG: Diagnostic contains: Test code should follow the Google Java style", - " .addOutputLines(\"A.java\", \"class A { }\")", - " // BUG: Diagnostic contains: Test code should follow the Google Java style", - " .addInputLines(\"B.java\", \"import java.util.Map;\", \"\", \"class B {}\")", - " // Unused import, but in an output file, so not flagged.", - " .addOutputLines(\"B.java\", \"import java.util.Map;\", \"\", \"class B {}\")", - " .doTest(TestMode.TEXT_MATCH);", - " }", - "}") + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode; + import com.google.errorprone.CompilationTestHelper; + import tech.picnic.errorprone.bugpatterns.EmptyMethod; + + class A { + private final CompilationTestHelper compilationTestHelper = + CompilationTestHelper.newInstance(EmptyMethod.class, getClass()); + private final BugCheckerRefactoringTestHelper refactoringTestHelper = + BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass()); + + void m() { + compilationTestHelper + // BUG: Diagnostic contains: No source code provided + .addSourceLines("A.java") + // BUG: Diagnostic contains: Source code is malformed: + .addSourceLines("B.java", "class B {") + // Well-formed code, so not flagged. + .addSourceLines("C.java", "class C {}") + // Malformed code, but not compile-time constant, so not flagged. + .addSourceLines("D.java", "class D {" + getClass()) + // BUG: Diagnostic contains: Test code should follow the Google Java style + .addSourceLines("E.java", "class E { }") + // BUG: Diagnostic contains: Test code should not be specified using a single text block + .addSourceLines("F.java", ""\" + class F {} + ""\") + // BUG: Diagnostic contains: Test code should follow the Google Java style (pay attention to + // trailing newlines) + .addSourceLines("G.java", "class G {}", "") + .doTest(); + + refactoringTestHelper + // BUG: Diagnostic contains: Test code should follow the Google Java style + .addInputLines("A.java", "class A { }") + // BUG: Diagnostic contains: Test code should follow the Google Java style + .addOutputLines("A.java", "class A { }") + // BUG: Diagnostic contains: Test code should follow the Google Java style + .addInputLines("B.java", "import java.util.Map;", "", "class B {}") + // Unused import, but in an output file, so not flagged. + .addOutputLines("B.java", "import java.util.Map;", "", "class B {}") + .doTest(TestMode.TEXT_MATCH); + } + } + """) .doTest(); } @@ -155,95 +159,99 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;", - "import com.google.errorprone.CompilationTestHelper;", - "import tech.picnic.errorprone.bugpatterns.EmptyMethod;", - "", - "class A {", - " private final CompilationTestHelper compilationTestHelper =", - " CompilationTestHelper.newInstance(EmptyMethod.class, getClass());", - " private final BugCheckerRefactoringTestHelper refactoringTestHelper =", - " BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass());", - "", - " void m() {", - " compilationTestHelper", - " .addSourceLines(", - " \"A.java\",", - " \"\"\"", - " import java.util.Map;", - " import java.util.Collection;", - " import java.util.List;", - "", - " interface A extends List, Map { }\"\"\")", - " .doTest();", - "", - " refactoringTestHelper", - " .addInputLines(", - " \"in/A.java\",", - " \"\"\"", - " import java.util.Map;", - " import java.util.Collection;", - " import java.util.List;", - "", - " interface A extends List, Map { }\"\"\")", - " .addOutputLines(", - " \"out/A.java\",", - " \"\"\"", - " import java.util.Map;", - " import java.util.Collection;", - " import java.util.List;", - "", - " interface A extends List, Map { }\"\"\")", - " .doTest(TestMode.TEXT_MATCH);", - " }", - "}") + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode; + import com.google.errorprone.CompilationTestHelper; + import tech.picnic.errorprone.bugpatterns.EmptyMethod; + + class A { + private final CompilationTestHelper compilationTestHelper = + CompilationTestHelper.newInstance(EmptyMethod.class, getClass()); + private final BugCheckerRefactoringTestHelper refactoringTestHelper = + BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass()); + + void m() { + compilationTestHelper + .addSourceLines( + "A.java", + ""\" + import java.util.Map; + import java.util.Collection; + import java.util.List; + + interface A extends List, Map { }""\") + .doTest(); + + refactoringTestHelper + .addInputLines( + "in/A.java", + ""\" + import java.util.Map; + import java.util.Collection; + import java.util.List; + + interface A extends List, Map { }""\") + .addOutputLines( + "out/A.java", + ""\" + import java.util.Map; + import java.util.Collection; + import java.util.List; + + interface A extends List, Map { }""\") + .doTest(TestMode.TEXT_MATCH); + } + } + """) .addOutputLines( "out/A.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;", - "import com.google.errorprone.CompilationTestHelper;", - "import tech.picnic.errorprone.bugpatterns.EmptyMethod;", - "", - "class A {", - " private final CompilationTestHelper compilationTestHelper =", - " CompilationTestHelper.newInstance(EmptyMethod.class, getClass());", - " private final BugCheckerRefactoringTestHelper refactoringTestHelper =", - " BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass());", - "", - " void m() {", - " compilationTestHelper", - " .addSourceLines(", - " \"A.java\",", - " \"\"\"", - " import java.util.List;", - " import java.util.Map;", - "", - " interface A extends List, Map {}", - " \"\"\")", - " .doTest();", - "", - " refactoringTestHelper", - " .addInputLines(", - " \"in/A.java\",", - " \"\"\"", - " import java.util.List;", - " import java.util.Map;", - "", - " interface A extends List, Map {}", - " \"\"\")", - " .addOutputLines(", - " \"out/A.java\",", - " \"\"\"", - " import java.util.Collection;", - " import java.util.List;", - " import java.util.Map;", - "", - " interface A extends List, Map {}", - " \"\"\")", - " .doTest(TestMode.TEXT_MATCH);", - " }", - "}") + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode; + import com.google.errorprone.CompilationTestHelper; + import tech.picnic.errorprone.bugpatterns.EmptyMethod; + + class A { + private final CompilationTestHelper compilationTestHelper = + CompilationTestHelper.newInstance(EmptyMethod.class, getClass()); + private final BugCheckerRefactoringTestHelper refactoringTestHelper = + BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass()); + + void m() { + compilationTestHelper + .addSourceLines( + "A.java", + ""\" + import java.util.List; + import java.util.Map; + + interface A extends List, Map {} + ""\") + .doTest(); + + refactoringTestHelper + .addInputLines( + "in/A.java", + ""\" + import java.util.List; + import java.util.Map; + + interface A extends List, Map {} + ""\") + .addOutputLines( + "out/A.java", + ""\" + import java.util.Collection; + import java.util.List; + import java.util.Map; + + interface A extends List, Map {} + ""\") + .doTest(TestMode.TEXT_MATCH); + } + } + """) .doTest(TestMode.TEXT_MATCH); } @@ -256,86 +264,90 @@ void replacementAvoidTextBlocks() { avoidTextBlocksRefactoringTestHelper .addInputLines( "in/A.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;", - "import com.google.errorprone.CompilationTestHelper;", - "import tech.picnic.errorprone.bugpatterns.EmptyMethod;", - "", - "class A {", - " private final CompilationTestHelper compilationTestHelper =", - " CompilationTestHelper.newInstance(EmptyMethod.class, getClass());", - " private final BugCheckerRefactoringTestHelper refactoringTestHelper =", - " BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass());", - "", - " void m() {", - " compilationTestHelper", - " .addSourceLines(", - " \"A.java\",", - " \"import java.util.Map;\",", - " \"import java.util.Collection;\",", - " \"import java.util.List;\",", - " \"\",", - " \"interface A extends List, Map { }\")", - " .doTest();", - "", - " refactoringTestHelper", - " .addInputLines(", - " \"A.java\",", - " \"import java.util.Map;\",", - " \"import java.util.Collection;\",", - " \"import java.util.List;\",", - " \"\",", - " \"interface A extends List, Map { }\")", - " .addOutputLines(", - " \"A.java\",", - " \"import java.util.Map;\",", - " \"import java.util.Collection;\",", - " \"import java.util.List;\",", - " \"\",", - " \"interface A extends List, Map { }\")", - " .doTest(TestMode.TEXT_MATCH);", - " }", - "}") + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode; + import com.google.errorprone.CompilationTestHelper; + import tech.picnic.errorprone.bugpatterns.EmptyMethod; + + class A { + private final CompilationTestHelper compilationTestHelper = + CompilationTestHelper.newInstance(EmptyMethod.class, getClass()); + private final BugCheckerRefactoringTestHelper refactoringTestHelper = + BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass()); + + void m() { + compilationTestHelper + .addSourceLines( + "A.java", + "import java.util.Map;", + "import java.util.Collection;", + "import java.util.List;", + "", + "interface A extends List, Map { }") + .doTest(); + + refactoringTestHelper + .addInputLines( + "A.java", + "import java.util.Map;", + "import java.util.Collection;", + "import java.util.List;", + "", + "interface A extends List, Map { }") + .addOutputLines( + "A.java", + "import java.util.Map;", + "import java.util.Collection;", + "import java.util.List;", + "", + "interface A extends List, Map { }") + .doTest(TestMode.TEXT_MATCH); + } + } + """) .addOutputLines( "A.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;", - "import com.google.errorprone.CompilationTestHelper;", - "import tech.picnic.errorprone.bugpatterns.EmptyMethod;", - "", - "class A {", - " private final CompilationTestHelper compilationTestHelper =", - " CompilationTestHelper.newInstance(EmptyMethod.class, getClass());", - " private final BugCheckerRefactoringTestHelper refactoringTestHelper =", - " BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass());", - "", - " void m() {", - " compilationTestHelper", - " .addSourceLines(", - " \"A.java\",", - " \"import java.util.List;\",", - " \"import java.util.Map;\",", - " \"\",", - " \"interface A extends List, Map {}\")", - " .doTest();", - "", - " refactoringTestHelper", - " .addInputLines(", - " \"A.java\",", - " \"import java.util.List;\",", - " \"import java.util.Map;\",", - " \"\",", - " \"interface A extends List, Map {}\")", - " .addOutputLines(", - " \"A.java\",", - " \"import java.util.Collection;\",", - " \"import java.util.List;\",", - " \"import java.util.Map;\",", - " \"\",", - " \"interface A extends List, Map {}\")", - " .doTest(TestMode.TEXT_MATCH);", - " }", - "}") + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode; + import com.google.errorprone.CompilationTestHelper; + import tech.picnic.errorprone.bugpatterns.EmptyMethod; + + class A { + private final CompilationTestHelper compilationTestHelper = + CompilationTestHelper.newInstance(EmptyMethod.class, getClass()); + private final BugCheckerRefactoringTestHelper refactoringTestHelper = + BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass()); + + void m() { + compilationTestHelper + .addSourceLines( + "A.java", + "import java.util.List;", + "import java.util.Map;", + "", + "interface A extends List, Map {}") + .doTest(); + + refactoringTestHelper + .addInputLines( + "A.java", + "import java.util.List;", + "import java.util.Map;", + "", + "interface A extends List, Map {}") + .addOutputLines( + "A.java", + "import java.util.Collection;", + "import java.util.List;", + "import java.util.Map;", + "", + "interface A extends List, Map {}") + .doTest(TestMode.TEXT_MATCH); + } + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ExplicitEnumOrderingTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ExplicitEnumOrderingTest.java index 3a8119a0ce1..973fb069c38 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ExplicitEnumOrderingTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ExplicitEnumOrderingTest.java @@ -12,74 +12,76 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import static java.lang.annotation.RetentionPolicy.CLASS;", - "import static java.lang.annotation.RetentionPolicy.RUNTIME;", - "import static java.lang.annotation.RetentionPolicy.SOURCE;", - "import static java.time.chrono.IsoEra.BCE;", - "import static java.time.chrono.IsoEra.CE;", - "", - "import com.google.common.collect.ImmutableList;", - "import com.google.common.collect.Ordering;", - "import java.lang.annotation.RetentionPolicy;", - "import java.time.chrono.IsoEra;", - "", - "class A {", - " {", - " // The `List`-accepting overload is currently ignored.", - " Ordering.explicit(ImmutableList.of(RetentionPolicy.SOURCE, RetentionPolicy.CLASS));", - "", - " Ordering.explicit(IsoEra.BCE, IsoEra.CE);", - " // BUG: Diagnostic contains: IsoEra.CE", - " Ordering.explicit(IsoEra.BCE);", - " // BUG: Diagnostic contains: IsoEra.BCE", - " Ordering.explicit(IsoEra.CE);", - "", - " Ordering.explicit(RetentionPolicy.SOURCE, RetentionPolicy.CLASS, RetentionPolicy.RUNTIME);", - " // BUG: Diagnostic contains: RetentionPolicy.CLASS, RetentionPolicy.RUNTIME", - " Ordering.explicit(RetentionPolicy.SOURCE);", - " // BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.RUNTIME", - " Ordering.explicit(RetentionPolicy.CLASS);", - " // BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.CLASS", - " Ordering.explicit(RetentionPolicy.RUNTIME);", - " // BUG: Diagnostic contains: RetentionPolicy.RUNTIME", - " Ordering.explicit(RetentionPolicy.SOURCE, RetentionPolicy.CLASS);", - " // BUG: Diagnostic contains: RetentionPolicy.CLASS", - " Ordering.explicit(RetentionPolicy.SOURCE, RetentionPolicy.RUNTIME);", - " // BUG: Diagnostic contains: RetentionPolicy.SOURCE", - " Ordering.explicit(RetentionPolicy.CLASS, RetentionPolicy.RUNTIME);", - "", - " Ordering.explicit(BCE, CE);", - " // BUG: Diagnostic contains: IsoEra.CE", - " Ordering.explicit(BCE);", - " // BUG: Diagnostic contains: IsoEra.BCE", - " Ordering.explicit(CE);", - "", - " Ordering.explicit(SOURCE, CLASS, RUNTIME);", - " // BUG: Diagnostic contains: RetentionPolicy.CLASS, RetentionPolicy.RUNTIME", - " Ordering.explicit(SOURCE);", - " // BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.RUNTIME", - " Ordering.explicit(CLASS);", - " // BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.CLASS", - " Ordering.explicit(RUNTIME);", - " // BUG: Diagnostic contains: RetentionPolicy.RUNTIME", - " Ordering.explicit(SOURCE, CLASS);", - " // BUG: Diagnostic contains: RetentionPolicy.CLASS", - " Ordering.explicit(SOURCE, RUNTIME);", - " // BUG: Diagnostic contains: RetentionPolicy.SOURCE", - " Ordering.explicit(CLASS, RUNTIME);", - "", - " Ordering.explicit(RetentionPolicy.SOURCE, BCE, RetentionPolicy.CLASS, CE, RUNTIME);", - " Ordering.explicit(SOURCE, IsoEra.BCE, CLASS, IsoEra.CE, RetentionPolicy.RUNTIME);", - " // BUG: Diagnostic contains: RetentionPolicy.CLASS", - " Ordering.explicit(RetentionPolicy.SOURCE, BCE, CE, RUNTIME);", - " // BUG: Diagnostic contains: RetentionPolicy.CLASS", - " Ordering.explicit(IsoEra.BCE, SOURCE, IsoEra.CE, RetentionPolicy.RUNTIME);", - " // BUG: Diagnostic contains: IsoEra.CE, RetentionPolicy.RUNTIME", - " Ordering.explicit(IsoEra.BCE, SOURCE, RetentionPolicy.CLASS);", - " // BUG: Diagnostic contains: RetentionPolicy.SOURCE, IsoEra.BCE", - " Ordering.explicit(CLASS, RUNTIME, CE);", - " }", - "}") + """ + import static java.lang.annotation.RetentionPolicy.CLASS; + import static java.lang.annotation.RetentionPolicy.RUNTIME; + import static java.lang.annotation.RetentionPolicy.SOURCE; + import static java.time.chrono.IsoEra.BCE; + import static java.time.chrono.IsoEra.CE; + + import com.google.common.collect.ImmutableList; + import com.google.common.collect.Ordering; + import java.lang.annotation.RetentionPolicy; + import java.time.chrono.IsoEra; + + class A { + { + // The `List`-accepting overload is currently ignored. + Ordering.explicit(ImmutableList.of(RetentionPolicy.SOURCE, RetentionPolicy.CLASS)); + + Ordering.explicit(IsoEra.BCE, IsoEra.CE); + // BUG: Diagnostic contains: IsoEra.CE + Ordering.explicit(IsoEra.BCE); + // BUG: Diagnostic contains: IsoEra.BCE + Ordering.explicit(IsoEra.CE); + + Ordering.explicit(RetentionPolicy.SOURCE, RetentionPolicy.CLASS, RetentionPolicy.RUNTIME); + // BUG: Diagnostic contains: RetentionPolicy.CLASS, RetentionPolicy.RUNTIME + Ordering.explicit(RetentionPolicy.SOURCE); + // BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.RUNTIME + Ordering.explicit(RetentionPolicy.CLASS); + // BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.CLASS + Ordering.explicit(RetentionPolicy.RUNTIME); + // BUG: Diagnostic contains: RetentionPolicy.RUNTIME + Ordering.explicit(RetentionPolicy.SOURCE, RetentionPolicy.CLASS); + // BUG: Diagnostic contains: RetentionPolicy.CLASS + Ordering.explicit(RetentionPolicy.SOURCE, RetentionPolicy.RUNTIME); + // BUG: Diagnostic contains: RetentionPolicy.SOURCE + Ordering.explicit(RetentionPolicy.CLASS, RetentionPolicy.RUNTIME); + + Ordering.explicit(BCE, CE); + // BUG: Diagnostic contains: IsoEra.CE + Ordering.explicit(BCE); + // BUG: Diagnostic contains: IsoEra.BCE + Ordering.explicit(CE); + + Ordering.explicit(SOURCE, CLASS, RUNTIME); + // BUG: Diagnostic contains: RetentionPolicy.CLASS, RetentionPolicy.RUNTIME + Ordering.explicit(SOURCE); + // BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.RUNTIME + Ordering.explicit(CLASS); + // BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.CLASS + Ordering.explicit(RUNTIME); + // BUG: Diagnostic contains: RetentionPolicy.RUNTIME + Ordering.explicit(SOURCE, CLASS); + // BUG: Diagnostic contains: RetentionPolicy.CLASS + Ordering.explicit(SOURCE, RUNTIME); + // BUG: Diagnostic contains: RetentionPolicy.SOURCE + Ordering.explicit(CLASS, RUNTIME); + + Ordering.explicit(RetentionPolicy.SOURCE, BCE, RetentionPolicy.CLASS, CE, RUNTIME); + Ordering.explicit(SOURCE, IsoEra.BCE, CLASS, IsoEra.CE, RetentionPolicy.RUNTIME); + // BUG: Diagnostic contains: RetentionPolicy.CLASS + Ordering.explicit(RetentionPolicy.SOURCE, BCE, CE, RUNTIME); + // BUG: Diagnostic contains: RetentionPolicy.CLASS + Ordering.explicit(IsoEra.BCE, SOURCE, IsoEra.CE, RetentionPolicy.RUNTIME); + // BUG: Diagnostic contains: IsoEra.CE, RetentionPolicy.RUNTIME + Ordering.explicit(IsoEra.BCE, SOURCE, RetentionPolicy.CLASS); + // BUG: Diagnostic contains: RetentionPolicy.SOURCE, IsoEra.BCE + Ordering.explicit(CLASS, RUNTIME, CE); + } + } + """) .doTest(); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/FluxFlatMapUsageTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/FluxFlatMapUsageTest.java index a80414e18bb..20ab887fc52 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/FluxFlatMapUsageTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/FluxFlatMapUsageTest.java @@ -19,55 +19,57 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import java.util.function.BiFunction;", - "import java.util.function.Function;", - "import reactor.core.publisher.Flux;", - "import reactor.core.publisher.Mono;", - "", - "class A {", - " void m() {", - " // BUG: Diagnostic contains:", - " Flux.just(1).flatMap(Flux::just);", - " // BUG: Diagnostic contains:", - " Flux.just(1).flatMap(i -> Flux.just(String.valueOf(i)));", - " // BUG: Diagnostic contains:", - " Flux.just(1).flatMapSequential(Flux::just);", - " // BUG: Diagnostic contains:", - " Flux.just(1).flatMapSequential(i -> Flux.just(String.valueOf(i)));", - " // BUG: Diagnostic contains:", - " Flux.just(1, 2).groupBy(i -> i).flatMap(Flux::just);", - " // BUG: Diagnostic contains:", - " Flux.just(1, 2).groupBy(i -> i).flatMap(i -> Flux.just(String.valueOf(i)));", - " // BUG: Diagnostic contains:", - " Flux.just(1, 2).groupBy(i -> i).flatMapSequential(Flux::just);", - " // BUG: Diagnostic contains:", - " Flux.just(1, 2).groupBy(i -> i).flatMapSequential(i -> Flux.just(String.valueOf(i)));", - "", - " Mono.just(1).flatMap(Mono::just);", - " Flux.just(1).concatMap(Flux::just);", - "", - " Flux.just(1).flatMap(Flux::just, 1);", - " Flux.just(1).flatMap(Flux::just, 1, 1);", - " Flux.just(1).flatMap(Flux::just, throwable -> Flux.empty(), Flux::empty);", - "", - " Flux.just(1).flatMapSequential(Flux::just, 1);", - " Flux.just(1).flatMapSequential(Flux::just, 1, 1);", - "", - " // BUG: Diagnostic contains:", - " this.>sink(Flux::flatMap);", - " // BUG: Diagnostic contains:", - " this.>sink(Flux::flatMap);", - "", - " // BUG: Diagnostic contains:", - " this.>sink(Flux::flatMapSequential);", - " // BUG: Diagnostic contains:", - " this.>sink(Flux::flatMapSequential);", - "", - " this.>sink(Mono::flatMap);", - " }", - "", - " private void sink(BiFunction, P> fun) {}", - "}") + """ + import java.util.function.BiFunction; + import java.util.function.Function; + import reactor.core.publisher.Flux; + import reactor.core.publisher.Mono; + + class A { + void m() { + // BUG: Diagnostic contains: + Flux.just(1).flatMap(Flux::just); + // BUG: Diagnostic contains: + Flux.just(1).flatMap(i -> Flux.just(String.valueOf(i))); + // BUG: Diagnostic contains: + Flux.just(1).flatMapSequential(Flux::just); + // BUG: Diagnostic contains: + Flux.just(1).flatMapSequential(i -> Flux.just(String.valueOf(i))); + // BUG: Diagnostic contains: + Flux.just(1, 2).groupBy(i -> i).flatMap(Flux::just); + // BUG: Diagnostic contains: + Flux.just(1, 2).groupBy(i -> i).flatMap(i -> Flux.just(String.valueOf(i))); + // BUG: Diagnostic contains: + Flux.just(1, 2).groupBy(i -> i).flatMapSequential(Flux::just); + // BUG: Diagnostic contains: + Flux.just(1, 2).groupBy(i -> i).flatMapSequential(i -> Flux.just(String.valueOf(i))); + + Mono.just(1).flatMap(Mono::just); + Flux.just(1).concatMap(Flux::just); + + Flux.just(1).flatMap(Flux::just, 1); + Flux.just(1).flatMap(Flux::just, 1, 1); + Flux.just(1).flatMap(Flux::just, throwable -> Flux.empty(), Flux::empty); + + Flux.just(1).flatMapSequential(Flux::just, 1); + Flux.just(1).flatMapSequential(Flux::just, 1, 1); + + // BUG: Diagnostic contains: + this.>sink(Flux::flatMap); + // BUG: Diagnostic contains: + this.>sink(Flux::flatMap); + + // BUG: Diagnostic contains: + this.>sink(Flux::flatMapSequential); + // BUG: Diagnostic contains: + this.>sink(Flux::flatMapSequential); + + this.>sink(Mono::flatMap); + } + + private void sink(BiFunction, P> fun) {} + } + """) .doTest(); } @@ -77,32 +79,36 @@ void replacementFirstSuggestedFix() { .setFixChooser(FixChoosers.FIRST) .addInputLines( "A.java", - "import reactor.core.publisher.Flux;", - "", - "class A {", - " private static final int MAX_CONCURRENCY = 8;", - "", - " void m() {", - " Flux.just(1).flatMap(Flux::just);", - " Flux.just(1).flatMapSequential(Flux::just);", - " Flux.just(1, 2).groupBy(i -> i).flatMap(Flux::just);", - " Flux.just(1, 2).groupBy(i -> i).flatMapSequential(Flux::just);", - " }", - "}") + """ + import reactor.core.publisher.Flux; + + class A { + private static final int MAX_CONCURRENCY = 8; + + void m() { + Flux.just(1).flatMap(Flux::just); + Flux.just(1).flatMapSequential(Flux::just); + Flux.just(1, 2).groupBy(i -> i).flatMap(Flux::just); + Flux.just(1, 2).groupBy(i -> i).flatMapSequential(Flux::just); + } + } + """) .addOutputLines( "A.java", - "import reactor.core.publisher.Flux;", - "", - "class A {", - " private static final int MAX_CONCURRENCY = 8;", - "", - " void m() {", - " Flux.just(1).concatMap(Flux::just);", - " Flux.just(1).concatMap(Flux::just);", - " Flux.just(1, 2).groupBy(i -> i).flatMap(Flux::just, MAX_CONCURRENCY);", - " Flux.just(1, 2).groupBy(i -> i).flatMapSequential(Flux::just, MAX_CONCURRENCY);", - " }", - "}") + """ + import reactor.core.publisher.Flux; + + class A { + private static final int MAX_CONCURRENCY = 8; + + void m() { + Flux.just(1).concatMap(Flux::just); + Flux.just(1).concatMap(Flux::just); + Flux.just(1, 2).groupBy(i -> i).flatMap(Flux::just, MAX_CONCURRENCY); + Flux.just(1, 2).groupBy(i -> i).flatMapSequential(Flux::just, MAX_CONCURRENCY); + } + } + """) .doTest(TestMode.TEXT_MATCH); } @@ -112,32 +118,36 @@ void replacementSecondSuggestedFix() { .setFixChooser(FixChoosers.SECOND) .addInputLines( "A.java", - "import reactor.core.publisher.Flux;", - "", - "class A {", - " private static final int MAX_CONCURRENCY = 8;", - "", - " void m() {", - " Flux.just(1).flatMap(Flux::just);", - " Flux.just(1).flatMapSequential(Flux::just);", - " Flux.just(1, 2).groupBy(i -> i).flatMap(Flux::just);", - " Flux.just(1, 2).groupBy(i -> i).flatMapSequential(Flux::just);", - " }", - "}") + """ + import reactor.core.publisher.Flux; + + class A { + private static final int MAX_CONCURRENCY = 8; + + void m() { + Flux.just(1).flatMap(Flux::just); + Flux.just(1).flatMapSequential(Flux::just); + Flux.just(1, 2).groupBy(i -> i).flatMap(Flux::just); + Flux.just(1, 2).groupBy(i -> i).flatMapSequential(Flux::just); + } + } + """) .addOutputLines( "A.java", - "import reactor.core.publisher.Flux;", - "", - "class A {", - " private static final int MAX_CONCURRENCY = 8;", - "", - " void m() {", - " Flux.just(1).flatMap(Flux::just, MAX_CONCURRENCY);", - " Flux.just(1).flatMapSequential(Flux::just, MAX_CONCURRENCY);", - " Flux.just(1, 2).groupBy(i -> i).concatMap(Flux::just);", - " Flux.just(1, 2).groupBy(i -> i).concatMap(Flux::just);", - " }", - "}") + """ + import reactor.core.publisher.Flux; + + class A { + private static final int MAX_CONCURRENCY = 8; + + void m() { + Flux.just(1).flatMap(Flux::just, MAX_CONCURRENCY); + Flux.just(1).flatMapSequential(Flux::just, MAX_CONCURRENCY); + Flux.just(1, 2).groupBy(i -> i).concatMap(Flux::just); + Flux.just(1, 2).groupBy(i -> i).concatMap(Flux::just); + } + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/FormatStringConcatenationTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/FormatStringConcatenationTest.java index 3eac62e01cb..c94f46d2ae2 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/FormatStringConcatenationTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/FormatStringConcatenationTest.java @@ -16,294 +16,296 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import static com.google.common.base.Preconditions.checkArgument;", - "import static com.google.common.base.Preconditions.checkNotNull;", - "import static com.google.common.base.Preconditions.checkState;", - "import static com.google.common.base.Verify.verify;", - "import static org.assertj.core.api.Assertions.assertThat;", - "import static org.assertj.core.api.SoftAssertions.assertSoftly;", - "", - "import java.util.Formatter;", - "import java.util.Locale;", - "import org.assertj.core.api.Assertions;", - "import org.assertj.core.api.BDDAssertions;", - "import org.assertj.core.api.Fail;", - "import org.assertj.core.api.ThrowableAssertAlternative;", - "import org.assertj.core.api.WithAssertions;", - "import org.slf4j.Logger;", - "import org.slf4j.LoggerFactory;", - "import org.slf4j.Marker;", - "", - "class A {", - " private static final Logger LOG = LoggerFactory.getLogger(A.class);", - "", - " void negative() {", - " hashCode();", - " equals(new A());", - " equals(toString());", - " equals(0);", - " equals(\"str\");", - " equals(\"str\" + 0);", - " equals(0 + 0);", - " equals(0 - 0);", - " equals(\"str \" + toString());", - " }", - "", - " void assertj() {", - " assertThat(0).overridingErrorMessage(toString());", - " assertThat(0).overridingErrorMessage(\"str\");", - " assertThat(0).overridingErrorMessage(\"str \" + 0);", - " assertThat(0).overridingErrorMessage(\"str %s\", 2 * 3);", - " assertThat(0).overridingErrorMessage(\"str %s\", toString());", - " // BUG: Diagnostic contains:", - " assertThat(0).overridingErrorMessage(\"str \" + hashCode() / 2);", - " // BUG: Diagnostic contains:", - " assertThat(0).overridingErrorMessage((\"str \" + toString()));", - " // BUG: Diagnostic contains:", - " assertThat(0).overridingErrorMessage(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " assertThat(0).overridingErrorMessage(\"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " assertThat(0).withFailMessage(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " assertThat(0).withFailMessage(\"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " assertSoftly(softly -> softly.fail(\"str \" + toString()));", - " // BUG: Diagnostic contains:", - " assertSoftly(softly -> softly.fail(\"%s \" + toString(), \"arg\"));", - " assertSoftly(softly -> softly.fail(\"str \" + toString(), new Throwable()));", - "", - " // BUG: Diagnostic contains:", - " assertThat(\"\").isEqualTo(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " assertThat(\"\").isEqualTo(\"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " assertThat(new Error()).hasMessage(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " assertThat(new Error()).hasMessage(\"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " assertThat(new Error()).hasMessageContaining(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " assertThat(new Error()).hasMessageContaining(\"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " assertThat(new Error()).hasMessageEndingWith(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " assertThat(new Error()).hasMessageEndingWith(\"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " assertThat(new Error()).hasMessageStartingWith(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " assertThat(new Error()).hasMessageStartingWith(\"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " assertThat(new Error()).hasRootCauseMessage(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " assertThat(new Error()).hasRootCauseMessage(\"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " assertThat(new Error()).hasStackTraceContaining(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " assertThat(new Error()).hasStackTraceContaining(\"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " assertThat(0).as(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " assertThat(0).as(\"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " assertThat(0).describedAs(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " assertThat(0).describedAs(\"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " ((ThrowableAssertAlternative) null).withMessage(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " ((ThrowableAssertAlternative) null).withMessage(\"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " ((ThrowableAssertAlternative) null).withMessageContaining(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " ((ThrowableAssertAlternative) null).withMessageContaining(\"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " ((ThrowableAssertAlternative) null).withMessageEndingWith(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " ((ThrowableAssertAlternative) null).withMessageEndingWith(\"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " ((ThrowableAssertAlternative) null).withMessageStartingWith(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " ((ThrowableAssertAlternative) null).withMessageStartingWith(\"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " ((ThrowableAssertAlternative) null).withStackTraceContaining(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " ((ThrowableAssertAlternative) null).withStackTraceContaining(\"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " ((WithAssertions) null).fail(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " ((WithAssertions) null).fail(\"%s \" + toString(), \"arg\");", - " ((WithAssertions) null).fail(\"str \" + toString(), new Throwable());", - "", - " // BUG: Diagnostic contains:", - " Assertions.fail(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " Assertions.fail(\"%s \" + toString(), \"arg\");", - " Assertions.fail(\"str \" + toString(), new Throwable());", - "", - " // BUG: Diagnostic contains:", - " BDDAssertions.fail(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " BDDAssertions.fail(\"%s \" + toString(), \"arg\");", - " BDDAssertions.fail(\"str \" + toString(), new Throwable());", - "", - " // BUG: Diagnostic contains:", - " Fail.fail(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " Fail.fail(\"%s \" + toString(), \"arg\");", - " Fail.fail(\"str \" + toString(), new Throwable());", - " }", - "", - " void guava() {", - " checkArgument(true);", - " checkArgument(true, toString());", - " checkArgument(true, \"str\");", - " checkArgument(true, \"str \" + 0);", - " checkArgument(true, \"str %s\", 2 * 3);", - " checkArgument(true, \"str %s\", toString());", - " // BUG: Diagnostic contains:", - " checkArgument(true, \"str \" + hashCode() / 2);", - " // BUG: Diagnostic contains:", - " checkArgument(true, (\"str \" + toString()));", - " // BUG: Diagnostic contains:", - " checkArgument(true, \"str \" + toString());", - " // BUG: Diagnostic contains:", - " checkArgument(true, \"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " checkNotNull(true, \"str \" + toString());", - " // BUG: Diagnostic contains:", - " checkNotNull(true, \"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " checkState(true, \"str \" + toString());", - " // BUG: Diagnostic contains:", - " checkState(true, \"%s \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " verify(true, \"str \" + toString());", - " // BUG: Diagnostic contains:", - " verify(true, \"%s \" + toString(), \"arg\");", - " }", - "", - " void jdk() {", - " String.format(\"str\");", - " String.format(\"str \" + 0);", - " String.format(\"str {}\", 2 * 3);", - " String.format(\"str {}\", toString());", - " // BUG: Diagnostic contains:", - " String.format(\"str \" + hashCode() / 2);", - " // BUG: Diagnostic contains:", - " String.format((\"str \" + toString()));", - " // BUG: Diagnostic contains:", - " String.format(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " String.format(\"{} \" + toString(), \"arg\");", - "", - " String.format(Locale.ROOT, \"str\");", - " String.format(Locale.ROOT, \"str \" + 0);", - " String.format(Locale.ROOT, \"str {}\", 2 * 3);", - " String.format(Locale.ROOT, \"str {}\", toString());", - " // BUG: Diagnostic contains:", - " String.format(Locale.ROOT, (\"str \" + toString()));", - " // BUG: Diagnostic contains:", - " String.format(Locale.ROOT, \"str \" + toString());", - " // BUG: Diagnostic contains:", - " String.format(Locale.ROOT, \"{} \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " new Formatter().format(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " new Formatter().format(\"{} \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " new Formatter().format(Locale.ROOT, \"str \" + toString());", - " // BUG: Diagnostic contains:", - " new Formatter().format(Locale.ROOT, \"{} \" + toString(), \"arg\");", - " }", - "", - " void slf4j() {", - " LOG.debug(\"str\");", - " LOG.debug(\"str \" + 0);", - " LOG.debug(\"str {}\", 2 * 3);", - " LOG.debug(\"str {}\", toString());", - " // BUG: Diagnostic contains:", - " LOG.debug(\"str \" + hashCode() / 2);", - " // BUG: Diagnostic contains:", - " LOG.debug((\"str \" + toString()));", - " // BUG: Diagnostic contains:", - " LOG.debug(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " LOG.debug(\"{} \" + toString(), \"arg\");", - "", - " LOG.debug((Marker) null, \"str\");", - " LOG.debug((Marker) null, \"str \" + 0);", - " LOG.debug((Marker) null, \"str {}\", 2 * 3);", - " LOG.debug((Marker) null, \"str {}\", toString());", - " // BUG: Diagnostic contains:", - " LOG.debug((Marker) null, (\"str \" + toString()));", - " // BUG: Diagnostic contains:", - " LOG.debug((Marker) null, \"str \" + toString());", - " // BUG: Diagnostic contains:", - " LOG.debug((Marker) null, \"{} \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " LOG.error(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " LOG.error(\"{} \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " LOG.error((Marker) null, \"str \" + toString());", - " // BUG: Diagnostic contains:", - " LOG.error((Marker) null, \"{} \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " LOG.info(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " LOG.info(\"{} \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " LOG.info((Marker) null, \"str \" + toString());", - " // BUG: Diagnostic contains:", - " LOG.info((Marker) null, \"{} \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " LOG.trace(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " LOG.trace(\"{} \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " LOG.trace((Marker) null, \"str \" + toString());", - " // BUG: Diagnostic contains:", - " LOG.trace((Marker) null, \"{} \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " LOG.warn(\"str \" + toString());", - " // BUG: Diagnostic contains:", - " LOG.warn(\"{} \" + toString(), \"arg\");", - "", - " // BUG: Diagnostic contains:", - " LOG.warn((Marker) null, \"str \" + toString());", - " // BUG: Diagnostic contains:", - " LOG.warn((Marker) null, \"{} \" + toString(), \"arg\");", - " }", - "}") + """ + import static com.google.common.base.Preconditions.checkArgument; + import static com.google.common.base.Preconditions.checkNotNull; + import static com.google.common.base.Preconditions.checkState; + import static com.google.common.base.Verify.verify; + import static org.assertj.core.api.Assertions.assertThat; + import static org.assertj.core.api.SoftAssertions.assertSoftly; + + import java.util.Formatter; + import java.util.Locale; + import org.assertj.core.api.Assertions; + import org.assertj.core.api.BDDAssertions; + import org.assertj.core.api.Fail; + import org.assertj.core.api.ThrowableAssertAlternative; + import org.assertj.core.api.WithAssertions; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; + import org.slf4j.Marker; + + class A { + private static final Logger LOG = LoggerFactory.getLogger(A.class); + + void negative() { + hashCode(); + equals(new A()); + equals(toString()); + equals(0); + equals("str"); + equals("str" + 0); + equals(0 + 0); + equals(0 - 0); + equals("str " + toString()); + } + + void assertj() { + assertThat(0).overridingErrorMessage(toString()); + assertThat(0).overridingErrorMessage("str"); + assertThat(0).overridingErrorMessage("str " + 0); + assertThat(0).overridingErrorMessage("str %s", 2 * 3); + assertThat(0).overridingErrorMessage("str %s", toString()); + // BUG: Diagnostic contains: + assertThat(0).overridingErrorMessage("str " + hashCode() / 2); + // BUG: Diagnostic contains: + assertThat(0).overridingErrorMessage(("str " + toString())); + // BUG: Diagnostic contains: + assertThat(0).overridingErrorMessage("str " + toString()); + // BUG: Diagnostic contains: + assertThat(0).overridingErrorMessage("%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + assertThat(0).withFailMessage("str " + toString()); + // BUG: Diagnostic contains: + assertThat(0).withFailMessage("%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + assertSoftly(softly -> softly.fail("str " + toString())); + // BUG: Diagnostic contains: + assertSoftly(softly -> softly.fail("%s " + toString(), "arg")); + assertSoftly(softly -> softly.fail("str " + toString(), new Throwable())); + + // BUG: Diagnostic contains: + assertThat("").isEqualTo("str " + toString()); + // BUG: Diagnostic contains: + assertThat("").isEqualTo("%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + assertThat(new Error()).hasMessage("str " + toString()); + // BUG: Diagnostic contains: + assertThat(new Error()).hasMessage("%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + assertThat(new Error()).hasMessageContaining("str " + toString()); + // BUG: Diagnostic contains: + assertThat(new Error()).hasMessageContaining("%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + assertThat(new Error()).hasMessageEndingWith("str " + toString()); + // BUG: Diagnostic contains: + assertThat(new Error()).hasMessageEndingWith("%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + assertThat(new Error()).hasMessageStartingWith("str " + toString()); + // BUG: Diagnostic contains: + assertThat(new Error()).hasMessageStartingWith("%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + assertThat(new Error()).hasRootCauseMessage("str " + toString()); + // BUG: Diagnostic contains: + assertThat(new Error()).hasRootCauseMessage("%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + assertThat(new Error()).hasStackTraceContaining("str " + toString()); + // BUG: Diagnostic contains: + assertThat(new Error()).hasStackTraceContaining("%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + assertThat(0).as("str " + toString()); + // BUG: Diagnostic contains: + assertThat(0).as("%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + assertThat(0).describedAs("str " + toString()); + // BUG: Diagnostic contains: + assertThat(0).describedAs("%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + ((ThrowableAssertAlternative) null).withMessage("str " + toString()); + // BUG: Diagnostic contains: + ((ThrowableAssertAlternative) null).withMessage("%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + ((ThrowableAssertAlternative) null).withMessageContaining("str " + toString()); + // BUG: Diagnostic contains: + ((ThrowableAssertAlternative) null).withMessageContaining("%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + ((ThrowableAssertAlternative) null).withMessageEndingWith("str " + toString()); + // BUG: Diagnostic contains: + ((ThrowableAssertAlternative) null).withMessageEndingWith("%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + ((ThrowableAssertAlternative) null).withMessageStartingWith("str " + toString()); + // BUG: Diagnostic contains: + ((ThrowableAssertAlternative) null).withMessageStartingWith("%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + ((ThrowableAssertAlternative) null).withStackTraceContaining("str " + toString()); + // BUG: Diagnostic contains: + ((ThrowableAssertAlternative) null).withStackTraceContaining("%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + ((WithAssertions) null).fail("str " + toString()); + // BUG: Diagnostic contains: + ((WithAssertions) null).fail("%s " + toString(), "arg"); + ((WithAssertions) null).fail("str " + toString(), new Throwable()); + + // BUG: Diagnostic contains: + Assertions.fail("str " + toString()); + // BUG: Diagnostic contains: + Assertions.fail("%s " + toString(), "arg"); + Assertions.fail("str " + toString(), new Throwable()); + + // BUG: Diagnostic contains: + BDDAssertions.fail("str " + toString()); + // BUG: Diagnostic contains: + BDDAssertions.fail("%s " + toString(), "arg"); + BDDAssertions.fail("str " + toString(), new Throwable()); + + // BUG: Diagnostic contains: + Fail.fail("str " + toString()); + // BUG: Diagnostic contains: + Fail.fail("%s " + toString(), "arg"); + Fail.fail("str " + toString(), new Throwable()); + } + + void guava() { + checkArgument(true); + checkArgument(true, toString()); + checkArgument(true, "str"); + checkArgument(true, "str " + 0); + checkArgument(true, "str %s", 2 * 3); + checkArgument(true, "str %s", toString()); + // BUG: Diagnostic contains: + checkArgument(true, "str " + hashCode() / 2); + // BUG: Diagnostic contains: + checkArgument(true, ("str " + toString())); + // BUG: Diagnostic contains: + checkArgument(true, "str " + toString()); + // BUG: Diagnostic contains: + checkArgument(true, "%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + checkNotNull(true, "str " + toString()); + // BUG: Diagnostic contains: + checkNotNull(true, "%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + checkState(true, "str " + toString()); + // BUG: Diagnostic contains: + checkState(true, "%s " + toString(), "arg"); + + // BUG: Diagnostic contains: + verify(true, "str " + toString()); + // BUG: Diagnostic contains: + verify(true, "%s " + toString(), "arg"); + } + + void jdk() { + String.format("str"); + String.format("str " + 0); + String.format("str {}", 2 * 3); + String.format("str {}", toString()); + // BUG: Diagnostic contains: + String.format("str " + hashCode() / 2); + // BUG: Diagnostic contains: + String.format(("str " + toString())); + // BUG: Diagnostic contains: + String.format("str " + toString()); + // BUG: Diagnostic contains: + String.format("{} " + toString(), "arg"); + + String.format(Locale.ROOT, "str"); + String.format(Locale.ROOT, "str " + 0); + String.format(Locale.ROOT, "str {}", 2 * 3); + String.format(Locale.ROOT, "str {}", toString()); + // BUG: Diagnostic contains: + String.format(Locale.ROOT, ("str " + toString())); + // BUG: Diagnostic contains: + String.format(Locale.ROOT, "str " + toString()); + // BUG: Diagnostic contains: + String.format(Locale.ROOT, "{} " + toString(), "arg"); + + // BUG: Diagnostic contains: + new Formatter().format("str " + toString()); + // BUG: Diagnostic contains: + new Formatter().format("{} " + toString(), "arg"); + + // BUG: Diagnostic contains: + new Formatter().format(Locale.ROOT, "str " + toString()); + // BUG: Diagnostic contains: + new Formatter().format(Locale.ROOT, "{} " + toString(), "arg"); + } + + void slf4j() { + LOG.debug("str"); + LOG.debug("str " + 0); + LOG.debug("str {}", 2 * 3); + LOG.debug("str {}", toString()); + // BUG: Diagnostic contains: + LOG.debug("str " + hashCode() / 2); + // BUG: Diagnostic contains: + LOG.debug(("str " + toString())); + // BUG: Diagnostic contains: + LOG.debug("str " + toString()); + // BUG: Diagnostic contains: + LOG.debug("{} " + toString(), "arg"); + + LOG.debug((Marker) null, "str"); + LOG.debug((Marker) null, "str " + 0); + LOG.debug((Marker) null, "str {}", 2 * 3); + LOG.debug((Marker) null, "str {}", toString()); + // BUG: Diagnostic contains: + LOG.debug((Marker) null, ("str " + toString())); + // BUG: Diagnostic contains: + LOG.debug((Marker) null, "str " + toString()); + // BUG: Diagnostic contains: + LOG.debug((Marker) null, "{} " + toString(), "arg"); + + // BUG: Diagnostic contains: + LOG.error("str " + toString()); + // BUG: Diagnostic contains: + LOG.error("{} " + toString(), "arg"); + + // BUG: Diagnostic contains: + LOG.error((Marker) null, "str " + toString()); + // BUG: Diagnostic contains: + LOG.error((Marker) null, "{} " + toString(), "arg"); + + // BUG: Diagnostic contains: + LOG.info("str " + toString()); + // BUG: Diagnostic contains: + LOG.info("{} " + toString(), "arg"); + + // BUG: Diagnostic contains: + LOG.info((Marker) null, "str " + toString()); + // BUG: Diagnostic contains: + LOG.info((Marker) null, "{} " + toString(), "arg"); + + // BUG: Diagnostic contains: + LOG.trace("str " + toString()); + // BUG: Diagnostic contains: + LOG.trace("{} " + toString(), "arg"); + + // BUG: Diagnostic contains: + LOG.trace((Marker) null, "str " + toString()); + // BUG: Diagnostic contains: + LOG.trace((Marker) null, "{} " + toString(), "arg"); + + // BUG: Diagnostic contains: + LOG.warn("str " + toString()); + // BUG: Diagnostic contains: + LOG.warn("{} " + toString(), "arg"); + + // BUG: Diagnostic contains: + LOG.warn((Marker) null, "str " + toString()); + // BUG: Diagnostic contains: + LOG.warn((Marker) null, "{} " + toString(), "arg"); + } + } + """) .doTest(); } @@ -312,102 +314,106 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "import static com.google.common.base.Preconditions.checkArgument;", - "import static org.assertj.core.api.Assertions.assertThat;", - "", - "import java.util.Locale;", - "import org.slf4j.Logger;", - "import org.slf4j.LoggerFactory;", - "import org.slf4j.Marker;", - "", - "class A {", - " private static final Logger LOG = LoggerFactory.getLogger(A.class);", - "", - " void assertj() {", - " assertThat(0).overridingErrorMessage(toString() + \" str\");", - " assertThat(0).overridingErrorMessage(\"str \" + toString());", - " assertThat(0).overridingErrorMessage(toString() + toString());", - " assertThat(0).overridingErrorMessage(\"str \" + toString() + \" word \" + new A().hashCode());", - " assertThat(0).overridingErrorMessage(\"str \" + (toString() + \" word \") + (hashCode() / 2));", - "", - " // Flagged but not auto-fixed.", - " assertThat(0).overridingErrorMessage(\"%s \" + toString(), \"arg\");", - " }", - "", - " void guava() {", - " checkArgument(true, \"str \" + toString());", - "", - " // Flagged but not auto-fixed.", - " checkArgument(true, \"%s \" + toString(), \"arg\");", - " }", - "", - " void jdk() {", - " String.format(\"str \" + toString());", - " String.format(Locale.ROOT, \"str \" + toString());", - "", - " // Flagged but not auto-fixed.", - " String.format(\"{} \" + toString(), \"arg\");", - " String.format(Locale.ROOT, \"{} \" + toString(), \"arg\");", - " }", - "", - " void slf4j() {", - " LOG.debug(\"str \" + toString());", - " LOG.debug((Marker) null, \"str \" + toString());", - "", - " // Flagged but not auto-fixed.", - " LOG.debug(\"{} \" + toString(), \"arg\");", - " LOG.debug((Marker) null, \"{} \" + toString(), \"arg\");", - " }", - "}") + """ + import static com.google.common.base.Preconditions.checkArgument; + import static org.assertj.core.api.Assertions.assertThat; + + import java.util.Locale; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; + import org.slf4j.Marker; + + class A { + private static final Logger LOG = LoggerFactory.getLogger(A.class); + + void assertj() { + assertThat(0).overridingErrorMessage(toString() + " str"); + assertThat(0).overridingErrorMessage("str " + toString()); + assertThat(0).overridingErrorMessage(toString() + toString()); + assertThat(0).overridingErrorMessage("str " + toString() + " word " + new A().hashCode()); + assertThat(0).overridingErrorMessage("str " + (toString() + " word ") + (hashCode() / 2)); + + // Flagged but not auto-fixed. + assertThat(0).overridingErrorMessage("%s " + toString(), "arg"); + } + + void guava() { + checkArgument(true, "str " + toString()); + + // Flagged but not auto-fixed. + checkArgument(true, "%s " + toString(), "arg"); + } + + void jdk() { + String.format("str " + toString()); + String.format(Locale.ROOT, "str " + toString()); + + // Flagged but not auto-fixed. + String.format("{} " + toString(), "arg"); + String.format(Locale.ROOT, "{} " + toString(), "arg"); + } + + void slf4j() { + LOG.debug("str " + toString()); + LOG.debug((Marker) null, "str " + toString()); + + // Flagged but not auto-fixed. + LOG.debug("{} " + toString(), "arg"); + LOG.debug((Marker) null, "{} " + toString(), "arg"); + } + } + """) .addOutputLines( "A.java", - "import static com.google.common.base.Preconditions.checkArgument;", - "import static org.assertj.core.api.Assertions.assertThat;", - "", - "import java.util.Locale;", - "import org.slf4j.Logger;", - "import org.slf4j.LoggerFactory;", - "import org.slf4j.Marker;", - "", - "class A {", - " private static final Logger LOG = LoggerFactory.getLogger(A.class);", - "", - " void assertj() {", - " assertThat(0).overridingErrorMessage(\"%s str\", toString());", - " assertThat(0).overridingErrorMessage(\"str %s\", toString());", - " assertThat(0).overridingErrorMessage(\"%s%s\", toString(), toString());", - " assertThat(0).overridingErrorMessage(\"str %s word %s\", toString(), new A().hashCode());", - " assertThat(0).overridingErrorMessage(\"str %s word %s\", toString(), hashCode() / 2);", - "", - " // Flagged but not auto-fixed.", - " assertThat(0).overridingErrorMessage(\"%s \" + toString(), \"arg\");", - " }", - "", - " void guava() {", - " checkArgument(true, \"str %s\", toString());", - "", - " // Flagged but not auto-fixed.", - " checkArgument(true, \"%s \" + toString(), \"arg\");", - " }", - "", - " void jdk() {", - " String.format(\"str %s\", toString());", - " String.format(Locale.ROOT, \"str %s\", toString());", - "", - " // Flagged but not auto-fixed.", - " String.format(\"{} \" + toString(), \"arg\");", - " String.format(Locale.ROOT, \"{} \" + toString(), \"arg\");", - " }", - "", - " void slf4j() {", - " LOG.debug(\"str {}\", toString());", - " LOG.debug((Marker) null, \"str {}\", toString());", - "", - " // Flagged but not auto-fixed.", - " LOG.debug(\"{} \" + toString(), \"arg\");", - " LOG.debug((Marker) null, \"{} \" + toString(), \"arg\");", - " }", - "}") + """ + import static com.google.common.base.Preconditions.checkArgument; + import static org.assertj.core.api.Assertions.assertThat; + + import java.util.Locale; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; + import org.slf4j.Marker; + + class A { + private static final Logger LOG = LoggerFactory.getLogger(A.class); + + void assertj() { + assertThat(0).overridingErrorMessage("%s str", toString()); + assertThat(0).overridingErrorMessage("str %s", toString()); + assertThat(0).overridingErrorMessage("%s%s", toString(), toString()); + assertThat(0).overridingErrorMessage("str %s word %s", toString(), new A().hashCode()); + assertThat(0).overridingErrorMessage("str %s word %s", toString(), hashCode() / 2); + + // Flagged but not auto-fixed. + assertThat(0).overridingErrorMessage("%s " + toString(), "arg"); + } + + void guava() { + checkArgument(true, "str %s", toString()); + + // Flagged but not auto-fixed. + checkArgument(true, "%s " + toString(), "arg"); + } + + void jdk() { + String.format("str %s", toString()); + String.format(Locale.ROOT, "str %s", toString()); + + // Flagged but not auto-fixed. + String.format("{} " + toString(), "arg"); + String.format(Locale.ROOT, "{} " + toString(), "arg"); + } + + void slf4j() { + LOG.debug("str {}", toString()); + LOG.debug((Marker) null, "str {}", toString()); + + // Flagged but not auto-fixed. + LOG.debug("{} " + toString(), "arg"); + LOG.debug((Marker) null, "{} " + toString(), "arg"); + } + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/IdentityConversionTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/IdentityConversionTest.java index a8f867502a5..3fb474f2a7c 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/IdentityConversionTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/IdentityConversionTest.java @@ -17,148 +17,150 @@ void identification() { compilationTestHelper .addSourceLines( "Foo.java", - "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 reactor.adapter.rxjava.RxJava2Adapter;", - "import reactor.core.publisher.Flux;", - "import reactor.core.publisher.Mono;", - "", - "public final class Foo {", - " public void foo() {", - " // 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);", - "", - " String str1 = String.valueOf(0);", - " // BUG: Diagnostic contains:", - " String str2 = String.valueOf(\"1\");", - "", - " // BUG: Diagnostic contains:", - " ImmutableBiMap o1 = ImmutableBiMap.copyOf(ImmutableBiMap.of());", - " // BUG: Diagnostic contains:", - " ImmutableList o2 = ImmutableList.copyOf(ImmutableList.of());", - " ImmutableListMultimap o3 =", - " // BUG: Diagnostic contains:", - " ImmutableListMultimap.copyOf(ImmutableListMultimap.of());", - " // BUG: Diagnostic contains:", - " ImmutableMap o4 = ImmutableMap.copyOf(ImmutableMap.of());", - " // BUG: Diagnostic contains:", - " ImmutableMultimap o5 = ImmutableMultimap.copyOf(ImmutableMultimap.of());", - " // BUG: Diagnostic contains:", - " ImmutableMultiset o6 = ImmutableMultiset.copyOf(ImmutableMultiset.of());", - " // BUG: Diagnostic contains:", - " ImmutableRangeMap o7 = ImmutableRangeMap.copyOf(ImmutableRangeMap.of());", - " // BUG: Diagnostic contains:", - " ImmutableRangeSet o8 = ImmutableRangeSet.copyOf(ImmutableRangeSet.of());", - " // BUG: Diagnostic contains:", - " ImmutableSet o9 = ImmutableSet.copyOf(ImmutableSet.of());", - " ImmutableSetMultimap o10 =", - " // BUG: Diagnostic contains:", - " ImmutableSetMultimap.copyOf(ImmutableSetMultimap.of());", - " // BUG: Diagnostic contains:", - " ImmutableTable o11 = ImmutableTable.copyOf(ImmutableTable.of());", - "", - " // BUG: Diagnostic contains:", - " Flux flux1 = Flux.just(1).flatMap(e -> RxJava2Adapter.fluxToFlowable(Flux.just(2)));", - " // BUG: Diagnostic contains:", - " Flux flux2 = Flux.concat(Flux.just(1));", - " // BUG: Diagnostic contains:", - " Flux flux3 = Flux.firstWithSignal(Flux.just(1));", - " // BUG: Diagnostic contains:", - " Flux flux4 = Flux.from(Flux.just(1));", - " // BUG: Diagnostic contains:", - " Flux flux5 = Flux.merge(Flux.just(1));", - "", - " // BUG: Diagnostic contains:", - " Mono m1 = Mono.from(Mono.just(1));", - " // BUG: Diagnostic contains:", - " Mono m2 = Mono.fromDirect(Mono.just(1));", - " }", - "}") + """ + 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 reactor.adapter.rxjava.RxJava2Adapter; + import reactor.core.publisher.Flux; + import reactor.core.publisher.Mono; + + public final class Foo { + public void foo() { + // 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); + + String str1 = String.valueOf(0); + // BUG: Diagnostic contains: + String str2 = String.valueOf("1"); + + // BUG: Diagnostic contains: + ImmutableBiMap o1 = ImmutableBiMap.copyOf(ImmutableBiMap.of()); + // BUG: Diagnostic contains: + ImmutableList o2 = ImmutableList.copyOf(ImmutableList.of()); + ImmutableListMultimap o3 = + // BUG: Diagnostic contains: + ImmutableListMultimap.copyOf(ImmutableListMultimap.of()); + // BUG: Diagnostic contains: + ImmutableMap o4 = ImmutableMap.copyOf(ImmutableMap.of()); + // BUG: Diagnostic contains: + ImmutableMultimap o5 = ImmutableMultimap.copyOf(ImmutableMultimap.of()); + // BUG: Diagnostic contains: + ImmutableMultiset o6 = ImmutableMultiset.copyOf(ImmutableMultiset.of()); + // BUG: Diagnostic contains: + ImmutableRangeMap o7 = ImmutableRangeMap.copyOf(ImmutableRangeMap.of()); + // BUG: Diagnostic contains: + ImmutableRangeSet o8 = ImmutableRangeSet.copyOf(ImmutableRangeSet.of()); + // BUG: Diagnostic contains: + ImmutableSet o9 = ImmutableSet.copyOf(ImmutableSet.of()); + ImmutableSetMultimap o10 = + // BUG: Diagnostic contains: + ImmutableSetMultimap.copyOf(ImmutableSetMultimap.of()); + // BUG: Diagnostic contains: + ImmutableTable o11 = ImmutableTable.copyOf(ImmutableTable.of()); + + // BUG: Diagnostic contains: + Flux flux1 = Flux.just(1).flatMap(e -> RxJava2Adapter.fluxToFlowable(Flux.just(2))); + // BUG: Diagnostic contains: + Flux flux2 = Flux.concat(Flux.just(1)); + // BUG: Diagnostic contains: + Flux flux3 = Flux.firstWithSignal(Flux.just(1)); + // BUG: Diagnostic contains: + Flux flux4 = Flux.from(Flux.just(1)); + // BUG: Diagnostic contains: + Flux flux5 = Flux.merge(Flux.just(1)); + + // BUG: Diagnostic contains: + Mono m1 = Mono.from(Mono.just(1)); + // BUG: Diagnostic contains: + Mono m2 = Mono.fromDirect(Mono.just(1)); + } + } + """) .doTest(); } @@ -168,94 +170,98 @@ void replacementFirstSuggestedFix() { .setFixChooser(FixChoosers.FIRST) .addInputLines( "Foo.java", - "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;", - "import org.reactivestreams.Publisher;", - "import reactor.adapter.rxjava.RxJava2Adapter;", - "import reactor.core.publisher.Flux;", - "import reactor.core.publisher.Mono;", - "", - "public final class Foo {", - " public void foo() {", - " ImmutableSet set1 = ImmutableSet.copyOf(ImmutableSet.of());", - " ImmutableSet set2 = ImmutableSet.copyOf(ImmutableList.of());", - "", - " ImmutableCollection list1 = ImmutableList.copyOf(ImmutableList.of(1));", - " ImmutableCollection list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));", - "", - " Collection c1 = ImmutableSet.copyOf(ImmutableSet.of(1));", - " Collection c2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));", - "", - " Flux f1 = Flux.just(1).flatMap(e -> RxJava2Adapter.fluxToFlowable(Flux.just(2)));", - " Flux f2 = Flux.concat(Flux.just(3));", - " Publisher f3 = Flux.firstWithSignal(Flux.just(4));", - " Publisher f4 = Flux.from(Flux.just(5));", - " Publisher f5 = Flux.merge(Flux.just(6));", - "", - " Mono m1 = Mono.from(Mono.just(7));", - " Publisher m2 = Mono.fromDirect(Mono.just(8));", - "", - " bar(Flux.concat(Flux.just(9)));", - " bar(Mono.from(Mono.just(10)));", - "", - " Object o1 = ImmutableSet.copyOf(ImmutableList.of());", - " Object o2 = ImmutableSet.copyOf(ImmutableSet.of());", - "", - " when(\"foo\".contains(\"f\")).thenAnswer(inv -> ImmutableSet.copyOf(ImmutableList.of(1)));", - " }", - "", - " void bar(Publisher publisher) {}", - "}") + """ + 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; + import org.reactivestreams.Publisher; + import reactor.adapter.rxjava.RxJava2Adapter; + import reactor.core.publisher.Flux; + import reactor.core.publisher.Mono; + + public final class Foo { + public void foo() { + ImmutableSet set1 = ImmutableSet.copyOf(ImmutableSet.of()); + ImmutableSet set2 = ImmutableSet.copyOf(ImmutableList.of()); + + ImmutableCollection list1 = ImmutableList.copyOf(ImmutableList.of(1)); + ImmutableCollection list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1))); + + Collection c1 = ImmutableSet.copyOf(ImmutableSet.of(1)); + Collection c2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1))); + + Flux f1 = Flux.just(1).flatMap(e -> RxJava2Adapter.fluxToFlowable(Flux.just(2))); + Flux f2 = Flux.concat(Flux.just(3)); + Publisher f3 = Flux.firstWithSignal(Flux.just(4)); + Publisher f4 = Flux.from(Flux.just(5)); + Publisher f5 = Flux.merge(Flux.just(6)); + + Mono m1 = Mono.from(Mono.just(7)); + Publisher m2 = Mono.fromDirect(Mono.just(8)); + + bar(Flux.concat(Flux.just(9))); + bar(Mono.from(Mono.just(10))); + + Object o1 = ImmutableSet.copyOf(ImmutableList.of()); + Object o2 = ImmutableSet.copyOf(ImmutableSet.of()); + + when("foo".contains("f")).thenAnswer(inv -> ImmutableSet.copyOf(ImmutableList.of(1))); + } + + void bar(Publisher publisher) {} + } + """) .addOutputLines( "Foo.java", - "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;", - "import org.reactivestreams.Publisher;", - "import reactor.adapter.rxjava.RxJava2Adapter;", - "import reactor.core.publisher.Flux;", - "import reactor.core.publisher.Mono;", - "", - "public final class Foo {", - " public void foo() {", - " ImmutableSet set1 = ImmutableSet.of();", - " ImmutableSet set2 = ImmutableSet.copyOf(ImmutableList.of());", - "", - " ImmutableCollection list1 = ImmutableList.of(1);", - " ImmutableCollection list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));", - "", - " Collection c1 = ImmutableSet.of(1);", - " Collection c2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));", - "", - " Flux f1 = Flux.just(1).flatMap(e -> Flux.just(2));", - " Flux f2 = Flux.just(3);", - " Publisher f3 = Flux.just(4);", - " Publisher f4 = Flux.just(5);", - " Publisher f5 = Flux.just(6);", - "", - " Mono m1 = Mono.just(7);", - " Publisher m2 = Mono.just(8);", - "", - " bar(Flux.just(9));", - " bar(Mono.just(10));", - "", - " Object o1 = ImmutableSet.copyOf(ImmutableList.of());", - " Object o2 = ImmutableSet.of();", - "", - " when(\"foo\".contains(\"f\")).thenAnswer(inv -> ImmutableSet.copyOf(ImmutableList.of(1)));", - " }", - "", - " void bar(Publisher publisher) {}", - "}") + """ + 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; + import org.reactivestreams.Publisher; + import reactor.adapter.rxjava.RxJava2Adapter; + import reactor.core.publisher.Flux; + import reactor.core.publisher.Mono; + + public final class Foo { + public void foo() { + ImmutableSet set1 = ImmutableSet.of(); + ImmutableSet set2 = ImmutableSet.copyOf(ImmutableList.of()); + + ImmutableCollection list1 = ImmutableList.of(1); + ImmutableCollection list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1))); + + Collection c1 = ImmutableSet.of(1); + Collection c2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1))); + + Flux f1 = Flux.just(1).flatMap(e -> Flux.just(2)); + Flux f2 = Flux.just(3); + Publisher f3 = Flux.just(4); + Publisher f4 = Flux.just(5); + Publisher f5 = Flux.just(6); + + Mono m1 = Mono.just(7); + Publisher m2 = Mono.just(8); + + bar(Flux.just(9)); + bar(Mono.just(10)); + + Object o1 = ImmutableSet.copyOf(ImmutableList.of()); + Object o2 = ImmutableSet.of(); + + when("foo".contains("f")).thenAnswer(inv -> ImmutableSet.copyOf(ImmutableList.of(1))); + } + + void bar(Publisher publisher) {} + } + """) .doTest(TestMode.TEXT_MATCH); } @@ -265,38 +271,42 @@ void replacementSecondSuggestedFix() { .setFixChooser(FixChoosers.SECOND) .addInputLines( "Foo.java", - "import com.google.common.collect.ImmutableCollection;", - "import com.google.common.collect.ImmutableList;", - "import com.google.common.collect.ImmutableSet;", - "import java.util.ArrayList;", - "", - "public final class Foo {", - " public void foo() {", - " ImmutableSet set1 = ImmutableSet.copyOf(ImmutableSet.of());", - " ImmutableSet set2 = ImmutableSet.copyOf(ImmutableList.of());", - "", - " ImmutableCollection list1 = ImmutableList.copyOf(ImmutableList.of(1));", - " ImmutableCollection list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));", - " }", - "}") + """ + import com.google.common.collect.ImmutableCollection; + import com.google.common.collect.ImmutableList; + import com.google.common.collect.ImmutableSet; + import java.util.ArrayList; + + public final class Foo { + public void foo() { + ImmutableSet set1 = ImmutableSet.copyOf(ImmutableSet.of()); + ImmutableSet set2 = ImmutableSet.copyOf(ImmutableList.of()); + + ImmutableCollection list1 = ImmutableList.copyOf(ImmutableList.of(1)); + ImmutableCollection list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1))); + } + } + """) .addOutputLines( "Foo.java", - "import com.google.common.collect.ImmutableCollection;", - "import com.google.common.collect.ImmutableList;", - "import com.google.common.collect.ImmutableSet;", - "import java.util.ArrayList;", - "", - "public final class Foo {", - " public void foo() {", - " @SuppressWarnings(\"IdentityConversion\")", - " ImmutableSet set1 = ImmutableSet.copyOf(ImmutableSet.of());", - " ImmutableSet set2 = ImmutableSet.copyOf(ImmutableList.of());", - "", - " @SuppressWarnings(\"IdentityConversion\")", - " ImmutableCollection list1 = ImmutableList.copyOf(ImmutableList.of(1));", - " ImmutableCollection list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));", - " }", - "}") + """ + import com.google.common.collect.ImmutableCollection; + import com.google.common.collect.ImmutableList; + import com.google.common.collect.ImmutableSet; + import java.util.ArrayList; + + public final class Foo { + public void foo() { + @SuppressWarnings("IdentityConversion") + ImmutableSet set1 = ImmutableSet.copyOf(ImmutableSet.of()); + ImmutableSet set2 = ImmutableSet.copyOf(ImmutableList.of()); + + @SuppressWarnings("IdentityConversion") + ImmutableCollection list1 = ImmutableList.copyOf(ImmutableList.of(1)); + ImmutableCollection list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1))); + } + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ImmutablesSortedSetComparatorTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ImmutablesSortedSetComparatorTest.java index 3942c6de1e1..5a9109940bf 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ImmutablesSortedSetComparatorTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ImmutablesSortedSetComparatorTest.java @@ -16,94 +16,96 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import com.google.common.collect.ContiguousSet;", - "import com.google.common.collect.ImmutableSet;", - "import com.google.common.collect.ImmutableSortedSet;", - "import java.util.NavigableSet;", - "import java.util.Set;", - "import java.util.SortedSet;", - "import java.util.TreeSet;", - "import org.immutables.value.Value;", - "", - "interface A {", - " @Value.Immutable", - " interface ImmutableInterface {", - " Set set();", - "", - " // BUG: Diagnostic contains:", - " SortedSet sortedSet();", - "", - " @Value.NaturalOrder", - " SortedSet sortedSet2();", - " }", - "", - " @Value.Modifiable", - " interface ModifiableInterfaceWithDefaults {", - " @Value.Default", - " default Set set() {", - " return new TreeSet<>();", - " }", - "", - " @Value.Default", - " // BUG: Diagnostic contains:", - " default NavigableSet navigableSet() {", - " return new TreeSet<>();", - " }", - "", - " @Value.Default", - " @Value.ReverseOrder", - " default NavigableSet navigableSet2() {", - " return new TreeSet<>();", - " }", - "", - " default NavigableSet nonPropertyNavigableSet() {", - " return new TreeSet<>();", - " }", - " }", - "", - " interface NonImmutablesInterface {", - " SortedSet sortedSet();", - " }", - "", - " @Value.Immutable", - " abstract class AbstractImmutableWithDefaults {", - " @Value.Default", - " ImmutableSet immutableSet() {", - " return ImmutableSet.of();", - " }", - "", - " @Value.Default", - " // BUG: Diagnostic contains:", - " ImmutableSortedSet immutableSortedSet() {", - " return ImmutableSortedSet.of();", - " }", - "", - " @Value.Default", - " @Value.NaturalOrder", - " ImmutableSortedSet immutableSortedSet2() {", - " return ImmutableSortedSet.of();", - " }", - "", - " ImmutableSortedSet nonPropertyImmutableSortedSet() {", - " return ImmutableSortedSet.of();", - " }", - " }", - "", - " @Value.Modifiable", - " abstract class AbstractModifiable {", - " abstract ImmutableSet immutableSet();", - "", - " // BUG: Diagnostic contains:", - " abstract ContiguousSet contiguousSet();", - "", - " @Value.ReverseOrder", - " abstract ContiguousSet contiguousSet2();", - " }", - "", - " abstract class AbstractNonImmutables {", - " abstract SortedSet sortedSet();", - " }", - "}") + """ + import com.google.common.collect.ContiguousSet; + import com.google.common.collect.ImmutableSet; + import com.google.common.collect.ImmutableSortedSet; + import java.util.NavigableSet; + import java.util.Set; + import java.util.SortedSet; + import java.util.TreeSet; + import org.immutables.value.Value; + + interface A { + @Value.Immutable + interface ImmutableInterface { + Set set(); + + // BUG: Diagnostic contains: + SortedSet sortedSet(); + + @Value.NaturalOrder + SortedSet sortedSet2(); + } + + @Value.Modifiable + interface ModifiableInterfaceWithDefaults { + @Value.Default + default Set set() { + return new TreeSet<>(); + } + + @Value.Default + // BUG: Diagnostic contains: + default NavigableSet navigableSet() { + return new TreeSet<>(); + } + + @Value.Default + @Value.ReverseOrder + default NavigableSet navigableSet2() { + return new TreeSet<>(); + } + + default NavigableSet nonPropertyNavigableSet() { + return new TreeSet<>(); + } + } + + interface NonImmutablesInterface { + SortedSet sortedSet(); + } + + @Value.Immutable + abstract class AbstractImmutableWithDefaults { + @Value.Default + ImmutableSet immutableSet() { + return ImmutableSet.of(); + } + + @Value.Default + // BUG: Diagnostic contains: + ImmutableSortedSet immutableSortedSet() { + return ImmutableSortedSet.of(); + } + + @Value.Default + @Value.NaturalOrder + ImmutableSortedSet immutableSortedSet2() { + return ImmutableSortedSet.of(); + } + + ImmutableSortedSet nonPropertyImmutableSortedSet() { + return ImmutableSortedSet.of(); + } + } + + @Value.Modifiable + abstract class AbstractModifiable { + abstract ImmutableSet immutableSet(); + + // BUG: Diagnostic contains: + abstract ContiguousSet contiguousSet(); + + @Value.ReverseOrder + abstract ContiguousSet contiguousSet2(); + } + + abstract class AbstractNonImmutables { + abstract SortedSet sortedSet(); + } + } + """) .doTest(); } @@ -112,36 +114,40 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "import com.google.common.collect.ImmutableSortedSet;", - "import java.util.SortedSet;", - "import org.immutables.value.Value;", - "", - "@Value.Immutable", - "abstract class A {", - " abstract ImmutableSortedSet sortedSet();", - "", - " @Value.Modifiable", - " interface B {", - " SortedSet sortedSet();", - " }", - "}") + """ + import com.google.common.collect.ImmutableSortedSet; + import java.util.SortedSet; + import org.immutables.value.Value; + + @Value.Immutable + abstract class A { + abstract ImmutableSortedSet sortedSet(); + + @Value.Modifiable + interface B { + SortedSet sortedSet(); + } + } + """) .addOutputLines( "A.java", - "import com.google.common.collect.ImmutableSortedSet;", - "import java.util.SortedSet;", - "import org.immutables.value.Value;", - "", - "@Value.Immutable", - "abstract class A {", - " @Value.NaturalOrder", - " abstract ImmutableSortedSet sortedSet();", - "", - " @Value.Modifiable", - " interface B {", - " @Value.NaturalOrder", - " SortedSet sortedSet();", - " }", - "}") + """ + import com.google.common.collect.ImmutableSortedSet; + import java.util.SortedSet; + import org.immutables.value.Value; + + @Value.Immutable + abstract class A { + @Value.NaturalOrder + abstract ImmutableSortedSet sortedSet(); + + @Value.Modifiable + interface B { + @Value.NaturalOrder + SortedSet sortedSet(); + } + } + """) .doTest(TestMode.TEXT_MATCH); } @@ -150,33 +156,37 @@ void replacementWithImportClash() { refactoringTestHelper .addInputLines( "MySpringService.java", - "import com.google.common.collect.ImmutableSortedSet;", - "import org.springframework.beans.factory.annotation.Value;", - "", - "class MySpringService {", - " MySpringService(@Value(\"${someProperty}\") String prop) {}", - " ;", - "", - " @org.immutables.value.Value.Immutable", - " interface A {", - " ImmutableSortedSet sortedSet();", - " }", - "}") + """ + import com.google.common.collect.ImmutableSortedSet; + import org.springframework.beans.factory.annotation.Value; + + class MySpringService { + MySpringService(@Value("${someProperty}") String prop) {} + ; + + @org.immutables.value.Value.Immutable + interface A { + ImmutableSortedSet sortedSet(); + } + } + """) .addOutputLines( "MySpringService.java", - "import com.google.common.collect.ImmutableSortedSet;", - "import org.springframework.beans.factory.annotation.Value;", - "", - "class MySpringService {", - " MySpringService(@Value(\"${someProperty}\") String prop) {}", - " ;", - "", - " @org.immutables.value.Value.Immutable", - " interface A {", - " @org.immutables.value.Value.NaturalOrder", - " ImmutableSortedSet sortedSet();", - " }", - "}") + """ + import com.google.common.collect.ImmutableSortedSet; + import org.springframework.beans.factory.annotation.Value; + + class MySpringService { + MySpringService(@Value("${someProperty}") String prop) {} + ; + + @org.immutables.value.Value.Immutable + interface A { + @org.immutables.value.Value.NaturalOrder + ImmutableSortedSet sortedSet(); + } + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/IsInstanceLambdaUsageTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/IsInstanceLambdaUsageTest.java index 205cebd270e..b5e091828a2 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/IsInstanceLambdaUsageTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/IsInstanceLambdaUsageTest.java @@ -16,15 +16,17 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import java.util.stream.Stream;", - "", - "class A {", - " void m() {", - " // BUG: Diagnostic contains:", - " Stream.of(1).filter(i -> i instanceof Integer);", - " Stream.of(2).filter(Integer.class::isInstance);", - " }", - "}") + """ + import java.util.stream.Stream; + + class A { + void m() { + // BUG: Diagnostic contains: + Stream.of(1).filter(i -> i instanceof Integer); + Stream.of(2).filter(Integer.class::isInstance); + } + } + """) .doTest(); } @@ -33,22 +35,26 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "import java.util.stream.Stream;", - "", - "class A {", - " void m() {", - " Stream.of(1).filter(i -> i instanceof Integer);", - " }", - "}") + """ + import java.util.stream.Stream; + + class A { + void m() { + Stream.of(1).filter(i -> i instanceof Integer); + } + } + """) .addOutputLines( "A.java", - "import java.util.stream.Stream;", - "", - "class A {", - " void m() {", - " Stream.of(1).filter(Integer.class::isInstance);", - " }", - "}") + """ + import java.util.stream.Stream; + + class A { + void m() { + Stream.of(1).filter(Integer.class::isInstance); + } + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/JUnitMethodDeclarationTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/JUnitMethodDeclarationTest.java index 2320daf7c9e..c7fa86a186d 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/JUnitMethodDeclarationTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/JUnitMethodDeclarationTest.java @@ -16,291 +16,297 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import static org.junit.jupiter.params.provider.Arguments.arguments;", - "", - "import org.junit.jupiter.api.AfterAll;", - "import org.junit.jupiter.api.AfterEach;", - "import org.junit.jupiter.api.BeforeAll;", - "import org.junit.jupiter.api.BeforeEach;", - "import org.junit.jupiter.api.Test;", - "import org.junit.jupiter.params.ParameterizedTest;", - "", - "class A {", - " {", - " arguments();", - " }", - "", - " @BeforeAll", - " void setUp1() {}", - "", - " @BeforeAll", - " // BUG: Diagnostic contains:", - " public void setUp2() {}", - "", - " @BeforeAll", - " // BUG: Diagnostic contains:", - " protected void setUp3() {}", - "", - " @BeforeAll", - " // BUG: Diagnostic contains:", - " private void setUp4() {}", - "", - " @BeforeEach", - " void setup5() {}", - "", - " @BeforeEach", - " // BUG: Diagnostic contains:", - " public void setUp6() {}", - "", - " @BeforeEach", - " // BUG: Diagnostic contains:", - " protected void setUp7() {}", - "", - " @BeforeEach", - " // BUG: Diagnostic contains:", - " private void setUp8() {}", - "", - " @AfterEach", - " void tearDown1() {}", - "", - " @AfterEach", - " // BUG: Diagnostic contains:", - " public void tearDown2() {}", - "", - " @AfterEach", - " // BUG: Diagnostic contains:", - " protected void tearDown3() {}", - "", - " @AfterEach", - " // BUG: Diagnostic contains:", - " private void tearDown4() {}", - "", - " @AfterAll", - " void tearDown5() {}", - "", - " @AfterAll", - " // BUG: Diagnostic contains:", - " public void tearDown6() {}", - "", - " @AfterAll", - " // BUG: Diagnostic contains:", - " protected void tearDown7() {}", - "", - " @AfterAll", - " // BUG: Diagnostic contains:", - " private void tearDown8() {}", - "", - " @Test", - " void method1() {}", - "", - " @Test", - " // BUG: Diagnostic contains:", - " void testMethod2() {}", - "", - " @Test", - " // BUG: Diagnostic contains:", - " public void method3() {}", - "", - " @Test", - " // BUG: Diagnostic contains:", - " protected void method4() {}", - "", - " @Test", - " // BUG: Diagnostic contains:", - " private void method5() {}", - "", - " @ParameterizedTest", - " void method6() {}", - "", - " @ParameterizedTest", - " // BUG: Diagnostic contains:", - " void testMethod7() {}", - "", - " @ParameterizedTest", - " // BUG: Diagnostic contains:", - " public void method8() {}", - "", - " @ParameterizedTest", - " // BUG: Diagnostic contains:", - " protected void method9() {}", - "", - " @ParameterizedTest", - " // BUG: Diagnostic contains:", - " private void method10() {}", - "", - " @BeforeEach", - " @BeforeAll", - " @AfterEach", - " @AfterAll", - " void testNonTestMethod1() {}", - "", - " public void testNonTestMethod2() {}", - "", - " protected void testNonTestMethod3() {}", - "", - " private void testNonTestMethod4() {}", - "", - " @Test", - " void test5() {}", - "", - " @Test", - " // BUG: Diagnostic contains: (but note that a method named `overload` already exists in this", - " // class)", - " void testOverload() {}", - "", - " void overload() {}", - "", - " @Test", - " // BUG: Diagnostic contains: (but note that `arguments` is already statically imported)", - " void testArguments() {}", - "", - " @Test", - " // BUG: Diagnostic contains: (but note that `public` is a reserved keyword)", - " void testPublic() {}", - "}") + """ + import static org.junit.jupiter.params.provider.Arguments.arguments; + + import org.junit.jupiter.api.AfterAll; + import org.junit.jupiter.api.AfterEach; + import org.junit.jupiter.api.BeforeAll; + import org.junit.jupiter.api.BeforeEach; + import org.junit.jupiter.api.Test; + import org.junit.jupiter.params.ParameterizedTest; + + class A { + { + arguments(); + } + + @BeforeAll + void setUp1() {} + + @BeforeAll + // BUG: Diagnostic contains: + public void setUp2() {} + + @BeforeAll + // BUG: Diagnostic contains: + protected void setUp3() {} + + @BeforeAll + // BUG: Diagnostic contains: + private void setUp4() {} + + @BeforeEach + void setup5() {} + + @BeforeEach + // BUG: Diagnostic contains: + public void setUp6() {} + + @BeforeEach + // BUG: Diagnostic contains: + protected void setUp7() {} + + @BeforeEach + // BUG: Diagnostic contains: + private void setUp8() {} + + @AfterEach + void tearDown1() {} + + @AfterEach + // BUG: Diagnostic contains: + public void tearDown2() {} + + @AfterEach + // BUG: Diagnostic contains: + protected void tearDown3() {} + + @AfterEach + // BUG: Diagnostic contains: + private void tearDown4() {} + + @AfterAll + void tearDown5() {} + + @AfterAll + // BUG: Diagnostic contains: + public void tearDown6() {} + + @AfterAll + // BUG: Diagnostic contains: + protected void tearDown7() {} + + @AfterAll + // BUG: Diagnostic contains: + private void tearDown8() {} + + @Test + void method1() {} + + @Test + // BUG: Diagnostic contains: + void testMethod2() {} + + @Test + // BUG: Diagnostic contains: + public void method3() {} + + @Test + // BUG: Diagnostic contains: + protected void method4() {} + + @Test + // BUG: Diagnostic contains: + private void method5() {} + + @ParameterizedTest + void method6() {} + + @ParameterizedTest + // BUG: Diagnostic contains: + void testMethod7() {} + + @ParameterizedTest + // BUG: Diagnostic contains: + public void method8() {} + + @ParameterizedTest + // BUG: Diagnostic contains: + protected void method9() {} + + @ParameterizedTest + // BUG: Diagnostic contains: + private void method10() {} + + @BeforeEach + @BeforeAll + @AfterEach + @AfterAll + void testNonTestMethod1() {} + + public void testNonTestMethod2() {} + + protected void testNonTestMethod3() {} + + private void testNonTestMethod4() {} + + @Test + void test5() {} + + @Test + // BUG: Diagnostic contains: (but note that a method named `overload` already exists in this + // class) + void testOverload() {} + + void overload() {} + + @Test + // BUG: Diagnostic contains: (but note that `arguments` is already statically imported) + void testArguments() {} + + @Test + // BUG: Diagnostic contains: (but note that `public` is a reserved keyword) + void testPublic() {} + } + """) .addSourceLines( "B.java", - "import org.junit.jupiter.api.AfterAll;", - "import org.junit.jupiter.api.AfterEach;", - "import org.junit.jupiter.api.BeforeAll;", - "import org.junit.jupiter.api.BeforeEach;", - "import org.junit.jupiter.api.Test;", - "import org.junit.jupiter.params.ParameterizedTest;", - "", - "class B extends A {", - " @Override", - " @BeforeAll", - " void setUp1() {}", - "", - " @Override", - " @BeforeAll", - " public void setUp2() {}", - "", - " @Override", - " @BeforeAll", - " protected void setUp3() {}", - "", - " @Override", - " @BeforeEach", - " void setup5() {}", - "", - " @Override", - " @BeforeEach", - " public void setUp6() {}", - "", - " @Override", - " @BeforeEach", - " protected void setUp7() {}", - "", - " @Override", - " @AfterEach", - " void tearDown1() {}", - "", - " @Override", - " @AfterEach", - " public void tearDown2() {}", - "", - " @Override", - " @AfterEach", - " protected void tearDown3() {}", - "", - " @Override", - " @AfterAll", - " void tearDown5() {}", - "", - " @Override", - " @AfterAll", - " public void tearDown6() {}", - "", - " @Override", - " @AfterAll", - " protected void tearDown7() {}", - "", - " @Override", - " @Test", - " void method1() {}", - "", - " @Override", - " @Test", - " void testMethod2() {}", - "", - " @Override", - " @Test", - " public void method3() {}", - "", - " @Override", - " @Test", - " protected void method4() {}", - "", - " @Override", - " @ParameterizedTest", - " void method6() {}", - "", - " @Override", - " @ParameterizedTest", - " void testMethod7() {}", - "", - " @Override", - " @ParameterizedTest", - " public void method8() {}", - "", - " @Override", - " @ParameterizedTest", - " protected void method9() {}", - "", - " @Override", - " @BeforeEach", - " @BeforeAll", - " @AfterEach", - " @AfterAll", - " void testNonTestMethod1() {}", - "", - " @Override", - " public void testNonTestMethod2() {}", - "", - " @Override", - " protected void testNonTestMethod3() {}", - "", - " @Override", - " @Test", - " void test5() {}", - "", - " @Override", - " @Test", - " void testOverload() {}", - "", - " @Override", - " void overload() {}", - "", - " @Override", - " @Test", - " void testArguments() {}", - "", - " @Override", - " @Test", - " void testPublic() {}", - "}") + """ + import org.junit.jupiter.api.AfterAll; + import org.junit.jupiter.api.AfterEach; + import org.junit.jupiter.api.BeforeAll; + import org.junit.jupiter.api.BeforeEach; + import org.junit.jupiter.api.Test; + import org.junit.jupiter.params.ParameterizedTest; + + class B extends A { + @Override + @BeforeAll + void setUp1() {} + + @Override + @BeforeAll + public void setUp2() {} + + @Override + @BeforeAll + protected void setUp3() {} + + @Override + @BeforeEach + void setup5() {} + + @Override + @BeforeEach + public void setUp6() {} + + @Override + @BeforeEach + protected void setUp7() {} + + @Override + @AfterEach + void tearDown1() {} + + @Override + @AfterEach + public void tearDown2() {} + + @Override + @AfterEach + protected void tearDown3() {} + + @Override + @AfterAll + void tearDown5() {} + + @Override + @AfterAll + public void tearDown6() {} + + @Override + @AfterAll + protected void tearDown7() {} + + @Override + @Test + void method1() {} + + @Override + @Test + void testMethod2() {} + + @Override + @Test + public void method3() {} + + @Override + @Test + protected void method4() {} + + @Override + @ParameterizedTest + void method6() {} + + @Override + @ParameterizedTest + void testMethod7() {} + + @Override + @ParameterizedTest + public void method8() {} + + @Override + @ParameterizedTest + protected void method9() {} + + @Override + @BeforeEach + @BeforeAll + @AfterEach + @AfterAll + void testNonTestMethod1() {} + + @Override + public void testNonTestMethod2() {} + + @Override + protected void testNonTestMethod3() {} + + @Override + @Test + void test5() {} + + @Override + @Test + void testOverload() {} + + @Override + void overload() {} + + @Override + @Test + void testArguments() {} + + @Override + @Test + void testPublic() {} + } + """) .addSourceLines( "C.java", - "import org.junit.jupiter.api.AfterAll;", - "import org.junit.jupiter.api.BeforeAll;", - "import org.junit.jupiter.api.Test;", - "", - "abstract class C {", - " @BeforeAll", - " public void setUp() {}", - "", - " @Test", - " void testMethod1() {}", - "", - " @AfterAll", - " // BUG: Diagnostic contains:", - " private void tearDown() {}", - "", - " @Test", - " // BUG: Diagnostic contains:", - " final void testMethod2() {}", - "}") + """ + import org.junit.jupiter.api.AfterAll; + import org.junit.jupiter.api.BeforeAll; + import org.junit.jupiter.api.Test; + + abstract class C { + @BeforeAll + public void setUp() {} + + @Test + void testMethod1() {} + + @AfterAll + // BUG: Diagnostic contains: + private void tearDown() {} + + @Test + // BUG: Diagnostic contains: + final void testMethod2() {} + } + """) .doTest(); } @@ -309,114 +315,118 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "import static org.junit.jupiter.params.provider.Arguments.arguments;", - "", - "import org.junit.jupiter.api.AfterAll;", - "import org.junit.jupiter.api.AfterEach;", - "import org.junit.jupiter.api.BeforeAll;", - "import org.junit.jupiter.api.BeforeEach;", - "import org.junit.jupiter.api.RepeatedTest;", - "import org.junit.jupiter.api.Test;", - "import org.junit.jupiter.params.ParameterizedTest;", - "", - "class A {", - " {", - " arguments();", - " }", - "", - " @BeforeAll", - " public void setUp1() {}", - "", - " @BeforeEach", - " protected void setUp2() {}", - "", - " @AfterEach", - " private void setUp3() {}", - "", - " @AfterAll", - " private void setUp4() {}", - "", - " @Test", - " void testFoo() {}", - "", - " @ParameterizedTest", - " void testBar() {}", - "", - " @Test", - " public void baz() {}", - "", - " @RepeatedTest(2)", - " private void qux() {}", - "", - " @ParameterizedTest", - " protected void quux() {}", - "", - " @Test", - " public void testOverload() {}", - "", - " void overload() {}", - "", - " @Test", - " protected void testArguments() {}", - "", - " @Test", - " private void testClass() {}", - "}") + """ + import static org.junit.jupiter.params.provider.Arguments.arguments; + + import org.junit.jupiter.api.AfterAll; + import org.junit.jupiter.api.AfterEach; + import org.junit.jupiter.api.BeforeAll; + import org.junit.jupiter.api.BeforeEach; + import org.junit.jupiter.api.RepeatedTest; + import org.junit.jupiter.api.Test; + import org.junit.jupiter.params.ParameterizedTest; + + class A { + { + arguments(); + } + + @BeforeAll + public void setUp1() {} + + @BeforeEach + protected void setUp2() {} + + @AfterEach + private void setUp3() {} + + @AfterAll + private void setUp4() {} + + @Test + void testFoo() {} + + @ParameterizedTest + void testBar() {} + + @Test + public void baz() {} + + @RepeatedTest(2) + private void qux() {} + + @ParameterizedTest + protected void quux() {} + + @Test + public void testOverload() {} + + void overload() {} + + @Test + protected void testArguments() {} + + @Test + private void testClass() {} + } + """) .addOutputLines( "A.java", - "import static org.junit.jupiter.params.provider.Arguments.arguments;", - "", - "import org.junit.jupiter.api.AfterAll;", - "import org.junit.jupiter.api.AfterEach;", - "import org.junit.jupiter.api.BeforeAll;", - "import org.junit.jupiter.api.BeforeEach;", - "import org.junit.jupiter.api.RepeatedTest;", - "import org.junit.jupiter.api.Test;", - "import org.junit.jupiter.params.ParameterizedTest;", - "", - "class A {", - " {", - " arguments();", - " }", - "", - " @BeforeAll", - " void setUp1() {}", - "", - " @BeforeEach", - " void setUp2() {}", - "", - " @AfterEach", - " void setUp3() {}", - "", - " @AfterAll", - " void setUp4() {}", - "", - " @Test", - " void foo() {}", - "", - " @ParameterizedTest", - " void bar() {}", - "", - " @Test", - " void baz() {}", - "", - " @RepeatedTest(2)", - " void qux() {}", - "", - " @ParameterizedTest", - " void quux() {}", - "", - " @Test", - " void testOverload() {}", - "", - " void overload() {}", - "", - " @Test", - " void testArguments() {}", - "", - " @Test", - " void testClass() {}", - "}") + """ + import static org.junit.jupiter.params.provider.Arguments.arguments; + + import org.junit.jupiter.api.AfterAll; + import org.junit.jupiter.api.AfterEach; + import org.junit.jupiter.api.BeforeAll; + import org.junit.jupiter.api.BeforeEach; + import org.junit.jupiter.api.RepeatedTest; + import org.junit.jupiter.api.Test; + import org.junit.jupiter.params.ParameterizedTest; + + class A { + { + arguments(); + } + + @BeforeAll + void setUp1() {} + + @BeforeEach + void setUp2() {} + + @AfterEach + void setUp3() {} + + @AfterAll + void setUp4() {} + + @Test + void foo() {} + + @ParameterizedTest + void bar() {} + + @Test + void baz() {} + + @RepeatedTest(2) + void qux() {} + + @ParameterizedTest + void quux() {} + + @Test + void testOverload() {} + + void overload() {} + + @Test + void testArguments() {} + + @Test + void testClass() {} + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/LexicographicalAnnotationAttributeListingTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/LexicographicalAnnotationAttributeListingTest.java index b7a204c457e..7e11d1b6e30 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/LexicographicalAnnotationAttributeListingTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/LexicographicalAnnotationAttributeListingTest.java @@ -25,138 +25,140 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import static java.math.RoundingMode.DOWN;", - "import static java.math.RoundingMode.UP;", - "", - "import com.fasterxml.jackson.annotation.JsonPropertyOrder;", - "import io.swagger.annotations.ApiImplicitParam;", - "import io.swagger.annotations.ApiImplicitParams;", - "import io.swagger.v3.oas.annotations.Parameter;", - "import io.swagger.v3.oas.annotations.Parameters;", - "import java.math.RoundingMode;", - "import javax.xml.bind.annotation.XmlType;", - "import org.springframework.context.annotation.PropertySource;", - "import org.springframework.test.context.TestPropertySource;", - "", - "interface A {", - " @interface Foo {", - " String[] value() default {};", - "", - " int[] ints() default {};", - "", - " Class[] cls() default {};", - "", - " RoundingMode[] enums() default {};", - "", - " Bar[] anns() default {};", - " }", - "", - " @interface Bar {", - " String[] value() default {};", - " }", - "", - " @Foo({})", - " A noString();", - "", - " @Foo({\"a\"})", - " A oneString();", - "", - " @Foo({\"a\", \"b\"})", - " A sortedStrings();", - " // BUG: Diagnostic contains:", - " @Foo({\"b\", \"a\"})", - " A unsortedString();", - "", - " @Foo({\"ab\", \"Ac\"})", - " A sortedStringCaseInsensitive();", - " // BUG: Diagnostic contains:", - " @Foo({\"ac\", \"Ab\"})", - " A unsortedStringCaseInsensitive();", - "", - " @Foo({\"A\", \"a\"})", - " A sortedStringCaseInsensitiveWithTotalOrderFallback();", - " // BUG: Diagnostic contains:", - " @Foo({\"a\", \"A\"})", - " A unsortedStringCaseInsensitiveWithTotalOrderFallback();", - "", - " @Foo(ints = {})", - " A noInts();", - "", - " @Foo(ints = {0})", - " A oneInt();", - "", - " @Foo(ints = {0, 1})", - " A sortedInts();", - "", - " @Foo(ints = {1, 0})", - " A unsortedInts();", - "", - " @Foo(cls = {})", - " A noClasses();", - "", - " @Foo(cls = {int.class})", - " A oneClass();", - "", - " @Foo(cls = {int.class, long.class})", - " A sortedClasses();", - " // BUG: Diagnostic contains:", - " @Foo(cls = {long.class, int.class})", - " A unsortedClasses();", - "", - " @Foo(enums = {})", - " A noEnums();", - "", - " @Foo(enums = {DOWN})", - " A oneEnum();", - "", - " @Foo(enums = {DOWN, UP})", - " A sortedEnums();", - " // BUG: Diagnostic contains:", - " @Foo(enums = {UP, DOWN})", - " A unsortedEnums();", - "", - " @Foo(anns = {})", - " A noAnns();", - "", - " @Foo(anns = {@Bar(\"a\")})", - " A oneAnn();", - "", - " @Foo(anns = {@Bar(\"a\"), @Bar(\"b\")})", - " A sortedAnns();", - " // BUG: Diagnostic contains:", - " @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})", - " A unsortedAnns();", - " // BUG: Diagnostic contains:", - " @Foo(anns = {@Bar(\"a\"), @Bar({\"b\", \"a\"})})", - " A unsortedInnderAnns();", - "", - " @Foo({\"a=foo\", \"a.b=bar\", \"a.c=baz\"})", - " A hierarchicallySorted();", - " // BUG: Diagnostic contains:", - " @Foo({\"a.b=bar\", \"a.c=baz\", \"a=foo\"})", - " A hierarchicallyUnsorted();", - "", - " @JsonPropertyOrder({\"field2\", \"field1\"})", - " A dto();", - "", - " @ApiImplicitParams({@ApiImplicitParam(\"p2\"), @ApiImplicitParam(\"p1\")})", - " A firstEndpoint();", - "", - " @Parameters({@Parameter(name = \"p2\"), @Parameter(name = \"p1\")})", - " A secondEndpoint();", - "", - " @XmlType(propOrder = {\"field2\", \"field1\"})", - " class XmlTypeDummy {}", - "", - " @PropertySource({\"field2\", \"field1\"})", - " class PropertySourceDummy {}", - "", - " @TestPropertySource(locations = {\"field2\", \"field1\"})", - " class FirstTestPropertySourceDummy {}", - "", - " @TestPropertySource({\"field2\", \"field1\"})", - " class SecondTestPropertySourceDummy {}", - "}") + """ + import static java.math.RoundingMode.DOWN; + import static java.math.RoundingMode.UP; + + import com.fasterxml.jackson.annotation.JsonPropertyOrder; + import io.swagger.annotations.ApiImplicitParam; + import io.swagger.annotations.ApiImplicitParams; + import io.swagger.v3.oas.annotations.Parameter; + import io.swagger.v3.oas.annotations.Parameters; + import java.math.RoundingMode; + import javax.xml.bind.annotation.XmlType; + import org.springframework.context.annotation.PropertySource; + import org.springframework.test.context.TestPropertySource; + + interface A { + @interface Foo { + String[] value() default {}; + + int[] ints() default {}; + + Class[] cls() default {}; + + RoundingMode[] enums() default {}; + + Bar[] anns() default {}; + } + + @interface Bar { + String[] value() default {}; + } + + @Foo({}) + A noString(); + + @Foo({"a"}) + A oneString(); + + @Foo({"a", "b"}) + A sortedStrings(); + // BUG: Diagnostic contains: + @Foo({"b", "a"}) + A unsortedString(); + + @Foo({"ab", "Ac"}) + A sortedStringCaseInsensitive(); + // BUG: Diagnostic contains: + @Foo({"ac", "Ab"}) + A unsortedStringCaseInsensitive(); + + @Foo({"A", "a"}) + A sortedStringCaseInsensitiveWithTotalOrderFallback(); + // BUG: Diagnostic contains: + @Foo({"a", "A"}) + A unsortedStringCaseInsensitiveWithTotalOrderFallback(); + + @Foo(ints = {}) + A noInts(); + + @Foo(ints = {0}) + A oneInt(); + + @Foo(ints = {0, 1}) + A sortedInts(); + + @Foo(ints = {1, 0}) + A unsortedInts(); + + @Foo(cls = {}) + A noClasses(); + + @Foo(cls = {int.class}) + A oneClass(); + + @Foo(cls = {int.class, long.class}) + A sortedClasses(); + // BUG: Diagnostic contains: + @Foo(cls = {long.class, int.class}) + A unsortedClasses(); + + @Foo(enums = {}) + A noEnums(); + + @Foo(enums = {DOWN}) + A oneEnum(); + + @Foo(enums = {DOWN, UP}) + A sortedEnums(); + // BUG: Diagnostic contains: + @Foo(enums = {UP, DOWN}) + A unsortedEnums(); + + @Foo(anns = {}) + A noAnns(); + + @Foo(anns = {@Bar("a")}) + A oneAnn(); + + @Foo(anns = {@Bar("a"), @Bar("b")}) + A sortedAnns(); + // BUG: Diagnostic contains: + @Foo(anns = {@Bar("b"), @Bar("a")}) + A unsortedAnns(); + // BUG: Diagnostic contains: + @Foo(anns = {@Bar("a"), @Bar({"b", "a"})}) + A unsortedInnderAnns(); + + @Foo({"a=foo", "a.b=bar", "a.c=baz"}) + A hierarchicallySorted(); + // BUG: Diagnostic contains: + @Foo({"a.b=bar", "a.c=baz", "a=foo"}) + A hierarchicallyUnsorted(); + + @JsonPropertyOrder({"field2", "field1"}) + A dto(); + + @ApiImplicitParams({@ApiImplicitParam("p2"), @ApiImplicitParam("p1")}) + A firstEndpoint(); + + @Parameters({@Parameter(name = "p2"), @Parameter(name = "p1")}) + A secondEndpoint(); + + @XmlType(propOrder = {"field2", "field1"}) + class XmlTypeDummy {} + + @PropertySource({"field2", "field1"}) + class PropertySourceDummy {} + + @TestPropertySource(locations = {"field2", "field1"}) + class FirstTestPropertySourceDummy {} + + @TestPropertySource({"field2", "field1"}) + class SecondTestPropertySourceDummy {} + } + """) .doTest(); } @@ -168,78 +170,82 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "import static java.math.RoundingMode.DOWN;", - "import static java.math.RoundingMode.UP;", - "", - "import java.math.RoundingMode;", - "", - "interface A {", - " @interface Foo {", - " String[] value() default {};", - "", - " Class[] cls() default {};", - "", - " RoundingMode[] enums() default {};", - "", - " Bar[] anns() default {};", - " }", - "", - " @interface Bar {", - " String[] value() default {};", - " }", - "", - " @Foo({\" \", \"\", \"b\", \"a\"})", - " A unsortedString();", - "", - " @Foo(cls = {long.class, int.class})", - " A unsortedClasses();", - "", - " @Foo(enums = {UP, DOWN})", - " A unsortedEnums();", - "", - " @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})", - " A unsortedAnns();", - "", - " @Foo(anns = {@Bar(\"a\"), @Bar({\"b\", \"a\"})})", - " A unsortedInnderAnns();", - "}") + """ + import static java.math.RoundingMode.DOWN; + import static java.math.RoundingMode.UP; + + import java.math.RoundingMode; + + interface A { + @interface Foo { + String[] value() default {}; + + Class[] cls() default {}; + + RoundingMode[] enums() default {}; + + Bar[] anns() default {}; + } + + @interface Bar { + String[] value() default {}; + } + + @Foo({" ", "", "b", "a"}) + A unsortedString(); + + @Foo(cls = {long.class, int.class}) + A unsortedClasses(); + + @Foo(enums = {UP, DOWN}) + A unsortedEnums(); + + @Foo(anns = {@Bar("b"), @Bar("a")}) + A unsortedAnns(); + + @Foo(anns = {@Bar("a"), @Bar({"b", "a"})}) + A unsortedInnderAnns(); + } + """) .addOutputLines( "A.java", - "import static java.math.RoundingMode.DOWN;", - "import static java.math.RoundingMode.UP;", - "", - "import java.math.RoundingMode;", - "", - "interface A {", - " @interface Foo {", - " String[] value() default {};", - "", - " Class[] cls() default {};", - "", - " RoundingMode[] enums() default {};", - "", - " Bar[] anns() default {};", - " }", - "", - " @interface Bar {", - " String[] value() default {};", - " }", - "", - " @Foo({\"\", \" \", \"a\", \"b\"})", - " A unsortedString();", - "", - " @Foo(cls = {int.class, long.class})", - " A unsortedClasses();", - "", - " @Foo(enums = {DOWN, UP})", - " A unsortedEnums();", - "", - " @Foo(anns = {@Bar(\"a\"), @Bar(\"b\")})", - " A unsortedAnns();", - "", - " @Foo(anns = {@Bar(\"a\"), @Bar({\"a\", \"b\"})})", - " A unsortedInnderAnns();", - "}") + """ + import static java.math.RoundingMode.DOWN; + import static java.math.RoundingMode.UP; + + import java.math.RoundingMode; + + interface A { + @interface Foo { + String[] value() default {}; + + Class[] cls() default {}; + + RoundingMode[] enums() default {}; + + Bar[] anns() default {}; + } + + @interface Bar { + String[] value() default {}; + } + + @Foo({"", " ", "a", "b"}) + A unsortedString(); + + @Foo(cls = {int.class, long.class}) + A unsortedClasses(); + + @Foo(enums = {DOWN, UP}) + A unsortedEnums(); + + @Foo(anns = {@Bar("a"), @Bar("b")}) + A unsortedAnns(); + + @Foo(anns = {@Bar("a"), @Bar({"a", "b"})}) + A unsortedInnderAnns(); + } + """) .doTest(TestMode.TEXT_MATCH); } @@ -249,46 +255,48 @@ void filtering() { restrictedCompilationTestHelper .addSourceLines( "pkg/A.java", - "package pkg;", - "", - "interface A {", - " @interface Foo {", - " String[] value() default {};", - "", - " String[] value2() default {};", - " }", - "", - " @interface Bar {", - " String[] value() default {};", - "", - " String[] value2() default {};", - " }", - "", - " @interface Baz {", - " String[] value() default {};", - "", - " String[] value2() default {};", - " }", - "", - " // BUG: Diagnostic contains:", - " @Foo({\"b\", \"a\"})", - " A fooValue();", - " // BUG: Diagnostic contains:", - " @Foo(value2 = {\"b\", \"a\"})", - " A fooValue2();", - "", - " @Bar({\"b\", \"a\"})", - " A barValue();", - " // BUG: Diagnostic contains:", - " @Bar(value2 = {\"b\", \"a\"})", - " A barValue2();", - "", - " @Baz({\"b\", \"a\"})", - " A bazValue();", - "", - " @Baz(value2 = {\"b\", \"a\"})", - " A bazValue2();", - "}") + """ + package pkg; + + interface A { + @interface Foo { + String[] value() default {}; + + String[] value2() default {}; + } + + @interface Bar { + String[] value() default {}; + + String[] value2() default {}; + } + + @interface Baz { + String[] value() default {}; + + String[] value2() default {}; + } + + // BUG: Diagnostic contains: + @Foo({"b", "a"}) + A fooValue(); + // BUG: Diagnostic contains: + @Foo(value2 = {"b", "a"}) + A fooValue2(); + + @Bar({"b", "a"}) + A barValue(); + // BUG: Diagnostic contains: + @Bar(value2 = {"b", "a"}) + A barValue2(); + + @Baz({"b", "a"}) + A bazValue(); + + @Baz(value2 = {"b", "a"}) + A bazValue2(); + } + """) .doTest(); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/LexicographicalAnnotationListingTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/LexicographicalAnnotationListingTest.java index 287a0e95f30..a07920940ea 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/LexicographicalAnnotationListingTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/LexicographicalAnnotationListingTest.java @@ -17,117 +17,119 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import java.lang.annotation.ElementType;", - "import java.lang.annotation.Repeatable;", - "import java.lang.annotation.Target;", - "", - "interface A {", - " @Repeatable(Foos.class)", - " @interface Foo {", - " String[] value() default {};", - "", - " int[] ints() default {};", - "", - " Bar[] anns() default {};", - " }", - "", - " @Target(ElementType.METHOD)", - " @interface Bar {", - " String[] value() default {};", - " }", - "", - " @interface Baz {", - " String[] str() default {};", - " }", - "", - " @interface Foos {", - " Foo[] value();", - " }", - "", - " @Target(ElementType.TYPE_USE)", - " @interface FooTypeUse {", - " String[] value() default {};", - " }", - "", - " @Target(ElementType.TYPE_USE)", - " @interface BarTypeUse {", - " String[] value() default {};", - " }", - "", - " // BUG: Diagnostic contains:", - " @Foo", - " @Bar", - " A unsortedSimpleCase();", - " // BUG: Diagnostic contains:", - " @Foo()", - " @Bar()", - " A unsortedWithParens();", - "", - " @Foo()", - " A onlyOneAnnotation();", - "", - " @Bar", - " @Foo()", - " A sortedAnnotationsOneWithParens();", - "", - " // BUG: Diagnostic contains:", - " @Foo", - " @Baz", - " @Bar", - " A threeUnsortedAnnotationsSameInitialLetter();", - " // BUG: Diagnostic contains:", - " @Bar", - " @Foo()", - " @Baz", - " A firstOrderedWithTwoUnsortedAnnotations();", - "", - " @Bar", - " @Baz", - " @Foo()", - " A threeSortedAnnotations();", - "", - " // BUG: Diagnostic contains:", - " @Foo({\"b\"})", - " @Bar({\"a\"})", - " A unsortedWithStringAttributes();", - " // BUG: Diagnostic contains:", - " @Baz(str = {\"a\", \"b\"})", - " @Foo(ints = {1, 0})", - " @Bar", - " A unsortedWithAttributes();", - " // BUG: Diagnostic contains:", - " @Bar", - " @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})", - " @Baz", - " A unsortedWithNestedBar();", - "", - " @Bar", - " @Baz", - " @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})", - " A sortedWithNestedBar();", - "", - " @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})", - " @Foo(ints = {1, 2})", - " @Foo({\"b\"})", - " A sortedRepeatableAnnotation();", - " // BUG: Diagnostic contains:", - " @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})", - " @Bar", - " @Foo(ints = {1, 2})", - " A unsortedRepeatableAnnotation();", - "", - " // BUG: Diagnostic contains:", - " default @FooTypeUse @BarTypeUse A unsortedTypeAnnotations() {", - " return null;", - " }", - "", - " // BUG: Diagnostic contains:", - " @Baz", - " @Bar", - " default @FooTypeUse @BarTypeUse A unsortedTypeUseAndOtherAnnotations() {", - " return null;", - " }", - "}") + """ + import java.lang.annotation.ElementType; + import java.lang.annotation.Repeatable; + import java.lang.annotation.Target; + + interface A { + @Repeatable(Foos.class) + @interface Foo { + String[] value() default {}; + + int[] ints() default {}; + + Bar[] anns() default {}; + } + + @Target(ElementType.METHOD) + @interface Bar { + String[] value() default {}; + } + + @interface Baz { + String[] str() default {}; + } + + @interface Foos { + Foo[] value(); + } + + @Target(ElementType.TYPE_USE) + @interface FooTypeUse { + String[] value() default {}; + } + + @Target(ElementType.TYPE_USE) + @interface BarTypeUse { + String[] value() default {}; + } + + // BUG: Diagnostic contains: + @Foo + @Bar + A unsortedSimpleCase(); + // BUG: Diagnostic contains: + @Foo() + @Bar() + A unsortedWithParens(); + + @Foo() + A onlyOneAnnotation(); + + @Bar + @Foo() + A sortedAnnotationsOneWithParens(); + + // BUG: Diagnostic contains: + @Foo + @Baz + @Bar + A threeUnsortedAnnotationsSameInitialLetter(); + // BUG: Diagnostic contains: + @Bar + @Foo() + @Baz + A firstOrderedWithTwoUnsortedAnnotations(); + + @Bar + @Baz + @Foo() + A threeSortedAnnotations(); + + // BUG: Diagnostic contains: + @Foo({"b"}) + @Bar({"a"}) + A unsortedWithStringAttributes(); + // BUG: Diagnostic contains: + @Baz(str = {"a", "b"}) + @Foo(ints = {1, 0}) + @Bar + A unsortedWithAttributes(); + // BUG: Diagnostic contains: + @Bar + @Foo(anns = {@Bar("b"), @Bar("a")}) + @Baz + A unsortedWithNestedBar(); + + @Bar + @Baz + @Foo(anns = {@Bar("b"), @Bar("a")}) + A sortedWithNestedBar(); + + @Foo(anns = {@Bar("b"), @Bar("a")}) + @Foo(ints = {1, 2}) + @Foo({"b"}) + A sortedRepeatableAnnotation(); + // BUG: Diagnostic contains: + @Foo(anns = {@Bar("b"), @Bar("a")}) + @Bar + @Foo(ints = {1, 2}) + A unsortedRepeatableAnnotation(); + + // BUG: Diagnostic contains: + default @FooTypeUse @BarTypeUse A unsortedTypeAnnotations() { + return null; + } + + // BUG: Diagnostic contains: + @Baz + @Bar + default @FooTypeUse @BarTypeUse A unsortedTypeUseAndOtherAnnotations() { + return null; + } + } + """) .doTest(); } @@ -136,166 +138,170 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "import java.lang.annotation.ElementType;", - "import java.lang.annotation.Repeatable;", - "import java.lang.annotation.Target;", - "", - "interface A {", - " @Repeatable(Foos.class)", - " @interface Foo {", - " String[] value() default {};", - "", - " int[] ints() default {};", - "", - " Bar[] anns() default {};", - " }", - "", - " @Target(ElementType.METHOD)", - " @interface Bar {", - " String[] value() default {};", - " }", - "", - " @interface Baz {", - " String[] str() default {};", - " }", - "", - " @interface Foos {", - " Foo[] value();", - " }", - "", - " @Target(ElementType.TYPE_USE)", - " @interface FooTypeUse {", - " String[] value() default {};", - " }", - "", - " @Target(ElementType.TYPE_USE)", - " @interface BarTypeUse {", - " String[] value() default {};", - " }", - "", - " @Bar", - " A singleAnnotation();", - "", - " @Bar", - " @Foo", - " A sortedAnnotations();", - "", - " @Foo", - " @Bar", - " A unsortedAnnotations();", - "", - " @Foo()", - " @Baz()", - " @Bar", - " A unsortedAnnotationsWithSomeParens();", - "", - " @Bar", - " @Baz(str = {\"a\", \"b\"})", - " @Foo()", - " A unsortedAnnotationsOneContainingAttributes();", - "", - " @Baz(str = {\"a\", \"b\"})", - " @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})", - " @Bar({\"b\"})", - " A unsortedAnnotationsWithAttributes();", - "", - " @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})", - " @Foo(ints = {1, 2})", - " @Foo({\"b\"})", - " A sortedRepeatableAnnotation();", - "", - " @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})", - " @Bar", - " @Foo(ints = {1, 2})", - " A unsortedRepeatableAnnotation();", - "", - " @Baz", - " @Bar", - " default @FooTypeUse @BarTypeUse A unsortedWithTypeUseAnnotations() {", - " return null;", - " }", - "}") + """ + import java.lang.annotation.ElementType; + import java.lang.annotation.Repeatable; + import java.lang.annotation.Target; + + interface A { + @Repeatable(Foos.class) + @interface Foo { + String[] value() default {}; + + int[] ints() default {}; + + Bar[] anns() default {}; + } + + @Target(ElementType.METHOD) + @interface Bar { + String[] value() default {}; + } + + @interface Baz { + String[] str() default {}; + } + + @interface Foos { + Foo[] value(); + } + + @Target(ElementType.TYPE_USE) + @interface FooTypeUse { + String[] value() default {}; + } + + @Target(ElementType.TYPE_USE) + @interface BarTypeUse { + String[] value() default {}; + } + + @Bar + A singleAnnotation(); + + @Bar + @Foo + A sortedAnnotations(); + + @Foo + @Bar + A unsortedAnnotations(); + + @Foo() + @Baz() + @Bar + A unsortedAnnotationsWithSomeParens(); + + @Bar + @Baz(str = {"a", "b"}) + @Foo() + A unsortedAnnotationsOneContainingAttributes(); + + @Baz(str = {"a", "b"}) + @Foo(anns = {@Bar("b"), @Bar("a")}) + @Bar({"b"}) + A unsortedAnnotationsWithAttributes(); + + @Foo(anns = {@Bar("b"), @Bar("a")}) + @Foo(ints = {1, 2}) + @Foo({"b"}) + A sortedRepeatableAnnotation(); + + @Foo(anns = {@Bar("b"), @Bar("a")}) + @Bar + @Foo(ints = {1, 2}) + A unsortedRepeatableAnnotation(); + + @Baz + @Bar + default @FooTypeUse @BarTypeUse A unsortedWithTypeUseAnnotations() { + return null; + } + } + """) .addOutputLines( "A.java", - "import java.lang.annotation.ElementType;", - "import java.lang.annotation.Repeatable;", - "import java.lang.annotation.Target;", - "", - "interface A {", - " @Repeatable(Foos.class)", - " @interface Foo {", - " String[] value() default {};", - "", - " int[] ints() default {};", - "", - " Bar[] anns() default {};", - " }", - "", - " @Target(ElementType.METHOD)", - " @interface Bar {", - " String[] value() default {};", - " }", - "", - " @interface Baz {", - " String[] str() default {};", - " }", - "", - " @interface Foos {", - " Foo[] value();", - " }", - "", - " @Target(ElementType.TYPE_USE)", - " @interface FooTypeUse {", - " String[] value() default {};", - " }", - "", - " @Target(ElementType.TYPE_USE)", - " @interface BarTypeUse {", - " String[] value() default {};", - " }", - "", - " @Bar", - " A singleAnnotation();", - "", - " @Bar", - " @Foo", - " A sortedAnnotations();", - "", - " @Bar", - " @Foo", - " A unsortedAnnotations();", - "", - " @Bar", - " @Baz()", - " @Foo()", - " A unsortedAnnotationsWithSomeParens();", - "", - " @Bar", - " @Baz(str = {\"a\", \"b\"})", - " @Foo()", - " A unsortedAnnotationsOneContainingAttributes();", - "", - " @Bar({\"b\"})", - " @Baz(str = {\"a\", \"b\"})", - " @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})", - " A unsortedAnnotationsWithAttributes();", - "", - " @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})", - " @Foo(ints = {1, 2})", - " @Foo({\"b\"})", - " A sortedRepeatableAnnotation();", - "", - " @Bar", - " @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})", - " @Foo(ints = {1, 2})", - " A unsortedRepeatableAnnotation();", - "", - " @Bar", - " @Baz", - " default @BarTypeUse @FooTypeUse A unsortedWithTypeUseAnnotations() {", - " return null;", - " }", - "}") + """ + import java.lang.annotation.ElementType; + import java.lang.annotation.Repeatable; + import java.lang.annotation.Target; + + interface A { + @Repeatable(Foos.class) + @interface Foo { + String[] value() default {}; + + int[] ints() default {}; + + Bar[] anns() default {}; + } + + @Target(ElementType.METHOD) + @interface Bar { + String[] value() default {}; + } + + @interface Baz { + String[] str() default {}; + } + + @interface Foos { + Foo[] value(); + } + + @Target(ElementType.TYPE_USE) + @interface FooTypeUse { + String[] value() default {}; + } + + @Target(ElementType.TYPE_USE) + @interface BarTypeUse { + String[] value() default {}; + } + + @Bar + A singleAnnotation(); + + @Bar + @Foo + A sortedAnnotations(); + + @Bar + @Foo + A unsortedAnnotations(); + + @Bar + @Baz() + @Foo() + A unsortedAnnotationsWithSomeParens(); + + @Bar + @Baz(str = {"a", "b"}) + @Foo() + A unsortedAnnotationsOneContainingAttributes(); + + @Bar({"b"}) + @Baz(str = {"a", "b"}) + @Foo(anns = {@Bar("b"), @Bar("a")}) + A unsortedAnnotationsWithAttributes(); + + @Foo(anns = {@Bar("b"), @Bar("a")}) + @Foo(ints = {1, 2}) + @Foo({"b"}) + A sortedRepeatableAnnotation(); + + @Bar + @Foo(anns = {@Bar("b"), @Bar("a")}) + @Foo(ints = {1, 2}) + A unsortedRepeatableAnnotation(); + + @Bar + @Baz + default @BarTypeUse @FooTypeUse A unsortedWithTypeUseAnnotations() { + return null; + } + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MethodReferenceUsageTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MethodReferenceUsageTest.java index 1ae63913eea..26a600844cb 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MethodReferenceUsageTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MethodReferenceUsageTest.java @@ -16,308 +16,310 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import com.google.common.collect.Streams;", - "import java.util.HashMap;", - "import java.util.Map;", - "import java.util.function.IntConsumer;", - "import java.util.function.IntFunction;", - "import java.util.stream.Stream;", - "", - "class A {", - " private final Stream s = Stream.of(1);", - " private final Map m = new HashMap<>();", - " private final Runnable thrower =", - " () -> {", - " throw new RuntimeException();", - " };", - "", - " void unaryExternalStaticFunctionCalls() {", - " s.forEach(String::valueOf);", - " // BUG: Diagnostic contains:", - " s.forEach(v -> String.valueOf(v));", - " s.forEach(", - " // BUG: Diagnostic contains:", - " (v) -> {", - " String.valueOf(v);", - " });", - " s.forEach(", - " // BUG: Diagnostic contains:", - " (Integer v) -> {", - " {", - " String.valueOf(v);", - " }", - " });", - " s.forEach(", - " v -> {", - " String.valueOf(v);", - " String.valueOf(v);", - " });", - "", - " s.map(String::valueOf);", - " // BUG: Diagnostic contains:", - " s.map(v -> String.valueOf(v));", - " // BUG: Diagnostic contains:", - " s.map((v) -> (String.valueOf(v)));", - " s.map(", - " // BUG: Diagnostic contains:", - " (Integer v) -> {", - " return String.valueOf(v);", - " });", - " s.map(", - " // BUG: Diagnostic contains:", - " (final Integer v) -> {", - " return (String.valueOf(v));", - " });", - " s.map(", - " v -> {", - " String.valueOf(v);", - " return String.valueOf(v);", - " });", - "", - " s.findFirst().orElseGet(() -> Integer.valueOf(\"0\"));", - " m.forEach((k, v) -> String.valueOf(v));", - " m.forEach((k, v) -> String.valueOf(k));", - " }", - "", - " void binaryExternalInstanceFunctionCalls() {", - " m.forEach(m::put);", - " // BUG: Diagnostic contains:", - " m.forEach((k, v) -> m.put(k, v));", - " m.forEach((k, v) -> m.put(v, k));", - " m.forEach(", - " // BUG: Diagnostic contains:", - " (Integer k, Integer v) -> {", - " m.put(k, v);", - " });", - " m.forEach(", - " (k, v) -> {", - " m.put(k, k);", - " });", - " m.forEach(", - " // BUG: Diagnostic contains:", - " (final Integer k, final Integer v) -> {", - " {", - " m.put(k, v);", - " }", - " });", - " m.forEach(", - " (k, v) -> {", - " {", - " m.put(v, v);", - " }", - " });", - " m.forEach((k, v) -> new HashMap().put(k, v));", - " m.forEach(", - " (k, v) -> {", - " m.put(k, v);", - " m.put(k, v);", - " });", - "", - " Streams.zip(s, s, m::put);", - " // BUG: Diagnostic contains:", - " Streams.zip(s, s, (a, b) -> m.put(a, b));", - " Streams.zip(s, s, (a, b) -> m.put(b, a));", - " // BUG: Diagnostic contains:", - " Streams.zip(s, s, (Integer a, Integer b) -> (m.put(a, b)));", - " Streams.zip(s, s, (a, b) -> (m.put(a, a)));", - " Streams.zip(", - " s,", - " s,", - " // BUG: Diagnostic contains:", - " (final Integer a, final Integer b) -> {", - " return m.put(a, b);", - " });", - " Streams.zip(", - " s,", - " s,", - " (a, b) -> {", - " return m.put(b, b);", - " });", - " Streams.zip(", - " s,", - " s,", - " // BUG: Diagnostic contains:", - " (a, b) -> {", - " return (m.put(a, b));", - " });", - " Streams.zip(", - " s,", - " s,", - " (a, b) -> {", - " return (m.put(b, a));", - " });", - " Streams.zip(", - " s,", - " s,", - " (a, b) -> {", - " m.put(a, b);", - " return m.put(a, b);", - " });", - " }", - "", - " void nullaryExternalInstanceFunctionCalls() {", - " s.map(Integer::doubleValue);", - " // BUG: Diagnostic contains:", - " s.map(i -> i.doubleValue());", - " s.map(i -> i.toString());", - " s.map(i -> s.toString());", - "", - " // BUG: Diagnostic contains:", - " Stream.of(int.class).filter(c -> c.isEnum());", - " Stream.of((Class) int.class).filter(Class::isEnum);", - " // BUG: Diagnostic contains:", - " Stream.of((Class) int.class).filter(c -> c.isEnum());", - " }", - "", - " void localFunctionCalls() {", - " s.forEach(v -> ivoid0());", - " s.forEach(v -> iint0());", - " s.forEach(v -> svoid0());", - " s.forEach(v -> sint0());", - "", - " s.forEach(this::ivoid1);", - " // BUG: Diagnostic contains:", - " s.forEach(v -> ivoid1(v));", - " s.forEach(", - " // BUG: Diagnostic contains:", - " v -> {", - " ivoid1(v);", - " });", - " s.forEach(this::iint1);", - " // BUG: Diagnostic contains:", - " s.forEach(v -> iint1(v));", - " s.forEach(", - " // BUG: Diagnostic contains:", - " v -> {", - " iint1(v);", - " });", - "", - " s.forEach(A::svoid1);", - " // BUG: Diagnostic contains:", - " s.forEach(v -> svoid1(v));", - " s.forEach(", - " // BUG: Diagnostic contains:", - " v -> {", - " svoid1(v);", - " });", - " s.forEach(A::sint1);", - " // BUG: Diagnostic contains:", - " s.forEach(v -> sint1(v));", - " s.forEach(", - " // BUG: Diagnostic contains:", - " v -> {", - " sint1(v);", - " });", - "", - " s.forEach(v -> ivoid2(v, v));", - " s.forEach(v -> iint2(v, v));", - " s.forEach(v -> svoid2(v, v));", - " s.forEach(v -> sint2(v, v));", - "", - " m.forEach((k, v) -> ivoid0());", - " m.forEach((k, v) -> iint0());", - " m.forEach((k, v) -> svoid0());", - " m.forEach((k, v) -> sint0());", - "", - " m.forEach(this::ivoid2);", - " // BUG: Diagnostic contains:", - " m.forEach((k, v) -> ivoid2(k, v));", - " m.forEach(", - " // BUG: Diagnostic contains:", - " (k, v) -> {", - " ivoid2(k, v);", - " });", - " m.forEach(this::iint2);", - " // BUG: Diagnostic contains:", - " m.forEach((k, v) -> iint2(k, v));", - " m.forEach(", - " // BUG: Diagnostic contains:", - " (k, v) -> {", - " iint2(k, v);", - " });", - "", - " m.forEach(A::svoid2);", - " // BUG: Diagnostic contains:", - " m.forEach((k, v) -> svoid2(k, v));", - " m.forEach(", - " // BUG: Diagnostic contains:", - " (k, v) -> {", - " svoid2(k, v);", - " });", - " m.forEach(A::sint2);", - " // BUG: Diagnostic contains:", - " m.forEach((k, v) -> sint2(k, v));", - " m.forEach(", - " // BUG: Diagnostic contains:", - " (k, v) -> {", - " sint2(k, v);", - " });", - " }", - "", - " void functionCallsWhoseReplacementWouldBeAmbiguous() {", - " receiver(", - " i -> {", - " Integer.toString(i);", - " });", - " }", - "", - " void assortedOtherEdgeCases() {", - " s.forEach(v -> String.valueOf(v.toString()));", - " TernaryOp o1 = (a, b, c) -> String.valueOf(a);", - " TernaryOp o2 = (a, b, c) -> String.valueOf(b);", - " TernaryOp o3 = (a, b, c) -> String.valueOf(c);", - " TernaryOp o4 = (a, b, c) -> c.concat(a);", - " TernaryOp o5 = (a, b, c) -> c.concat(b);", - " TernaryOp o6 = (a, b, c) -> a.concat(c);", - " TernaryOp o7 = (a, b, c) -> b.concat(c);", - " }", - "", - " void receiver(IntFunction op) {}", - "", - " void receiver(IntConsumer op) {}", - "", - " void ivoid0() {}", - "", - " void ivoid1(int a) {}", - "", - " void ivoid2(int a, int b) {}", - "", - " int iint0() {", - " return 0;", - " }", - "", - " int iint1(int a) {", - " return 0;", - " }", - "", - " int iint2(int a, int b) {", - " return 0;", - " }", - "", - " static void svoid0() {}", - "", - " static void svoid1(int a) {}", - "", - " static void svoid2(int a, int b) {}", - "", - " static void svoid3(int a, int b, int c) {}", - "", - " static int sint0() {", - " return 0;", - " }", - "", - " static int sint1(int a) {", - " return 0;", - " }", - "", - " static int sint2(int a, int b) {", - " return 0;", - " }", - "", - " interface TernaryOp {", - " String collect(String a, String b, String c);", - " }", - "}") + """ + import com.google.common.collect.Streams; + import java.util.HashMap; + import java.util.Map; + import java.util.function.IntConsumer; + import java.util.function.IntFunction; + import java.util.stream.Stream; + + class A { + private final Stream s = Stream.of(1); + private final Map m = new HashMap<>(); + private final Runnable thrower = + () -> { + throw new RuntimeException(); + }; + + void unaryExternalStaticFunctionCalls() { + s.forEach(String::valueOf); + // BUG: Diagnostic contains: + s.forEach(v -> String.valueOf(v)); + s.forEach( + // BUG: Diagnostic contains: + (v) -> { + String.valueOf(v); + }); + s.forEach( + // BUG: Diagnostic contains: + (Integer v) -> { + { + String.valueOf(v); + } + }); + s.forEach( + v -> { + String.valueOf(v); + String.valueOf(v); + }); + + s.map(String::valueOf); + // BUG: Diagnostic contains: + s.map(v -> String.valueOf(v)); + // BUG: Diagnostic contains: + s.map((v) -> (String.valueOf(v))); + s.map( + // BUG: Diagnostic contains: + (Integer v) -> { + return String.valueOf(v); + }); + s.map( + // BUG: Diagnostic contains: + (final Integer v) -> { + return (String.valueOf(v)); + }); + s.map( + v -> { + String.valueOf(v); + return String.valueOf(v); + }); + + s.findFirst().orElseGet(() -> Integer.valueOf("0")); + m.forEach((k, v) -> String.valueOf(v)); + m.forEach((k, v) -> String.valueOf(k)); + } + + void binaryExternalInstanceFunctionCalls() { + m.forEach(m::put); + // BUG: Diagnostic contains: + m.forEach((k, v) -> m.put(k, v)); + m.forEach((k, v) -> m.put(v, k)); + m.forEach( + // BUG: Diagnostic contains: + (Integer k, Integer v) -> { + m.put(k, v); + }); + m.forEach( + (k, v) -> { + m.put(k, k); + }); + m.forEach( + // BUG: Diagnostic contains: + (final Integer k, final Integer v) -> { + { + m.put(k, v); + } + }); + m.forEach( + (k, v) -> { + { + m.put(v, v); + } + }); + m.forEach((k, v) -> new HashMap().put(k, v)); + m.forEach( + (k, v) -> { + m.put(k, v); + m.put(k, v); + }); + + Streams.zip(s, s, m::put); + // BUG: Diagnostic contains: + Streams.zip(s, s, (a, b) -> m.put(a, b)); + Streams.zip(s, s, (a, b) -> m.put(b, a)); + // BUG: Diagnostic contains: + Streams.zip(s, s, (Integer a, Integer b) -> (m.put(a, b))); + Streams.zip(s, s, (a, b) -> (m.put(a, a))); + Streams.zip( + s, + s, + // BUG: Diagnostic contains: + (final Integer a, final Integer b) -> { + return m.put(a, b); + }); + Streams.zip( + s, + s, + (a, b) -> { + return m.put(b, b); + }); + Streams.zip( + s, + s, + // BUG: Diagnostic contains: + (a, b) -> { + return (m.put(a, b)); + }); + Streams.zip( + s, + s, + (a, b) -> { + return (m.put(b, a)); + }); + Streams.zip( + s, + s, + (a, b) -> { + m.put(a, b); + return m.put(a, b); + }); + } + + void nullaryExternalInstanceFunctionCalls() { + s.map(Integer::doubleValue); + // BUG: Diagnostic contains: + s.map(i -> i.doubleValue()); + s.map(i -> i.toString()); + s.map(i -> s.toString()); + + // BUG: Diagnostic contains: + Stream.of(int.class).filter(c -> c.isEnum()); + Stream.of((Class) int.class).filter(Class::isEnum); + // BUG: Diagnostic contains: + Stream.of((Class) int.class).filter(c -> c.isEnum()); + } + + void localFunctionCalls() { + s.forEach(v -> ivoid0()); + s.forEach(v -> iint0()); + s.forEach(v -> svoid0()); + s.forEach(v -> sint0()); + + s.forEach(this::ivoid1); + // BUG: Diagnostic contains: + s.forEach(v -> ivoid1(v)); + s.forEach( + // BUG: Diagnostic contains: + v -> { + ivoid1(v); + }); + s.forEach(this::iint1); + // BUG: Diagnostic contains: + s.forEach(v -> iint1(v)); + s.forEach( + // BUG: Diagnostic contains: + v -> { + iint1(v); + }); + + s.forEach(A::svoid1); + // BUG: Diagnostic contains: + s.forEach(v -> svoid1(v)); + s.forEach( + // BUG: Diagnostic contains: + v -> { + svoid1(v); + }); + s.forEach(A::sint1); + // BUG: Diagnostic contains: + s.forEach(v -> sint1(v)); + s.forEach( + // BUG: Diagnostic contains: + v -> { + sint1(v); + }); + + s.forEach(v -> ivoid2(v, v)); + s.forEach(v -> iint2(v, v)); + s.forEach(v -> svoid2(v, v)); + s.forEach(v -> sint2(v, v)); + + m.forEach((k, v) -> ivoid0()); + m.forEach((k, v) -> iint0()); + m.forEach((k, v) -> svoid0()); + m.forEach((k, v) -> sint0()); + + m.forEach(this::ivoid2); + // BUG: Diagnostic contains: + m.forEach((k, v) -> ivoid2(k, v)); + m.forEach( + // BUG: Diagnostic contains: + (k, v) -> { + ivoid2(k, v); + }); + m.forEach(this::iint2); + // BUG: Diagnostic contains: + m.forEach((k, v) -> iint2(k, v)); + m.forEach( + // BUG: Diagnostic contains: + (k, v) -> { + iint2(k, v); + }); + + m.forEach(A::svoid2); + // BUG: Diagnostic contains: + m.forEach((k, v) -> svoid2(k, v)); + m.forEach( + // BUG: Diagnostic contains: + (k, v) -> { + svoid2(k, v); + }); + m.forEach(A::sint2); + // BUG: Diagnostic contains: + m.forEach((k, v) -> sint2(k, v)); + m.forEach( + // BUG: Diagnostic contains: + (k, v) -> { + sint2(k, v); + }); + } + + void functionCallsWhoseReplacementWouldBeAmbiguous() { + receiver( + i -> { + Integer.toString(i); + }); + } + + void assortedOtherEdgeCases() { + s.forEach(v -> String.valueOf(v.toString())); + TernaryOp o1 = (a, b, c) -> String.valueOf(a); + TernaryOp o2 = (a, b, c) -> String.valueOf(b); + TernaryOp o3 = (a, b, c) -> String.valueOf(c); + TernaryOp o4 = (a, b, c) -> c.concat(a); + TernaryOp o5 = (a, b, c) -> c.concat(b); + TernaryOp o6 = (a, b, c) -> a.concat(c); + TernaryOp o7 = (a, b, c) -> b.concat(c); + } + + void receiver(IntFunction op) {} + + void receiver(IntConsumer op) {} + + void ivoid0() {} + + void ivoid1(int a) {} + + void ivoid2(int a, int b) {} + + int iint0() { + return 0; + } + + int iint1(int a) { + return 0; + } + + int iint2(int a, int b) { + return 0; + } + + static void svoid0() {} + + static void svoid1(int a) {} + + static void svoid2(int a, int b) {} + + static void svoid3(int a, int b, int c) {} + + static int sint0() { + return 0; + } + + static int sint1(int a) { + return 0; + } + + static int sint2(int a, int b) { + return 0; + } + + interface TernaryOp { + String collect(String a, String b, String c); + } + } + """) .doTest(); } @@ -326,111 +328,115 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "import static java.util.Collections.emptyList;", - "", - "import java.util.Collections;", - "import java.util.List;", - "import java.util.Map;", - "import java.util.function.IntSupplier;", - "import java.util.function.Supplier;", - "import java.util.stream.Stream;", - "", - "class A {", - " static class B extends A {", - " final A a = new B();", - " final B b = new B();", - "", - " IntSupplier intSup;", - " Supplier> listSup;", - "", - " void m() {", - " intSup = () -> a.iint0();", - " intSup = () -> b.iint0();", - " intSup = () -> this.iint0();", - " intSup = () -> super.iint0();", - "", - " intSup = () -> a.sint0();", - " intSup = () -> b.sint0();", - " intSup = () -> this.sint0();", - " intSup = () -> super.sint0();", - " intSup = () -> A.sint0();", - " intSup = () -> B.sint0();", - "", - " listSup = () -> Collections.emptyList();", - " listSup = () -> emptyList();", - "", - " Stream.of((Class) int.class).filter(c -> c.isEnum());", - " Stream.of((Map) null).map(Map::keySet).map(s -> s.size());", - " }", - "", - " @Override", - " int iint0() {", - " return 0;", - " }", - " }", - "", - " int iint0() {", - " return 0;", - " }", - "", - " static int sint0() {", - " return 0;", - " }", - "}") + """ + import static java.util.Collections.emptyList; + + import java.util.Collections; + import java.util.List; + import java.util.Map; + import java.util.function.IntSupplier; + import java.util.function.Supplier; + import java.util.stream.Stream; + + class A { + static class B extends A { + final A a = new B(); + final B b = new B(); + + IntSupplier intSup; + Supplier> listSup; + + void m() { + intSup = () -> a.iint0(); + intSup = () -> b.iint0(); + intSup = () -> this.iint0(); + intSup = () -> super.iint0(); + + intSup = () -> a.sint0(); + intSup = () -> b.sint0(); + intSup = () -> this.sint0(); + intSup = () -> super.sint0(); + intSup = () -> A.sint0(); + intSup = () -> B.sint0(); + + listSup = () -> Collections.emptyList(); + listSup = () -> emptyList(); + + Stream.of((Class) int.class).filter(c -> c.isEnum()); + Stream.of((Map) null).map(Map::keySet).map(s -> s.size()); + } + + @Override + int iint0() { + return 0; + } + } + + int iint0() { + return 0; + } + + static int sint0() { + return 0; + } + } + """) .addOutputLines( "A.java", - "import static java.util.Collections.emptyList;", - "", - "import java.util.Collections;", - "import java.util.List;", - "import java.util.Map;", - "import java.util.Set;", - "import java.util.function.IntSupplier;", - "import java.util.function.Supplier;", - "import java.util.stream.Stream;", - "", - "class A {", - " static class B extends A {", - " final A a = new B();", - " final B b = new B();", - "", - " IntSupplier intSup;", - " Supplier> listSup;", - "", - " void m() {", - " intSup = a::iint0;", - " intSup = b::iint0;", - " intSup = this::iint0;", - " intSup = super::iint0;", - "", - " intSup = () -> a.sint0();", - " intSup = () -> b.sint0();", - " intSup = () -> this.sint0();", - " intSup = () -> super.sint0();", - " intSup = A::sint0;", - " intSup = B::sint0;", - "", - " listSup = Collections::emptyList;", - " listSup = Collections::emptyList;", - "", - " Stream.of((Class) int.class).filter(Class::isEnum);", - " Stream.of((Map) null).map(Map::keySet).map(Set::size);", - " }", - "", - " @Override", - " int iint0() {", - " return 0;", - " }", - " }", - "", - " int iint0() {", - " return 0;", - " }", - "", - " static int sint0() {", - " return 0;", - " }", - "}") + """ + import static java.util.Collections.emptyList; + + import java.util.Collections; + import java.util.List; + import java.util.Map; + import java.util.Set; + import java.util.function.IntSupplier; + import java.util.function.Supplier; + import java.util.stream.Stream; + + class A { + static class B extends A { + final A a = new B(); + final B b = new B(); + + IntSupplier intSup; + Supplier> listSup; + + void m() { + intSup = a::iint0; + intSup = b::iint0; + intSup = this::iint0; + intSup = super::iint0; + + intSup = () -> a.sint0(); + intSup = () -> b.sint0(); + intSup = () -> this.sint0(); + intSup = () -> super.sint0(); + intSup = A::sint0; + intSup = B::sint0; + + listSup = Collections::emptyList; + listSup = Collections::emptyList; + + Stream.of((Class) int.class).filter(Class::isEnum); + Stream.of((Map) null).map(Map::keySet).map(Set::size); + } + + @Override + int iint0() { + return 0; + } + } + + int iint0() { + return 0; + } + + static int sint0() { + return 0; + } + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MissingRefasterAnnotationTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MissingRefasterAnnotationTest.java index 74b2fcbfa01..19ec34ad929 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MissingRefasterAnnotationTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MissingRefasterAnnotationTest.java @@ -18,76 +18,78 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import com.google.errorprone.refaster.annotation.AfterTemplate;", - "import com.google.errorprone.refaster.annotation.AlsoNegation;", - "import com.google.errorprone.refaster.annotation.BeforeTemplate;", - "import java.util.Map;", - "", - "class A {", - " // BUG: Diagnostic matches: X", - " static final class MethodLacksBeforeTemplateAnnotation {", - " @BeforeTemplate", - " boolean before1(String string) {", - " return string.equals(\"\");", - " }", - "", - " // @BeforeTemplate is missing", - " boolean before2(String string) {", - " return string.length() == 0;", - " }", - "", - " @AfterTemplate", - " @AlsoNegation", - " boolean after(String string) {", - " return string.isEmpty();", - " }", - " }", - "", - " // BUG: Diagnostic matches: X", - " static final class MethodLacksAfterTemplateAnnotation {", - " @BeforeTemplate", - " boolean before(String string) {", - " return string.equals(\"\");", - " }", - "", - " // @AfterTemplate is missing", - " boolean after(String string) {", - " return string.isEmpty();", - " }", - " }", - "", - " // BUG: Diagnostic matches: X", - " abstract class MethodLacksPlaceholderAnnotation {", - " // @Placeholder is missing", - " abstract V function(K key);", - "", - " @BeforeTemplate", - " void before(Map map, K key) {", - " if (!map.containsKey(key)) {", - " map.put(key, function(key));", - " }", - " }", - "", - " @AfterTemplate", - " void after(Map map, K key) {", - " map.computeIfAbsent(key, k -> function(k));", - " }", - " }", - "", - " static final class ValidRefasterRule {", - " @BeforeTemplate", - " void unusedPureFunctionCall(Object o) {", - " o.toString();", - " }", - " }", - "", - " static final class NotARefasterRule {", - " @Override", - " public String toString() {", - " return \"This is not a Refaster rule\";", - " }", - " }", - "}") + """ + import com.google.errorprone.refaster.annotation.AfterTemplate; + import com.google.errorprone.refaster.annotation.AlsoNegation; + import com.google.errorprone.refaster.annotation.BeforeTemplate; + import java.util.Map; + + class A { + // BUG: Diagnostic matches: X + static final class MethodLacksBeforeTemplateAnnotation { + @BeforeTemplate + boolean before1(String string) { + return string.equals(""); + } + + // @BeforeTemplate is missing + boolean before2(String string) { + return string.length() == 0; + } + + @AfterTemplate + @AlsoNegation + boolean after(String string) { + return string.isEmpty(); + } + } + + // BUG: Diagnostic matches: X + static final class MethodLacksAfterTemplateAnnotation { + @BeforeTemplate + boolean before(String string) { + return string.equals(""); + } + + // @AfterTemplate is missing + boolean after(String string) { + return string.isEmpty(); + } + } + + // BUG: Diagnostic matches: X + abstract class MethodLacksPlaceholderAnnotation { + // @Placeholder is missing + abstract V function(K key); + + @BeforeTemplate + void before(Map map, K key) { + if (!map.containsKey(key)) { + map.put(key, function(key)); + } + } + + @AfterTemplate + void after(Map map, K key) { + map.computeIfAbsent(key, k -> function(k)); + } + } + + static final class ValidRefasterRule { + @BeforeTemplate + void unusedPureFunctionCall(Object o) { + o.toString(); + } + } + + static final class NotARefasterRule { + @Override + public String toString() { + return "This is not a Refaster rule"; + } + } + } + """) .doTest(); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MockitoStubbingTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MockitoStubbingTest.java index a1725d4b02f..6ddad77c858 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MockitoStubbingTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MockitoStubbingTest.java @@ -16,40 +16,42 @@ void identification() { compilationTestHelper .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 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 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()));", - " }", - "}") + """ + 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 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 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(); } @@ -58,48 +60,52 @@ void replacement() { refactoringTestHelper .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 consumer = mock(Consumer.class);", - " doAnswer(inv -> null).when(consumer).accept(ArgumentMatchers.eq(\"foo\"));", - " doAnswer(inv -> null).when(consumer).accept(eq(toString()));", - "", - " BiConsumer 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()));", - " }", - "}") + """ + 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 consumer = mock(Consumer.class); + doAnswer(inv -> null).when(consumer).accept(ArgumentMatchers.eq("foo")); + doAnswer(inv -> null).when(consumer).accept(eq(toString())); + + BiConsumer 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 consumer = mock(Consumer.class);", - " doAnswer(inv -> null).when(consumer).accept(\"foo\");", - " doAnswer(inv -> null).when(consumer).accept(toString());", - "", - " BiConsumer biConsumer = mock(BiConsumer.class);", - " doAnswer(inv -> null).when(biConsumer).accept(0, \"foo\");", - " doAnswer(inv -> null).when(biConsumer).accept(hashCode(), toString());", - " }", - "}") + """ + 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 consumer = mock(Consumer.class); + doAnswer(inv -> null).when(consumer).accept("foo"); + doAnswer(inv -> null).when(consumer).accept(toString()); + + BiConsumer biConsumer = mock(BiConsumer.class); + doAnswer(inv -> null).when(biConsumer).accept(0, "foo"); + doAnswer(inv -> null).when(biConsumer).accept(hashCode(), toString()); + } + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/NestedOptionalsTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/NestedOptionalsTest.java index d5154cf5540..ce082580f12 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/NestedOptionalsTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/NestedOptionalsTest.java @@ -12,31 +12,33 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import java.util.Optional;", - "import java.util.stream.Stream;", - "", - "class A {", - " void m() {", - " Optional.empty();", - " Optional.of(1);", - " // BUG: Diagnostic contains:", - " Optional.of(Optional.empty());", - " // BUG: Diagnostic contains:", - " Optional.of(Optional.of(1));", - "", - " Optional.ofNullable(null);", - " // BUG: Diagnostic contains:", - " Optional.ofNullable((Optional) null);", - "", - " Optional.of(\"foo\").map(String::length);", - " // BUG: Diagnostic contains:", - " Optional.of(\"foo\").map(Optional::of);", - "", - " Stream.of(\"foo\").findFirst();", - " // BUG: Diagnostic contains:", - " Stream.of(\"foo\").map(Optional::of).findFirst();", - " }", - "}") + """ + import java.util.Optional; + import java.util.stream.Stream; + + class A { + void m() { + Optional.empty(); + Optional.of(1); + // BUG: Diagnostic contains: + Optional.of(Optional.empty()); + // BUG: Diagnostic contains: + Optional.of(Optional.of(1)); + + Optional.ofNullable(null); + // BUG: Diagnostic contains: + Optional.ofNullable((Optional) null); + + Optional.of("foo").map(String::length); + // BUG: Diagnostic contains: + Optional.of("foo").map(Optional::of); + + Stream.of("foo").findFirst(); + // BUG: Diagnostic contains: + Stream.of("foo").map(Optional::of).findFirst(); + } + } + """) .doTest(); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/NonEmptyMonoTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/NonEmptyMonoTest.java index c4e79c91a84..25adc8aa0c5 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/NonEmptyMonoTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/NonEmptyMonoTest.java @@ -17,95 +17,97 @@ 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();", - " }", - "}") + """ + 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(); } @@ -114,42 +116,46 @@ 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));", - " }", - "}") + """ + 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();", - " }", - "}") + """ + 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); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/PrimitiveComparisonTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/PrimitiveComparisonTest.java index 276fb3633d6..f05882e99c9 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/PrimitiveComparisonTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/PrimitiveComparisonTest.java @@ -23,98 +23,100 @@ void byteComparison() { compilationTestHelper .addSourceLines( "A.java", - "import java.util.Comparator;", - "import java.util.function.Function;", - "", - "class A {", - " {", - " // BUG: Diagnostic contains:", - " Comparator.comparing(this::toPrimitive);", - " Comparator.comparing(this::toPrimitive, cmp());", - " // BUG: Diagnostic contains:", - " Comparator.comparing(o -> (byte) 0);", - " Comparator.comparing(o -> (byte) 0, cmp());", - " Comparator.comparing(this::toBoxed);", - " Comparator.comparing(this::toBoxed, cmp());", - " Comparator.comparing(o -> Byte.valueOf((byte) 0));", - " Comparator.comparing(o -> Byte.valueOf((byte) 0), cmp());", - " Comparator.comparing(toBoxed());", - " Comparator.comparing(toBoxed(), cmp());", - " Comparator.comparingInt(this::toPrimitive);", - " Comparator.comparingInt(o -> (byte) 0);", - " // BUG: Diagnostic contains:", - " Comparator.comparingInt(this::toBoxed);", - " // BUG: Diagnostic contains:", - " Comparator.comparingInt(o -> Byte.valueOf((byte) 0));", - " // BUG: Diagnostic contains:", - " Comparator.comparingLong(this::toPrimitive);", - " // BUG: Diagnostic contains:", - " Comparator.comparingLong(o -> (byte) 0);", - " // BUG: Diagnostic contains:", - " Comparator.comparingLong(this::toBoxed);", - " // BUG: Diagnostic contains:", - " Comparator.comparingLong(o -> Byte.valueOf((byte) 0));", - " // BUG: Diagnostic contains:", - " Comparator.comparingDouble(this::toPrimitive);", - " // BUG: Diagnostic contains:", - " Comparator.comparingDouble(o -> (byte) 0);", - " // BUG: Diagnostic contains:", - " Comparator.comparingDouble(this::toBoxed);", - " // BUG: Diagnostic contains:", - " Comparator.comparingDouble(o -> Byte.valueOf((byte) 0));", - "", - " // BUG: Diagnostic contains:", - " cmp().thenComparing(this::toPrimitive);", - " cmp().thenComparing(this::toPrimitive, cmp());", - " // BUG: Diagnostic contains:", - " cmp().thenComparing(o -> (byte) 0);", - " cmp().thenComparing(o -> (byte) 0, cmp());", - " cmp().thenComparing(this::toBoxed);", - " cmp().thenComparing(this::toBoxed, cmp());", - " cmp().thenComparing(o -> Byte.valueOf((byte) 0));", - " cmp().thenComparing(o -> Byte.valueOf((byte) 0), cmp());", - " cmp().thenComparing(toBoxed());", - " cmp().thenComparing(toBoxed(), cmp());", - " cmp().thenComparingInt(this::toPrimitive);", - " cmp().thenComparingInt(o -> (byte) 0);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingInt(this::toBoxed);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingInt(o -> Byte.valueOf((byte) 0));", - " // BUG: Diagnostic contains:", - " cmp().thenComparingLong(this::toPrimitive);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingLong(o -> (byte) 0);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingLong(this::toBoxed);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingLong(o -> Byte.valueOf((byte) 0));", - " // BUG: Diagnostic contains:", - " cmp().thenComparingDouble(this::toPrimitive);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingDouble(o -> (byte) 0);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingDouble(this::toBoxed);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingDouble(o -> Byte.valueOf((byte) 0));", - " }", - "", - " private Comparator cmp() {", - " return null;", - " }", - "", - " private byte toPrimitive(Object o) {", - " return 0;", - " }", - "", - " private Byte toBoxed(Object o) {", - " return 0;", - " }", - "", - " private Function toBoxed() {", - " return o -> 0;", - " }", - "}") + """ + import java.util.Comparator; + import java.util.function.Function; + + class A { + { + // BUG: Diagnostic contains: + Comparator.comparing(this::toPrimitive); + Comparator.comparing(this::toPrimitive, cmp()); + // BUG: Diagnostic contains: + Comparator.comparing(o -> (byte) 0); + Comparator.comparing(o -> (byte) 0, cmp()); + Comparator.comparing(this::toBoxed); + Comparator.comparing(this::toBoxed, cmp()); + Comparator.comparing(o -> Byte.valueOf((byte) 0)); + Comparator.comparing(o -> Byte.valueOf((byte) 0), cmp()); + Comparator.comparing(toBoxed()); + Comparator.comparing(toBoxed(), cmp()); + Comparator.comparingInt(this::toPrimitive); + Comparator.comparingInt(o -> (byte) 0); + // BUG: Diagnostic contains: + Comparator.comparingInt(this::toBoxed); + // BUG: Diagnostic contains: + Comparator.comparingInt(o -> Byte.valueOf((byte) 0)); + // BUG: Diagnostic contains: + Comparator.comparingLong(this::toPrimitive); + // BUG: Diagnostic contains: + Comparator.comparingLong(o -> (byte) 0); + // BUG: Diagnostic contains: + Comparator.comparingLong(this::toBoxed); + // BUG: Diagnostic contains: + Comparator.comparingLong(o -> Byte.valueOf((byte) 0)); + // BUG: Diagnostic contains: + Comparator.comparingDouble(this::toPrimitive); + // BUG: Diagnostic contains: + Comparator.comparingDouble(o -> (byte) 0); + // BUG: Diagnostic contains: + Comparator.comparingDouble(this::toBoxed); + // BUG: Diagnostic contains: + Comparator.comparingDouble(o -> Byte.valueOf((byte) 0)); + + // BUG: Diagnostic contains: + cmp().thenComparing(this::toPrimitive); + cmp().thenComparing(this::toPrimitive, cmp()); + // BUG: Diagnostic contains: + cmp().thenComparing(o -> (byte) 0); + cmp().thenComparing(o -> (byte) 0, cmp()); + cmp().thenComparing(this::toBoxed); + cmp().thenComparing(this::toBoxed, cmp()); + cmp().thenComparing(o -> Byte.valueOf((byte) 0)); + cmp().thenComparing(o -> Byte.valueOf((byte) 0), cmp()); + cmp().thenComparing(toBoxed()); + cmp().thenComparing(toBoxed(), cmp()); + cmp().thenComparingInt(this::toPrimitive); + cmp().thenComparingInt(o -> (byte) 0); + // BUG: Diagnostic contains: + cmp().thenComparingInt(this::toBoxed); + // BUG: Diagnostic contains: + cmp().thenComparingInt(o -> Byte.valueOf((byte) 0)); + // BUG: Diagnostic contains: + cmp().thenComparingLong(this::toPrimitive); + // BUG: Diagnostic contains: + cmp().thenComparingLong(o -> (byte) 0); + // BUG: Diagnostic contains: + cmp().thenComparingLong(this::toBoxed); + // BUG: Diagnostic contains: + cmp().thenComparingLong(o -> Byte.valueOf((byte) 0)); + // BUG: Diagnostic contains: + cmp().thenComparingDouble(this::toPrimitive); + // BUG: Diagnostic contains: + cmp().thenComparingDouble(o -> (byte) 0); + // BUG: Diagnostic contains: + cmp().thenComparingDouble(this::toBoxed); + // BUG: Diagnostic contains: + cmp().thenComparingDouble(o -> Byte.valueOf((byte) 0)); + } + + private Comparator cmp() { + return null; + } + + private byte toPrimitive(Object o) { + return 0; + } + + private Byte toBoxed(Object o) { + return 0; + } + + private Function toBoxed() { + return o -> 0; + } + } + """) .doTest(); } @@ -123,105 +125,107 @@ void intComparison() { compilationTestHelper .addSourceLines( "A.java", - "import java.util.Comparator;", - "import java.util.function.Function;", - "import java.util.function.ToIntFunction;", - "", - "class A {", - " {", - " // BUG: Diagnostic contains:", - " Comparator.comparing(this::toPrimitive);", - " Comparator.comparing(this::toPrimitive, cmp());", - " // BUG: Diagnostic contains:", - " Comparator.comparing(o -> 0);", - " Comparator.comparing(o -> 0, cmp());", - " Comparator.comparing(this::toBoxed);", - " Comparator.comparing(this::toBoxed, cmp());", - " Comparator.comparing(o -> Integer.valueOf(0));", - " Comparator.comparing(o -> Integer.valueOf(0), cmp());", - " Comparator.comparing(toBoxed());", - " Comparator.comparing(toBoxed(), cmp());", - " Comparator.comparingInt(this::toPrimitive);", - " Comparator.comparingInt(o -> 0);", - " Comparator.comparingInt(toPrimitive());", - " // BUG: Diagnostic contains:", - " Comparator.comparingInt(this::toBoxed);", - " // BUG: Diagnostic contains:", - " Comparator.comparingInt(o -> Integer.valueOf(0));", - " // BUG: Diagnostic contains:", - " Comparator.comparingLong(this::toPrimitive);", - " // BUG: Diagnostic contains:", - " Comparator.comparingLong(o -> 0);", - " // BUG: Diagnostic contains:", - " Comparator.comparingLong(this::toBoxed);", - " // BUG: Diagnostic contains:", - " Comparator.comparingLong(o -> Integer.valueOf(0));", - " // BUG: Diagnostic contains:", - " Comparator.comparingDouble(this::toPrimitive);", - " // BUG: Diagnostic contains:", - " Comparator.comparingDouble(o -> 0);", - " // BUG: Diagnostic contains:", - " Comparator.comparingDouble(this::toBoxed);", - " // BUG: Diagnostic contains:", - " Comparator.comparingDouble(o -> Integer.valueOf(0));", - "", - " // BUG: Diagnostic contains:", - " cmp().thenComparing(this::toPrimitive);", - " cmp().thenComparing(this::toPrimitive, cmp());", - " // BUG: Diagnostic contains:", - " cmp().thenComparing(o -> 0);", - " cmp().thenComparing(o -> 0, cmp());", - " cmp().thenComparing(this::toBoxed);", - " cmp().thenComparing(this::toBoxed, cmp());", - " cmp().thenComparing(o -> Integer.valueOf(0));", - " cmp().thenComparing(o -> Integer.valueOf(0), cmp());", - " cmp().thenComparing(toBoxed());", - " cmp().thenComparing(toBoxed(), cmp());", - " cmp().thenComparingInt(this::toPrimitive);", - " cmp().thenComparingInt(o -> 0);", - " cmp().thenComparingInt(toPrimitive());", - " // BUG: Diagnostic contains:", - " cmp().thenComparingInt(this::toBoxed);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingInt(o -> Integer.valueOf(0));", - " // BUG: Diagnostic contains:", - " cmp().thenComparingLong(this::toPrimitive);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingLong(o -> 0);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingLong(this::toBoxed);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingLong(o -> Integer.valueOf(0));", - " // BUG: Diagnostic contains:", - " cmp().thenComparingDouble(this::toPrimitive);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingDouble(o -> 0);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingDouble(this::toBoxed);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingDouble(o -> Integer.valueOf(0));", - " }", - "", - " private Comparator cmp() {", - " return null;", - " }", - "", - " private int toPrimitive(Object o) {", - " return 0;", - " }", - "", - " private Integer toBoxed(Object o) {", - " return 0;", - " }", - "", - " private Function toBoxed() {", - " return o -> 0;", - " }", - "", - " private ToIntFunction toPrimitive() {", - " return o -> 0;", - " }", - "}") + """ + import java.util.Comparator; + import java.util.function.Function; + import java.util.function.ToIntFunction; + + class A { + { + // BUG: Diagnostic contains: + Comparator.comparing(this::toPrimitive); + Comparator.comparing(this::toPrimitive, cmp()); + // BUG: Diagnostic contains: + Comparator.comparing(o -> 0); + Comparator.comparing(o -> 0, cmp()); + Comparator.comparing(this::toBoxed); + Comparator.comparing(this::toBoxed, cmp()); + Comparator.comparing(o -> Integer.valueOf(0)); + Comparator.comparing(o -> Integer.valueOf(0), cmp()); + Comparator.comparing(toBoxed()); + Comparator.comparing(toBoxed(), cmp()); + Comparator.comparingInt(this::toPrimitive); + Comparator.comparingInt(o -> 0); + Comparator.comparingInt(toPrimitive()); + // BUG: Diagnostic contains: + Comparator.comparingInt(this::toBoxed); + // BUG: Diagnostic contains: + Comparator.comparingInt(o -> Integer.valueOf(0)); + // BUG: Diagnostic contains: + Comparator.comparingLong(this::toPrimitive); + // BUG: Diagnostic contains: + Comparator.comparingLong(o -> 0); + // BUG: Diagnostic contains: + Comparator.comparingLong(this::toBoxed); + // BUG: Diagnostic contains: + Comparator.comparingLong(o -> Integer.valueOf(0)); + // BUG: Diagnostic contains: + Comparator.comparingDouble(this::toPrimitive); + // BUG: Diagnostic contains: + Comparator.comparingDouble(o -> 0); + // BUG: Diagnostic contains: + Comparator.comparingDouble(this::toBoxed); + // BUG: Diagnostic contains: + Comparator.comparingDouble(o -> Integer.valueOf(0)); + + // BUG: Diagnostic contains: + cmp().thenComparing(this::toPrimitive); + cmp().thenComparing(this::toPrimitive, cmp()); + // BUG: Diagnostic contains: + cmp().thenComparing(o -> 0); + cmp().thenComparing(o -> 0, cmp()); + cmp().thenComparing(this::toBoxed); + cmp().thenComparing(this::toBoxed, cmp()); + cmp().thenComparing(o -> Integer.valueOf(0)); + cmp().thenComparing(o -> Integer.valueOf(0), cmp()); + cmp().thenComparing(toBoxed()); + cmp().thenComparing(toBoxed(), cmp()); + cmp().thenComparingInt(this::toPrimitive); + cmp().thenComparingInt(o -> 0); + cmp().thenComparingInt(toPrimitive()); + // BUG: Diagnostic contains: + cmp().thenComparingInt(this::toBoxed); + // BUG: Diagnostic contains: + cmp().thenComparingInt(o -> Integer.valueOf(0)); + // BUG: Diagnostic contains: + cmp().thenComparingLong(this::toPrimitive); + // BUG: Diagnostic contains: + cmp().thenComparingLong(o -> 0); + // BUG: Diagnostic contains: + cmp().thenComparingLong(this::toBoxed); + // BUG: Diagnostic contains: + cmp().thenComparingLong(o -> Integer.valueOf(0)); + // BUG: Diagnostic contains: + cmp().thenComparingDouble(this::toPrimitive); + // BUG: Diagnostic contains: + cmp().thenComparingDouble(o -> 0); + // BUG: Diagnostic contains: + cmp().thenComparingDouble(this::toBoxed); + // BUG: Diagnostic contains: + cmp().thenComparingDouble(o -> Integer.valueOf(0)); + } + + private Comparator cmp() { + return null; + } + + private int toPrimitive(Object o) { + return 0; + } + + private Integer toBoxed(Object o) { + return 0; + } + + private Function toBoxed() { + return o -> 0; + } + + private ToIntFunction toPrimitive() { + return o -> 0; + } + } + """) .doTest(); } @@ -230,89 +234,91 @@ void longComparison() { compilationTestHelper .addSourceLines( "A.java", - "import java.util.Comparator;", - "import java.util.function.Function;", - "import java.util.function.ToLongFunction;", - "", - "class A {", - " {", - " // BUG: Diagnostic contains:", - " Comparator.comparing(this::toPrimitive);", - " Comparator.comparing(this::toPrimitive, cmp());", - " // BUG: Diagnostic contains:", - " Comparator.comparing(o -> 0L);", - " Comparator.comparing(o -> 0L, cmp());", - " Comparator.comparing(this::toBoxed);", - " Comparator.comparing(this::toBoxed, cmp());", - " Comparator.comparing(o -> Long.valueOf(0));", - " Comparator.comparing(o -> Long.valueOf(0), cmp());", - " Comparator.comparing(toBoxed());", - " Comparator.comparing(toBoxed(), cmp());", - " Comparator.comparingLong(this::toPrimitive);", - " Comparator.comparingLong(o -> 0L);", - " Comparator.comparingLong(toPrimitive());", - " // BUG: Diagnostic contains:", - " Comparator.comparingLong(this::toBoxed);", - " // BUG: Diagnostic contains:", - " Comparator.comparingLong(o -> Long.valueOf(0));", - " // BUG: Diagnostic contains:", - " Comparator.comparingDouble(this::toPrimitive);", - " // BUG: Diagnostic contains:", - " Comparator.comparingDouble(o -> 0L);", - " // BUG: Diagnostic contains:", - " Comparator.comparingDouble(this::toBoxed);", - " // BUG: Diagnostic contains:", - " Comparator.comparingDouble(o -> Long.valueOf(0));", - "", - " // BUG: Diagnostic contains:", - " cmp().thenComparing(this::toPrimitive);", - " cmp().thenComparing(this::toPrimitive, cmp());", - " // BUG: Diagnostic contains:", - " cmp().thenComparing(o -> 0L);", - " cmp().thenComparing(o -> 0L, cmp());", - " cmp().thenComparing(this::toBoxed);", - " cmp().thenComparing(this::toBoxed, cmp());", - " cmp().thenComparing(o -> Long.valueOf(0));", - " cmp().thenComparing(o -> Long.valueOf(0), cmp());", - " cmp().thenComparing(toBoxed());", - " cmp().thenComparing(toBoxed(), cmp());", - " cmp().thenComparingLong(this::toPrimitive);", - " cmp().thenComparingLong(o -> 0L);", - " cmp().thenComparingLong(toPrimitive());", - " // BUG: Diagnostic contains:", - " cmp().thenComparingLong(this::toBoxed);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingLong(o -> Long.valueOf(0));", - " // BUG: Diagnostic contains:", - " cmp().thenComparingDouble(this::toPrimitive);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingDouble(o -> 0L);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingDouble(this::toBoxed);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingDouble(o -> Long.valueOf(0));", - " }", - "", - " private Comparator cmp() {", - " return null;", - " }", - "", - " private long toPrimitive(Object o) {", - " return 0L;", - " }", - "", - " private Long toBoxed(Object o) {", - " return 0L;", - " }", - "", - " private Function toBoxed() {", - " return o -> 0L;", - " }", - "", - " private ToLongFunction toPrimitive() {", - " return o -> 0L;", - " }", - "}") + """ + import java.util.Comparator; + import java.util.function.Function; + import java.util.function.ToLongFunction; + + class A { + { + // BUG: Diagnostic contains: + Comparator.comparing(this::toPrimitive); + Comparator.comparing(this::toPrimitive, cmp()); + // BUG: Diagnostic contains: + Comparator.comparing(o -> 0L); + Comparator.comparing(o -> 0L, cmp()); + Comparator.comparing(this::toBoxed); + Comparator.comparing(this::toBoxed, cmp()); + Comparator.comparing(o -> Long.valueOf(0)); + Comparator.comparing(o -> Long.valueOf(0), cmp()); + Comparator.comparing(toBoxed()); + Comparator.comparing(toBoxed(), cmp()); + Comparator.comparingLong(this::toPrimitive); + Comparator.comparingLong(o -> 0L); + Comparator.comparingLong(toPrimitive()); + // BUG: Diagnostic contains: + Comparator.comparingLong(this::toBoxed); + // BUG: Diagnostic contains: + Comparator.comparingLong(o -> Long.valueOf(0)); + // BUG: Diagnostic contains: + Comparator.comparingDouble(this::toPrimitive); + // BUG: Diagnostic contains: + Comparator.comparingDouble(o -> 0L); + // BUG: Diagnostic contains: + Comparator.comparingDouble(this::toBoxed); + // BUG: Diagnostic contains: + Comparator.comparingDouble(o -> Long.valueOf(0)); + + // BUG: Diagnostic contains: + cmp().thenComparing(this::toPrimitive); + cmp().thenComparing(this::toPrimitive, cmp()); + // BUG: Diagnostic contains: + cmp().thenComparing(o -> 0L); + cmp().thenComparing(o -> 0L, cmp()); + cmp().thenComparing(this::toBoxed); + cmp().thenComparing(this::toBoxed, cmp()); + cmp().thenComparing(o -> Long.valueOf(0)); + cmp().thenComparing(o -> Long.valueOf(0), cmp()); + cmp().thenComparing(toBoxed()); + cmp().thenComparing(toBoxed(), cmp()); + cmp().thenComparingLong(this::toPrimitive); + cmp().thenComparingLong(o -> 0L); + cmp().thenComparingLong(toPrimitive()); + // BUG: Diagnostic contains: + cmp().thenComparingLong(this::toBoxed); + // BUG: Diagnostic contains: + cmp().thenComparingLong(o -> Long.valueOf(0)); + // BUG: Diagnostic contains: + cmp().thenComparingDouble(this::toPrimitive); + // BUG: Diagnostic contains: + cmp().thenComparingDouble(o -> 0L); + // BUG: Diagnostic contains: + cmp().thenComparingDouble(this::toBoxed); + // BUG: Diagnostic contains: + cmp().thenComparingDouble(o -> Long.valueOf(0)); + } + + private Comparator cmp() { + return null; + } + + private long toPrimitive(Object o) { + return 0L; + } + + private Long toBoxed(Object o) { + return 0L; + } + + private Function toBoxed() { + return o -> 0L; + } + + private ToLongFunction toPrimitive() { + return o -> 0L; + } + } + """) .doTest(); } @@ -321,66 +327,68 @@ void floatComparison() { compilationTestHelper .addSourceLines( "A.java", - "import java.util.Comparator;", - "import java.util.function.Function;", - "", - "class A {", - " {", - " // BUG: Diagnostic contains:", - " Comparator.comparing(this::toPrimitive);", - " Comparator.comparing(this::toPrimitive, cmp());", - " // BUG: Diagnostic contains:", - " Comparator.comparing(o -> 0.0f);", - " Comparator.comparing(o -> 0.0f, cmp());", - " Comparator.comparing(this::toBoxed);", - " Comparator.comparing(this::toBoxed, cmp());", - " Comparator.comparing(o -> Float.valueOf(0));", - " Comparator.comparing(o -> Float.valueOf(0), cmp());", - " Comparator.comparing(toBoxed());", - " Comparator.comparing(toBoxed(), cmp());", - " Comparator.comparingDouble(this::toPrimitive);", - " Comparator.comparingDouble(o -> 0.0f);", - " // BUG: Diagnostic contains:", - " Comparator.comparingDouble(this::toBoxed);", - " // BUG: Diagnostic contains:", - " Comparator.comparingDouble(o -> Float.valueOf(0));", - "", - " // BUG: Diagnostic contains:", - " cmp().thenComparing(this::toPrimitive);", - " cmp().thenComparing(this::toPrimitive, cmp());", - " // BUG: Diagnostic contains:", - " cmp().thenComparing(o -> 0.0f);", - " cmp().thenComparing(o -> 0.0f, cmp());", - " cmp().thenComparing(this::toBoxed);", - " cmp().thenComparing(this::toBoxed, cmp());", - " cmp().thenComparing(o -> Float.valueOf(0));", - " cmp().thenComparing(o -> Float.valueOf(0), cmp());", - " cmp().thenComparing(toBoxed());", - " cmp().thenComparing(toBoxed(), cmp());", - " cmp().thenComparingDouble(this::toPrimitive);", - " cmp().thenComparingDouble(o -> 0.0f);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingDouble(this::toBoxed);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingDouble(o -> Float.valueOf(0));", - " }", - "", - " private Comparator cmp() {", - " return null;", - " }", - "", - " private float toPrimitive(Object o) {", - " return 0.0f;", - " }", - "", - " private Float toBoxed(Object o) {", - " return 0.0f;", - " }", - "", - " private Function toBoxed() {", - " return o -> 0.0f;", - " }", - "}") + """ + import java.util.Comparator; + import java.util.function.Function; + + class A { + { + // BUG: Diagnostic contains: + Comparator.comparing(this::toPrimitive); + Comparator.comparing(this::toPrimitive, cmp()); + // BUG: Diagnostic contains: + Comparator.comparing(o -> 0.0f); + Comparator.comparing(o -> 0.0f, cmp()); + Comparator.comparing(this::toBoxed); + Comparator.comparing(this::toBoxed, cmp()); + Comparator.comparing(o -> Float.valueOf(0)); + Comparator.comparing(o -> Float.valueOf(0), cmp()); + Comparator.comparing(toBoxed()); + Comparator.comparing(toBoxed(), cmp()); + Comparator.comparingDouble(this::toPrimitive); + Comparator.comparingDouble(o -> 0.0f); + // BUG: Diagnostic contains: + Comparator.comparingDouble(this::toBoxed); + // BUG: Diagnostic contains: + Comparator.comparingDouble(o -> Float.valueOf(0)); + + // BUG: Diagnostic contains: + cmp().thenComparing(this::toPrimitive); + cmp().thenComparing(this::toPrimitive, cmp()); + // BUG: Diagnostic contains: + cmp().thenComparing(o -> 0.0f); + cmp().thenComparing(o -> 0.0f, cmp()); + cmp().thenComparing(this::toBoxed); + cmp().thenComparing(this::toBoxed, cmp()); + cmp().thenComparing(o -> Float.valueOf(0)); + cmp().thenComparing(o -> Float.valueOf(0), cmp()); + cmp().thenComparing(toBoxed()); + cmp().thenComparing(toBoxed(), cmp()); + cmp().thenComparingDouble(this::toPrimitive); + cmp().thenComparingDouble(o -> 0.0f); + // BUG: Diagnostic contains: + cmp().thenComparingDouble(this::toBoxed); + // BUG: Diagnostic contains: + cmp().thenComparingDouble(o -> Float.valueOf(0)); + } + + private Comparator cmp() { + return null; + } + + private float toPrimitive(Object o) { + return 0.0f; + } + + private Float toBoxed(Object o) { + return 0.0f; + } + + private Function toBoxed() { + return o -> 0.0f; + } + } + """) .doTest(); } @@ -389,73 +397,75 @@ void doubleComparison() { compilationTestHelper .addSourceLines( "A.java", - "import java.util.Comparator;", - "import java.util.function.Function;", - "import java.util.function.ToDoubleFunction;", - "", - "class A {", - " {", - " // BUG: Diagnostic contains:", - " Comparator.comparing(this::toPrimitive);", - " Comparator.comparing(this::toPrimitive, cmp());", - " // BUG: Diagnostic contains:", - " Comparator.comparing(o -> 0.0);", - " Comparator.comparing(o -> 0.0, cmp());", - " Comparator.comparing(this::toBoxed);", - " Comparator.comparing(this::toBoxed, cmp());", - " Comparator.comparing(o -> Double.valueOf(0));", - " Comparator.comparing(o -> Double.valueOf(0), cmp());", - " Comparator.comparing(toBoxed());", - " Comparator.comparing(toBoxed(), cmp());", - " Comparator.comparingDouble(this::toPrimitive);", - " Comparator.comparingDouble(o -> 0.0);", - " Comparator.comparingDouble(toPrimitive());", - " // BUG: Diagnostic contains:", - " Comparator.comparingDouble(this::toBoxed);", - " // BUG: Diagnostic contains:", - " Comparator.comparingDouble(o -> Double.valueOf(0));", - "", - " // BUG: Diagnostic contains:", - " cmp().thenComparing(this::toPrimitive);", - " cmp().thenComparing(this::toPrimitive, cmp());", - " // BUG: Diagnostic contains:", - " cmp().thenComparing(o -> 0.0);", - " cmp().thenComparing(o -> 0.0, cmp());", - " cmp().thenComparing(this::toBoxed);", - " cmp().thenComparing(this::toBoxed, cmp());", - " cmp().thenComparing(o -> Double.valueOf(0));", - " cmp().thenComparing(o -> Double.valueOf(0), cmp());", - " cmp().thenComparing(toBoxed());", - " cmp().thenComparing(toBoxed(), cmp());", - " cmp().thenComparingDouble(this::toPrimitive);", - " cmp().thenComparingDouble(o -> 0.0);", - " cmp().thenComparingDouble(toPrimitive());", - " // BUG: Diagnostic contains:", - " cmp().thenComparingDouble(this::toBoxed);", - " // BUG: Diagnostic contains:", - " cmp().thenComparingDouble(o -> Double.valueOf(0));", - " }", - "", - " private Comparator cmp() {", - " return null;", - " }", - "", - " private double toPrimitive(Object o) {", - " return 0.0;", - " }", - "", - " private Double toBoxed(Object o) {", - " return 0.0;", - " }", - "", - " private Function toBoxed() {", - " return o -> 0.0;", - " }", - "", - " private ToDoubleFunction toPrimitive() {", - " return o -> 0.0;", - " }", - "}") + """ + import java.util.Comparator; + import java.util.function.Function; + import java.util.function.ToDoubleFunction; + + class A { + { + // BUG: Diagnostic contains: + Comparator.comparing(this::toPrimitive); + Comparator.comparing(this::toPrimitive, cmp()); + // BUG: Diagnostic contains: + Comparator.comparing(o -> 0.0); + Comparator.comparing(o -> 0.0, cmp()); + Comparator.comparing(this::toBoxed); + Comparator.comparing(this::toBoxed, cmp()); + Comparator.comparing(o -> Double.valueOf(0)); + Comparator.comparing(o -> Double.valueOf(0), cmp()); + Comparator.comparing(toBoxed()); + Comparator.comparing(toBoxed(), cmp()); + Comparator.comparingDouble(this::toPrimitive); + Comparator.comparingDouble(o -> 0.0); + Comparator.comparingDouble(toPrimitive()); + // BUG: Diagnostic contains: + Comparator.comparingDouble(this::toBoxed); + // BUG: Diagnostic contains: + Comparator.comparingDouble(o -> Double.valueOf(0)); + + // BUG: Diagnostic contains: + cmp().thenComparing(this::toPrimitive); + cmp().thenComparing(this::toPrimitive, cmp()); + // BUG: Diagnostic contains: + cmp().thenComparing(o -> 0.0); + cmp().thenComparing(o -> 0.0, cmp()); + cmp().thenComparing(this::toBoxed); + cmp().thenComparing(this::toBoxed, cmp()); + cmp().thenComparing(o -> Double.valueOf(0)); + cmp().thenComparing(o -> Double.valueOf(0), cmp()); + cmp().thenComparing(toBoxed()); + cmp().thenComparing(toBoxed(), cmp()); + cmp().thenComparingDouble(this::toPrimitive); + cmp().thenComparingDouble(o -> 0.0); + cmp().thenComparingDouble(toPrimitive()); + // BUG: Diagnostic contains: + cmp().thenComparingDouble(this::toBoxed); + // BUG: Diagnostic contains: + cmp().thenComparingDouble(o -> Double.valueOf(0)); + } + + private Comparator cmp() { + return null; + } + + private double toPrimitive(Object o) { + return 0.0; + } + + private Double toBoxed(Object o) { + return 0.0; + } + + private Function toBoxed() { + return o -> 0.0; + } + + private ToDoubleFunction toPrimitive() { + return o -> 0.0; + } + } + """) .doTest(); } @@ -464,34 +474,36 @@ void stringComparison() { compilationTestHelper .addSourceLines( "A.java", - "import java.util.Comparator;", - "import java.util.function.Function;", - "", - "class A {", - " {", - " Comparator.comparing(String::valueOf);", - " Comparator.comparing(String::valueOf, cmp());", - " Comparator.comparing(o -> String.valueOf(o));", - " Comparator.comparing(o -> String.valueOf(o), cmp());", - " Comparator.comparing(toStr());", - " Comparator.comparing(toStr(), cmp());", - "", - " cmp().thenComparing(String::valueOf);", - " cmp().thenComparing(String::valueOf, cmp());", - " cmp().thenComparing(o -> String.valueOf(o));", - " cmp().thenComparing(o -> String.valueOf(o), cmp());", - " cmp().thenComparing(toStr());", - " cmp().thenComparing(toStr(), cmp());", - " }", - "", - " private Comparator cmp() {", - " return null;", - " }", - "", - " private Function toStr() {", - " return String::valueOf;", - " }", - "}") + """ + import java.util.Comparator; + import java.util.function.Function; + + class A { + { + Comparator.comparing(String::valueOf); + Comparator.comparing(String::valueOf, cmp()); + Comparator.comparing(o -> String.valueOf(o)); + Comparator.comparing(o -> String.valueOf(o), cmp()); + Comparator.comparing(toStr()); + Comparator.comparing(toStr(), cmp()); + + cmp().thenComparing(String::valueOf); + cmp().thenComparing(String::valueOf, cmp()); + cmp().thenComparing(o -> String.valueOf(o)); + cmp().thenComparing(o -> String.valueOf(o), cmp()); + cmp().thenComparing(toStr()); + cmp().thenComparing(toStr(), cmp()); + } + + private Comparator cmp() { + return null; + } + + private Function toStr() { + return String::valueOf; + } + } + """) .doTest(); } @@ -500,78 +512,82 @@ void replacementWithPrimitiveVariants() { refactoringTestHelper .addInputLines( "A.java", - "import java.util.Comparator;", - "", - "interface A extends Comparable {", - " Comparator bCmp = Comparator.comparing(o -> (byte) 0);", - " Comparator bCmp2 = Comparator.comparing(o -> (byte) 0);", - " Comparator cCmp = Comparator.comparing(o -> (char) 0);", - " Comparator cCmp2 = Comparator.comparing(o -> (char) 0);", - " Comparator sCmp = Comparator.comparing(o -> (short) 0);", - " Comparator sCmp2 = Comparator.comparing(o -> (short) 0);", - " Comparator iCmp = Comparator.comparing(o -> 0);", - " Comparator iCmp2 = Comparator.comparing(o -> 0);", - " Comparator lCmp = Comparator.comparing(o -> 0L);", - " Comparator lCmp2 = Comparator.comparing(o -> 0L);", - " Comparator fCmp = Comparator.comparing(o -> 0.0f);", - " Comparator fCmp2 = Comparator.comparing(o -> 0.0f);", - " Comparator dCmp = Comparator.comparing(o -> 0.0);", - " Comparator dCmp2 = Comparator.comparing(o -> 0.0);", - "", - " default void m() {", - " bCmp.thenComparing(o -> (byte) 0);", - " bCmp.thenComparing(o -> (byte) 0);", - " cCmp.thenComparing(o -> (char) 0);", - " cCmp.thenComparing(o -> (char) 0);", - " sCmp.thenComparing(o -> (short) 0);", - " sCmp.thenComparing(o -> (short) 0);", - " iCmp.thenComparing(o -> 0);", - " iCmp.thenComparing(o -> 0);", - " lCmp.thenComparing(o -> 0L);", - " lCmp.thenComparing(o -> 0L);", - " fCmp.thenComparing(o -> 0.0f);", - " fCmp.thenComparing(o -> 0.0f);", - " dCmp.thenComparing(o -> 0.0);", - " dCmp.thenComparing(o -> 0.0);", - " }", - "}") + """ + import java.util.Comparator; + + interface A extends Comparable { + Comparator bCmp = Comparator.comparing(o -> (byte) 0); + Comparator bCmp2 = Comparator.comparing(o -> (byte) 0); + Comparator cCmp = Comparator.comparing(o -> (char) 0); + Comparator cCmp2 = Comparator.comparing(o -> (char) 0); + Comparator sCmp = Comparator.comparing(o -> (short) 0); + Comparator sCmp2 = Comparator.comparing(o -> (short) 0); + Comparator iCmp = Comparator.comparing(o -> 0); + Comparator iCmp2 = Comparator.comparing(o -> 0); + Comparator lCmp = Comparator.comparing(o -> 0L); + Comparator lCmp2 = Comparator.comparing(o -> 0L); + Comparator fCmp = Comparator.comparing(o -> 0.0f); + Comparator fCmp2 = Comparator.comparing(o -> 0.0f); + Comparator dCmp = Comparator.comparing(o -> 0.0); + Comparator dCmp2 = Comparator.comparing(o -> 0.0); + + default void m() { + bCmp.thenComparing(o -> (byte) 0); + bCmp.thenComparing(o -> (byte) 0); + cCmp.thenComparing(o -> (char) 0); + cCmp.thenComparing(o -> (char) 0); + sCmp.thenComparing(o -> (short) 0); + sCmp.thenComparing(o -> (short) 0); + iCmp.thenComparing(o -> 0); + iCmp.thenComparing(o -> 0); + lCmp.thenComparing(o -> 0L); + lCmp.thenComparing(o -> 0L); + fCmp.thenComparing(o -> 0.0f); + fCmp.thenComparing(o -> 0.0f); + dCmp.thenComparing(o -> 0.0); + dCmp.thenComparing(o -> 0.0); + } + } + """) .addOutputLines( "A.java", - "import java.util.Comparator;", - "", - "interface A extends Comparable {", - " Comparator bCmp = Comparator.comparingInt(o -> (byte) 0);", - " Comparator bCmp2 = Comparator.comparingInt(o -> (byte) 0);", - " Comparator cCmp = Comparator.comparingInt(o -> (char) 0);", - " Comparator cCmp2 = Comparator.comparingInt(o -> (char) 0);", - " Comparator sCmp = Comparator.comparingInt(o -> (short) 0);", - " Comparator sCmp2 = Comparator.comparingInt(o -> (short) 0);", - " Comparator iCmp = Comparator.comparingInt(o -> 0);", - " Comparator iCmp2 = Comparator.comparingInt(o -> 0);", - " Comparator lCmp = Comparator.comparingLong(o -> 0L);", - " Comparator lCmp2 = Comparator.comparingLong(o -> 0L);", - " Comparator fCmp = Comparator.comparingDouble(o -> 0.0f);", - " Comparator fCmp2 = Comparator.comparingDouble(o -> 0.0f);", - " Comparator dCmp = Comparator.comparingDouble(o -> 0.0);", - " Comparator dCmp2 = Comparator.comparingDouble(o -> 0.0);", - "", - " default void m() {", - " bCmp.thenComparingInt(o -> (byte) 0);", - " bCmp.thenComparingInt(o -> (byte) 0);", - " cCmp.thenComparingInt(o -> (char) 0);", - " cCmp.thenComparingInt(o -> (char) 0);", - " sCmp.thenComparingInt(o -> (short) 0);", - " sCmp.thenComparingInt(o -> (short) 0);", - " iCmp.thenComparingInt(o -> 0);", - " iCmp.thenComparingInt(o -> 0);", - " lCmp.thenComparingLong(o -> 0L);", - " lCmp.thenComparingLong(o -> 0L);", - " fCmp.thenComparingDouble(o -> 0.0f);", - " fCmp.thenComparingDouble(o -> 0.0f);", - " dCmp.thenComparingDouble(o -> 0.0);", - " dCmp.thenComparingDouble(o -> 0.0);", - " }", - "}") + """ + import java.util.Comparator; + + interface A extends Comparable { + Comparator bCmp = Comparator.comparingInt(o -> (byte) 0); + Comparator bCmp2 = Comparator.comparingInt(o -> (byte) 0); + Comparator cCmp = Comparator.comparingInt(o -> (char) 0); + Comparator cCmp2 = Comparator.comparingInt(o -> (char) 0); + Comparator sCmp = Comparator.comparingInt(o -> (short) 0); + Comparator sCmp2 = Comparator.comparingInt(o -> (short) 0); + Comparator iCmp = Comparator.comparingInt(o -> 0); + Comparator iCmp2 = Comparator.comparingInt(o -> 0); + Comparator lCmp = Comparator.comparingLong(o -> 0L); + Comparator lCmp2 = Comparator.comparingLong(o -> 0L); + Comparator fCmp = Comparator.comparingDouble(o -> 0.0f); + Comparator fCmp2 = Comparator.comparingDouble(o -> 0.0f); + Comparator dCmp = Comparator.comparingDouble(o -> 0.0); + Comparator dCmp2 = Comparator.comparingDouble(o -> 0.0); + + default void m() { + bCmp.thenComparingInt(o -> (byte) 0); + bCmp.thenComparingInt(o -> (byte) 0); + cCmp.thenComparingInt(o -> (char) 0); + cCmp.thenComparingInt(o -> (char) 0); + sCmp.thenComparingInt(o -> (short) 0); + sCmp.thenComparingInt(o -> (short) 0); + iCmp.thenComparingInt(o -> 0); + iCmp.thenComparingInt(o -> 0); + lCmp.thenComparingLong(o -> 0L); + lCmp.thenComparingLong(o -> 0L); + fCmp.thenComparingDouble(o -> 0.0f); + fCmp.thenComparingDouble(o -> 0.0f); + dCmp.thenComparingDouble(o -> 0.0); + dCmp.thenComparingDouble(o -> 0.0); + } + } + """) .doTest(TestMode.TEXT_MATCH); } @@ -580,64 +596,68 @@ void replacementWithBoxedVariants() { refactoringTestHelper .addInputLines( "A.java", - "import java.util.Comparator;", - "", - "interface A extends Comparable {", - " Comparator bCmp = Comparator.comparingInt(o -> Byte.valueOf((byte) 0));", - " Comparator bCmp2 = Comparator.comparingInt(o -> Byte.valueOf((byte) 0));", - " Comparator cCmp = Comparator.comparingInt(o -> Character.valueOf((char) 0));", - " Comparator cCmp2 = Comparator.comparingInt(o -> Character.valueOf((char) 0));", - " Comparator sCmp = Comparator.comparingInt(o -> Short.valueOf((short) 0));", - " Comparator sCmp2 = Comparator.comparingInt(o -> Short.valueOf((short) 0));", - " Comparator iCmp = Comparator.comparingInt(o -> Integer.valueOf(0));", - " Comparator iCmp2 = Comparator.comparingInt(o -> Integer.valueOf(0));", - " Comparator lCmp = Comparator.comparingLong(o -> Long.valueOf(0));", - " Comparator lCmp2 = Comparator.comparingLong(o -> Long.valueOf(0));", - " Comparator fCmp = Comparator.comparingDouble(o -> Float.valueOf(0));", - " Comparator fCmp2 = Comparator.comparingDouble(o -> Float.valueOf(0));", - " Comparator dCmp = Comparator.comparingDouble(o -> Double.valueOf(0));", - " Comparator dCmp2 = Comparator.comparingDouble(o -> Double.valueOf(0));", - "", - " default void m() {", - " bCmp.thenComparingInt(o -> Byte.valueOf((byte) 0));", - " cCmp.thenComparingInt(o -> Character.valueOf((char) 0));", - " sCmp.thenComparingInt(o -> Short.valueOf((short) 0));", - " iCmp.thenComparingInt(o -> Integer.valueOf(0));", - " lCmp.thenComparingLong(o -> Long.valueOf(0));", - " fCmp.thenComparingDouble(o -> Float.valueOf(0));", - " dCmp.thenComparingDouble(o -> Double.valueOf(0));", - " }", - "}") + """ + import java.util.Comparator; + + interface A extends Comparable { + Comparator bCmp = Comparator.comparingInt(o -> Byte.valueOf((byte) 0)); + Comparator bCmp2 = Comparator.comparingInt(o -> Byte.valueOf((byte) 0)); + Comparator cCmp = Comparator.comparingInt(o -> Character.valueOf((char) 0)); + Comparator cCmp2 = Comparator.comparingInt(o -> Character.valueOf((char) 0)); + Comparator sCmp = Comparator.comparingInt(o -> Short.valueOf((short) 0)); + Comparator sCmp2 = Comparator.comparingInt(o -> Short.valueOf((short) 0)); + Comparator iCmp = Comparator.comparingInt(o -> Integer.valueOf(0)); + Comparator iCmp2 = Comparator.comparingInt(o -> Integer.valueOf(0)); + Comparator lCmp = Comparator.comparingLong(o -> Long.valueOf(0)); + Comparator lCmp2 = Comparator.comparingLong(o -> Long.valueOf(0)); + Comparator fCmp = Comparator.comparingDouble(o -> Float.valueOf(0)); + Comparator fCmp2 = Comparator.comparingDouble(o -> Float.valueOf(0)); + Comparator dCmp = Comparator.comparingDouble(o -> Double.valueOf(0)); + Comparator dCmp2 = Comparator.comparingDouble(o -> Double.valueOf(0)); + + default void m() { + bCmp.thenComparingInt(o -> Byte.valueOf((byte) 0)); + cCmp.thenComparingInt(o -> Character.valueOf((char) 0)); + sCmp.thenComparingInt(o -> Short.valueOf((short) 0)); + iCmp.thenComparingInt(o -> Integer.valueOf(0)); + lCmp.thenComparingLong(o -> Long.valueOf(0)); + fCmp.thenComparingDouble(o -> Float.valueOf(0)); + dCmp.thenComparingDouble(o -> Double.valueOf(0)); + } + } + """) .addOutputLines( "A.java", - "import java.util.Comparator;", - "", - "interface A extends Comparable {", - " Comparator bCmp = Comparator.comparing(o -> Byte.valueOf((byte) 0));", - " Comparator bCmp2 = Comparator.comparing(o -> Byte.valueOf((byte) 0));", - " Comparator cCmp = Comparator.comparing(o -> Character.valueOf((char) 0));", - " Comparator cCmp2 = Comparator.comparing(o -> Character.valueOf((char) 0));", - " Comparator sCmp = Comparator.comparing(o -> Short.valueOf((short) 0));", - " Comparator sCmp2 = Comparator.comparing(o -> Short.valueOf((short) 0));", - " Comparator iCmp = Comparator.comparing(o -> Integer.valueOf(0));", - " Comparator iCmp2 = Comparator.comparing(o -> Integer.valueOf(0));", - " Comparator lCmp = Comparator.comparing(o -> Long.valueOf(0));", - " Comparator lCmp2 = Comparator.comparing(o -> Long.valueOf(0));", - " Comparator fCmp = Comparator.comparing(o -> Float.valueOf(0));", - " Comparator fCmp2 = Comparator.comparing(o -> Float.valueOf(0));", - " Comparator dCmp = Comparator.comparing(o -> Double.valueOf(0));", - " Comparator dCmp2 = Comparator.comparing(o -> Double.valueOf(0));", - "", - " default void m() {", - " bCmp.thenComparing(o -> Byte.valueOf((byte) 0));", - " cCmp.thenComparing(o -> Character.valueOf((char) 0));", - " sCmp.thenComparing(o -> Short.valueOf((short) 0));", - " iCmp.thenComparing(o -> Integer.valueOf(0));", - " lCmp.thenComparing(o -> Long.valueOf(0));", - " fCmp.thenComparing(o -> Float.valueOf(0));", - " dCmp.thenComparing(o -> Double.valueOf(0));", - " }", - "}") + """ + import java.util.Comparator; + + interface A extends Comparable { + Comparator bCmp = Comparator.comparing(o -> Byte.valueOf((byte) 0)); + Comparator bCmp2 = Comparator.comparing(o -> Byte.valueOf((byte) 0)); + Comparator cCmp = Comparator.comparing(o -> Character.valueOf((char) 0)); + Comparator cCmp2 = Comparator.comparing(o -> Character.valueOf((char) 0)); + Comparator sCmp = Comparator.comparing(o -> Short.valueOf((short) 0)); + Comparator sCmp2 = Comparator.comparing(o -> Short.valueOf((short) 0)); + Comparator iCmp = Comparator.comparing(o -> Integer.valueOf(0)); + Comparator iCmp2 = Comparator.comparing(o -> Integer.valueOf(0)); + Comparator lCmp = Comparator.comparing(o -> Long.valueOf(0)); + Comparator lCmp2 = Comparator.comparing(o -> Long.valueOf(0)); + Comparator fCmp = Comparator.comparing(o -> Float.valueOf(0)); + Comparator fCmp2 = Comparator.comparing(o -> Float.valueOf(0)); + Comparator dCmp = Comparator.comparing(o -> Double.valueOf(0)); + Comparator dCmp2 = Comparator.comparing(o -> Double.valueOf(0)); + + default void m() { + bCmp.thenComparing(o -> Byte.valueOf((byte) 0)); + cCmp.thenComparing(o -> Character.valueOf((char) 0)); + sCmp.thenComparing(o -> Short.valueOf((short) 0)); + iCmp.thenComparing(o -> Integer.valueOf(0)); + lCmp.thenComparing(o -> Long.valueOf(0)); + fCmp.thenComparing(o -> Float.valueOf(0)); + dCmp.thenComparing(o -> Double.valueOf(0)); + } + } + """) .doTest(TestMode.TEXT_MATCH); } @@ -646,37 +666,41 @@ void replacementWithPrimitiveVariantsUsingStaticImports() { refactoringTestHelper .addInputLines( "A.java", - "import static java.util.Comparator.comparing;", - "", - "import java.util.Comparator;", - "", - "interface A extends Comparable {", - " Comparator bCmp = comparing(o -> (byte) 0);", - " Comparator cCmp = comparing(o -> (char) 0);", - " Comparator sCmp = comparing(o -> (short) 0);", - " Comparator iCmp = comparing(o -> 0);", - " Comparator lCmp = comparing(o -> 0L);", - " Comparator fCmp = comparing(o -> 0.0f);", - " Comparator dCmp = comparing(o -> 0.0);", - "}") + """ + import static java.util.Comparator.comparing; + + import java.util.Comparator; + + interface A extends Comparable { + Comparator bCmp = comparing(o -> (byte) 0); + Comparator cCmp = comparing(o -> (char) 0); + Comparator sCmp = comparing(o -> (short) 0); + Comparator iCmp = comparing(o -> 0); + Comparator lCmp = comparing(o -> 0L); + Comparator fCmp = comparing(o -> 0.0f); + Comparator dCmp = comparing(o -> 0.0); + } + """) .addOutputLines( "A.java", - "import static java.util.Comparator.comparing;", - "import static java.util.Comparator.comparingDouble;", - "import static java.util.Comparator.comparingInt;", - "import static java.util.Comparator.comparingLong;", - "", - "import java.util.Comparator;", - "", - "interface A extends Comparable {", - " Comparator bCmp = comparingInt(o -> (byte) 0);", - " Comparator cCmp = comparingInt(o -> (char) 0);", - " Comparator sCmp = comparingInt(o -> (short) 0);", - " Comparator iCmp = comparingInt(o -> 0);", - " Comparator lCmp = comparingLong(o -> 0L);", - " Comparator fCmp = comparingDouble(o -> 0.0f);", - " Comparator dCmp = comparingDouble(o -> 0.0);", - "}") + """ + import static java.util.Comparator.comparing; + import static java.util.Comparator.comparingDouble; + import static java.util.Comparator.comparingInt; + import static java.util.Comparator.comparingLong; + + import java.util.Comparator; + + interface A extends Comparable { + Comparator bCmp = comparingInt(o -> (byte) 0); + Comparator cCmp = comparingInt(o -> (char) 0); + Comparator sCmp = comparingInt(o -> (short) 0); + Comparator iCmp = comparingInt(o -> 0); + Comparator lCmp = comparingLong(o -> 0L); + Comparator fCmp = comparingDouble(o -> 0.0f); + Comparator dCmp = comparingDouble(o -> 0.0); + } + """) .doTest(TestMode.TEXT_MATCH); } @@ -685,39 +709,43 @@ void replacementWithBoxedVariantsUsingStaticImports() { refactoringTestHelper .addInputLines( "A.java", - "import static java.util.Comparator.comparingDouble;", - "import static java.util.Comparator.comparingInt;", - "import static java.util.Comparator.comparingLong;", - "", - "import java.util.Comparator;", - "", - "interface A extends Comparable {", - " Comparator bCmp = comparingInt(o -> Byte.valueOf((byte) 0));", - " Comparator cCmp = comparingInt(o -> Character.valueOf((char) 0));", - " Comparator sCmp = comparingInt(o -> Short.valueOf((short) 0));", - " Comparator iCmp = comparingInt(o -> Integer.valueOf(0));", - " Comparator lCmp = comparingLong(o -> Long.valueOf(0));", - " Comparator fCmp = comparingDouble(o -> Float.valueOf(0));", - " Comparator dCmp = comparingDouble(o -> Double.valueOf(0));", - "}") + """ + import static java.util.Comparator.comparingDouble; + import static java.util.Comparator.comparingInt; + import static java.util.Comparator.comparingLong; + + import java.util.Comparator; + + interface A extends Comparable { + Comparator bCmp = comparingInt(o -> Byte.valueOf((byte) 0)); + Comparator cCmp = comparingInt(o -> Character.valueOf((char) 0)); + Comparator sCmp = comparingInt(o -> Short.valueOf((short) 0)); + Comparator iCmp = comparingInt(o -> Integer.valueOf(0)); + Comparator lCmp = comparingLong(o -> Long.valueOf(0)); + Comparator fCmp = comparingDouble(o -> Float.valueOf(0)); + Comparator dCmp = comparingDouble(o -> Double.valueOf(0)); + } + """) .addOutputLines( "A.java", - "import static java.util.Comparator.comparing;", - "import static java.util.Comparator.comparingDouble;", - "import static java.util.Comparator.comparingInt;", - "import static java.util.Comparator.comparingLong;", - "", - "import java.util.Comparator;", - "", - "interface A extends Comparable {", - " Comparator bCmp = comparing(o -> Byte.valueOf((byte) 0));", - " Comparator cCmp = comparing(o -> Character.valueOf((char) 0));", - " Comparator sCmp = comparing(o -> Short.valueOf((short) 0));", - " Comparator iCmp = comparing(o -> Integer.valueOf(0));", - " Comparator lCmp = comparing(o -> Long.valueOf(0));", - " Comparator fCmp = comparing(o -> Float.valueOf(0));", - " Comparator dCmp = comparing(o -> Double.valueOf(0));", - "}") + """ + import static java.util.Comparator.comparing; + import static java.util.Comparator.comparingDouble; + import static java.util.Comparator.comparingInt; + import static java.util.Comparator.comparingLong; + + import java.util.Comparator; + + interface A extends Comparable { + Comparator bCmp = comparing(o -> Byte.valueOf((byte) 0)); + Comparator cCmp = comparing(o -> Character.valueOf((char) 0)); + Comparator sCmp = comparing(o -> Short.valueOf((short) 0)); + Comparator iCmp = comparing(o -> Integer.valueOf(0)); + Comparator lCmp = comparing(o -> Long.valueOf(0)); + Comparator fCmp = comparing(o -> Float.valueOf(0)); + Comparator dCmp = comparing(o -> Double.valueOf(0)); + } + """) .doTest(TestMode.TEXT_MATCH); } @@ -726,30 +754,34 @@ void replacementWithPrimitiveVariantsInComplexSyntacticalContext() { refactoringTestHelper .addInputLines( "A.java", - "import java.util.Comparator;", - "", - "interface A extends Comparable {", - " Comparator bCmp = Comparator.comparing(o -> o).thenComparing(o -> (byte) 0);", - " Comparator cCmp = Comparator.comparing(o -> o).thenComparing(o -> (char) 0);", - " Comparator sCmp = Comparator.comparing(o -> o).thenComparing(o -> (short) 0);", - " Comparator iCmp = Comparator.comparing(o -> o).thenComparing(o -> 0);", - " Comparator lCmp = Comparator.comparing(o -> o).thenComparing(o -> 0L);", - " Comparator fCmp = Comparator.comparing(o -> o).thenComparing(o -> 0.0f);", - " Comparator dCmp = Comparator.comparing(o -> o).thenComparing(o -> 0.0);", - "}") + """ + import java.util.Comparator; + + interface A extends Comparable { + Comparator bCmp = Comparator.comparing(o -> o).thenComparing(o -> (byte) 0); + Comparator cCmp = Comparator.comparing(o -> o).thenComparing(o -> (char) 0); + Comparator sCmp = Comparator.comparing(o -> o).thenComparing(o -> (short) 0); + Comparator iCmp = Comparator.comparing(o -> o).thenComparing(o -> 0); + Comparator lCmp = Comparator.comparing(o -> o).thenComparing(o -> 0L); + Comparator fCmp = Comparator.comparing(o -> o).thenComparing(o -> 0.0f); + Comparator dCmp = Comparator.comparing(o -> o).thenComparing(o -> 0.0); + } + """) .addOutputLines( "A.java", - "import java.util.Comparator;", - "", - "interface A extends Comparable {", - " Comparator bCmp = Comparator.comparing(o -> o).thenComparingInt(o -> (byte) 0);", - " Comparator cCmp = Comparator.comparing(o -> o).thenComparingInt(o -> (char) 0);", - " Comparator sCmp = Comparator.comparing(o -> o).thenComparingInt(o -> (short) 0);", - " Comparator iCmp = Comparator.comparing(o -> o).thenComparingInt(o -> 0);", - " Comparator lCmp = Comparator.comparing(o -> o).thenComparingLong(o -> 0L);", - " Comparator fCmp = Comparator.comparing(o -> o).thenComparingDouble(o -> 0.0f);", - " Comparator dCmp = Comparator.comparing(o -> o).thenComparingDouble(o -> 0.0);", - "}") + """ + import java.util.Comparator; + + interface A extends Comparable { + Comparator bCmp = Comparator.comparing(o -> o).thenComparingInt(o -> (byte) 0); + Comparator cCmp = Comparator.comparing(o -> o).thenComparingInt(o -> (char) 0); + Comparator sCmp = Comparator.comparing(o -> o).thenComparingInt(o -> (short) 0); + Comparator iCmp = Comparator.comparing(o -> o).thenComparingInt(o -> 0); + Comparator lCmp = Comparator.comparing(o -> o).thenComparingLong(o -> 0L); + Comparator fCmp = Comparator.comparing(o -> o).thenComparingDouble(o -> 0.0f); + Comparator dCmp = Comparator.comparing(o -> o).thenComparingDouble(o -> 0.0); + } + """) .doTest(TestMode.TEXT_MATCH); } @@ -758,38 +790,42 @@ void replacementWithBoxedVariantsInComplexSyntacticalContext() { refactoringTestHelper .addInputLines( "A.java", - "import java.util.Comparator;", - "", - "interface A extends Comparable {", - " Comparator bCmp =", - " Comparator.comparing(o -> o).thenComparingInt(o -> Byte.valueOf((byte) 0));", - " Comparator cCmp =", - " Comparator.comparing(o -> o).thenComparingInt(o -> Character.valueOf((char) 0));", - " Comparator sCmp =", - " Comparator.comparing(o -> o).thenComparingInt(o -> Short.valueOf((short) 0));", - " Comparator iCmp = Comparator.comparing(o -> o).thenComparingInt(o -> Integer.valueOf(0));", - " Comparator lCmp = Comparator.comparing(o -> o).thenComparingLong(o -> Long.valueOf(0));", - " Comparator fCmp =", - " Comparator.comparing(o -> o).thenComparingDouble(o -> Float.valueOf(0));", - " Comparator dCmp =", - " Comparator.comparing(o -> o).thenComparingDouble(o -> Double.valueOf(0));", - "}") + """ + import java.util.Comparator; + + interface A extends Comparable { + Comparator bCmp = + Comparator.comparing(o -> o).thenComparingInt(o -> Byte.valueOf((byte) 0)); + Comparator cCmp = + Comparator.comparing(o -> o).thenComparingInt(o -> Character.valueOf((char) 0)); + Comparator sCmp = + Comparator.comparing(o -> o).thenComparingInt(o -> Short.valueOf((short) 0)); + Comparator iCmp = Comparator.comparing(o -> o).thenComparingInt(o -> Integer.valueOf(0)); + Comparator lCmp = Comparator.comparing(o -> o).thenComparingLong(o -> Long.valueOf(0)); + Comparator fCmp = + Comparator.comparing(o -> o).thenComparingDouble(o -> Float.valueOf(0)); + Comparator dCmp = + Comparator.comparing(o -> o).thenComparingDouble(o -> Double.valueOf(0)); + } + """) .addOutputLines( "A.java", - "import java.util.Comparator;", - "", - "interface A extends Comparable {", - " Comparator bCmp =", - " Comparator.comparing(o -> o).thenComparing(o -> Byte.valueOf((byte) 0));", - " Comparator cCmp =", - " Comparator.comparing(o -> o).thenComparing(o -> Character.valueOf((char) 0));", - " Comparator sCmp =", - " Comparator.comparing(o -> o).thenComparing(o -> Short.valueOf((short) 0));", - " Comparator iCmp = Comparator.comparing(o -> o).thenComparing(o -> Integer.valueOf(0));", - " Comparator lCmp = Comparator.comparing(o -> o).thenComparing(o -> Long.valueOf(0));", - " Comparator fCmp = Comparator.comparing(o -> o).thenComparing(o -> Float.valueOf(0));", - " Comparator dCmp = Comparator.comparing(o -> o).thenComparing(o -> Double.valueOf(0));", - "}") + """ + import java.util.Comparator; + + interface A extends Comparable { + Comparator bCmp = + Comparator.comparing(o -> o).thenComparing(o -> Byte.valueOf((byte) 0)); + Comparator cCmp = + Comparator.comparing(o -> o).thenComparing(o -> Character.valueOf((char) 0)); + Comparator sCmp = + Comparator.comparing(o -> o).thenComparing(o -> Short.valueOf((short) 0)); + Comparator iCmp = Comparator.comparing(o -> o).thenComparing(o -> Integer.valueOf(0)); + Comparator lCmp = Comparator.comparing(o -> o).thenComparing(o -> Long.valueOf(0)); + Comparator fCmp = Comparator.comparing(o -> o).thenComparing(o -> Float.valueOf(0)); + Comparator dCmp = Comparator.comparing(o -> o).thenComparing(o -> Double.valueOf(0)); + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RedundantStringConversionTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RedundantStringConversionTest.java index 62f82b3f5aa..e7144a9078a 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RedundantStringConversionTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RedundantStringConversionTest.java @@ -25,21 +25,23 @@ void identificationOfIdentityTransformation() { compilationTestHelper .addSourceLines( "A.java", - "class A {", - " private final Object o = new Object();", - " private final String s = o.toString();", - "", - " String[] m() {", - " return new String[] {", - " o.toString(),", - " // BUG: Diagnostic contains:", - " s.toString(),", - " String.valueOf(o),", - " // BUG: Diagnostic contains:", - " String.valueOf(s),", - " };", - " }", - "}") + """ + class A { + private final Object o = new Object(); + private final String s = o.toString(); + + String[] m() { + return new String[] { + o.toString(), + // BUG: Diagnostic contains: + s.toString(), + String.valueOf(o), + // BUG: Diagnostic contains: + String.valueOf(s), + }; + } + } + """) .doTest(); } @@ -48,59 +50,61 @@ void identificationWithinMutatingAssignment() { compilationTestHelper .addSourceLines( "A.java", - "import java.math.BigInteger;", - "import java.util.Objects;", - "", - "class A {", - " private final BigInteger i = BigInteger.ZERO;", - "", - " void m1() {", - " String s = i.toString();", - " // BUG: Diagnostic contains:", - " s += this.toString();", - " s += super.toString();", - " // BUG: Diagnostic contains:", - " s += i.toString();", - " s += i.toString(16);", - " // BUG: Diagnostic contains:", - " s += Objects.toString(i);", - " // BUG: Diagnostic contains:", - " s += Objects.toString(null);", - " // BUG: Diagnostic contains:", - " s += String.valueOf(i);", - " // BUG: Diagnostic contains:", - " s += String.valueOf(0);", - " // BUG: Diagnostic contains:", - " s += String.valueOf((String) null);", - " s += String.valueOf(null);", - " s += String.valueOf(new char[0]);", - " s += String.valueOf(new char[0], 0, 0);", - " // BUG: Diagnostic contains:", - " s += Boolean.toString(false);", - " // BUG: Diagnostic contains:", - " s += Byte.toString((byte) 0);", - " // BUG: Diagnostic contains:", - " s += Character.toString((char) 0);", - " // BUG: Diagnostic contains:", - " s += Short.toString((short) 0);", - " // BUG: Diagnostic contains:", - " s += Integer.toString(0);", - " // BUG: Diagnostic contains:", - " s += Long.toString(0);", - " // BUG: Diagnostic contains:", - " s += Float.toString((float) 0.0);", - " // BUG: Diagnostic contains:", - " s += Double.toString(0.0);", - " }", - "", - " void m2() {", - " int i = 0;", - " i += 1;", - " i -= 1;", - " i *= 1;", - " i /= 1;", - " }", - "}") + """ + import java.math.BigInteger; + import java.util.Objects; + + class A { + private final BigInteger i = BigInteger.ZERO; + + void m1() { + String s = i.toString(); + // BUG: Diagnostic contains: + s += this.toString(); + s += super.toString(); + // BUG: Diagnostic contains: + s += i.toString(); + s += i.toString(16); + // BUG: Diagnostic contains: + s += Objects.toString(i); + // BUG: Diagnostic contains: + s += Objects.toString(null); + // BUG: Diagnostic contains: + s += String.valueOf(i); + // BUG: Diagnostic contains: + s += String.valueOf(0); + // BUG: Diagnostic contains: + s += String.valueOf((String) null); + s += String.valueOf(null); + s += String.valueOf(new char[0]); + s += String.valueOf(new char[0], 0, 0); + // BUG: Diagnostic contains: + s += Boolean.toString(false); + // BUG: Diagnostic contains: + s += Byte.toString((byte) 0); + // BUG: Diagnostic contains: + s += Character.toString((char) 0); + // BUG: Diagnostic contains: + s += Short.toString((short) 0); + // BUG: Diagnostic contains: + s += Integer.toString(0); + // BUG: Diagnostic contains: + s += Long.toString(0); + // BUG: Diagnostic contains: + s += Float.toString((float) 0.0); + // BUG: Diagnostic contains: + s += Double.toString(0.0); + } + + void m2() { + int i = 0; + i += 1; + i -= 1; + i *= 1; + i /= 1; + } + } + """) .doTest(); } @@ -109,93 +113,95 @@ void identificationWithinBinaryOperation() { compilationTestHelper .addSourceLines( "A.java", - "import java.math.BigInteger;", - "", - "class A {", - " private final BigInteger i = BigInteger.ZERO;", - " private final String s = i.toString();", - "", - " String[] m1() {", - " return new String[] {", - " // BUG: Diagnostic contains:", - " s + this.toString(),", - " s + super.toString(),", - " // BUG: Diagnostic contains:", - " s + i.toString(),", - " s + i.toString(16),", - " // BUG: Diagnostic contains:", - " s + String.valueOf(i),", - " // BUG: Diagnostic contains:", - " s + String.valueOf(0),", - " // BUG: Diagnostic contains:", - " s + String.valueOf((String) null),", - " s + String.valueOf(null),", - " s + String.valueOf(new char[0]),", - " s + String.valueOf(new char[0], 0, 0),", - " //", - " 42 + this.toString(),", - " 42 + super.toString(),", - " 42 + i.toString(),", - " 42 + i.toString(16),", - " 42 + String.valueOf(i),", - " // BUG: Diagnostic contains:", - " 42 + String.valueOf((String) null),", - " 42 + String.valueOf(null),", - " 42 + String.valueOf(new char[0]),", - " 42 + String.valueOf(new char[0], 0, 0),", - "", - " // BUG: Diagnostic contains:", - " this.toString() + s,", - " super.toString() + s,", - " // BUG: Diagnostic contains:", - " i.toString() + s,", - " i.toString(16) + s,", - " // BUG: Diagnostic contains:", - " String.valueOf(i) + s,", - " // BUG: Diagnostic contains:", - " String.valueOf(0) + s,", - " // BUG: Diagnostic contains:", - " String.valueOf((String) null) + s,", - " String.valueOf(null) + s,", - " String.valueOf(new char[0]) + s,", - " String.valueOf(new char[0], 0, 0) + s,", - " //", - " this.toString() + 42,", - " super.toString() + 42,", - " i.toString() + 42,", - " i.toString(16) + 42,", - " String.valueOf(i) + 42,", - " String.valueOf(0) + 42,", - " // BUG: Diagnostic contains:", - " String.valueOf((String) null) + 42,", - " String.valueOf(null) + 42,", - " String.valueOf(new char[0]) + 42,", - " String.valueOf(new char[0], 0, 0) + 42,", - "", - " // BUG: Diagnostic contains:", - " this.toString() + this.toString(),", - " super.toString() + super.toString(),", - " // BUG: Diagnostic contains:", - " i.toString() + i.toString(),", - " i.toString(16) + i.toString(16),", - " // BUG: Diagnostic contains:", - " String.valueOf(i) + String.valueOf(i),", - " // BUG: Diagnostic contains:", - " String.valueOf(0) + String.valueOf(0),", - " // BUG: Diagnostic contains:", - " String.valueOf((String) null) + String.valueOf((String) null),", - " String.valueOf(null) + String.valueOf(null),", - " String.valueOf(new char[0]) + String.valueOf(new char[0]),", - " String.valueOf(new char[0], 0, 0) + String.valueOf(new char[0], 0, 0),", - " };", - " }", - "", - " int[] m2() {", - " return new int[] {", - " 1 + 1, 1 - 1, 1 * 1, 1 / 1,", - " };", - " }", - "}") + """ + import java.math.BigInteger; + + class A { + private final BigInteger i = BigInteger.ZERO; + private final String s = i.toString(); + + String[] m1() { + return new String[] { + // BUG: Diagnostic contains: + s + this.toString(), + s + super.toString(), + // BUG: Diagnostic contains: + s + i.toString(), + s + i.toString(16), + // BUG: Diagnostic contains: + s + String.valueOf(i), + // BUG: Diagnostic contains: + s + String.valueOf(0), + // BUG: Diagnostic contains: + s + String.valueOf((String) null), + s + String.valueOf(null), + s + String.valueOf(new char[0]), + s + String.valueOf(new char[0], 0, 0), + // + 42 + this.toString(), + 42 + super.toString(), + 42 + i.toString(), + 42 + i.toString(16), + 42 + String.valueOf(i), + // BUG: Diagnostic contains: + 42 + String.valueOf((String) null), + 42 + String.valueOf(null), + 42 + String.valueOf(new char[0]), + 42 + String.valueOf(new char[0], 0, 0), + + // BUG: Diagnostic contains: + this.toString() + s, + super.toString() + s, + // BUG: Diagnostic contains: + i.toString() + s, + i.toString(16) + s, + // BUG: Diagnostic contains: + String.valueOf(i) + s, + // BUG: Diagnostic contains: + String.valueOf(0) + s, + // BUG: Diagnostic contains: + String.valueOf((String) null) + s, + String.valueOf(null) + s, + String.valueOf(new char[0]) + s, + String.valueOf(new char[0], 0, 0) + s, + // + this.toString() + 42, + super.toString() + 42, + i.toString() + 42, + i.toString(16) + 42, + String.valueOf(i) + 42, + String.valueOf(0) + 42, + // BUG: Diagnostic contains: + String.valueOf((String) null) + 42, + String.valueOf(null) + 42, + String.valueOf(new char[0]) + 42, + String.valueOf(new char[0], 0, 0) + 42, + + // BUG: Diagnostic contains: + this.toString() + this.toString(), + super.toString() + super.toString(), + // BUG: Diagnostic contains: + i.toString() + i.toString(), + i.toString(16) + i.toString(16), + // BUG: Diagnostic contains: + String.valueOf(i) + String.valueOf(i), + // BUG: Diagnostic contains: + String.valueOf(0) + String.valueOf(0), + // BUG: Diagnostic contains: + String.valueOf((String) null) + String.valueOf((String) null), + String.valueOf(null) + String.valueOf(null), + String.valueOf(new char[0]) + String.valueOf(new char[0]), + String.valueOf(new char[0], 0, 0) + String.valueOf(new char[0], 0, 0), + }; + } + + int[] m2() { + return new int[] { + 1 + 1, 1 - 1, 1 * 1, 1 / 1, + }; + } + } + """) .doTest(); } @@ -204,52 +210,54 @@ void identificationWithinStringBuilderMethod() { compilationTestHelper .addSourceLines( "A.java", - "import java.math.BigInteger;", - "", - "class A {", - " private final BigInteger i = BigInteger.ZERO;", - " private final String s = i.toString();", - "", - " void m() {", - " StringBuilder sb = new StringBuilder();", - "", - " sb.append(1);", - " sb.append(i);", - " // BUG: Diagnostic contains:", - " sb.append(i.toString());", - " sb.append(i.toString(16));", - " // BUG: Diagnostic contains:", - " sb.append(String.valueOf(i));", - " // BUG: Diagnostic contains:", - " sb.append(String.valueOf(0));", - " // BUG: Diagnostic contains:", - " sb.append(String.valueOf((String) null));", - " sb.append(String.valueOf(null));", - " sb.append(String.valueOf(new char[0]));", - " sb.append(String.valueOf(new char[0], 0, 0));", - " sb.append(s);", - " sb.append(\"constant\");", - "", - " sb.insert(0, 1);", - " sb.insert(0, i);", - " // BUG: Diagnostic contains:", - " sb.insert(0, i.toString());", - " sb.insert(0, i.toString(16));", - " // BUG: Diagnostic contains:", - " sb.insert(0, String.valueOf(i));", - " // BUG: Diagnostic contains:", - " sb.insert(0, String.valueOf(0));", - " // BUG: Diagnostic contains:", - " sb.insert(0, String.valueOf((String) null));", - " sb.insert(0, String.valueOf(null));", - " sb.insert(0, String.valueOf(new char[0]));", - " sb.insert(0, String.valueOf(new char[0], 0, 0));", - " sb.insert(0, s);", - " sb.insert(0, \"constant\");", - "", - " sb.replace(0, 1, i.toString());", - " }", - "}") + """ + import java.math.BigInteger; + + class A { + private final BigInteger i = BigInteger.ZERO; + private final String s = i.toString(); + + void m() { + StringBuilder sb = new StringBuilder(); + + sb.append(1); + sb.append(i); + // BUG: Diagnostic contains: + sb.append(i.toString()); + sb.append(i.toString(16)); + // BUG: Diagnostic contains: + sb.append(String.valueOf(i)); + // BUG: Diagnostic contains: + sb.append(String.valueOf(0)); + // BUG: Diagnostic contains: + sb.append(String.valueOf((String) null)); + sb.append(String.valueOf(null)); + sb.append(String.valueOf(new char[0])); + sb.append(String.valueOf(new char[0], 0, 0)); + sb.append(s); + sb.append("constant"); + + sb.insert(0, 1); + sb.insert(0, i); + // BUG: Diagnostic contains: + sb.insert(0, i.toString()); + sb.insert(0, i.toString(16)); + // BUG: Diagnostic contains: + sb.insert(0, String.valueOf(i)); + // BUG: Diagnostic contains: + sb.insert(0, String.valueOf(0)); + // BUG: Diagnostic contains: + sb.insert(0, String.valueOf((String) null)); + sb.insert(0, String.valueOf(null)); + sb.insert(0, String.valueOf(new char[0])); + sb.insert(0, String.valueOf(new char[0], 0, 0)); + sb.insert(0, s); + sb.insert(0, "constant"); + + sb.replace(0, 1, i.toString()); + } + } + """) .doTest(); } @@ -259,43 +267,45 @@ void identificationWithinFormatterMethod() { compilationTestHelper .addSourceLines( "A.java", - "import java.util.Formattable;", - "import java.util.Locale;", - "", - "class A {", - " private final Locale locale = Locale.ROOT;", - " private final Formattable f = (formatter, flags, width, precision) -> {};", - " private final Object o = new Object();", - " private final String s = o.toString();", - "", - " void m() {", - " String.format(s, f);", - " String.format(s, o);", - " String.format(s, s);", - " String.format(s, f.toString());", - " // BUG: Diagnostic contains:", - " String.format(s, o.toString());", - " // BUG: Diagnostic contains:", - " String.format(s, String.valueOf(o));", - "", - " String.format(locale, s, f);", - " String.format(locale, s, o);", - " String.format(locale, s, s);", - " String.format(locale, s, f.toString());", - " // BUG: Diagnostic contains:", - " String.format(locale, s, o.toString());", - " // BUG: Diagnostic contains:", - " String.format(locale, s, String.valueOf(o));", - "", - " String.format(o.toString(), o);", - " // BUG: Diagnostic contains:", - " String.format(s.toString(), o);", - " String.format(locale.toString(), s, o);", - " String.format(locale, o.toString(), o);", - " // BUG: Diagnostic contains:", - " String.format(locale, s.toString(), o);", - " }", - "}") + """ + import java.util.Formattable; + import java.util.Locale; + + class A { + private final Locale locale = Locale.ROOT; + private final Formattable f = (formatter, flags, width, precision) -> {}; + private final Object o = new Object(); + private final String s = o.toString(); + + void m() { + String.format(s, f); + String.format(s, o); + String.format(s, s); + String.format(s, f.toString()); + // BUG: Diagnostic contains: + String.format(s, o.toString()); + // BUG: Diagnostic contains: + String.format(s, String.valueOf(o)); + + String.format(locale, s, f); + String.format(locale, s, o); + String.format(locale, s, s); + String.format(locale, s, f.toString()); + // BUG: Diagnostic contains: + String.format(locale, s, o.toString()); + // BUG: Diagnostic contains: + String.format(locale, s, String.valueOf(o)); + + String.format(o.toString(), o); + // BUG: Diagnostic contains: + String.format(s.toString(), o); + String.format(locale.toString(), s, o); + String.format(locale, o.toString(), o); + // BUG: Diagnostic contains: + String.format(locale, s.toString(), o); + } + } + """) .doTest(); } @@ -304,58 +314,60 @@ void identificationWithinGuavaGuardMethod() { compilationTestHelper .addSourceLines( "A.java", - "import static com.google.common.base.Preconditions.checkArgument;", - "import static com.google.common.base.Preconditions.checkNotNull;", - "import static com.google.common.base.Preconditions.checkState;", - "import static com.google.common.base.Verify.verify;", - "import static com.google.common.base.Verify.verifyNotNull;", - "", - "import java.util.Formattable;", - "", - "class A {", - " private final Formattable f = (formatter, flags, width, precision) -> {};", - " private final Object o = new Object();", - " private final String s = o.toString();", - "", - " void m() {", - " checkState(true, s, f);", - " // BUG: Diagnostic contains:", - " checkState(true, s, f.toString());", - " checkState(true, f.toString(), f);", - " // BUG: Diagnostic contains:", - " checkState(true, s.toString(), f);", - "", - " checkArgument(true, s, f);", - " // BUG: Diagnostic contains:", - " checkArgument(true, s, f.toString());", - " checkArgument(true, f.toString(), f);", - " // BUG: Diagnostic contains:", - " checkArgument(true, s.toString(), f);", - "", - " checkNotNull(o, s, f);", - " // BUG: Diagnostic contains:", - " checkNotNull(o, s, f.toString());", - " checkNotNull(o, f.toString(), f);", - " // BUG: Diagnostic contains:", - " checkNotNull(o, s.toString(), f);", - " checkNotNull(o.toString(), s, f);", - "", - " verify(true, s, f);", - " // BUG: Diagnostic contains:", - " verify(true, s, f.toString());", - " verify(true, f.toString(), f);", - " // BUG: Diagnostic contains:", - " verify(true, s.toString(), f);", - "", - " verifyNotNull(o, s, f);", - " // BUG: Diagnostic contains:", - " verifyNotNull(o, s, f.toString());", - " verifyNotNull(o, f.toString(), f);", - " // BUG: Diagnostic contains:", - " verifyNotNull(o, s.toString(), f);", - " verifyNotNull(o.toString(), s, f);", - " }", - "}") + """ + import static com.google.common.base.Preconditions.checkArgument; + import static com.google.common.base.Preconditions.checkNotNull; + import static com.google.common.base.Preconditions.checkState; + import static com.google.common.base.Verify.verify; + import static com.google.common.base.Verify.verifyNotNull; + + import java.util.Formattable; + + class A { + private final Formattable f = (formatter, flags, width, precision) -> {}; + private final Object o = new Object(); + private final String s = o.toString(); + + void m() { + checkState(true, s, f); + // BUG: Diagnostic contains: + checkState(true, s, f.toString()); + checkState(true, f.toString(), f); + // BUG: Diagnostic contains: + checkState(true, s.toString(), f); + + checkArgument(true, s, f); + // BUG: Diagnostic contains: + checkArgument(true, s, f.toString()); + checkArgument(true, f.toString(), f); + // BUG: Diagnostic contains: + checkArgument(true, s.toString(), f); + + checkNotNull(o, s, f); + // BUG: Diagnostic contains: + checkNotNull(o, s, f.toString()); + checkNotNull(o, f.toString(), f); + // BUG: Diagnostic contains: + checkNotNull(o, s.toString(), f); + checkNotNull(o.toString(), s, f); + + verify(true, s, f); + // BUG: Diagnostic contains: + verify(true, s, f.toString()); + verify(true, f.toString(), f); + // BUG: Diagnostic contains: + verify(true, s.toString(), f); + + verifyNotNull(o, s, f); + // BUG: Diagnostic contains: + verifyNotNull(o, s, f.toString()); + verifyNotNull(o, f.toString(), f); + // BUG: Diagnostic contains: + verifyNotNull(o, s.toString(), f); + verifyNotNull(o.toString(), s, f); + } + } + """) .doTest(); } @@ -364,53 +376,55 @@ void identificationWithinSlf4jLoggerMethod() { compilationTestHelper .addSourceLines( "A.java", - "import java.util.Formattable;", - "import org.slf4j.Logger;", - "import org.slf4j.LoggerFactory;", - "import org.slf4j.Marker;", - "import org.slf4j.MarkerFactory;", - "", - "class A {", - " private static final Logger LOG = LoggerFactory.getLogger(A.class);", - "", - " private final Marker marker = MarkerFactory.getMarker(A.class.getName());", - " private final Formattable f = (formatter, flags, width, precision) -> {};", - " private final Object o = new Object();", - " private final String s = f.toString();", - " private final Throwable t = new Throwable();", - "", - " void m() {", - " LOG.trace(s, f);", - " // BUG: Diagnostic contains:", - " LOG.debug(s, f.toString());", - " LOG.info(s, t.toString());", - " LOG.warn(s, o, t.toString());", - " // BUG: Diagnostic contains:", - " LOG.error(s, o.toString(), t.toString());", - " // BUG: Diagnostic contains:", - " LOG.trace(s, t.toString(), o);", - "", - " LOG.trace(marker, s, f);", - " // BUG: Diagnostic contains:", - " LOG.debug(marker, s, f.toString());", - " LOG.info(marker, s, t.toString());", - " LOG.warn(marker, s, o, t.toString());", - " // BUG: Diagnostic contains:", - " LOG.error(marker, s, o.toString(), t.toString());", - " // BUG: Diagnostic contains:", - " LOG.trace(marker, s, t.toString(), o);", - "", - " LOG.trace(f.toString(), f);", - " // BUG: Diagnostic contains:", - " LOG.debug(s.toString(), f);", - " LOG.info(t.toString(), f);", - " LOG.warn(marker.toString(), s, f);", - " LOG.error(marker, o.toString(), f);", - " // BUG: Diagnostic contains:", - " LOG.trace(marker, s.toString(), f);", - " LOG.debug(marker, t.toString(), f);", - " }", - "}") + """ + import java.util.Formattable; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; + import org.slf4j.Marker; + import org.slf4j.MarkerFactory; + + class A { + private static final Logger LOG = LoggerFactory.getLogger(A.class); + + private final Marker marker = MarkerFactory.getMarker(A.class.getName()); + private final Formattable f = (formatter, flags, width, precision) -> {}; + private final Object o = new Object(); + private final String s = f.toString(); + private final Throwable t = new Throwable(); + + void m() { + LOG.trace(s, f); + // BUG: Diagnostic contains: + LOG.debug(s, f.toString()); + LOG.info(s, t.toString()); + LOG.warn(s, o, t.toString()); + // BUG: Diagnostic contains: + LOG.error(s, o.toString(), t.toString()); + // BUG: Diagnostic contains: + LOG.trace(s, t.toString(), o); + + LOG.trace(marker, s, f); + // BUG: Diagnostic contains: + LOG.debug(marker, s, f.toString()); + LOG.info(marker, s, t.toString()); + LOG.warn(marker, s, o, t.toString()); + // BUG: Diagnostic contains: + LOG.error(marker, s, o.toString(), t.toString()); + // BUG: Diagnostic contains: + LOG.trace(marker, s, t.toString(), o); + + LOG.trace(f.toString(), f); + // BUG: Diagnostic contains: + LOG.debug(s.toString(), f); + LOG.info(t.toString(), f); + LOG.warn(marker.toString(), s, f); + LOG.error(marker, o.toString(), f); + // BUG: Diagnostic contains: + LOG.trace(marker, s.toString(), f); + LOG.debug(marker, t.toString(), f); + } + } + """) .doTest(); } @@ -419,91 +433,93 @@ void identificationOfCustomConversionMethod() { customizedCompilationTestHelper .addSourceLines( "A.java", - "import java.math.RoundingMode;", - "import java.util.Objects;", - "", - "class A {", - " static class B {", - " String name() {", - " return toString();", - " }", - "", - " static String toString(int i) {", - " return Integer.toString(i);", - " }", - "", - " static String toString(int i, int j) {", - " return Integer.toString(i * j);", - " }", - " }", - "", - " enum E {", - " ELEM;", - "", - " public String toString() {", - " return \"__\" + name() + \"__\";", - " }", - " }", - "", - " private final B b = new B();", - " private final String s = b.toString();", - "", - " String[] builtin() {", - " return new String[] {", - " // BUG: Diagnostic contains:", - " s + b.toString(),", - " // BUG: Diagnostic contains:", - " s + Objects.toString(b),", - " // BUG: Diagnostic contains:", - " s + String.valueOf(b),", - " // BUG: Diagnostic contains:", - " s + Boolean.toString(false),", - " // BUG: Diagnostic contains:", - " s + Byte.toString((byte) 0),", - " // BUG: Diagnostic contains:", - " s + Character.toString((char) 0),", - " // BUG: Diagnostic contains:", - " s + Short.toString((short) 0),", - " // BUG: Diagnostic contains:", - " s + Integer.toString(0),", - " s + Integer.toString(0, 16),", - " // BUG: Diagnostic contains:", - " s + Long.toString(0),", - " s + Long.toString(0, 16),", - " // BUG: Diagnostic contains:", - " s + Float.toString((float) 0.0),", - " // BUG: Diagnostic contains:", - " s + Double.toString(0.0),", - " };", - " }", - "", - " String[] custom() {", - " return new String[] {", - " s + b.name(),", - " // BUG: Diagnostic contains:", - " s + RoundingMode.UP.name(),", - " // BUG: Diagnostic contains:", - " s + mode().name(),", - " s + A.name(),", - " s + A.toString(42),", - " // BUG: Diagnostic contains:", - " s + B.toString(42),", - " s + B.toString(42, 42),", - " };", - " }", - "", - " static String name() {", - " return A.class.toString();", - " }", - "", - " RoundingMode mode() {", - " return RoundingMode.UP;", - " }", - "", - " static String toString(int i) {", - " return Integer.toString(i);", - " }", - "}") + """ + import java.math.RoundingMode; + import java.util.Objects; + + class A { + static class B { + String name() { + return toString(); + } + + static String toString(int i) { + return Integer.toString(i); + } + + static String toString(int i, int j) { + return Integer.toString(i * j); + } + } + + enum E { + ELEM; + + public String toString() { + return "__" + name() + "__"; + } + } + + private final B b = new B(); + private final String s = b.toString(); + + String[] builtin() { + return new String[] { + // BUG: Diagnostic contains: + s + b.toString(), + // BUG: Diagnostic contains: + s + Objects.toString(b), + // BUG: Diagnostic contains: + s + String.valueOf(b), + // BUG: Diagnostic contains: + s + Boolean.toString(false), + // BUG: Diagnostic contains: + s + Byte.toString((byte) 0), + // BUG: Diagnostic contains: + s + Character.toString((char) 0), + // BUG: Diagnostic contains: + s + Short.toString((short) 0), + // BUG: Diagnostic contains: + s + Integer.toString(0), + s + Integer.toString(0, 16), + // BUG: Diagnostic contains: + s + Long.toString(0), + s + Long.toString(0, 16), + // BUG: Diagnostic contains: + s + Float.toString((float) 0.0), + // BUG: Diagnostic contains: + s + Double.toString(0.0), + }; + } + + String[] custom() { + return new String[] { + s + b.name(), + // BUG: Diagnostic contains: + s + RoundingMode.UP.name(), + // BUG: Diagnostic contains: + s + mode().name(), + s + A.name(), + s + A.toString(42), + // BUG: Diagnostic contains: + s + B.toString(42), + s + B.toString(42, 42), + }; + } + + static String name() { + return A.class.toString(); + } + + RoundingMode mode() { + return RoundingMode.UP; + } + + static String toString(int i) { + return Integer.toString(i); + } + } + """) .doTest(); } @@ -512,32 +528,36 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "class A {", - " private final Object o = new Object();", - " private final String s = o.toString();", - "", - " void m() {", - " String v1 = s.toString();", - " String v2 = \"foo\".toString();", - " String v3 = v2 + super.toString();", - " String v4 = 42 + String.valueOf((String) null);", - " String.format(\"%s\", o.toString());", - " }", - "}") + """ + class A { + private final Object o = new Object(); + private final String s = o.toString(); + + void m() { + String v1 = s.toString(); + String v2 = "foo".toString(); + String v3 = v2 + super.toString(); + String v4 = 42 + String.valueOf((String) null); + String.format("%s", o.toString()); + } + } + """) .addOutputLines( "A.java", - "class A {", - " private final Object o = new Object();", - " private final String s = o.toString();", - "", - " void m() {", - " String v1 = s;", - " String v2 = \"foo\";", - " String v3 = v2 + super.toString();", - " String v4 = 42 + (String) null;", - " String.format(\"%s\", o);", - " }", - "}") + """ + class A { + private final Object o = new Object(); + private final String s = o.toString(); + + void m() { + String v1 = s; + String v2 = "foo"; + String v3 = v2 + super.toString(); + String v4 = 42 + (String) null; + String.format("%s", o); + } + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RefasterAnyOfUsageTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RefasterAnyOfUsageTest.java index 20db60b0b66..7cb248f636f 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RefasterAnyOfUsageTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RefasterAnyOfUsageTest.java @@ -16,23 +16,25 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import com.google.errorprone.refaster.Refaster;", - "import com.google.errorprone.refaster.annotation.BeforeTemplate;", - "", - "class A {", - " @BeforeTemplate", - " String before(String str) {", - " // BUG: Diagnostic contains:", - " Refaster.anyOf();", - " // BUG: Diagnostic contains:", - " return Refaster.anyOf(str);", - " }", - "", - " @BeforeTemplate", - " Object before2(String str, Object obj) {", - " return Refaster.anyOf(str, obj);", - " }", - "}") + """ + import com.google.errorprone.refaster.Refaster; + import com.google.errorprone.refaster.annotation.BeforeTemplate; + + class A { + @BeforeTemplate + String before(String str) { + // BUG: Diagnostic contains: + Refaster.anyOf(); + // BUG: Diagnostic contains: + return Refaster.anyOf(str); + } + + @BeforeTemplate + Object before2(String str, Object obj) { + return Refaster.anyOf(str, obj); + } + } + """) .doTest(); } @@ -41,28 +43,32 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "import com.google.errorprone.refaster.Refaster;", - "import com.google.errorprone.refaster.annotation.BeforeTemplate;", - "", - "class A {", - " @BeforeTemplate", - " String before(String str) {", - " Refaster.anyOf();", - " return Refaster.anyOf(str);", - " }", - "}") + """ + import com.google.errorprone.refaster.Refaster; + import com.google.errorprone.refaster.annotation.BeforeTemplate; + + class A { + @BeforeTemplate + String before(String str) { + Refaster.anyOf(); + return Refaster.anyOf(str); + } + } + """) .addOutputLines( "A.java", - "import com.google.errorprone.refaster.Refaster;", - "import com.google.errorprone.refaster.annotation.BeforeTemplate;", - "", - "class A {", - " @BeforeTemplate", - " String before(String str) {", - " Refaster.anyOf();", - " return str;", - " }", - "}") + """ + import com.google.errorprone.refaster.Refaster; + import com.google.errorprone.refaster.annotation.BeforeTemplate; + + class A { + @BeforeTemplate + String before(String str) { + Refaster.anyOf(); + return str; + } + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RefasterRuleModifiersTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RefasterRuleModifiersTest.java index c21a784925b..31f665bb0e2 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RefasterRuleModifiersTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RefasterRuleModifiersTest.java @@ -16,121 +16,129 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import com.google.errorprone.refaster.annotation.BeforeTemplate;", - "", - "final class A {", - " @BeforeTemplate", - " String before(String str) {", - " return str;", - " }", - "", - " String nonRefasterMethod(String str) {", - " return str;", - " }", - "", - " static final class Inner {", - " @BeforeTemplate", - " String before(String str) {", - " return str;", - " }", - " }", - "}") + """ + import com.google.errorprone.refaster.annotation.BeforeTemplate; + + final class A { + @BeforeTemplate + String before(String str) { + return str; + } + + String nonRefasterMethod(String str) { + return str; + } + + static final class Inner { + @BeforeTemplate + String before(String str) { + return str; + } + } + } + """) .addSourceLines( "B.java", - "import com.google.errorprone.refaster.annotation.BeforeTemplate;", - "import com.google.errorprone.refaster.annotation.Placeholder;", - "", - "abstract class B {", - " @Placeholder", - " abstract O someFunction(I input);", - "", - " @BeforeTemplate", - " String before(I input) {", - " return String.valueOf(someFunction(input));", - " }", - "", - " abstract static class Inner {", - " @Placeholder", - " abstract O someFunction(I input);", - "", - " @BeforeTemplate", - " String before(I input) {", - " return String.valueOf(someFunction(input));", - " }", - " }", - "}") + """ + import com.google.errorprone.refaster.annotation.BeforeTemplate; + import com.google.errorprone.refaster.annotation.Placeholder; + + abstract class B { + @Placeholder + abstract O someFunction(I input); + + @BeforeTemplate + String before(I input) { + return String.valueOf(someFunction(input)); + } + + abstract static class Inner { + @Placeholder + abstract O someFunction(I input); + + @BeforeTemplate + String before(I input) { + return String.valueOf(someFunction(input)); + } + } + } + """) .addSourceLines( "C.java", - "import com.google.errorprone.refaster.annotation.BeforeTemplate;", - "", - "// BUG: Diagnostic contains:", - "class C {", - " @BeforeTemplate", - " // BUG: Diagnostic contains:", - " final String beforeFinal(String str) {", - " return str;", - " }", - "", - " @BeforeTemplate", - " // BUG: Diagnostic contains:", - " private String beforePrivate(String str) {", - " return str;", - " }", - "", - " @BeforeTemplate", - " // BUG: Diagnostic contains:", - " public String beforePublic(String str) {", - " return str;", - " }", - "", - " @BeforeTemplate", - " // BUG: Diagnostic contains:", - " static String beforeStatic(String str) {", - " return str;", - " }", - "", - " @BeforeTemplate", - " // BUG: Diagnostic contains:", - " synchronized String beforeSynchronized(String str) {", - " return str;", - " }", - "", - " // BUG: Diagnostic contains:", - " abstract static class AbstractInner {", - " @BeforeTemplate", - " String before(String str) {", - " return str;", - " }", - " }", - "", - " // BUG: Diagnostic contains:", - " static class NonFinalInner {", - " @BeforeTemplate", - " String before(String str) {", - " return str;", - " }", - " }", - "", - " // BUG: Diagnostic contains:", - " final class NonStaticInner {", - " @BeforeTemplate", - " String before(String str) {", - " return str;", - " }", - " }", - "}") + """ + import com.google.errorprone.refaster.annotation.BeforeTemplate; + + // BUG: Diagnostic contains: + class C { + @BeforeTemplate + // BUG: Diagnostic contains: + final String beforeFinal(String str) { + return str; + } + + @BeforeTemplate + // BUG: Diagnostic contains: + private String beforePrivate(String str) { + return str; + } + + @BeforeTemplate + // BUG: Diagnostic contains: + public String beforePublic(String str) { + return str; + } + + @BeforeTemplate + // BUG: Diagnostic contains: + static String beforeStatic(String str) { + return str; + } + + @BeforeTemplate + // BUG: Diagnostic contains: + synchronized String beforeSynchronized(String str) { + return str; + } + + // BUG: Diagnostic contains: + abstract static class AbstractInner { + @BeforeTemplate + String before(String str) { + return str; + } + } + + // BUG: Diagnostic contains: + static class NonFinalInner { + @BeforeTemplate + String before(String str) { + return str; + } + } + + // BUG: Diagnostic contains: + final class NonStaticInner { + @BeforeTemplate + String before(String str) { + return str; + } + } + } + """) .addSourceLines( "D.java", - "import com.google.errorprone.refaster.annotation.BeforeTemplate;", - "", - "// BUG: Diagnostic contains:", - "abstract class D {", - " @BeforeTemplate", - " // BUG: Diagnostic contains:", - " protected String beforeProtected(String str) {", - " return str;", - " }", - "}") + """ + import com.google.errorprone.refaster.annotation.BeforeTemplate; + + // BUG: Diagnostic contains: + abstract class D { + @BeforeTemplate + // BUG: Diagnostic contains: + protected String beforeProtected(String str) { + return str; + } + } + """) .doTest(); } @@ -139,70 +147,78 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "import com.google.errorprone.refaster.annotation.BeforeTemplate;", - "", - "class A {", - " @BeforeTemplate", - " private static String before(String str) {", - " return str;", - " }", - "}") + """ + import com.google.errorprone.refaster.annotation.BeforeTemplate; + + class A { + @BeforeTemplate + private static String before(String str) { + return str; + } + } + """) .addOutputLines( "A.java", - "import com.google.errorprone.refaster.annotation.BeforeTemplate;", - "", - "final class A {", - " @BeforeTemplate", - " String before(String str) {", - " return str;", - " }", - "}") + """ + import com.google.errorprone.refaster.annotation.BeforeTemplate; + + final class A { + @BeforeTemplate + String before(String str) { + return str; + } + } + """) .addInputLines( "B.java", - "import com.google.errorprone.refaster.annotation.BeforeTemplate;", - "import com.google.errorprone.refaster.annotation.Placeholder;", - "", - "final class B {", - " abstract class WithoutPlaceholder {", - " @BeforeTemplate", - " protected synchronized String before(String str) {", - " return str;", - " }", - " }", - "", - " abstract class WithPlaceholder {", - " @Placeholder", - " public abstract O someFunction(I input);", - "", - " @BeforeTemplate", - " public final String before(I input) {", - " return String.valueOf(someFunction(input));", - " }", - " }", - "}") + """ + import com.google.errorprone.refaster.annotation.BeforeTemplate; + import com.google.errorprone.refaster.annotation.Placeholder; + + final class B { + abstract class WithoutPlaceholder { + @BeforeTemplate + protected synchronized String before(String str) { + return str; + } + } + + abstract class WithPlaceholder { + @Placeholder + public abstract O someFunction(I input); + + @BeforeTemplate + public final String before(I input) { + return String.valueOf(someFunction(input)); + } + } + } + """) .addOutputLines( "B.java", - "import com.google.errorprone.refaster.annotation.BeforeTemplate;", - "import com.google.errorprone.refaster.annotation.Placeholder;", - "", - "final class B {", - " static final class WithoutPlaceholder {", - " @BeforeTemplate", - " String before(String str) {", - " return str;", - " }", - " }", - "", - " abstract static class WithPlaceholder {", - " @Placeholder", - " abstract O someFunction(I input);", - "", - " @BeforeTemplate", - " String before(I input) {", - " return String.valueOf(someFunction(input));", - " }", - " }", - "}") + """ + import com.google.errorprone.refaster.annotation.BeforeTemplate; + import com.google.errorprone.refaster.annotation.Placeholder; + + final class B { + static final class WithoutPlaceholder { + @BeforeTemplate + String before(String str) { + return str; + } + } + + abstract static class WithPlaceholder { + @Placeholder + abstract O someFunction(I input); + + @BeforeTemplate + String before(I input) { + return String.valueOf(someFunction(input)); + } + } + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RequestMappingAnnotationTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RequestMappingAnnotationTest.java index 38593565586..bb8b758347b 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RequestMappingAnnotationTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RequestMappingAnnotationTest.java @@ -12,125 +12,127 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import java.io.InputStream;", - "import java.time.ZoneId;", - "import java.util.Locale;", - "import java.util.TimeZone;", - "import javax.servlet.http.HttpServletRequest;", - "import javax.servlet.http.HttpServletResponse;", - "import org.springframework.http.HttpMethod;", - "import org.springframework.web.bind.annotation.DeleteMapping;", - "import org.springframework.web.bind.annotation.GetMapping;", - "import org.springframework.web.bind.annotation.PatchMapping;", - "import org.springframework.web.bind.annotation.PathVariable;", - "import org.springframework.web.bind.annotation.PostMapping;", - "import org.springframework.web.bind.annotation.PutMapping;", - "import org.springframework.web.bind.annotation.RequestAttribute;", - "import org.springframework.web.bind.annotation.RequestBody;", - "import org.springframework.web.bind.annotation.RequestHeader;", - "import org.springframework.web.bind.annotation.RequestMapping;", - "import org.springframework.web.bind.annotation.RequestParam;", - "import org.springframework.web.bind.annotation.RequestPart;", - "import org.springframework.web.context.request.NativeWebRequest;", - "import org.springframework.web.context.request.WebRequest;", - "import org.springframework.web.server.ServerWebExchange;", - "import org.springframework.web.util.UriBuilder;", - "import org.springframework.web.util.UriComponentsBuilder;", - "", - "interface A {", - " A noMapping();", - "", - " A noMapping(String param);", - "", - " @DeleteMapping", - " A properNoParameters();", - "", - " @GetMapping", - " A properPathVariable(@PathVariable String param);", - "", - " @PatchMapping", - " A properRequestAttribute(@RequestAttribute String attribute);", - "", - " @PostMapping", - " A properRequestBody(@RequestBody String body);", - "", - " @PutMapping", - " A properRequestHeader(@RequestHeader String header);", - "", - " @RequestMapping", - " A properRequestParam(@RequestParam String param);", - "", - " @RequestMapping", - " A properRequestPart(@RequestPart String part);", - "", - " @RequestMapping", - " A properInputStream(InputStream input);", - "", - " @RequestMapping", - " A properZoneId(ZoneId zoneId);", - "", - " @RequestMapping", - " A properLocale(Locale locale);", - "", - " @RequestMapping", - " A properTimeZone(TimeZone timeZone);", - "", - " @RequestMapping", - " A properHttpServletRequest(HttpServletRequest request);", - "", - " @RequestMapping", - " A properHttpServletResponse(HttpServletResponse response);", - "", - " @RequestMapping", - " A properHttpMethod(HttpMethod method);", - "", - " @RequestMapping", - " A properNativeWebRequest(NativeWebRequest request);", - "", - " @RequestMapping", - " A properWebRequest(WebRequest request);", - "", - " @RequestMapping", - " A properServerWebExchange(ServerWebExchange exchange);", - "", - " @RequestMapping", - " A properServerUriBuilder(UriBuilder builder);", - "", - " @RequestMapping", - " A properServerUriComponentsBuilder(UriComponentsBuilder builder);", - "", - " @DeleteMapping", - " // BUG: Diagnostic contains:", - " A delete(String param);", - "", - " @GetMapping", - " // BUG: Diagnostic contains:", - " A get(String param);", - "", - " @PatchMapping", - " // BUG: Diagnostic contains:", - " A patch(String param);", - "", - " @PostMapping", - " // BUG: Diagnostic contains:", - " A post(String param);", - "", - " @PutMapping", - " // BUG: Diagnostic contains:", - " A put(String param);", - "", - " @RequestMapping", - " // BUG: Diagnostic contains:", - " A requestMultiple(String param, String param2);", - "", - " @RequestMapping", - " // BUG: Diagnostic contains:", - " A requestFirstParamViolation(String param, @PathVariable String param2);", - "", - " @RequestMapping", - " // BUG: Diagnostic contains:", - " A requestSecondParamViolation(@RequestBody String param, String param2);", - "}") + """ + import java.io.InputStream; + import java.time.ZoneId; + import java.util.Locale; + import java.util.TimeZone; + import javax.servlet.http.HttpServletRequest; + import javax.servlet.http.HttpServletResponse; + import org.springframework.http.HttpMethod; + import org.springframework.web.bind.annotation.DeleteMapping; + import org.springframework.web.bind.annotation.GetMapping; + import org.springframework.web.bind.annotation.PatchMapping; + import org.springframework.web.bind.annotation.PathVariable; + import org.springframework.web.bind.annotation.PostMapping; + import org.springframework.web.bind.annotation.PutMapping; + import org.springframework.web.bind.annotation.RequestAttribute; + import org.springframework.web.bind.annotation.RequestBody; + import org.springframework.web.bind.annotation.RequestHeader; + import org.springframework.web.bind.annotation.RequestMapping; + import org.springframework.web.bind.annotation.RequestParam; + import org.springframework.web.bind.annotation.RequestPart; + import org.springframework.web.context.request.NativeWebRequest; + import org.springframework.web.context.request.WebRequest; + import org.springframework.web.server.ServerWebExchange; + import org.springframework.web.util.UriBuilder; + import org.springframework.web.util.UriComponentsBuilder; + + interface A { + A noMapping(); + + A noMapping(String param); + + @DeleteMapping + A properNoParameters(); + + @GetMapping + A properPathVariable(@PathVariable String param); + + @PatchMapping + A properRequestAttribute(@RequestAttribute String attribute); + + @PostMapping + A properRequestBody(@RequestBody String body); + + @PutMapping + A properRequestHeader(@RequestHeader String header); + + @RequestMapping + A properRequestParam(@RequestParam String param); + + @RequestMapping + A properRequestPart(@RequestPart String part); + + @RequestMapping + A properInputStream(InputStream input); + + @RequestMapping + A properZoneId(ZoneId zoneId); + + @RequestMapping + A properLocale(Locale locale); + + @RequestMapping + A properTimeZone(TimeZone timeZone); + + @RequestMapping + A properHttpServletRequest(HttpServletRequest request); + + @RequestMapping + A properHttpServletResponse(HttpServletResponse response); + + @RequestMapping + A properHttpMethod(HttpMethod method); + + @RequestMapping + A properNativeWebRequest(NativeWebRequest request); + + @RequestMapping + A properWebRequest(WebRequest request); + + @RequestMapping + A properServerWebExchange(ServerWebExchange exchange); + + @RequestMapping + A properServerUriBuilder(UriBuilder builder); + + @RequestMapping + A properServerUriComponentsBuilder(UriComponentsBuilder builder); + + @DeleteMapping + // BUG: Diagnostic contains: + A delete(String param); + + @GetMapping + // BUG: Diagnostic contains: + A get(String param); + + @PatchMapping + // BUG: Diagnostic contains: + A patch(String param); + + @PostMapping + // BUG: Diagnostic contains: + A post(String param); + + @PutMapping + // BUG: Diagnostic contains: + A put(String param); + + @RequestMapping + // BUG: Diagnostic contains: + A requestMultiple(String param, String param2); + + @RequestMapping + // BUG: Diagnostic contains: + A requestFirstParamViolation(String param, @PathVariable String param2); + + @RequestMapping + // BUG: Diagnostic contains: + A requestSecondParamViolation(@RequestBody String param, String param2); + } + """) .doTest(); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RequestParamTypeTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RequestParamTypeTest.java index 6dfc7fb329d..b3e6289d2c7 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RequestParamTypeTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/RequestParamTypeTest.java @@ -12,55 +12,57 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import com.google.common.collect.ImmutableBiMap;", - "import com.google.common.collect.ImmutableList;", - "import com.google.common.collect.ImmutableMap;", - "import com.google.common.collect.ImmutableSet;", - "import java.util.List;", - "import java.util.Map;", - "import java.util.Set;", - "import org.jspecify.nullness.Nullable;", - "import org.springframework.web.bind.annotation.DeleteMapping;", - "import org.springframework.web.bind.annotation.GetMapping;", - "import org.springframework.web.bind.annotation.PostMapping;", - "import org.springframework.web.bind.annotation.PutMapping;", - "import org.springframework.web.bind.annotation.RequestBody;", - "import org.springframework.web.bind.annotation.RequestParam;", - "", - "interface A {", - " @PostMapping", - " A properRequestParam(@RequestBody String body);", - "", - " @GetMapping", - " A properRequestParam(@RequestParam int param);", - "", - " @GetMapping", - " A properRequestParam(@RequestParam List param);", - "", - " @PostMapping", - " A properRequestParam(@RequestBody String body, @RequestParam Set param);", - "", - " @PutMapping", - " A properRequestParam(@RequestBody String body, @RequestParam Map param);", - "", - " @GetMapping", - " // BUG: Diagnostic contains:", - " A get(@RequestParam ImmutableBiMap param);", - "", - " @PostMapping", - " // BUG: Diagnostic contains:", - " A post(@Nullable @RequestParam ImmutableList param);", - "", - " @PutMapping", - " // BUG: Diagnostic contains:", - " A put(@RequestBody String body, @RequestParam ImmutableSet param);", - "", - " @DeleteMapping", - " // BUG: Diagnostic contains:", - " A delete(@RequestBody String body, @RequestParam ImmutableMap param);", - "", - " void negative(ImmutableSet set, ImmutableMap map);", - "}") + """ + import com.google.common.collect.ImmutableBiMap; + import com.google.common.collect.ImmutableList; + import com.google.common.collect.ImmutableMap; + import com.google.common.collect.ImmutableSet; + import java.util.List; + import java.util.Map; + import java.util.Set; + import org.jspecify.nullness.Nullable; + import org.springframework.web.bind.annotation.DeleteMapping; + import org.springframework.web.bind.annotation.GetMapping; + import org.springframework.web.bind.annotation.PostMapping; + import org.springframework.web.bind.annotation.PutMapping; + import org.springframework.web.bind.annotation.RequestBody; + import org.springframework.web.bind.annotation.RequestParam; + + interface A { + @PostMapping + A properRequestParam(@RequestBody String body); + + @GetMapping + A properRequestParam(@RequestParam int param); + + @GetMapping + A properRequestParam(@RequestParam List param); + + @PostMapping + A properRequestParam(@RequestBody String body, @RequestParam Set param); + + @PutMapping + A properRequestParam(@RequestBody String body, @RequestParam Map param); + + @GetMapping + // BUG: Diagnostic contains: + A get(@RequestParam ImmutableBiMap param); + + @PostMapping + // BUG: Diagnostic contains: + A post(@Nullable @RequestParam ImmutableList param); + + @PutMapping + // BUG: Diagnostic contains: + A put(@RequestBody String body, @RequestParam ImmutableSet param); + + @DeleteMapping + // BUG: Diagnostic contains: + A delete(@RequestBody String body, @RequestParam ImmutableMap param); + + void negative(ImmutableSet set, ImmutableMap map); + } + """) .doTest(); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ScheduledTransactionTraceTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ScheduledTransactionTraceTest.java index 95478fe7127..6659cc8d679 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ScheduledTransactionTraceTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ScheduledTransactionTraceTest.java @@ -17,30 +17,32 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import com.newrelic.api.agent.Trace;", - "import org.springframework.scheduling.annotation.Scheduled;", - "", - "class A {", - " void notScheduled() {}", - "", - " @Scheduled(fixedDelay = 1)", - " // BUG: Diagnostic contains:", - " void scheduledButNotTraced() {}", - "", - " @Scheduled(fixedDelay = 1)", - " // BUG: Diagnostic contains:", - " @Trace", - " void scheduledButImproperlyTraced1() {}", - "", - " @Scheduled(fixedDelay = 1)", - " // BUG: Diagnostic contains:", - " @Trace(dispatcher = false)", - " void scheduledButImproperlyTraced2() {}", - "", - " @Scheduled(fixedDelay = 1)", - " @Trace(dispatcher = true)", - " void scheduledAndProperlyTraced() {}", - "}") + """ + import com.newrelic.api.agent.Trace; + import org.springframework.scheduling.annotation.Scheduled; + + class A { + void notScheduled() {} + + @Scheduled(fixedDelay = 1) + // BUG: Diagnostic contains: + void scheduledButNotTraced() {} + + @Scheduled(fixedDelay = 1) + // BUG: Diagnostic contains: + @Trace + void scheduledButImproperlyTraced1() {} + + @Scheduled(fixedDelay = 1) + // BUG: Diagnostic contains: + @Trace(dispatcher = false) + void scheduledButImproperlyTraced2() {} + + @Scheduled(fixedDelay = 1) + @Trace(dispatcher = true) + void scheduledAndProperlyTraced() {} + } + """) .doTest(); } @@ -50,12 +52,14 @@ void identificationWithoutNewRelicAgentApiOnClasspath() { .withClasspath(Scheduled.class) .addSourceLines( "A.java", - "import org.springframework.scheduling.annotation.Scheduled;", - "", - "class A {", - " @Scheduled(fixedDelay = 1)", - " void scheduledButNotTraced() {}", - "}") + """ + import org.springframework.scheduling.annotation.Scheduled; + + class A { + @Scheduled(fixedDelay = 1) + void scheduledButNotTraced() {} + } + """) .doTest(); } @@ -64,47 +68,51 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "import com.newrelic.api.agent.Trace;", - "import org.springframework.scheduling.annotation.Scheduled;", - "", - "class A {", - " @Scheduled(fixedDelay = 1)", - " void scheduledButNotTraced() {}", - "", - " @Scheduled(fixedDelay = 1)", - " @Trace", - " void scheduledButImproperlyTraced1() {}", - "", - " @Scheduled(fixedDelay = 1)", - " @Trace(dispatcher = false)", - " void scheduledButImproperlyTraced2() {}", - "", - " @Scheduled(fixedDelay = 1)", - " @Trace(leaf = true)", - " void scheduledButImproperlyTraced3() {}", - "}") + """ + import com.newrelic.api.agent.Trace; + import org.springframework.scheduling.annotation.Scheduled; + + class A { + @Scheduled(fixedDelay = 1) + void scheduledButNotTraced() {} + + @Scheduled(fixedDelay = 1) + @Trace + void scheduledButImproperlyTraced1() {} + + @Scheduled(fixedDelay = 1) + @Trace(dispatcher = false) + void scheduledButImproperlyTraced2() {} + + @Scheduled(fixedDelay = 1) + @Trace(leaf = true) + void scheduledButImproperlyTraced3() {} + } + """) .addOutputLines( "A.java", - "import com.newrelic.api.agent.Trace;", - "import org.springframework.scheduling.annotation.Scheduled;", - "", - "class A {", - " @Trace(dispatcher = true)", - " @Scheduled(fixedDelay = 1)", - " void scheduledButNotTraced() {}", - "", - " @Scheduled(fixedDelay = 1)", - " @Trace(dispatcher = true)", - " void scheduledButImproperlyTraced1() {}", - "", - " @Scheduled(fixedDelay = 1)", - " @Trace(dispatcher = true)", - " void scheduledButImproperlyTraced2() {}", - "", - " @Scheduled(fixedDelay = 1)", - " @Trace(dispatcher = true, leaf = true)", - " void scheduledButImproperlyTraced3() {}", - "}") + """ + import com.newrelic.api.agent.Trace; + import org.springframework.scheduling.annotation.Scheduled; + + class A { + @Trace(dispatcher = true) + @Scheduled(fixedDelay = 1) + void scheduledButNotTraced() {} + + @Scheduled(fixedDelay = 1) + @Trace(dispatcher = true) + void scheduledButImproperlyTraced1() {} + + @Scheduled(fixedDelay = 1) + @Trace(dispatcher = true) + void scheduledButImproperlyTraced2() {} + + @Scheduled(fixedDelay = 1) + @Trace(dispatcher = true, leaf = true) + void scheduledButImproperlyTraced3() {} + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/Slf4jLogStatementTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/Slf4jLogStatementTest.java index 5900a450716..201718056aa 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/Slf4jLogStatementTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/Slf4jLogStatementTest.java @@ -16,80 +16,82 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import org.slf4j.Logger;", - "import org.slf4j.LoggerFactory;", - "import org.slf4j.Marker;", - "import org.slf4j.MarkerFactory;", - "", - "class A {", - " private static final String FMT0 = \"format-string-without-placeholders\";", - " private static final String FMT1 = \"format-string-with-{}-placeholder\";", - " private static final String FMT2 = \"format-string-with-{}-{}-placeholders\";", - " private static final String FMT_ERR = \"format-string-with-%s-placeholder\";", - " private static final Logger LOG = LoggerFactory.getLogger(A.class);", - "", - " private final Marker marker = MarkerFactory.getMarker(A.class.getName());", - " private final Object o = new Object();", - " private final String s = o.toString();", - " private final Throwable t = new Throwable();", - "", - " void m() {", - " LOG.trace(s);", - " LOG.debug(s, o);", - " LOG.info(s, t);", - " LOG.warn(s, o, t);", - " LOG.error(marker, s);", - " LOG.trace(marker, s, o);", - " LOG.debug(marker, s, t);", - " LOG.info(marker, s, o, t);", - "", - " LOG.warn(FMT0);", - " // BUG: Diagnostic contains: Log statement contains 0 placeholders, but specifies 1 matching", - " // argument(s)", - " LOG.error(FMT0, o);", - " LOG.trace(FMT0, t);", - " // BUG: Diagnostic contains:", - " LOG.debug(FMT0, o, t);", - " LOG.info(marker, FMT0);", - " // BUG: Diagnostic contains:", - " LOG.warn(marker, FMT0, o);", - " LOG.error(marker, FMT0, t);", - " // BUG: Diagnostic contains:", - " LOG.trace(marker, FMT0, o, t);", - "", - " // BUG: Diagnostic contains: Log statement contains 1 placeholders, but specifies 0 matching", - " // argument(s)", - " LOG.debug(FMT1);", - " LOG.info(FMT1, o);", - " // BUG: Diagnostic contains:", - " LOG.warn(FMT1, t);", - " LOG.error(FMT1, o, t);", - " // BUG: Diagnostic contains: Log statement contains 1 placeholders, but specifies 2 matching", - " // argument(s)", - " LOG.trace(FMT1, o, o);", - " // BUG: Diagnostic contains:", - " LOG.debug(FMT1, o, o, t);", - " // BUG: Diagnostic contains:", - " LOG.info(marker, FMT1);", - " LOG.warn(marker, FMT1, o);", - " // BUG: Diagnostic contains:", - " LOG.error(marker, FMT1, t);", - " LOG.trace(marker, FMT1, o, t);", - " // BUG: Diagnostic contains:", - " LOG.debug(marker, FMT1, o, o);", - " // BUG: Diagnostic contains:", - " LOG.info(marker, FMT1, o, o, t);", - "", - " // BUG: Diagnostic contains: SLF4J log statement placeholders are of the form `{}`, not `%s`", - " LOG.warn(FMT_ERR);", - " // BUG: Diagnostic contains:", - " LOG.error(FMT_ERR, t);", - " // BUG: Diagnostic contains:", - " LOG.trace(FMT_ERR, o);", - " // BUG: Diagnostic contains:", - " LOG.debug(FMT_ERR, o, t);", - " }", - "}") + """ + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; + import org.slf4j.Marker; + import org.slf4j.MarkerFactory; + + class A { + private static final String FMT0 = "format-string-without-placeholders"; + private static final String FMT1 = "format-string-with-{}-placeholder"; + private static final String FMT2 = "format-string-with-{}-{}-placeholders"; + private static final String FMT_ERR = "format-string-with-%s-placeholder"; + private static final Logger LOG = LoggerFactory.getLogger(A.class); + + private final Marker marker = MarkerFactory.getMarker(A.class.getName()); + private final Object o = new Object(); + private final String s = o.toString(); + private final Throwable t = new Throwable(); + + void m() { + LOG.trace(s); + LOG.debug(s, o); + LOG.info(s, t); + LOG.warn(s, o, t); + LOG.error(marker, s); + LOG.trace(marker, s, o); + LOG.debug(marker, s, t); + LOG.info(marker, s, o, t); + + LOG.warn(FMT0); + // BUG: Diagnostic contains: Log statement contains 0 placeholders, but specifies 1 matching + // argument(s) + LOG.error(FMT0, o); + LOG.trace(FMT0, t); + // BUG: Diagnostic contains: + LOG.debug(FMT0, o, t); + LOG.info(marker, FMT0); + // BUG: Diagnostic contains: + LOG.warn(marker, FMT0, o); + LOG.error(marker, FMT0, t); + // BUG: Diagnostic contains: + LOG.trace(marker, FMT0, o, t); + + // BUG: Diagnostic contains: Log statement contains 1 placeholders, but specifies 0 matching + // argument(s) + LOG.debug(FMT1); + LOG.info(FMT1, o); + // BUG: Diagnostic contains: + LOG.warn(FMT1, t); + LOG.error(FMT1, o, t); + // BUG: Diagnostic contains: Log statement contains 1 placeholders, but specifies 2 matching + // argument(s) + LOG.trace(FMT1, o, o); + // BUG: Diagnostic contains: + LOG.debug(FMT1, o, o, t); + // BUG: Diagnostic contains: + LOG.info(marker, FMT1); + LOG.warn(marker, FMT1, o); + // BUG: Diagnostic contains: + LOG.error(marker, FMT1, t); + LOG.trace(marker, FMT1, o, t); + // BUG: Diagnostic contains: + LOG.debug(marker, FMT1, o, o); + // BUG: Diagnostic contains: + LOG.info(marker, FMT1, o, o, t); + + // BUG: Diagnostic contains: SLF4J log statement placeholders are of the form `{}`, not `%s` + LOG.warn(FMT_ERR); + // BUG: Diagnostic contains: + LOG.error(FMT_ERR, t); + // BUG: Diagnostic contains: + LOG.trace(FMT_ERR, o); + // BUG: Diagnostic contains: + LOG.debug(FMT_ERR, o, t); + } + } + """) .doTest(); } @@ -99,50 +101,54 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "import org.slf4j.Logger;", - "import org.slf4j.LoggerFactory;", - "import org.slf4j.Marker;", - "import org.slf4j.MarkerFactory;", - "", - "class A {", - " private static final String FMT_ERR = \"format-string-with-%s-placeholder\";", - " private static final Logger LOG = LoggerFactory.getLogger(A.class);", - "", - " private final Marker marker = MarkerFactory.getMarker(A.class.getName());", - " private final Object o = new Object();", - " private final String s = o.toString();", - " private final Throwable t = new Throwable();", - "", - " void m() {", - " LOG.error(FMT_ERR, o);", - " LOG.error(\"format-string-with-'%s'-placeholder\", o);", - " LOG.error(\"format-string-with-\\\"%s\\\"-placeholder\", o);", - " LOG.error(\"format-string-with-%s\" + \"-placeholder\", o);", - " }", - "}") + """ + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; + import org.slf4j.Marker; + import org.slf4j.MarkerFactory; + + class A { + private static final String FMT_ERR = "format-string-with-%s-placeholder"; + private static final Logger LOG = LoggerFactory.getLogger(A.class); + + private final Marker marker = MarkerFactory.getMarker(A.class.getName()); + private final Object o = new Object(); + private final String s = o.toString(); + private final Throwable t = new Throwable(); + + void m() { + LOG.error(FMT_ERR, o); + LOG.error("format-string-with-'%s'-placeholder", o); + LOG.error("format-string-with-\\"%s\\"-placeholder", o); + LOG.error("format-string-with-%s" + "-placeholder", o); + } + } + """) .addOutputLines( "A.java", - "import org.slf4j.Logger;", - "import org.slf4j.LoggerFactory;", - "import org.slf4j.Marker;", - "import org.slf4j.MarkerFactory;", - "", - "class A {", - " private static final String FMT_ERR = \"format-string-with-%s-placeholder\";", - " private static final Logger LOG = LoggerFactory.getLogger(A.class);", - "", - " private final Marker marker = MarkerFactory.getMarker(A.class.getName());", - " private final Object o = new Object();", - " private final String s = o.toString();", - " private final Throwable t = new Throwable();", - "", - " void m() {", - " LOG.error(FMT_ERR, o);", - " LOG.error(\"format-string-with-'{}'-placeholder\", o);", - " LOG.error(\"format-string-with-\\\"{}\\\"-placeholder\", o);", - " LOG.error(\"format-string-with-{}\" + \"-placeholder\", o);", - " }", - "}") + """ + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; + import org.slf4j.Marker; + import org.slf4j.MarkerFactory; + + class A { + private static final String FMT_ERR = "format-string-with-%s-placeholder"; + private static final Logger LOG = LoggerFactory.getLogger(A.class); + + private final Marker marker = MarkerFactory.getMarker(A.class.getName()); + private final Object o = new Object(); + private final String s = o.toString(); + private final Throwable t = new Throwable(); + + void m() { + LOG.error(FMT_ERR, o); + LOG.error("format-string-with-'{}'-placeholder", o); + LOG.error("format-string-with-\\"{}\\"-placeholder", o); + LOG.error("format-string-with-{}" + "-placeholder", o); + } + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/SpringMvcAnnotationTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/SpringMvcAnnotationTest.java index ee47ad2a7f0..237e8a7868f 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/SpringMvcAnnotationTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/SpringMvcAnnotationTest.java @@ -16,70 +16,72 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import static org.springframework.web.bind.annotation.RequestMethod.DELETE;", - "import static org.springframework.web.bind.annotation.RequestMethod.GET;", - "import static org.springframework.web.bind.annotation.RequestMethod.HEAD;", - "import static org.springframework.web.bind.annotation.RequestMethod.PATCH;", - "import static org.springframework.web.bind.annotation.RequestMethod.POST;", - "import static org.springframework.web.bind.annotation.RequestMethod.PUT;", - "", - "import org.springframework.web.bind.annotation.DeleteMapping;", - "import org.springframework.web.bind.annotation.GetMapping;", - "import org.springframework.web.bind.annotation.PatchMapping;", - "import org.springframework.web.bind.annotation.PostMapping;", - "import org.springframework.web.bind.annotation.PutMapping;", - "import org.springframework.web.bind.annotation.RequestMapping;", - "import org.springframework.web.bind.annotation.RequestMethod;", - "", - "interface A {", - " @RequestMapping", - " A simple();", - "", - " @RequestMapping(method = {})", - " A explicitDefault();", - " // BUG: Diagnostic contains:", - " @RequestMapping(method = RequestMethod.GET)", - " A get();", - " // BUG: Diagnostic contains:", - " @RequestMapping(method = {RequestMethod.POST})", - " A post();", - " // BUG: Diagnostic contains:", - " @RequestMapping(method = {PUT})", - " A put();", - " // BUG: Diagnostic contains:", - " @RequestMapping(method = {DELETE})", - " A delete();", - " // BUG: Diagnostic contains:", - " @RequestMapping(method = {PATCH})", - " A patch();", - "", - " @RequestMapping(method = HEAD)", - " A head();", - "", - " @RequestMapping(method = RequestMethod.OPTIONS)", - " A options();", - "", - " @RequestMapping(method = {GET, POST})", - " A simpleMix();", - "", - " @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST})", - " A verboseMix();", - "", - " @DeleteMapping", - " A properDelete();", - "", - " @GetMapping", - " A properGet();", - "", - " @PatchMapping", - " A properPatch();", - "", - " @PostMapping", - " A properPost();", - "", - " @PutMapping", - " A properPut();", - "}") + """ + import static org.springframework.web.bind.annotation.RequestMethod.DELETE; + import static org.springframework.web.bind.annotation.RequestMethod.GET; + import static org.springframework.web.bind.annotation.RequestMethod.HEAD; + import static org.springframework.web.bind.annotation.RequestMethod.PATCH; + import static org.springframework.web.bind.annotation.RequestMethod.POST; + import static org.springframework.web.bind.annotation.RequestMethod.PUT; + + import org.springframework.web.bind.annotation.DeleteMapping; + import org.springframework.web.bind.annotation.GetMapping; + import org.springframework.web.bind.annotation.PatchMapping; + import org.springframework.web.bind.annotation.PostMapping; + import org.springframework.web.bind.annotation.PutMapping; + import org.springframework.web.bind.annotation.RequestMapping; + import org.springframework.web.bind.annotation.RequestMethod; + + interface A { + @RequestMapping + A simple(); + + @RequestMapping(method = {}) + A explicitDefault(); + // BUG: Diagnostic contains: + @RequestMapping(method = RequestMethod.GET) + A get(); + // BUG: Diagnostic contains: + @RequestMapping(method = {RequestMethod.POST}) + A post(); + // BUG: Diagnostic contains: + @RequestMapping(method = {PUT}) + A put(); + // BUG: Diagnostic contains: + @RequestMapping(method = {DELETE}) + A delete(); + // BUG: Diagnostic contains: + @RequestMapping(method = {PATCH}) + A patch(); + + @RequestMapping(method = HEAD) + A head(); + + @RequestMapping(method = RequestMethod.OPTIONS) + A options(); + + @RequestMapping(method = {GET, POST}) + A simpleMix(); + + @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}) + A verboseMix(); + + @DeleteMapping + A properDelete(); + + @GetMapping + A properGet(); + + @PatchMapping + A properPatch(); + + @PostMapping + A properPost(); + + @PutMapping + A properPut(); + } + """) .doTest(); } @@ -88,66 +90,70 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "import static org.springframework.web.bind.annotation.RequestMethod.PATCH;", - "import static org.springframework.web.bind.annotation.RequestMethod.POST;", - "import static org.springframework.web.bind.annotation.RequestMethod.PUT;", - "", - "import org.springframework.web.bind.annotation.RequestMapping;", - "import org.springframework.web.bind.annotation.RequestMethod;", - "", - "interface A {", - " @RequestMapping(method = RequestMethod.GET)", - " A simple();", - "", - " @RequestMapping(path = \"/foo/bar\", method = POST)", - " A prefixed();", - "", - " @RequestMapping(", - " method = {RequestMethod.DELETE},", - " path = \"/foo/bar\")", - " A suffixed();", - "", - " @RequestMapping(", - " path = \"/foo/bar\",", - " method = {PUT},", - " consumes = {\"a\", \"b\"})", - " A surrounded();", - "", - " @RequestMapping(method = {PATCH})", - " A curly();", - "}") + """ + import static org.springframework.web.bind.annotation.RequestMethod.PATCH; + import static org.springframework.web.bind.annotation.RequestMethod.POST; + import static org.springframework.web.bind.annotation.RequestMethod.PUT; + + import org.springframework.web.bind.annotation.RequestMapping; + import org.springframework.web.bind.annotation.RequestMethod; + + interface A { + @RequestMapping(method = RequestMethod.GET) + A simple(); + + @RequestMapping(path = "/foo/bar", method = POST) + A prefixed(); + + @RequestMapping( + method = {RequestMethod.DELETE}, + path = "/foo/bar") + A suffixed(); + + @RequestMapping( + path = "/foo/bar", + method = {PUT}, + consumes = {"a", "b"}) + A surrounded(); + + @RequestMapping(method = {PATCH}) + A curly(); + } + """) .addOutputLines( "A.java", - "import static org.springframework.web.bind.annotation.RequestMethod.PATCH;", - "import static org.springframework.web.bind.annotation.RequestMethod.POST;", - "import static org.springframework.web.bind.annotation.RequestMethod.PUT;", - "", - "import org.springframework.web.bind.annotation.DeleteMapping;", - "import org.springframework.web.bind.annotation.GetMapping;", - "import org.springframework.web.bind.annotation.PatchMapping;", - "import org.springframework.web.bind.annotation.PostMapping;", - "import org.springframework.web.bind.annotation.PutMapping;", - "import org.springframework.web.bind.annotation.RequestMapping;", - "import org.springframework.web.bind.annotation.RequestMethod;", - "", - "interface A {", - " @GetMapping()", - " A simple();", - "", - " @PostMapping(path = \"/foo/bar\")", - " A prefixed();", - "", - " @DeleteMapping(path = \"/foo/bar\")", - " A suffixed();", - "", - " @PutMapping(", - " path = \"/foo/bar\",", - " consumes = {\"a\", \"b\"})", - " A surrounded();", - "", - " @PatchMapping()", - " A curly();", - "}") + """ + import static org.springframework.web.bind.annotation.RequestMethod.PATCH; + import static org.springframework.web.bind.annotation.RequestMethod.POST; + import static org.springframework.web.bind.annotation.RequestMethod.PUT; + + import org.springframework.web.bind.annotation.DeleteMapping; + import org.springframework.web.bind.annotation.GetMapping; + import org.springframework.web.bind.annotation.PatchMapping; + import org.springframework.web.bind.annotation.PostMapping; + import org.springframework.web.bind.annotation.PutMapping; + import org.springframework.web.bind.annotation.RequestMapping; + import org.springframework.web.bind.annotation.RequestMethod; + + interface A { + @GetMapping() + A simple(); + + @PostMapping(path = "/foo/bar") + A prefixed(); + + @DeleteMapping(path = "/foo/bar") + A suffixed(); + + @PutMapping( + path = "/foo/bar", + consumes = {"a", "b"}) + A surrounded(); + + @PatchMapping() + A curly(); + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/StaticImportTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/StaticImportTest.java index 861ea8421da..7bf4c6bb3af 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/StaticImportTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/StaticImportTest.java @@ -36,83 +36,85 @@ void identification() { compilationTestHelper .addSourceLines( "A.java", - "import static com.google.common.collect.ImmutableMap.toImmutableMap;", - "import static com.google.common.collect.ImmutableSet.toImmutableSet;", - "import static java.nio.charset.StandardCharsets.UTF_8;", - "import static java.util.function.Predicate.not;", - "import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;", - "", - "import com.google.common.base.Predicates;", - "import com.google.common.collect.ImmutableMap;", - "import com.google.common.collect.ImmutableMultiset;", - "import com.google.common.collect.ImmutableSet;", - "import com.google.errorprone.refaster.ImportPolicy;", - "import com.google.errorprone.refaster.annotation.UseImportPolicy;", - "import java.nio.charset.StandardCharsets;", - "import java.time.ZoneOffset;", - "import java.util.Optional;", - "import java.util.UUID;", - "import java.util.function.Predicate;", - "import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;", - "import org.springframework.http.MediaType;", - "", - "class A {", - " void m() {", - " // BUG: Diagnostic contains:", - " ImmutableMap.toImmutableMap(v -> v, v -> v);", - " ImmutableMap.toImmutableMap(v -> v, v -> v);", - " toImmutableMap(v -> v, v -> v);", - "", - " // BUG: Diagnostic contains:", - " ImmutableSet.toImmutableSet();", - " ImmutableSet.toImmutableSet();", - " toImmutableSet();", - "", - " // Not flagged because we define `#toImmutableMultiset` below.", - " ImmutableMultiset.toImmutableMultiset();", - " ImmutableMultiset.toImmutableMultiset();", - " toImmutableMultiset();", - "", - " // BUG: Diagnostic contains:", - " Predicate.not(null);", - " not(null);", - "", - " // BUG: Diagnostic contains:", - " Predicates.alwaysTrue();", - " // BUG: Diagnostic contains:", - " Predicates.alwaysFalse();", - " // Not flagged because of `java.util.function.Predicate.not` import.", - " Predicates.not(null);", - "", - " // BUG: Diagnostic contains:", - " UUID uuid = UUID.randomUUID();", - "", - " // BUG: Diagnostic contains:", - " Object o1 = StandardCharsets.UTF_8;", - " Object o2 = UTF_8;", - "", - " // BUG: Diagnostic contains:", - " Object e1 = WebEnvironment.RANDOM_PORT;", - " Object e2 = RANDOM_PORT;", - "", - " // Not flagged because `MediaType.ALL` is exempted.", - " MediaType t1 = MediaType.ALL;", - " // BUG: Diagnostic contains:", - " MediaType t2 = MediaType.APPLICATION_JSON;", - "", - " Optional.empty();", - "", - " // BUG: Diagnostic contains:", - " ZoneOffset zo1 = ZoneOffset.UTC;", - " ZoneOffset zo2 = ZoneOffset.MIN;", - " }", - "", - " // BUG: Diagnostic contains:", - " @UseImportPolicy(ImportPolicy.IMPORT_TOP_LEVEL)", - " void refasterAfterTemplate() {}", - "", - " void toImmutableMultiset() {}", - "}") + """ + import static com.google.common.collect.ImmutableMap.toImmutableMap; + import static com.google.common.collect.ImmutableSet.toImmutableSet; + import static java.nio.charset.StandardCharsets.UTF_8; + import static java.util.function.Predicate.not; + import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + + import com.google.common.base.Predicates; + import com.google.common.collect.ImmutableMap; + import com.google.common.collect.ImmutableMultiset; + import com.google.common.collect.ImmutableSet; + import com.google.errorprone.refaster.ImportPolicy; + import com.google.errorprone.refaster.annotation.UseImportPolicy; + import java.nio.charset.StandardCharsets; + import java.time.ZoneOffset; + import java.util.Optional; + import java.util.UUID; + import java.util.function.Predicate; + import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + import org.springframework.http.MediaType; + + class A { + void m() { + // BUG: Diagnostic contains: + ImmutableMap.toImmutableMap(v -> v, v -> v); + ImmutableMap.toImmutableMap(v -> v, v -> v); + toImmutableMap(v -> v, v -> v); + + // BUG: Diagnostic contains: + ImmutableSet.toImmutableSet(); + ImmutableSet.toImmutableSet(); + toImmutableSet(); + + // Not flagged because we define `#toImmutableMultiset` below. + ImmutableMultiset.toImmutableMultiset(); + ImmutableMultiset.toImmutableMultiset(); + toImmutableMultiset(); + + // BUG: Diagnostic contains: + Predicate.not(null); + not(null); + + // BUG: Diagnostic contains: + Predicates.alwaysTrue(); + // BUG: Diagnostic contains: + Predicates.alwaysFalse(); + // Not flagged because of `java.util.function.Predicate.not` import. + Predicates.not(null); + + // BUG: Diagnostic contains: + UUID uuid = UUID.randomUUID(); + + // BUG: Diagnostic contains: + Object o1 = StandardCharsets.UTF_8; + Object o2 = UTF_8; + + // BUG: Diagnostic contains: + Object e1 = WebEnvironment.RANDOM_PORT; + Object e2 = RANDOM_PORT; + + // Not flagged because `MediaType.ALL` is exempted. + MediaType t1 = MediaType.ALL; + // BUG: Diagnostic contains: + MediaType t2 = MediaType.APPLICATION_JSON; + + Optional.empty(); + + // BUG: Diagnostic contains: + ZoneOffset zo1 = ZoneOffset.UTC; + ZoneOffset zo2 = ZoneOffset.MIN; + } + + // BUG: Diagnostic contains: + @UseImportPolicy(ImportPolicy.IMPORT_TOP_LEVEL) + void refasterAfterTemplate() {} + + void toImmutableMultiset() {} + } + """) .doTest(); } @@ -121,154 +123,158 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "import static java.util.function.Predicate.not;", - "", - "import com.google.common.base.Predicates;", - "import com.google.common.collect.ImmutableMap;", - "import com.google.common.collect.ImmutableSet;", - "import com.google.errorprone.BugPattern;", - "import com.google.errorprone.BugPattern.SeverityLevel;", - "import java.nio.charset.StandardCharsets;", - "import java.util.ArrayList;", - "import java.util.Collections;", - "import java.util.Objects;", - "import java.util.regex.Pattern;", - "import org.junit.jupiter.params.provider.Arguments;", - "import org.springframework.boot.test.context.SpringBootTest;", - "import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;", - "import org.springframework.format.annotation.DateTimeFormat;", - "import org.springframework.format.annotation.DateTimeFormat.ISO;", - "import org.springframework.http.MediaType;", - "", - "class A {", - " void m1() {", - " ImmutableMap.toImmutableMap(v -> v, v -> v);", - " ImmutableMap.toImmutableMap(v -> v, v -> v);", - "", - " ImmutableSet.toImmutableSet();", - " ImmutableSet.toImmutableSet();", - "", - " Collections.disjoint(ImmutableSet.of(), ImmutableSet.of());", - " Collections.reverse(new ArrayList<>());", - "", - " Predicates.not(null);", - " not(null);", - "", - " Arguments.arguments(\"foo\");", - "", - " Objects.requireNonNull(\"bar\");", - "", - " Object o = StandardCharsets.UTF_8;", - "", - " ImmutableSet.of(", - " MediaType.ALL,", - " MediaType.APPLICATION_XHTML_XML,", - " MediaType.TEXT_HTML,", - " MediaType.valueOf(\"image/webp\"));", - "", - " Pattern.compile(\"\", Pattern.CASE_INSENSITIVE);", - " }", - "", - " void m2(", - " @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) String date,", - " @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) String dateTime,", - " @DateTimeFormat(iso = DateTimeFormat.ISO.TIME) String time) {}", - "", - " void m3(", - " @DateTimeFormat(iso = ISO.DATE) String date,", - " @DateTimeFormat(iso = ISO.DATE_TIME) String dateTime,", - " @DateTimeFormat(iso = ISO.TIME) String time) {}", - "", - " @BugPattern(", - " summary = \"\",", - " linkType = BugPattern.LinkType.NONE,", - " severity = SeverityLevel.SUGGESTION,", - " tags = BugPattern.StandardTags.SIMPLIFICATION)", - " static final class TestBugPattern {}", - "", - " @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)", - " final class Test {}", - "}") + """ + import static java.util.function.Predicate.not; + + import com.google.common.base.Predicates; + import com.google.common.collect.ImmutableMap; + import com.google.common.collect.ImmutableSet; + import com.google.errorprone.BugPattern; + import com.google.errorprone.BugPattern.SeverityLevel; + import java.nio.charset.StandardCharsets; + import java.util.ArrayList; + import java.util.Collections; + import java.util.Objects; + import java.util.regex.Pattern; + import org.junit.jupiter.params.provider.Arguments; + import org.springframework.boot.test.context.SpringBootTest; + import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + import org.springframework.format.annotation.DateTimeFormat; + import org.springframework.format.annotation.DateTimeFormat.ISO; + import org.springframework.http.MediaType; + + class A { + void m1() { + ImmutableMap.toImmutableMap(v -> v, v -> v); + ImmutableMap.toImmutableMap(v -> v, v -> v); + + ImmutableSet.toImmutableSet(); + ImmutableSet.toImmutableSet(); + + Collections.disjoint(ImmutableSet.of(), ImmutableSet.of()); + Collections.reverse(new ArrayList<>()); + + Predicates.not(null); + not(null); + + Arguments.arguments("foo"); + + Objects.requireNonNull("bar"); + + Object o = StandardCharsets.UTF_8; + + ImmutableSet.of( + MediaType.ALL, + MediaType.APPLICATION_XHTML_XML, + MediaType.TEXT_HTML, + MediaType.valueOf("image/webp")); + + Pattern.compile("", Pattern.CASE_INSENSITIVE); + } + + void m2( + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) String date, + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) String dateTime, + @DateTimeFormat(iso = DateTimeFormat.ISO.TIME) String time) {} + + void m3( + @DateTimeFormat(iso = ISO.DATE) String date, + @DateTimeFormat(iso = ISO.DATE_TIME) String dateTime, + @DateTimeFormat(iso = ISO.TIME) String time) {} + + @BugPattern( + summary = "", + linkType = BugPattern.LinkType.NONE, + severity = SeverityLevel.SUGGESTION, + tags = BugPattern.StandardTags.SIMPLIFICATION) + static final class TestBugPattern {} + + @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) + final class Test {} + } + """) .addOutputLines( "A.java", - "import static com.google.common.collect.ImmutableMap.toImmutableMap;", - "import static com.google.common.collect.ImmutableSet.toImmutableSet;", - "import static com.google.errorprone.BugPattern.LinkType.NONE;", - "import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;", - "import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;", - "import static java.nio.charset.StandardCharsets.UTF_8;", - "import static java.util.Collections.disjoint;", - "import static java.util.Collections.reverse;", - "import static java.util.Objects.requireNonNull;", - "import static java.util.function.Predicate.not;", - "import static java.util.regex.Pattern.CASE_INSENSITIVE;", - "import static org.junit.jupiter.params.provider.Arguments.arguments;", - "import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;", - "import static org.springframework.format.annotation.DateTimeFormat.ISO.DATE;", - "import static org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME;", - "import static org.springframework.format.annotation.DateTimeFormat.ISO.TIME;", - "import static org.springframework.http.MediaType.APPLICATION_XHTML_XML;", - "import static org.springframework.http.MediaType.TEXT_HTML;", - "", - "import com.google.common.base.Predicates;", - "import com.google.common.collect.ImmutableMap;", - "import com.google.common.collect.ImmutableSet;", - "import com.google.errorprone.BugPattern;", - "import com.google.errorprone.BugPattern.SeverityLevel;", - "import java.nio.charset.StandardCharsets;", - "import java.util.ArrayList;", - "import java.util.Collections;", - "import java.util.Objects;", - "import java.util.regex.Pattern;", - "import org.junit.jupiter.params.provider.Arguments;", - "import org.springframework.boot.test.context.SpringBootTest;", - "import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;", - "import org.springframework.format.annotation.DateTimeFormat;", - "import org.springframework.format.annotation.DateTimeFormat.ISO;", - "import org.springframework.http.MediaType;", - "", - "class A {", - " void m1() {", - " toImmutableMap(v -> v, v -> v);", - " ImmutableMap.toImmutableMap(v -> v, v -> v);", - "", - " toImmutableSet();", - " ImmutableSet.toImmutableSet();", - "", - " disjoint(ImmutableSet.of(), ImmutableSet.of());", - " reverse(new ArrayList<>());", - "", - " Predicates.not(null);", - " not(null);", - "", - " arguments(\"foo\");", - "", - " requireNonNull(\"bar\");", - "", - " Object o = UTF_8;", - "", - " ImmutableSet.of(", - " MediaType.ALL, APPLICATION_XHTML_XML, TEXT_HTML, MediaType.valueOf(\"image/webp\"));", - "", - " Pattern.compile(\"\", CASE_INSENSITIVE);", - " }", - "", - " void m2(", - " @DateTimeFormat(iso = DATE) String date,", - " @DateTimeFormat(iso = DATE_TIME) String dateTime,", - " @DateTimeFormat(iso = TIME) String time) {}", - "", - " void m3(", - " @DateTimeFormat(iso = DATE) String date,", - " @DateTimeFormat(iso = DATE_TIME) String dateTime,", - " @DateTimeFormat(iso = TIME) String time) {}", - "", - " @BugPattern(summary = \"\", linkType = NONE, severity = SUGGESTION, tags = SIMPLIFICATION)", - " static final class TestBugPattern {}", - "", - " @SpringBootTest(webEnvironment = RANDOM_PORT)", - " final class Test {}", - "}") + """ + import static com.google.common.collect.ImmutableMap.toImmutableMap; + import static com.google.common.collect.ImmutableSet.toImmutableSet; + import static com.google.errorprone.BugPattern.LinkType.NONE; + import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION; + import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION; + import static java.nio.charset.StandardCharsets.UTF_8; + import static java.util.Collections.disjoint; + import static java.util.Collections.reverse; + import static java.util.Objects.requireNonNull; + import static java.util.function.Predicate.not; + import static java.util.regex.Pattern.CASE_INSENSITIVE; + import static org.junit.jupiter.params.provider.Arguments.arguments; + import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + import static org.springframework.format.annotation.DateTimeFormat.ISO.DATE; + import static org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME; + import static org.springframework.format.annotation.DateTimeFormat.ISO.TIME; + import static org.springframework.http.MediaType.APPLICATION_XHTML_XML; + import static org.springframework.http.MediaType.TEXT_HTML; + + import com.google.common.base.Predicates; + import com.google.common.collect.ImmutableMap; + import com.google.common.collect.ImmutableSet; + import com.google.errorprone.BugPattern; + import com.google.errorprone.BugPattern.SeverityLevel; + import java.nio.charset.StandardCharsets; + import java.util.ArrayList; + import java.util.Collections; + import java.util.Objects; + import java.util.regex.Pattern; + import org.junit.jupiter.params.provider.Arguments; + import org.springframework.boot.test.context.SpringBootTest; + import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + import org.springframework.format.annotation.DateTimeFormat; + import org.springframework.format.annotation.DateTimeFormat.ISO; + import org.springframework.http.MediaType; + + class A { + void m1() { + toImmutableMap(v -> v, v -> v); + ImmutableMap.toImmutableMap(v -> v, v -> v); + + toImmutableSet(); + ImmutableSet.toImmutableSet(); + + disjoint(ImmutableSet.of(), ImmutableSet.of()); + reverse(new ArrayList<>()); + + Predicates.not(null); + not(null); + + arguments("foo"); + + requireNonNull("bar"); + + Object o = UTF_8; + + ImmutableSet.of( + MediaType.ALL, APPLICATION_XHTML_XML, TEXT_HTML, MediaType.valueOf("image/webp")); + + Pattern.compile("", CASE_INSENSITIVE); + } + + void m2( + @DateTimeFormat(iso = DATE) String date, + @DateTimeFormat(iso = DATE_TIME) String dateTime, + @DateTimeFormat(iso = TIME) String time) {} + + void m3( + @DateTimeFormat(iso = DATE) String date, + @DateTimeFormat(iso = DATE_TIME) String dateTime, + @DateTimeFormat(iso = TIME) String time) {} + + @BugPattern(summary = "", linkType = NONE, severity = SUGGESTION, tags = SIMPLIFICATION) + static final class TestBugPattern {} + + @SpringBootTest(webEnvironment = RANDOM_PORT) + final class Test {} + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/StringJoinTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/StringJoinTest.java index 2dcd7ed5102..ff7ff5be1bf 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/StringJoinTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/StringJoinTest.java @@ -21,43 +21,45 @@ void identification() { compilationHelper .addSourceLines( "A.java", - "import java.util.Formattable;", - "import java.util.Locale;", - "", - "class A {", - " void m() {", - " String.join(\"-\", getClass().getName());", - " String.format(getClass().getName(), getClass().getName());", - " String.format(Locale.ROOT, \"%s\", getClass().getName());", - " String.format(\"%20s\", getClass().getName());", - " // BUG: Diagnostic matches: valueOf", - " String.format(\"%s\", getClass().getName());", - " // BUG: Diagnostic matches: valueOf", - " String.format(\"%s\", hashCode());", - " String.format(\"%s\", (Formattable) null);", - " String.format(\"-%s\", getClass().getName());", - " String.format(\"%s-\", getClass().getName());", - " String.format(\"-%s-\", getClass().getName());", - " // BUG: Diagnostic matches: join", - " String.format(\"%s%s\", getClass().getName(), getClass().getName());", - " // BUG: Diagnostic matches: join", - " String.format(\"%s%s\", getClass().getName(), hashCode());", - " // BUG: Diagnostic matches: join", - " String.format(\"%s%s\", hashCode(), getClass().getName());", - " String.format(\"%s%s\", getClass().getName(), (Formattable) null);", - " String.format(\"%s%s\", (Formattable) null, getClass().getName());", - " String.format(\"%s%s\", getClass().getName());", - " // BUG: Diagnostic matches: join", - " String.format(\"%s-%s\", getClass().getName(), getClass().getName());", - " // BUG: Diagnostic matches: join", - " String.format(\"%saa%s\", getClass().getName(), getClass().getName());", - " String.format(\"%s%%%s\", getClass().getName(), getClass().getName());", - " // BUG: Diagnostic matches: join", - " String.format(\"%s_%s_%s\", getClass().getName(), getClass().getName(), getClass().getName());", - " String.format(\"%s_%s_%s\", getClass().getName(), getClass().getName());", - " String.format(\"%s_%s-%s\", getClass().getName(), getClass().getName(), getClass().getName());", - " }", - "}") + """ + import java.util.Formattable; + import java.util.Locale; + + class A { + void m() { + String.join("-", getClass().getName()); + String.format(getClass().getName(), getClass().getName()); + String.format(Locale.ROOT, "%s", getClass().getName()); + String.format("%20s", getClass().getName()); + // BUG: Diagnostic matches: valueOf + String.format("%s", getClass().getName()); + // BUG: Diagnostic matches: valueOf + String.format("%s", hashCode()); + String.format("%s", (Formattable) null); + String.format("-%s", getClass().getName()); + String.format("%s-", getClass().getName()); + String.format("-%s-", getClass().getName()); + // BUG: Diagnostic matches: join + String.format("%s%s", getClass().getName(), getClass().getName()); + // BUG: Diagnostic matches: join + String.format("%s%s", getClass().getName(), hashCode()); + // BUG: Diagnostic matches: join + String.format("%s%s", hashCode(), getClass().getName()); + String.format("%s%s", getClass().getName(), (Formattable) null); + String.format("%s%s", (Formattable) null, getClass().getName()); + String.format("%s%s", getClass().getName()); + // BUG: Diagnostic matches: join + String.format("%s-%s", getClass().getName(), getClass().getName()); + // BUG: Diagnostic matches: join + String.format("%saa%s", getClass().getName(), getClass().getName()); + String.format("%s%%%s", getClass().getName(), getClass().getName()); + // BUG: Diagnostic matches: join + String.format("%s_%s_%s", getClass().getName(), getClass().getName(), getClass().getName()); + String.format("%s_%s_%s", getClass().getName(), getClass().getName()); + String.format("%s_%s-%s", getClass().getName(), getClass().getName(), getClass().getName()); + } + } + """) .doTest(); } @@ -66,32 +68,36 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "class A {", - " void m() {", - " String.format(\"%s\", getClass().getName());", - " String.format(\"%s%s\", getClass().getName(), getClass().getName());", - " String.format(\"%s%s\", getClass().getName(), hashCode());", - " String.format(\"%s%s\", hashCode(), getClass().getName());", - " String.format(\"%s-%s\", getClass().getName(), getClass().getName());", - " String.format(\"%saa%s\", getClass().getName(), getClass().getName());", - " String.format(\"%s\\\"%s\", getClass().getName(), getClass().getName());", - " String.format(\"%s_%s_%s\", getClass().getName(), getClass().getName(), getClass().getName());", - " }", - "}") + """ + class A { + void m() { + String.format("%s", getClass().getName()); + String.format("%s%s", getClass().getName(), getClass().getName()); + String.format("%s%s", getClass().getName(), hashCode()); + String.format("%s%s", hashCode(), getClass().getName()); + String.format("%s-%s", getClass().getName(), getClass().getName()); + String.format("%saa%s", getClass().getName(), getClass().getName()); + String.format("%s\\"%s", getClass().getName(), getClass().getName()); + String.format("%s_%s_%s", getClass().getName(), getClass().getName(), getClass().getName()); + } + } + """) .addOutputLines( "A.java", - "class A {", - " void m() {", - " String.valueOf(getClass().getName());", - " String.join(\"\", getClass().getName(), getClass().getName());", - " String.join(\"\", getClass().getName(), String.valueOf(hashCode()));", - " String.join(\"\", String.valueOf(hashCode()), getClass().getName());", - " String.join(\"-\", getClass().getName(), getClass().getName());", - " String.join(\"aa\", getClass().getName(), getClass().getName());", - " String.join(\"\\\"\", getClass().getName(), getClass().getName());", - " String.join(\"_\", getClass().getName(), getClass().getName(), getClass().getName());", - " }", - "}") + """ + class A { + void m() { + String.valueOf(getClass().getName()); + String.join("", getClass().getName(), getClass().getName()); + String.join("", getClass().getName(), String.valueOf(hashCode())); + String.join("", String.valueOf(hashCode()), getClass().getName()); + String.join("-", getClass().getName(), getClass().getName()); + String.join("aa", getClass().getName(), getClass().getName()); + String.join("\\"", getClass().getName(), getClass().getName()); + String.join("_", getClass().getName(), getClass().getName(), getClass().getName()); + } + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/TimeZoneUsageTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/TimeZoneUsageTest.java index ad4e8a8b07b..7b2ffdab6f8 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/TimeZoneUsageTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/TimeZoneUsageTest.java @@ -12,110 +12,112 @@ void identification() { compilationHelper .addSourceLines( "A.java", - "import static java.time.ZoneOffset.UTC;", - "", - "import java.time.Clock;", - "import java.time.Duration;", - "import java.time.Instant;", - "import java.time.LocalDate;", - "import java.time.LocalDateTime;", - "import java.time.LocalTime;", - "import java.time.OffsetDateTime;", - "import java.time.OffsetTime;", - "import java.time.ZoneId;", - "import java.time.ZonedDateTime;", - "", - "class A {", - " void m() {", - " Clock clock = Clock.fixed(Instant.EPOCH, UTC);", - " clock.instant();", - " clock.millis();", - " Clock.offset(clock, Duration.ZERO);", - " Clock.tick(clock, Duration.ZERO);", - "", - " // BUG: Diagnostic contains:", - " Clock.systemUTC();", - " // BUG: Diagnostic contains:", - " Clock.systemDefaultZone();", - " // BUG: Diagnostic contains:", - " Clock.system(UTC);", - " // BUG: Diagnostic contains:", - " Clock.tickMillis(UTC);", - " // BUG: Diagnostic contains:", - " Clock.tickMinutes(UTC);", - " // BUG: Diagnostic contains:", - " Clock.tickSeconds(UTC);", - " // BUG: Diagnostic contains:", - " clock.getZone();", - " // BUG: Diagnostic contains:", - " clock.withZone(UTC);", - "", - " // BUG: Diagnostic contains:", - " Instant.now();", - " // This is equivalent to `clock.instant()`, which is fine.", - " Instant.now(clock);", - "", - " // BUG: Diagnostic contains:", - " LocalDate.now();", - " // BUG: Diagnostic contains:", - " LocalDate.now(clock);", - " // BUG: Diagnostic contains:", - " LocalDate.now(UTC);", - "", - " // BUG: Diagnostic contains:", - " LocalDateTime.now();", - " // BUG: Diagnostic contains:", - " LocalDateTime.now(clock);", - " // BUG: Diagnostic contains:", - " LocalDateTime.now(UTC);", - "", - " // BUG: Diagnostic contains:", - " LocalTime.now();", - " // BUG: Diagnostic contains:", - " LocalTime.now(clock);", - " // BUG: Diagnostic contains:", - " LocalTime.now(UTC);", - "", - " // BUG: Diagnostic contains:", - " OffsetDateTime.now();", - " // BUG: Diagnostic contains:", - " OffsetDateTime.now(clock);", - " // BUG: Diagnostic contains:", - " OffsetDateTime.now(UTC);", - "", - " // BUG: Diagnostic contains:", - " OffsetTime.now();", - " // BUG: Diagnostic contains:", - " OffsetTime.now(clock);", - " // BUG: Diagnostic contains:", - " OffsetTime.now(UTC);", - "", - " // BUG: Diagnostic contains:", - " ZonedDateTime.now();", - " // BUG: Diagnostic contains:", - " ZonedDateTime.now(clock);", - " // BUG: Diagnostic contains:", - " ZonedDateTime.now(UTC);", - " }", - "", - " abstract class ForwardingClock extends Clock {", - " private final Clock clock;", - "", - " ForwardingClock(Clock clock) {", - " this.clock = clock;", - " }", - "", - " @Override", - " public ZoneId getZone() {", - " return clock.getZone();", - " }", - "", - " @Override", - " public Clock withZone(ZoneId zone) {", - " return clock.withZone(zone);", - " }", - " }", - "}") + """ + import static java.time.ZoneOffset.UTC; + + import java.time.Clock; + import java.time.Duration; + import java.time.Instant; + import java.time.LocalDate; + import java.time.LocalDateTime; + import java.time.LocalTime; + import java.time.OffsetDateTime; + import java.time.OffsetTime; + import java.time.ZoneId; + import java.time.ZonedDateTime; + + class A { + void m() { + Clock clock = Clock.fixed(Instant.EPOCH, UTC); + clock.instant(); + clock.millis(); + Clock.offset(clock, Duration.ZERO); + Clock.tick(clock, Duration.ZERO); + + // BUG: Diagnostic contains: + Clock.systemUTC(); + // BUG: Diagnostic contains: + Clock.systemDefaultZone(); + // BUG: Diagnostic contains: + Clock.system(UTC); + // BUG: Diagnostic contains: + Clock.tickMillis(UTC); + // BUG: Diagnostic contains: + Clock.tickMinutes(UTC); + // BUG: Diagnostic contains: + Clock.tickSeconds(UTC); + // BUG: Diagnostic contains: + clock.getZone(); + // BUG: Diagnostic contains: + clock.withZone(UTC); + + // BUG: Diagnostic contains: + Instant.now(); + // This is equivalent to `clock.instant()`, which is fine. + Instant.now(clock); + + // BUG: Diagnostic contains: + LocalDate.now(); + // BUG: Diagnostic contains: + LocalDate.now(clock); + // BUG: Diagnostic contains: + LocalDate.now(UTC); + + // BUG: Diagnostic contains: + LocalDateTime.now(); + // BUG: Diagnostic contains: + LocalDateTime.now(clock); + // BUG: Diagnostic contains: + LocalDateTime.now(UTC); + + // BUG: Diagnostic contains: + LocalTime.now(); + // BUG: Diagnostic contains: + LocalTime.now(clock); + // BUG: Diagnostic contains: + LocalTime.now(UTC); + + // BUG: Diagnostic contains: + OffsetDateTime.now(); + // BUG: Diagnostic contains: + OffsetDateTime.now(clock); + // BUG: Diagnostic contains: + OffsetDateTime.now(UTC); + + // BUG: Diagnostic contains: + OffsetTime.now(); + // BUG: Diagnostic contains: + OffsetTime.now(clock); + // BUG: Diagnostic contains: + OffsetTime.now(UTC); + + // BUG: Diagnostic contains: + ZonedDateTime.now(); + // BUG: Diagnostic contains: + ZonedDateTime.now(clock); + // BUG: Diagnostic contains: + ZonedDateTime.now(UTC); + } + + abstract class ForwardingClock extends Clock { + private final Clock clock; + + ForwardingClock(Clock clock) { + this.clock = clock; + } + + @Override + public ZoneId getZone() { + return clock.getZone(); + } + + @Override + public Clock withZone(ZoneId zone) { + return clock.withZone(zone); + } + } + } + """) .doTest(); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MethodMatcherFactoryTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MethodMatcherFactoryTest.java index 782b5f77c9b..6e39ea74d1d 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MethodMatcherFactoryTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MethodMatcherFactoryTest.java @@ -61,153 +61,165 @@ void matcher() { compilationTestHelper .addSourceLines( "com/example/A.java", - "package com.example;", - "", - "public class A {", - " public void m1() {}", - "", - " public void m1(String s) {}", - "", - " public void m1(int i, int j) {}", - "", - " public void m2() {}", - "", - " public void m2(String s) {}", - "", - " public void m2(int i, int j) {}", - "", - " public void m3() {}", - "", - " public void m3(String s) {}", - "", - " public void m3(int i, int j) {}", - "}") + """ + package com.example; + + public class A { + public void m1() {} + + public void m1(String s) {} + + public void m1(int i, int j) {} + + public void m2() {} + + public void m2(String s) {} + + public void m2(int i, int j) {} + + public void m3() {} + + public void m3(String s) {} + + public void m3(int i, int j) {} + } + """) .addSourceLines( "com/example/B.java", - "package com.example;", - "", - "public class B {", - " public void m1() {}", - "", - " public void m1(String s) {}", - "", - " public void m1(int i, int j) {}", - "", - " public void m2() {}", - "", - " public void m2(String s) {}", - "", - " public void m2(int i, int j) {}", - "", - " public void m3() {}", - "", - " public void m3(String s) {}", - "", - " public void m3(int i, int j) {}", - "}") + """ + package com.example; + + public class B { + public void m1() {} + + public void m1(String s) {} + + public void m1(int i, int j) {} + + public void m2() {} + + public void m2(String s) {} + + public void m2(int i, int j) {} + + public void m3() {} + + public void m3(String s) {} + + public void m3(int i, int j) {} + } + """) .addSourceLines( "com/example/sub/A.java", - "package com.example.sub;", - "", - "public class A {", - " public static void m1() {}", - "", - " public static void m1(String s) {}", - "", - " public static void m1(int i, int j) {}", - "", - " public static void m2() {}", - "", - " public static void m2(String s) {}", - "", - " public static void m2(int i, int j) {}", - "", - " public static void m3() {}", - "", - " public static void m3(String s) {}", - "", - " public static void m3(int i, int j) {}", - "}") + """ + package com.example.sub; + + public class A { + public static void m1() {} + + public static void m1(String s) {} + + public static void m1(int i, int j) {} + + public static void m2() {} + + public static void m2(String s) {} + + public static void m2(int i, int j) {} + + public static void m3() {} + + public static void m3(String s) {} + + public static void m3(int i, int j) {} + } + """) .addSourceLines( "com/example/sub/B.java", - "package com.example.sub;", - "", - "public class B {", - " public static void m1() {}", - "", - " public static void m1(String s) {}", - "", - " public static void m1(int i, int j) {}", - "", - " public static void m2() {}", - "", - " public static void m2(String s) {}", - "", - " public static void m2(int i, int j) {}", - "", - " public static void m3() {}", - "", - " public static void m3(String s) {}", - "", - " public static void m3(int i, int j) {}", - "}") + """ + package com.example.sub; + + public class B { + public static void m1() {} + + public static void m1(String s) {} + + public static void m1(int i, int j) {} + + public static void m2() {} + + public static void m2(String s) {} + + public static void m2(int i, int j) {} + + public static void m3() {} + + public static void m3(String s) {} + + public static void m3(int i, int j) {} + } + """) .addSourceLines( "External.java", - "import com.example.A;", - "import com.example.sub.B;", - "", - "public class External {", - " void invocations() {", - " // BUG: Diagnostic contains:", - " new A().m1();", - " new A().m1(\"\");", - " new A().m1(0, 0);", - " new A().m2();", - " // BUG: Diagnostic contains:", - " new A().m2(\"\");", - " new A().m2(0, 0);", - " new A().m3();", - " new A().m3(\"\");", - " new A().m3(0, 0);", - " B.m1();", - " B.m1(\"\");", - " B.m1(0, 0);", - " B.m2();", - " B.m2(\"\");", - " B.m2(0, 0);", - " B.m3();", - " B.m3(\"\");", - " // BUG: Diagnostic contains:", - " B.m3(0, 0);", - " }", - "}") + """ + import com.example.A; + import com.example.sub.B; + + public class External { + void invocations() { + // BUG: Diagnostic contains: + new A().m1(); + new A().m1(""); + new A().m1(0, 0); + new A().m2(); + // BUG: Diagnostic contains: + new A().m2(""); + new A().m2(0, 0); + new A().m3(); + new A().m3(""); + new A().m3(0, 0); + B.m1(); + B.m1(""); + B.m1(0, 0); + B.m2(); + B.m2(""); + B.m2(0, 0); + B.m3(); + B.m3(""); + // BUG: Diagnostic contains: + B.m3(0, 0); + } + } + """) .addSourceLines( "ExternalWithDifferentPackages.java", - "import com.example.B;", - "import com.example.sub.A;", - "", - "public class ExternalWithDifferentPackages {", - " void invocations() {", - " A.m1();", - " A.m1(\"\");", - " A.m1(0, 0);", - " A.m2();", - " A.m2(\"\");", - " A.m2(0, 0);", - " A.m3();", - " A.m3(\"\");", - " A.m3(0, 0);", - " new B().m1();", - " new B().m1(\"\");", - " new B().m1(0, 0);", - " new B().m2();", - " new B().m2(\"\");", - " new B().m2(0, 0);", - " new B().m3();", - " new B().m3(\"\");", - " new B().m3(0, 0);", - " }", - "}") + """ + import com.example.B; + import com.example.sub.A; + + public class ExternalWithDifferentPackages { + void invocations() { + A.m1(); + A.m1(""); + A.m1(0, 0); + A.m2(); + A.m2(""); + A.m2(0, 0); + A.m3(); + A.m3(""); + A.m3(0, 0); + new B().m1(); + new B().m1(""); + new B().m1(0, 0); + new B().m2(); + new B().m2(""); + new B().m2(0, 0); + new B().m3(); + new B().m3(""); + new B().m3(0, 0); + } + } + """) .doTest(); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MoreTypesTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MoreTypesTest.java index 48d003fa205..a6a34b18a5d 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MoreTypesTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MoreTypesTest.java @@ -70,91 +70,93 @@ void matcher() { CompilationTestHelper.newInstance(SubtypeFlagger.class, getClass()) .addSourceLines( "/A.java", - "import java.util.Collection;", - "import java.util.List;", - "import java.util.Map;", - "import java.util.Optional;", - "import java.util.Set;", - "", - "class A {", - " void m() {", - " Object object = factory();", - " A a = factory();", - "", - " // BUG: Diagnostic contains: [Number, ? super Number, Integer, ? super Integer]", - " int integer = factory();", - "", - " // BUG: Diagnostic contains: [String]", - " String string = factory();", - "", - " // BUG: Diagnostic contains: [Optional]", - " Optional rawOptional = factory();", - " // BUG: Diagnostic contains: [Optional, Optional]", - " Optional optionalOfS = factory();", - " // BUG: Diagnostic contains: [Optional, Optional]", - " Optional optionalOfT = factory();", - " // BUG: Diagnostic contains: [Optional, Optional, Optional]", - " Optional optionalOfNumber = factory();", - " // BUG: Diagnostic contains: [Optional, Optional]", - " Optional optionalOfInteger = factory();", - "", - " // BUG: Diagnostic contains: [Collection]", - " Collection rawCollection = factory();", - " // BUG: Diagnostic contains: [Collection, Collection, Collection, Collection, Collection, Collection]", - " Collection collectionOfNumber = factory();", - " // BUG: Diagnostic contains: [Collection, Collection, Collection,", - " // Collection, Collection, Collection]", - " Collection collectionOfInteger = factory();", - " // BUG: Diagnostic contains: [Collection, Collection, Collection]", - " Collection collectionOfShort = factory();", - "", - " // BUG: Diagnostic contains: [Collection, List]", - " List rawList = factory();", - " // BUG: Diagnostic contains: [Collection, Collection, Collection, Collection, Collection, Collection, List, List,", - " // List, List, List, List]", - " List listOfNumber = factory();", - " // BUG: Diagnostic contains: [Collection, Collection, Collection,", - " // Collection, Collection, Collection, List,", - " // List, List, List, List, List]", - " List listOfInteger = factory();", - " // BUG: Diagnostic contains: [Collection, Collection, Collection, List,", - " // List, List]", - " List listOfShort = factory();", - "", - " // BUG: Diagnostic contains: [Collection]", - " Set rawSet = factory();", - " // BUG: Diagnostic contains: [Collection, Collection, Collection, Collection, Collection, Collection]", - " Set setOfNumber = factory();", - " // BUG: Diagnostic contains: [Collection, Collection, Collection,", - " // Collection, Collection, Collection]", - " Set setOfInteger = factory();", - " // BUG: Diagnostic contains: [Collection, Collection, Collection]", - " Set setOfShort = factory();", - "", - " Map rawMap = factory();", - " Map> mapFromNumberToCollectionOfNumber = factory();", - " Map> mapFromNumberToCollectionOfShort = factory();", - " Map> mapFromNumberToCollectionOfInteger = factory();", - " // BUG: Diagnostic contains: [Map>]", - " Map> mapFromStringToCollectionOfNumber = factory();", - " // BUG: Diagnostic contains: [Map>]", - " Map> mapFromStringToCollectionOfShort = factory();", - " Map> mapFromStringToCollectionOfInteger = factory();", - " // BUG: Diagnostic contains: [Map>]", - " Map> mapFromStringToListOfNumber = factory();", - " // BUG: Diagnostic contains: [Map>]", - " Map> mapFromStringToListOfShort = factory();", - " Map> mapFromStringToListOfInteger = factory();", - " }", - "", - " private T factory() {", - " return null;", - " }", - "}") + """ + import java.util.Collection; + import java.util.List; + import java.util.Map; + import java.util.Optional; + import java.util.Set; + + class A { + void m() { + Object object = factory(); + A a = factory(); + + // BUG: Diagnostic contains: [Number, ? super Number, Integer, ? super Integer] + int integer = factory(); + + // BUG: Diagnostic contains: [String] + String string = factory(); + + // BUG: Diagnostic contains: [Optional] + Optional rawOptional = factory(); + // BUG: Diagnostic contains: [Optional, Optional] + Optional optionalOfS = factory(); + // BUG: Diagnostic contains: [Optional, Optional] + Optional optionalOfT = factory(); + // BUG: Diagnostic contains: [Optional, Optional, Optional] + Optional optionalOfNumber = factory(); + // BUG: Diagnostic contains: [Optional, Optional] + Optional optionalOfInteger = factory(); + + // BUG: Diagnostic contains: [Collection] + Collection rawCollection = factory(); + // BUG: Diagnostic contains: [Collection, Collection, Collection, Collection, Collection, Collection] + Collection collectionOfNumber = factory(); + // BUG: Diagnostic contains: [Collection, Collection, Collection, + // Collection, Collection, Collection] + Collection collectionOfInteger = factory(); + // BUG: Diagnostic contains: [Collection, Collection, Collection] + Collection collectionOfShort = factory(); + + // BUG: Diagnostic contains: [Collection, List] + List rawList = factory(); + // BUG: Diagnostic contains: [Collection, Collection, Collection, Collection, Collection, Collection, List, List, + // List, List, List, List] + List listOfNumber = factory(); + // BUG: Diagnostic contains: [Collection, Collection, Collection, + // Collection, Collection, Collection, List, + // List, List, List, List, List] + List listOfInteger = factory(); + // BUG: Diagnostic contains: [Collection, Collection, Collection, List, + // List, List] + List listOfShort = factory(); + + // BUG: Diagnostic contains: [Collection] + Set rawSet = factory(); + // BUG: Diagnostic contains: [Collection, Collection, Collection, Collection, Collection, Collection] + Set setOfNumber = factory(); + // BUG: Diagnostic contains: [Collection, Collection, Collection, + // Collection, Collection, Collection] + Set setOfInteger = factory(); + // BUG: Diagnostic contains: [Collection, Collection, Collection] + Set setOfShort = factory(); + + Map rawMap = factory(); + Map> mapFromNumberToCollectionOfNumber = factory(); + Map> mapFromNumberToCollectionOfShort = factory(); + Map> mapFromNumberToCollectionOfInteger = factory(); + // BUG: Diagnostic contains: [Map>] + Map> mapFromStringToCollectionOfNumber = factory(); + // BUG: Diagnostic contains: [Map>] + Map> mapFromStringToCollectionOfShort = factory(); + Map> mapFromStringToCollectionOfInteger = factory(); + // BUG: Diagnostic contains: [Map>] + Map> mapFromStringToListOfNumber = factory(); + // BUG: Diagnostic contains: [Map>] + Map> mapFromStringToListOfShort = factory(); + Map> mapFromStringToListOfInteger = factory(); + } + + private T factory() { + return null; + } + } + """) .doTest(); } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/ThirdPartyLibraryTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/ThirdPartyLibraryTest.java index 8d888851288..789a80cd2fe 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/ThirdPartyLibraryTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/ThirdPartyLibraryTest.java @@ -26,8 +26,10 @@ void isIntroductionAllowed() { compilationTestHelper .addSourceLines( "A.java", - "// BUG: Diagnostic contains: ASSERTJ: true, GUAVA: true, NEW_RELIC_AGENT_API: true, REACTOR: true", - "class A {}") + """ + // BUG: Diagnostic contains: ASSERTJ: true, GUAVA: true, NEW_RELIC_AGENT_API: true, REACTOR: true + class A {} + """) .doTest(); } @@ -36,20 +38,22 @@ void isIntroductionAllowedWitnessClassesInSymtab() { compilationTestHelper .addSourceLines( "A.java", - "import com.google.common.collect.ImmutableList;", - "import com.newrelic.api.agent.Agent;", - "import org.assertj.core.api.Assertions;", - "import reactor.core.publisher.Flux;", - "", - "// BUG: Diagnostic contains: ASSERTJ: true, GUAVA: true, NEW_RELIC_AGENT_API: true, REACTOR: true", - "class A {", - " void m(Class clazz) {", - " m(Assertions.class);", - " m(ImmutableList.class);", - " m(Agent.class);", - " m(Flux.class);", - " }", - "}") + """ + import com.google.common.collect.ImmutableList; + import com.newrelic.api.agent.Agent; + import org.assertj.core.api.Assertions; + import reactor.core.publisher.Flux; + + // BUG: Diagnostic contains: ASSERTJ: true, GUAVA: true, NEW_RELIC_AGENT_API: true, REACTOR: true + class A { + void m(Class clazz) { + m(Assertions.class); + m(ImmutableList.class); + m(Agent.class); + m(Flux.class); + } + } + """) .doTest(); } @@ -59,8 +63,10 @@ void isIntroductionAllowedWitnessClassesPartiallyOnClassPath() { .withClasspath(ImmutableList.class, Flux.class) .addSourceLines( "A.java", - "// BUG: Diagnostic contains: ASSERTJ: false, GUAVA: true, NEW_RELIC_AGENT_API: false, REACTOR: true", - "class A {}") + """ + // BUG: Diagnostic contains: ASSERTJ: false, GUAVA: true, NEW_RELIC_AGENT_API: false, REACTOR: true + class A {} + """) .doTest(); } @@ -70,9 +76,11 @@ void isIntroductionAllowedWitnessClassesNotOnClassPath() { .withClasspath() .addSourceLines( "A.java", - "// BUG: Diagnostic contains: ASSERTJ: false, GUAVA: false, NEW_RELIC_AGENT_API: false, REACTOR:", - "// false", - "class A {}") + """ + // BUG: Diagnostic contains: ASSERTJ: false, GUAVA: false, NEW_RELIC_AGENT_API: false, REACTOR: + // false + class A {} + """) .doTest(); } diff --git a/refaster-runner/src/test/java/tech/picnic/errorprone/refaster/runner/RefasterTest.java b/refaster-runner/src/test/java/tech/picnic/errorprone/refaster/runner/RefasterTest.java index 8ec4e5122ce..c7ace7c31ab 100644 --- a/refaster-runner/src/test/java/tech/picnic/errorprone/refaster/runner/RefasterTest.java +++ b/refaster-runner/src/test/java/tech/picnic/errorprone/refaster/runner/RefasterTest.java @@ -62,18 +62,20 @@ void identification() { compilationHelper .addSourceLines( "A.java", - "class A {", - " void m() {", - " // BUG: Diagnostic matches: StringOfSizeZeroRule", - " boolean b1 = \"foo\".toCharArray().length == 0;", - " // BUG: Diagnostic matches: StringOfSizeOneRule", - " boolean b2 = \"bar\".toCharArray().length == 1;", - " // BUG: Diagnostic matches: StringOfSizeTwoRule", - " boolean b3 = \"baz\".toCharArray().length == 2;", - " // BUG: Diagnostic matches: StringOfSizeThreeRule", - " boolean b4 = \"qux\".toCharArray().length == 3;", - " }", - "}") + """ + class A { + void m() { + // BUG: Diagnostic matches: StringOfSizeZeroRule + boolean b1 = "foo".toCharArray().length == 0; + // BUG: Diagnostic matches: StringOfSizeOneRule + boolean b2 = "bar".toCharArray().length == 1; + // BUG: Diagnostic matches: StringOfSizeTwoRule + boolean b3 = "baz".toCharArray().length == 2; + // BUG: Diagnostic matches: StringOfSizeThreeRule + boolean b4 = "qux".toCharArray().length == 3; + } + } + """) .doTest(); } @@ -173,16 +175,18 @@ void severityAssignment( .setArgs(arguments) .addSourceLines( "A.java", - "class A {", - " void m() {", - " boolean[] bs = {", - " \"foo\".toCharArray().length == 0,", - " \"bar\".toCharArray().length == 1,", - " \"baz\".toCharArray().length == 2,", - " \"qux\".toCharArray().length == 3", - " };", - " }", - "}") + """ + class A { + void m() { + boolean[] bs = { + "foo".toCharArray().length == 0, + "bar".toCharArray().length == 1, + "baz".toCharArray().length == 2, + "qux".toCharArray().length == 3 + }; + } + } + """) .doTest()) .isInstanceOf(AssertionError.class) .message() @@ -223,24 +227,28 @@ void replacement() { refactoringTestHelper .addInputLines( "A.java", - "class A {", - " void m() {", - " boolean b1 = \"foo\".toCharArray().length == 0;", - " boolean b2 = \"bar\".toCharArray().length == 1;", - " boolean b3 = \"baz\".toCharArray().length == 2;", - " boolean b4 = \"qux\".toCharArray().length == 3;", - " }", - "}") + """ + class A { + void m() { + boolean b1 = "foo".toCharArray().length == 0; + boolean b2 = "bar".toCharArray().length == 1; + boolean b3 = "baz".toCharArray().length == 2; + boolean b4 = "qux".toCharArray().length == 3; + } + } + """) .addOutputLines( "A.java", - "class A {", - " void m() {", - " boolean b1 = \"foo\".isEmpty();", - " boolean b2 = \"bar\".length() == 1;", - " boolean b3 = \"baz\".length() == 2;", - " boolean b4 = \"qux\".length() == 3;", - " }", - "}") + """ + class A { + void m() { + boolean b1 = "foo".isEmpty(); + boolean b2 = "bar".length() == 1; + boolean b3 = "baz".length() == 2; + boolean b4 = "qux".length() == 3; + } + } + """) .doTest(TestMode.TEXT_MATCH); } @@ -249,24 +257,28 @@ void restrictedReplacement() { restrictedRefactoringTestHelper .addInputLines( "A.java", - "class A {", - " void m() {", - " boolean b1 = \"foo\".toCharArray().length == 0;", - " boolean b2 = \"bar\".toCharArray().length == 1;", - " boolean b3 = \"baz\".toCharArray().length == 2;", - " boolean b4 = \"qux\".toCharArray().length == 3;", - " }", - "}") + """ + class A { + void m() { + boolean b1 = "foo".toCharArray().length == 0; + boolean b2 = "bar".toCharArray().length == 1; + boolean b3 = "baz".toCharArray().length == 2; + boolean b4 = "qux".toCharArray().length == 3; + } + } + """) .addOutputLines( "A.java", - "class A {", - " void m() {", - " boolean b1 = \"foo\".length() + 1 == 1;", - " boolean b2 = \"bar\".toCharArray().length == 1;", - " boolean b3 = \"baz\".length() == 2;", - " boolean b4 = \"qux\".toCharArray().length == 3;", - " }", - "}") + """ + class A { + void m() { + boolean b1 = "foo".length() + 1 == 1; + boolean b2 = "bar".toCharArray().length == 1; + boolean b3 = "baz".length() == 2; + boolean b4 = "qux".toCharArray().length == 3; + } + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/refaster-support/src/test/java/tech/picnic/errorprone/refaster/ErrorProneForkTest.java b/refaster-support/src/test/java/tech/picnic/errorprone/refaster/ErrorProneForkTest.java index 06b11b85012..a2b3be8f9aa 100644 --- a/refaster-support/src/test/java/tech/picnic/errorprone/refaster/ErrorProneForkTest.java +++ b/refaster-support/src/test/java/tech/picnic/errorprone/refaster/ErrorProneForkTest.java @@ -26,8 +26,10 @@ void isSuggestionsAsWarningsEnabledWithoutFlag() { CompilationTestHelper.newInstance(TestChecker.class, getClass()) .addSourceLines( "A.java", - "// BUG: Diagnostic contains: Suggestions as warnings enabled: false", - "class A {}") + """ + // BUG: Diagnostic contains: Suggestions as warnings enabled: false + class A {} + """) .doTest(); } @@ -41,8 +43,10 @@ void isSuggestionsAsWarningsEnabledWithFlag() { .setArgs("-XepAllSuggestionsAsWarnings") .addSourceLines( "A.java", - "// BUG: Diagnostic contains: Suggestions as warnings enabled: true", - "class A {}") + """ + // BUG: Diagnostic contains: Suggestions as warnings enabled: true + class A {} + """) .doTest(); } diff --git a/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsArrayTest.java b/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsArrayTest.java index c2840d414a1..95e9c7d7627 100644 --- a/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsArrayTest.java +++ b/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsArrayTest.java @@ -13,38 +13,40 @@ void matches() { CompilationTestHelper.newInstance(MatcherTestChecker.class, getClass()) .addSourceLines( "A.java", - "class A {", - " Object negative1() {", - " return alwaysNull();", - " }", - "", - " String negative2() {", - " return alwaysNull();", - " }", - "", - " int negative3() {", - " return alwaysNull();", - " }", - "", - " Object[] positive1() {", - " // BUG: Diagnostic contains:", - " return alwaysNull();", - " }", - "", - " String[] positive2() {", - " // BUG: Diagnostic contains:", - " return alwaysNull();", - " }", - "", - " int[] positive3() {", - " // BUG: Diagnostic contains:", - " return alwaysNull();", - " }", - "", - " private static T alwaysNull() {", - " return null;", - " }", - "}") + """ + class A { + Object negative1() { + return alwaysNull(); + } + + String negative2() { + return alwaysNull(); + } + + int negative3() { + return alwaysNull(); + } + + Object[] positive1() { + // BUG: Diagnostic contains: + return alwaysNull(); + } + + String[] positive2() { + // BUG: Diagnostic contains: + return alwaysNull(); + } + + int[] positive3() { + // BUG: Diagnostic contains: + return alwaysNull(); + } + + private static T alwaysNull() { + return null; + } + } + """) .doTest(); } diff --git a/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsCharacterTest.java b/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsCharacterTest.java index 7f4ddc2fe19..30d150caf67 100644 --- a/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsCharacterTest.java +++ b/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsCharacterTest.java @@ -13,38 +13,40 @@ void matches() { CompilationTestHelper.newInstance(MatcherTestChecker.class, getClass()) .addSourceLines( "A.java", - "class A {", - " String negative1() {", - " return \"a\";", - " }", - "", - " char[] negative2() {", - " return \"a\".toCharArray();", - " }", - "", - " byte negative3() {", - " return (byte) 0;", - " }", - "", - " int negative4() {", - " return 0;", - " }", - "", - " char positive1() {", - " // BUG: Diagnostic contains:", - " return 'a';", - " }", - "", - " Character positive2() {", - " // BUG: Diagnostic contains:", - " return (Character) null;", - " }", - "", - " char positive3() {", - " // BUG: Diagnostic contains:", - " return (char) 1;", - " }", - "}") + """ + class A { + String negative1() { + return "a"; + } + + char[] negative2() { + return "a".toCharArray(); + } + + byte negative3() { + return (byte) 0; + } + + int negative4() { + return 0; + } + + char positive1() { + // BUG: Diagnostic contains: + return 'a'; + } + + Character positive2() { + // BUG: Diagnostic contains: + return (Character) null; + } + + char positive3() { + // BUG: Diagnostic contains: + return (char) 1; + } + } + """) .doTest(); } diff --git a/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/ThrowsCheckedExceptionTest.java b/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/ThrowsCheckedExceptionTest.java index 4281ba42c00..6a4cecd1cbd 100644 --- a/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/ThrowsCheckedExceptionTest.java +++ b/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/ThrowsCheckedExceptionTest.java @@ -13,69 +13,71 @@ void matches() { CompilationTestHelper.newInstance(MatcherTestChecker.class, getClass()) .addSourceLines( "A.java", - "import java.util.concurrent.Callable;", - "import java.util.function.Supplier;", - "", - "class A {", - " void negative1() {", - " callableSink(null);", - " }", - "", - " void negative2() {", - " supplierSink(null);", - " }", - "", - " void negative3() {", - " callableSink(() -> toString());", - " }", - "", - " void negative4() {", - " supplierSink(() -> toString());", - " }", - "", - " void negative5() {", - " callableSink(this::toString);", - " }", - "", - " void negative6() {", - " supplierSink(this::toString);", - " }", - "", - " void negative7() {", - " supplierSink(", - " new Supplier<>() {", - " @Override", - " public Object get() {", - " return getClass();", - " }", - " });", - " }", - "", - " void positive1() {", - " // BUG: Diagnostic contains:", - " callableSink(() -> getClass().getDeclaredConstructor());", - " }", - "", - " void positive2() {", - " // BUG: Diagnostic contains:", - " callableSink(getClass()::getDeclaredConstructor);", - " }", - "", - " void positive3() {", - " callableSink(", - " // BUG: Diagnostic contains:", - " new Callable<>() {", - " @Override", - " public Object call() throws NoSuchMethodException {", - " return getClass().getDeclaredConstructor();", - " }", - " });", - " }", - "", - " private static void callableSink(Callable callable) {}", - "", - " private static void supplierSink(Supplier supplier) {}", - "}") + """ + import java.util.concurrent.Callable; + import java.util.function.Supplier; + + class A { + void negative1() { + callableSink(null); + } + + void negative2() { + supplierSink(null); + } + + void negative3() { + callableSink(() -> toString()); + } + + void negative4() { + supplierSink(() -> toString()); + } + + void negative5() { + callableSink(this::toString); + } + + void negative6() { + supplierSink(this::toString); + } + + void negative7() { + supplierSink( + new Supplier<>() { + @Override + public Object get() { + return getClass(); + } + }); + } + + void positive1() { + // BUG: Diagnostic contains: + callableSink(() -> getClass().getDeclaredConstructor()); + } + + void positive2() { + // BUG: Diagnostic contains: + callableSink(getClass()::getDeclaredConstructor); + } + + void positive3() { + callableSink( + // BUG: Diagnostic contains: + new Callable<>() { + @Override + public Object call() throws NoSuchMethodException { + return getClass().getDeclaredConstructor(); + } + }); + } + + private static void callableSink(Callable callable) {} + + private static void supplierSink(Supplier supplier) {} + } + """) .doTest(); }