diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnusedVariable.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnusedVariable.java index 84f6569fd58..ccfa1c21fda 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnusedVariable.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnusedVariable.java @@ -117,9 +117,9 @@ severity = WARNING, documentSuppression = false) public final class UnusedVariable extends BugChecker implements CompilationUnitTreeMatcher { - private static final String EXEMPT_PREFIX = "unused"; + private final ImmutableList exemptPrefixes; - private static final ImmutableSet EXEMPT_NAMES = ImmutableSet.of("ignored"); + private final ImmutableSet exemptNames; /** * The set of annotation full names which exempt annotated element from being reported as unused. @@ -163,6 +163,18 @@ public UnusedVariable(ErrorProneFlags flags) { .ifPresent(methodAnnotationsExemptingParameters::addAll); this.methodAnnotationsExemptingParameters = methodAnnotationsExemptingParameters.build(); this.reportInjectedFields = flags.getBoolean("Unused:ReportInjectedFields").orElse(false); + + ImmutableSet.Builder exemptNames = ImmutableSet.builder().add("ignored"); + flags + .getList("Unused:exemptNames") + .ifPresent(exemptNames::addAll); + this.exemptNames = exemptNames.build(); + + ImmutableList.Builder exemptPrefixes = ImmutableList.builder().add("unused"); + flags + .getList("Unused:exemptPrefixes") + .ifPresent(exemptPrefixes::addAll); + this.exemptPrefixes = exemptPrefixes.build(); } @Override @@ -542,12 +554,6 @@ private static boolean exemptedByAnnotation( return false; } - private static boolean exemptedByName(Name name) { - String nameString = name.toString(); - return Ascii.toLowerCase(nameString).startsWith(EXEMPT_PREFIX) - || EXEMPT_NAMES.contains(nameString); - } - private class VariableFinder extends TreePathScanner { private final Map unusedElements = new HashMap<>(); @@ -610,6 +616,13 @@ && exemptedFieldBySuperType(getType(variableTree), state)) { return null; } + private boolean exemptedByName(Name name) { + String nameString = name.toString(); + String nameStringLower = Ascii.toLowerCase(nameString); + return exemptPrefixes.stream().anyMatch(nameStringLower::startsWith) + || exemptNames.contains(nameString); + } + private boolean exemptedFieldBySuperType(Type type, VisitorState state) { return EXEMPTING_FIELD_SUPER_TYPES.stream() .anyMatch(t -> isSubtype(type, state.getTypeFromString(t), state)); diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/UnusedMethodTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/UnusedMethodTest.java index 03393369ecd..d30969aafbd 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/UnusedMethodTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/UnusedMethodTest.java @@ -14,6 +14,7 @@ package com.google.errorprone.bugpatterns; +import com.google.common.collect.ImmutableList; import com.google.errorprone.BugCheckerRefactoringTestHelper; import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode; import com.google.errorprone.CompilationTestHelper; @@ -102,10 +103,18 @@ public void exemptedByName() { "Unuseds.java", "package unusedvars;", "class ExemptedByName {", - " private void unused1(int a, int unusedParam) {", + " private void unused1(" + + " int a, int unusedParam, " + + " int customUnused1, int customUnused2, " + + " int prefixUnused1Param, int prefixUnused2Param" + + " ) {", " int unusedLocal = a;", " }", "}") + .setArgs( + "-XepOpt:Unused:exemptNames=customUnused1,customUnused2", + "-XepOpt:Unused:exemptPrefixes=prefixunused1,prefixunused2" + ) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/UnusedVariableTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/UnusedVariableTest.java index 81616a60c99..422320557de 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/UnusedVariableTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/UnusedVariableTest.java @@ -436,7 +436,15 @@ public void exemptedByName() { " private int unusedInt;", " private static final int UNUSED_CONSTANT = 5;", " private int ignored;", + " private int customUnused1;", + " private int customUnused2;", + " private int prefixUnused1Field;", + " private int prefixUnused2Field;", "}") + .setArgs( + "-XepOpt:Unused:exemptNames=customUnused1,customUnused2", + "-XepOpt:Unused:exemptPrefixes=prefixunused1,prefixunused2" + ) .doTest(); }