Skip to content

Commit

Permalink
Disallow disabling or overriding the severity of a check by altname from
Browse files Browse the repository at this point in the history
the command line.

Fixes #554

RELNOTES: Command line flags must now use canonical names to override or
disable checks.

MOE_MIGRATED_REVID=149777068
  • Loading branch information
eaftan authored and cushon committed Mar 11, 2017
1 parent 517f76f commit ae4dd95
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 53 deletions.
Expand Up @@ -19,12 +19,10 @@
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.errorprone.BugCheckerInfo; import com.google.errorprone.BugCheckerInfo;
import com.google.errorprone.BugPattern; import com.google.errorprone.BugPattern;
Expand All @@ -34,7 +32,6 @@
import com.google.errorprone.InvalidCommandLineOptionException; import com.google.errorprone.InvalidCommandLineOptionException;
import com.google.errorprone.bugpatterns.BugChecker; import com.google.errorprone.bugpatterns.BugChecker;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
Expand Down Expand Up @@ -150,23 +147,13 @@ public ScannerSupplier applyOverrides(ErrorProneOptions errorProneOptions)
Map<String, SeverityLevel> severities = new LinkedHashMap<>(severities()); Map<String, SeverityLevel> severities = new LinkedHashMap<>(severities());
Set<String> disabled = new HashSet<>(disabled()); Set<String> disabled = new HashSet<>(disabled());


// Create a map from names (canonical and alternate) to checks. We could do this when the
// supplier is created, but applyOverrides() is unlikely to be called more than once per
// scanner instance.
Multimap<String, BugCheckerInfo> checksByAllNames = ArrayListMultimap.create();
for (BugCheckerInfo checker : getAllChecks().values()) {
for (String name : checker.allNames()) {
checksByAllNames.put(name, checker);
}
}

if (errorProneOptions.isEnableAllChecks()) { if (errorProneOptions.isEnableAllChecks()) {
disabled.forEach(c -> severities.put(c, checks.get(c).defaultSeverity())); disabled.forEach(c -> severities.put(c, checks.get(c).defaultSeverity()));
disabled.clear(); disabled.clear();
} }


if (errorProneOptions.isDropErrorsToWarnings()) { if (errorProneOptions.isDropErrorsToWarnings()) {
checksByAllNames getAllChecks()
.values() .values()
.stream() .stream()
.filter( .filter(
Expand All @@ -177,46 +164,45 @@ public ScannerSupplier applyOverrides(ErrorProneOptions errorProneOptions)
// Process overrides // Process overrides
severityOverrides.forEach( severityOverrides.forEach(
(checkName, newSeverity) -> { (checkName, newSeverity) -> {
Collection<BugCheckerInfo> checksWithName = checksByAllNames.get(checkName); BugCheckerInfo check = getAllChecks().get(checkName);
if (checksWithName.isEmpty()) { if (check == null) {
if (errorProneOptions.ignoreUnknownChecks()) { if (errorProneOptions.ignoreUnknownChecks()) {
return; return;
} }
throw new InvalidCommandLineOptionException(checkName + " is not a valid checker name"); throw new InvalidCommandLineOptionException(checkName + " is not a valid checker name");
} }
for (BugCheckerInfo check : checksWithName) {
switch (newSeverity) { switch (newSeverity) {
case OFF: case OFF:
if (!check.suppressibility().disableable()) { if (!check.suppressibility().disableable()) {
throw new InvalidCommandLineOptionException( throw new InvalidCommandLineOptionException(
check.canonicalName() + " may not be disabled"); check.canonicalName() + " may not be disabled");
} }
severities.remove(check.canonicalName()); severities.remove(check.canonicalName());
disabled.add(check.canonicalName()); disabled.add(check.canonicalName());
break; break;
case DEFAULT: case DEFAULT:
severities.put(check.canonicalName(), check.defaultSeverity()); severities.put(check.canonicalName(), check.defaultSeverity());
disabled.remove(check.canonicalName()); disabled.remove(check.canonicalName());
break; break;
case WARN: case WARN:
// Demoting an enabled check from an error to a warning is a form of disabling // Demoting an enabled check from an error to a warning is a form of disabling
if (!disabled().contains(check.canonicalName()) if (!disabled().contains(check.canonicalName())
&& !check.suppressibility().disableable() && !check.suppressibility().disableable()
&& check.defaultSeverity() == SeverityLevel.ERROR) { && check.defaultSeverity() == SeverityLevel.ERROR) {
throw new InvalidCommandLineOptionException( throw new InvalidCommandLineOptionException(
check.canonicalName() check.canonicalName()
+ " is not disableable and may not be demoted to a warning"); + " is not disableable and may not be demoted to a warning");
} }
severities.put(check.canonicalName(), SeverityLevel.WARNING); severities.put(check.canonicalName(), SeverityLevel.WARNING);
disabled.remove(check.canonicalName()); disabled.remove(check.canonicalName());
break; break;
case ERROR: case ERROR:
severities.put(check.canonicalName(), SeverityLevel.ERROR); severities.put(check.canonicalName(), SeverityLevel.ERROR);
disabled.remove(check.canonicalName()); disabled.remove(check.canonicalName());
break; break;
default: default:
throw new IllegalStateException("Unexpected severity level: " + newSeverity); throw new IllegalStateException("Unexpected severity level: " + newSeverity);
}
} }
}); });


Expand Down
Expand Up @@ -257,15 +257,15 @@ public void cantOverrideNonexistentCheck() throws Exception {
} }


@Test @Test
public void canOverrideByAltname() throws Exception { public void cantOverrideByAltname() throws Exception {
ErrorProneTestCompiler compiler = ErrorProneTestCompiler compiler =
builder.report(ScannerSupplier.fromBugCheckerClasses(DisableableChecker.class)).build(); builder.report(ScannerSupplier.fromBugCheckerClasses(DisableableChecker.class)).build();
List<JavaFileObject> sources = List<JavaFileObject> sources =
compiler.fileManager().forResources(getClass(), "CommandLineFlagTestFile.java"); compiler.fileManager().forResources(getClass(), "CommandLineFlagTestFile.java");


Result exitCode = compiler.compile(new String[]{"-Xep:foo:OFF"}, Result exitCode = compiler.compile(new String[] {"-Xep:foo:OFF"}, sources);
sources); assertThat(exitCode).isEqualTo(Result.CMDERR);
assertThat(exitCode).isEqualTo(Result.OK); assertThat(output.toString()).contains("foo is not a valid checker name");
} }


@Test @Test
Expand Down

0 comments on commit ae4dd95

Please sign in to comment.