This commit is contained in:
Stephan Schroevers
2023-09-16 12:53:16 +02:00
parent 77501067b5
commit 49b5d2f51f
4 changed files with 70 additions and 12 deletions

View File

@@ -51,10 +51,10 @@ public final class CanonicalAnnotationSyntax extends BugChecker implements Annot
@Override
public Description matchAnnotation(AnnotationTree tree, VisitorState state) {
if (!isSourceAccurateCodeAvailable(tree, state)) {
/* Without the source code there's not much we can do. */
return Description.NO_MATCH;
}
// if (!isSourceAccurateCodeAvailable(tree, state)) {
// /* Without the source code there's not much we can do. */
// return Description.NO_MATCH;
// }
return FIX_FACTORIES.stream()
.map(op -> op.apply(tree, state))
@@ -65,11 +65,11 @@ public final class CanonicalAnnotationSyntax extends BugChecker implements Annot
}
// XXX: Explain, link to Lombok issue.
private static boolean isSourceAccurateCodeAvailable(AnnotationTree tree, VisitorState state) {
String source = state.getSourceForNode(tree);
String parentSource = state.getSourceForNode(state.getPath().getParentPath().getLeaf());
return source != null && parentSource != null && parentSource.contains(source);
}
// private static boolean isSourceAccurateCodeAvailable(AnnotationTree tree, VisitorState state) {
// String source = state.getSourceForNode(tree);
// String parentSource = state.getSourceForNode(state.getPath().getParentPath().getLeaf());
// return source != null && parentSource != null && parentSource.contains(source);
// }
private static Optional<Fix> dropRedundantParentheses(AnnotationTree tree, VisitorState state) {
if (!tree.getArguments().isEmpty()) {
@@ -110,7 +110,7 @@ public final class CanonicalAnnotationSyntax extends BugChecker implements Annot
}
ExpressionTree expr = AnnotationMatcherUtils.getArgument(tree, "value");
if (expr == null) {
if (expr == null || !SourceCode.isLikelyAccurateSourceAvailable(state)) {
/* This is not an explicit assignment to the `value` attribute. */
return Optional.empty();
}

View File

@@ -6,6 +6,7 @@ import static java.util.stream.Collectors.joining;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.CharMatcher;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Streams;
import com.google.errorprone.VisitorState;
@@ -14,9 +15,12 @@ import com.google.errorprone.util.ErrorProneToken;
import com.google.errorprone.util.ErrorProneTokens;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.TreePath;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.Position;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;
/**
* A collection of Error Prone utility methods for dealing with the source code representation of
@@ -28,6 +32,15 @@ public final class SourceCode {
private SourceCode() {}
// XXX: Explain.
public static boolean isLikelyAccurateSourceAvailable(VisitorState state) {
return !Strings.isNullOrEmpty(
Stream.iterate(state.getPath(), Objects::nonNull, TreePath::getParentPath)
.map(p -> state.getSourceForNode(p.getLeaf()))
// .filter(Objects::nonNull)
.reduce("", (prev, next) -> prev != null && next.contains(prev) ? next : null));
}
/**
* Returns a string representation of the given {@link Tree}, preferring the original source code
* (if available) over its prettified representation.

View File

@@ -5,6 +5,7 @@ import static com.google.errorprone.BugPattern.SeverityLevel.ERROR;
import com.google.errorprone.BugCheckerRefactoringTestHelper;
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
import com.google.errorprone.BugPattern;
import com.google.errorprone.CompilationTestHelper;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker.AnnotationTreeMatcher;
@@ -20,6 +21,31 @@ import javax.lang.model.element.Name;
import org.junit.jupiter.api.Test;
final class SourceCodeTest {
@Test
void isLikelyAccurateSourceAvailable() {
CompilationTestHelper.newInstance(IsLikelyAccurateSourceAvailableTestChecker.class, getClass())
.setArgs("-processor", "lombok.launch.AnnotationProcessorHider$AnnotationProcessor")
.addSourceLines(
"A.java",
"import lombok.Data;",
"import com.fasterxml.jackson.annotation.JsonProperty;",
"",
"class A {",
"class WithoutLombok {",
" // BUG: Diagnostic contains:",
" @JsonProperty(\"custom_field_name\")",
" private String field;",
"}",
"",
"@Data",
"class WithLombok {",
" // BUG: Diagnostic contains:",
" @JsonProperty(\"custom_field_name\")",
" private String field;",
"}}")
.doTest();
}
@Test
void deleteWithTrailingWhitespaceAnnotations() {
BugCheckerRefactoringTestHelper.newInstance(
@@ -228,6 +254,25 @@ final class SourceCodeTest {
.doTest(TestMode.TEXT_MATCH);
}
/**
* A {@link BugChecker} that uses {@link SourceCode#isLikelyAccurateSourceAvailable(VisitorState)}
* to flag annotations, fields and types for which accurate source code does not appear to be
* available.
*/
// XXX: Update set of matches Tree types.
@BugPattern(severity = ERROR, summary = "Interacts with `SourceCode` for testing purposes")
public static final class IsLikelyAccurateSourceAvailableTestChecker extends BugChecker
implements AnnotationTreeMatcher {
private static final long serialVersionUID = 1L;
@Override
public Description matchAnnotation(AnnotationTree tree, VisitorState state) {
return SourceCode.isLikelyAccurateSourceAvailable(state)
? Description.NO_MATCH
: describeMatch(tree);
}
}
/**
* A {@link BugChecker} that uses {@link SourceCode#deleteWithTrailingWhitespace(Tree,
* VisitorState)} to suggest the deletion of annotations and methods with a name containing

View File

@@ -201,8 +201,8 @@
<version.auto-value>1.10.3</version.auto-value>
<version.error-prone>${version.error-prone-orig}</version.error-prone>
<version.error-prone-fork>v${version.error-prone-orig}-picnic-1</version.error-prone-fork>
<version.error-prone-orig>HEAD-SNAPSHOT</version.error-prone-orig>
<!--<version.error-prone-orig>2.21.1</version.error-prone-orig>-->
<!--<version.error-prone-orig>HEAD-SNAPSHOT</version.error-prone-orig>-->
<version.error-prone-orig>2.21.1</version.error-prone-orig>
<version.error-prone-slf4j>0.1.20</version.error-prone-slf4j>
<version.guava-beta-checker>1.0</version.guava-beta-checker>
<version.jdk>11</version.jdk>