mirror of
https://github.com/jlengrand/error-prone-support.git
synced 2026-03-10 08:11:25 +00:00
Introduce a CanonicalAnnotationSyntax check
While there, clean up some existing code.
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
package com.picnicinternational.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.common.base.Verify.verify;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.ProvidesFix;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.AnnotationTreeMatcher;
|
||||
import com.google.errorprone.fixes.Fix;
|
||||
import com.google.errorprone.fixes.SuggestedFix;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.sun.source.tree.AnnotationTree;
|
||||
import com.sun.source.tree.AssignmentTree;
|
||||
import com.sun.source.tree.ExpressionTree;
|
||||
import com.sun.source.tree.IdentifierTree;
|
||||
import com.sun.source.tree.Tree.Kind;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
// XXX: Drop redundant curly braces.
|
||||
// XXX: Also flag/drop trailing commas?
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
name = "CanonicalAnnotationSyntax",
|
||||
summary = "Omit redundant syntax from annotation declarations",
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.STYLE,
|
||||
providesFix = ProvidesFix.REQUIRES_HUMAN_ATTENTION
|
||||
)
|
||||
public final class CanonicalAnnotationSyntaxCheck extends BugChecker
|
||||
implements AnnotationTreeMatcher {
|
||||
private static final ImmutableSet<BiFunction<AnnotationTree, VisitorState, Optional<Fix>>>
|
||||
FIX_FACTORIES =
|
||||
ImmutableSet.of(
|
||||
CanonicalAnnotationSyntaxCheck::dropRedundantParentheses,
|
||||
CanonicalAnnotationSyntaxCheck::dropRedundantValueAttribute);
|
||||
|
||||
@Override
|
||||
public Description matchAnnotation(AnnotationTree tree, VisitorState state) {
|
||||
return FIX_FACTORIES
|
||||
.stream()
|
||||
.map(op -> op.apply(tree, state))
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.findFirst()
|
||||
.map(fix -> buildDescription(tree).addFix(fix).build())
|
||||
.orElse(Description.NO_MATCH);
|
||||
}
|
||||
|
||||
private static Optional<Fix> dropRedundantParentheses(AnnotationTree tree, VisitorState state) {
|
||||
if (!tree.getArguments().isEmpty()) {
|
||||
/* Parentheses are necessary. */
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String src = state.getSourceForNode(tree);
|
||||
if (src == null) {
|
||||
/* Without the source code there's not much we can do. */
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
int parenIndex = src.indexOf('(');
|
||||
if (parenIndex < 0) {
|
||||
/* There are no redundant parentheses. */
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(SuggestedFix.replace(tree, src.substring(0, parenIndex)));
|
||||
}
|
||||
|
||||
private static Optional<Fix> dropRedundantValueAttribute(
|
||||
AnnotationTree tree, VisitorState state) {
|
||||
List<? extends ExpressionTree> args = tree.getArguments();
|
||||
if (args.size() != 1) {
|
||||
/* The `value` attribute, if specified, cannot be dropped. */
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
ExpressionTree arg = args.get(0);
|
||||
if (arg.getKind() != Kind.ASSIGNMENT) {
|
||||
verify(
|
||||
arg.getKind() == Kind.IDENTIFIER,
|
||||
"Unexpected type of expression: %s" + arg.getKind());
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
ExpressionTree variable = ((AssignmentTree) arg).getVariable();
|
||||
if (variable.getKind() != Kind.IDENTIFIER
|
||||
|| !((IdentifierTree) variable).getName().contentEquals("value")
|
||||
|| state.getSourceForNode(variable) == null) {
|
||||
/* This is not an explicit assignment to the `value` attribute. */
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/* Replace the assignment with just its value. */
|
||||
return Optional.of(
|
||||
SuggestedFix.replace(arg, ((AssignmentTree) arg).getExpression().toString()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.picnicinternational.errorprone.bugpatterns;
|
||||
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.AnnotationTreeMatcher;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.sun.source.tree.AnnotationTree;
|
||||
|
||||
// XXX: Add documentation. Explain that sorting reduces changes of conflicts and simplifies their resolution when they do happen.
|
||||
// XXX: Add support for inclusions and exclusions.
|
||||
// XXX: Disable until implemented.
|
||||
//@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
name = "LexicographicalAnnotationAttributeListing",
|
||||
summary = "Where possible, sort annotation array attributes lexicographically",
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.STYLE
|
||||
)
|
||||
public final class LexicographicalAnnotationAttributeListingCheck extends BugChecker
|
||||
implements AnnotationTreeMatcher {
|
||||
@Override
|
||||
public Description matchAnnotation(AnnotationTree tree, VisitorState state) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -20,182 +20,6 @@ public final class BoxingComparisonCheckTest {
|
||||
// - During actual compilation only the first replacement is applied.
|
||||
// XXX: Can we perhaps work-around this by describing the fixes in reverse order?
|
||||
|
||||
@Test
|
||||
public void testReplacementWithPrimitiveVariants() throws IOException {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/Test.java",
|
||||
"import java.util.Comparator;",
|
||||
"class Test {",
|
||||
" Comparator<Object> bCmp = Comparator.comparing(o -> (byte) 0);",
|
||||
" Comparator<Object> cCmp = Comparator.comparing(o -> (char) 0);",
|
||||
" Comparator<Object> sCmp = Comparator.comparing(o -> (short) 0);",
|
||||
" Comparator<Object> iCmp = Comparator.comparing(o -> 0);",
|
||||
" Comparator<Object> lCmp = Comparator.comparing(o -> 0L);",
|
||||
" Comparator<Object> fCmp = Comparator.comparing(o -> 0.0f);",
|
||||
" Comparator<Object> dCmp = Comparator.comparing(o -> 0.0);",
|
||||
"",
|
||||
" {",
|
||||
" bCmp.thenComparing(o -> (byte) 0);",
|
||||
" cCmp.thenComparing(o -> (char) 0);",
|
||||
" sCmp.thenComparing(o -> (short) 0);",
|
||||
" iCmp.thenComparing(o -> 0);",
|
||||
" lCmp.thenComparing(o -> 0L);",
|
||||
" fCmp.thenComparing(o -> 0.0f);",
|
||||
" dCmp.thenComparing(o -> 0.0);",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/Test.java",
|
||||
"import java.util.Comparator;",
|
||||
"class Test {",
|
||||
" Comparator<Object> bCmp = Comparator.comparingInt(o -> (byte) 0);",
|
||||
" Comparator<Object> cCmp = Comparator.comparingInt(o -> (char) 0);",
|
||||
" Comparator<Object> sCmp = Comparator.comparingInt(o -> (short) 0);",
|
||||
" Comparator<Object> iCmp = Comparator.comparingInt(o -> 0);",
|
||||
" Comparator<Object> lCmp = Comparator.comparingLong(o -> 0L);",
|
||||
" Comparator<Object> fCmp = Comparator.comparingDouble(o -> 0.0f);",
|
||||
" Comparator<Object> dCmp = Comparator.comparingDouble(o -> 0.0);",
|
||||
"",
|
||||
" {",
|
||||
" bCmp.thenComparingInt(o -> (byte) 0);",
|
||||
" cCmp.thenComparingInt(o -> (char) 0);",
|
||||
" sCmp.thenComparingInt(o -> (short) 0);",
|
||||
" iCmp.thenComparingInt(o -> 0);",
|
||||
" lCmp.thenComparingLong(o -> 0L);",
|
||||
" fCmp.thenComparingDouble(o -> 0.0f);",
|
||||
" dCmp.thenComparingDouble(o -> 0.0);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacementWithBoxedVariants() throws IOException {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/Test.java",
|
||||
"import java.util.Comparator;",
|
||||
"class Test {",
|
||||
" Comparator<Object> bCmp = Comparator.comparingInt(o -> Byte.valueOf((byte) 0));",
|
||||
" Comparator<Object> cCmp = Comparator.comparingInt(o -> Character.valueOf((char) 0));",
|
||||
" Comparator<Object> sCmp = Comparator.comparingInt(o -> Short.valueOf((short) 0));",
|
||||
" Comparator<Object> iCmp = Comparator.comparingInt(o -> Integer.valueOf(0));",
|
||||
" Comparator<Object> lCmp = Comparator.comparingLong(o -> Long.valueOf(0));",
|
||||
" Comparator<Object> fCmp = Comparator.comparingDouble(o -> Float.valueOf(0));",
|
||||
" Comparator<Object> dCmp = Comparator.comparingDouble(o -> Double.valueOf(0));",
|
||||
"",
|
||||
" {",
|
||||
" 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(
|
||||
"out/Test.java",
|
||||
"import java.util.Comparator;",
|
||||
"class Test {",
|
||||
" Comparator<Object> bCmp = Comparator.comparing(o -> Byte.valueOf((byte) 0));",
|
||||
" Comparator<Object> cCmp = Comparator.comparing(o -> Character.valueOf((char) 0));",
|
||||
" Comparator<Object> sCmp = Comparator.comparing(o -> Short.valueOf((short) 0));",
|
||||
" Comparator<Object> iCmp = Comparator.comparing(o -> Integer.valueOf(0));",
|
||||
" Comparator<Object> lCmp = Comparator.comparing(o -> Long.valueOf(0));",
|
||||
" Comparator<Object> fCmp = Comparator.comparing(o -> Float.valueOf(0));",
|
||||
" Comparator<Object> dCmp = Comparator.comparing(o -> Double.valueOf(0));",
|
||||
"",
|
||||
" {",
|
||||
" 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();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacementWithPrimitiveVariantsUsingStaticImports() throws IOException {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/Test.java",
|
||||
"import static java.util.Comparator.comparing;",
|
||||
"",
|
||||
"import java.util.Comparator;",
|
||||
"class Test {",
|
||||
" Comparator<Object> bCmp = comparing(o -> (byte) 0);",
|
||||
" Comparator<Object> cCmp = comparing(o -> (char) 0);",
|
||||
" Comparator<Object> sCmp = comparing(o -> (short) 0);",
|
||||
" Comparator<Object> iCmp = comparing(o -> 0);",
|
||||
" Comparator<Object> lCmp = comparing(o -> 0L);",
|
||||
" Comparator<Object> fCmp = comparing(o -> 0.0f);",
|
||||
" Comparator<Object> dCmp = comparing(o -> 0.0);",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/Test.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;",
|
||||
"class Test {",
|
||||
" Comparator<Object> bCmp = comparingInt(o -> (byte) 0);",
|
||||
" Comparator<Object> cCmp = comparingInt(o -> (char) 0);",
|
||||
" Comparator<Object> sCmp = comparingInt(o -> (short) 0);",
|
||||
" Comparator<Object> iCmp = comparingInt(o -> 0);",
|
||||
" Comparator<Object> lCmp = comparingLong(o -> 0L);",
|
||||
" Comparator<Object> fCmp = comparingDouble(o -> 0.0f);",
|
||||
" Comparator<Object> dCmp = comparingDouble(o -> 0.0);",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacementWithBoxedVariantsUsingStaticImports() throws IOException {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/Test.java",
|
||||
"import static java.util.Comparator.comparingDouble;",
|
||||
"import static java.util.Comparator.comparingInt;",
|
||||
"import static java.util.Comparator.comparingLong;",
|
||||
"",
|
||||
"import java.util.Comparator;",
|
||||
"class Test {",
|
||||
" Comparator<Object> bCmp = comparingInt(o -> Byte.valueOf((byte) 0));",
|
||||
" Comparator<Object> cCmp = comparingInt(o -> Character.valueOf((char) 0));",
|
||||
" Comparator<Object> sCmp = comparingInt(o -> Short.valueOf((short) 0));",
|
||||
" Comparator<Object> iCmp = comparingInt(o -> Integer.valueOf(0));",
|
||||
" Comparator<Object> lCmp = comparingLong(o -> Long.valueOf(0));",
|
||||
" Comparator<Object> fCmp = comparingDouble(o -> Float.valueOf(0));",
|
||||
" Comparator<Object> dCmp = comparingDouble(o -> Double.valueOf(0));",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/Test.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;",
|
||||
"class Test {",
|
||||
" Comparator<Object> bCmp = comparing(o -> Byte.valueOf((byte) 0));",
|
||||
" Comparator<Object> cCmp = comparing(o -> Character.valueOf((char) 0));",
|
||||
" Comparator<Object> sCmp = comparing(o -> Short.valueOf((short) 0));",
|
||||
" Comparator<Object> iCmp = comparing(o -> Integer.valueOf(0));",
|
||||
" Comparator<Object> lCmp = comparing(o -> Long.valueOf(0));",
|
||||
" Comparator<Object> fCmp = comparing(o -> Float.valueOf(0));",
|
||||
" Comparator<Object> dCmp = comparing(o -> Double.valueOf(0));",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
// The logic for `char` and `short` is exactly analogous to the `byte` case.
|
||||
@Test
|
||||
public void testByteComparison() {
|
||||
@@ -204,6 +28,7 @@ public final class BoxingComparisonCheckTest {
|
||||
"A.java",
|
||||
"import java.util.Comparator;",
|
||||
"import java.util.function.Function;",
|
||||
"",
|
||||
"class A {",
|
||||
" {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
@@ -293,6 +118,7 @@ public final class BoxingComparisonCheckTest {
|
||||
"import java.util.Comparator;",
|
||||
"import java.util.function.Function;",
|
||||
"import java.util.function.ToIntFunction;",
|
||||
"",
|
||||
"class A {",
|
||||
" {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
@@ -385,6 +211,7 @@ public final class BoxingComparisonCheckTest {
|
||||
"import java.util.Comparator;",
|
||||
"import java.util.function.Function;",
|
||||
"import java.util.function.ToLongFunction;",
|
||||
"",
|
||||
"class A {",
|
||||
" {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
@@ -460,6 +287,7 @@ public final class BoxingComparisonCheckTest {
|
||||
"A.java",
|
||||
"import java.util.Comparator;",
|
||||
"import java.util.function.Function;",
|
||||
"",
|
||||
"class A {",
|
||||
" {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
@@ -517,6 +345,7 @@ public final class BoxingComparisonCheckTest {
|
||||
"import java.util.Comparator;",
|
||||
"import java.util.function.Function;",
|
||||
"import java.util.function.ToDoubleFunction;",
|
||||
"",
|
||||
"class A {",
|
||||
" {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
@@ -576,6 +405,7 @@ public final class BoxingComparisonCheckTest {
|
||||
"A.java",
|
||||
"import java.util.Comparator;",
|
||||
"import java.util.function.Function;",
|
||||
"",
|
||||
"class A {",
|
||||
" {",
|
||||
" Comparator.comparing(String::valueOf);",
|
||||
@@ -598,4 +428,188 @@ public final class BoxingComparisonCheckTest {
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacementWithPrimitiveVariants() throws IOException {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
"import java.util.Comparator;",
|
||||
"",
|
||||
"class A {",
|
||||
" Comparator<Object> bCmp = Comparator.comparing(o -> (byte) 0);",
|
||||
" Comparator<Object> cCmp = Comparator.comparing(o -> (char) 0);",
|
||||
" Comparator<Object> sCmp = Comparator.comparing(o -> (short) 0);",
|
||||
" Comparator<Object> iCmp = Comparator.comparing(o -> 0);",
|
||||
" Comparator<Object> lCmp = Comparator.comparing(o -> 0L);",
|
||||
" Comparator<Object> fCmp = Comparator.comparing(o -> 0.0f);",
|
||||
" Comparator<Object> dCmp = Comparator.comparing(o -> 0.0);",
|
||||
"",
|
||||
" {",
|
||||
" bCmp.thenComparing(o -> (byte) 0);",
|
||||
" cCmp.thenComparing(o -> (char) 0);",
|
||||
" sCmp.thenComparing(o -> (short) 0);",
|
||||
" iCmp.thenComparing(o -> 0);",
|
||||
" lCmp.thenComparing(o -> 0L);",
|
||||
" fCmp.thenComparing(o -> 0.0f);",
|
||||
" dCmp.thenComparing(o -> 0.0);",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/A.java",
|
||||
"import java.util.Comparator;",
|
||||
"",
|
||||
"class A {",
|
||||
" Comparator<Object> bCmp = Comparator.comparingInt(o -> (byte) 0);",
|
||||
" Comparator<Object> cCmp = Comparator.comparingInt(o -> (char) 0);",
|
||||
" Comparator<Object> sCmp = Comparator.comparingInt(o -> (short) 0);",
|
||||
" Comparator<Object> iCmp = Comparator.comparingInt(o -> 0);",
|
||||
" Comparator<Object> lCmp = Comparator.comparingLong(o -> 0L);",
|
||||
" Comparator<Object> fCmp = Comparator.comparingDouble(o -> 0.0f);",
|
||||
" Comparator<Object> dCmp = Comparator.comparingDouble(o -> 0.0);",
|
||||
"",
|
||||
" {",
|
||||
" bCmp.thenComparingInt(o -> (byte) 0);",
|
||||
" cCmp.thenComparingInt(o -> (char) 0);",
|
||||
" sCmp.thenComparingInt(o -> (short) 0);",
|
||||
" iCmp.thenComparingInt(o -> 0);",
|
||||
" lCmp.thenComparingLong(o -> 0L);",
|
||||
" fCmp.thenComparingDouble(o -> 0.0f);",
|
||||
" dCmp.thenComparingDouble(o -> 0.0);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacementWithBoxedVariants() throws IOException {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
"import java.util.Comparator;",
|
||||
"",
|
||||
"class A {",
|
||||
" Comparator<Object> bCmp = Comparator.comparingInt(o -> Byte.valueOf((byte) 0));",
|
||||
" Comparator<Object> cCmp = Comparator.comparingInt(o -> Character.valueOf((char) 0));",
|
||||
" Comparator<Object> sCmp = Comparator.comparingInt(o -> Short.valueOf((short) 0));",
|
||||
" Comparator<Object> iCmp = Comparator.comparingInt(o -> Integer.valueOf(0));",
|
||||
" Comparator<Object> lCmp = Comparator.comparingLong(o -> Long.valueOf(0));",
|
||||
" Comparator<Object> fCmp = Comparator.comparingDouble(o -> Float.valueOf(0));",
|
||||
" Comparator<Object> dCmp = Comparator.comparingDouble(o -> Double.valueOf(0));",
|
||||
"",
|
||||
" {",
|
||||
" 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(
|
||||
"out/A.java",
|
||||
"import java.util.Comparator;",
|
||||
"",
|
||||
"class A {",
|
||||
" Comparator<Object> bCmp = Comparator.comparing(o -> Byte.valueOf((byte) 0));",
|
||||
" Comparator<Object> cCmp = Comparator.comparing(o -> Character.valueOf((char) 0));",
|
||||
" Comparator<Object> sCmp = Comparator.comparing(o -> Short.valueOf((short) 0));",
|
||||
" Comparator<Object> iCmp = Comparator.comparing(o -> Integer.valueOf(0));",
|
||||
" Comparator<Object> lCmp = Comparator.comparing(o -> Long.valueOf(0));",
|
||||
" Comparator<Object> fCmp = Comparator.comparing(o -> Float.valueOf(0));",
|
||||
" Comparator<Object> dCmp = Comparator.comparing(o -> Double.valueOf(0));",
|
||||
"",
|
||||
" {",
|
||||
" 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();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacementWithPrimitiveVariantsUsingStaticImports() throws IOException {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
"import static java.util.Comparator.comparing;",
|
||||
"",
|
||||
"import java.util.Comparator;",
|
||||
"",
|
||||
"class A {",
|
||||
" Comparator<Object> bCmp = comparing(o -> (byte) 0);",
|
||||
" Comparator<Object> cCmp = comparing(o -> (char) 0);",
|
||||
" Comparator<Object> sCmp = comparing(o -> (short) 0);",
|
||||
" Comparator<Object> iCmp = comparing(o -> 0);",
|
||||
" Comparator<Object> lCmp = comparing(o -> 0L);",
|
||||
" Comparator<Object> fCmp = comparing(o -> 0.0f);",
|
||||
" Comparator<Object> dCmp = comparing(o -> 0.0);",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/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;",
|
||||
"",
|
||||
"class A {",
|
||||
" Comparator<Object> bCmp = comparingInt(o -> (byte) 0);",
|
||||
" Comparator<Object> cCmp = comparingInt(o -> (char) 0);",
|
||||
" Comparator<Object> sCmp = comparingInt(o -> (short) 0);",
|
||||
" Comparator<Object> iCmp = comparingInt(o -> 0);",
|
||||
" Comparator<Object> lCmp = comparingLong(o -> 0L);",
|
||||
" Comparator<Object> fCmp = comparingDouble(o -> 0.0f);",
|
||||
" Comparator<Object> dCmp = comparingDouble(o -> 0.0);",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacementWithBoxedVariantsUsingStaticImports() throws IOException {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
"import static java.util.Comparator.comparingDouble;",
|
||||
"import static java.util.Comparator.comparingInt;",
|
||||
"import static java.util.Comparator.comparingLong;",
|
||||
"",
|
||||
"import java.util.Comparator;",
|
||||
"",
|
||||
"class A {",
|
||||
" Comparator<Object> bCmp = comparingInt(o -> Byte.valueOf((byte) 0));",
|
||||
" Comparator<Object> cCmp = comparingInt(o -> Character.valueOf((char) 0));",
|
||||
" Comparator<Object> sCmp = comparingInt(o -> Short.valueOf((short) 0));",
|
||||
" Comparator<Object> iCmp = comparingInt(o -> Integer.valueOf(0));",
|
||||
" Comparator<Object> lCmp = comparingLong(o -> Long.valueOf(0));",
|
||||
" Comparator<Object> fCmp = comparingDouble(o -> Float.valueOf(0));",
|
||||
" Comparator<Object> dCmp = comparingDouble(o -> Double.valueOf(0));",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/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;",
|
||||
"",
|
||||
"class A {",
|
||||
" Comparator<Object> bCmp = comparing(o -> Byte.valueOf((byte) 0));",
|
||||
" Comparator<Object> cCmp = comparing(o -> Character.valueOf((char) 0));",
|
||||
" Comparator<Object> sCmp = comparing(o -> Short.valueOf((short) 0));",
|
||||
" Comparator<Object> iCmp = comparing(o -> Integer.valueOf(0));",
|
||||
" Comparator<Object> lCmp = comparing(o -> Long.valueOf(0));",
|
||||
" Comparator<Object> fCmp = comparing(o -> Float.valueOf(0));",
|
||||
" Comparator<Object> dCmp = comparing(o -> Double.valueOf(0));",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
package com.picnicinternational.errorprone.bugpatterns;
|
||||
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import java.io.IOException;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public final class CanonicalAnnotationSyntaxCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(CanonicalAnnotationSyntaxCheck.class, getClass());
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(
|
||||
new CanonicalAnnotationSyntaxCheck(), getClass());
|
||||
|
||||
@Test
|
||||
public void testIdentification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"pkg/A.java",
|
||||
"package pkg;",
|
||||
"",
|
||||
"import pkg.A.Foo;",
|
||||
"",
|
||||
"@Foo",
|
||||
"interface A {",
|
||||
" @interface Foo {",
|
||||
" int value() default 0;",
|
||||
" int value2() default 0;",
|
||||
" }",
|
||||
"",
|
||||
" @pkg.A.Foo Object minimal1();",
|
||||
" @A.Foo Object minimal2();",
|
||||
" @Foo Object minimal3();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @pkg.A.Foo() Object functional1();",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @A.Foo() Object functional2();",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo() Object functional3();",
|
||||
"",
|
||||
" @pkg.A.Foo(1) Object simple1();",
|
||||
" @A.Foo(1) Object simple2();",
|
||||
" @Foo(1) Object simple3();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @pkg.A.Foo(value = 1) Object verbose1();",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @A.Foo(value = 1) Object verbose2();",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo(value = 1) Object verbose3();",
|
||||
"",
|
||||
" @pkg.A.Foo(value2 = 2) Object custom1();",
|
||||
" @A.Foo(value2 = 2) Object custom2();",
|
||||
" @Foo(value2 = 2) Object custom3();",
|
||||
"",
|
||||
" @pkg.A.Foo(value = 1, value2 = 2) Object extended1();",
|
||||
" @A.Foo(value = 1, value2 = 2) Object extended2();",
|
||||
" @Foo(value = 1, value2 = 2) Object extended3();",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacement() throws IOException {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/pkg/A.java",
|
||||
"package pkg;",
|
||||
"",
|
||||
"import pkg.A.Foo;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @interface Foo {",
|
||||
" int value() default 0;",
|
||||
" int value2() default 0;",
|
||||
" }",
|
||||
"",
|
||||
" @pkg.A.Foo() Object functional1();",
|
||||
" @A.Foo() Object functional2();",
|
||||
" @Foo() Object functional3();",
|
||||
"",
|
||||
" @pkg.A.Foo(value = 1) Object verbose1();",
|
||||
" @A.Foo(value = 1) Object verbose2();",
|
||||
" @Foo(value = 1) Object verbose3();",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/pkg/A.java",
|
||||
"package pkg;",
|
||||
"",
|
||||
"import pkg.A.Foo;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @interface Foo {",
|
||||
" int value() default 0;",
|
||||
" int value2() default 0;",
|
||||
" }",
|
||||
"",
|
||||
" @pkg.A.Foo Object functional1();",
|
||||
" @A.Foo Object functional2();",
|
||||
" @Foo Object functional3();",
|
||||
"",
|
||||
" @pkg.A.Foo(1) Object verbose1();",
|
||||
" @A.Foo(1) Object verbose2();",
|
||||
" @Foo(1) Object verbose3();",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
@@ -7,12 +7,12 @@ import org.junit.runners.JUnit4;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public final class EmptyMethodCheckTest {
|
||||
private final CompilationTestHelper testHelper =
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(EmptyMethodCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
public void testNegative() {
|
||||
testHelper
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"class A {",
|
||||
@@ -33,7 +33,7 @@ public final class EmptyMethodCheckTest {
|
||||
|
||||
@Test
|
||||
public void testPositive() {
|
||||
testHelper
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"class A {",
|
||||
|
||||
Reference in New Issue
Block a user