Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
import static com.google.errorprone.util.ASTHelpers.isAbstract;
import static com.google.errorprone.util.ASTHelpers.isStatic;
import static com.google.errorprone.util.ASTHelpers.isSubtype;
import static com.google.errorprone.util.AnnotationNames.AFTER_TEMPLATE_ANNOTATION;
import static com.google.errorprone.util.AnnotationNames.BEFORE_TEMPLATE_ANNOTATION;
import static com.google.errorprone.util.SideEffectAnalysis.hasSideEffect;
import static com.sun.source.tree.Tree.Kind.POSTFIX_DECREMENT;
import static com.sun.source.tree.Tree.Kind.POSTFIX_INCREMENT;
Expand Down Expand Up @@ -139,8 +141,8 @@ public final class UnusedVariable extends BugChecker implements CompilationUnitT
.addAll(InjectMatchers.PROVIDES_ANNOTATIONS)
.addAll(InjectMatchers.MULTIBINDINGS_ANNOTATIONS)
.add(
"com.google.errorprone.refaster.annotation.AfterTemplate",
"com.google.errorprone.refaster.annotation.BeforeTemplate",
AFTER_TEMPLATE_ANNOTATION,
BEFORE_TEMPLATE_ANNOTATION,
// Parameters on test methods imply the test is parameterised, and those parameters
// should be used or removed.
"org.junit.Test")
Expand Down Expand Up @@ -711,10 +713,16 @@ && exemptedFieldBySuperType(getType(variableTree), state)) {
}
}
case LOCAL_VARIABLE -> {
if (isInsideRefasterTemplate(getCurrentPath())) {
return;
}
unusedElements.put(symbol, getCurrentPath());
usageSites.put(symbol, getCurrentPath());
}
case BINDING_VARIABLE -> {
if (isInsideRefasterTemplate(getCurrentPath())) {
return;
}
if (parent instanceof BindingPatternTree
&& getCurrentPath().getParentPath().getParentPath().getLeaf()
instanceof InstanceOfTree) {
Expand Down Expand Up @@ -743,6 +751,18 @@ && getCurrentPath().getParentPath().getParentPath().getLeaf()
}
}

private boolean isInsideRefasterTemplate(TreePath path) {
for (Tree node : path) {
if (node instanceof MethodTree methodTree) {
if (hasAnnotation(methodTree, BEFORE_TEMPLATE_ANNOTATION, state)
|| hasAnnotation(methodTree, AFTER_TEMPLATE_ANNOTATION, state)) {
return true;
}
}
}
return false;
}

private boolean exemptedFieldBySuperType(Type type, VisitorState state) {
return EXEMPTING_FIELD_SUPER_TYPES.stream()
.anyMatch(t -> isSubtype(type, state.getTypeFromString(t), state));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2266,4 +2266,110 @@ public static void main(String[] args) {
.expectUnchanged()
.doTest();
}

@Test
public void refasterBeforeTemplate_unusedLocalVariable_noFinding() {
helper
.addSourceLines(
"BeforeTemplate.java",
"""
package com.google.errorprone.refaster.annotation;

public @interface BeforeTemplate {}
""")
.addSourceLines(
"Test.java",
"""
import com.google.errorprone.refaster.annotation.BeforeTemplate;

class Test {
@BeforeTemplate
void before(String s) {
String local = s.trim();
}
}
""")
.doTest();
}

@Test
public void refasterAfterTemplate_unusedLocalVariable_noFinding() {
helper
.addSourceLines(
"AfterTemplate.java",
"""
package com.google.errorprone.refaster.annotation;

public @interface AfterTemplate {}
""")
.addSourceLines(
"Test.java",
"""
import com.google.errorprone.refaster.annotation.AfterTemplate;

class Test {
@AfterTemplate
void after(String s) {
String local = s.trim();
}
}
""")
.doTest();
}

@Test
public void refasterTemplate_unusedParameter_flagged() {
helper
.addSourceLines(
"BeforeTemplate.java",
"""
package com.google.errorprone.refaster.annotation;

public @interface BeforeTemplate {}
""")
.addSourceLines(
"Test.java",
"""
import com.google.errorprone.refaster.annotation.BeforeTemplate;

class Test {
@BeforeTemplate
// BUG: Diagnostic contains: The parameter 'bar' is never read
void before(String foo, String bar) {
System.out.println(foo);
}
}
""")
.doTest();
}

@Test
public void refasterTemplate_regularMethod_unusedLocalVariable_flagged() {
helper
.addSourceLines(
"BeforeTemplate.java",
"""
package com.google.errorprone.refaster.annotation;

public @interface BeforeTemplate {}
""")
.addSourceLines(
"Test.java",
"""
import com.google.errorprone.refaster.annotation.BeforeTemplate;

class Test {
@BeforeTemplate
void before(String s) {
String local = s.trim();
}

void regularMethod(String s) {
// BUG: Diagnostic contains: The local variable 'local' is never read
String local = s.trim();
}
}
""")
.doTest();
}
}
Loading