mirror of
https://github.com/jlengrand/error-prone-support.git
synced 2026-03-10 08:11:25 +00:00
remove old check
This commit is contained in:
committed by
Rick Ossendrijver
parent
1a98a4d599
commit
35ada6b449
@@ -1,213 +0,0 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.ERROR;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.REFACTORING;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher;
|
||||
import com.google.errorprone.fixes.Replacement;
|
||||
import com.google.errorprone.fixes.SuggestedFix;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.google.errorprone.util.ASTHelpers;
|
||||
import com.sun.source.tree.AnnotationTree;
|
||||
import com.sun.source.tree.AssignmentTree;
|
||||
import com.sun.source.tree.ClassTree;
|
||||
import com.sun.source.tree.CompilationUnitTree;
|
||||
import com.sun.source.tree.ExpressionTree;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
import com.sun.source.tree.Tree;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import tech.picnic.errorprone.bugpatterns.util.AnnotationAttributeMatcher;
|
||||
import tech.picnic.errorprone.bugpatterns.util.SourceCode;
|
||||
|
||||
/**
|
||||
* A {@link BugChecker} that replaces a predefined list of annotation attributes with its own
|
||||
* separate annotation.
|
||||
*/
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
summary = "Replace annotation attributes with an annotation",
|
||||
linkType = NONE,
|
||||
tags = REFACTORING,
|
||||
severity = ERROR)
|
||||
public final class AnnotationAttributeReplacement extends BugChecker implements MethodTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final ImmutableMap<AnnotationAttributeMatcher, AnnotationAttributeReplacer>
|
||||
ANNOTATION_ATTRIBUTE_REPLACEMENT =
|
||||
ImmutableMap.<AnnotationAttributeMatcher, AnnotationAttributeReplacer>builder()
|
||||
.put(
|
||||
singleArgumentMatcher("org.testng.annotations.Test#singleThreaded"),
|
||||
(annotation, argument, state) ->
|
||||
Optional.of(
|
||||
SuggestedFix.builder()
|
||||
.merge(removeAnnotationArgument(annotation, argument, state))
|
||||
.merge(
|
||||
SuggestedFix.prefixWith(
|
||||
annotation,
|
||||
"// XXX: Removed argument `singleThreaded = true`, as this cannot be migrated to JUnit!\n"))
|
||||
.build()))
|
||||
.put(
|
||||
singleArgumentMatcher("org.testng.annotations.Test#priority"),
|
||||
(annotation, argument, state) -> {
|
||||
ClassTree classTree = state.findEnclosing(ClassTree.class);
|
||||
if (classTree == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
if (argument.getKind() != Tree.Kind.ASSIGNMENT) {
|
||||
return Optional.empty();
|
||||
}
|
||||
AssignmentTree assignmentTree = (AssignmentTree) argument;
|
||||
|
||||
return Optional.of(
|
||||
SuggestedFix.builder()
|
||||
.merge(removeAnnotationArgument(annotation, argument, state))
|
||||
.merge(
|
||||
SuggestedFix.postfixWith(
|
||||
annotation,
|
||||
String.format(
|
||||
"\n@org.junit.jupiter.api.Order(%s)",
|
||||
SourceCode.treeToString(
|
||||
assignmentTree.getExpression(), state))))
|
||||
.merge(
|
||||
SuggestedFix.prefixWith(
|
||||
classTree,
|
||||
"@TestMethodOrder(MethodOrderer.OrderAnnotation.class)\n"))
|
||||
.addImport("org.junit.jupiter.api.TestMethodOrder")
|
||||
.addImport("org.junit.jupiter.api.MethodOrderer")
|
||||
.build());
|
||||
})
|
||||
.put(
|
||||
singleArgumentMatcher("org.testng.annotations.Test#description"),
|
||||
(annotation, argument, state) ->
|
||||
Optional.of(argument)
|
||||
.filter(AssignmentTree.class::isInstance)
|
||||
.map(AssignmentTree.class::cast)
|
||||
.map(
|
||||
assignmentTree ->
|
||||
SuggestedFix.builder()
|
||||
.merge(removeAnnotationArgument(annotation, argument, state))
|
||||
.merge(
|
||||
SuggestedFix.postfixWith(
|
||||
annotation,
|
||||
String.format(
|
||||
"\n@org.junit.jupiter.api.DisplayName(%s)",
|
||||
SourceCode.treeToString(
|
||||
assignmentTree.getExpression(), state))))
|
||||
.build()))
|
||||
.put(
|
||||
singleArgumentMatcher("org.testng.annotations.Test#groups"),
|
||||
(annotation, argument, state) ->
|
||||
Optional.of(argument)
|
||||
.filter(AssignmentTree.class::isInstance)
|
||||
.map(AssignmentTree.class::cast)
|
||||
.map(
|
||||
assignmentTree ->
|
||||
SuggestedFix.builder()
|
||||
.merge(removeAnnotationArgument(annotation, argument, state))
|
||||
.merge(
|
||||
SuggestedFix.postfixWith(
|
||||
annotation,
|
||||
String.format(
|
||||
"\n@org.junit.jupiter.api.Tag(%s)",
|
||||
SourceCode.treeToString(
|
||||
assignmentTree.getExpression(), state))))
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
@Override
|
||||
public Description matchMethod(MethodTree tree, VisitorState state) {
|
||||
ImmutableList<AnnotationTree> annotations =
|
||||
ASTHelpers.getAnnotations(tree).stream().collect(toImmutableList());
|
||||
|
||||
SuggestedFix.Builder builder = SuggestedFix.builder();
|
||||
annotations.forEach(
|
||||
annotation -> {
|
||||
ANNOTATION_ATTRIBUTE_REPLACEMENT.forEach(
|
||||
(matcher, fixBuilder) ->
|
||||
matcher
|
||||
.extractMatchingArguments(annotation)
|
||||
.forEach(
|
||||
argument ->
|
||||
fixBuilder
|
||||
.buildFix(annotation, argument, state)
|
||||
.ifPresent(builder::merge)));
|
||||
|
||||
tryRemoveTrailingParenthesis(annotation, builder.build(), state)
|
||||
.ifPresent(builder::merge);
|
||||
});
|
||||
|
||||
return builder.isEmpty() ? Description.NO_MATCH : describeMatch(tree, builder.build());
|
||||
}
|
||||
|
||||
private static Optional<SuggestedFix> tryRemoveTrailingParenthesis(
|
||||
AnnotationTree annotation, SuggestedFix fix, VisitorState state) {
|
||||
JCTree.JCCompilationUnit compileUnit =
|
||||
((JCTree.JCCompilationUnit) state.findEnclosing(CompilationUnitTree.class));
|
||||
if (compileUnit == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
Set<Replacement> replacements = fix.getReplacements(compileUnit.endPositions);
|
||||
String annotationSource = SourceCode.treeToString(annotation, state).replace(", ", ",");
|
||||
String annotationArguments =
|
||||
annotationSource.substring(
|
||||
annotationSource.indexOf("(") + 1, annotationSource.length() - 1);
|
||||
int argumentReplacementLength = replacements.stream().mapToInt(Replacement::length).sum();
|
||||
if (argumentReplacementLength != annotationArguments.length()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return replacements.stream()
|
||||
.filter(replacement -> replacement.length() != 0)
|
||||
.map(Replacement::startPosition)
|
||||
.reduce(Integer::min)
|
||||
.flatMap(
|
||||
min ->
|
||||
replacements.stream()
|
||||
.filter(replacement -> replacement.length() != 0)
|
||||
.map(Replacement::endPosition)
|
||||
.reduce(Integer::max)
|
||||
.map(
|
||||
max ->
|
||||
SuggestedFix.builder()
|
||||
.merge(SuggestedFix.replace(min - 1, min, ""))
|
||||
.merge(SuggestedFix.replace(max, max + 1, ""))
|
||||
.build()));
|
||||
}
|
||||
|
||||
private static SuggestedFix removeAnnotationArgument(
|
||||
AnnotationTree annotation, ExpressionTree argument, VisitorState state) {
|
||||
String annotationSource = SourceCode.treeToString(annotation, state);
|
||||
String argumentSource = SourceCode.treeToString(argument, state);
|
||||
int argumentSourceIndex = annotationSource.indexOf(argumentSource);
|
||||
boolean endsWithComma =
|
||||
annotationSource
|
||||
.substring(
|
||||
argumentSourceIndex + argumentSource.length(),
|
||||
argumentSourceIndex + argumentSource.length() + 1)
|
||||
.equals(",");
|
||||
return SuggestedFix.builder().replace(argument, "", 0, endsWithComma ? 1 : 0).build();
|
||||
}
|
||||
|
||||
private static AnnotationAttributeMatcher singleArgumentMatcher(String fullyQualifiedArgument) {
|
||||
return AnnotationAttributeMatcher.create(
|
||||
Optional.of(ImmutableList.of(fullyQualifiedArgument)), ImmutableList.of());
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface AnnotationAttributeReplacer {
|
||||
Optional<SuggestedFix> buildFix(
|
||||
AnnotationTree annotation, ExpressionTree argument, VisitorState state);
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode.TEXT_MATCH;
|
||||
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
final class AnnotationAttributeReplacementTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(AnnotationAttributeReplacement.class, getClass());
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(AnnotationAttributeReplacement.class, getClass());
|
||||
|
||||
@Test
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import org.testng.annotations.Test;",
|
||||
"",
|
||||
"class A {",
|
||||
" @Test(priority = 10)",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" public void foo() {}",
|
||||
"",
|
||||
" @Test(description = \"unit\")",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" public void bar() {}",
|
||||
"",
|
||||
" @Test(dataProvider = \"unit\")",
|
||||
" public void baz() {}",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacement() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"import org.testng.annotations.Test;",
|
||||
"",
|
||||
"class A {",
|
||||
" @Test(priority = 1, groups = \"unit\", description = \"test\")",
|
||||
" public void foo() {}",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"import org.junit.jupiter.api.MethodOrderer;",
|
||||
"import org.junit.jupiter.api.TestMethodOrder;",
|
||||
"import org.testng.annotations.Test;",
|
||||
"",
|
||||
"@TestMethodOrder(MethodOrderer.OrderAnnotation.class)",
|
||||
"class A {",
|
||||
" @Test",
|
||||
" @org.junit.jupiter.api.Order(1)",
|
||||
" @org.junit.jupiter.api.DisplayName(\"test\")",
|
||||
" @org.junit.jupiter.api.Tag(\"unit\")",
|
||||
" public void foo() {}",
|
||||
"}")
|
||||
.doTest(TEXT_MATCH);
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacementUpdateArgumentListAfterSingleArgument() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"import org.testng.annotations.Test;",
|
||||
"",
|
||||
"class A {",
|
||||
" @Test(priority = 2, invocationTimeOut = 10L)",
|
||||
" public void foo() {}",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"import org.junit.jupiter.api.MethodOrderer;",
|
||||
"import org.junit.jupiter.api.TestMethodOrder;",
|
||||
"import org.testng.annotations.Test;",
|
||||
"",
|
||||
"@TestMethodOrder(MethodOrderer.OrderAnnotation.class)",
|
||||
"class A {",
|
||||
" @Test(invocationTimeOut = 10L)",
|
||||
" @org.junit.jupiter.api.Order(2)",
|
||||
" public void foo() {}",
|
||||
"}")
|
||||
.doTest(TEXT_MATCH);
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacementSingleThreaded() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"import org.testng.annotations.Test;",
|
||||
"",
|
||||
"class A {",
|
||||
" @Test(singleThreaded = true)",
|
||||
" public void foo() {}",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"import org.testng.annotations.Test;",
|
||||
"",
|
||||
"class A {",
|
||||
" // XXX: Removed argument `singleThreaded = true`, as this cannot be migrated to JUnit!",
|
||||
" @Test",
|
||||
" public void foo() {}",
|
||||
"}")
|
||||
.doTest(TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user