diff --git a/documentation-support/src/test/java/tech/picnic/errorprone/documentation/BugPatternExtractorTest.java b/documentation-support/src/test/java/tech/picnic/errorprone/documentation/BugPatternExtractorTest.java index f74b0326016..8f3c8fdc4fc 100644 --- a/documentation-support/src/test/java/tech/picnic/errorprone/documentation/BugPatternExtractorTest.java +++ b/documentation-support/src/test/java/tech/picnic/errorprone/documentation/BugPatternExtractorTest.java @@ -13,9 +13,11 @@ void noBugPattern(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "TestCheckerWithoutAnnotation.java", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "public final class TestCheckerWithoutAnnotation extends BugChecker {}"); + """ + import com.google.errorprone.bugpatterns.BugChecker; + + public final class TestCheckerWithoutAnnotation extends BugChecker {} + """); assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory(); } @@ -25,14 +27,16 @@ void minimalBugPattern(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "MinimalBugChecker.java", - "package pkg;", - "", - "import com.google.errorprone.BugPattern;", - "import com.google.errorprone.BugPattern.SeverityLevel;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "@BugPattern(summary = \"MinimalBugChecker summary\", severity = SeverityLevel.ERROR)", - "public final class MinimalBugChecker extends BugChecker {}"); + """ + package pkg; + + import com.google.errorprone.BugPattern; + import com.google.errorprone.BugPattern.SeverityLevel; + import com.google.errorprone.bugpatterns.BugChecker; + + @BugPattern(summary = "MinimalBugChecker summary", severity = SeverityLevel.ERROR) + public final class MinimalBugChecker extends BugChecker {} + """); verifyGeneratedFileContent( outputDirectory, @@ -60,25 +64,27 @@ void completeBugPattern(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "CompleteBugChecker.java", - "package pkg;", - "", - "import com.google.errorprone.BugPattern;", - "import com.google.errorprone.BugPattern.SeverityLevel;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "import org.junit.jupiter.api.Test;", - "", - "@BugPattern(", - " name = \"OtherName\",", - " summary = \"CompleteBugChecker summary\",", - " linkType = BugPattern.LinkType.CUSTOM,", - " link = \"https://error-prone.picnic.tech\",", - " explanation = \"Example explanation\",", - " severity = SeverityLevel.SUGGESTION,", - " altNames = \"Check\",", - " tags = BugPattern.StandardTags.SIMPLIFICATION,", - " disableable = false,", - " suppressionAnnotations = {BugPattern.class, Test.class})", - "public final class CompleteBugChecker extends BugChecker {}"); + """ + package pkg; + + import com.google.errorprone.BugPattern; + import com.google.errorprone.BugPattern.SeverityLevel; + import com.google.errorprone.bugpatterns.BugChecker; + import org.junit.jupiter.api.Test; + + @BugPattern( + name = "OtherName", + summary = "CompleteBugChecker summary", + linkType = BugPattern.LinkType.CUSTOM, + link = "https://error-prone.picnic.tech", + explanation = "Example explanation", + severity = SeverityLevel.SUGGESTION, + altNames = "Check", + tags = BugPattern.StandardTags.SIMPLIFICATION, + disableable = false, + suppressionAnnotations = {BugPattern.class, Test.class}) + public final class CompleteBugChecker extends BugChecker {} + """); verifyGeneratedFileContent( outputDirectory, @@ -111,17 +117,19 @@ void undocumentedSuppressionBugPattern(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "UndocumentedSuppressionBugPattern.java", - "package pkg;", - "", - "import com.google.errorprone.BugPattern;", - "import com.google.errorprone.BugPattern.SeverityLevel;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "@BugPattern(", - " summary = \"UndocumentedSuppressionBugPattern summary\",", - " severity = SeverityLevel.WARNING,", - " documentSuppression = false)", - "public final class UndocumentedSuppressionBugPattern extends BugChecker {}"); + """ + package pkg; + + import com.google.errorprone.BugPattern; + import com.google.errorprone.BugPattern.SeverityLevel; + import com.google.errorprone.bugpatterns.BugChecker; + + @BugPattern( + summary = "UndocumentedSuppressionBugPattern summary", + severity = SeverityLevel.WARNING, + documentSuppression = false) + public final class UndocumentedSuppressionBugPattern extends BugChecker {} + """); verifyGeneratedFileContent( outputDirectory, diff --git a/documentation-support/src/test/java/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest.java b/documentation-support/src/test/java/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest.java index ecd6d2032ca..94a25c6ce20 100644 --- a/documentation-support/src/test/java/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest.java +++ b/documentation-support/src/test/java/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest.java @@ -15,9 +15,11 @@ void noTestClass(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "TestCheckerWithoutAnnotation.java", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "public final class TestCheckerWithoutAnnotation extends BugChecker {}"); + """ + import com.google.errorprone.bugpatterns.BugChecker; + + public final class TestCheckerWithoutAnnotation extends BugChecker {} + """); assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory(); } @@ -27,22 +29,24 @@ void noDoTestInvocation(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "TestCheckerTest.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.CompilationTestHelper;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "final class TestCheckerTest {", - " private static class TestChecker extends BugChecker {}", - "", - " void m() {", - " CompilationTestHelper.newInstance(TestChecker.class, getClass())", - " .addSourceLines(\"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\");", - "", - " BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())", - " .addInputLines(\"A.java\", \"class A {}\")", - " .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\");", - " }", - "}"); + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.CompilationTestHelper; + import com.google.errorprone.bugpatterns.BugChecker; + + final class TestCheckerTest { + private static class TestChecker extends BugChecker {} + + void m() { + CompilationTestHelper.newInstance(TestChecker.class, getClass()) + .addSourceLines("A.java", "// BUG: Diagnostic contains:", "class A {}"); + + BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass()) + .addInputLines("A.java", "class A {}") + .addOutputLines("A.java", "class A { /* This is a change. */ }"); + } + } + """); assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory(); } @@ -52,22 +56,24 @@ void nullBugCheckerInstance(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "TestCheckerTest.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.CompilationTestHelper;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "final class TestCheckerTest {", - " void m() {", - " CompilationTestHelper.newInstance((Class) null, getClass())", - " .addSourceLines(\"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\")", - " .doTest();", - "", - " BugCheckerRefactoringTestHelper.newInstance((Class) null, getClass())", - " .addInputLines(\"A.java\", \"class A {}\")", - " .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\")", - " .doTest();", - " }", - "}"); + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.CompilationTestHelper; + import com.google.errorprone.bugpatterns.BugChecker; + + final class TestCheckerTest { + void m() { + CompilationTestHelper.newInstance((Class) null, getClass()) + .addSourceLines("A.java", "// BUG: Diagnostic contains:", "class A {}") + .doTest(); + + BugCheckerRefactoringTestHelper.newInstance((Class) null, getClass()) + .addInputLines("A.java", "class A {}") + .addOutputLines("A.java", "class A { /* This is a change. */ }") + .doTest(); + } + } + """); assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory(); } @@ -77,28 +83,30 @@ void rawBugCheckerInstance(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "TestCheckerTest.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.CompilationTestHelper;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "final class TestCheckerTest {", - " private static class TestChecker extends BugChecker {}", - "", - " @SuppressWarnings(\"unchecked\")", - " void m() {", - " @SuppressWarnings(\"rawtypes\")", - " Class bugChecker = TestChecker.class;", - "", - " CompilationTestHelper.newInstance(bugChecker, getClass())", - " .addSourceLines(\"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\")", - " .doTest();", - "", - " BugCheckerRefactoringTestHelper.newInstance(bugChecker, getClass())", - " .addInputLines(\"A.java\", \"class A {}\")", - " .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\")", - " .doTest();", - " }", - "}"); + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.CompilationTestHelper; + import com.google.errorprone.bugpatterns.BugChecker; + + final class TestCheckerTest { + private static class TestChecker extends BugChecker {} + + @SuppressWarnings("unchecked") + void m() { + @SuppressWarnings("rawtypes") + Class bugChecker = TestChecker.class; + + CompilationTestHelper.newInstance(bugChecker, getClass()) + .addSourceLines("A.java", "// BUG: Diagnostic contains:", "class A {}") + .doTest(); + + BugCheckerRefactoringTestHelper.newInstance(bugChecker, getClass()) + .addInputLines("A.java", "class A {}") + .addOutputLines("A.java", "class A { /* This is a change. */ }") + .doTest(); + } + } + """); assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory(); } @@ -108,27 +116,29 @@ void scannerSupplierInstance(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "TestCheckerTest.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.CompilationTestHelper;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "import com.google.errorprone.scanner.ScannerSupplier;", - "", - "final class TestCheckerTest {", - " private static class TestChecker extends BugChecker {}", - "", - " void m() {", - " CompilationTestHelper.newInstance(", - " ScannerSupplier.fromBugCheckerClasses(TestChecker.class), getClass())", - " .addSourceLines(\"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\")", - " .doTest();", - "", - " BugCheckerRefactoringTestHelper.newInstance(", - " ScannerSupplier.fromBugCheckerClasses(TestChecker.class), getClass())", - " .addInputLines(\"A.java\", \"class A {}\")", - " .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\")", - " .doTest();", - " }", - "}"); + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.CompilationTestHelper; + import com.google.errorprone.bugpatterns.BugChecker; + import com.google.errorprone.scanner.ScannerSupplier; + + final class TestCheckerTest { + private static class TestChecker extends BugChecker {} + + void m() { + CompilationTestHelper.newInstance( + ScannerSupplier.fromBugCheckerClasses(TestChecker.class), getClass()) + .addSourceLines("A.java", "// BUG: Diagnostic contains:", "class A {}") + .doTest(); + + BugCheckerRefactoringTestHelper.newInstance( + ScannerSupplier.fromBugCheckerClasses(TestChecker.class), getClass()) + .addInputLines("A.java", "class A {}") + .addOutputLines("A.java", "class A { /* This is a change. */ }") + .doTest(); + } + } + """); assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory(); } @@ -138,29 +148,31 @@ void nonCompileTimeConstantStrings(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "TestCheckerTest.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.CompilationTestHelper;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "final class TestCheckerTest {", - " private static class TestChecker extends BugChecker {}", - "", - " void m() {", - " CompilationTestHelper.newInstance(TestChecker.class, getClass())", - " .addSourceLines(toString() + \"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\")", - " .addSourceLines(\"B.java\", \"// BUG: Diagnostic contains:\", \"class B {}\", toString())", - " .doTest();", - "", - " BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())", - " .addInputLines(toString() + \"A.java\", \"class A {}\")", - " .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\")", - " .addInputLines(\"B.java\", \"class B {}\", toString())", - " .addOutputLines(\"B.java\", \"class B { /* This is a change. */ }\")", - " .addInputLines(\"C.java\", \"class C {}\")", - " .addOutputLines(\"C.java\", \"class C { /* This is a change. */ }\", toString())", - " .doTest();", - " }", - "}"); + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.CompilationTestHelper; + import com.google.errorprone.bugpatterns.BugChecker; + + final class TestCheckerTest { + private static class TestChecker extends BugChecker {} + + void m() { + CompilationTestHelper.newInstance(TestChecker.class, getClass()) + .addSourceLines(toString() + "A.java", "// BUG: Diagnostic contains:", "class A {}") + .addSourceLines("B.java", "// BUG: Diagnostic contains:", "class B {}", toString()) + .doTest(); + + BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass()) + .addInputLines(toString() + "A.java", "class A {}") + .addOutputLines("A.java", "class A { /* This is a change. */ }") + .addInputLines("B.java", "class B {}", toString()) + .addOutputLines("B.java", "class B { /* This is a change. */ }") + .addInputLines("C.java", "class C {}") + .addOutputLines("C.java", "class C { /* This is a change. */ }", toString()) + .doTest(); + } + } + """); assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory(); } @@ -170,26 +182,28 @@ void nonFluentTestHelperExpressions(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "TestCheckerTest.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.CompilationTestHelper;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "final class TestCheckerTest {", - " private static class TestChecker extends BugChecker {}", - "", - " void m() {", - " CompilationTestHelper testHelper =", - " CompilationTestHelper.newInstance(TestChecker.class, getClass())", - " .addSourceLines(\"A.java\", \"class A {}\");", - " testHelper.doTest();", - "", - " BugCheckerRefactoringTestHelper.ExpectOutput expectedOutput =", - " BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())", - " .addInputLines(\"A.java\", \"class A {}\");", - " expectedOutput.addOutputLines(\"A.java\", \"class A {}\").doTest();", - " expectedOutput.expectUnchanged().doTest();", - " }", - "}"); + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.CompilationTestHelper; + import com.google.errorprone.bugpatterns.BugChecker; + + final class TestCheckerTest { + private static class TestChecker extends BugChecker {} + + void m() { + CompilationTestHelper testHelper = + CompilationTestHelper.newInstance(TestChecker.class, getClass()) + .addSourceLines("A.java", "class A {}"); + testHelper.doTest(); + + BugCheckerRefactoringTestHelper.ExpectOutput expectedOutput = + BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass()) + .addInputLines("A.java", "class A {}"); + expectedOutput.addOutputLines("A.java", "class A {}").doTest(); + expectedOutput.expectUnchanged().doTest(); + } + } + """); assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory(); } @@ -199,19 +213,21 @@ void noSource(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "TestCheckerTest.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.CompilationTestHelper;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "final class TestCheckerTest {", - " private static class TestChecker extends BugChecker {}", - "", - " void m() {", - " CompilationTestHelper.newInstance(TestChecker.class, getClass()).doTest();", - "", - " BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass()).doTest();", - " }", - "}"); + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.CompilationTestHelper; + import com.google.errorprone.bugpatterns.BugChecker; + + final class TestCheckerTest { + private static class TestChecker extends BugChecker {} + + void m() { + CompilationTestHelper.newInstance(TestChecker.class, getClass()).doTest(); + + BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass()).doTest(); + } + } + """); assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory(); } @@ -221,26 +237,28 @@ void noDiagnostics(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "TestCheckerTest.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.CompilationTestHelper;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "final class TestCheckerTest {", - " private static class TestChecker extends BugChecker {}", - "", - " void m() {", - " CompilationTestHelper.newInstance(TestChecker.class, getClass())", - " .addSourceLines(\"A.java\", \"class A {}\")", - " .doTest();", - "", - " BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())", - " .addInputLines(\"A.java\", \"class A {}\")", - " .addOutputLines(\"A.java\", \"class A {}\")", - " .addInputLines(\"B.java\", \"class B {}\")", - " .expectUnchanged()", - " .doTest();", - " }", - "}"); + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.CompilationTestHelper; + import com.google.errorprone.bugpatterns.BugChecker; + + final class TestCheckerTest { + private static class TestChecker extends BugChecker {} + + void m() { + CompilationTestHelper.newInstance(TestChecker.class, getClass()) + .addSourceLines("A.java", "class A {}") + .doTest(); + + BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass()) + .addInputLines("A.java", "class A {}") + .addOutputLines("A.java", "class A {}") + .addInputLines("B.java", "class B {}") + .expectUnchanged() + .doTest(); + } + } + """); assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory(); } @@ -250,18 +268,20 @@ void singleFileCompilationTestHelper(@TempDir Path outputDirectory) throws IOExc Compilation.compileWithDocumentationGenerator( outputDirectory, "SingleFileCompilationTestHelperTest.java", - "import com.google.errorprone.CompilationTestHelper;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "final class SingleFileCompilationTestHelperTest {", - " private static class TestChecker extends BugChecker {}", - "", - " void m() {", - " CompilationTestHelper.newInstance(TestChecker.class, getClass())", - " .addSourceLines(\"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\")", - " .doTest();", - " }", - "}"); + """ + import com.google.errorprone.CompilationTestHelper; + import com.google.errorprone.bugpatterns.BugChecker; + + final class SingleFileCompilationTestHelperTest { + private static class TestChecker extends BugChecker {} + + void m() { + CompilationTestHelper.newInstance(TestChecker.class, getClass()) + .addSourceLines("A.java", "// BUG: Diagnostic contains:", "class A {}") + .doTest(); + } + } + """); verifyGeneratedFileContent(outputDirectory, "SingleFileCompilationTestHelperTest"); } @@ -272,19 +292,21 @@ void singleFileCompilationTestHelperWithSetArgs(@TempDir Path outputDirectory) Compilation.compileWithDocumentationGenerator( outputDirectory, "SingleFileCompilationTestHelperWithSetArgsTest.java", - "import com.google.errorprone.CompilationTestHelper;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "final class SingleFileCompilationTestHelperWithSetArgsTest {", - " private static class TestChecker extends BugChecker {}", - "", - " void m() {", - " CompilationTestHelper.newInstance(TestChecker.class, getClass())", - " .setArgs(\"-XepAllSuggestionsAsWarnings\")", - " .addSourceLines(\"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\")", - " .doTest();", - " }", - "}"); + """ + import com.google.errorprone.CompilationTestHelper; + import com.google.errorprone.bugpatterns.BugChecker; + + final class SingleFileCompilationTestHelperWithSetArgsTest { + private static class TestChecker extends BugChecker {} + + void m() { + CompilationTestHelper.newInstance(TestChecker.class, getClass()) + .setArgs("-XepAllSuggestionsAsWarnings") + .addSourceLines("A.java", "// BUG: Diagnostic contains:", "class A {}") + .doTest(); + } + } + """); verifyGeneratedFileContent(outputDirectory, "SingleFileCompilationTestHelperWithSetArgsTest"); } @@ -294,19 +316,21 @@ void multiFileCompilationTestHelper(@TempDir Path outputDirectory) throws IOExce Compilation.compileWithDocumentationGenerator( outputDirectory, "MultiFileCompilationTestHelperTest.java", - "import com.google.errorprone.CompilationTestHelper;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "final class MultiFileCompilationTestHelperTest {", - " private static class TestChecker extends BugChecker {}", - "", - " void m() {", - " CompilationTestHelper.newInstance(TestChecker.class, getClass())", - " .addSourceLines(\"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\")", - " .addSourceLines(\"B.java\", \"// BUG: Diagnostic contains:\", \"class B {}\")", - " .doTest();", - " }", - "}"); + """ + import com.google.errorprone.CompilationTestHelper; + import com.google.errorprone.bugpatterns.BugChecker; + + final class MultiFileCompilationTestHelperTest { + private static class TestChecker extends BugChecker {} + + void m() { + CompilationTestHelper.newInstance(TestChecker.class, getClass()) + .addSourceLines("A.java", "// BUG: Diagnostic contains:", "class A {}") + .addSourceLines("B.java", "// BUG: Diagnostic contains:", "class B {}") + .doTest(); + } + } + """); verifyGeneratedFileContent(outputDirectory, "MultiFileCompilationTestHelperTest"); } @@ -316,19 +340,21 @@ void singleFileBugCheckerRefactoringTestHelper(@TempDir Path outputDirectory) th Compilation.compileWithDocumentationGenerator( outputDirectory, "SingleFileBugCheckerRefactoringTestHelperTest.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "final class SingleFileBugCheckerRefactoringTestHelperTest {", - " private static class TestChecker extends BugChecker {}", - "", - " void m() {", - " BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())", - " .addInputLines(\"A.java\", \"class A {}\")", - " .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\")", - " .doTest();", - " }", - "}"); + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.bugpatterns.BugChecker; + + final class SingleFileBugCheckerRefactoringTestHelperTest { + private static class TestChecker extends BugChecker {} + + void m() { + BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass()) + .addInputLines("A.java", "class A {}") + .addOutputLines("A.java", "class A { /* This is a change. */ }") + .doTest(); + } + } + """); verifyGeneratedFileContent(outputDirectory, "SingleFileBugCheckerRefactoringTestHelperTest"); } @@ -339,23 +365,25 @@ void singleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTest Compilation.compileWithDocumentationGenerator( outputDirectory, "SingleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestModeTest.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.BugCheckerRefactoringTestHelper.FixChoosers;", - "import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "final class SingleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestModeTest {", - " private static class TestChecker extends BugChecker {}", - "", - " void m() {", - " BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())", - " .setArgs(\"-XepAllSuggestionsAsWarnings\")", - " .setFixChooser(FixChoosers.SECOND)", - " .addInputLines(\"A.java\", \"class A {}\")", - " .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\")", - " .doTest(TestMode.TEXT_MATCH);", - " }", - "}"); + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.BugCheckerRefactoringTestHelper.FixChoosers; + import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode; + import com.google.errorprone.bugpatterns.BugChecker; + + final class SingleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestModeTest { + private static class TestChecker extends BugChecker {} + + void m() { + BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass()) + .setArgs("-XepAllSuggestionsAsWarnings") + .setFixChooser(FixChoosers.SECOND) + .addInputLines("A.java", "class A {}") + .addOutputLines("A.java", "class A { /* This is a change. */ }") + .doTest(TestMode.TEXT_MATCH); + } + } + """); verifyGeneratedFileContent( outputDirectory, @@ -367,21 +395,23 @@ void multiFileBugCheckerRefactoringTestHelper(@TempDir Path outputDirectory) thr Compilation.compileWithDocumentationGenerator( outputDirectory, "MultiFileBugCheckerRefactoringTestHelperTest.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "final class MultiFileBugCheckerRefactoringTestHelperTest {", - " private static class TestChecker extends BugChecker {}", - "", - " void m() {", - " BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())", - " .addInputLines(\"A.java\", \"class A {}\")", - " .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\")", - " .addInputLines(\"B.java\", \"class B {}\")", - " .addOutputLines(\"B.java\", \"class B { /* This is a change. */ }\")", - " .doTest();", - " }", - "}"); + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.bugpatterns.BugChecker; + + final class MultiFileBugCheckerRefactoringTestHelperTest { + private static class TestChecker extends BugChecker {} + + void m() { + BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass()) + .addInputLines("A.java", "class A {}") + .addOutputLines("A.java", "class A { /* This is a change. */ }") + .addInputLines("B.java", "class B {}") + .addOutputLines("B.java", "class B { /* This is a change. */ }") + .doTest(); + } + } + """); verifyGeneratedFileContent(outputDirectory, "MultiFileBugCheckerRefactoringTestHelperTest"); } @@ -392,24 +422,26 @@ void compilationAndBugCheckerRefactoringTestHelpers(@TempDir Path outputDirector Compilation.compileWithDocumentationGenerator( outputDirectory, "CompilationAndBugCheckerRefactoringTestHelpersTest.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.CompilationTestHelper;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "final class CompilationAndBugCheckerRefactoringTestHelpersTest {", - " private static class TestChecker extends BugChecker {}", - "", - " void m() {", - " CompilationTestHelper.newInstance(TestChecker.class, getClass())", - " .addSourceLines(\"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\")", - " .doTest();", - "", - " BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())", - " .addInputLines(\"A.java\", \"class A {}\")", - " .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\")", - " .doTest();", - " }", - "}"); + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.CompilationTestHelper; + import com.google.errorprone.bugpatterns.BugChecker; + + final class CompilationAndBugCheckerRefactoringTestHelpersTest { + private static class TestChecker extends BugChecker {} + + void m() { + CompilationTestHelper.newInstance(TestChecker.class, getClass()) + .addSourceLines("A.java", "// BUG: Diagnostic contains:", "class A {}") + .doTest(); + + BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass()) + .addInputLines("A.java", "class A {}") + .addOutputLines("A.java", "class A { /* This is a change. */ }") + .doTest(); + } + } + """); verifyGeneratedFileContent( outputDirectory, "CompilationAndBugCheckerRefactoringTestHelpersTest"); @@ -421,28 +453,30 @@ void compilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNa Compilation.compileWithDocumentationGenerator( outputDirectory, "CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest.java", - "package pkg;", - "", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.CompilationTestHelper;", - "import com.google.errorprone.bugpatterns.BugChecker;", - "", - "final class CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest {", - " private static class CustomTestChecker extends BugChecker {}", - "", - " private static class CustomTestChecker2 extends BugChecker {}", - "", - " void m() {", - " CompilationTestHelper.newInstance(CustomTestChecker.class, getClass())", - " .addSourceLines(\"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\")", - " .doTest();", - "", - " BugCheckerRefactoringTestHelper.newInstance(CustomTestChecker2.class, getClass())", - " .addInputLines(\"A.java\", \"class A {}\")", - " .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\")", - " .doTest();", - " }", - "}"); + """ + package pkg; + + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.CompilationTestHelper; + import com.google.errorprone.bugpatterns.BugChecker; + + final class CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest { + private static class CustomTestChecker extends BugChecker {} + + private static class CustomTestChecker2 extends BugChecker {} + + void m() { + CompilationTestHelper.newInstance(CustomTestChecker.class, getClass()) + .addSourceLines("A.java", "// BUG: Diagnostic contains:", "class A {}") + .doTest(); + + BugCheckerRefactoringTestHelper.newInstance(CustomTestChecker2.class, getClass()) + .addInputLines("A.java", "class A {}") + .addOutputLines("A.java", "class A { /* This is a change. */ }") + .doTest(); + } + } + """); verifyGeneratedFileContent( outputDirectory, diff --git a/documentation-support/src/test/java/tech/picnic/errorprone/documentation/DocumentationGeneratorTaskListenerTest.java b/documentation-support/src/test/java/tech/picnic/errorprone/documentation/DocumentationGeneratorTaskListenerTest.java index 0b300dc23b3..0606ad5cd8f 100644 --- a/documentation-support/src/test/java/tech/picnic/errorprone/documentation/DocumentationGeneratorTaskListenerTest.java +++ b/documentation-support/src/test/java/tech/picnic/errorprone/documentation/DocumentationGeneratorTaskListenerTest.java @@ -62,7 +62,11 @@ private static void readOnlyFileSystemFailsToWrite(Path outputDirectory) { assertThatThrownBy( () -> Compilation.compileWithDocumentationGenerator( - outputDirectory, "A.java", "class A {}")) + outputDirectory, + "A.java", + """ + class A {} + """)) .hasRootCauseInstanceOf(FileSystemException.class) .hasCauseInstanceOf(IllegalStateException.class) .hasMessageEndingWith("Error while creating directory with path '%s'", outputDirectory); @@ -70,7 +74,10 @@ private static void readOnlyFileSystemFailsToWrite(Path outputDirectory) { @Test void noClassNoOutput(@TempDir Path outputDirectory) { - Compilation.compileWithDocumentationGenerator(outputDirectory, "A.java", "package pkg;"); + Compilation.compileWithDocumentationGenerator( + outputDirectory, "A.java", """ + package pkg; + """); assertThat(outputDirectory).isEmptyDirectory(); } @@ -81,7 +88,11 @@ void excessArguments(@TempDir Path outputDirectory) { assertThatThrownBy( () -> Compilation.compileWithDocumentationGenerator( - actualOutputDirectory, "A.java", "package pkg;")) + actualOutputDirectory, + "A.java", + """ + package pkg; + """)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Precisely one path must be provided"); } @@ -91,7 +102,9 @@ void extraction(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "DocumentationGeneratorTaskListenerTestClass.java", - "class DocumentationGeneratorTaskListenerTestClass {}"); + """ + class DocumentationGeneratorTaskListenerTestClass {} + """); // XXX: Once we support only JDK 15+, use a text block for the `expected` string. assertThat( 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 82976c53365..736b5ae7954 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 @@ -13,99 +13,101 @@ void identification() { "X", m -> m.contains("`JsonCreator.Mode` should be set for single-argument creators")) .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(); } @@ -114,28 +116,32 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(AmbiguousJsonCreator.class, getClass()) .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(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 9ba9e0ad09d..d45231a6216 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 @@ -11,22 +11,24 @@ void identification() { CompilationTestHelper.newInstance(AssertJIsNull.class, getClass()) .addSourceLines( "A.java", - "import static org.assertj.core.api.Assertions.assertThat;", - "", - "class A {", - " void m() {", - " assertThat(1).isEqualTo(1);", - " // BUG: Diagnostic contains:", - " assertThat(1).isEqualTo(null);", - " // BUG: Diagnostic contains:", - " assertThat(\"foo\").isEqualTo(null);", - " isEqualTo(null);", - " }", - "", - " private boolean isEqualTo(Object value) {", - " return value.equals(\"bar\");", - " }", - "}") + """ + 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(); } @@ -35,24 +37,28 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(AssertJIsNull.class, getClass()) .addInputLines( "A.java", - "import static org.assertj.core.api.Assertions.assertThat;", - "", - "class A {", - " void m() {", - " assertThat(1).isEqualTo(null);", - " assertThat(\"foo\").isEqualTo(null);", - " }", - "}") + """ + 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(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/AssociativeMethodInvocationTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/AssociativeMethodInvocationTest.java index 789fb14ec6b..dd998c7e908 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/AssociativeMethodInvocationTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/AssociativeMethodInvocationTest.java @@ -11,44 +11,46 @@ void identification() { CompilationTestHelper.newInstance(AssociativeMethodInvocation.class, getClass()) .addSourceLines( "A.java", - "import com.google.common.collect.ImmutableList;", - "import com.google.errorprone.matchers.Matchers;", - "import com.google.errorprone.refaster.Refaster;", - "", - "class A {", - " void m() {", - " Matchers.allOf();", - " Matchers.anyOf();", - " Refaster.anyOf();", - "", - " Matchers.allOf((t, s) -> true);", - " Matchers.anyOf((t, s) -> true);", - " Refaster.anyOf(0);", - "", - " Matchers.allOf(Matchers.anyOf((t, s) -> true));", - " Matchers.anyOf(Matchers.allOf((t, s) -> true));", - " Refaster.anyOf(Matchers.allOf((t, s) -> true));", - "", - " // BUG: Diagnostic contains:", - " Matchers.allOf(Matchers.allOf((t, s) -> true));", - " // BUG: Diagnostic contains:", - " Matchers.anyOf(Matchers.anyOf((t, s) -> true));", - " // BUG: Diagnostic contains:", - " Refaster.anyOf(Refaster.anyOf(0));", - "", - " Matchers.allOf(Matchers.allOf(ImmutableList.of((t, s) -> true)));", - " Matchers.anyOf(Matchers.anyOf(ImmutableList.of((t, s) -> true)));", - "", - " // BUG: Diagnostic contains:", - " Matchers.allOf(", - " (t, s) -> true, Matchers.allOf((t, s) -> false, (t, s) -> true), (t, s) -> false);", - " // BUG: Diagnostic contains:", - " Matchers.anyOf(", - " (t, s) -> true, Matchers.anyOf((t, s) -> false, (t, s) -> true), (t, s) -> false);", - " // BUG: Diagnostic contains:", - " Refaster.anyOf(0, Refaster.anyOf(1, 2), 3);", - " }", - "}") + """ + import com.google.common.collect.ImmutableList; + import com.google.errorprone.matchers.Matchers; + import com.google.errorprone.refaster.Refaster; + + class A { + void m() { + Matchers.allOf(); + Matchers.anyOf(); + Refaster.anyOf(); + + Matchers.allOf((t, s) -> true); + Matchers.anyOf((t, s) -> true); + Refaster.anyOf(0); + + Matchers.allOf(Matchers.anyOf((t, s) -> true)); + Matchers.anyOf(Matchers.allOf((t, s) -> true)); + Refaster.anyOf(Matchers.allOf((t, s) -> true)); + + // BUG: Diagnostic contains: + Matchers.allOf(Matchers.allOf((t, s) -> true)); + // BUG: Diagnostic contains: + Matchers.anyOf(Matchers.anyOf((t, s) -> true)); + // BUG: Diagnostic contains: + Refaster.anyOf(Refaster.anyOf(0)); + + Matchers.allOf(Matchers.allOf(ImmutableList.of((t, s) -> true))); + Matchers.anyOf(Matchers.anyOf(ImmutableList.of((t, s) -> true))); + + // BUG: Diagnostic contains: + Matchers.allOf( + (t, s) -> true, Matchers.allOf((t, s) -> false, (t, s) -> true), (t, s) -> false); + // BUG: Diagnostic contains: + Matchers.anyOf( + (t, s) -> true, Matchers.anyOf((t, s) -> false, (t, s) -> true), (t, s) -> false); + // BUG: Diagnostic contains: + Refaster.anyOf(0, Refaster.anyOf(1, 2), 3); + } + } + """) .doTest(); } @@ -57,54 +59,58 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(AssociativeMethodInvocation.class, getClass()) .addInputLines( "A.java", - "import com.google.errorprone.matchers.Matchers;", - "import com.google.errorprone.refaster.Refaster;", - "", - "class A {", - " void m() {", - " Matchers.allOf(Matchers.allOf());", - " Matchers.anyOf(Matchers.anyOf());", - " Refaster.anyOf(Refaster.anyOf());", - "", - " Matchers.allOf(Matchers.allOf((t, s) -> true));", - " Matchers.anyOf(Matchers.anyOf((t, s) -> true));", - " Refaster.anyOf(Refaster.anyOf(0));", - "", - " Matchers.allOf(", - " Matchers.anyOf(),", - " Matchers.allOf((t, s) -> false, (t, s) -> true),", - " Matchers.allOf(),", - " Matchers.anyOf((t, s) -> false));", - " Matchers.anyOf(", - " Matchers.allOf(),", - " Matchers.anyOf((t, s) -> false, (t, s) -> true),", - " Matchers.anyOf(),", - " Matchers.allOf((t, s) -> false));", - " Refaster.anyOf(Matchers.allOf(), Refaster.anyOf(1, 2), Matchers.anyOf());", - " }", - "}") + """ + import com.google.errorprone.matchers.Matchers; + import com.google.errorprone.refaster.Refaster; + + class A { + void m() { + Matchers.allOf(Matchers.allOf()); + Matchers.anyOf(Matchers.anyOf()); + Refaster.anyOf(Refaster.anyOf()); + + Matchers.allOf(Matchers.allOf((t, s) -> true)); + Matchers.anyOf(Matchers.anyOf((t, s) -> true)); + Refaster.anyOf(Refaster.anyOf(0)); + + Matchers.allOf( + Matchers.anyOf(), + Matchers.allOf((t, s) -> false, (t, s) -> true), + Matchers.allOf(), + Matchers.anyOf((t, s) -> false)); + Matchers.anyOf( + Matchers.allOf(), + Matchers.anyOf((t, s) -> false, (t, s) -> true), + Matchers.anyOf(), + Matchers.allOf((t, s) -> false)); + Refaster.anyOf(Matchers.allOf(), Refaster.anyOf(1, 2), Matchers.anyOf()); + } + } + """) .addOutputLines( "A.java", - "import com.google.errorprone.matchers.Matchers;", - "import com.google.errorprone.refaster.Refaster;", - "", - "class A {", - " void m() {", - " Matchers.allOf();", - " Matchers.anyOf();", - " Refaster.anyOf();", - "", - " Matchers.allOf((t, s) -> true);", - " Matchers.anyOf((t, s) -> true);", - " Refaster.anyOf(0);", - "", - " Matchers.allOf(", - " Matchers.anyOf(), (t, s) -> false, (t, s) -> true, Matchers.anyOf((t, s) -> false));", - " Matchers.anyOf(", - " Matchers.allOf(), (t, s) -> false, (t, s) -> true, Matchers.allOf((t, s) -> false));", - " Refaster.anyOf(Matchers.allOf(), 1, 2, Matchers.anyOf());", - " }", - "}") + """ + import com.google.errorprone.matchers.Matchers; + import com.google.errorprone.refaster.Refaster; + + class A { + void m() { + Matchers.allOf(); + Matchers.anyOf(); + Refaster.anyOf(); + + Matchers.allOf((t, s) -> true); + Matchers.anyOf((t, s) -> true); + Refaster.anyOf(0); + + Matchers.allOf( + Matchers.anyOf(), (t, s) -> false, (t, s) -> true, Matchers.anyOf((t, s) -> false)); + Matchers.anyOf( + Matchers.allOf(), (t, s) -> false, (t, s) -> true, Matchers.allOf((t, s) -> false)); + Refaster.anyOf(Matchers.allOf(), 1, 2, Matchers.anyOf()); + } + } + """) .doTest(TestMode.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 12276bc5910..9ea82733813 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 @@ -11,56 +11,58 @@ void identification() { CompilationTestHelper.newInstance(AutowiredConstructor.class, getClass()) .addSourceLines( "Container.java", - "import com.google.errorprone.annotations.Immutable;", - "import java.util.List;", - "import org.springframework.beans.factory.annotation.Autowired;", - "", - "interface Container {", - " @Immutable", - " class A {", - " A() {}", - " }", - "", - " class B {", - " @Autowired", - " void setProperty(Object o) {}", - " }", - "", - " class C {", - " // BUG: Diagnostic contains:", - " @Autowired", - " C() {}", - " }", - "", - " class D {", - " // BUG: Diagnostic contains:", - " @Autowired", - " D(String x) {}", - " }", - "", - " class E {", - " @Autowired", - " E() {}", - "", - " E(String x) {}", - " }", - "", - " class F {", - " F() {}", - "", - " @Autowired", - " F(String x) {}", - " }", - "", - " class G {", - " @Autowired private Object o;", - " }", - "", - " class H {", - " @SafeVarargs", - " H(List... 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(); } @@ -69,34 +71,38 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(AutowiredConstructor.class, getClass()) .addInputLines( "Container.java", - "import org.springframework.beans.factory.annotation.Autowired;", - "", - "interface Container {", - " class A {", - " @Autowired", - " @Deprecated", - " A() {}", - " }", - "", - " class B {", - " @Autowired", - " B(String x) {}", - " }", - "}") + """ + 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 1c37fad1887..0874ef1e1ba 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 @@ -11,128 +11,130 @@ void identification() { CompilationTestHelper.newInstance(CanonicalAnnotationSyntax.class, getClass()) .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(); } @@ -141,139 +143,143 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(CanonicalAnnotationSyntax.class, getClass()) .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/CanonicalClassNameUsageTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/CanonicalClassNameUsageTest.java index 27a57e4b131..e82d2922e75 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/CanonicalClassNameUsageTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/CanonicalClassNameUsageTest.java @@ -14,35 +14,37 @@ void identification() { "--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED") .addSourceLines( "A.java", - "import static com.google.errorprone.matchers.Matchers.instanceMethod;", - "", - "import com.google.errorprone.VisitorState;", - "import tech.picnic.errorprone.bugpatterns.util.MoreTypes;", - "", - "class A {", - " void m(VisitorState state) {", - " String a = A.class.getName();", - " String b = getClass().getName();", - " A.class.getName().toString();", - " System.out.println(A.class.getName());", - " methodInUnnamedPackage(A.class.getName());", - " instanceMethod().onExactClass(A.class.getCanonicalName());", - " MoreTypes.type(A.class.getCanonicalName());", - " MoreTypes.type(A.class.getCanonicalName() + \".SubType\");", - " instanceMethod().onExactClass(new Object() {}.getClass().getName());", - " instanceMethod().onExactClass(methodInUnnamedPackage(A.class.getName()));", - " // BUG: Diagnostic contains:", - " instanceMethod().onExactClass(A.class.getName());", - " // BUG: Diagnostic contains:", - " MoreTypes.type(A.class.getName());", - " // BUG: Diagnostic contains:", - " state.binaryNameFromClassname(A.class.getName() + \".SubType\");", - " }", - "", - " String methodInUnnamedPackage(String str) {", - " return str;", - " }", - "}") + """ + import static com.google.errorprone.matchers.Matchers.instanceMethod; + + import com.google.errorprone.VisitorState; + import tech.picnic.errorprone.bugpatterns.util.MoreTypes; + + class A { + void m(VisitorState state) { + String a = A.class.getName(); + String b = getClass().getName(); + A.class.getName().toString(); + System.out.println(A.class.getName()); + methodInUnnamedPackage(A.class.getName()); + instanceMethod().onExactClass(A.class.getCanonicalName()); + MoreTypes.type(A.class.getCanonicalName()); + MoreTypes.type(A.class.getCanonicalName() + ".SubType"); + instanceMethod().onExactClass(new Object() {}.getClass().getName()); + instanceMethod().onExactClass(methodInUnnamedPackage(A.class.getName())); + // BUG: Diagnostic contains: + instanceMethod().onExactClass(A.class.getName()); + // BUG: Diagnostic contains: + MoreTypes.type(A.class.getName()); + // BUG: Diagnostic contains: + state.binaryNameFromClassname(A.class.getName() + ".SubType"); + } + + String methodInUnnamedPackage(String str) { + return str; + } + } + """) .doTest(); } @@ -51,32 +53,36 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(CanonicalClassNameUsage.class, getClass()) .addInputLines( "A.java", - "import static com.google.errorprone.matchers.Matchers.instanceMethod;", - "", - "import com.google.errorprone.BugPattern;", - "import tech.picnic.errorprone.bugpatterns.util.MoreTypes;", - "", - "class A {", - " void m() {", - " instanceMethod().onDescendantOfAny(A.class.getName(), BugPattern.LinkType.class.getName());", - " MoreTypes.type(String.class.getName());", - " }", - "}") + """ + import static com.google.errorprone.matchers.Matchers.instanceMethod; + + import com.google.errorprone.BugPattern; + import tech.picnic.errorprone.bugpatterns.util.MoreTypes; + + class A { + void m() { + instanceMethod().onDescendantOfAny(A.class.getName(), BugPattern.LinkType.class.getName()); + MoreTypes.type(String.class.getName()); + } + } + """) .addOutputLines( "A.java", - "import static com.google.errorprone.matchers.Matchers.instanceMethod;", - "", - "import com.google.errorprone.BugPattern;", - "import tech.picnic.errorprone.bugpatterns.util.MoreTypes;", - "", - "class A {", - " void m() {", - " instanceMethod()", - " .onDescendantOfAny(", - " A.class.getCanonicalName(), BugPattern.LinkType.class.getCanonicalName());", - " MoreTypes.type(String.class.getCanonicalName());", - " }", - "}") + """ + import static com.google.errorprone.matchers.Matchers.instanceMethod; + + import com.google.errorprone.BugPattern; + import tech.picnic.errorprone.bugpatterns.util.MoreTypes; + + class A { + void m() { + instanceMethod() + .onDescendantOfAny( + A.class.getCanonicalName(), BugPattern.LinkType.class.getCanonicalName()); + MoreTypes.type(String.class.getCanonicalName()); + } + } + """) .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 d4e7f1310b8..cb71ec3d593 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 @@ -13,50 +13,52 @@ void identification() { CompilationTestHelper.newInstance(CollectorMutability.class, getClass()) .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(); } @@ -66,14 +68,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(); } @@ -82,55 +86,59 @@ void replacementFirstSuggestedFix() { BugCheckerRefactoringTestHelper.newInstance(CollectorMutability.class, getClass()) .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); } @@ -140,73 +148,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/DirectReturnTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/DirectReturnTest.java index 42e18894148..6315481e206 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/DirectReturnTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/DirectReturnTest.java @@ -11,184 +11,186 @@ void identification() { CompilationTestHelper.newInstance(DirectReturn.class, getClass()) .addSourceLines( "A.java", - "import static org.mockito.Mockito.mock;", - "import static org.mockito.Mockito.spy;", - "", - "import java.util.function.Supplier;", - "", - "class A {", - " private String field;", - "", - " void emptyMethod() {}", - "", - " void voidMethod() {", - " toString();", - " return;", - " }", - "", - " String directReturnOfParam(String param) {", - " return param;", - " }", - "", - " String assignmentToField() {", - " field = toString();", - " return field;", - " }", - "", - " Object redundantAssignmentToParam(String param) {", - " // BUG: Diagnostic contains:", - " param = toString();", - " return param;", - " }", - "", - " String redundantMockAssignmentToParam(String param) {", - " // BUG: Diagnostic contains:", - " param = mock();", - " return param;", - " }", - "", - " Object redundantMockWithExplicitTypeAssignmentToParam(String param) {", - " // BUG: Diagnostic contains:", - " param = mock(String.class);", - " return param;", - " }", - "", - " Object salientMockAssignmentToParam(String param) {", - " param = mock();", - " return param;", - " }", - "", - " String redundantAssignmentToLocalVariable() {", - " String variable = null;", - " // BUG: Diagnostic contains:", - " variable = toString();", - " return variable;", - " }", - "", - " String unusedAssignmentToLocalVariable(String param) {", - " String variable = null;", - " variable = toString();", - " return param;", - " }", - "", - " String redundantVariableDeclaration() {", - " // BUG: Diagnostic contains:", - " String variable = toString();", - " return variable;", - " }", - "", - " String redundantSpyVariableDeclaration() {", - " // BUG: Diagnostic contains:", - " String variable = spy();", - " return variable;", - " }", - "", - " Object redundantSpyWithExplicitTypeVariableDeclaration() {", - " // BUG: Diagnostic contains:", - " String variable = spy(String.class);", - " return variable;", - " }", - "", - " Object salientSpyTypeVariableDeclaration() {", - " String variable = spy(\"name\");", - " return variable;", - " }", - "", - " String unusedVariableDeclaration(String param) {", - " String variable = toString();", - " return param;", - " }", - "", - " String assignmentToAnnotatedVariable() {", - " @SuppressWarnings(\"HereBeDragons\")", - " String variable = toString();", - " return variable;", - " }", - "", - " String complexReturnStatement() {", - " String variable = toString();", - " return variable + toString();", - " }", - "", - " String assignmentInsideIfClause() {", - " String variable = null;", - " if (true) {", - " variable = toString();", - " }", - " return variable;", - " }", - "", - " String redundantAssignmentInsideElseClause() {", - " String variable = toString();", - " if (true) {", - " return variable;", - " } else {", - " // BUG: Diagnostic contains:", - " variable = \"foo\";", - " return variable;", - " }", - " }", - "", - " Supplier redundantAssignmentInsideLambda() {", - " return () -> {", - " // BUG: Diagnostic contains:", - " String variable = toString();", - " return variable;", - " };", - " }", - "", - " String redundantAssignmentInsideTryBlock(AutoCloseable closeable) throws Exception {", - " try (closeable) {", - " // BUG: Diagnostic contains:", - " String variable = toString();", - " return variable;", - " }", - " }", - "", - " String redundantAssignmentsInsideTryAndFinallyBlocks() {", - " String variable = toString();", - " try {", - " // BUG: Diagnostic contains:", - " variable = \"foo\";", - " return variable;", - " } finally {", - " String variable2 = toString();", - " if (true) {", - " // BUG: Diagnostic contains:", - " String variable3 = toString();", - " return variable3;", - " }", - " return variable2;", - " }", - " }", - "", - " String assignmentUsedInsideFinallyBlock() {", - " String variable = toString();", - " try {", - " variable = \"foo\";", - " return variable;", - " } finally {", - " String variable2 = toString();", - " return variable + variable2;", - " }", - " }", - "", - " String redundantAssignmentToVariableUsedInsideUnexecutedFinallyBlock(AutoCloseable closeable)", - " throws Exception {", - " String variable = toString();", - " try (closeable) {", - " if (true) {", - " // BUG: Diagnostic contains:", - " variable = \"foo\";", - " return variable;", - " }", - " }", - " try {", - " } finally {", - " return variable;", - " }", - " }", - "}") + """ + import static org.mockito.Mockito.mock; + import static org.mockito.Mockito.spy; + + import java.util.function.Supplier; + + class A { + private String field; + + void emptyMethod() {} + + void voidMethod() { + toString(); + return; + } + + String directReturnOfParam(String param) { + return param; + } + + String assignmentToField() { + field = toString(); + return field; + } + + Object redundantAssignmentToParam(String param) { + // BUG: Diagnostic contains: + param = toString(); + return param; + } + + String redundantMockAssignmentToParam(String param) { + // BUG: Diagnostic contains: + param = mock(); + return param; + } + + Object redundantMockWithExplicitTypeAssignmentToParam(String param) { + // BUG: Diagnostic contains: + param = mock(String.class); + return param; + } + + Object salientMockAssignmentToParam(String param) { + param = mock(); + return param; + } + + String redundantAssignmentToLocalVariable() { + String variable = null; + // BUG: Diagnostic contains: + variable = toString(); + return variable; + } + + String unusedAssignmentToLocalVariable(String param) { + String variable = null; + variable = toString(); + return param; + } + + String redundantVariableDeclaration() { + // BUG: Diagnostic contains: + String variable = toString(); + return variable; + } + + String redundantSpyVariableDeclaration() { + // BUG: Diagnostic contains: + String variable = spy(); + return variable; + } + + Object redundantSpyWithExplicitTypeVariableDeclaration() { + // BUG: Diagnostic contains: + String variable = spy(String.class); + return variable; + } + + Object salientSpyTypeVariableDeclaration() { + String variable = spy("name"); + return variable; + } + + String unusedVariableDeclaration(String param) { + String variable = toString(); + return param; + } + + String assignmentToAnnotatedVariable() { + @SuppressWarnings("HereBeDragons") + String variable = toString(); + return variable; + } + + String complexReturnStatement() { + String variable = toString(); + return variable + toString(); + } + + String assignmentInsideIfClause() { + String variable = null; + if (true) { + variable = toString(); + } + return variable; + } + + String redundantAssignmentInsideElseClause() { + String variable = toString(); + if (true) { + return variable; + } else { + // BUG: Diagnostic contains: + variable = "foo"; + return variable; + } + } + + Supplier redundantAssignmentInsideLambda() { + return () -> { + // BUG: Diagnostic contains: + String variable = toString(); + return variable; + }; + } + + String redundantAssignmentInsideTryBlock(AutoCloseable closeable) throws Exception { + try (closeable) { + // BUG: Diagnostic contains: + String variable = toString(); + return variable; + } + } + + String redundantAssignmentsInsideTryAndFinallyBlocks() { + String variable = toString(); + try { + // BUG: Diagnostic contains: + variable = "foo"; + return variable; + } finally { + String variable2 = toString(); + if (true) { + // BUG: Diagnostic contains: + String variable3 = toString(); + return variable3; + } + return variable2; + } + } + + String assignmentUsedInsideFinallyBlock() { + String variable = toString(); + try { + variable = "foo"; + return variable; + } finally { + String variable2 = toString(); + return variable + variable2; + } + } + + String redundantAssignmentToVariableUsedInsideUnexecutedFinallyBlock(AutoCloseable closeable) + throws Exception { + String variable = toString(); + try (closeable) { + if (true) { + // BUG: Diagnostic contains: + variable = "foo"; + return variable; + } + } + try { + } finally { + return variable; + } + } + } + """) .doTest(); } @@ -197,30 +199,34 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(DirectReturn.class, getClass()) .addInputLines( "A.java", - "class A {", - " String m1() {", - " String variable = null;", - " variable = toString();", - " return variable;", - " }", - "", - " String m2() {", - " String variable = toString();", - " return variable;", - " }", - "}") + """ + class A { + String m1() { + String variable = null; + variable = toString(); + return variable; + } + + String m2() { + String variable = toString(); + return variable; + } + } + """) .addOutputLines( "A.java", - "class A {", - " String m1() {", - " String variable = null;", - " return toString();", - " }", - "", - " String m2() {", - " return toString();", - " }", - "}") + """ + class A { + String m1() { + String variable = null; + return toString(); + } + + String m2() { + return toString(); + } + } + """) .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 e2bbf87a5df..3bc52e5d180 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 @@ -11,54 +11,58 @@ void identification() { CompilationTestHelper.newInstance(EmptyMethod.class, getClass()) .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(); } @@ -67,22 +71,26 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass()) .addInputLines( "A.java", - "final class A {", - " void instanceMethod() {}", - "", - " static void staticMethod() {}", - "", - " static void staticMethodWithComment() {", - " /* Foo. */", - " }", - "}") + """ + final class A { + void instanceMethod() {} + + static void staticMethod() {} + + static void staticMethodWithComment() { + /* Foo. */ + } + } + """) .addOutputLines( "A.java", - "final class A {", - " static void staticMethodWithComment() {", - " /* Foo. */", - " }", - "}") + """ + final class A { + static void staticMethodWithComment() { + /* Foo. */ + } + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ErrorProneRuntimeClasspathTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ErrorProneRuntimeClasspathTest.java index 7aff4887d0e..9f01e6c1de3 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ErrorProneRuntimeClasspathTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/ErrorProneRuntimeClasspathTest.java @@ -21,67 +21,69 @@ void identification() { "This type may not be on the runtime classpath; use a string literal instead")) .addSourceLines( "A.java", - "import com.google.common.collect.ImmutableList;", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.BugPattern;", - "import com.google.errorprone.CompilationTestHelper;", - "import org.junit.jupiter.api.Test;", - "", - "class A {", - " @SuppressWarnings(\"java.lang.String\")", - " void m(Object o) {", - " m(null);", - " m(0);", - " m(getClass().getName());", - " m(getClass().getCanonicalName());", - " m(\"\");", - " m(\"foo\");", - " m(\"java.util.\");", - "", - " m(\"org.junit.jupiter.api.Test\");", - " m(\"org.junit.jupiter.api.Test.toString\");", - " m(\"com.google.errorprone.CompilationTestHelper\");", - " m(\"com.google.errorprone.CompilationTestHelper.toString\");", - " m(\"com.google.errorprone.BugCheckerRefactoringTestHelper.ExpectOutput\");", - " m(\"com.google.errorprone.BugCheckerRefactoringTestHelper.ExpectOutput.toString\");", - " m(\"com.google.errorprone.NonExistent\");", - " m(\"com.google.common.NonExistent.toString\");", - " m(\"java.lang.NonExistent\");", - " // BUG: Diagnostic matches: USE_CLASS_REFERENCE", - " m(\"com.google.errorprone.BugPattern\");", - " // BUG: Diagnostic matches: USE_CLASS_REFERENCE", - " m(\"com.google.errorprone.util.ErrorProneToken\");", - " // BUG: Diagnostic matches: USE_CLASS_REFERENCE", - " m(\"com.google.common.collect.ImmutableList\");", - " // BUG: Diagnostic matches: USE_CLASS_REFERENCE", - " m(\"java.lang.String\");", - " // BUG: Diagnostic matches: USE_CLASS_REFERENCE", - " m(\"java.lang.String.toString\");", - "", - " m(BugPattern.class.getCanonicalName());", - " m(ImmutableList.class.getCanonicalName());", - " m(String.class.getCanonicalName());", - " m(void.class.getCanonicalName());", - " m(boolean.class.getCanonicalName());", - " m(byte.class.getCanonicalName());", - " m(char.class.getCanonicalName());", - " m(short.class.getCanonicalName());", - " m(int.class.getCanonicalName());", - " m(long.class.getCanonicalName());", - " m(float.class.getCanonicalName());", - " m(double.class.getCanonicalName());", - " m(java.lang.Iterable.class.getCanonicalName());", - " m(CompilationTestHelper.class.toString());", - " // BUG: Diagnostic matches: USE_STRING_LITERAL", - " m(CompilationTestHelper.class.getCanonicalName());", - " // BUG: Diagnostic matches: USE_STRING_LITERAL", - " m(BugCheckerRefactoringTestHelper.ExpectOutput.class.getCanonicalName());", - " // BUG: Diagnostic matches: USE_STRING_LITERAL", - " m(Test.class.getCanonicalName());", - " // BUG: Diagnostic matches: USE_STRING_LITERAL", - " m(org.junit.jupiter.api.Nested.class.getCanonicalName());", - " }", - "}") + """ + import com.google.common.collect.ImmutableList; + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.BugPattern; + import com.google.errorprone.CompilationTestHelper; + import org.junit.jupiter.api.Test; + + class A { + @SuppressWarnings("java.lang.String") + void m(Object o) { + m(null); + m(0); + m(getClass().getName()); + m(getClass().getCanonicalName()); + m(""); + m("foo"); + m("java.util."); + + m("org.junit.jupiter.api.Test"); + m("org.junit.jupiter.api.Test.toString"); + m("com.google.errorprone.CompilationTestHelper"); + m("com.google.errorprone.CompilationTestHelper.toString"); + m("com.google.errorprone.BugCheckerRefactoringTestHelper.ExpectOutput"); + m("com.google.errorprone.BugCheckerRefactoringTestHelper.ExpectOutput.toString"); + m("com.google.errorprone.NonExistent"); + m("com.google.common.NonExistent.toString"); + m("java.lang.NonExistent"); + // BUG: Diagnostic matches: USE_CLASS_REFERENCE + m("com.google.errorprone.BugPattern"); + // BUG: Diagnostic matches: USE_CLASS_REFERENCE + m("com.google.errorprone.util.ErrorProneToken"); + // BUG: Diagnostic matches: USE_CLASS_REFERENCE + m("com.google.common.collect.ImmutableList"); + // BUG: Diagnostic matches: USE_CLASS_REFERENCE + m("java.lang.String"); + // BUG: Diagnostic matches: USE_CLASS_REFERENCE + m("java.lang.String.toString"); + + m(BugPattern.class.getCanonicalName()); + m(ImmutableList.class.getCanonicalName()); + m(String.class.getCanonicalName()); + m(void.class.getCanonicalName()); + m(boolean.class.getCanonicalName()); + m(byte.class.getCanonicalName()); + m(char.class.getCanonicalName()); + m(short.class.getCanonicalName()); + m(int.class.getCanonicalName()); + m(long.class.getCanonicalName()); + m(float.class.getCanonicalName()); + m(double.class.getCanonicalName()); + m(java.lang.Iterable.class.getCanonicalName()); + m(CompilationTestHelper.class.toString()); + // BUG: Diagnostic matches: USE_STRING_LITERAL + m(CompilationTestHelper.class.getCanonicalName()); + // BUG: Diagnostic matches: USE_STRING_LITERAL + m(BugCheckerRefactoringTestHelper.ExpectOutput.class.getCanonicalName()); + // BUG: Diagnostic matches: USE_STRING_LITERAL + m(Test.class.getCanonicalName()); + // BUG: Diagnostic matches: USE_STRING_LITERAL + m(org.junit.jupiter.api.Nested.class.getCanonicalName()); + } + } + """) .doTest(); } @@ -90,47 +92,51 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(ErrorProneRuntimeClasspath.class, getClass()) .addInputLines( "A.java", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.CompilationTestHelper;", - "import org.junit.jupiter.api.Test;", - "", - "class A {", - " void m(Object o) {", - " m(\"com.google.errorprone.BugPattern\");", - " m(\"com.google.errorprone.util.ErrorProneToken\");", - " m(\"com.google.common.collect.ImmutableList\");", - " m(\"java.lang.String\");", - " m(\"java.lang.String.toString\");", - "", - " m(CompilationTestHelper.class.getCanonicalName());", - " m(BugCheckerRefactoringTestHelper.ExpectOutput.class.getCanonicalName());", - " m(Test.class.getCanonicalName());", - " m(org.junit.jupiter.api.Nested.class.getCanonicalName());", - " }", - "}") + """ + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.CompilationTestHelper; + import org.junit.jupiter.api.Test; + + class A { + void m(Object o) { + m("com.google.errorprone.BugPattern"); + m("com.google.errorprone.util.ErrorProneToken"); + m("com.google.common.collect.ImmutableList"); + m("java.lang.String"); + m("java.lang.String.toString"); + + m(CompilationTestHelper.class.getCanonicalName()); + m(BugCheckerRefactoringTestHelper.ExpectOutput.class.getCanonicalName()); + m(Test.class.getCanonicalName()); + m(org.junit.jupiter.api.Nested.class.getCanonicalName()); + } + } + """) .addOutputLines( "A.java", - "import com.google.common.collect.ImmutableList;", - "import com.google.errorprone.BugCheckerRefactoringTestHelper;", - "import com.google.errorprone.BugPattern;", - "import com.google.errorprone.CompilationTestHelper;", - "import com.google.errorprone.util.ErrorProneToken;", - "import org.junit.jupiter.api.Test;", - "", - "class A {", - " void m(Object o) {", - " m(BugPattern.class.getCanonicalName());", - " m(ErrorProneToken.class.getCanonicalName());", - " m(ImmutableList.class.getCanonicalName());", - " m(String.class.getCanonicalName());", - " m(String.class.getCanonicalName() + \".toString\");", - "", - " m(\"com.google.errorprone.CompilationTestHelper\");", - " m(\"com.google.errorprone.BugCheckerRefactoringTestHelper.ExpectOutput\");", - " m(\"org.junit.jupiter.api.Test\");", - " m(\"org.junit.jupiter.api.Nested\");", - " }", - "}") + """ + import com.google.common.collect.ImmutableList; + import com.google.errorprone.BugCheckerRefactoringTestHelper; + import com.google.errorprone.BugPattern; + import com.google.errorprone.CompilationTestHelper; + import com.google.errorprone.util.ErrorProneToken; + import org.junit.jupiter.api.Test; + + class A { + void m(Object o) { + m(BugPattern.class.getCanonicalName()); + m(ErrorProneToken.class.getCanonicalName()); + m(ImmutableList.class.getCanonicalName()); + m(String.class.getCanonicalName()); + m(String.class.getCanonicalName() + ".toString"); + + m("com.google.errorprone.CompilationTestHelper"); + m("com.google.errorprone.BugCheckerRefactoringTestHelper.ExpectOutput"); + m("org.junit.jupiter.api.Test"); + m("org.junit.jupiter.api.Nested"); + } + } + """) .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 e6655d20429..020e1eeb596 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 @@ -18,58 +18,60 @@ void identification() { CompilationTestHelper.newInstance(ErrorProneTestHelperSourceFormat.class, getClass()) .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 {", - " void m() {", - " CompilationTestHelper.newInstance(EmptyMethod.class, getClass())", - " // 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();", - "", - " BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass())", - " // 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 { + void m() { + CompilationTestHelper.newInstance(EmptyMethod.class, getClass()) + // 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(); + + BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass()) + // 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(); } @@ -80,45 +82,47 @@ void identificationAvoidTextBlocks() { .setArgs("-XepOpt:ErrorProneTestHelperSourceFormat:AvoidTextBlocks=true") .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 {", - " void m() {", - " CompilationTestHelper.newInstance(EmptyMethod.class, getClass())", - " // 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();", - "", - " BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass())", - " // 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 { + void m() { + CompilationTestHelper.newInstance(EmptyMethod.class, getClass()) + // 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(); + + BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass()) + // 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(); } @@ -134,89 +138,93 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(ErrorProneTestHelperSourceFormat.class, getClass()) .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 {", - " void m() {", - " CompilationTestHelper.newInstance(EmptyMethod.class, getClass())", - " .addSourceLines(", - " \"A.java\",", - " \"\"\"", - " import java.util.Map;", - " import java.util.Collection;", - " import java.util.List;", - "", - " interface A extends List, Map { }\"\"\")", - " .addSourceLines(\"B.java\", \"class B {}\")", - " .doTest();", - "", - " BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass())", - " .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 { + void m() { + CompilationTestHelper.newInstance(EmptyMethod.class, getClass()) + .addSourceLines( + "A.java", + ""\" + import java.util.Map; + import java.util.Collection; + import java.util.List; + + interface A extends List, Map { }""\") + .addSourceLines("B.java", "class B {}") + .doTest(); + + BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass()) + .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 {", - " void m() {", - " CompilationTestHelper.newInstance(EmptyMethod.class, getClass())", - " .addSourceLines(", - " \"A.java\",", - " \"\"\"", - " import java.util.List;", - " import java.util.Map;", - "", - " interface A extends List, Map {}", - " \"\"\")", - " .addSourceLines(\"B.java\", \"\"\"", - " class B {}", - " \"\"\")", - " .doTest();", - "", - " BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass())", - " .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 { + void m() { + CompilationTestHelper.newInstance(EmptyMethod.class, getClass()) + .addSourceLines( + "A.java", + ""\" + import java.util.List; + import java.util.Map; + + interface A extends List, Map {} + ""\") + .addSourceLines("B.java", ""\" + class B {} + ""\") + .doTest(); + + BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass()) + .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); } @@ -230,76 +238,80 @@ void replacementAvoidTextBlocks() { .setArgs("-XepOpt:ErrorProneTestHelperSourceFormat:AvoidTextBlocks=true") .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 {", - " void m() {", - " CompilationTestHelper.newInstance(EmptyMethod.class, getClass())", - " .addSourceLines(", - " \"A.java\",", - " \"import java.util.Map;\",", - " \"import java.util.Collection;\",", - " \"import java.util.List;\",", - " \"\",", - " \"interface A extends List, Map { }\")", - " .doTest();", - "", - " BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass())", - " .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 { + void m() { + CompilationTestHelper.newInstance(EmptyMethod.class, getClass()) + .addSourceLines( + "A.java", + "import java.util.Map;", + "import java.util.Collection;", + "import java.util.List;", + "", + "interface A extends List, Map { }") + .doTest(); + + BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass()) + .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 {", - " void m() {", - " CompilationTestHelper.newInstance(EmptyMethod.class, getClass())", - " .addSourceLines(", - " \"A.java\",", - " \"import java.util.List;\",", - " \"import java.util.Map;\",", - " \"\",", - " \"interface A extends List, Map {}\")", - " .doTest();", - "", - " BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass())", - " .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 { + void m() { + CompilationTestHelper.newInstance(EmptyMethod.class, getClass()) + .addSourceLines( + "A.java", + "import java.util.List;", + "import java.util.Map;", + "", + "interface A extends List, Map {}") + .doTest(); + + BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass()) + .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 7afdf30ac3a..f0135228236 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 @@ -9,74 +9,76 @@ void identification() { CompilationTestHelper.newInstance(ExplicitEnumOrdering.class, getClass()) .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 bce223a2b49..41f435571a7 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 @@ -12,55 +12,57 @@ void identification() { CompilationTestHelper.newInstance(FluxFlatMapUsage.class, getClass()) .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(); } @@ -69,32 +71,36 @@ void replacementFirstSuggestedFix() { BugCheckerRefactoringTestHelper.newInstance(FluxFlatMapUsage.class, getClass()) .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); } @@ -104,32 +110,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/FluxImplicitBlockTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/FluxImplicitBlockTest.java index 91cecd34399..3dc7db5bcad 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/FluxImplicitBlockTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/FluxImplicitBlockTest.java @@ -21,36 +21,38 @@ void identification() { m -> Stream.of("SuppressWarnings", "toImmutableList", "toList").allMatch(m::contains)) .addSourceLines( "A.java", - "import com.google.common.collect.ImmutableList;", - "import java.util.stream.Stream;", - "import reactor.core.publisher.Flux;", - "", - "class A {", - " void m() {", - " // BUG: Diagnostic matches: X", - " Flux.just(1).toIterable();", - " // BUG: Diagnostic matches: X", - " Flux.just(2).toStream();", - " // BUG: Diagnostic matches: X", - " long count = Flux.just(3).toStream().count();", - "", - " Flux.just(4).toIterable(1);", - " Flux.just(5).toIterable(2, null);", - " Flux.just(6).toStream(3);", - " new Foo().toIterable();", - " new Foo().toStream();", - " }", - "", - " class Foo {", - " Iterable toIterable() {", - " return ImmutableList.of();", - " }", - "", - " Stream toStream() {", - " return Stream.empty();", - " }", - " }", - "}") + """ + import com.google.common.collect.ImmutableList; + import java.util.stream.Stream; + import reactor.core.publisher.Flux; + + class A { + void m() { + // BUG: Diagnostic matches: X + Flux.just(1).toIterable(); + // BUG: Diagnostic matches: X + Flux.just(2).toStream(); + // BUG: Diagnostic matches: X + long count = Flux.just(3).toStream().count(); + + Flux.just(4).toIterable(1); + Flux.just(5).toIterable(2, null); + Flux.just(6).toStream(3); + new Foo().toIterable(); + new Foo().toStream(); + } + + class Foo { + Iterable toIterable() { + return ImmutableList.of(); + } + + Stream toStream() { + return Stream.empty(); + } + } + } + """) .doTest(); } @@ -61,16 +63,18 @@ void identificationWithoutGuavaOnClasspath() { .expectErrorMessage("X", m -> !m.contains("toImmutableList")) .addSourceLines( "A.java", - "import reactor.core.publisher.Flux;", - "", - "class A {", - " void m() {", - " // BUG: Diagnostic matches: X", - " Flux.just(1).toIterable();", - " // BUG: Diagnostic matches: X", - " Flux.just(2).toStream();", - " }", - "}") + """ + import reactor.core.publisher.Flux; + + class A { + void m() { + // BUG: Diagnostic matches: X + Flux.just(1).toIterable(); + // BUG: Diagnostic matches: X + Flux.just(2).toStream(); + } + } + """) .doTest(); } @@ -79,25 +83,29 @@ void replacementFirstSuggestedFix() { BugCheckerRefactoringTestHelper.newInstance(FluxImplicitBlock.class, getClass()) .addInputLines( "A.java", - "import reactor.core.publisher.Flux;", - "", - "class A {", - " void m() {", - " Flux.just(1).toIterable();", - " Flux.just(2).toStream();", - " }", - "}") + """ + import reactor.core.publisher.Flux; + + class A { + void m() { + Flux.just(1).toIterable(); + Flux.just(2).toStream(); + } + } + """) .addOutputLines( "A.java", - "import reactor.core.publisher.Flux;", - "", - "class A {", - " @SuppressWarnings(\"FluxImplicitBlock\")", - " void m() {", - " Flux.just(1).toIterable();", - " Flux.just(2).toStream();", - " }", - "}") + """ + import reactor.core.publisher.Flux; + + class A { + @SuppressWarnings("FluxImplicitBlock") + void m() { + Flux.just(1).toIterable(); + Flux.just(2).toStream(); + } + } + """) .doTest(TestMode.TEXT_MATCH); } @@ -107,34 +115,38 @@ void replacementSecondSuggestedFix() { .setFixChooser(SECOND) .addInputLines( "A.java", - "import reactor.core.publisher.Flux;", - "", - "class A {", - " void m() {", - " Flux.just(1).toIterable();", - " Flux.just(2).toStream();", - " Flux.just(3).toIterable().iterator();", - " Flux.just(4).toStream().count();", - " Flux.just(5) /* a */./* b */ toIterable /* c */(/* d */ ) /* e */;", - " Flux.just(6) /* a */./* b */ toStream /* c */(/* d */ ) /* e */;", - " }", - "}") + """ + import reactor.core.publisher.Flux; + + class A { + void m() { + Flux.just(1).toIterable(); + Flux.just(2).toStream(); + Flux.just(3).toIterable().iterator(); + Flux.just(4).toStream().count(); + Flux.just(5) /* a */./* b */ toIterable /* c */(/* d */ ) /* e */; + Flux.just(6) /* a */./* b */ toStream /* c */(/* d */ ) /* e */; + } + } + """) .addOutputLines( "A.java", - "import static com.google.common.collect.ImmutableList.toImmutableList;", - "", - "import reactor.core.publisher.Flux;", - "", - "class A {", - " void m() {", - " Flux.just(1).collect(toImmutableList()).block();", - " Flux.just(2).collect(toImmutableList()).block().stream();", - " Flux.just(3).collect(toImmutableList()).block().iterator();", - " Flux.just(4).collect(toImmutableList()).block().stream().count();", - " Flux.just(5).collect(toImmutableList()).block() /* e */;", - " Flux.just(6).collect(toImmutableList()).block().stream() /* e */;", - " }", - "}") + """ + import static com.google.common.collect.ImmutableList.toImmutableList; + + import reactor.core.publisher.Flux; + + class A { + void m() { + Flux.just(1).collect(toImmutableList()).block(); + Flux.just(2).collect(toImmutableList()).block().stream(); + Flux.just(3).collect(toImmutableList()).block().iterator(); + Flux.just(4).collect(toImmutableList()).block().stream().count(); + Flux.just(5).collect(toImmutableList()).block() /* e */; + Flux.just(6).collect(toImmutableList()).block().stream() /* e */; + } + } + """) .doTest(TestMode.TEXT_MATCH); } @@ -144,34 +156,38 @@ void replacementThirdSuggestedFix() { .setFixChooser(THIRD) .addInputLines( "A.java", - "import reactor.core.publisher.Flux;", - "", - "class A {", - " void m() {", - " Flux.just(1).toIterable();", - " Flux.just(2).toStream();", - " Flux.just(3).toIterable().iterator();", - " Flux.just(4).toStream().count();", - " Flux.just(5) /* a */./* b */ toIterable /* c */(/* d */ ) /* e */;", - " Flux.just(6) /* a */./* b */ toStream /* c */(/* d */ ) /* e */;", - " }", - "}") + """ + import reactor.core.publisher.Flux; + + class A { + void m() { + Flux.just(1).toIterable(); + Flux.just(2).toStream(); + Flux.just(3).toIterable().iterator(); + Flux.just(4).toStream().count(); + Flux.just(5) /* a */./* b */ toIterable /* c */(/* d */ ) /* e */; + Flux.just(6) /* a */./* b */ toStream /* c */(/* d */ ) /* e */; + } + } + """) .addOutputLines( "A.java", - "import static java.util.stream.Collectors.toList;", - "", - "import reactor.core.publisher.Flux;", - "", - "class A {", - " void m() {", - " Flux.just(1).collect(toList()).block();", - " Flux.just(2).collect(toList()).block().stream();", - " Flux.just(3).collect(toList()).block().iterator();", - " Flux.just(4).collect(toList()).block().stream().count();", - " Flux.just(5).collect(toList()).block() /* e */;", - " Flux.just(6).collect(toList()).block().stream() /* e */;", - " }", - "}") + """ + import static java.util.stream.Collectors.toList; + + import reactor.core.publisher.Flux; + + class A { + void m() { + Flux.just(1).collect(toList()).block(); + Flux.just(2).collect(toList()).block().stream(); + Flux.just(3).collect(toList()).block().iterator(); + Flux.just(4).collect(toList()).block().stream().count(); + Flux.just(5).collect(toList()).block() /* e */; + Flux.just(6).collect(toList()).block().stream() /* e */; + } + } + """) .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 cf300ebf4de..737fab3d3d9 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 @@ -11,294 +11,296 @@ void identification() { CompilationTestHelper.newInstance(FormatStringConcatenation.class, getClass()) .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(); } @@ -307,102 +309,106 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(FormatStringConcatenation.class, getClass()) .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 631acdad68e..b354890d31e 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 @@ -12,168 +12,170 @@ void identification() { CompilationTestHelper.newInstance(IdentityConversion.class, getClass()) .addSourceLines( "A.java", - "import static com.google.errorprone.matchers.Matchers.instanceMethod;", - "import static com.google.errorprone.matchers.Matchers.staticMethod;", - "", - "import com.google.common.collect.ImmutableBiMap;", - "import com.google.common.collect.ImmutableList;", - "import com.google.common.collect.ImmutableListMultimap;", - "import com.google.common.collect.ImmutableMap;", - "import com.google.common.collect.ImmutableMultimap;", - "import com.google.common.collect.ImmutableMultiset;", - "import com.google.common.collect.ImmutableRangeMap;", - "import com.google.common.collect.ImmutableRangeSet;", - "import com.google.common.collect.ImmutableSet;", - "import com.google.common.collect.ImmutableSetMultimap;", - "import com.google.common.collect.ImmutableTable;", - "import com.google.errorprone.matchers.Matcher;", - "import com.google.errorprone.matchers.Matchers;", - "import reactor.adapter.rxjava.RxJava2Adapter;", - "import reactor.core.publisher.Flux;", - "import reactor.core.publisher.Mono;", - "", - "public final class A {", - " public void m() {", - " // BUG: Diagnostic contains:", - " Boolean b1 = Boolean.valueOf(Boolean.FALSE);", - " // BUG: Diagnostic contains:", - " Boolean b2 = Boolean.valueOf(false);", - " // BUG: Diagnostic contains:", - " boolean b3 = Boolean.valueOf(Boolean.FALSE);", - " // BUG: Diagnostic contains:", - " boolean b4 = Boolean.valueOf(false);", - "", - " // BUG: Diagnostic contains:", - " Byte byte1 = Byte.valueOf((Byte) Byte.MIN_VALUE);", - " // BUG: Diagnostic contains:", - " Byte byte2 = Byte.valueOf(Byte.MIN_VALUE);", - " // BUG: Diagnostic contains:", - " byte byte3 = Byte.valueOf((Byte) Byte.MIN_VALUE);", - " // BUG: Diagnostic contains:", - " byte byte4 = Byte.valueOf(Byte.MIN_VALUE);", - "", - " // BUG: Diagnostic contains:", - " Character c1 = Character.valueOf((Character) 'a');", - " // BUG: Diagnostic contains:", - " Character c2 = Character.valueOf('a');", - " // BUG: Diagnostic contains:", - " char c3 = Character.valueOf((Character) 'a');", - " // BUG: Diagnostic contains:", - " char c4 = Character.valueOf('a');", - "", - " // BUG: Diagnostic contains:", - " Double d1 = Double.valueOf((Double) 0.0);", - " // BUG: Diagnostic contains:", - " Double d2 = Double.valueOf(0.0);", - " // BUG: Diagnostic contains:", - " double d3 = Double.valueOf((Double) 0.0);", - " // BUG: Diagnostic contains:", - " double d4 = Double.valueOf(0.0);", - "", - " // BUG: Diagnostic contains:", - " Float f1 = Float.valueOf((Float) 0.0F);", - " // BUG: Diagnostic contains:", - " Float f2 = Float.valueOf(0.0F);", - " // BUG: Diagnostic contains:", - " float f3 = Float.valueOf((Float) 0.0F);", - " // BUG: Diagnostic contains:", - " float f4 = Float.valueOf(0.0F);", - "", - " // BUG: Diagnostic contains:", - " Integer i1 = Integer.valueOf((Integer) 1);", - " // BUG: Diagnostic contains:", - " Integer i2 = Integer.valueOf(1);", - " // BUG: Diagnostic contains:", - " int i3 = Integer.valueOf((Integer) 1);", - " // BUG: Diagnostic contains:", - " int i4 = Integer.valueOf(1);", - "", - " // BUG: Diagnostic contains:", - " Long l1 = Long.valueOf((Long) 1L);", - " // BUG: Diagnostic contains:", - " Long l2 = Long.valueOf(1L);", - " // BUG: Diagnostic contains:", - " long l3 = Long.valueOf((Long) 1L);", - " // BUG: Diagnostic contains:", - " long l4 = Long.valueOf(1L);", - "", - " Long l5 = Long.valueOf((Integer) 1);", - " Long l6 = Long.valueOf(1);", - " // BUG: Diagnostic contains:", - " long l7 = Long.valueOf((Integer) 1);", - " // BUG: Diagnostic contains:", - " long l8 = Long.valueOf(1);", - "", - " // BUG: Diagnostic contains:", - " Short s1 = Short.valueOf((Short) Short.MIN_VALUE);", - " // BUG: Diagnostic contains:", - " Short s2 = Short.valueOf(Short.MIN_VALUE);", - " // BUG: Diagnostic contains:", - " short s3 = Short.valueOf((Short) Short.MIN_VALUE);", - " // BUG: Diagnostic contains:", - " short s4 = Short.valueOf(Short.MIN_VALUE);", - "", - " // BUG: Diagnostic contains:", - " String boolStr = Boolean.valueOf(Boolean.FALSE).toString();", - " int boolHash = Boolean.valueOf(false).hashCode();", - " // BUG: Diagnostic contains:", - " int byteHash = Byte.valueOf((Byte) Byte.MIN_VALUE).hashCode();", - " String byteStr = Byte.valueOf(Byte.MIN_VALUE).toString();", - "", - " String str1 = String.valueOf(0);", - " // BUG: Diagnostic contains:", - " String str2 = String.valueOf(\"1\");", - "", - " // BUG: Diagnostic contains:", - " ImmutableBiMap 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:", - " Matcher allOf1 = Matchers.allOf(instanceMethod());", - " Matcher allOf2 = Matchers.allOf(instanceMethod(), staticMethod());", - " // BUG: Diagnostic contains:", - " Matcher anyOf1 = Matchers.anyOf(staticMethod());", - " Matcher anyOf2 = Matchers.anyOf(instanceMethod(), staticMethod());", - "", - " // BUG: Diagnostic contains:", - " 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 mono1 = Mono.from(Mono.just(1));", - " // BUG: Diagnostic contains:", - " Mono mono2 = Mono.fromDirect(Mono.just(1));", - " }", - "}") + """ + import static com.google.errorprone.matchers.Matchers.instanceMethod; + import static com.google.errorprone.matchers.Matchers.staticMethod; + + import com.google.common.collect.ImmutableBiMap; + import com.google.common.collect.ImmutableList; + import com.google.common.collect.ImmutableListMultimap; + import com.google.common.collect.ImmutableMap; + import com.google.common.collect.ImmutableMultimap; + import com.google.common.collect.ImmutableMultiset; + import com.google.common.collect.ImmutableRangeMap; + import com.google.common.collect.ImmutableRangeSet; + import com.google.common.collect.ImmutableSet; + import com.google.common.collect.ImmutableSetMultimap; + import com.google.common.collect.ImmutableTable; + import com.google.errorprone.matchers.Matcher; + import com.google.errorprone.matchers.Matchers; + import reactor.adapter.rxjava.RxJava2Adapter; + import reactor.core.publisher.Flux; + import reactor.core.publisher.Mono; + + public final class A { + public void m() { + // BUG: Diagnostic contains: + Boolean b1 = Boolean.valueOf(Boolean.FALSE); + // BUG: Diagnostic contains: + Boolean b2 = Boolean.valueOf(false); + // BUG: Diagnostic contains: + boolean b3 = Boolean.valueOf(Boolean.FALSE); + // BUG: Diagnostic contains: + boolean b4 = Boolean.valueOf(false); + + // BUG: Diagnostic contains: + Byte byte1 = Byte.valueOf((Byte) Byte.MIN_VALUE); + // BUG: Diagnostic contains: + Byte byte2 = Byte.valueOf(Byte.MIN_VALUE); + // BUG: Diagnostic contains: + byte byte3 = Byte.valueOf((Byte) Byte.MIN_VALUE); + // BUG: Diagnostic contains: + byte byte4 = Byte.valueOf(Byte.MIN_VALUE); + + // BUG: Diagnostic contains: + Character c1 = Character.valueOf((Character) 'a'); + // BUG: Diagnostic contains: + Character c2 = Character.valueOf('a'); + // BUG: Diagnostic contains: + char c3 = Character.valueOf((Character) 'a'); + // BUG: Diagnostic contains: + char c4 = Character.valueOf('a'); + + // BUG: Diagnostic contains: + Double d1 = Double.valueOf((Double) 0.0); + // BUG: Diagnostic contains: + Double d2 = Double.valueOf(0.0); + // BUG: Diagnostic contains: + double d3 = Double.valueOf((Double) 0.0); + // BUG: Diagnostic contains: + double d4 = Double.valueOf(0.0); + + // BUG: Diagnostic contains: + Float f1 = Float.valueOf((Float) 0.0F); + // BUG: Diagnostic contains: + Float f2 = Float.valueOf(0.0F); + // BUG: Diagnostic contains: + float f3 = Float.valueOf((Float) 0.0F); + // BUG: Diagnostic contains: + float f4 = Float.valueOf(0.0F); + + // BUG: Diagnostic contains: + Integer i1 = Integer.valueOf((Integer) 1); + // BUG: Diagnostic contains: + Integer i2 = Integer.valueOf(1); + // BUG: Diagnostic contains: + int i3 = Integer.valueOf((Integer) 1); + // BUG: Diagnostic contains: + int i4 = Integer.valueOf(1); + + // BUG: Diagnostic contains: + Long l1 = Long.valueOf((Long) 1L); + // BUG: Diagnostic contains: + Long l2 = Long.valueOf(1L); + // BUG: Diagnostic contains: + long l3 = Long.valueOf((Long) 1L); + // BUG: Diagnostic contains: + long l4 = Long.valueOf(1L); + + Long l5 = Long.valueOf((Integer) 1); + Long l6 = Long.valueOf(1); + // BUG: Diagnostic contains: + long l7 = Long.valueOf((Integer) 1); + // BUG: Diagnostic contains: + long l8 = Long.valueOf(1); + + // BUG: Diagnostic contains: + Short s1 = Short.valueOf((Short) Short.MIN_VALUE); + // BUG: Diagnostic contains: + Short s2 = Short.valueOf(Short.MIN_VALUE); + // BUG: Diagnostic contains: + short s3 = Short.valueOf((Short) Short.MIN_VALUE); + // BUG: Diagnostic contains: + short s4 = Short.valueOf(Short.MIN_VALUE); + + // BUG: Diagnostic contains: + String boolStr = Boolean.valueOf(Boolean.FALSE).toString(); + int boolHash = Boolean.valueOf(false).hashCode(); + // BUG: Diagnostic contains: + int byteHash = Byte.valueOf((Byte) Byte.MIN_VALUE).hashCode(); + String byteStr = Byte.valueOf(Byte.MIN_VALUE).toString(); + + String str1 = String.valueOf(0); + // BUG: Diagnostic contains: + String str2 = String.valueOf("1"); + + // BUG: Diagnostic contains: + ImmutableBiMap 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: + Matcher allOf1 = Matchers.allOf(instanceMethod()); + Matcher allOf2 = Matchers.allOf(instanceMethod(), staticMethod()); + // BUG: Diagnostic contains: + Matcher anyOf1 = Matchers.anyOf(staticMethod()); + Matcher anyOf2 = Matchers.anyOf(instanceMethod(), staticMethod()); + + // BUG: Diagnostic contains: + 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 mono1 = Mono.from(Mono.just(1)); + // BUG: Diagnostic contains: + Mono mono2 = Mono.fromDirect(Mono.just(1)); + } + } + """) .doTest(); } @@ -182,104 +184,108 @@ void replacementFirstSuggestedFix() { BugCheckerRefactoringTestHelper.newInstance(IdentityConversion.class, getClass()) .addInputLines( "A.java", - "import static com.google.errorprone.matchers.Matchers.staticMethod;", - "import static org.mockito.Mockito.when;", - "", - "import com.google.common.collect.ImmutableCollection;", - "import com.google.common.collect.ImmutableList;", - "import com.google.common.collect.ImmutableSet;", - "import com.google.errorprone.matchers.Matcher;", - "import com.google.errorprone.matchers.Matchers;", - "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 A {", - " public void m() {", - " 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());", - "", - " Matcher matcher = Matchers.allOf(staticMethod());", - "", - " when(\"foo\".contains(\"f\")).thenAnswer(inv -> ImmutableSet.copyOf(ImmutableList.of(1)));", - " }", - "", - " void bar(Publisher publisher) {}", - "}") + """ + import static com.google.errorprone.matchers.Matchers.staticMethod; + import static org.mockito.Mockito.when; + + import com.google.common.collect.ImmutableCollection; + import com.google.common.collect.ImmutableList; + import com.google.common.collect.ImmutableSet; + import com.google.errorprone.matchers.Matcher; + import com.google.errorprone.matchers.Matchers; + 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 A { + public void m() { + 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()); + + Matcher matcher = Matchers.allOf(staticMethod()); + + when("foo".contains("f")).thenAnswer(inv -> ImmutableSet.copyOf(ImmutableList.of(1))); + } + + void bar(Publisher publisher) {} + } + """) .addOutputLines( "A.java", - "import static com.google.errorprone.matchers.Matchers.staticMethod;", - "import static org.mockito.Mockito.when;", - "", - "import com.google.common.collect.ImmutableCollection;", - "import com.google.common.collect.ImmutableList;", - "import com.google.common.collect.ImmutableSet;", - "import com.google.errorprone.matchers.Matcher;", - "import com.google.errorprone.matchers.Matchers;", - "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 A {", - " public void m() {", - " 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();", - "", - " Matcher matcher = staticMethod();", - "", - " when(\"foo\".contains(\"f\")).thenAnswer(inv -> ImmutableSet.copyOf(ImmutableList.of(1)));", - " }", - "", - " void bar(Publisher publisher) {}", - "}") + """ + import static com.google.errorprone.matchers.Matchers.staticMethod; + import static org.mockito.Mockito.when; + + import com.google.common.collect.ImmutableCollection; + import com.google.common.collect.ImmutableList; + import com.google.common.collect.ImmutableSet; + import com.google.errorprone.matchers.Matcher; + import com.google.errorprone.matchers.Matchers; + 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 A { + public void m() { + 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(); + + Matcher matcher = staticMethod(); + + when("foo".contains("f")).thenAnswer(inv -> ImmutableSet.copyOf(ImmutableList.of(1))); + } + + void bar(Publisher publisher) {} + } + """) .doTest(TestMode.TEXT_MATCH); } @@ -289,38 +295,42 @@ void replacementSecondSuggestedFix() { .setFixChooser(FixChoosers.SECOND) .addInputLines( "A.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 A {", - " public void m() {", - " 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 A { + public void m() { + 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( "A.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 A {", - " public void m() {", - " @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 A { + public void m() { + @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 b77767af845..486fec3880e 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 @@ -11,94 +11,96 @@ void identification() { CompilationTestHelper.newInstance(ImmutablesSortedSetComparator.class, getClass()) .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(); } @@ -107,36 +109,40 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(ImmutablesSortedSetComparator.class, getClass()) .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); } @@ -145,33 +151,37 @@ void replacementWithImportClash() { BugCheckerRefactoringTestHelper.newInstance(ImmutablesSortedSetComparator.class, getClass()) .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 a6204c5abf8..9b407cccf44 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 @@ -11,31 +11,33 @@ void identification() { CompilationTestHelper.newInstance(IsInstanceLambdaUsage.class, getClass()) .addSourceLines( "A.java", - "import java.util.stream.Stream;", - "import reactor.core.publisher.Flux;", - "", - "class A {", - " void m() {", - " Integer localVariable = 0;", - "", - " Stream.of(0).map(i -> i + 1);", - " Stream.of(1).filter(Integer.class::isInstance);", - " Stream.of(2).filter(i -> i.getClass() instanceof Class);", - " Stream.of(3).filter(i -> localVariable instanceof Integer);", - " // XXX: Ideally this case is also flagged. Pick this up in the context of merging the", - " // `IsInstanceLambdaUsage` and `MethodReferenceUsage` checks, or introduce a separate check that", - " // simplifies unnecessary block lambda expressions.", - " Stream.of(4)", - " .filter(", - " i -> {", - " return localVariable instanceof Integer;", - " });", - " Flux.just(5, \"foo\").distinctUntilChanged(v -> v, (a, b) -> a instanceof Integer);", - "", - " // BUG: Diagnostic contains:", - " Stream.of(6).filter(i -> i instanceof Integer);", - " }", - "}") + """ + import java.util.stream.Stream; + import reactor.core.publisher.Flux; + + class A { + void m() { + Integer localVariable = 0; + + Stream.of(0).map(i -> i + 1); + Stream.of(1).filter(Integer.class::isInstance); + Stream.of(2).filter(i -> i.getClass() instanceof Class); + Stream.of(3).filter(i -> localVariable instanceof Integer); + // XXX: Ideally this case is also flagged. Pick this up in the context of merging the + // `IsInstanceLambdaUsage` and `MethodReferenceUsage` checks, or introduce a separate check that + // simplifies unnecessary block lambda expressions. + Stream.of(4) + .filter( + i -> { + return localVariable instanceof Integer; + }); + Flux.just(5, "foo").distinctUntilChanged(v -> v, (a, b) -> a instanceof Integer); + + // BUG: Diagnostic contains: + Stream.of(6).filter(i -> i instanceof Integer); + } + } + """) .doTest(); } @@ -44,22 +46,26 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(IsInstanceLambdaUsage.class, getClass()) .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/JUnitClassModifiersTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/JUnitClassModifiersTest.java index 7d2ab285370..632c34f5bca 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/JUnitClassModifiersTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/JUnitClassModifiersTest.java @@ -11,83 +11,85 @@ void identification() { CompilationTestHelper.newInstance(JUnitClassModifiers.class, getClass()) .addSourceLines( "Container.java", - "import org.junit.jupiter.api.Test;", - "import org.junit.jupiter.params.ParameterizedTest;", - "import org.springframework.boot.test.context.TestConfiguration;", - "import org.springframework.context.annotation.Configuration;", - "", - "class Container {", - " final class FinalAndPackagePrivate {", - " @Test", - " void foo() {}", - " }", - "", - " final class FinalAndPackagePrivateWithCustomTestMethod {", - " @ParameterizedTest", - " void foo() {}", - " }", - "", - " public abstract class Abstract {", - " @Test", - " void foo() {}", - " }", - "", - " @Configuration", - " class WithConfigurationAnnotation {", - " @Test", - " void foo() {}", - " }", - "", - " @TestConfiguration", - " class WithConfigurationMetaAnnotation {", - " @Test", - " void foo() {}", - " }", - "", - " // BUG: Diagnostic contains:", - " private final class Private {", - " @Test", - " void foo() {}", - " }", - "", - " // BUG: Diagnostic contains:", - " protected final class Protected {", - " @Test", - " void foo() {}", - " }", - "", - " // BUG: Diagnostic contains:", - " public final class Public {", - " @Test", - " void foo() {}", - " }", - "", - " // BUG: Diagnostic contains:", - " class NonFinal {", - " @Test", - " void foo() {}", - " }", - "", - " // BUG: Diagnostic contains:", - " class NonFinalWithCustomTestMethod {", - " @ParameterizedTest", - " void foo() {}", - " }", - "", - " @Configuration", - " // BUG: Diagnostic contains:", - " public class PublicWithConfigurationAnnotation {", - " @Test", - " void foo() {}", - " }", - "", - " @TestConfiguration", - " // BUG: Diagnostic contains:", - " protected class ProtectedWithConfigurationMetaAnnotation {", - " @Test", - " void foo() {}", - " }", - "}") + """ + import org.junit.jupiter.api.Test; + import org.junit.jupiter.params.ParameterizedTest; + import org.springframework.boot.test.context.TestConfiguration; + import org.springframework.context.annotation.Configuration; + + class Container { + final class FinalAndPackagePrivate { + @Test + void foo() {} + } + + final class FinalAndPackagePrivateWithCustomTestMethod { + @ParameterizedTest + void foo() {} + } + + public abstract class Abstract { + @Test + void foo() {} + } + + @Configuration + class WithConfigurationAnnotation { + @Test + void foo() {} + } + + @TestConfiguration + class WithConfigurationMetaAnnotation { + @Test + void foo() {} + } + + // BUG: Diagnostic contains: + private final class Private { + @Test + void foo() {} + } + + // BUG: Diagnostic contains: + protected final class Protected { + @Test + void foo() {} + } + + // BUG: Diagnostic contains: + public final class Public { + @Test + void foo() {} + } + + // BUG: Diagnostic contains: + class NonFinal { + @Test + void foo() {} + } + + // BUG: Diagnostic contains: + class NonFinalWithCustomTestMethod { + @ParameterizedTest + void foo() {} + } + + @Configuration + // BUG: Diagnostic contains: + public class PublicWithConfigurationAnnotation { + @Test + void foo() {} + } + + @TestConfiguration + // BUG: Diagnostic contains: + protected class ProtectedWithConfigurationMetaAnnotation { + @Test + void foo() {} + } + } + """) .doTest(); } @@ -96,34 +98,38 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(JUnitClassModifiers.class, getClass()) .addInputLines( "A.java", - "import org.junit.jupiter.api.Test;", - "import org.springframework.context.annotation.Configuration;", - "", - "public class A {", - " @Test", - " void foo() {}", - "", - " @Configuration", - " private static class B {", - " @Test", - " void bar() {}", - " }", - "}") + """ + import org.junit.jupiter.api.Test; + import org.springframework.context.annotation.Configuration; + + public class A { + @Test + void foo() {} + + @Configuration + private static class B { + @Test + void bar() {} + } + } + """) .addOutputLines( "A.java", - "import org.junit.jupiter.api.Test;", - "import org.springframework.context.annotation.Configuration;", - "", - "final class A {", - " @Test", - " void foo() {}", - "", - " @Configuration", - " static class B {", - " @Test", - " void bar() {}", - " }", - "}") + """ + import org.junit.jupiter.api.Test; + import org.springframework.context.annotation.Configuration; + + final class A { + @Test + void foo() {} + + @Configuration + static class B { + @Test + void bar() {} + } + } + """) .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 b4c016da5fa..6fe485bceef 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 @@ -11,330 +11,336 @@ void identification() { CompilationTestHelper.newInstance(JUnitMethodDeclaration.class, getClass()) .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 test() {}", - "", - " @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 `toString` is already defined in this", - " // class or a supertype)", - " void testToString() {}", - "", - " @Test", - " // BUG: Diagnostic contains: (but note that a method named `overload` is already defined in this", - " // class or a supertype)", - " 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 not a valid identifier)", - " void testPublic() {}", - "", - " @Test", - " // BUG: Diagnostic contains: (but note that `null` is not a valid identifier)", - " void testNull() {}", - "", - " @Test", - " // BUG: Diagnostic contains:", - " void testRecord() {}", - "", - " @Test", - " // BUG: Diagnostic contains:", - " void testMethodThatIsOverriddenWithoutOverrideAnnotation() {}", - "}") + """ + 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 test() {} + + @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 `toString` is already defined in this + // class or a supertype) + void testToString() {} + + @Test + // BUG: Diagnostic contains: (but note that a method named `overload` is already defined in this + // class or a supertype) + 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 not a valid identifier) + void testPublic() {} + + @Test + // BUG: Diagnostic contains: (but note that `null` is not a valid identifier) + void testNull() {} + + @Test + // BUG: Diagnostic contains: + void testRecord() {} + + @Test + // BUG: Diagnostic contains: + void testMethodThatIsOverriddenWithoutOverrideAnnotation() {} + } + """) .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 test() {}", - "", - " @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 testToString() {}", - "", - " @Override", - " @Test", - " void testOverload() {}", - "", - " @Override", - " void overload() {}", - "", - " @Override", - " @Test", - " void testArguments() {}", - "", - " @Override", - " @Test", - " void testPublic() {}", - "", - " @Override", - " @Test", - " void testNull() {}", - "", - " @Override", - " @Test", - " void testRecord() {}", - "", - " @Test", - " void testMethodThatIsOverriddenWithoutOverrideAnnotation() {}", - "}") + """ + 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 test() {} + + @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 testToString() {} + + @Override + @Test + void testOverload() {} + + @Override + void overload() {} + + @Override + @Test + void testArguments() {} + + @Override + @Test + void testPublic() {} + + @Override + @Test + void testNull() {} + + @Override + @Test + void testRecord() {} + + @Test + void testMethodThatIsOverriddenWithoutOverrideAnnotation() {} + } + """) .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(); } @@ -343,126 +349,130 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(JUnitMethodDeclaration.class, getClass()) .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 testToString() {}", - "", - " @Test", - " public void testOverload() {}", - "", - " void overload() {}", - "", - " @Test", - " protected void testArguments() {}", - "", - " @Test", - " private void testClass() {}", - "", - " @Test", - " private void testTrue() {}", - "}") + """ + 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 testToString() {} + + @Test + public void testOverload() {} + + void overload() {} + + @Test + protected void testArguments() {} + + @Test + private void testClass() {} + + @Test + private void testTrue() {} + } + """) .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 testToString() {}", - "", - " @Test", - " void testOverload() {}", - "", - " void overload() {}", - "", - " @Test", - " void testArguments() {}", - "", - " @Test", - " void testClass() {}", - "", - " @Test", - " void testTrue() {}", - "}") + """ + 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 testToString() {} + + @Test + void testOverload() {} + + void overload() {} + + @Test + void testArguments() {} + + @Test + void testClass() {} + + @Test + void testTrue() {} + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/JUnitNullaryParameterizedTestDeclarationTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/JUnitNullaryParameterizedTestDeclarationTest.java index ba46a7d4f11..4df791bd2a0 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/JUnitNullaryParameterizedTestDeclarationTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/JUnitNullaryParameterizedTestDeclarationTest.java @@ -11,25 +11,27 @@ void identification() { CompilationTestHelper.newInstance(JUnitNullaryParameterizedTestDeclaration.class, getClass()) .addSourceLines( "A.java", - "import org.junit.jupiter.api.Test;", - "import org.junit.jupiter.params.ParameterizedTest;", - "import org.junit.jupiter.params.provider.ValueSource;", - "", - "class A {", - " void nonTest() {}", - "", - " @Test", - " void nonParameterizedTest() {}", - "", - " @ParameterizedTest", - " @ValueSource(ints = {0, 1})", - " void goodParameterizedTest(int someInt) {}", - "", - " @ParameterizedTest", - " @ValueSource(ints = {0, 1})", - " // BUG: Diagnostic contains:", - " void nullaryParameterizedTest() {}", - "}") + """ + import org.junit.jupiter.api.Test; + import org.junit.jupiter.params.ParameterizedTest; + import org.junit.jupiter.params.provider.ValueSource; + + class A { + void nonTest() {} + + @Test + void nonParameterizedTest() {} + + @ParameterizedTest + @ValueSource(ints = {0, 1}) + void goodParameterizedTest(int someInt) {} + + @ParameterizedTest + @ValueSource(ints = {0, 1}) + // BUG: Diagnostic contains: + void nullaryParameterizedTest() {} + } + """) .doTest(); } @@ -39,117 +41,125 @@ void replacement() { JUnitNullaryParameterizedTestDeclaration.class, getClass()) .addInputLines( "A.java", - "import org.junit.jupiter.params.ParameterizedTest;", - "import org.junit.jupiter.params.provider.ArgumentsProvider;", - "import org.junit.jupiter.params.provider.ArgumentsSource;", - "import org.junit.jupiter.params.provider.ArgumentsSources;", - "import org.junit.jupiter.params.provider.MethodSource;", - "import org.junit.jupiter.params.provider.ValueSource;", - "", - "class A {", - " @ParameterizedTest", - " void withoutArgumentSource() {}", - "", - " @ParameterizedTest", - " @ArgumentsSource(ArgumentsProvider.class)", - " void withCustomArgumentSource() {}", - "", - " @ParameterizedTest", - " @ArgumentsSources({", - " @ArgumentsSource(ArgumentsProvider.class),", - " @ArgumentsSource(ArgumentsProvider.class)", - " })", - " void withCustomerArgumentSources() {}", - "", - " /** Foo. */", - " @ParameterizedTest", - " @ValueSource(ints = {0, 1})", - " void withValueSourceAndJavadoc() {}", - "", - " @ParameterizedTest", - " @MethodSource(\"nonexistentMethod\")", - " @SuppressWarnings(\"foo\")", - " void withMethodSourceAndUnrelatedAnnotation() {}", - "", - " @org.junit.jupiter.params.ParameterizedTest", - " @ArgumentsSource(ArgumentsProvider.class)", - " @ValueSource(ints = {0, 1})", - " @MethodSource(\"nonexistentMethod\")", - " void withMultipleArgumentSourcesAndFullyQualifiedImport() {}", - "", - " class NestedWithTestAnnotationFirst {", - " @ParameterizedTest", - " @ValueSource(ints = {0, 1})", - " void withValueSource() {}", - " }", - "", - " class NestedWithTestAnnotationSecond {", - " @ValueSource(ints = {0, 1})", - " @ParameterizedTest", - " void withValueSource() {}", - " }", - "}") + """ + import org.junit.jupiter.params.ParameterizedTest; + import org.junit.jupiter.params.provider.ArgumentsProvider; + import org.junit.jupiter.params.provider.ArgumentsSource; + import org.junit.jupiter.params.provider.ArgumentsSources; + import org.junit.jupiter.params.provider.MethodSource; + import org.junit.jupiter.params.provider.ValueSource; + + class A { + @ParameterizedTest + void withoutArgumentSource() {} + + @ParameterizedTest + @ArgumentsSource(ArgumentsProvider.class) + void withCustomArgumentSource() {} + + @ParameterizedTest + @ArgumentsSources({ + @ArgumentsSource(ArgumentsProvider.class), + @ArgumentsSource(ArgumentsProvider.class) + }) + void withCustomerArgumentSources() {} + + /** Foo. */ + @ParameterizedTest + @ValueSource(ints = {0, 1}) + void withValueSourceAndJavadoc() {} + + @ParameterizedTest + @MethodSource("nonexistentMethod") + @SuppressWarnings("foo") + void withMethodSourceAndUnrelatedAnnotation() {} + + @org.junit.jupiter.params.ParameterizedTest + @ArgumentsSource(ArgumentsProvider.class) + @ValueSource(ints = {0, 1}) + @MethodSource("nonexistentMethod") + void withMultipleArgumentSourcesAndFullyQualifiedImport() {} + + class NestedWithTestAnnotationFirst { + @ParameterizedTest + @ValueSource(ints = {0, 1}) + void withValueSource() {} + } + + class NestedWithTestAnnotationSecond { + @ValueSource(ints = {0, 1}) + @ParameterizedTest + void withValueSource() {} + } + } + """) .addOutputLines( "A.java", - "import org.junit.jupiter.api.Test;", - "import org.junit.jupiter.params.ParameterizedTest;", - "import org.junit.jupiter.params.provider.ArgumentsProvider;", - "import org.junit.jupiter.params.provider.ArgumentsSource;", - "import org.junit.jupiter.params.provider.ArgumentsSources;", - "import org.junit.jupiter.params.provider.MethodSource;", - "import org.junit.jupiter.params.provider.ValueSource;", - "", - "class A {", - " @Test", - " void withoutArgumentSource() {}", - "", - " @Test", - " void withCustomArgumentSource() {}", - "", - " @Test", - " void withCustomerArgumentSources() {}", - "", - " /** Foo. */", - " @Test", - " void withValueSourceAndJavadoc() {}", - "", - " @Test", - " @SuppressWarnings(\"foo\")", - " void withMethodSourceAndUnrelatedAnnotation() {}", - "", - " @Test", - " void withMultipleArgumentSourcesAndFullyQualifiedImport() {}", - "", - " class NestedWithTestAnnotationFirst {", - " @Test", - " void withValueSource() {}", - " }", - "", - " class NestedWithTestAnnotationSecond {", - " @Test", - " void withValueSource() {}", - " }", - "}") + """ + import org.junit.jupiter.api.Test; + import org.junit.jupiter.params.ParameterizedTest; + import org.junit.jupiter.params.provider.ArgumentsProvider; + import org.junit.jupiter.params.provider.ArgumentsSource; + import org.junit.jupiter.params.provider.ArgumentsSources; + import org.junit.jupiter.params.provider.MethodSource; + import org.junit.jupiter.params.provider.ValueSource; + + class A { + @Test + void withoutArgumentSource() {} + + @Test + void withCustomArgumentSource() {} + + @Test + void withCustomerArgumentSources() {} + + /** Foo. */ + @Test + void withValueSourceAndJavadoc() {} + + @Test + @SuppressWarnings("foo") + void withMethodSourceAndUnrelatedAnnotation() {} + + @Test + void withMultipleArgumentSourcesAndFullyQualifiedImport() {} + + class NestedWithTestAnnotationFirst { + @Test + void withValueSource() {} + } + + class NestedWithTestAnnotationSecond { + @Test + void withValueSource() {} + } + } + """) .addInputLines( "B.java", - "import org.junit.jupiter.params.ParameterizedTest;", - "", - "class B {", - " @ParameterizedTest", - " void scopeInWhichIdentifierTestIsAlreadyDeclared() {}", - "", - " class Test {}", - "}") + """ + import org.junit.jupiter.params.ParameterizedTest; + + class B { + @ParameterizedTest + void scopeInWhichIdentifierTestIsAlreadyDeclared() {} + + class Test {} + } + """) .addOutputLines( "B.java", - "import org.junit.jupiter.params.ParameterizedTest;", - "", - "class B {", - " @org.junit.jupiter.api.Test", - " void scopeInWhichIdentifierTestIsAlreadyDeclared() {}", - "", - " class Test {}", - "}") + """ + import org.junit.jupiter.params.ParameterizedTest; + + class B { + @org.junit.jupiter.api.Test + void scopeInWhichIdentifierTestIsAlreadyDeclared() {} + + class Test {} + } + """) .doTest(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/JUnitValueSourceTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/JUnitValueSourceTest.java index 13ed3fa24db..2c37a86285b 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/JUnitValueSourceTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/JUnitValueSourceTest.java @@ -11,189 +11,191 @@ void identification() { CompilationTestHelper.newInstance(JUnitValueSource.class, getClass()) .addSourceLines( "A.java", - "import static org.junit.jupiter.params.provider.Arguments.arguments;", - "", - "import java.util.Optional;", - "import java.util.stream.Stream;", - "import org.junit.jupiter.params.ParameterizedTest;", - "import org.junit.jupiter.params.provider.Arguments;", - "import org.junit.jupiter.params.provider.MethodSource;", - "", - "class A {", - " private static Stream identificationTestCases() {", - " return Stream.of(arguments(1), Arguments.of(2));", - " }", - "", - " @ParameterizedTest", - " // BUG: Diagnostic contains:", - " @MethodSource(\"identificationTestCases\")", - " void identification(int foo) {}", - "", - " private static int[] identificationWithParensTestCases() {", - " return new int[] {1, 2};", - " }", - "", - " @ParameterizedTest", - " // BUG: Diagnostic contains:", - " @MethodSource(\"identificationWithParensTestCases()\")", - " void identificationWithParens(int foo) {}", - "", - " @ParameterizedTest", - " @MethodSource(\"valueFactoryMissingTestCases\")", - " void valueFactoryMissing(int foo) {}", - "", - " private static Stream multipleUsagesTestCases() {", - " return Stream.of(arguments(1), Arguments.of(2));", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"multipleUsagesTestCases\")", - " void multipleUsages1(int foo) {}", - "", - " @ParameterizedTest", - " @MethodSource(\"multipleUsagesTestCases()\")", - " void multipleUsages2(int bar) {}", - "", - " private static Stream valueFactoryRepeatedTestCases() {", - " return Stream.of(arguments(1), arguments(2));", - " }", - "", - " @ParameterizedTest", - " @MethodSource({\"valueFactoryRepeatedTestCases\", \"valueFactoryRepeatedTestCases\"})", - " void valueFactoryRepeated(int foo) {}", - "", - " private static Stream multipleParametersTestCases() {", - " return Stream.of(arguments(1, 2), arguments(3, 4));", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"multipleParametersTestCases\")", - " void multipleParameters(int first, int second) {}", - "", - " private static int[] arrayWithoutInitializersTestCases() {", - " return new int[1];", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"arrayWithoutInitializersTestCases\")", - " void arrayWithoutInitializers(int foo) {}", - "", - " private static Stream runtimeValueTestCases() {", - " int second = 2;", - " return Stream.of(arguments(1), arguments(second));", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"runtimeValueTestCases\")", - " void runtimeValue(int foo) {}", - "", - " private static Stream streamChainTestCases() {", - " return Stream.of(1, 2).map(Arguments::arguments);", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"streamChainTestCases\")", - " void streamChain(int number) {}", - "", - " private static Stream multipleReturnsTestCases() {", - " if (true) {", - " return Stream.of(arguments(1), arguments(2));", - " } else {", - " return Stream.of(arguments(3), arguments(4));", - " }", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"multipleReturnsTestCases\")", - " void multipleReturns(int number) {}", - "", - " private static Stream multipleFactoriesFooTestCases() {", - " return Stream.of(arguments(1));", - " }", - "", - " private static Stream multipleFactoriesBarTestCases() {", - " return Stream.of(arguments(1));", - " }", - "", - " @ParameterizedTest", - " @MethodSource({\"multipleFactoriesFooTestCases\", \"multipleFactoriesBarTestCases\"})", - " void multipleFactories(int i) {}", - "", - " private static Stream extraArgsTestCases() {", - " return Stream.of(arguments(1), arguments(1, 2));", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"extraArgsTestCases\")", - " void extraArgs(int... i) {}", - "", - " private static Stream localClassTestCases() {", - " class Foo {", - " Stream foo() {", - " return Stream.of(arguments(1), arguments(2));", - " }", - " }", - " return Stream.of(arguments(1), arguments(2));", - " }", - "", - " @ParameterizedTest", - " // BUG: Diagnostic contains:", - " @MethodSource(\"localClassTestCases\")", - " void localClass(int i) {}", - "", - " private static Stream lambdaReturnTestCases() {", - " int foo =", - " Optional.of(10)", - " .map(", - " i -> {", - " return i / 2;", - " })", - " .orElse(0);", - " return Stream.of(arguments(1), arguments(1));", - " }", - "", - " @ParameterizedTest", - " // BUG: Diagnostic contains:", - " @MethodSource(\"lambdaReturnTestCases\")", - " void lambdaReturn(int i) {}", - "", - " @ParameterizedTest", - " @MethodSource(\"tech.picnic.errorprone.Foo#fooTestCases\")", - " void staticMethodReference(int foo) {}", - "", - " private static Stream valueFactoryWithArgumentTestCases(int amount) {", - " return Stream.of(arguments(1), arguments(2));", - " }", - "", - " @ParameterizedTest", - " // BUG: Diagnostic contains:", - " @MethodSource(\"valueFactoryWithArgumentTestCases\")", - " void valueFactoryWithArgument(int foo) {}", - "", - " private static Arguments[] emptyArrayValueFactoryTestCases() {", - " return new Arguments[] {};", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"emptyArrayValueFactoryTestCases\")", - " void emptyArrayValueFactory(int foo) {}", - "", - " private static Stream emptyStreamValueFactoryTestCases() {", - " return Stream.of();", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"emptyStreamValueFactoryTestCases\")", - " void emptyStreamValueFactory(int foo) {}", - "", - " private static Arguments[] invalidValueFactoryArgumentsTestCases() {", - " return new Arguments[] {arguments(1), arguments(new Object() {})};", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"invalidValueFactoryArgumentsTestCases\")", - " void invalidValueFactoryArguments(int foo) {}", - "}") + """ + import static org.junit.jupiter.params.provider.Arguments.arguments; + + import java.util.Optional; + import java.util.stream.Stream; + import org.junit.jupiter.params.ParameterizedTest; + import org.junit.jupiter.params.provider.Arguments; + import org.junit.jupiter.params.provider.MethodSource; + + class A { + private static Stream identificationTestCases() { + return Stream.of(arguments(1), Arguments.of(2)); + } + + @ParameterizedTest + // BUG: Diagnostic contains: + @MethodSource("identificationTestCases") + void identification(int foo) {} + + private static int[] identificationWithParensTestCases() { + return new int[] {1, 2}; + } + + @ParameterizedTest + // BUG: Diagnostic contains: + @MethodSource("identificationWithParensTestCases()") + void identificationWithParens(int foo) {} + + @ParameterizedTest + @MethodSource("valueFactoryMissingTestCases") + void valueFactoryMissing(int foo) {} + + private static Stream multipleUsagesTestCases() { + return Stream.of(arguments(1), Arguments.of(2)); + } + + @ParameterizedTest + @MethodSource("multipleUsagesTestCases") + void multipleUsages1(int foo) {} + + @ParameterizedTest + @MethodSource("multipleUsagesTestCases()") + void multipleUsages2(int bar) {} + + private static Stream valueFactoryRepeatedTestCases() { + return Stream.of(arguments(1), arguments(2)); + } + + @ParameterizedTest + @MethodSource({"valueFactoryRepeatedTestCases", "valueFactoryRepeatedTestCases"}) + void valueFactoryRepeated(int foo) {} + + private static Stream multipleParametersTestCases() { + return Stream.of(arguments(1, 2), arguments(3, 4)); + } + + @ParameterizedTest + @MethodSource("multipleParametersTestCases") + void multipleParameters(int first, int second) {} + + private static int[] arrayWithoutInitializersTestCases() { + return new int[1]; + } + + @ParameterizedTest + @MethodSource("arrayWithoutInitializersTestCases") + void arrayWithoutInitializers(int foo) {} + + private static Stream runtimeValueTestCases() { + int second = 2; + return Stream.of(arguments(1), arguments(second)); + } + + @ParameterizedTest + @MethodSource("runtimeValueTestCases") + void runtimeValue(int foo) {} + + private static Stream streamChainTestCases() { + return Stream.of(1, 2).map(Arguments::arguments); + } + + @ParameterizedTest + @MethodSource("streamChainTestCases") + void streamChain(int number) {} + + private static Stream multipleReturnsTestCases() { + if (true) { + return Stream.of(arguments(1), arguments(2)); + } else { + return Stream.of(arguments(3), arguments(4)); + } + } + + @ParameterizedTest + @MethodSource("multipleReturnsTestCases") + void multipleReturns(int number) {} + + private static Stream multipleFactoriesFooTestCases() { + return Stream.of(arguments(1)); + } + + private static Stream multipleFactoriesBarTestCases() { + return Stream.of(arguments(1)); + } + + @ParameterizedTest + @MethodSource({"multipleFactoriesFooTestCases", "multipleFactoriesBarTestCases"}) + void multipleFactories(int i) {} + + private static Stream extraArgsTestCases() { + return Stream.of(arguments(1), arguments(1, 2)); + } + + @ParameterizedTest + @MethodSource("extraArgsTestCases") + void extraArgs(int... i) {} + + private static Stream localClassTestCases() { + class Foo { + Stream foo() { + return Stream.of(arguments(1), arguments(2)); + } + } + return Stream.of(arguments(1), arguments(2)); + } + + @ParameterizedTest + // BUG: Diagnostic contains: + @MethodSource("localClassTestCases") + void localClass(int i) {} + + private static Stream lambdaReturnTestCases() { + int foo = + Optional.of(10) + .map( + i -> { + return i / 2; + }) + .orElse(0); + return Stream.of(arguments(1), arguments(1)); + } + + @ParameterizedTest + // BUG: Diagnostic contains: + @MethodSource("lambdaReturnTestCases") + void lambdaReturn(int i) {} + + @ParameterizedTest + @MethodSource("tech.picnic.errorprone.Foo#fooTestCases") + void staticMethodReference(int foo) {} + + private static Stream valueFactoryWithArgumentTestCases(int amount) { + return Stream.of(arguments(1), arguments(2)); + } + + @ParameterizedTest + // BUG: Diagnostic contains: + @MethodSource("valueFactoryWithArgumentTestCases") + void valueFactoryWithArgument(int foo) {} + + private static Arguments[] emptyArrayValueFactoryTestCases() { + return new Arguments[] {}; + } + + @ParameterizedTest + @MethodSource("emptyArrayValueFactoryTestCases") + void emptyArrayValueFactory(int foo) {} + + private static Stream emptyStreamValueFactoryTestCases() { + return Stream.of(); + } + + @ParameterizedTest + @MethodSource("emptyStreamValueFactoryTestCases") + void emptyStreamValueFactory(int foo) {} + + private static Arguments[] invalidValueFactoryArgumentsTestCases() { + return new Arguments[] {arguments(1), arguments(new Object() {})}; + } + + @ParameterizedTest + @MethodSource("invalidValueFactoryArgumentsTestCases") + void invalidValueFactoryArguments(int foo) {} + } + """) .doTest(); } @@ -202,295 +204,299 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(JUnitValueSource.class, getClass()) .addInputLines( "A.java", - "import static org.junit.jupiter.params.provider.Arguments.arguments;", - "", - "import com.google.common.collect.ImmutableList;", - "import com.google.common.collect.ImmutableSet;", - "import java.util.List;", - "import java.util.Set;", - "import java.util.stream.DoubleStream;", - "import java.util.stream.IntStream;", - "import java.util.stream.LongStream;", - "import java.util.stream.Stream;", - "import org.junit.jupiter.params.ParameterizedTest;", - "import org.junit.jupiter.params.provider.Arguments;", - "import org.junit.jupiter.params.provider.MethodSource;", - "", - "class A {", - " private static final boolean CONST_BOOLEAN = false;", - " private static final byte CONST_BYTE = 42;", - " private static final char CONST_CHARACTER = 'a';", - " private static final short CONST_SHORT = 42;", - " private static final int CONST_INTEGER = 42;", - " private static final long CONST_LONG = 42;", - " private static final float CONST_FLOAT = 42;", - " private static final double CONST_DOUBLE = 42;", - " private static final String CONST_STRING = \"foo\";", - "", - " private static Stream streamOfBooleanArguments() {", - " return Stream.of(arguments(false), arguments(true), arguments(CONST_BOOLEAN));", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"streamOfBooleanArguments\")", - " void primitiveBoolean(boolean b) {}", - "", - " private static Stream streamOfBooleansAndBooleanArguments() {", - " return Stream.of(false, arguments(true), CONST_BOOLEAN);", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"streamOfBooleansAndBooleanArguments\")", - " void boxedBoolean(Boolean b) {}", - "", - " private static List listOfByteArguments() {", - " return List.of(arguments((byte) 0), arguments((byte) 1), arguments(CONST_BYTE));", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"listOfByteArguments\")", - " void primitiveByte(byte b) {}", - "", - " private static List listOfBytesAndByteArguments() {", - " return List.of((byte) 0, arguments((byte) 1), CONST_BYTE);", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"listOfBytesAndByteArguments\")", - " void boxedByte(Byte b) {}", - "", - " private static Set setOfCharacterArguments() {", - " return Set.of(arguments((char) 0), arguments((char) 1), arguments(CONST_CHARACTER));", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"setOfCharacterArguments\")", - " void primitiveCharacter(char c) {}", - "", - " private static Set setOfCharactersAndCharacterArguments() {", - " return Set.of((char) 0, arguments((char) 1), CONST_CHARACTER);", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"setOfCharactersAndCharacterArguments\")", - " void boxedCharacter(Character c) {}", - "", - " private static Arguments[] arrayOfShortArguments() {", - " return new Arguments[] {arguments((short) 0), arguments((short) 1), arguments(CONST_SHORT)};", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"arrayOfShortArguments\")", - " void primitiveShort(short s) {}", - "", - " private static Object[] arrayOfShortsAndShortArguments() {", - " return new Object[] {(short) 0, arguments((short) 1), CONST_SHORT};", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"arrayOfShortsAndShortArguments\")", - " void boxedShort(Short s) {}", - "", - " private static IntStream intStream() {", - " return IntStream.of(0, 1, CONST_INTEGER);", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"intStream\")", - " void primitiveInteger(int i) {}", - "", - " private static int[] intArray() {", - " return new int[] {0, 1, CONST_INTEGER};", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"intArray\")", - " void boxedInteger(Integer i) {}", - "", - " private static LongStream longStream() {", - " return LongStream.of(0, 1, CONST_LONG);", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"longStream\")", - " void primitiveLong(long l) {}", - "", - " private static long[] longArray() {", - " return new long[] {0, 1, CONST_LONG};", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"longArray\")", - " void boxedLong(Long l) {}", - "", - " private static ImmutableList immutableListOfFloatArguments() {", - " return ImmutableList.of(arguments(0.0F), arguments(1.0F), arguments(CONST_FLOAT));", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"immutableListOfFloatArguments\")", - " void primitiveFloat(float f) {}", - "", - " private static Stream streamOfFloatsAndFloatArguments() {", - " return Stream.of(0.0F, arguments(1.0F), CONST_FLOAT);", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"streamOfFloatsAndFloatArguments\")", - " void boxedFloat(Float f) {}", - "", - " private static DoubleStream doubleStream() {", - " return DoubleStream.of(0, 1, CONST_DOUBLE);", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"doubleStream\")", - " void primitiveDouble(double d) {}", - "", - " private static double[] doubleArray() {", - " return new double[] {0, 1, CONST_DOUBLE};", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"doubleArray\")", - " void boxedDouble(Double d) {}", - "", - " private static ImmutableSet immutableSetOfStringArguments() {", - " return ImmutableSet.of(arguments(\"foo\"), arguments(\"bar\"), arguments(CONST_STRING));", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"immutableSetOfStringArguments\")", - " void string(String s) {}", - "", - " private static Stream> streamOfClasses() {", - " return Stream.of(Stream.class, java.util.Map.class);", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"streamOfClasses\")", - " void clazz(Class c) {}", - "", - " private static Stream sameNameFactoryTestCases() {", - " return Stream.of(arguments(1));", - " }", - "", - " private static Stream sameNameFactoryTestCases(int overload) {", - " return Stream.of(arguments(overload));", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"sameNameFactoryTestCases\")", - " void sameNameFactory(int i) {}", - "}") + """ + import static org.junit.jupiter.params.provider.Arguments.arguments; + + import com.google.common.collect.ImmutableList; + import com.google.common.collect.ImmutableSet; + import java.util.List; + import java.util.Set; + import java.util.stream.DoubleStream; + import java.util.stream.IntStream; + import java.util.stream.LongStream; + import java.util.stream.Stream; + import org.junit.jupiter.params.ParameterizedTest; + import org.junit.jupiter.params.provider.Arguments; + import org.junit.jupiter.params.provider.MethodSource; + + class A { + private static final boolean CONST_BOOLEAN = false; + private static final byte CONST_BYTE = 42; + private static final char CONST_CHARACTER = 'a'; + private static final short CONST_SHORT = 42; + private static final int CONST_INTEGER = 42; + private static final long CONST_LONG = 42; + private static final float CONST_FLOAT = 42; + private static final double CONST_DOUBLE = 42; + private static final String CONST_STRING = "foo"; + + private static Stream streamOfBooleanArguments() { + return Stream.of(arguments(false), arguments(true), arguments(CONST_BOOLEAN)); + } + + @ParameterizedTest + @MethodSource("streamOfBooleanArguments") + void primitiveBoolean(boolean b) {} + + private static Stream streamOfBooleansAndBooleanArguments() { + return Stream.of(false, arguments(true), CONST_BOOLEAN); + } + + @ParameterizedTest + @MethodSource("streamOfBooleansAndBooleanArguments") + void boxedBoolean(Boolean b) {} + + private static List listOfByteArguments() { + return List.of(arguments((byte) 0), arguments((byte) 1), arguments(CONST_BYTE)); + } + + @ParameterizedTest + @MethodSource("listOfByteArguments") + void primitiveByte(byte b) {} + + private static List listOfBytesAndByteArguments() { + return List.of((byte) 0, arguments((byte) 1), CONST_BYTE); + } + + @ParameterizedTest + @MethodSource("listOfBytesAndByteArguments") + void boxedByte(Byte b) {} + + private static Set setOfCharacterArguments() { + return Set.of(arguments((char) 0), arguments((char) 1), arguments(CONST_CHARACTER)); + } + + @ParameterizedTest + @MethodSource("setOfCharacterArguments") + void primitiveCharacter(char c) {} + + private static Set setOfCharactersAndCharacterArguments() { + return Set.of((char) 0, arguments((char) 1), CONST_CHARACTER); + } + + @ParameterizedTest + @MethodSource("setOfCharactersAndCharacterArguments") + void boxedCharacter(Character c) {} + + private static Arguments[] arrayOfShortArguments() { + return new Arguments[] {arguments((short) 0), arguments((short) 1), arguments(CONST_SHORT)}; + } + + @ParameterizedTest + @MethodSource("arrayOfShortArguments") + void primitiveShort(short s) {} + + private static Object[] arrayOfShortsAndShortArguments() { + return new Object[] {(short) 0, arguments((short) 1), CONST_SHORT}; + } + + @ParameterizedTest + @MethodSource("arrayOfShortsAndShortArguments") + void boxedShort(Short s) {} + + private static IntStream intStream() { + return IntStream.of(0, 1, CONST_INTEGER); + } + + @ParameterizedTest + @MethodSource("intStream") + void primitiveInteger(int i) {} + + private static int[] intArray() { + return new int[] {0, 1, CONST_INTEGER}; + } + + @ParameterizedTest + @MethodSource("intArray") + void boxedInteger(Integer i) {} + + private static LongStream longStream() { + return LongStream.of(0, 1, CONST_LONG); + } + + @ParameterizedTest + @MethodSource("longStream") + void primitiveLong(long l) {} + + private static long[] longArray() { + return new long[] {0, 1, CONST_LONG}; + } + + @ParameterizedTest + @MethodSource("longArray") + void boxedLong(Long l) {} + + private static ImmutableList immutableListOfFloatArguments() { + return ImmutableList.of(arguments(0.0F), arguments(1.0F), arguments(CONST_FLOAT)); + } + + @ParameterizedTest + @MethodSource("immutableListOfFloatArguments") + void primitiveFloat(float f) {} + + private static Stream streamOfFloatsAndFloatArguments() { + return Stream.of(0.0F, arguments(1.0F), CONST_FLOAT); + } + + @ParameterizedTest + @MethodSource("streamOfFloatsAndFloatArguments") + void boxedFloat(Float f) {} + + private static DoubleStream doubleStream() { + return DoubleStream.of(0, 1, CONST_DOUBLE); + } + + @ParameterizedTest + @MethodSource("doubleStream") + void primitiveDouble(double d) {} + + private static double[] doubleArray() { + return new double[] {0, 1, CONST_DOUBLE}; + } + + @ParameterizedTest + @MethodSource("doubleArray") + void boxedDouble(Double d) {} + + private static ImmutableSet immutableSetOfStringArguments() { + return ImmutableSet.of(arguments("foo"), arguments("bar"), arguments(CONST_STRING)); + } + + @ParameterizedTest + @MethodSource("immutableSetOfStringArguments") + void string(String s) {} + + private static Stream> streamOfClasses() { + return Stream.of(Stream.class, java.util.Map.class); + } + + @ParameterizedTest + @MethodSource("streamOfClasses") + void clazz(Class c) {} + + private static Stream sameNameFactoryTestCases() { + return Stream.of(arguments(1)); + } + + private static Stream sameNameFactoryTestCases(int overload) { + return Stream.of(arguments(overload)); + } + + @ParameterizedTest + @MethodSource("sameNameFactoryTestCases") + void sameNameFactory(int i) {} + } + """) .addOutputLines( "A.java", - "import static org.junit.jupiter.params.provider.Arguments.arguments;", - "", - "import com.google.common.collect.ImmutableList;", - "import com.google.common.collect.ImmutableSet;", - "import java.util.List;", - "import java.util.Set;", - "import java.util.stream.DoubleStream;", - "import java.util.stream.IntStream;", - "import java.util.stream.LongStream;", - "import java.util.stream.Stream;", - "import org.junit.jupiter.params.ParameterizedTest;", - "import org.junit.jupiter.params.provider.Arguments;", - "import org.junit.jupiter.params.provider.MethodSource;", - "import org.junit.jupiter.params.provider.ValueSource;", - "", - "class A {", - " private static final boolean CONST_BOOLEAN = false;", - " private static final byte CONST_BYTE = 42;", - " private static final char CONST_CHARACTER = 'a';", - " private static final short CONST_SHORT = 42;", - " private static final int CONST_INTEGER = 42;", - " private static final long CONST_LONG = 42;", - " private static final float CONST_FLOAT = 42;", - " private static final double CONST_DOUBLE = 42;", - " private static final String CONST_STRING = \"foo\";", - "", - " @ParameterizedTest", - " @ValueSource(booleans = {false, true, CONST_BOOLEAN})", - " void primitiveBoolean(boolean b) {}", - "", - " @ParameterizedTest", - " @ValueSource(booleans = {false, true, CONST_BOOLEAN})", - " void boxedBoolean(Boolean b) {}", - "", - " @ParameterizedTest", - " @ValueSource(bytes = {(byte) 0, (byte) 1, CONST_BYTE})", - " void primitiveByte(byte b) {}", - "", - " @ParameterizedTest", - " @ValueSource(bytes = {(byte) 0, (byte) 1, CONST_BYTE})", - " void boxedByte(Byte b) {}", - "", - " @ParameterizedTest", - " @ValueSource(chars = {(char) 0, (char) 1, CONST_CHARACTER})", - " void primitiveCharacter(char c) {}", - "", - " @ParameterizedTest", - " @ValueSource(chars = {(char) 0, (char) 1, CONST_CHARACTER})", - " void boxedCharacter(Character c) {}", - "", - " @ParameterizedTest", - " @ValueSource(shorts = {(short) 0, (short) 1, CONST_SHORT})", - " void primitiveShort(short s) {}", - "", - " @ParameterizedTest", - " @ValueSource(shorts = {(short) 0, (short) 1, CONST_SHORT})", - " void boxedShort(Short s) {}", - "", - " @ParameterizedTest", - " @ValueSource(ints = {0, 1, CONST_INTEGER})", - " void primitiveInteger(int i) {}", - "", - " @ParameterizedTest", - " @ValueSource(ints = {0, 1, CONST_INTEGER})", - " void boxedInteger(Integer i) {}", - "", - " @ParameterizedTest", - " @ValueSource(longs = {0, 1, CONST_LONG})", - " void primitiveLong(long l) {}", - "", - " @ParameterizedTest", - " @ValueSource(longs = {0, 1, CONST_LONG})", - " void boxedLong(Long l) {}", - "", - " @ParameterizedTest", - " @ValueSource(floats = {0.0F, 1.0F, CONST_FLOAT})", - " void primitiveFloat(float f) {}", - "", - " @ParameterizedTest", - " @ValueSource(floats = {0.0F, 1.0F, CONST_FLOAT})", - " void boxedFloat(Float f) {}", - "", - " @ParameterizedTest", - " @ValueSource(doubles = {0, 1, CONST_DOUBLE})", - " void primitiveDouble(double d) {}", - "", - " @ParameterizedTest", - " @ValueSource(doubles = {0, 1, CONST_DOUBLE})", - " void boxedDouble(Double d) {}", - "", - " @ParameterizedTest", - " @ValueSource(strings = {\"foo\", \"bar\", CONST_STRING})", - " void string(String s) {}", - "", - " @ParameterizedTest", - " @ValueSource(classes = {Stream.class, java.util.Map.class})", - " void clazz(Class c) {}", - "", - " private static Stream sameNameFactoryTestCases(int overload) {", - " return Stream.of(arguments(overload));", - " }", - "", - " @ParameterizedTest", - " @ValueSource(ints = 1)", - " void sameNameFactory(int i) {}", - "}") + """ + import static org.junit.jupiter.params.provider.Arguments.arguments; + + import com.google.common.collect.ImmutableList; + import com.google.common.collect.ImmutableSet; + import java.util.List; + import java.util.Set; + import java.util.stream.DoubleStream; + import java.util.stream.IntStream; + import java.util.stream.LongStream; + import java.util.stream.Stream; + import org.junit.jupiter.params.ParameterizedTest; + import org.junit.jupiter.params.provider.Arguments; + import org.junit.jupiter.params.provider.MethodSource; + import org.junit.jupiter.params.provider.ValueSource; + + class A { + private static final boolean CONST_BOOLEAN = false; + private static final byte CONST_BYTE = 42; + private static final char CONST_CHARACTER = 'a'; + private static final short CONST_SHORT = 42; + private static final int CONST_INTEGER = 42; + private static final long CONST_LONG = 42; + private static final float CONST_FLOAT = 42; + private static final double CONST_DOUBLE = 42; + private static final String CONST_STRING = "foo"; + + @ParameterizedTest + @ValueSource(booleans = {false, true, CONST_BOOLEAN}) + void primitiveBoolean(boolean b) {} + + @ParameterizedTest + @ValueSource(booleans = {false, true, CONST_BOOLEAN}) + void boxedBoolean(Boolean b) {} + + @ParameterizedTest + @ValueSource(bytes = {(byte) 0, (byte) 1, CONST_BYTE}) + void primitiveByte(byte b) {} + + @ParameterizedTest + @ValueSource(bytes = {(byte) 0, (byte) 1, CONST_BYTE}) + void boxedByte(Byte b) {} + + @ParameterizedTest + @ValueSource(chars = {(char) 0, (char) 1, CONST_CHARACTER}) + void primitiveCharacter(char c) {} + + @ParameterizedTest + @ValueSource(chars = {(char) 0, (char) 1, CONST_CHARACTER}) + void boxedCharacter(Character c) {} + + @ParameterizedTest + @ValueSource(shorts = {(short) 0, (short) 1, CONST_SHORT}) + void primitiveShort(short s) {} + + @ParameterizedTest + @ValueSource(shorts = {(short) 0, (short) 1, CONST_SHORT}) + void boxedShort(Short s) {} + + @ParameterizedTest + @ValueSource(ints = {0, 1, CONST_INTEGER}) + void primitiveInteger(int i) {} + + @ParameterizedTest + @ValueSource(ints = {0, 1, CONST_INTEGER}) + void boxedInteger(Integer i) {} + + @ParameterizedTest + @ValueSource(longs = {0, 1, CONST_LONG}) + void primitiveLong(long l) {} + + @ParameterizedTest + @ValueSource(longs = {0, 1, CONST_LONG}) + void boxedLong(Long l) {} + + @ParameterizedTest + @ValueSource(floats = {0.0F, 1.0F, CONST_FLOAT}) + void primitiveFloat(float f) {} + + @ParameterizedTest + @ValueSource(floats = {0.0F, 1.0F, CONST_FLOAT}) + void boxedFloat(Float f) {} + + @ParameterizedTest + @ValueSource(doubles = {0, 1, CONST_DOUBLE}) + void primitiveDouble(double d) {} + + @ParameterizedTest + @ValueSource(doubles = {0, 1, CONST_DOUBLE}) + void boxedDouble(Double d) {} + + @ParameterizedTest + @ValueSource(strings = {"foo", "bar", CONST_STRING}) + void string(String s) {} + + @ParameterizedTest + @ValueSource(classes = {Stream.class, java.util.Map.class}) + void clazz(Class c) {} + + private static Stream sameNameFactoryTestCases(int overload) { + return Stream.of(arguments(overload)); + } + + @ParameterizedTest + @ValueSource(ints = 1) + void sameNameFactory(int i) {} + } + """) .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 da842fd92a8..5314d4aad66 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 @@ -12,146 +12,148 @@ void identification() { CompilationTestHelper.newInstance(LexicographicalAnnotationAttributeListing.class, getClass()) .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(); } @@ -164,78 +166,82 @@ void replacement() { LexicographicalAnnotationAttributeListing.class, getClass()) .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,48 +255,50 @@ void filtering() { "-XepOpt:LexicographicalAnnotationAttributeListing:Excludes=pkg.A.Bar#value")) .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 e4857157543..3dd2f549f96 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 @@ -11,122 +11,124 @@ void identification() { CompilationTestHelper.newInstance(LexicographicalAnnotationListing.class, getClass()) .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(); } @@ -135,166 +137,170 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(LexicographicalAnnotationListing.class, getClass()) .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 ca583d92e60..f593cad914e 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 @@ -11,308 +11,310 @@ void identification() { CompilationTestHelper.newInstance(MethodReferenceUsage.class, getClass()) .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(); } @@ -321,111 +323,115 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(MethodReferenceUsage.class, getClass()) .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/MockitoMockClassReferenceTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MockitoMockClassReferenceTest.java index 8fc34e35c66..a1d869a0c4d 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MockitoMockClassReferenceTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MockitoMockClassReferenceTest.java @@ -11,86 +11,88 @@ void identification() { CompilationTestHelper.newInstance(MockitoMockClassReference.class, getClass()) .addSourceLines( "A.java", - "import static org.mockito.Mockito.mock;", - "import static org.mockito.Mockito.spy;", - "import static org.mockito.Mockito.withSettings;", - "", - "import java.util.List;", - "import java.util.Objects;", - "import org.mockito.invocation.InvocationOnMock;", - "", - "class A {", - " {", - " Double d = Objects.requireNonNullElseGet(null, () -> mock(Double.class));", - " Double d2 =", - " Objects.requireNonNullElseGet(", - " null,", - " () -> {", - " return mock(Double.class);", - " });", - " }", - "", - " void m() {", - " Number variableMock = 42;", - " // BUG: Diagnostic contains:", - " variableMock = mock(Number.class);", - " // BUG: Diagnostic contains:", - " variableMock = mock(Number.class, \"name\");", - " // BUG: Diagnostic contains:", - " variableMock = mock(Number.class, InvocationOnMock::callRealMethod);", - " // BUG: Diagnostic contains:", - " variableMock = mock(Number.class, withSettings());", - " variableMock = mock(Integer.class);", - " variableMock = 42;", - " // BUG: Diagnostic contains:", - " List rawMock = mock(List.class);", - " // BUG: Diagnostic contains:", - " List genericMock = mock(List.class);", - " var varMock = mock(Integer.class);", - " Class numberType = Integer.class;", - " Number variableTypeMock = mock(numberType);", - " Object subtypeMock = mock(Integer.class);", - "", - " Number variableSpy = 42;", - " // BUG: Diagnostic contains:", - " variableSpy = spy(Number.class);", - " variableSpy = spy(Integer.class);", - " variableSpy = 42;", - " // BUG: Diagnostic contains:", - " List rawSpy = spy(List.class);", - " // BUG: Diagnostic contains:", - " List genericSpy = spy(List.class);", - " var varSpy = spy(Integer.class);", - " Number variableTypeSpy = spy(numberType);", - " Object subtypeSpy = spy(Integer.class);", - " Object objectSpy = spy(new Object());", - "", - " Objects.hash(mock(Integer.class));", - " Integer i = mock(mock(Integer.class));", - " String s = new String(mock(String.class));", - " }", - "", - " Double getDoubleMock() {", - " return Objects.requireNonNullElseGet(", - " null,", - " () -> {", - " return mock(Double.class);", - " });", - " }", - "", - " Integer getIntegerMock() {", - " // BUG: Diagnostic contains:", - " return mock(Integer.class);", - " }", - "", - " T getGenericMock(Class clazz) {", - " return mock(clazz);", - " }", - "", - " Number getSubTypeMock() {", - " return mock(Integer.class);", - " }", - "}") + """ + import static org.mockito.Mockito.mock; + import static org.mockito.Mockito.spy; + import static org.mockito.Mockito.withSettings; + + import java.util.List; + import java.util.Objects; + import org.mockito.invocation.InvocationOnMock; + + class A { + { + Double d = Objects.requireNonNullElseGet(null, () -> mock(Double.class)); + Double d2 = + Objects.requireNonNullElseGet( + null, + () -> { + return mock(Double.class); + }); + } + + void m() { + Number variableMock = 42; + // BUG: Diagnostic contains: + variableMock = mock(Number.class); + // BUG: Diagnostic contains: + variableMock = mock(Number.class, "name"); + // BUG: Diagnostic contains: + variableMock = mock(Number.class, InvocationOnMock::callRealMethod); + // BUG: Diagnostic contains: + variableMock = mock(Number.class, withSettings()); + variableMock = mock(Integer.class); + variableMock = 42; + // BUG: Diagnostic contains: + List rawMock = mock(List.class); + // BUG: Diagnostic contains: + List genericMock = mock(List.class); + var varMock = mock(Integer.class); + Class numberType = Integer.class; + Number variableTypeMock = mock(numberType); + Object subtypeMock = mock(Integer.class); + + Number variableSpy = 42; + // BUG: Diagnostic contains: + variableSpy = spy(Number.class); + variableSpy = spy(Integer.class); + variableSpy = 42; + // BUG: Diagnostic contains: + List rawSpy = spy(List.class); + // BUG: Diagnostic contains: + List genericSpy = spy(List.class); + var varSpy = spy(Integer.class); + Number variableTypeSpy = spy(numberType); + Object subtypeSpy = spy(Integer.class); + Object objectSpy = spy(new Object()); + + Objects.hash(mock(Integer.class)); + Integer i = mock(mock(Integer.class)); + String s = new String(mock(String.class)); + } + + Double getDoubleMock() { + return Objects.requireNonNullElseGet( + null, + () -> { + return mock(Double.class); + }); + } + + Integer getIntegerMock() { + // BUG: Diagnostic contains: + return mock(Integer.class); + } + + T getGenericMock(Class clazz) { + return mock(clazz); + } + + Number getSubTypeMock() { + return mock(Integer.class); + } + } + """) .doTest(); } @@ -99,38 +101,42 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(MockitoMockClassReference.class, getClass()) .addInputLines( "A.java", - "import static org.mockito.Mockito.mock;", - "import static org.mockito.Mockito.spy;", - "import static org.mockito.Mockito.withSettings;", - "", - "import org.mockito.invocation.InvocationOnMock;", - "", - "class A {", - " void m() {", - " Number simpleMock = mock(Number.class);", - " Number namedMock = mock(Number.class, \"name\");", - " Number customAnswerMock = mock(Number.class, InvocationOnMock::callRealMethod);", - " Number customSettingsMock = mock(Number.class, withSettings());", - " Number simpleSpy = spy(Number.class);", - " }", - "}") + """ + import static org.mockito.Mockito.mock; + import static org.mockito.Mockito.spy; + import static org.mockito.Mockito.withSettings; + + import org.mockito.invocation.InvocationOnMock; + + class A { + void m() { + Number simpleMock = mock(Number.class); + Number namedMock = mock(Number.class, "name"); + Number customAnswerMock = mock(Number.class, InvocationOnMock::callRealMethod); + Number customSettingsMock = mock(Number.class, withSettings()); + Number simpleSpy = spy(Number.class); + } + } + """) .addOutputLines( "A.java", - "import static org.mockito.Mockito.mock;", - "import static org.mockito.Mockito.spy;", - "import static org.mockito.Mockito.withSettings;", - "", - "import org.mockito.invocation.InvocationOnMock;", - "", - "class A {", - " void m() {", - " Number simpleMock = mock();", - " Number namedMock = mock(\"name\");", - " Number customAnswerMock = mock(InvocationOnMock::callRealMethod);", - " Number customSettingsMock = mock(withSettings());", - " Number simpleSpy = spy();", - " }", - "}") + """ + import static org.mockito.Mockito.mock; + import static org.mockito.Mockito.spy; + import static org.mockito.Mockito.withSettings; + + import org.mockito.invocation.InvocationOnMock; + + class A { + void m() { + Number simpleMock = mock(); + Number namedMock = mock("name"); + Number customAnswerMock = mock(InvocationOnMock::callRealMethod); + Number customSettingsMock = mock(withSettings()); + Number simpleSpy = spy(); + } + } + """) .doTest(TestMode.TEXT_MATCH); } } 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 7a806301e80..efd20a67917 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 @@ -11,40 +11,42 @@ void identification() { CompilationTestHelper.newInstance(MockitoStubbing.class, getClass()) .addSourceLines( "A.java", - "import static org.mockito.ArgumentMatchers.eq;", - "import static org.mockito.ArgumentMatchers.notNull;", - "import static org.mockito.Mockito.doAnswer;", - "import static org.mockito.Mockito.mock;", - "", - "import java.util.function.BiConsumer;", - "import java.util.function.Consumer;", - "import org.mockito.ArgumentMatchers;", - "", - "class A {", - " void m() {", - " Runnable runnable = mock(Runnable.class);", - " doAnswer(inv -> null).when(runnable).run();", - "", - " Consumer 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(); } @@ -53,48 +55,52 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(MockitoStubbing.class, getClass()) .addInputLines( "A.java", - "import static org.mockito.ArgumentMatchers.eq;", - "import static org.mockito.Mockito.doAnswer;", - "import static org.mockito.Mockito.mock;", - "", - "import java.util.function.BiConsumer;", - "import java.util.function.Consumer;", - "import org.mockito.ArgumentMatchers;", - "", - "class A {", - " void m() {", - " Consumer 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/MongoDBTextFilterUsageTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MongoDBTextFilterUsageTest.java index ea9ca288a89..9ceaa1b850d 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MongoDBTextFilterUsageTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MongoDBTextFilterUsageTest.java @@ -9,18 +9,20 @@ void identification() { CompilationTestHelper.newInstance(MongoDBTextFilterUsage.class, getClass()) .addSourceLines( "A.java", - "import com.mongodb.client.model.Filters;", - "import com.mongodb.client.model.TextSearchOptions;", - "", - "class A {", - " void m() {", - " Filters.eq(\"foo\", \"bar\");", - " // BUG: Diagnostic contains:", - " Filters.text(\"foo\");", - " // BUG: Diagnostic contains:", - " Filters.text(\"foo\", new TextSearchOptions());", - " }", - "}") + """ + import com.mongodb.client.model.Filters; + import com.mongodb.client.model.TextSearchOptions; + + class A { + void m() { + Filters.eq("foo", "bar"); + // BUG: Diagnostic contains: + Filters.text("foo"); + // BUG: Diagnostic contains: + Filters.text("foo", new TextSearchOptions()); + } + } + """) .doTest(); } } 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 8923c11b761..0029d9b6197 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 @@ -9,31 +9,33 @@ void identification() { CompilationTestHelper.newInstance(NestedOptionals.class, getClass()) .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/NestedPublishersTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/NestedPublishersTest.java index 846405becde..39f0230f04c 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/NestedPublishersTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/NestedPublishersTest.java @@ -9,29 +9,31 @@ void identification() { CompilationTestHelper.newInstance(NestedPublishers.class, getClass()) .addSourceLines( "A.java", - "import org.reactivestreams.Publisher;", - "import reactor.core.publisher.Flux;", - "import reactor.core.publisher.GroupedFlux;", - "import reactor.core.publisher.Mono;", - "", - "class A {", - " void m() {", - " Mono.empty();", - " Flux.just(1);", - " Flux.just(1, 2).groupBy(i -> i).map(groupedFlux -> (GroupedFlux) groupedFlux);", - "", - " // BUG: Diagnostic contains:", - " Mono.just(Mono.empty());", - " // BUG: Diagnostic contains:", - " Flux.just(Flux.empty());", - " // BUG: Diagnostic contains:", - " Mono.just((Flux) Flux.just(1));", - " // BUG: Diagnostic contains:", - " Flux.just((Publisher) Mono.just(1));", - " // BUG: Diagnostic contains:", - " Mono.just(1).map(Mono::just);", - " }", - "}") + """ + import org.reactivestreams.Publisher; + import reactor.core.publisher.Flux; + import reactor.core.publisher.GroupedFlux; + import reactor.core.publisher.Mono; + + class A { + void m() { + Mono.empty(); + Flux.just(1); + Flux.just(1, 2).groupBy(i -> i).map(groupedFlux -> (GroupedFlux) groupedFlux); + + // BUG: Diagnostic contains: + Mono.just(Mono.empty()); + // BUG: Diagnostic contains: + Flux.just(Flux.empty()); + // BUG: Diagnostic contains: + Mono.just((Flux) Flux.just(1)); + // BUG: Diagnostic contains: + Flux.just((Publisher) Mono.just(1)); + // BUG: Diagnostic contains: + Mono.just(1).map(Mono::just); + } + } + """) .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 7080382357c..25279d8e040 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 @@ -11,95 +11,97 @@ void identification() { CompilationTestHelper.newInstance(NonEmptyMono.class, getClass()) .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(); } @@ -108,42 +110,46 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(NonEmptyMono.class, getClass()) .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(TestMode.TEXT_MATCH); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/NonStaticImportTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/NonStaticImportTest.java index 86ef74d4e6f..45e3e51e2a3 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/NonStaticImportTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/NonStaticImportTest.java @@ -40,71 +40,73 @@ void identification() { CompilationTestHelper.newInstance(NonStaticImport.class, getClass()) .addSourceLines( "pkg/A.java", - "package pkg;", - "", - "// BUG: Diagnostic contains:", - "import static com.google.common.base.Strings.nullToEmpty;", - "// BUG: Diagnostic contains:", - "import static com.google.common.collect.ImmutableList.copyOf;", - "// BUG: Diagnostic contains:", - "import static java.lang.Integer.MAX_VALUE;", - "// BUG: Diagnostic contains:", - "import static java.lang.Integer.MIN_VALUE;", - "// BUG: Diagnostic contains:", - "import static java.time.Clock.systemUTC;", - "// BUG: Diagnostic contains:", - "import static java.time.Instant.MIN;", - "// BUG: Diagnostic contains:", - "import static java.time.ZoneOffset.SHORT_IDS;", - "import static java.time.ZoneOffset.UTC;", - "// BUG: Diagnostic contains:", - "import static java.util.Collections.min;", - "import static java.util.Locale.ENGLISH;", - "// BUG: Diagnostic contains:", - "import static java.util.Locale.ROOT;", - "// BUG: Diagnostic contains:", - "import static java.util.Optional.empty;", - "import static pkg.A.WithMethodThatIsSelectivelyFlagged.list;", - "", - "import com.google.common.collect.ImmutableList;", - "import com.google.common.collect.ImmutableSet;", - "import java.time.Instant;", - "import java.time.ZoneOffset;", - "import java.util.Locale;", - "import java.util.Map;", - "import pkg.A.Wrapper.ZERO;", - "", - "class A {", - " private Integer MIN_VALUE = 12;", - "", - " void m() {", - " nullToEmpty(null);", - " copyOf(ImmutableList.of());", - " int max = MAX_VALUE;", - " int min = MIN_VALUE;", - " systemUTC();", - " Instant minInstant = MIN;", - " Map shortIds = SHORT_IDS;", - " ZoneOffset utc = UTC;", - " min(ImmutableSet.of());", - " Locale english = ENGLISH;", - " Locale root = ROOT;", - " empty();", - "", - " list();", - " new ZERO();", - " }", - "", - " static final class WithMethodThatIsSelectivelyFlagged {", - " static ImmutableList list() {", - " return ImmutableList.of();", - " }", - " }", - "", - " static final class Wrapper {", - " static final class ZERO {}", - " }", - "}") + """ + package pkg; + + // BUG: Diagnostic contains: + import static com.google.common.base.Strings.nullToEmpty; + // BUG: Diagnostic contains: + import static com.google.common.collect.ImmutableList.copyOf; + // BUG: Diagnostic contains: + import static java.lang.Integer.MAX_VALUE; + // BUG: Diagnostic contains: + import static java.lang.Integer.MIN_VALUE; + // BUG: Diagnostic contains: + import static java.time.Clock.systemUTC; + // BUG: Diagnostic contains: + import static java.time.Instant.MIN; + // BUG: Diagnostic contains: + import static java.time.ZoneOffset.SHORT_IDS; + import static java.time.ZoneOffset.UTC; + // BUG: Diagnostic contains: + import static java.util.Collections.min; + import static java.util.Locale.ENGLISH; + // BUG: Diagnostic contains: + import static java.util.Locale.ROOT; + // BUG: Diagnostic contains: + import static java.util.Optional.empty; + import static pkg.A.WithMethodThatIsSelectivelyFlagged.list; + + import com.google.common.collect.ImmutableList; + import com.google.common.collect.ImmutableSet; + import java.time.Instant; + import java.time.ZoneOffset; + import java.util.Locale; + import java.util.Map; + import pkg.A.Wrapper.ZERO; + + class A { + private Integer MIN_VALUE = 12; + + void m() { + nullToEmpty(null); + copyOf(ImmutableList.of()); + int max = MAX_VALUE; + int min = MIN_VALUE; + systemUTC(); + Instant minInstant = MIN; + Map shortIds = SHORT_IDS; + ZoneOffset utc = UTC; + min(ImmutableSet.of()); + Locale english = ENGLISH; + Locale root = ROOT; + empty(); + + list(); + new ZERO(); + } + + static final class WithMethodThatIsSelectivelyFlagged { + static ImmutableList list() { + return ImmutableList.of(); + } + } + + static final class Wrapper { + static final class ZERO {} + } + } + """) .doTest(); } @@ -113,84 +115,88 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(NonStaticImport.class, getClass()) .addInputLines( "A.java", - "import static com.google.common.collect.ImmutableList.copyOf;", - "import static com.google.common.collect.ImmutableSet.of;", - "import static java.time.Clock.systemUTC;", - "import static java.time.Instant.MAX;", - "import static java.time.Instant.MIN;", - "import static java.util.Collections.min;", - "import static java.util.Locale.ROOT;", - "import static java.util.Optional.empty;", - "", - "import com.google.common.collect.ImmutableList;", - "import com.google.common.collect.ImmutableSet;", - "import java.time.Clock;", - "import java.time.Instant;", - "import java.util.Locale;", - "import java.util.Optional;", - "", - "class A {", - " void m() {", - " systemUTC();", - " Clock.systemUTC();", - "", - " Optional o1 = empty();", - " Optional o2 = Optional.empty();", - "", - " Object l1 = copyOf(ImmutableList.of());", - " Object l2 = ImmutableList.copyOf(ImmutableList.of());", - "", - " Locale lo1 = ROOT;", - " Locale lo2 = Locale.ROOT;", - "", - " Instant i1 = MIN;", - " Instant i2 = MAX;", - "", - " ImmutableSet.of(min(of()));", - " }", - "", - " private static final class WithCustomConstant {", - " private static final Instant MIN = Instant.EPOCH;", - " private static final Instant OTHER = MIN;", - " private static final Instant OTHER_MAX = MAX;", - " }", - "}") + """ + import static com.google.common.collect.ImmutableList.copyOf; + import static com.google.common.collect.ImmutableSet.of; + import static java.time.Clock.systemUTC; + import static java.time.Instant.MAX; + import static java.time.Instant.MIN; + import static java.util.Collections.min; + import static java.util.Locale.ROOT; + import static java.util.Optional.empty; + + import com.google.common.collect.ImmutableList; + import com.google.common.collect.ImmutableSet; + import java.time.Clock; + import java.time.Instant; + import java.util.Locale; + import java.util.Optional; + + class A { + void m() { + systemUTC(); + Clock.systemUTC(); + + Optional o1 = empty(); + Optional o2 = Optional.empty(); + + Object l1 = copyOf(ImmutableList.of()); + Object l2 = ImmutableList.copyOf(ImmutableList.of()); + + Locale lo1 = ROOT; + Locale lo2 = Locale.ROOT; + + Instant i1 = MIN; + Instant i2 = MAX; + + ImmutableSet.of(min(of())); + } + + private static final class WithCustomConstant { + private static final Instant MIN = Instant.EPOCH; + private static final Instant OTHER = MIN; + private static final Instant OTHER_MAX = MAX; + } + } + """) .addOutputLines( "A.java", - "import com.google.common.collect.ImmutableList;", - "import com.google.common.collect.ImmutableSet;", - "import java.time.Clock;", - "import java.time.Instant;", - "import java.util.Collections;", - "import java.util.Locale;", - "import java.util.Optional;", - "", - "class A {", - " void m() {", - " Clock.systemUTC();", - " Clock.systemUTC();", - "", - " Optional o1 = Optional.empty();", - " Optional o2 = Optional.empty();", - "", - " Object l1 = ImmutableList.copyOf(ImmutableList.of());", - " Object l2 = ImmutableList.copyOf(ImmutableList.of());", - "", - " Locale lo1 = Locale.ROOT;", - " Locale lo2 = Locale.ROOT;", - "", - " Instant i1 = Instant.MIN;", - " Instant i2 = Instant.MAX;", - "", - " ImmutableSet.of(Collections.min(ImmutableSet.of()));", - " }", - "", - " private static final class WithCustomConstant {", - " private static final Instant MIN = Instant.EPOCH;", - " private static final Instant OTHER = MIN;", - " private static final Instant OTHER_MAX = Instant.MAX;", - " }", - "}") + """ + import com.google.common.collect.ImmutableList; + import com.google.common.collect.ImmutableSet; + import java.time.Clock; + import java.time.Instant; + import java.util.Collections; + import java.util.Locale; + import java.util.Optional; + + class A { + void m() { + Clock.systemUTC(); + Clock.systemUTC(); + + Optional o1 = Optional.empty(); + Optional o2 = Optional.empty(); + + Object l1 = ImmutableList.copyOf(ImmutableList.of()); + Object l2 = ImmutableList.copyOf(ImmutableList.of()); + + Locale lo1 = Locale.ROOT; + Locale lo2 = Locale.ROOT; + + Instant i1 = Instant.MIN; + Instant i2 = Instant.MAX; + + ImmutableSet.of(Collections.min(ImmutableSet.of())); + } + + private static final class WithCustomConstant { + private static final Instant MIN = Instant.EPOCH; + private static final Instant OTHER = MIN; + private static final Instant OTHER_MAX = Instant.MAX; + } + } + """) .doTest(TestMode.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 3362b95b444..f750f37ae29 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 @@ -22,98 +22,100 @@ void byteComparison() { CompilationTestHelper.newInstance(PrimitiveComparison.class, getClass()) .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(); } @@ -122,105 +124,107 @@ void intComparison() { CompilationTestHelper.newInstance(PrimitiveComparison.class, getClass()) .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(); } @@ -229,89 +233,91 @@ void longComparison() { CompilationTestHelper.newInstance(PrimitiveComparison.class, getClass()) .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(); } @@ -320,66 +326,68 @@ void floatComparison() { CompilationTestHelper.newInstance(PrimitiveComparison.class, getClass()) .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(); } @@ -388,73 +396,75 @@ void doubleComparison() { CompilationTestHelper.newInstance(PrimitiveComparison.class, getClass()) .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(); } @@ -463,34 +473,36 @@ void stringComparison() { CompilationTestHelper.newInstance(PrimitiveComparison.class, getClass()) .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(); } @@ -499,78 +511,82 @@ void replacementWithPrimitiveVariants() { BugCheckerRefactoringTestHelper.newInstance(PrimitiveComparison.class, getClass()) .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); } @@ -579,64 +595,68 @@ void replacementWithBoxedVariants() { BugCheckerRefactoringTestHelper.newInstance(PrimitiveComparison.class, getClass()) .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); } @@ -645,37 +665,41 @@ void replacementWithPrimitiveVariantsUsingStaticImports() { BugCheckerRefactoringTestHelper.newInstance(PrimitiveComparison.class, getClass()) .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); } @@ -684,39 +708,43 @@ void replacementWithBoxedVariantsUsingStaticImports() { BugCheckerRefactoringTestHelper.newInstance(PrimitiveComparison.class, getClass()) .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); } @@ -725,30 +753,34 @@ void replacementWithPrimitiveVariantsInComplexSyntacticalContext() { BugCheckerRefactoringTestHelper.newInstance(PrimitiveComparison.class, getClass()) .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); } @@ -757,38 +789,42 @@ void replacementWithBoxedVariantsInComplexSyntacticalContext() { BugCheckerRefactoringTestHelper.newInstance(PrimitiveComparison.class, getClass()) .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 906a16229bc..4bfeefcd955 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 @@ -15,21 +15,23 @@ void identificationOfIdentityTransformation() { CompilationTestHelper.newInstance(RedundantStringConversion.class, getClass()) .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(); } @@ -38,59 +40,61 @@ void identificationWithinMutatingAssignment() { CompilationTestHelper.newInstance(RedundantStringConversion.class, getClass()) .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(); } @@ -99,93 +103,95 @@ void identificationWithinBinaryOperation() { CompilationTestHelper.newInstance(RedundantStringConversion.class, getClass()) .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(); } @@ -194,52 +200,54 @@ void identificationWithinStringBuilderMethod() { CompilationTestHelper.newInstance(RedundantStringConversion.class, getClass()) .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(); } @@ -249,43 +257,45 @@ void identificationWithinFormatterMethod() { CompilationTestHelper.newInstance(RedundantStringConversion.class, getClass()) .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(); } @@ -294,58 +304,60 @@ void identificationWithinGuavaGuardMethod() { CompilationTestHelper.newInstance(RedundantStringConversion.class, getClass()) .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(); } @@ -354,53 +366,55 @@ void identificationWithinSlf4jLoggerMethod() { CompilationTestHelper.newInstance(RedundantStringConversion.class, getClass()) .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(); } @@ -412,91 +426,93 @@ void identificationOfCustomConversionMethod() { "-XepOpt:RedundantStringConversion:ExtraConversionMethods=java.lang.Enum#name(),A#name(),A.B#toString(int)")) .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(); } @@ -505,32 +521,36 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(RedundantStringConversion.class, getClass()) .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 c00458c7a06..0ad82b1b0a8 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 @@ -11,23 +11,25 @@ void identification() { CompilationTestHelper.newInstance(RefasterAnyOfUsage.class, getClass()) .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(); } @@ -36,28 +38,32 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(RefasterAnyOfUsage.class, getClass()) .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 c2e2f287a92..b179f50c4a5 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 @@ -11,121 +11,129 @@ void identification() { CompilationTestHelper.newInstance(RefasterRuleModifiers.class, getClass()) .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(); } @@ -134,70 +142,78 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(RefasterRuleModifiers.class, getClass()) .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 baa62651dbb..c58a4e67d71 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 @@ -9,133 +9,135 @@ void identification() { CompilationTestHelper.newInstance(RequestMappingAnnotation.class, getClass()) .addSourceLines( "A.java", - "import jakarta.servlet.http.HttpServletRequest;", - "import jakarta.servlet.http.HttpServletResponse;", - "import java.io.InputStream;", - "import java.time.ZoneId;", - "import java.util.Locale;", - "import java.util.TimeZone;", - "import org.springframework.http.HttpMethod;", - "import org.springframework.ui.Model;", - "import org.springframework.validation.BindingResult;", - "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 properModel(Model model);", - "", - " @RequestMapping", - " A properBindingResult(BindingResult result);", - "", - " @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 jakarta.servlet.http.HttpServletRequest; + import jakarta.servlet.http.HttpServletResponse; + import java.io.InputStream; + import java.time.ZoneId; + import java.util.Locale; + import java.util.TimeZone; + import org.springframework.http.HttpMethod; + import org.springframework.ui.Model; + import org.springframework.validation.BindingResult; + 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 properModel(Model model); + + @RequestMapping + A properBindingResult(BindingResult result); + + @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 38616e4ea0f..b2fe83859e8 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 @@ -9,55 +9,57 @@ void identification() { CompilationTestHelper.newInstance(RequestParamType.class, getClass()) .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.annotations.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.annotations.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(); } @@ -68,47 +70,49 @@ void identificationRestricted() { "-XepOpt:RequestParamType:SupportedCustomTypes=com.google.common.collect.ImmutableSet,com.google.common.collect.ImmutableSortedMultiset") .addSourceLines( "A.java", - "import com.google.common.collect.ImmutableBiMap;", - "import com.google.common.collect.ImmutableCollection;", - "import com.google.common.collect.ImmutableList;", - "import com.google.common.collect.ImmutableMap;", - "import com.google.common.collect.ImmutableMultiset;", - "import com.google.common.collect.ImmutableSet;", - "import com.google.common.collect.ImmutableSortedMultiset;", - "import com.google.common.collect.ImmutableSortedSet;", - "import org.springframework.web.bind.annotation.GetMapping;", - "import org.springframework.web.bind.annotation.RequestParam;", - "", - "interface A {", - " @GetMapping", - " // BUG: Diagnostic contains:", - " A immutableCollection(@RequestParam ImmutableCollection param);", - "", - " @GetMapping", - " // BUG: Diagnostic contains:", - " A immutableList(@RequestParam ImmutableList param);", - "", - " @GetMapping", - " A immutableSet(@RequestParam ImmutableSet param);", - "", - " @GetMapping", - " A immutableSortedSet(@RequestParam ImmutableSortedSet param);", - "", - " @GetMapping", - " // BUG: Diagnostic contains:", - " A immutableMultiset(@RequestParam ImmutableMultiset param);", - "", - " @GetMapping", - " A immutableSortedMultiset(@RequestParam ImmutableSortedMultiset param);", - "", - " @GetMapping", - " // BUG: Diagnostic contains:", - " A immutableMap(@RequestParam ImmutableMap param);", - "", - " @GetMapping", - " // BUG: Diagnostic contains:", - " A immutableBiMap(@RequestParam ImmutableBiMap param);", - "}") + """ + import com.google.common.collect.ImmutableBiMap; + import com.google.common.collect.ImmutableCollection; + import com.google.common.collect.ImmutableList; + import com.google.common.collect.ImmutableMap; + import com.google.common.collect.ImmutableMultiset; + import com.google.common.collect.ImmutableSet; + import com.google.common.collect.ImmutableSortedMultiset; + import com.google.common.collect.ImmutableSortedSet; + import org.springframework.web.bind.annotation.GetMapping; + import org.springframework.web.bind.annotation.RequestParam; + + interface A { + @GetMapping + // BUG: Diagnostic contains: + A immutableCollection(@RequestParam ImmutableCollection param); + + @GetMapping + // BUG: Diagnostic contains: + A immutableList(@RequestParam ImmutableList param); + + @GetMapping + A immutableSet(@RequestParam ImmutableSet param); + + @GetMapping + A immutableSortedSet(@RequestParam ImmutableSortedSet param); + + @GetMapping + // BUG: Diagnostic contains: + A immutableMultiset(@RequestParam ImmutableMultiset param); + + @GetMapping + A immutableSortedMultiset(@RequestParam ImmutableSortedMultiset param); + + @GetMapping + // BUG: Diagnostic contains: + A immutableMap(@RequestParam ImmutableMap param); + + @GetMapping + // BUG: Diagnostic contains: + A immutableBiMap(@RequestParam ImmutableBiMap param); + } + """) .doTest(); } } 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 bd03f35e2e2..ecb0ea7b570 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 @@ -11,80 +11,82 @@ void identification() { CompilationTestHelper.newInstance(Slf4jLogStatement.class, getClass()) .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(); } @@ -94,50 +96,54 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(Slf4jLogStatement.class, getClass()) .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 d0ae0c49ca9..f0aa2f8835f 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 @@ -11,75 +11,77 @@ void identification() { CompilationTestHelper.newInstance(SpringMvcAnnotation.class, getClass()) .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() { BugCheckerRefactoringTestHelper.newInstance(SpringMvcAnnotation.class, getClass()) .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 4dde83f6e1c..ad92bfcbf85 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 @@ -34,90 +34,92 @@ void identification() { CompilationTestHelper.newInstance(StaticImport.class, getClass()) .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.fasterxml.jackson.annotation.JsonCreator;", - "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:", - " @JsonCreator(mode = JsonCreator.Mode.DELEGATING)", - " private static A jsonCreator(int a) {", - " return new A();", - " }", - "", - " // 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.fasterxml.jackson.annotation.JsonCreator; + 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: + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + private static A jsonCreator(int a) { + return new A(); + } + + // BUG: Diagnostic contains: + @UseImportPolicy(ImportPolicy.IMPORT_TOP_LEVEL) + void refasterAfterTemplate() {} + + void toImmutableMultiset() {} + } + """) .doTest(); } @@ -126,167 +128,171 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(StaticImport.class, getClass()) .addInputLines( "A.java", - "import static java.util.function.Predicate.not;", - "", - "import com.fasterxml.jackson.annotation.JsonCreator;", - "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) {}", - "", - " @JsonCreator(mode = JsonCreator.Mode.DELEGATING)", - " private static A jsonCreator(int a) {", - " return new A();", - " }", - "", - " @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.fasterxml.jackson.annotation.JsonCreator; + 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) {} + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + private static A jsonCreator(int a) { + return new A(); + } + + @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.fasterxml.jackson.annotation.JsonCreator.Mode.DELEGATING;", - "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.fasterxml.jackson.annotation.JsonCreator;", - "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) {}", - "", - " @JsonCreator(mode = DELEGATING)", - " private static A jsonCreator(int a) {", - " return new A();", - " }", - "", - " @BugPattern(summary = \"\", linkType = NONE, severity = SUGGESTION, tags = SIMPLIFICATION)", - " static final class TestBugPattern {}", - "", - " @SpringBootTest(webEnvironment = RANDOM_PORT)", - " final class Test {}", - "}") + """ + import static com.fasterxml.jackson.annotation.JsonCreator.Mode.DELEGATING; + 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.fasterxml.jackson.annotation.JsonCreator; + 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) {} + + @JsonCreator(mode = DELEGATING) + private static A jsonCreator(int a) { + return new A(); + } + + @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 3bc5eb9547c..5b0129782e6 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 @@ -14,43 +14,45 @@ void identification() { .expectErrorMessage("join", m -> m.contains("Prefer `String#join` over `String#format`")) .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(); } @@ -59,32 +61,36 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(StringJoin.class, getClass()) .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 abca2d4ec66..dcfb3a3bf10 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 @@ -9,110 +9,112 @@ void identification() { CompilationTestHelper.newInstance(TimeZoneUsage.class, getClass()) .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/UnqualifiedSuggestedFixImportTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/UnqualifiedSuggestedFixImportTest.java index c414af3adc0..ed590d6ef31 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/UnqualifiedSuggestedFixImportTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/UnqualifiedSuggestedFixImportTest.java @@ -19,26 +19,28 @@ void identification() { "Prefer `SuggestedFixes#qualifyStaticImport` over direct invocation of `SuggestedFix.Builder#addStaticImport`")) .addSourceLines( "A.java", - "import com.google.errorprone.fixes.SuggestedFix;", - "", - "class A {", - " void m() {", - " System.out.println(\"foo\");", - " addImport(\"bar\");", - " addStaticImport(\"baz\");", - "", - " SuggestedFix.Builder builder = SuggestedFix.builder();", - " // BUG: Diagnostic matches: IMPORT", - " builder.addImport(\"java.lang.String\");", - " // BUG: Diagnostic matches: STATIC_IMPORT", - " builder.addStaticImport(\"java.lang.String.toString\");", - " builder.build();", - " }", - "", - " private void addImport(String s) {}", - "", - " private void addStaticImport(String s) {}", - "}") + """ + import com.google.errorprone.fixes.SuggestedFix; + + class A { + void m() { + System.out.println("foo"); + addImport("bar"); + addStaticImport("baz"); + + SuggestedFix.Builder builder = SuggestedFix.builder(); + // BUG: Diagnostic matches: IMPORT + builder.addImport("java.lang.String"); + // BUG: Diagnostic matches: STATIC_IMPORT + builder.addStaticImport("java.lang.String.toString"); + builder.build(); + } + + private void addImport(String s) {} + + private void addStaticImport(String s) {} + } + """) .doTest(); } } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/ConflictDetectionTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/ConflictDetectionTest.java index 70282dd4fa0..735c0be7eab 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/ConflictDetectionTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/ConflictDetectionTest.java @@ -19,38 +19,40 @@ void matcher() { CompilationTestHelper.newInstance(RenameBlockerFlagger.class, getClass()) .addSourceLines( "pkg/A.java", - "package pkg;", - "", - "import static pkg.A.B.method3t;", - "", - "import pkg.A.method4t;", - "", - "class A {", - " void method1() {", - " method3t();", - " method4(method4t.class);", - " }", - "", - " // BUG: Diagnostic contains: a method named `method2t` is already defined in this class or a", - " // supertype", - " void method2() {}", - "", - " void method2t() {}", - "", - " // BUG: Diagnostic contains: `method3t` is already statically imported", - " void method3() {}", - "", - " void method4(Object o) {}", - "", - " // BUG: Diagnostic contains: `int` is not a valid identifier", - " void in() {}", - "", - " static class B {", - " static void method3t() {}", - " }", - "", - " class method4t {}", - "}") + """ + package pkg; + + import static pkg.A.B.method3t; + + import pkg.A.method4t; + + class A { + void method1() { + method3t(); + method4(method4t.class); + } + + // BUG: Diagnostic contains: a method named `method2t` is already defined in this class or a + // supertype + void method2() {} + + void method2t() {} + + // BUG: Diagnostic contains: `method3t` is already statically imported + void method3() {} + + void method4(Object o) {} + + // BUG: Diagnostic contains: `int` is not a valid identifier + void in() {} + + static class B { + static void method3t() {} + } + + class method4t {} + } + """) .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 2e06f291aa8..95b850a18dc 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 @@ -51,153 +51,165 @@ void matcher() { CompilationTestHelper.newInstance(MatchedMethodsFlagger.class, getClass()) .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/MoreASTHelpersTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MoreASTHelpersTest.java index 19f3db045dc..ee7c1efae24 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MoreASTHelpersTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MoreASTHelpersTest.java @@ -27,24 +27,26 @@ void findMethods() { CompilationTestHelper.newInstance(FindMethodsTestChecker.class, getClass()) .addSourceLines( "A.java", - "class A {", - " // BUG: Diagnostic contains: {foo=1, bar=2, baz=0}", - " void foo() {}", - "", - " // BUG: Diagnostic contains: {foo=1, bar=2, baz=0}", - " void bar() {}", - "", - " // BUG: Diagnostic contains: {foo=1, bar=2, baz=0}", - " void bar(int i) {}", - "", - " static class B {", - " // BUG: Diagnostic contains: {foo=0, bar=1, baz=1}", - " void bar() {}", - "", - " // BUG: Diagnostic contains: {foo=0, bar=1, baz=1}", - " void baz() {}", - " }", - "}") + """ + class A { + // BUG: Diagnostic contains: {foo=1, bar=2, baz=0} + void foo() {} + + // BUG: Diagnostic contains: {foo=1, bar=2, baz=0} + void bar() {} + + // BUG: Diagnostic contains: {foo=1, bar=2, baz=0} + void bar(int i) {} + + static class B { + // BUG: Diagnostic contains: {foo=0, bar=1, baz=1} + void bar() {} + + // BUG: Diagnostic contains: {foo=0, bar=1, baz=1} + void baz() {} + } + } + """) .doTest(); } @@ -53,24 +55,26 @@ void methodExistsInEnclosingClass() { CompilationTestHelper.newInstance(MethodExistsTestChecker.class, getClass()) .addSourceLines( "A.java", - "class A {", - " // BUG: Diagnostic contains: {foo=true, bar=true, baz=false}", - " void foo() {}", - "", - " // BUG: Diagnostic contains: {foo=true, bar=true, baz=false}", - " void bar() {}", - "", - " // BUG: Diagnostic contains: {foo=true, bar=true, baz=false}", - " void bar(int i) {}", - "", - " static class B {", - " // BUG: Diagnostic contains: {foo=false, bar=true, baz=true}", - " void bar() {}", - "", - " // BUG: Diagnostic contains: {foo=false, bar=true, baz=true}", - " void baz() {}", - " }", - "}") + """ + class A { + // BUG: Diagnostic contains: {foo=true, bar=true, baz=false} + void foo() {} + + // BUG: Diagnostic contains: {foo=true, bar=true, baz=false} + void bar() {} + + // BUG: Diagnostic contains: {foo=true, bar=true, baz=false} + void bar(int i) {} + + static class B { + // BUG: Diagnostic contains: {foo=false, bar=true, baz=true} + void bar() {} + + // BUG: Diagnostic contains: {foo=false, bar=true, baz=true} + void baz() {} + } + } + """) .doTest(); } @@ -79,42 +83,44 @@ void findMethodExitedOnReturn() { CompilationTestHelper.newInstance(FindMethodReturnTestChecker.class, getClass()) .addSourceLines( "A.java", - "import java.util.stream.Stream;", - "", - "class A {", - " {", - " toString();", - " }", - "", - " String topLevelMethod() {", - " // BUG: Diagnostic contains: topLevelMethod", - " toString();", - " // BUG: Diagnostic contains: topLevelMethod", - " return toString();", - " }", - "", - " Stream anotherMethod() {", - " // BUG: Diagnostic contains: anotherMethod", - " return Stream.of(1)", - " .map(", - " n -> {", - " toString();", - " return toString();", - " });", - " }", - "", - " void recursiveMethod(Runnable r) {", - " // BUG: Diagnostic contains: recursiveMethod", - " recursiveMethod(", - " new Runnable() {", - " @Override", - " public void run() {", - " // BUG: Diagnostic contains: run", - " toString();", - " }", - " });", - " }", - "}") + """ + import java.util.stream.Stream; + + class A { + { + toString(); + } + + String topLevelMethod() { + // BUG: Diagnostic contains: topLevelMethod + toString(); + // BUG: Diagnostic contains: topLevelMethod + return toString(); + } + + Stream anotherMethod() { + // BUG: Diagnostic contains: anotherMethod + return Stream.of(1) + .map( + n -> { + toString(); + return toString(); + }); + } + + void recursiveMethod(Runnable r) { + // BUG: Diagnostic contains: recursiveMethod + recursiveMethod( + new Runnable() { + @Override + public void run() { + // BUG: Diagnostic contains: run + toString(); + } + }); + } + } + """) .doTest(); } @@ -123,17 +129,19 @@ void areSameType() { CompilationTestHelper.newInstance(AreSameTypeTestChecker.class, getClass()) .addSourceLines( "A.java", - "class A {", - " void negative1(String a, Integer b) {}", - "", - " void negative2(Integer a, Number b) {}", - "", - " // BUG: Diagnostic contains:", - " void positive1(String a, String b) {}", - "", - " // BUG: Diagnostic contains:", - " void positive2(Iterable a, Iterable b) {}", - "}") + """ + class A { + void negative1(String a, Integer b) {} + + void negative2(Integer a, Number b) {} + + // BUG: Diagnostic contains: + void positive1(String a, String b) {} + + // BUG: Diagnostic contains: + void positive2(Iterable a, Iterable b) {} + } + """) .doTest(); } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MoreJUnitMatchersTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MoreJUnitMatchersTest.java index f21d57c6082..9497f6a01b0 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MoreJUnitMatchersTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MoreJUnitMatchersTest.java @@ -27,56 +27,58 @@ void methodMatchers() { CompilationTestHelper.newInstance(MethodMatchersTestChecker.class, getClass()) .addSourceLines( "A.java", - "import static org.junit.jupiter.params.provider.Arguments.arguments;", - "", - "import java.util.stream.Stream;", - "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;", - "import org.junit.jupiter.params.provider.Arguments;", - "import org.junit.jupiter.params.provider.MethodSource;", - "", - "class A {", - " @BeforeAll", - " // BUG: Diagnostic contains: SETUP_OR_TEARDOWN_METHOD", - " public void beforeAll() {}", - "", - " @BeforeEach", - " @Test", - " // BUG: Diagnostic contains: TEST_METHOD, SETUP_OR_TEARDOWN_METHOD", - " protected void beforeEachAndTest() {}", - "", - " @AfterEach", - " // BUG: Diagnostic contains: SETUP_OR_TEARDOWN_METHOD", - " private void afterEach() {}", - "", - " @AfterAll", - " // BUG: Diagnostic contains: SETUP_OR_TEARDOWN_METHOD", - " private void afterAll() {}", - "", - " @Test", - " // BUG: Diagnostic contains: TEST_METHOD", - " void test() {}", - "", - " private static Stream booleanArgs() {", - " return Stream.of(arguments(false), arguments(true));", - " }", - "", - " @ParameterizedTest", - " @MethodSource(\"booleanArgs\")", - " // BUG: Diagnostic contains: TEST_METHOD, HAS_METHOD_SOURCE", - " void parameterizedTest(boolean b) {}", - "", - " @RepeatedTest(2)", - " // BUG: Diagnostic contains: TEST_METHOD", - " private void repeatedTest() {}", - "", - " private void unannotatedMethod() {}", - "}") + """ + import static org.junit.jupiter.params.provider.Arguments.arguments; + + import java.util.stream.Stream; + 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; + import org.junit.jupiter.params.provider.Arguments; + import org.junit.jupiter.params.provider.MethodSource; + + class A { + @BeforeAll + // BUG: Diagnostic contains: SETUP_OR_TEARDOWN_METHOD + public void beforeAll() {} + + @BeforeEach + @Test + // BUG: Diagnostic contains: TEST_METHOD, SETUP_OR_TEARDOWN_METHOD + protected void beforeEachAndTest() {} + + @AfterEach + // BUG: Diagnostic contains: SETUP_OR_TEARDOWN_METHOD + private void afterEach() {} + + @AfterAll + // BUG: Diagnostic contains: SETUP_OR_TEARDOWN_METHOD + private void afterAll() {} + + @Test + // BUG: Diagnostic contains: TEST_METHOD + void test() {} + + private static Stream booleanArgs() { + return Stream.of(arguments(false), arguments(true)); + } + + @ParameterizedTest + @MethodSource("booleanArgs") + // BUG: Diagnostic contains: TEST_METHOD, HAS_METHOD_SOURCE + void parameterizedTest(boolean b) {} + + @RepeatedTest(2) + // BUG: Diagnostic contains: TEST_METHOD + private void repeatedTest() {} + + private void unannotatedMethod() {} + } + """) .doTest(); } @@ -85,32 +87,34 @@ void getMethodSourceFactoryNames() { CompilationTestHelper.newInstance(MethodSourceFactoryNamesTestChecker.class, getClass()) .addSourceLines( "A.java", - "import org.junit.jupiter.params.provider.MethodSource;", - "", - "class A {", - " @MethodSource", - " // BUG: Diagnostic contains: [matchingMethodSource]", - " void matchingMethodSource(boolean b) {}", - "", - " @MethodSource(\"myValueFactory\")", - " // BUG: Diagnostic contains: [myValueFactory]", - " void singleCustomMethodSource(boolean b) {}", - "", - " @MethodSource({", - " \"nullary()\",", - " \"nullary()\",", - " \"\",", - " \"withStringParam(java.lang.String)\",", - " \"paramsUnspecified\"", - " })", - " // BUG: Diagnostic contains: [nullary, nullary, multipleMethodSources, withStringParam,", - " // paramsUnspecified]", - " void multipleMethodSources(boolean b) {}", - "", - " @MethodSource({\"foo\", \"()\", \"bar\"})", - " // BUG: Diagnostic contains: [foo, , bar]", - " void methodSourceWithoutName(boolean b) {}", - "}") + """ + import org.junit.jupiter.params.provider.MethodSource; + + class A { + @MethodSource + // BUG: Diagnostic contains: [matchingMethodSource] + void matchingMethodSource(boolean b) {} + + @MethodSource("myValueFactory") + // BUG: Diagnostic contains: [myValueFactory] + void singleCustomMethodSource(boolean b) {} + + @MethodSource({ + "nullary()", + "nullary()", + "", + "withStringParam(java.lang.String)", + "paramsUnspecified" + }) + // BUG: Diagnostic contains: [nullary, nullary, multipleMethodSources, withStringParam, + // paramsUnspecified] + void multipleMethodSources(boolean b) {} + + @MethodSource({"foo", "()", "bar"}) + // BUG: Diagnostic contains: [foo, , bar] + void methodSourceWithoutName(boolean b) {} + } + """) .doTest(); } @@ -119,49 +123,51 @@ void getMethodSourceFactoryDescriptors() { CompilationTestHelper.newInstance(MethodSourceFactoryDescriptorsTestChecker.class, getClass()) .addSourceLines( "A.java", - "import org.junit.jupiter.params.provider.MethodSource;", - "", - "class A {", - " @MethodSource", - " // BUG: Diagnostic contains: [matchingMethodSource]", - " void matchingMethodSource(boolean b) {}", - "", - " @MethodSource()", - " // BUG: Diagnostic contains: [matchingMethodSourceWithParens]", - " void matchingMethodSourceWithParens(boolean b) {}", - "", - " @MethodSource(\"\")", - " // BUG: Diagnostic contains: [matchingMethodSourceMadeExplicit]", - " void matchingMethodSourceMadeExplicit(boolean b) {}", - "", - " @MethodSource({\"\"})", - " // BUG: Diagnostic contains: [matchingMethodSourceMadeExplicitWithParens]", - " void matchingMethodSourceMadeExplicitWithParens(boolean b) {}", - "", - " @MethodSource({})", - " // BUG: Diagnostic contains: []", - " void noMethodSources(boolean b) {}", - "", - " @MethodSource(\"myValueFactory\")", - " // BUG: Diagnostic contains: [myValueFactory]", - " void singleCustomMethodSource(boolean b) {}", - "", - " @MethodSource({\"firstValueFactory\", \"secondValueFactory\"})", - " // BUG: Diagnostic contains: [firstValueFactory, secondValueFactory]", - " void twoCustomMethodSources(boolean b) {}", - "", - " @MethodSource({\"myValueFactory\", \"\"})", - " // BUG: Diagnostic contains: [myValueFactory, customAndMatchingMethodSources]", - " void customAndMatchingMethodSources(boolean b) {}", - "", - " @MethodSource({\"factory\", \"\", \"factory\", \"\"})", - " // BUG: Diagnostic contains: [factory, repeatedMethodSources, factory, repeatedMethodSources]", - " void repeatedMethodSources(boolean b) {}", - "", - " @MethodSource({\"nullary()\", \"withStringParam(java.lang.String)\"})", - " // BUG: Diagnostic contains: [nullary(), withStringParam(java.lang.String)]", - " void methodSourcesWithParameterSpecification(boolean b) {}", - "}") + """ + import org.junit.jupiter.params.provider.MethodSource; + + class A { + @MethodSource + // BUG: Diagnostic contains: [matchingMethodSource] + void matchingMethodSource(boolean b) {} + + @MethodSource() + // BUG: Diagnostic contains: [matchingMethodSourceWithParens] + void matchingMethodSourceWithParens(boolean b) {} + + @MethodSource("") + // BUG: Diagnostic contains: [matchingMethodSourceMadeExplicit] + void matchingMethodSourceMadeExplicit(boolean b) {} + + @MethodSource({""}) + // BUG: Diagnostic contains: [matchingMethodSourceMadeExplicitWithParens] + void matchingMethodSourceMadeExplicitWithParens(boolean b) {} + + @MethodSource({}) + // BUG: Diagnostic contains: [] + void noMethodSources(boolean b) {} + + @MethodSource("myValueFactory") + // BUG: Diagnostic contains: [myValueFactory] + void singleCustomMethodSource(boolean b) {} + + @MethodSource({"firstValueFactory", "secondValueFactory"}) + // BUG: Diagnostic contains: [firstValueFactory, secondValueFactory] + void twoCustomMethodSources(boolean b) {} + + @MethodSource({"myValueFactory", ""}) + // BUG: Diagnostic contains: [myValueFactory, customAndMatchingMethodSources] + void customAndMatchingMethodSources(boolean b) {} + + @MethodSource({"factory", "", "factory", ""}) + // BUG: Diagnostic contains: [factory, repeatedMethodSources, factory, repeatedMethodSources] + void repeatedMethodSources(boolean b) {} + + @MethodSource({"nullary()", "withStringParam(java.lang.String)"}) + // BUG: Diagnostic contains: [nullary(), withStringParam(java.lang.String)] + void methodSourcesWithParameterSpecification(boolean b) {} + } + """) .doTest(); } diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MoreMatchersTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MoreMatchersTest.java index b299ff20eb4..fa8883ce7ec 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MoreMatchersTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/MoreMatchersTest.java @@ -26,32 +26,34 @@ void hasMetaAnnotation() { CompilationTestHelper.newInstance(HasMetaAnnotationTestChecker.class, getClass()) .addSourceLines( "A.java", - "import org.junit.jupiter.api.AfterAll;", - "import org.junit.jupiter.api.RepeatedTest;", - "import org.junit.jupiter.api.Test;", - "import org.junit.jupiter.api.TestTemplate;", - "import org.junit.jupiter.params.ParameterizedTest;", - "", - "class A {", - " void negative1() {}", - "", - " @Test", - " void negative2() {}", - "", - " @AfterAll", - " void negative3() {}", - "", - " @TestTemplate", - " void negative4() {}", - "", - " // BUG: Diagnostic contains:", - " @ParameterizedTest", - " void positive1() {}", - "", - " // BUG: Diagnostic contains:", - " @RepeatedTest(2)", - " void positive2() {}", - "}") + """ + import org.junit.jupiter.api.AfterAll; + import org.junit.jupiter.api.RepeatedTest; + import org.junit.jupiter.api.Test; + import org.junit.jupiter.api.TestTemplate; + import org.junit.jupiter.params.ParameterizedTest; + + class A { + void negative1() {} + + @Test + void negative2() {} + + @AfterAll + void negative3() {} + + @TestTemplate + void negative4() {} + + // BUG: Diagnostic contains: + @ParameterizedTest + void positive1() {} + + // BUG: Diagnostic contains: + @RepeatedTest(2) + void positive2() {} + } + """) .doTest(); } @@ -60,33 +62,35 @@ void isSubTypeOf() { CompilationTestHelper.newInstance(IsSubTypeOfTestChecker.class, getClass()) .addSourceLines( "A.java", - "import com.google.common.collect.ImmutableList;", - "import com.google.common.collect.ImmutableSet;", - "import com.google.common.collect.ImmutableSortedSet;", - "", - "class A {", - " void m() {", - " ImmutableSet.of(\"foo\");", - " ImmutableSortedSet.of(\"foo\");", - " ImmutableList.of(\"foo\");", - " ImmutableList.of(1);", - " ImmutableList.of(1.0);", - " ImmutableList.of((Number) 1);", - "", - " // BUG: Diagnostic contains:", - " ImmutableSet.of(1);", - " // BUG: Diagnostic contains:", - " ImmutableSet.of(1.0);", - " // BUG: Diagnostic contains:", - " ImmutableSet.of((Number) 1);", - " // BUG: Diagnostic contains:", - " ImmutableSortedSet.of(1);", - " // BUG: Diagnostic contains:", - " ImmutableSortedSet.of(1.0);", - " // BUG: Diagnostic contains:", - " ImmutableSortedSet.of((Number) 1);", - " }", - "}") + """ + import com.google.common.collect.ImmutableList; + import com.google.common.collect.ImmutableSet; + import com.google.common.collect.ImmutableSortedSet; + + class A { + void m() { + ImmutableSet.of("foo"); + ImmutableSortedSet.of("foo"); + ImmutableList.of("foo"); + ImmutableList.of(1); + ImmutableList.of(1.0); + ImmutableList.of((Number) 1); + + // BUG: Diagnostic contains: + ImmutableSet.of(1); + // BUG: Diagnostic contains: + ImmutableSet.of(1.0); + // BUG: Diagnostic contains: + ImmutableSet.of((Number) 1); + // BUG: Diagnostic contains: + ImmutableSortedSet.of(1); + // BUG: Diagnostic contains: + ImmutableSortedSet.of(1.0); + // BUG: Diagnostic contains: + ImmutableSortedSet.of((Number) 1); + } + } + """) .doTest(); } @@ -96,11 +100,13 @@ void isSubTypeOfBoundTypeUnknown() { .withClasspath() .addSourceLines( "A.java", - "class A {", - " void m() {", - " System.out.println(toString());", - " }", - "}") + """ + class A { + void m() { + System.out.println(toString()); + } + } + """) .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 0a30ba4bc62..2fbbe8b6c24 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 @@ -33,91 +33,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/SourceCodeTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/SourceCodeTest.java index 4c21be431e0..6975bbde0d8 100644 --- a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/SourceCodeTest.java +++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/util/SourceCodeTest.java @@ -32,22 +32,24 @@ void isTextBlock() { CompilationTestHelper.newInstance(TextBlockFlagger.class, getClass()) .addSourceLines( "A.java", - "class A {", - " String negative1() {", - " return toString();", - " }", - "", - " String negative2() {", - " return \"foo\";", - " }", - "", - " String positive1() {", - " // BUG: Diagnostic contains:", - " return \"\"\"", - " foo", - " \"\"\";", - " }", - "}") + """ + class A { + String negative1() { + return toString(); + } + + String negative2() { + return "foo"; + } + + String positive1() { + // BUG: Diagnostic contains: + return ""\" + foo + ""\"; + } + } + """) .doTest(); } @@ -55,73 +57,84 @@ void isTextBlock() { void deleteWithTrailingWhitespaceAnnotations() { BugCheckerRefactoringTestHelper.newInstance( DeleteWithTrailingWhitespaceTestChecker.class, getClass()) - .addInputLines("AnnotationToBeDeleted.java", "@interface AnnotationToBeDeleted {}") + .addInputLines( + "AnnotationToBeDeleted.java", + """ + @interface AnnotationToBeDeleted {} + """) .expectUnchanged() .addInputLines( - "AnotherAnnotationToBeDeleted.java", "@interface AnotherAnnotationToBeDeleted {}") + "AnotherAnnotationToBeDeleted.java", + """ + @interface AnotherAnnotationToBeDeleted {} + """) .expectUnchanged() .addInputLines( "AnnotationDeletions.java", - "interface AnnotationDeletions {", - " class SoleAnnotation {", - " @AnnotationToBeDeleted", - " void m() {}", - " }", - "", - " class FirstAnnotation {", - " @AnnotationToBeDeleted", - " @Deprecated", - " void m() {}", - " }", - "", - " class MiddleAnnotation {", - " @Deprecated", - " @AnnotationToBeDeleted", - " @SuppressWarnings(\"foo\")", - " void m() {}", - " }", - "", - " class LastAnnotation {", - " @Deprecated", - " @AnnotationToBeDeleted", - " void m() {}", - " }", - "", - " class MultipleAnnotations {", - " @AnnotationToBeDeleted", - " @AnotherAnnotationToBeDeleted", - " @Deprecated", - " void m() {}", - " }", - "}") + """ + interface AnnotationDeletions { + class SoleAnnotation { + @AnnotationToBeDeleted + void m() {} + } + + class FirstAnnotation { + @AnnotationToBeDeleted + @Deprecated + void m() {} + } + + class MiddleAnnotation { + @Deprecated + @AnnotationToBeDeleted + @SuppressWarnings("foo") + void m() {} + } + + class LastAnnotation { + @Deprecated + @AnnotationToBeDeleted + void m() {} + } + + class MultipleAnnotations { + @AnnotationToBeDeleted + @AnotherAnnotationToBeDeleted + @Deprecated + void m() {} + } + } + """) .addOutputLines( "AnnotationDeletions.java", - "interface AnnotationDeletions {", - " class SoleAnnotation {", - " void m() {}", - " }", - "", - " class FirstAnnotation {", - " @Deprecated", - " void m() {}", - " }", - "", - " class MiddleAnnotation {", - " @Deprecated", - " @SuppressWarnings(\"foo\")", - " void m() {}", - " }", - "", - " class LastAnnotation {", - " @Deprecated", - " void m() {}", - " }", - "", - " class MultipleAnnotations {", - " @Deprecated", - " void m() {}", - " }", - "}") + """ + interface AnnotationDeletions { + class SoleAnnotation { + void m() {} + } + + class FirstAnnotation { + @Deprecated + void m() {} + } + + class MiddleAnnotation { + @Deprecated + @SuppressWarnings("foo") + void m() {} + } + + class LastAnnotation { + @Deprecated + void m() {} + } + + class MultipleAnnotations { + @Deprecated + void m() {} + } + } + """) .doTest(TestMode.TEXT_MATCH); } @@ -131,66 +144,70 @@ void deleteWithTrailingWhitespaceMethods() { DeleteWithTrailingWhitespaceTestChecker.class, getClass()) .addInputLines( "MethodDeletions.java", - "interface MethodDeletions {", - " class SoleMethod {", - " void methodToBeDeleted() {}", - " }", - "", - " class FirstMethod {", - " void methodToBeDeleted() {}", - "", - " void finalMethod() {}", - " }", - "", - " class MiddleMethod {", - " void initialMethod() {}", - "", - " void methodToBeDeleted() {}", - "", - " void finalMethod() {}", - " }", - "", - " class LastMethod {", - " void initialMethod() {}", - "", - " void methodToBeDeleted() {}", - " }", - "", - " class MultipleMethods {", - " void method1ToBeDeleted() {}", - "", - " void method2ToBeDeleted() {}", - "", - " void middleMethod() {}", - "", - " void method3ToBeDeleted() {}", - "", - " void method4ToBeDeleted() {}", - " }", - "}") + """ + interface MethodDeletions { + class SoleMethod { + void methodToBeDeleted() {} + } + + class FirstMethod { + void methodToBeDeleted() {} + + void finalMethod() {} + } + + class MiddleMethod { + void initialMethod() {} + + void methodToBeDeleted() {} + + void finalMethod() {} + } + + class LastMethod { + void initialMethod() {} + + void methodToBeDeleted() {} + } + + class MultipleMethods { + void method1ToBeDeleted() {} + + void method2ToBeDeleted() {} + + void middleMethod() {} + + void method3ToBeDeleted() {} + + void method4ToBeDeleted() {} + } + } + """) .addOutputLines( "MethodDeletions.java", - "interface MethodDeletions {", - " class SoleMethod {}", - "", - " class FirstMethod {", - " void finalMethod() {}", - " }", - "", - " class MiddleMethod {", - " void initialMethod() {}", - "", - " void finalMethod() {}", - " }", - "", - " class LastMethod {", - " void initialMethod() {}", - " }", - "", - " class MultipleMethods {", - " void middleMethod() {}", - " }", - "}") + """ + interface MethodDeletions { + class SoleMethod {} + + class FirstMethod { + void finalMethod() {} + } + + class MiddleMethod { + void initialMethod() {} + + void finalMethod() {} + } + + class LastMethod { + void initialMethod() {} + } + + class MultipleMethods { + void middleMethod() {} + } + } + """) .doTest(TestMode.TEXT_MATCH); } @@ -199,30 +216,34 @@ void unwrapMethodInvocation() { BugCheckerRefactoringTestHelper.newInstance(UnwrapMethodInvocationTestChecker.class, getClass()) .addInputLines( "A.java", - "import com.google.common.collect.ImmutableList;", - "", - "class A {", - " Object[] m() {", - " return new Object[][] {", - " {ImmutableList.of()},", - " {ImmutableList.of(1)},", - " {com.google.common.collect.ImmutableList.of(1, 2)},", - " {", - " 0, /*a*/", - " ImmutableList /*b*/./*c*/ /*d*/of /*e*/(/*f*/ 1 /*g*/, /*h*/ 2 /*i*/) /*j*/", - " }", - " };", - " }", - "}") + """ + import com.google.common.collect.ImmutableList; + + class A { + Object[] m() { + return new Object[][] { + {ImmutableList.of()}, + {ImmutableList.of(1)}, + {com.google.common.collect.ImmutableList.of(1, 2)}, + { + 0, /*a*/ + ImmutableList /*b*/./*c*/ /*d*/of /*e*/(/*f*/ 1 /*g*/, /*h*/ 2 /*i*/) /*j*/ + } + }; + } + } + """) .addOutputLines( "A.java", - "import com.google.common.collect.ImmutableList;", - "", - "class A {", - " Object[] m() {", - " return new Object[][] {{}, {1}, {1, 2}, {0, /*a*/ /*f*/ 1 /*g*/, /*h*/ 2 /*i*/ /*j*/}};", - " }", - "}") + """ + import com.google.common.collect.ImmutableList; + + class A { + Object[] m() { + return new Object[][] {{}, {1}, {1, 2}, {0, /*a*/ /*f*/ 1 /*g*/, /*h*/ 2 /*i*/ /*j*/}}; + } + } + """) .doTest(TestMode.TEXT_MATCH); } @@ -232,30 +253,34 @@ void unwrapMethodInvocationDroppingWhitespaceAndComments() { UnwrapMethodInvocationDroppingWhitespaceAndCommentsTestChecker.class, getClass()) .addInputLines( "A.java", - "import com.google.common.collect.ImmutableList;", - "", - "class A {", - " Object[] m() {", - " return new Object[][] {", - " {ImmutableList.of()},", - " {ImmutableList.of(1)},", - " {com.google.common.collect.ImmutableList.of(1, 2)},", - " {", - " 0, /*a*/", - " ImmutableList /*b*/./*c*/ /*d*/of /*e*/(/*f*/ 1 /*g*/, /*h*/ 2 /*i*/) /*j*/", - " }", - " };", - " }", - "}") + """ + import com.google.common.collect.ImmutableList; + + class A { + Object[] m() { + return new Object[][] { + {ImmutableList.of()}, + {ImmutableList.of(1)}, + {com.google.common.collect.ImmutableList.of(1, 2)}, + { + 0, /*a*/ + ImmutableList /*b*/./*c*/ /*d*/of /*e*/(/*f*/ 1 /*g*/, /*h*/ 2 /*i*/) /*j*/ + } + }; + } + } + """) .addOutputLines( "A.java", - "import com.google.common.collect.ImmutableList;", - "", - "class A {", - " Object[] m() {", - " return new Object[][] {{}, {1}, {1, 2}, {0, /*a*/ 1, 2 /*j*/}};", - " }", - "}") + """ + import com.google.common.collect.ImmutableList; + + class A { + Object[] m() { + return new Object[][] {{}, {1}, {1, 2}, {0, /*a*/ 1, 2 /*j*/}}; + } + } + """) .doTest(TestMode.TEXT_MATCH); } 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 4338f9af358..0ca354c2c0b 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 @@ -23,8 +23,10 @@ void isIntroductionAllowed() { CompilationTestHelper.newInstance(TestChecker.class, getClass()) .addSourceLines( "A.java", - "// BUG: Diagnostic contains: ASSERTJ: true, GUAVA: true, REACTOR: true", - "class A {}") + """ + // BUG: Diagnostic contains: ASSERTJ: true, GUAVA: true, REACTOR: true + class A {} + """) .doTest(); } @@ -33,18 +35,20 @@ void isIntroductionAllowedWitnessClassesInSymtab() { CompilationTestHelper.newInstance(TestChecker.class, getClass()) .addSourceLines( "A.java", - "import com.google.common.collect.ImmutableList;", - "import org.assertj.core.api.Assertions;", - "import reactor.core.publisher.Flux;", - "", - "// BUG: Diagnostic contains: ASSERTJ: true, GUAVA: true, REACTOR: true", - "class A {", - " void m(Class clazz) {", - " m(Assertions.class);", - " m(ImmutableList.class);", - " m(Flux.class);", - " }", - "}") + """ + import com.google.common.collect.ImmutableList; + import org.assertj.core.api.Assertions; + import reactor.core.publisher.Flux; + + // BUG: Diagnostic contains: ASSERTJ: true, GUAVA: true, REACTOR: true + class A { + void m(Class clazz) { + m(Assertions.class); + m(ImmutableList.class); + m(Flux.class); + } + } + """) .doTest(); } @@ -54,8 +58,10 @@ void isIntroductionAllowedWitnessClassesPartiallyOnClassPath() { .withClasspath(ImmutableList.class, Flux.class) .addSourceLines( "A.java", - "// BUG: Diagnostic contains: ASSERTJ: false, GUAVA: true, REACTOR: true", - "class A {}") + """ + // BUG: Diagnostic contains: ASSERTJ: false, GUAVA: true, REACTOR: true + class A {} + """) .doTest(); } @@ -65,9 +71,11 @@ void isIntroductionAllowedWitnessClassesNotOnClassPath() { .withClasspath() .addSourceLines( "A.java", - "// BUG: Diagnostic contains: ASSERTJ: false, GUAVA: false, REACTOR:", - "// false", - "class A {}") + """ + // BUG: Diagnostic contains: ASSERTJ: false, GUAVA: 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 65abc2d9ca7..076b87c9b45 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 @@ -52,18 +52,20 @@ void identification() { .expectErrorMessage("StringOfSizeThreeRule", DIAGNOSTIC_STRING_OF_SIZE_THREE.asPredicate()) .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(); } @@ -154,16 +156,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 + }; + } + } + """); if (expectedSeverities.isEmpty()) { compilationTestHelper.doTest(); @@ -205,24 +209,28 @@ void replacement() { BugCheckerRefactoringTestHelper.newInstance(Refaster.class, getClass()) .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); } @@ -233,24 +241,28 @@ void restrictedReplacement() { "-XepOpt:Refaster:NamePattern=.*\\$(StringOfSizeZeroVerboseRule|StringOfSizeTwoRule)$") .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/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/IsEmptyTest.java b/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsEmptyTest.java index 318328cbec3..1b41d5af274 100644 --- a/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsEmptyTest.java +++ b/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsEmptyTest.java @@ -13,418 +13,420 @@ void matches() { CompilationTestHelper.newInstance(MatcherTestChecker.class, getClass()) .addSourceLines( "A.java", - "import com.google.common.collect.ImmutableList;", - "import com.google.common.collect.ImmutableMap;", - "import com.google.common.collect.ImmutableSet;", - "import com.google.common.collect.ImmutableSetMultimap;", - "import java.util.ArrayList;", - "import java.util.Collections;", - "import java.util.Comparator;", - "import java.util.HashMap;", - "import java.util.HashSet;", - "import java.util.LinkedHashMap;", - "import java.util.LinkedHashSet;", - "import java.util.LinkedList;", - "import java.util.List;", - "import java.util.Map;", - "import java.util.Random;", - "import java.util.Set;", - "import java.util.Stack;", - "import java.util.TreeMap;", - "import java.util.TreeSet;", - "import java.util.Vector;", - "import java.util.stream.Stream;", - "import reactor.core.publisher.Flux;", - "import reactor.core.publisher.Mono;", - "import reactor.util.context.Context;", - "", - "class A {", - " int[] negative1() {", - " return new int[1];", - " }", - "", - " int[][] negative2() {", - " return new int[1][0];", - " }", - "", - " int[] negative3() {", - " return new int[] {0};", - " }", - "", - " int[][] negative4() {", - " return new int[][] {{0}};", - " }", - "", - " Random negative5() {", - " return new Random();", - " }", - "", - " List negative6() {", - " return new ArrayList<>(ImmutableList.of(1));", - " }", - "", - " Map negative7() {", - " return new HashMap<>(ImmutableMap.of(1, 2));", - " }", - "", - " Set negative8() {", - " return new HashSet<>(ImmutableList.of(1));", - " }", - "", - " Map negative9() {", - " return new LinkedHashMap<>(ImmutableMap.of(1, 2));", - " }", - "", - " Set negative10() {", - " return new LinkedHashSet<>(ImmutableList.of(1));", - " }", - "", - " List negative11() {", - " return new LinkedList<>(ImmutableList.of(1));", - " }", - "", - " Map negative12() {", - " return new HashMap<>(ImmutableMap.of(1, 2));", - " }", - "", - " Set negative13() {", - " return new HashSet<>(ImmutableList.of(1));", - " }", - "", - " List negative14() {", - " return new Vector<>(ImmutableList.of(1));", - " }", - "", - " ImmutableList negative15() {", - " return ImmutableList.of(1);", - " }", - "", - " ImmutableSet negative16() {", - " return ImmutableSet.of(1);", - " }", - "", - " ImmutableMap negative17() {", - " return ImmutableMap.of(1, 2);", - " }", - "", - " ImmutableSetMultimap negative18() {", - " return ImmutableSetMultimap.of(1, 2);", - " }", - "", - " List negative19() {", - " return List.of(1);", - " }", - "", - " Map negative20() {", - " return Map.of(1, 2);", - " }", - "", - " Set negative21() {", - " return Set.of(1);", - " }", - "", - " Stream negative22() {", - " return Stream.of(1);", - " }", - "", - " int[] positive1() {", - " // BUG: Diagnostic contains:", - " return new int[0];", - " }", - "", - " int[][] positive2() {", - " // BUG: Diagnostic contains:", - " return new int[0][1];", - " }", - "", - " int[] positive3() {", - " // BUG: Diagnostic contains:", - " return new int[] {};", - " }", - "", - " int[][] positive4() {", - " // BUG: Diagnostic contains:", - " return new int[][] {};", - " }", - "", - " List positive5() {", - " // BUG: Diagnostic contains:", - " return new ArrayList<>();", - " }", - "", - " List positive6() {", - " // BUG: Diagnostic contains:", - " return new ArrayList<>(1);", - " }", - "", - " List positive7() {", - " // BUG: Diagnostic contains:", - " return new ArrayList<>(", - " // BUG: Diagnostic contains:", - " ImmutableList.of());", - " }", - "", - " Map positive8() {", - " // BUG: Diagnostic contains:", - " return new HashMap<>();", - " }", - "", - " Map positive9() {", - " // BUG: Diagnostic contains:", - " return new HashMap<>(1);", - " }", - "", - " Map positive10() {", - " // BUG: Diagnostic contains:", - " return new HashMap<>(1, 1.0F);", - " }", - "", - " Map positive11() {", - " // BUG: Diagnostic contains:", - " return new HashMap<>(", - " // BUG: Diagnostic contains:", - " ImmutableMap.of());", - " }", - "", - " Set positive12() {", - " // BUG: Diagnostic contains:", - " return new HashSet<>();", - " }", - "", - " Set positive13() {", - " // BUG: Diagnostic contains:", - " return new HashSet<>(1);", - " }", - "", - " Set positive14() {", - " // BUG: Diagnostic contains:", - " return new HashSet<>(1, 1.0F);", - " }", - "", - " Set positive15() {", - " // BUG: Diagnostic contains:", - " return new HashSet<>(", - " // BUG: Diagnostic contains:", - " ImmutableList.of());", - " }", - "", - " Map positive16() {", - " // BUG: Diagnostic contains:", - " return new LinkedHashMap<>();", - " }", - "", - " Map positive17() {", - " // BUG: Diagnostic contains:", - " return new LinkedHashMap<>(1);", - " }", - "", - " Map positive18() {", - " // BUG: Diagnostic contains:", - " return new LinkedHashMap<>(1, 1.0F);", - " }", - "", - " Map positive19() {", - " // BUG: Diagnostic contains:", - " return new LinkedHashMap<>(1, 1.0F, false);", - " }", - "", - " Map positive20() {", - " // BUG: Diagnostic contains:", - " return new LinkedHashMap<>(", - " // BUG: Diagnostic contains:", - " ImmutableMap.of());", - " }", - "", - " Set positive21() {", - " // BUG: Diagnostic contains:", - " return new LinkedHashSet<>();", - " }", - "", - " Set positive22() {", - " // BUG: Diagnostic contains:", - " return new LinkedHashSet<>(1);", - " }", - "", - " Set positive23() {", - " // BUG: Diagnostic contains:", - " return new LinkedHashSet<>(1, 1.0F);", - " }", - "", - " Set positive24() {", - " // BUG: Diagnostic contains:", - " return new LinkedHashSet<>(", - " // BUG: Diagnostic contains:", - " ImmutableList.of());", - " }", - "", - " List positive25() {", - " // BUG: Diagnostic contains:", - " return new LinkedList<>();", - " }", - "", - " List positive26() {", - " // BUG: Diagnostic contains:", - " return new LinkedList<>(", - " // BUG: Diagnostic contains:", - " ImmutableList.of());", - " }", - "", - " List positive27() {", - " // BUG: Diagnostic contains:", - " return new Stack<>();", - " }", - "", - " Map positive28() {", - " // BUG: Diagnostic contains:", - " return new TreeMap<>();", - " }", - "", - " Map positive29() {", - " // BUG: Diagnostic contains:", - " return new TreeMap<>(Comparator.naturalOrder());", - " }", - "", - " Map positive30() {", - " // BUG: Diagnostic contains:", - " return new TreeMap<>(", - " // BUG: Diagnostic contains:", - " ImmutableMap.of());", - " }", - "", - " Set positive31() {", - " // BUG: Diagnostic contains:", - " return new TreeSet<>();", - " }", - "", - " Set positive32() {", - " // BUG: Diagnostic contains:", - " return new TreeSet<>(Comparator.naturalOrder());", - " }", - "", - " Set positive33() {", - " // BUG: Diagnostic contains:", - " return new TreeSet<>(", - " // BUG: Diagnostic contains:", - " ImmutableList.of());", - " }", - "", - " List positive34() {", - " // BUG: Diagnostic contains:", - " return new Vector<>();", - " }", - "", - " List positive35() {", - " // BUG: Diagnostic contains:", - " return new Vector<>(1);", - " }", - "", - " List positive36() {", - " // BUG: Diagnostic contains:", - " return new Vector<>(1, 2);", - " }", - "", - " List positive37() {", - " // BUG: Diagnostic contains:", - " return new Vector<>(", - " // BUG: Diagnostic contains:", - " ImmutableList.of());", - " }", - "", - " List positive38() {", - " // BUG: Diagnostic contains:", - " return Collections.EMPTY_LIST;", - " }", - "", - " Map positive39() {", - " // BUG: Diagnostic contains:", - " return Collections.EMPTY_MAP;", - " }", - "", - " Set positive40() {", - " // BUG: Diagnostic contains:", - " return Collections.EMPTY_SET;", - " }", - "", - " List positive41() {", - " // BUG: Diagnostic contains:", - " return Collections.emptyList();", - " }", - "", - " Map positive42() {", - " // BUG: Diagnostic contains:", - " return Collections.emptyMap();", - " }", - "", - " Set positive43() {", - " // BUG: Diagnostic contains:", - " return Collections.emptySet();", - " }", - "", - " ImmutableList positive44() {", - " // BUG: Diagnostic contains:", - " return ImmutableList.of();", - " }", - "", - " ImmutableSet positive45() {", - " // BUG: Diagnostic contains:", - " return ImmutableSet.of();", - " }", - "", - " ImmutableMap positive46() {", - " // BUG: Diagnostic contains:", - " return ImmutableMap.of();", - " }", - "", - " ImmutableSetMultimap positive47() {", - " // BUG: Diagnostic contains:", - " return ImmutableSetMultimap.of();", - " }", - "", - " List positive48() {", - " // BUG: Diagnostic contains:", - " return List.of();", - " }", - "", - " Map positive49() {", - " // BUG: Diagnostic contains:", - " return Map.of();", - " }", - "", - " Set positive50() {", - " // BUG: Diagnostic contains:", - " return Set.of();", - " }", - "", - " Stream positive51() {", - " // BUG: Diagnostic contains:", - " return Stream.of();", - " }", - "", - " Stream positive52() {", - " // BUG: Diagnostic contains:", - " return Stream.empty();", - " }", - "", - " Flux positive53() {", - " // BUG: Diagnostic contains:", - " return Flux.empty();", - " }", - "", - " Mono positive54() {", - " // BUG: Diagnostic contains:", - " return Mono.empty();", - " }", - "", - " Context positive55() {", - " // BUG: Diagnostic contains:", - " return Context.empty();", - " }", - "", - " Flux positive56() {", - " // BUG: Diagnostic contains:", - " return Flux.just();", - " }", - "}") + """ + import com.google.common.collect.ImmutableList; + import com.google.common.collect.ImmutableMap; + import com.google.common.collect.ImmutableSet; + import com.google.common.collect.ImmutableSetMultimap; + import java.util.ArrayList; + import java.util.Collections; + import java.util.Comparator; + import java.util.HashMap; + import java.util.HashSet; + import java.util.LinkedHashMap; + import java.util.LinkedHashSet; + import java.util.LinkedList; + import java.util.List; + import java.util.Map; + import java.util.Random; + import java.util.Set; + import java.util.Stack; + import java.util.TreeMap; + import java.util.TreeSet; + import java.util.Vector; + import java.util.stream.Stream; + import reactor.core.publisher.Flux; + import reactor.core.publisher.Mono; + import reactor.util.context.Context; + + class A { + int[] negative1() { + return new int[1]; + } + + int[][] negative2() { + return new int[1][0]; + } + + int[] negative3() { + return new int[] {0}; + } + + int[][] negative4() { + return new int[][] {{0}}; + } + + Random negative5() { + return new Random(); + } + + List negative6() { + return new ArrayList<>(ImmutableList.of(1)); + } + + Map negative7() { + return new HashMap<>(ImmutableMap.of(1, 2)); + } + + Set negative8() { + return new HashSet<>(ImmutableList.of(1)); + } + + Map negative9() { + return new LinkedHashMap<>(ImmutableMap.of(1, 2)); + } + + Set negative10() { + return new LinkedHashSet<>(ImmutableList.of(1)); + } + + List negative11() { + return new LinkedList<>(ImmutableList.of(1)); + } + + Map negative12() { + return new HashMap<>(ImmutableMap.of(1, 2)); + } + + Set negative13() { + return new HashSet<>(ImmutableList.of(1)); + } + + List negative14() { + return new Vector<>(ImmutableList.of(1)); + } + + ImmutableList negative15() { + return ImmutableList.of(1); + } + + ImmutableSet negative16() { + return ImmutableSet.of(1); + } + + ImmutableMap negative17() { + return ImmutableMap.of(1, 2); + } + + ImmutableSetMultimap negative18() { + return ImmutableSetMultimap.of(1, 2); + } + + List negative19() { + return List.of(1); + } + + Map negative20() { + return Map.of(1, 2); + } + + Set negative21() { + return Set.of(1); + } + + Stream negative22() { + return Stream.of(1); + } + + int[] positive1() { + // BUG: Diagnostic contains: + return new int[0]; + } + + int[][] positive2() { + // BUG: Diagnostic contains: + return new int[0][1]; + } + + int[] positive3() { + // BUG: Diagnostic contains: + return new int[] {}; + } + + int[][] positive4() { + // BUG: Diagnostic contains: + return new int[][] {}; + } + + List positive5() { + // BUG: Diagnostic contains: + return new ArrayList<>(); + } + + List positive6() { + // BUG: Diagnostic contains: + return new ArrayList<>(1); + } + + List positive7() { + // BUG: Diagnostic contains: + return new ArrayList<>( + // BUG: Diagnostic contains: + ImmutableList.of()); + } + + Map positive8() { + // BUG: Diagnostic contains: + return new HashMap<>(); + } + + Map positive9() { + // BUG: Diagnostic contains: + return new HashMap<>(1); + } + + Map positive10() { + // BUG: Diagnostic contains: + return new HashMap<>(1, 1.0F); + } + + Map positive11() { + // BUG: Diagnostic contains: + return new HashMap<>( + // BUG: Diagnostic contains: + ImmutableMap.of()); + } + + Set positive12() { + // BUG: Diagnostic contains: + return new HashSet<>(); + } + + Set positive13() { + // BUG: Diagnostic contains: + return new HashSet<>(1); + } + + Set positive14() { + // BUG: Diagnostic contains: + return new HashSet<>(1, 1.0F); + } + + Set positive15() { + // BUG: Diagnostic contains: + return new HashSet<>( + // BUG: Diagnostic contains: + ImmutableList.of()); + } + + Map positive16() { + // BUG: Diagnostic contains: + return new LinkedHashMap<>(); + } + + Map positive17() { + // BUG: Diagnostic contains: + return new LinkedHashMap<>(1); + } + + Map positive18() { + // BUG: Diagnostic contains: + return new LinkedHashMap<>(1, 1.0F); + } + + Map positive19() { + // BUG: Diagnostic contains: + return new LinkedHashMap<>(1, 1.0F, false); + } + + Map positive20() { + // BUG: Diagnostic contains: + return new LinkedHashMap<>( + // BUG: Diagnostic contains: + ImmutableMap.of()); + } + + Set positive21() { + // BUG: Diagnostic contains: + return new LinkedHashSet<>(); + } + + Set positive22() { + // BUG: Diagnostic contains: + return new LinkedHashSet<>(1); + } + + Set positive23() { + // BUG: Diagnostic contains: + return new LinkedHashSet<>(1, 1.0F); + } + + Set positive24() { + // BUG: Diagnostic contains: + return new LinkedHashSet<>( + // BUG: Diagnostic contains: + ImmutableList.of()); + } + + List positive25() { + // BUG: Diagnostic contains: + return new LinkedList<>(); + } + + List positive26() { + // BUG: Diagnostic contains: + return new LinkedList<>( + // BUG: Diagnostic contains: + ImmutableList.of()); + } + + List positive27() { + // BUG: Diagnostic contains: + return new Stack<>(); + } + + Map positive28() { + // BUG: Diagnostic contains: + return new TreeMap<>(); + } + + Map positive29() { + // BUG: Diagnostic contains: + return new TreeMap<>(Comparator.naturalOrder()); + } + + Map positive30() { + // BUG: Diagnostic contains: + return new TreeMap<>( + // BUG: Diagnostic contains: + ImmutableMap.of()); + } + + Set positive31() { + // BUG: Diagnostic contains: + return new TreeSet<>(); + } + + Set positive32() { + // BUG: Diagnostic contains: + return new TreeSet<>(Comparator.naturalOrder()); + } + + Set positive33() { + // BUG: Diagnostic contains: + return new TreeSet<>( + // BUG: Diagnostic contains: + ImmutableList.of()); + } + + List positive34() { + // BUG: Diagnostic contains: + return new Vector<>(); + } + + List positive35() { + // BUG: Diagnostic contains: + return new Vector<>(1); + } + + List positive36() { + // BUG: Diagnostic contains: + return new Vector<>(1, 2); + } + + List positive37() { + // BUG: Diagnostic contains: + return new Vector<>( + // BUG: Diagnostic contains: + ImmutableList.of()); + } + + List positive38() { + // BUG: Diagnostic contains: + return Collections.EMPTY_LIST; + } + + Map positive39() { + // BUG: Diagnostic contains: + return Collections.EMPTY_MAP; + } + + Set positive40() { + // BUG: Diagnostic contains: + return Collections.EMPTY_SET; + } + + List positive41() { + // BUG: Diagnostic contains: + return Collections.emptyList(); + } + + Map positive42() { + // BUG: Diagnostic contains: + return Collections.emptyMap(); + } + + Set positive43() { + // BUG: Diagnostic contains: + return Collections.emptySet(); + } + + ImmutableList positive44() { + // BUG: Diagnostic contains: + return ImmutableList.of(); + } + + ImmutableSet positive45() { + // BUG: Diagnostic contains: + return ImmutableSet.of(); + } + + ImmutableMap positive46() { + // BUG: Diagnostic contains: + return ImmutableMap.of(); + } + + ImmutableSetMultimap positive47() { + // BUG: Diagnostic contains: + return ImmutableSetMultimap.of(); + } + + List positive48() { + // BUG: Diagnostic contains: + return List.of(); + } + + Map positive49() { + // BUG: Diagnostic contains: + return Map.of(); + } + + Set positive50() { + // BUG: Diagnostic contains: + return Set.of(); + } + + Stream positive51() { + // BUG: Diagnostic contains: + return Stream.of(); + } + + Stream positive52() { + // BUG: Diagnostic contains: + return Stream.empty(); + } + + Flux positive53() { + // BUG: Diagnostic contains: + return Flux.empty(); + } + + Mono positive54() { + // BUG: Diagnostic contains: + return Mono.empty(); + } + + Context positive55() { + // BUG: Diagnostic contains: + return Context.empty(); + } + + Flux positive56() { + // BUG: Diagnostic contains: + return Flux.just(); + } + } + """) .doTest(); } diff --git a/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsIdentityOperationTest.java b/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsIdentityOperationTest.java index 324a8f784dd..5f126e46611 100644 --- a/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsIdentityOperationTest.java +++ b/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsIdentityOperationTest.java @@ -13,52 +13,54 @@ void matches() { CompilationTestHelper.newInstance(MatcherTestChecker.class, getClass()) .addSourceLines( "A.java", - "import java.util.function.BinaryOperator;", - "import java.util.function.DoubleUnaryOperator;", - "import java.util.function.Function;", - "import java.util.function.IntUnaryOperator;", - "import java.util.function.LongUnaryOperator;", - "import java.util.function.UnaryOperator;", - "", - "class A {", - " BinaryOperator negative1() {", - " return (a, b) -> a;", - " }", - "", - " UnaryOperator negative2() {", - " return a -> a + a;", - " }", - "", - " DoubleUnaryOperator positive1() {", - " // BUG: Diagnostic contains:", - " return DoubleUnaryOperator.identity();", - " }", - "", - " Function positive2() {", - " // BUG: Diagnostic contains:", - " return Function.identity();", - " }", - "", - " UnaryOperator positive3() {", - " // BUG: Diagnostic contains:", - " return UnaryOperator.identity();", - " }", - "", - " IntUnaryOperator positive4() {", - " // BUG: Diagnostic contains:", - " return IntUnaryOperator.identity();", - " }", - "", - " LongUnaryOperator positive5() {", - " // BUG: Diagnostic contains:", - " return LongUnaryOperator.identity();", - " }", - "", - " UnaryOperator positive6() {", - " // BUG: Diagnostic contains:", - " return a -> a;", - " }", - "}") + """ + import java.util.function.BinaryOperator; + import java.util.function.DoubleUnaryOperator; + import java.util.function.Function; + import java.util.function.IntUnaryOperator; + import java.util.function.LongUnaryOperator; + import java.util.function.UnaryOperator; + + class A { + BinaryOperator negative1() { + return (a, b) -> a; + } + + UnaryOperator negative2() { + return a -> a + a; + } + + DoubleUnaryOperator positive1() { + // BUG: Diagnostic contains: + return DoubleUnaryOperator.identity(); + } + + Function positive2() { + // BUG: Diagnostic contains: + return Function.identity(); + } + + UnaryOperator positive3() { + // BUG: Diagnostic contains: + return UnaryOperator.identity(); + } + + IntUnaryOperator positive4() { + // BUG: Diagnostic contains: + return IntUnaryOperator.identity(); + } + + LongUnaryOperator positive5() { + // BUG: Diagnostic contains: + return LongUnaryOperator.identity(); + } + + UnaryOperator positive6() { + // BUG: Diagnostic contains: + return a -> a; + } + } + """) .doTest(); } diff --git a/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsLambdaExpressionOrMethodReferenceTest.java b/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsLambdaExpressionOrMethodReferenceTest.java index 3280024cda1..5908216df13 100644 --- a/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsLambdaExpressionOrMethodReferenceTest.java +++ b/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsLambdaExpressionOrMethodReferenceTest.java @@ -13,45 +13,47 @@ void matches() { CompilationTestHelper.newInstance(MatcherTestChecker.class, getClass()) .addSourceLines( "A.java", - "import com.google.common.base.Predicates;", - "import java.util.function.Function;", - "import java.util.function.Predicate;", - "", - "class A {", - " boolean negative1() {", - " return true;", - " }", - "", - " String negative2() {", - " return new String(new byte[0]);", - " }", - "", - " Predicate negative3() {", - " return Predicates.alwaysTrue();", - " }", - "", - " Predicate positive1() {", - " // BUG: Diagnostic contains:", - " return str -> true;", - " }", - "", - " Predicate positive2() {", - " // BUG: Diagnostic contains:", - " return str -> {", - " return true;", - " };", - " }", - "", - " Predicate positive3() {", - " // BUG: Diagnostic contains:", - " return String::isEmpty;", - " }", - "", - " Function positive4() {", - " // BUG: Diagnostic contains:", - " return String::new;", - " }", - "}") + """ + import com.google.common.base.Predicates; + import java.util.function.Function; + import java.util.function.Predicate; + + class A { + boolean negative1() { + return true; + } + + String negative2() { + return new String(new byte[0]); + } + + Predicate negative3() { + return Predicates.alwaysTrue(); + } + + Predicate positive1() { + // BUG: Diagnostic contains: + return str -> true; + } + + Predicate positive2() { + // BUG: Diagnostic contains: + return str -> { + return true; + }; + } + + Predicate positive3() { + // BUG: Diagnostic contains: + return String::isEmpty; + } + + Function positive4() { + // BUG: Diagnostic contains: + return String::new; + } + } + """) .doTest(); } diff --git a/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsLikelyTrivialComputationTest.java b/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsLikelyTrivialComputationTest.java index a140e7248fc..93881db4485 100644 --- a/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsLikelyTrivialComputationTest.java +++ b/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsLikelyTrivialComputationTest.java @@ -14,116 +14,118 @@ void matches() { CompilationTestHelper.newInstance(MatcherTestChecker.class, getClass()) .addSourceLines( "A.java", - "import java.util.function.Predicate;", - "", - "class A {", - " String negative1() {", - " return String.valueOf(1);", - " }", - "", - " String negative2() {", - " return toString().toString();", - " }", - "", - " String negative3() {", - " return \"foo\" + toString();", - " }", - "", - " byte negative4() {", - " return \"foo\".getBytes()[0];", - " }", - "", - " int negative5() {", - " int[] arr = new int[0];", - " return arr[hashCode()];", - " }", - "", - " int negative6() {", - " return 1 * 2;", - " }", - "", - " Predicate negative7() {", - " return toString()::equals;", - " }", - "", - " String negative8() {", - " return (toString());", - " }", - "", - " Object negative9() {", - " return (Object) toString();", - " }", - "", - " int negative10() {", - " return -hashCode();", - " }", - "", - " String positive1() {", - " // BUG: Diagnostic contains:", - " return toString();", - " }", - "", - " String positive2() {", - " // BUG: Diagnostic contains:", - " return this.toString();", - " }", - "", - " int positive3() {", - " int[] arr = new int[0];", - " // BUG: Diagnostic contains:", - " return arr[0];", - " }", - "", - " String positive4() {", - " // BUG: Diagnostic contains:", - " return null;", - " }", - "", - " boolean positive5() {", - " // BUG: Diagnostic contains:", - " return false;", - " }", - "", - " int positive6() {", - " // BUG: Diagnostic contains:", - " return 0;", - " }", - "", - " String positive7() {", - " // BUG: Diagnostic contains:", - " return \"foo\" + \"bar\";", - " }", - "", - " Predicate positive8() {", - " // BUG: Diagnostic contains:", - " return v -> \"foo\".equals(v);", - " }", - "", - " A positive9() {", - " // BUG: Diagnostic contains:", - " return this;", - " }", - "", - " Predicate positive10() {", - " // BUG: Diagnostic contains:", - " return \"foo\"::equals;", - " }", - "", - " A positive11() {", - " // BUG: Diagnostic contains:", - " return (this);", - " }", - "", - " Object positive12() {", - " // BUG: Diagnostic contains:", - " return (Object) this;", - " }", - "", - " boolean positive13() {", - " // BUG: Diagnostic contains:", - " return !false;", - " }", - "}") + """ + import java.util.function.Predicate; + + class A { + String negative1() { + return String.valueOf(1); + } + + String negative2() { + return toString().toString(); + } + + String negative3() { + return "foo" + toString(); + } + + byte negative4() { + return "foo".getBytes()[0]; + } + + int negative5() { + int[] arr = new int[0]; + return arr[hashCode()]; + } + + int negative6() { + return 1 * 2; + } + + Predicate negative7() { + return toString()::equals; + } + + String negative8() { + return (toString()); + } + + Object negative9() { + return (Object) toString(); + } + + int negative10() { + return -hashCode(); + } + + String positive1() { + // BUG: Diagnostic contains: + return toString(); + } + + String positive2() { + // BUG: Diagnostic contains: + return this.toString(); + } + + int positive3() { + int[] arr = new int[0]; + // BUG: Diagnostic contains: + return arr[0]; + } + + String positive4() { + // BUG: Diagnostic contains: + return null; + } + + boolean positive5() { + // BUG: Diagnostic contains: + return false; + } + + int positive6() { + // BUG: Diagnostic contains: + return 0; + } + + String positive7() { + // BUG: Diagnostic contains: + return "foo" + "bar"; + } + + Predicate positive8() { + // BUG: Diagnostic contains: + return v -> "foo".equals(v); + } + + A positive9() { + // BUG: Diagnostic contains: + return this; + } + + Predicate positive10() { + // BUG: Diagnostic contains: + return "foo"::equals; + } + + A positive11() { + // BUG: Diagnostic contains: + return (this); + } + + Object positive12() { + // BUG: Diagnostic contains: + return (Object) this; + } + + boolean positive13() { + // BUG: Diagnostic contains: + return !false; + } + } + """) .doTest(); } diff --git a/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsRefasterAsVarargsTest.java b/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsRefasterAsVarargsTest.java index 5cc8c0b564b..4175a791e88 100644 --- a/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsRefasterAsVarargsTest.java +++ b/refaster-support/src/test/java/tech/picnic/errorprone/refaster/matchers/IsRefasterAsVarargsTest.java @@ -13,30 +13,32 @@ void matches() { CompilationTestHelper.newInstance(MatcherTestChecker.class, getClass()) .addSourceLines( "A.java", - "import com.google.errorprone.refaster.Refaster;", - "", - "class A {", - " int[] negative1() {", - " return new int[4];", - " }", - "", - " String[] negative2() {", - " return \"foo\".split(\"o\");", - " }", - "", - " String[] negative3() {", - " return asVarArgs(\"bar\");", - " }", - "", - " String[] positive1() {", - " // BUG: Diagnostic contains:", - " return Refaster.asVarargs(\"o\");", - " }", - "", - " private static String[] asVarArgs(String s) {", - " return s.split(\"a\");", - " }", - "}") + """ + import com.google.errorprone.refaster.Refaster; + + class A { + int[] negative1() { + return new int[4]; + } + + String[] negative2() { + return "foo".split("o"); + } + + String[] negative3() { + return asVarArgs("bar"); + } + + String[] positive1() { + // BUG: Diagnostic contains: + return Refaster.asVarargs("o"); + } + + private static String[] asVarArgs(String s) { + return s.split("a"); + } + } + """) .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(); }