kafka/checkstyle/checkstyle.xml

168 lines
5.9 KiB
XML
Raw Normal View History

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<module name="Checker">
<property name="localeLanguage" value="en"/>
<module name="FileTabCharacter"/>
<!-- header -->
<module name="Header">
<property name="headerFile" value="${config_loc}/java.header" />
</module>
<module name="TreeWalker">
<!-- code cleanup -->
<module name="UnusedImports">
<property name="processJavadoc" value="true" />
</module>
<module name="RedundantImport"/>
<module name="IllegalImport" />
<module name="EqualsHashCode"/>
<module name="SimplifyBooleanExpression"/>
<module name="OneStatementPerLine"/>
<module name="UnnecessaryParentheses">
<property name="tokens" value="IDENT, NUM_DOUBLE, LAMBDA, TEXT_BLOCK_LITERAL_BEGIN, UNARY_MINUS, UNARY_PLUS, INC, DEC, POST_INC, POST_DEC" />
</module>
<module name="SimplifyBooleanReturn"/>
MINOR: Disallow unused local variables (#18963) Recently, we found a regression that could have been detected by static analysis, since a local variable wasn't being passed to a method during a refactoring, and was left unused. It was fixed in [7a749b5](https://github.com/apache/kafka/commit/7a749b589f8c98bd452b79b49cdfb182894d7f57), but almost slipped into 4.0. Unused variables are typically detected by IDEs, but this is insufficient to prevent these kinds of bugs. This change enables unused local variable detection in checkstyle for Kafka. A few notes on the usage: - There are two situations in which people actually want to have a local variable but not use it. First, there are `for (Type ignored: collection)` loops which have to loop `collection.length` number of times, but that do not use `ignored` in the loop body. These are typically still easier to read than a classical `for` loop. Second, some IDEs detect it if a return value of a function such as `File.delete` is not being used. In this case, people sometimes store the result in an unused local variable to make ignoring the return value explicit and to avoid the squiggly lines. - In Java 22, unsued local variables can be omitted by using a single underscore `_`. This is supported by checkstyle. In pre-22 versions, IntelliJ allows such variables to be named `ignored` to suppress the unused local variable warning. This pattern is often (but not consistently) used in the Kafka codebase. This is, however, not supported by checkstyle. Since we cannot switch to Java 22, yet, and we want to use automated detection using checkstyle, we have to resort to prefixing the unused local variables with `@SuppressWarnings("UnusedLocalVariable")`. We have to apply this in 11 cases across the Kafka codebase. While not being pretty, I'd argue it's worth it to prevent bugs like the one fixed in [7a749b5](https://github.com/apache/kafka/commit/7a749b589f8c98bd452b79b49cdfb182894d7f57). Reviewers: Andrew Schofield <aschofield@confluent.io>, David Arthur <mumrah@gmail.com>, Matthias J. Sax <matthias@confluent.io>, Bruno Cadonna <cadonna@apache.org>, Kirk True <ktrue@confluent.io>
2025-03-10 16:37:35 +08:00
<module name="UnusedLocalVariable"/>
<!-- style -->
<module name="DefaultComesLast"/>
<module name="EmptyStatement"/>
<module name="ArrayTypeStyle"/>
<module name="UpperEll"/>
<module name="LeftCurly"/>
<module name="RightCurly"/>
<module name="EmptyStatement"/>
<module name="ConstantName">
<property name="format" value="(^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$)|(^log$)"/>
</module>
<module name="LocalVariableName"/>
<module name="LocalFinalVariableName"/>
<module name="MemberName"/>
<module name="ClassTypeParameterName">
<property name="format" value="^[A-Z][a-zA-Z0-9]*$$"/>
</module>
<module name="MethodTypeParameterName">
<property name="format" value="^[A-Z][a-zA-Z0-9]*$$"/>
</module>
<module name="InterfaceTypeParameterName">
<property name="format" value="^[A-Z][a-zA-Z0-9]*$$"/>
</module>
<module name="PackageName"/>
<module name="ParameterName"/>
<module name="StaticVariableName"/>
<module name="TypeName"/>
<module name="AvoidStarImport"/>
<!-- variables that can be final should be final (suppressed except for Streams) -->
<module name="FinalLocalVariable">
<property name="tokens" value="VARIABLE_DEF,PARAMETER_DEF"/>
<property name="validateEnhancedForLoopVariable" value="true"/>
</module>
<!-- dependencies -->
<module name="ImportControl">
<property name="file" value="${config_loc}/${importControlFile}"/>
</module>
<!-- don't define any import order here! Import order check/format is addressed by spotless.-->
<!-- whitespace -->
<module name="GenericWhitespace"/>
<module name="NoWhitespaceBefore"/>
<module name="WhitespaceAfter" />
<module name="NoWhitespaceAfter"/>
<module name="WhitespaceAround">
<property name="allowEmptyConstructors" value="true"/>
<property name="allowEmptyMethods" value="true"/>
</module>
<module name="Indentation"/>
<module name="MethodParamPad"/>
<module name="ParenPad"/>
<module name="TypecastParenPad"/>
<!-- locale-sensitive methods should specify locale -->
<module name="Regexp">
<property name="format" value="\.to(Lower|Upper)Case\(\)"/>
<property name="illegalPattern" value="true"/>
<property name="ignoreComments" value="true"/>
</module>
<module name="Regexp">
<property name="id" value="dontUseSystemExit"/>
<property name="format" value="System\.exit"/>
<property name="illegalPattern" value="true"/>
<property name="ignoreComments" value="true"/>
<property name="message" value="'System.exit': Should not directly call System.exit, but Exit.exit instead."/>
</module>
<!-- code quality -->
<module name="MethodLength">
<property name="max" value="170" />
</module>
<module name="ParameterNumber">
<!-- default is 8 -->
<property name="max" value="13"/>
</module>
<module name="ClassDataAbstractionCoupling">
<!-- default is 7 -->
<property name="max" value="25"/>
<property name="excludeClassesRegexps" value="AtomicInteger"/>
</module>
<module name="BooleanExpressionComplexity">
<!-- default is 3 -->
<property name="max" value="5"/>
</module>
<module name="ClassFanOutComplexity">
<!-- default is 20 -->
<property name="max" value="52"/>
</module>
<module name="CyclomaticComplexity">
<!-- default is 10-->
<property name="max" value="16"/>
</module>
<module name="JavaNCSS">
<!-- default is 50 -->
<property name="methodMaximum" value="100"/>
</module>
<module name="NPathComplexity">
<!-- default is 200 -->
<property name="max" value="500"/>
</module>
<!-- Allows the use of the @SuppressWarnings annotation in the code -->
<module name="SuppressWarningsHolder"/>
<module name="ModifierOrder"/>
</module>
<module name="SuppressionFilter">
<property name="file" value="${config_loc}/suppressions.xml"/>
</module>
<!-- Allows the use of the @SuppressWarnings annotation in the code -->
<module name="SuppressWarningsFilter"/>
</module>