Introduce a CanonicalAnnotationSyntax check

While there, clean up some existing code.
This commit is contained in:
Stephan Schroevers
2017-10-22 15:25:40 +02:00
parent 1f8fe5ff94
commit 66ebebbe35
5 changed files with 438 additions and 179 deletions

View File

@@ -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()));
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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 {",