From d07c17a47327394e4ee499068e37044dad50cb9c Mon Sep 17 00:00:00 2001 From: Mikkel Kjeldsen Date: Tue, 25 Feb 2025 14:58:28 +0100 Subject: [PATCH] IdentifierName: accept regex to exempt type name violations Occasionally, type names need to follow conventions that violate the styleguide without being able to rely on inheritance or annotations for exemption. For example, JMX MBean and MXBean definitions will routinely violate the styleguide, and outside the JDK, `maven-failsafe-plugin` 3.5.2's default filter is a set of 3 violating patterns. Suppressing these violations quickly becomes tedious. Rather than Whac-A-Mole'ing tolerated violations, define a new option whose value is a regex such that, if a possibly-violating type name matches that regex, the type name is allowed anyway. References: https://github.com/google/error-prone/issues/4776 References: https://github.com/google/error-prone/issues/4832 --- .../errorprone/bugpatterns/IdentifierName.java | 9 ++++++++- .../bugpatterns/IdentifierNameTest.java | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/IdentifierName.java b/core/src/main/java/com/google/errorprone/bugpatterns/IdentifierName.java index 9b8e5cb14d5..3976965cbb1 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/IdentifierName.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/IdentifierName.java @@ -60,6 +60,7 @@ import com.sun.tools.javac.code.Symbol.MethodSymbol; import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.util.Name; +import java.util.Optional; import java.util.regex.Pattern; import java.util.stream.Stream; import javax.inject.Inject; @@ -103,10 +104,14 @@ public final class IdentifierName extends BugChecker private final boolean allowInitialismsInTypeName; + private final Pattern allowRegexInTypeName; + @Inject IdentifierName(ErrorProneFlags flags) { this.allowInitialismsInTypeName = flags.getBoolean("IdentifierName:AllowInitialismsInTypeName").orElse(false); + this.allowRegexInTypeName = + Pattern.compile(flags.get("IdentifierName:AllowRegexInTypeName").orElse(".+")); } @Override @@ -294,7 +299,9 @@ private static boolean isConformantLowerCamelName(String name) { private boolean isConformantTypeName(String name) { return !name.contains("_") && isUpperCase(name.charAt(0)) - && (allowInitialismsInTypeName || !PROBABLE_INITIALISM.matcher(name).find()); + && (allowInitialismsInTypeName + || allowRegexInTypeName.matcher(name).matches() + || !PROBABLE_INITIALISM.matcher(name).find()); } private static boolean isStaticVariable(Symbol symbol) { diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/IdentifierNameTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/IdentifierNameTest.java index 2e838b354b9..ecd9c943023 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/IdentifierNameTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/IdentifierNameTest.java @@ -658,6 +658,21 @@ public void className_underscore() { .doTest(); } + @Test + public void className_badPattern_allowed() { + helper + .setArgs("-XepOpt:IdentifierName:AllowRegexInTypeName=.+(IT|MX?Bean)") + .addSourceLines( + "SomethingMBean.java", // + "interface SomethingMBean {", + "}") + .addSourceLines( + "SomethingIT.java", // + "class SomethingIT {", + "}") + .doTest(); + } + @Test public void enumName() { helper