pmd/rules.xml (343 lines of code) (raw):

<?xml version="1.0"?> <ruleset name="buck" xmlns="http://pmd.sf.net/ruleset/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd" xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"> <description>Rules for the Buck project.</description> <!-- Visit https://github.com/pmd/pmd/tree/master/pmd-java/src/main/resources/rulesets/java for ruleset definitions. Note that Buck is currently built with PMD 5.0.3. --> <rule ref="rulesets/java/basic.xml"> <exclude name="CollapsibleIfStatements" /> </rule> <rule ref="rulesets/java/empty.xml"> <exclude name="EmptyCatchBlock" /> <exclude name="EmptyWhileStmt" /> </rule> <rule ref="rulesets/java/imports.xml"> <!-- Excluded because tests that use both JUnit and EasyMock tend to statically import many methods, which we allow. --> <exclude name="TooManyStaticImports" /> <!-- google-java-format covers this one; we don't need two messages. --> <exclude name="UnusedImports" /> </rule> <rule ref="rulesets/java/coupling.xml/LooseCoupling" /> <rule ref="rulesets/java/junit.xml"> <!-- This is not practical. --> <exclude name="JUnitAssertionsShouldIncludeMessage" /> <!-- Unclear what an appropriate upper bound would be. --> <exclude name="JUnitTestContainsTooManyAsserts" /> <!-- Not practical: pure EasyMock tests or tests that exclusively assert using MoreAsserts.* should not need to be annotated with this. --> <exclude name="JUnitTestsShouldIncludeAssert" /> </rule> <rule ref="rulesets/java/unusedcode.xml"> <!-- This rule is buggy (http://sourceforge.net/p/pmd/bugs/792/ and others). --> <exclude name="UnusedPrivateField" /> <exclude name="UnusedPrivateMethod" /> </rule> <rule ref="rulesets/java/optimizations.xml"> <exclude name="AvoidInstantiatingObjectsInLoops" /> <exclude name="LocalVariableCouldBeFinal" /> <exclude name="MethodArgumentCouldBeFinal" /> <exclude name="RedundantFieldInitializer" /> <exclude name="UseStringBufferForStringAppends" /> <exclude name="SimplifyStartsWith" /> <exclude name="PrematureDeclaration" /> </rule> <rule name="RuleArgMustBePackagePrivate" message="@RuleArg value types must be package-private" class="net.sourceforge.pmd.lang.rule.XPathRule" language="java"> <description>Value types decorated with @RuleArg must be package-private (i.e., not public or private). The build will automatically generate a public subclass or implementation of your value type. All clients should use that API, so the parent value type should limit its visibility as much as possible.</description> <priority>1</priority> <properties> <property name="xpath"> <value> <![CDATA[ //ClassOrInterfaceDeclaration[@PackagePrivate='false'] [ancestor::*/Annotation/MarkerAnnotation/Name [@Image='RuleArg']] ]]> </value> </property> </properties> <example> <![CDATA[ // OK @RuleArg interface AbstractFoo { } // Bad: uses public visibility @RuleArg public class AbstractBar { } // Bad: uses public visibility @RuleArg public interface AbstractBaz { } ]]> </example> </rule> <rule name="BuckImmutablesMustNotHaveValueImmutableAnnotation" message=" Value types decorated with @RuleArg or @ImmutableInfo should not use @Value.Immutable in any way" class="net.sourceforge.pmd.lang.rule.XPathRule" language="java"> <description> Using @Value.Immutable is forbidden when using @RuleArg or @ImmutableInfo.</description> <priority>1</priority> <properties> <property name="xpath"> <value> <![CDATA[ //Annotation[ following-sibling::ClassOrInterfaceDeclaration[ preceding-sibling::Annotation//Name [@Image='ImmutableInfo' or @Image='RuleArg'] ] ]/*[ Name/@Image='Value.Immutable' ] ]]> </value> </property> </properties> <example> <![CDATA[ // OK: No @Value.Immutable @RuleArg abstract class AbstractOk1 { } // OK: No @Value.Immutable @ImmutableInfo abstract class Ok2 { } // Bad: using @Value.Immutable @Value.Immutable @RuleArg abstract class AbstractBad1 { } // Bad: using @Value.Immutable @Value.Immutable @ImmutableInfo abstract class Bad2 { } ]]> </example> </rule> <rule name="RuleArgNameMustStartWithAbstract" message="Name of @RuleArg value types must start with Abstract" class="net.sourceforge.pmd.lang.rule.XPathRule" language="java"> <description>Value types decorated with @RuleArg must have a name starting with 'Abstract' The build will automatically generate a subclass or implementation of your value type without 'Abstract' in the name.</description> <priority>1</priority> <properties> <property name="xpath"> <value> <![CDATA[ //ClassOrInterfaceDeclaration[not(starts-with(@Image,'Abstract'))] [ancestor::*/Annotation/MarkerAnnotation/Name [@Image='RuleArg']] ]]> </value> </property> </properties> <example> <![CDATA[ // OK @RuleArg interface AbstractFoo { } // Bad: name does not start with Abstract @RuleArg interface Bar { } ]]> </example> </rule> <rule name="BuckStyleImmutablesMustNotHaveDefaultsImplicitlyOverridden" message=" Value types decorated with @BuckStyleValue variants must specify all of 'builder', 'copy', 'prehash' and 'intern' when overriding defaults" class="net.sourceforge.pmd.lang.rule.XPathRule" language="java"> <description>Using @Value.Immutable with @BuckStyleValue variants must specify all of 'builder', 'copy', 'prehash' and 'intern' when overriding defaults</description> <priority>1</priority> <properties> <property name="xpath"> <value> <![CDATA[ //Annotation[ following-sibling::ClassOrInterfaceDeclaration[ preceding-sibling::Annotation//Name [@Image='BuckStyleValue' or @Image='BuckStylePrehashedValue' or @Image='BuckStyleValueWithBuilder'] ] ]/*[ Name/@Image='Value.Immutable' and (not(MemberValuePairs/MemberValuePair/@Image="builder") or not(MemberValuePairs/MemberValuePair/@Image="copy") or not(MemberValuePairs/MemberValuePair/@Image="prehash") or not(MemberValuePairs/MemberValuePair/@Image="intern")) ] ]]> </value> </property> </properties> <example> <![CDATA[ // OK: No @Value.Immutable @BuckStyleValue abstract class Ok1 { } // OK: all overriden @BuckStylePrehashedValue @Value.Immutable(builder = false, copy = false, prehash = true, intern = true) abstract class Ok2 { } // OK: No @Value.Immutable @BuckStyleValueWithBuilder abstract class Ok3 { } // Bad: using @Value.Immutable @Value.Immutable @BuckStyleValue abstract class Bad1 { } // Bad: using @Value.Immutable @Value.Immutable @BuckStylePrehashedValue abstract class Bad2 { } // Bad: using @Value.Immutable partially overriden @Value.Immutable(intern = true) @BuckStyleValueWithBuilder abstract class Bad3 { } ]]> </example> </rule> <rule name="NoRawUseofValueImmutable" message="Direct use of @Value.Immutable without being adjacent to a @BuckStyleValue variant is forbidden" class="net.sourceforge.pmd.lang.rule.XPathRule" language="java"> <description>Use of @Value.Immutable without overriding defaults 'builder', 'copy', and 'intern' is forbidden. Either use one of existing BuckStyleValues, or override these defaults.</description> <priority>1</priority> <properties> <property name="xpath"> <value> <![CDATA[ //Annotation[ following-sibling::ClassOrInterfaceDeclaration[ not (preceding-sibling::Annotation//Name [@Image='BuckStyleValue' or @Image='BuckStylePrehashedValue' or @Image='BuckStyleValueWithBuilder']) ] ]/*[ Name/@Image='Value.Immutable' ] ]]> </value> </property> </properties> <example> <![CDATA[ // OK @Value.Immutable(builder = false, copy = false, prehash = true, intern = true) @BuckStyleValue interface Foo { } // Bad: does not belong beside buck style immutables @Value.Immutable(copy=false, builder=false, prehash=true) interface Bar { } ]]> </example> </rule> <!-- Blacklist docs: http://liveramp.com/engineering/using-pmd-to-blacklist-unsafe-methods/ --> <rule name="BlacklistedDefaultCharsetMethods" message="These APIs implicitly use the system default Charset. Use explicit ones instead." class="com.liveramp.pmd_extensions.BlacklistMethods"> <description> We blacklist (disallow) use of APIs which implicitly use the system default Charset. Instead, use APIs which explicitly take a Charset argument. </description> <priority>1</priority> <properties> <!-- The syntax here is a comma-separated list of pairs in the format: package.Class:method:num-args;suggested-alternative ... --> <property name="BlacklistMethods.BlacklistedMethods" value=" java.lang.String:getBytes:0;String.getBytes(Charset) "/> </properties> </rule> <rule name="BlacklistedDefaultProcessMethod" message="All subprocess creation should go through BgProcessKiller." class="com.liveramp.pmd_extensions.BlacklistMethods"> <description> We use a process-group-wide signal to kill all our subprocesses on demand; we need to synchronize this kill operation with process creation to ensure that no process gets created with SIG_IGN for SIGHUP. </description> <priority>1</priority> <properties> <!-- The syntax here is a comma-separated list of pairs in the format: package.Class:method:num-args;suggested-alternative ... --> <property name="BlacklistMethods.BlacklistedMethods" value=" java.lang.ProcessBuilder:start:0;BgProcessKiller.startProcess(ProcessBuilder),com.zaxxer.nuprocess.NuProcessBuilder:start:0;BgProcessKiller.startProcess(NuProcessBuilder) "/> </properties> </rule> <rule name="BlacklistedJavaUtilLoggerUsage" message="Use com.facebook.buck.core.util.log.Logger instead of java.util.logging.Logger" class="com.liveramp.pmd_extensions.BlacklistClassUsages"> <description> Buck uses a custom Logger which does custom formatting and maybe other things. java.util.logging.Logger bypasses this. </description> <priority>1</priority> <properties> <property name="BlacklistClassUsages.BlacklistedClasses" value="java.util.logging.Logger" /> </properties> <example> <![CDATA[ // OK import com.facebook.buck.log.Logger; private static final Logger LOG = Logger.getLogger(Main.class); // Bad import java.util.logging.Logger; private static final Logger LOG = Logger.getLogger(Main.class.getName()); ]]> </example> </rule> <rule name="BlacklistedPrintWriterUsage" message="Use com.facebook.buck.util.ThrowingPrintWriter instead of java.io.PrintWriter" class="com.liveramp.pmd_extensions.BlacklistClassUsages"> <description> java.io.PrintWriter eats IOExceptions. Using it when writing build artifacts and metadata risks generation of corrupted artifacts when I/O operations fail (such as in low-disk-space situations). </description> <priority>1</priority> <properties> <property name="BlacklistClassUsages.BlacklistedClasses" value="java.io.PrintWriter" /> <property name="violationSuppressRegex" value=".*/buck/test/.*" /> </properties> </rule> <rule name="SimplifyStringReplace" message="[perf] Use String.replace(char, char) for one-character replacements" class="net.sourceforge.pmd.lang.rule.XPathRule" language="java"> <description>Use String.replace('\\', '/') instead of String.replace("\\", "/") String#replace(char, char) is extremely efficient. String#replace(String, String) has to compile and execute a regular expression. Always prefer the former when doing single-character replacements. </description> <priority>1</priority> <properties> <property name="xpath"> <value> <!-- Match calls to str.replace("x", "y") or str.replace("\n", "\r") but not str.replace("foo", "bar") --> <![CDATA[ (//PrimaryPrefix/Name[ends-with(@Image, '.replace')]/../..| //PrimarySuffix[ends-with(@Image, 'replace')]/..) /PrimarySuffix/Arguments/ArgumentList [Expression[1]/PrimaryExpression/PrimaryPrefix/Literal[@SingleCharacterStringLiteral='true']] [Expression[2]/PrimaryExpression/PrimaryPrefix/Literal[@SingleCharacterStringLiteral='true']] ]]> </value> </property> </properties> <example> <![CDATA[ // OK class Foo { public void bar(String s) { return s.replace('\r', '\n'); } } // Bad: using expensive regular expressions to replace single characters class Foo { public void bar(String s) { return s.replace("\r", "\n"); } } ]]> </example> </rule> <rule name="BlacklistedSystemGetenv" message="Use com.facebook.buck.util.environment.EnvVariablesProvider instead of System.getenv()" class="com.liveramp.pmd_extensions.BlacklistMethods"> <description> System.getenv() returns environment variables with names that may be case-insensitive on some OSes (for example, Windows). EnvVariablesProvider.getSystemEnv() returns unified variables with names converted to upper cases. </description> <priority>1</priority> <properties> <property name="BlacklistMethods.BlacklistedMethods" value="System:getenv:0;com.facebook.buck.util.environment.EnvVariablesProvider:getSystemEnv"/> </properties> </rule> </ruleset>