druid/codestyle/checkstyle.xml

290 lines
13 KiB
XML

<?xml version="1.0" ?>
<!--
~ 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.
-->
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.2//EN"
"http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
<module name="Checker">
<module name="Header">
<property name="headerFile" value="${checkstyle.header.file}"/>
<property name="fileExtensions" value="java"/>
</module>
<module name="NewlineAtEndOfFile"/>
<module name="FileTabCharacter"/>
<module name="TreeWalker">
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="CHECKSTYLE.OFF\: ([\w\|]+)"/>
<property name="onCommentFormat" value="CHECKSTYLE.ON\: ([\w\|]+)"/>
<property name="checkFormat" value="$1"/>
</module>
<module name="RedundantModifier">
<property name="tokens" value="INTERFACE_DEF,ENUM_DEF,METHOD_DEF"/>
</module>
<!-- See http://checkstyle.sourceforge.net/checks.html for examples -->
<!--<module name="LineLength">-->
<!--<property name="max" value="120"/>-->
<!--</module>-->
<module name="AvoidStarImport"/>
<module name="AvoidStaticImport"/>
<module name="RedundantImport"/>
<module name="UnusedImports" />
<module name="NeedBraces"/>
<module name="LeftCurly">
<property name="option" value="nl"/>
<property name="tokens" value="INTERFACE_DEF,CLASS_DEF,ANNOTATION_DEF,ENUM_DEF,CTOR_DEF,METHOD_DEF"/>
</module>
<module name="LeftCurly">
<property name="option" value="eol"/>
<property name="tokens" value="LITERAL_WHILE,LITERAL_TRY,LITERAL_CATCH,LITERAL_FINALLY,LITERAL_SYNCHRONIZED,LITERAL_SWITCH,LITERAL_DO,LITERAL_IF,LITERAL_ELSE,LITERAL_FOR,STATIC_INIT,LAMBDA,ENUM_CONSTANT_DEF"/>
</module>
<module name="RightCurly">
<property name="option" value="same"/>
<property name="tokens" value="LITERAL_IF,LITERAL_ELSE,LITERAL_DO"/>
</module>
<module name="RightCurly">
<property name="option" value="alone"/>
<property name="tokens" value="LITERAL_TRY,LITERAL_CATCH,LITERAL_FINALLY,CLASS_DEF,METHOD_DEF,CTOR_DEF,LITERAL_FOR,LITERAL_WHILE,STATIC_INIT,INSTANCE_INIT"/>
</module>
<module name="WhitespaceAfter"/>
<module name="WhitespaceAround">
<property name="allowEmptyConstructors" value="true"/>
<property name="allowEmptyMethods" value="true"/>
<property name="allowEmptyLambdas" value="true"/>
<property name="allowEmptyTypes" value="true"/>
<property name="ignoreEnhancedForColon" value="false"/>
</module>
<module name="ParenPad"/>
<module name="SingleSpaceSeparator"/>
<module name="NoWhitespaceBefore">
<property name="tokens" value="COMMA,SEMI,POST_INC,POST_DEC,ELLIPSIS,METHOD_REF"/>
</module>
<module name="NoWhitespaceBefore">
<property name="tokens" value="DOT"/>
<property name="allowLineBreaks" value="true"/>
</module>
<module name="NoWhitespaceAfter"/>
<module name="NoWhitespaceAfter">
<property name="tokens" value="DOT"/>
<property name="allowLineBreaks" value="false"/>
</module>
<module name="GenericWhitespace"/>
<module name="EmptyLineSeparator">
<property name="tokens" value="PACKAGE_DEF,IMPORT,STATIC_IMPORT,INTERFACE_DEF,STATIC_INIT,INSTANCE_INIT,CTOR_DEF,VARIABLE_DEF"/>
<property name="allowNoEmptyLineBetweenFields" value="true"/>
<property name="allowMultipleEmptyLinesInsideClassMembers" value="false"/>
</module>
<module name="Indentation">
<property name="basicOffset" value="2"/>
<property name="caseIndent" value="2"/>
</module>
<module name="MethodParamPad">
<property name="allowLineBreaks" value="true"/>
</module>
<module name="OneStatementPerLine"/>
<module name="EmptyStatement"/>
<module name="ModifierOrder" />
<module name="Regexp">
<property name="format" value="com\.google\.common\.io\.Closer"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Use org.apache.druid.java.util.common.io.Closer instead of Guava's Closer"/>
</module>
<module name="Regexp">
<property name="format" value="^// {2}"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Don't commit IntelliJ-style commented code lines"/>
</module>
<module name="Regexp">
<property name="format" value="/\*[^\*].*?\n(\s*\*.*?\n)*\s+\*/[\s\n]*(transient|volatile|strictfp|synchronized|native|abstract|class|interface|enum|static|private|public|protected|default|void|byte|char|short|int|float|long|double|[A-Z])"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Comments to classes and methods must be Javadoc comments"/>
</module>
<module name="Regexp">
<property name="format" value="natural\(\)[\s\n]*\.[\s\n]*nullsFirst\(\)"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Use Comparators.naturalNullsFirst() instead of Ordering.natural().nullsFirst()"/>
</module>
<module name="Regexp">
<property name="format" value="Enums\.getIfPresent\("/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Use GuavaUtils.getEnumIfPresent() instead of Enums.getIfPresent()"/>
</module>
<module name="Regexp">
<property name="format" value="(Byte|Character|Short|Integer|Long|Float|Double)\.TYPE"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Use primitive.class instead. But check twice that you don't actually need BoxedPrimitive.class instead of BoxedPrimitive.TYPE"/>
</module>
<module name="Regexp">
<property name="format" value="Float\.MAX_VALUE"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Use Float.POSITIVE_INFINITY"/>
</module>
<module name="Regexp">
<property name="format" value="Float\.MIN_VALUE"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Use Float.NEGATIVE_INFINITY"/>
</module>
<module name="Regexp">
<property name="format" value="Double\.MAX_VALUE"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Use Double.POSITIVE_INFINITY"/>
</module>
<module name="Regexp">
<property name="format" value="Double\.MIN_VALUE"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Use Double.NEGATIVE_INFINITY"/>
</module>
<module name="Regexp">
<property name="format" value="com\.metamx\.common\.logger"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Use org.apache.druid.java.util.common.logger.Logger instead"/>
</module>
<module name="Regexp">
<!-- Couldn't check this in forbidden-apis, because javac replaces compile-time constants without refs. -->
<property name="format" value="(Shorts|Chars|Ints|Longs|Floats|Doubles)\.BYTES"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Use java.lang.Primitive.BYTES instead."/>
</module>
<!-- This regex should be replaced with an IntelliJ inspection when teamcity.jetbrains.com updates to at least IntelliJ 2018.1 (currently it uses 2017.2) -->
<module name="Regexp">
<property name="format" value='[a-z][a-zA-Z0-9_]*\.equals\((\"|[A-Z_]+\))'/>
<property name="illegalPattern" value="true"/>
<property name="message" value='Use "string".equals(javaVar) and STRING_CONSTANT.equals(javaVar) instead of javaVar.equals("string") and javaVar.equals(STRING_CONSTANT)'/>
</module>
<module name="Regexp">
<property name="format" value="toArray\([\s\n]*new [a-zA-Z0-9_]+\[[^0]"/>
<property name="illegalPattern" value="true"/>
<property name="message" value='Use toArray(new Object[0]) instead'/>
</module>
<module name="Regexp">
<property name="format" value="Strings.emptyToNull"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Use org.apache.druid.common.config.NullHandling.emptyToNullIfNeeded instead"/>
</module>
<module name="Regexp">
<property name="format" value="Strings.nullToEmpty"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Use org.apache.druid.common.config.NullHandling.nullToEmptyIfNeeded instead"/>
</module>
<module name="PackageName">
<property name="format" value="^org.apache.druid.*$"/>
</module>
<module name="PackageDeclaration"/>
<!-- See https://github.com/checkstyle/checkstyle/issues/5510 and the ImportOrder suppression in
checkstyle-suppressions.xml -->
<module name="ImportOrder">
<property name="groups" value="*,javax,java"/>
<property name="ordered" value="true"/>
<property name="separated" value="true"/>
<property name="option" value="bottom"/>
<property name="sortStaticImportsAlphabetically" value="true"/>
</module>
<module name="Regexp">
<property name="format" value="instanceof\s+(ObjectColumnSelector|LongColumnSelector|FloatColumnSelector|DoubleColumnSelector)"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="ObjectColumnSelector, LongColumnSelector, FloatColumnSelector
and DoubleColumnSelector must not be used in an instanceof statement, see Javadoc of those interfaces."/>
</module>
<module name="Regexp">
<property name="id" value="argumentLineBreaking"/>
<property
name="format"
value='(?&lt;!ImmutableMap.of|Types.mapOf|orderedMap|makeSelectResults|makeListOfPairs)\(\s*\n +([^,\n\(\{"&lt;/]+|[^,\n\(\{" /]+&gt; [a-zA-Z0-9_]+)\, ++[^,\n/]+'
/>
<property name="illegalPattern" value="true"/>
<property name="message" value="&#10;
According to the Druid code style, if a method or constructor declaration or a call&#10;
doesn't fit a single line, each parameter or argument should be on it's own, e. g:&#10;
&#10;
MyReturnType myMethodWithAVeryLongName(&#10;
MyParamTypeA myParamAWithAVeryLongName,&#10;
MyParamTypeB myParamBWithAVeryLongName&#10;
)&#10;
&#10;
or&#10;
&#10;
MyValueType myValue = myMethodWithAVeryLongName(&#10;
myVeryLongArgA,&#10;
myVeryLongArgB&#10;
)&#10;
&#10;
The exceptions from this rule are map-like and pair-accepting constructors and methods,&#10;
for those it's preferred to put each pair on it's own line, e. g:&#10;
&#10;
Map&lt;MyKeyType, MyValueType&gt; myMap = ImmutableMap.of(&#10;
myKey1, myValue1,&#10;
myKey2, myValue2&#10;
)&#10;
&#10;
Always prefer to fit a declaration or a method or constructor call into a single line&#10;
(less than 120 cols), if possible.&#10;
&#10;
Two things to note to avoid unnecessary breakdown:&#10;
&#10;
1) Exceptions declared for a method could be broken to the next line separately, e. g:&#10;
&#10;
MyReturnType myMethodWithAVeryLongName(MyParamTypeA myParamA, MyParamTypeB myParamB)&#10;
throws MyExceptionTypeAWithVeryLongName, MyExceptionTypeBWithVeryLongName&#10;
&#10;
2) In a variable, field or constant assignment, it's often more readable to break the&#10;
whole right hand side expression to the next line, instead of breaking the expression&#10;
arguments, e. g:&#10;
&#10;
MyTypeWithAVeryLongName myVariableWithAVeryLongName =&#10;
myMethodWithAVeryLongName(myArgA, myArgB);&#10;
&#10;
Also note that this checkstyle rule (the one that caused this message to be printed)&#10;
doesn't spot all violations of the corresponding Druid code style rule. If you see&#10;
a place where method or constructor parameters or call arguments are not properly&#10;
located each on it's own line, but this checkstyle rule is silent, if doesn't mean&#10;
that the code is formatted correctly. Fix it anyway.&#10;
&#10;
If you encouter a map-like or a pair-accepting method that is reported by this&#10;
checkstyle rule, you should add it as an exception in the corresponding rule in&#10;
codestyle/checkstyle.xml.&#10;"/>
</module>
<module name="Regexp">
<property name="id" value="duplicateLine"/>
<property name="format" value="^(.*;)(\r?\n\1)+$"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Duplicate line"/>
</module>
</module>
</module>