Merge branch 'text-utils-javacc' into text-utils-comments

This commit is contained in:
Clément Fournier
2021-12-22 19:58:33 +01:00
540 changed files with 23655 additions and 7386 deletions

6491
.all-contributorsrc Normal file

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,10 @@ It uses the common scripts from [build-tools](https://github.com/pmd/build-tools
This files contains the following environment variables:
* DANGER_GITHUB_API_TOKEN: Token for danger to add comments to PRs as <https://github.com/pmd-test>.
The token needs the scope "public_repo".
The token needs the scope "public_repo". Note: The default GITHUB_TOKEN can't be used, because
danger runs in pull request builds from fork and the default GITHUB_TOKEN has read-only access there
and can't write comments. Therefore the personal access token of the bot account "pmd-test" is used.
pmd-test has no commit permissions, but can comment on any public repo, including pmd/pmd.
* PMD_CI_CHUNK_TOKEN: Token for uploading reports to chunk.io
The file is encrypted, so that the tokens are not automatically disabled when github detects them

View File

@ -9,14 +9,16 @@ SCRIPT_INCLUDES="log.bash utils.bash setup-secrets.bash openjdk.bash maven.bash
source "$(dirname "$0")/inc/fetch_ci_scripts.bash" && fetch_ci_scripts
function build() {
pmd_ci_log_group_start "Prepare Java 8+11, Bundler"
pmd_ci_openjdk_install_adoptopenjdk 11
pmd_ci_log_group_start "Prepare Java 8+11+17, Bundler"
pmd_ci_openjdk_install_adoptium 11
pmd_ci_openjdk_setdefault 11
PMD_MAVEN_EXTRA_OPTS=()
if [ "$(pmd_ci_utils_get_os)" = "linux" ]; then
pmd_ci_log_info "Install openjdk8 for integration tests and pmd-regression-tests"
pmd_ci_openjdk_install_adoptopenjdk 8
PMD_MAVEN_EXTRA_OPTS=(-Djava8.home="${HOME}/openjdk8")
pmd_ci_openjdk_install_adoptium 8
pmd_ci_log_info "Install openjdk17 for integration tests and pmd-regression-tests"
pmd_ci_openjdk_install_adoptium 17
PMD_MAVEN_EXTRA_OPTS=(-Djava8.home="${HOME}/openjdk8" -Djava17.home="${HOME}/openjdk17")
fi
pmd_ci_build_setup_bundler
pmd_ci_log_group_end
@ -85,6 +87,23 @@ function build() {
pmd_ci_log_group_end
if pmd_ci_maven_isSnapshotBuild; then
if [ "${PMD_CI_MAVEN_PROJECT_VERSION}" != "7.0.0-SNAPSHOT" ]; then
pmd_ci_log_group_start "Executing PMD dogfood test with ${PMD_CI_MAVEN_PROJECT_VERSION}"
./mvnw versions:set -DnewVersion="${PMD_CI_MAVEN_PROJECT_VERSION}-dogfood" -DgenerateBackupPoms=false
sed -i 's/<version>[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}.*<\/version>\( *<!-- pmd.dogfood.version -->\)/<version>'"${PMD_CI_MAVEN_PROJECT_VERSION}"'<\/version>\1/' pom.xml
./mvnw verify --show-version --errors --batch-mode --no-transfer-progress "${PMD_MAVEN_EXTRA_OPTS[@]}" \
-DskipTests \
-Dmaven.javadoc.skip=true \
-Dmaven.source.skip=true \
-Dcheckstyle.skip=true
./mvnw versions:set -DnewVersion="${PMD_CI_MAVEN_PROJECT_VERSION}" -DgenerateBackupPoms=false
git checkout -- pom.xml
pmd_ci_log_group_end
else
# current maven-pmd-plugin is not compatible with PMD 7 yet.
pmd_ci_log_info "Skipping PMD dogfood test with ${PMD_CI_MAVEN_PROJECT_VERSION}"
fi
pmd_ci_log_group_start "Executing build with sonar"
# Note: Sonar also needs GITHUB_TOKEN (!)
./mvnw \

View File

@ -42,9 +42,11 @@
<rule ref="category/java/bestpractices.xml/MissingOverride"/>
<rule ref="category/java/bestpractices.xml/OneDeclarationPerLine"/>
<rule ref="category/java/bestpractices.xml/PreserveStackTrace"/>
<rule ref="category/java/bestpractices.xml/PrimitiveWrapperInstantiation"/>
<rule ref="category/java/bestpractices.xml/ReplaceEnumerationWithIterator"/>
<rule ref="category/java/bestpractices.xml/ReplaceHashtableWithMap"/>
<rule ref="category/java/bestpractices.xml/ReplaceVectorWithList"/>
<!-- <rule ref="category/java/bestpractices.xml/SimplifiableTestAssertion" /> -->
<rule ref="category/java/bestpractices.xml/SwitchStmtsShouldHaveDefault"/>
<rule ref="category/java/bestpractices.xml/SystemPrintln"/>
<rule ref="category/java/bestpractices.xml/UnusedAssignment"/>
@ -52,10 +54,6 @@
<rule ref="category/java/bestpractices.xml/UnusedLocalVariable"/>
<rule ref="category/java/bestpractices.xml/UnusedPrivateField"/>
<rule ref="category/java/bestpractices.xml/UnusedPrivateMethod"/>
<rule ref="category/java/bestpractices.xml/UseAssertEqualsInsteadOfAssertTrue"/>
<rule ref="category/java/bestpractices.xml/UseAssertNullInsteadOfAssertTrue"/>
<rule ref="category/java/bestpractices.xml/UseAssertSameInsteadOfAssertTrue"/>
<rule ref="category/java/bestpractices.xml/UseAssertTrueInsteadOfAssertEquals"/>
<rule ref="category/java/bestpractices.xml/UseCollectionIsEmpty"/>
<rule ref="category/java/bestpractices.xml/UseStandardCharsets" />
<rule ref="category/java/bestpractices.xml/UseTryWithResources"/>
@ -75,7 +73,6 @@
<rule ref="category/java/codestyle.xml/CommentDefaultAccessModifier"/>
<rule ref="category/java/codestyle.xml/ConfusingTernary"/>
<rule ref="category/java/codestyle.xml/ControlStatementBraces"/>
<rule ref="category/java/codestyle.xml/DefaultPackage"/>
<rule ref="category/java/codestyle.xml/EmptyMethodInAbstractClassShouldBeAbstract"/>
<rule ref="category/java/codestyle.xml/ExtendsObject"/>
<rule ref="category/java/codestyle.xml/FieldDeclarationsShouldBeAtStartOfClass"/>
@ -106,6 +103,7 @@
<rule ref="category/java/codestyle.xml/UnnecessaryAnnotationValueElement"/>
<rule ref="category/java/codestyle.xml/UnnecessaryCast"/>
<rule ref="category/java/codestyle.xml/UnnecessaryConstructor"/>
<rule ref="category/java/codestyle.xml/UnnecessaryBoxing"/>
<rule ref="category/java/codestyle.xml/UnnecessaryFullyQualifiedName"/>
<!-- <rule ref="category/java/codestyle.xml/UnnecessaryImport"/> -->
<rule ref="category/java/codestyle.xml/UnnecessaryLocalBeforeReturn"/>
@ -126,10 +124,10 @@
<!-- <rule ref="category/java/design.xml/AvoidThrowingNewInstanceOfSameException"/> -->
<rule ref="category/java/design.xml/AvoidThrowingNullPointerException"/>
<!-- <rule ref="category/java/design.xml/AvoidThrowingRawExceptionTypes"/> -->
<!-- <rule ref="category/java/design.xml/AvoidUncheckedExceptionsInSignatures"/> -->
<!-- <rule ref="category/java/design.xml/ClassWithOnlyPrivateConstructorsShouldBeFinal"/> -->
<rule ref="category/java/design.xml/AvoidUncheckedExceptionsInSignatures"/>
<rule ref="category/java/design.xml/ClassWithOnlyPrivateConstructorsShouldBeFinal"/>
<rule ref="category/java/design.xml/CognitiveComplexity" />
<!-- <rule ref="category/java/design.xml/CollapsibleIfStatements"/> -->
<rule ref="category/java/design.xml/CollapsibleIfStatements"/>
<!-- <rule ref="category/java/design.xml/CouplingBetweenObjects"/> -->
<rule ref="category/java/design.xml/CyclomaticComplexity"/>
<rule ref="category/java/design.xml/DataClass"/>
@ -140,28 +138,27 @@
<rule ref="category/java/design.xml/ExcessiveMethodLength"/>
<rule ref="category/java/design.xml/ExcessiveParameterList"/>
<rule ref="category/java/design.xml/ExcessivePublicCount"/>
<!-- <rule ref="category/java/design.xml/FinalFieldCouldBeStatic"/> -->
<rule ref="category/java/design.xml/FinalFieldCouldBeStatic"/>
<rule ref="category/java/design.xml/GodClass"/>
<rule ref="category/java/design.xml/ImmutableField"/>
<!-- <rule ref="category/java/design.xml/LawOfDemeter"/> -->
<!-- <rule ref="category/java/design.xml/LogicInversion"/> -->
<rule ref="category/java/design.xml/LogicInversion"/>
<!-- <rule ref="category/java/design.xml/LoosePackageCoupling"/> -->
<rule ref="category/java/design.xml/MutableStaticState" />
<rule ref="category/java/design.xml/NPathComplexity"/>
<rule ref="category/java/design.xml/NcssCount"/>
<!-- <rule ref="category/java/design.xml/SignatureDeclareThrowsException"/> -->
<!-- <rule ref="category/java/design.xml/SimplifiedTernary"/> -->
<!-- <rule ref="category/java/design.xml/SimplifyBooleanAssertion"/> -->
<rule ref="category/java/design.xml/SimplifiedTernary"/>
<rule ref="category/java/design.xml/SimplifyBooleanExpressions"/>
<rule ref="category/java/design.xml/SimplifyBooleanReturns"/>
<!-- <rule ref="category/java/design.xml/SimplifyConditional"/> -->
<rule ref="category/java/design.xml/SimplifyConditional"/>
<rule ref="category/java/design.xml/SingularField"/>
<!-- <rule ref="category/java/design.xml/SwitchDensity"/> -->
<rule ref="category/java/design.xml/SwitchDensity"/>
<!-- <rule ref="category/java/design.xml/TooManyFields"/> -->
<!-- <rule ref="category/java/design.xml/TooManyMethods"/> -->
<!-- <rule ref="category/java/design.xml/UseObjectForClearerAPI"/> -->
<!-- <rule ref="category/java/design.xml/UseUtilityClass"/> -->
<!-- <rule ref="category/java/design.xml/UselessOverridingMethod"/> -->
<rule ref="category/java/design.xml/UseUtilityClass"/>
<rule ref="category/java/design.xml/UselessOverridingMethod"/>
<!-- documentation.xml -->
@ -174,9 +171,10 @@
<!-- errorprone.xml -->
<rule ref="category/java/errorprone.xml/AssignmentInOperand"/>
<!-- <rule ref="category/java/errorprone.xml/AssignmentToNonFinalStatic"/> -->
<rule ref="category/java/errorprone.xml/AssignmentToNonFinalStatic"/>
<rule ref="category/java/errorprone.xml/AvoidAccessibilityAlteration"/>
<rule ref="category/java/errorprone.xml/AvoidAssertAsIdentifier"/>
<!-- <rule ref="category/java/errorprone.xml/AvoidBranchingStatementAsLastInLoop"/> -->
<rule ref="category/java/errorprone.xml/AvoidBranchingStatementAsLastInLoop"/>
<!-- <rule ref="category/java/errorprone.xml/AvoidCallingFinalize"/> -->
<!-- <rule ref="category/java/errorprone.xml/AvoidCatchingNPE"/> -->
<rule ref="category/java/errorprone.xml/AvoidCatchingThrowable"/>
@ -185,34 +183,33 @@
<rule ref="category/java/errorprone.xml/AvoidEnumAsIdentifier"/>
<!-- <rule ref="category/java/errorprone.xml/AvoidFieldNameMatchingMethodName"/> -->
<!-- <rule ref="category/java/errorprone.xml/AvoidFieldNameMatchingTypeName"/> -->
<!-- <rule ref="category/java/errorprone.xml/AvoidInstanceofChecksInCatchClause"/> -->
<rule ref="category/java/errorprone.xml/AvoidInstanceofChecksInCatchClause"/>
<!-- <rule ref="category/java/errorprone.xml/AvoidLiteralsInIfCondition"/> -->
<!-- <rule ref="category/java/errorprone.xml/AvoidLosingExceptionInformation"/> -->
<rule ref="category/java/errorprone.xml/AvoidMultipleUnaryOperators"/>
<!-- <rule ref="category/java/errorprone.xml/AvoidUsingOctalValues"/> -->
<rule ref="category/java/errorprone.xml/AvoidUsingOctalValues"/>
<!-- <rule ref="category/java/errorprone.xml/BeanMembersShouldSerialize"/> -->
<rule ref="category/java/errorprone.xml/BrokenNullCheck"/>
<!-- <rule ref="category/java/errorprone.xml/CallSuperFirst"/> -->
<!-- <rule ref="category/java/errorprone.xml/CallSuperLast"/> -->
<!-- <rule ref="category/java/errorprone.xml/CheckSkipResult"/> -->
<!-- <rule ref="category/java/errorprone.xml/ClassCastExceptionWithToArray"/> -->
<!-- <rule ref="category/java/errorprone.xml/CloneMethodMustBePublic"/> -->
<rule ref="category/java/errorprone.xml/CheckSkipResult"/>
<rule ref="category/java/errorprone.xml/ClassCastExceptionWithToArray"/>
<rule ref="category/java/errorprone.xml/CloneMethodMustBePublic"/>
<rule ref="category/java/errorprone.xml/CloneMethodMustImplementCloneable"/>
<!-- <rule ref="category/java/errorprone.xml/CloneMethodReturnTypeMustMatchClassName"/> -->
<rule ref="category/java/errorprone.xml/CloneMethodReturnTypeMustMatchClassName"/>
<!-- <rule ref="category/java/errorprone.xml/CloneThrowsCloneNotSupportedException"/> -->
<!-- <rule ref="category/java/errorprone.xml/CloseResource"/> -->
<rule ref="category/java/errorprone.xml/CloseResource"/>
<rule ref="category/java/errorprone.xml/CompareObjectsWithEquals"/>
<!-- <rule ref="category/java/errorprone.xml/ComparisonWithNaN"/> -->
<rule ref="category/java/errorprone.xml/ComparisonWithNaN"/>
<rule ref="category/java/errorprone.xml/ConstructorCallsOverridableMethod"/>
<!-- <rule ref="category/java/errorprone.xml/DataflowAnomalyAnalysis"/> -->
<!-- <rule ref="category/java/errorprone.xml/DetachedTestCase"/> -->
<!-- <rule ref="category/java/errorprone.xml/DoNotCallGarbageCollectionExplicitly"/> -->
<!-- <rule ref="category/java/errorprone.xml/DoNotCallSystemExit"/> -->
<rule ref="category/java/errorprone.xml/DoNotCallGarbageCollectionExplicitly"/>
<!-- <rule ref="category/java/errorprone.xml/DoNotExtendJavaLangThrowable"/> -->
<!-- <rule ref="category/java/errorprone.xml/DoNotHardCodeSDCard"/> -->
<!-- <rule ref="category/java/errorprone.xml/DoNotThrowExceptionInFinally"/> -->
<!-- <rule ref="category/java/errorprone.xml/DontImportSun"/> -->
<!-- <rule ref="category/java/errorprone.xml/DontUseFloatTypeForLoopIndices"/> -->
<rule ref="category/java/errorprone.xml/DontImportSun"/>
<rule ref="category/java/errorprone.xml/DontUseFloatTypeForLoopIndices"/>
<rule ref="category/java/errorprone.xml/EmptyCatchBlock"/>
<rule ref="category/java/errorprone.xml/EmptyFinalizer"/>
<rule ref="category/java/errorprone.xml/EmptyFinallyBlock"/>
@ -225,48 +222,48 @@
<rule ref="category/java/errorprone.xml/EmptyTryBlock"/>
<rule ref="category/java/errorprone.xml/EmptyWhileStmt"/>
<rule ref="category/java/errorprone.xml/EqualsNull"/>
<!-- <rule ref="category/java/errorprone.xml/FinalizeDoesNotCallSuperFinalize"/> -->
<!-- <rule ref="category/java/errorprone.xml/FinalizeOnlyCallsSuperFinalize"/> -->
<!-- <rule ref="category/java/errorprone.xml/FinalizeOverloaded"/> -->
<!-- <rule ref="category/java/errorprone.xml/FinalizeShouldBeProtected"/> -->
<!-- <rule ref="category/java/errorprone.xml/IdempotentOperations"/> -->
<!-- <rule ref="category/java/errorprone.xml/InstantiationToGetClass"/> -->
<!-- <rule ref="category/java/errorprone.xml/InvalidLogMessageFormat"/> -->
<rule ref="category/java/errorprone.xml/FinalizeDoesNotCallSuperFinalize"/>
<rule ref="category/java/errorprone.xml/FinalizeOnlyCallsSuperFinalize"/>
<rule ref="category/java/errorprone.xml/FinalizeOverloaded"/>
<rule ref="category/java/errorprone.xml/FinalizeShouldBeProtected"/>
<rule ref="category/java/errorprone.xml/IdempotentOperations"/>
<rule ref="category/java/errorprone.xml/ImplicitSwitchFallThrough"/>
<rule ref="category/java/errorprone.xml/InstantiationToGetClass"/>
<rule ref="category/java/errorprone.xml/InvalidLogMessageFormat"/>
<rule ref="category/java/errorprone.xml/JUnitSpelling"/>
<rule ref="category/java/errorprone.xml/JUnitStaticSuite"/>
<!-- <rule ref="category/java/errorprone.xml/JumbledIncrementer"/> -->
<rule ref="category/java/errorprone.xml/JumbledIncrementer"/>
<!-- <rule ref="category/java/errorprone.xml/MethodWithSameNameAsEnclosingClass"/> -->
<!-- <rule ref="category/java/errorprone.xml/MisplacedNullCheck"/> -->
<rule ref="category/java/errorprone.xml/MissingBreakInSwitch"/>
<!-- <rule ref="category/java/errorprone.xml/MissingSerialVersionUID"/> -->
<!-- <rule ref="category/java/errorprone.xml/MissingStaticMethodInNonInstantiatableClass"/> -->
<rule ref="category/java/errorprone.xml/MisplacedNullCheck"/>
<rule ref="category/java/errorprone.xml/MissingSerialVersionUID"/>
<rule ref="category/java/errorprone.xml/MissingStaticMethodInNonInstantiatableClass"/>
<!-- <rule ref="category/java/errorprone.xml/MoreThanOneLogger"/> -->
<!-- <rule ref="category/java/errorprone.xml/NonCaseLabelInSwitchStatement"/> -->
<!-- <rule ref="category/java/errorprone.xml/NonStaticInitializer"/> -->
<rule ref="category/java/errorprone.xml/NonCaseLabelInSwitchStatement"/>
<rule ref="category/java/errorprone.xml/NonStaticInitializer"/>
<!-- <rule ref="category/java/errorprone.xml/NullAssignment"/> -->
<!-- <rule ref="category/java/errorprone.xml/OverrideBothEqualsAndHashcode"/> -->
<!-- <rule ref="category/java/errorprone.xml/ProperCloneImplementation"/> -->
<!-- <rule ref="category/java/errorprone.xml/ProperLogger"/> -->
<!-- <rule ref="category/java/errorprone.xml/ReturnEmptyArrayRatherThanNull"/> -->
<!-- <rule ref="category/java/errorprone.xml/ReturnFromFinallyBlock"/> -->
<!-- <rule ref="category/java/errorprone.xml/SimpleDateFormatNeedsLocale"/> -->
<!-- <rule ref="category/java/errorprone.xml/SingleMethodSingleton"/> -->
<!-- <rule ref="category/java/errorprone.xml/SingletonClassReturningNewInstance"/> -->
<!-- <rule ref="category/java/errorprone.xml/StaticEJBFieldShouldBeFinal"/> -->
<!-- <rule ref="category/java/errorprone.xml/StringBufferInstantiationWithChar"/> -->
<!-- <rule ref="category/java/errorprone.xml/SuspiciousEqualsMethodName"/> -->
<!-- <rule ref="category/java/errorprone.xml/SuspiciousHashcodeMethodName"/> -->
<!-- <rule ref="category/java/errorprone.xml/SuspiciousOctalEscape"/> -->
<rule ref="category/java/errorprone.xml/OverrideBothEqualsAndHashcode"/>
<rule ref="category/java/errorprone.xml/ProperCloneImplementation"/>
<rule ref="category/java/errorprone.xml/ProperLogger"/>
<rule ref="category/java/errorprone.xml/ReturnEmptyCollectionRatherThanNull"/>
<rule ref="category/java/errorprone.xml/ReturnFromFinallyBlock"/>
<rule ref="category/java/errorprone.xml/SimpleDateFormatNeedsLocale"/>
<rule ref="category/java/errorprone.xml/SingleMethodSingleton"/>
<rule ref="category/java/errorprone.xml/SingletonClassReturningNewInstance"/>
<rule ref="category/java/errorprone.xml/StaticEJBFieldShouldBeFinal"/>
<rule ref="category/java/errorprone.xml/StringBufferInstantiationWithChar"/>
<rule ref="category/java/errorprone.xml/SuspiciousEqualsMethodName"/>
<rule ref="category/java/errorprone.xml/SuspiciousHashcodeMethodName"/>
<rule ref="category/java/errorprone.xml/SuspiciousOctalEscape"/>
<rule ref="category/java/errorprone.xml/TestClassWithoutTestCases"/>
<!-- <rule ref="category/java/errorprone.xml/UnconditionalIfStatement"/> -->
<!-- <rule ref="category/java/errorprone.xml/UnnecessaryBooleanAssertion"/> -->
<!-- <rule ref="category/java/errorprone.xml/UnnecessaryCaseChange"/> -->
<!-- <rule ref="category/java/errorprone.xml/UnnecessaryConversionTemporary"/> -->
<!-- <rule ref="category/java/errorprone.xml/UnusedNullCheckInEquals"/> -->
<!-- <rule ref="category/java/errorprone.xml/UseCorrectExceptionLogging"/> -->
<!-- <rule ref="category/java/errorprone.xml/UseEqualsToCompareStrings"/> -->
<!-- <rule ref="category/java/errorprone.xml/UseLocaleWithCaseConversions"/> -->
<!-- <rule ref="category/java/errorprone.xml/UseProperClassLoader"/> -->
<rule ref="category/java/errorprone.xml/UnconditionalIfStatement"/>
<rule ref="category/java/errorprone.xml/UnnecessaryBooleanAssertion"/>
<rule ref="category/java/errorprone.xml/UnnecessaryCaseChange"/>
<rule ref="category/java/errorprone.xml/UnnecessaryConversionTemporary"/>
<rule ref="category/java/errorprone.xml/UnusedNullCheckInEquals"/>
<rule ref="category/java/errorprone.xml/UseCorrectExceptionLogging"/>
<rule ref="category/java/errorprone.xml/UseEqualsToCompareStrings"/>
<rule ref="category/java/errorprone.xml/UseLocaleWithCaseConversions"/>
<rule ref="category/java/errorprone.xml/UseProperClassLoader"/>
<rule ref="category/java/errorprone.xml/UselessOperationOnImmutable"/>
<!-- multithreading.xml -->
@ -277,8 +274,8 @@
<rule ref="category/java/multithreading.xml/DoNotUseThreads"/>
<rule ref="category/java/multithreading.xml/DontCallThreadRun"/>
<rule ref="category/java/multithreading.xml/DoubleCheckedLocking"/>
<!-- <rule ref="category/java/multithreading.xml/NonThreadSafeSingleton"/> -->
<!-- <rule ref="category/java/multithreading.xml/UnsynchronizedStaticFormatter"/> -->
<rule ref="category/java/multithreading.xml/NonThreadSafeSingleton"/>
<rule ref="category/java/multithreading.xml/UnsynchronizedStaticFormatter"/>
<rule ref="category/java/multithreading.xml/UseConcurrentHashMap"/>
<rule ref="category/java/multithreading.xml/UseNotifyAllInsteadOfNotify"/>
@ -286,29 +283,21 @@
<rule ref="category/java/performance.xml/AddEmptyString"/>
<rule ref="category/java/performance.xml/AppendCharacterWithChar"/>
<!-- <rule ref="category/java/performance.xml/AvoidArrayLoops"/> -->
<!-- <rule ref="category/java/performance.xml/AvoidCalendarDateCreation"/> -->
<rule ref="category/java/performance.xml/AvoidArrayLoops"/>
<rule ref="category/java/performance.xml/AvoidCalendarDateCreation"/>
<rule ref="category/java/performance.xml/AvoidFileStream"/>
<!-- <rule ref="category/java/performance.xml/AvoidInstantiatingObjectsInLoops"/> -->
<rule ref="category/java/performance.xml/AvoidUsingShortType"/>
<!-- <rule ref="category/java/performance.xml/BigIntegerInstantiation"/> -->
<!-- <rule ref="category/java/performance.xml/BooleanInstantiation"/> -->
<rule ref="category/java/performance.xml/ByteInstantiation"/>
<rule ref="category/java/performance.xml/AvoidInstantiatingObjectsInLoops"/>
<rule ref="category/java/performance.xml/BigIntegerInstantiation"/>
<rule ref="category/java/performance.xml/ConsecutiveAppendsShouldReuse"/>
<rule ref="category/java/performance.xml/ConsecutiveLiteralAppends"/>
<rule ref="category/java/performance.xml/InefficientEmptyStringCheck"/>
<rule ref="category/java/performance.xml/InefficientStringBuffering"/>
<rule ref="category/java/performance.xml/InsufficientStringBufferDeclaration"/>
<rule ref="category/java/performance.xml/IntegerInstantiation"/>
<rule ref="category/java/performance.xml/LongInstantiation"/>
<rule ref="category/java/performance.xml/OptimizableToArrayCall"/>
<rule ref="category/java/performance.xml/RedundantFieldInitializer"/>
<rule ref="category/java/performance.xml/ShortInstantiation"/>
<rule ref="category/java/performance.xml/SimplifyStartsWith"/>
<rule ref="category/java/performance.xml/StringInstantiation"/>
<rule ref="category/java/performance.xml/StringToString"/>
<rule ref="category/java/performance.xml/TooFewBranchesForASwitchStatement"/>
<!-- <rule ref="category/java/performance.xml/UnnecessaryWrapperObjectCreation"/> -->
<rule ref="category/java/performance.xml/UseArrayListInsteadOfVector"/>
<rule ref="category/java/performance.xml/UseArraysAsList"/>
<rule ref="category/java/performance.xml/UseIOStreamsWithApacheCommonsFileItem"/>

View File

@ -8,10 +8,11 @@ xsi:noNamespaceSchemaLocation="projectlist_1_1_0.xsd">
<name>checkstyle</name>
<type>git</type>
<connection>https://github.com/checkstyle/checkstyle</connection>
<tag>checkstyle-8.10</tag>
<tag>checkstyle-9.1</tag>
<exclude-pattern>.*/target/test-classes/com/puppycrawl/tools/checkstyle/.*</exclude-pattern>
<exclude-pattern>.*/target/generated-sources/.*</exclude-pattern>
<exclude-pattern>.*/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/javaparser/InputJavaParserNoFreezeOnDeeplyNestedLambdas.java</exclude-pattern>
<build-command><![CDATA[#!/usr/bin/env bash
if test -e classpath.txt; then
@ -20,6 +21,10 @@ fi
set -e
# Make sure to use java11. This is already installed by build.sh
export JAVA_HOME=${HOME}/openjdk11
export PATH=$JAVA_HOME/bin:$PATH
mvn test-compile -B
mvn dependency:build-classpath -DincludeScope=test -Dmdep.outputFile=classpath.txt -B
]]></build-command>
@ -30,7 +35,7 @@ mvn dependency:build-classpath -DincludeScope=test -Dmdep.outputFile=classpath.t
<name>spring-framework</name>
<type>git</type>
<connection>https://github.com/spring-projects/spring-framework</connection>
<tag>v5.0.6.RELEASE</tag>
<tag>v5.3.13</tag>
<exclude-pattern>.*/build/generated-sources/.*</exclude-pattern>
@ -41,55 +46,95 @@ fi
set -e
# Note: openjdk8 will be installed by "before_install.sh"
export JAVA_HOME=${HOME}/openjdk8
# Make sure to use java11. This is already installed by build.sh
export JAVA_HOME=${HOME}/openjdk11
export PATH=$JAVA_HOME/bin:$PATH
## Patches
# keep the tabs!!
# Patch 1: See https://github.com/spring-projects/spring-framework/commit/381b7d035a16d430b8783b7390c1677c9e7d1f68
# and https://github.com/spring-projects/spring-framework/commit/9e1ed6c7718d38c4b9fe5f75921abad33264307c
(cat <<EOF
--- build.gradle 2020-11-14 09:43:51.705417551 +0000
+++ build.gradle.patched 2020-11-14 09:43:27.265215303 +0000
@@ -1,5 +1,6 @@
buildscript {
repositories {
+ mavenCentral()
maven { url "https://repo.spring.io/plugins-release" }
}
dependencies {
@@ -138,6 +139,7 @@
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java
index 37f5884e67..53022443ee 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java
@@ -539,7 +539,9 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
*/
@SuppressWarnings({"deprecation", "cast"})
protected boolean determineRequiredStatus(MergedAnnotation<?> ann) {
- return determineRequiredStatus(
+ // Cast to (AnnotationAttributes) is required. Otherwise, the :spring-beans:compileGroovy
+ // task fails in the Gradle build.
+ return determineRequiredStatus((AnnotationAttributes)
ann.asMap(mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
}
repositories {
+ mavenCentral()
maven { url "https://repo.spring.io/libs-release" }
}
EOF
) | patch --strip=1
# Patch 2: Ignore compiler warnings
(cat <<EOF
diff --git a/buildSrc/src/main/java/org/springframework/build/compile/CompilerConventionsPlugin.java b/buildSrc/src/main/java/org/springframework/build/compile/CompilerConventionsPlugin.java
index f2424c549e..b6ec8b04da 100644
--- a/buildSrc/src/main/java/org/springframework/build/compile/CompilerConventionsPlugin.java
+++ b/buildSrc/src/main/java/org/springframework/build/compile/CompilerConventionsPlugin.java
@@ -51,7 +51,7 @@ public class CompilerConventionsPlugin implements Plugin<Project> {
COMPILER_ARGS.addAll(commonCompilerArgs);
COMPILER_ARGS.addAll(Arrays.asList(
"-Xlint:varargs", "-Xlint:fallthrough", "-Xlint:rawtypes", "-Xlint:deprecation",
- "-Xlint:unchecked", "-Werror"
+ "-Xlint:unchecked"//, "-Werror"
));
TEST_COMPILER_ARGS = new ArrayList<>();
TEST_COMPILER_ARGS.addAll(commonCompilerArgs);
diff --git a/spring-beans/spring-beans.gradle b/spring-beans/spring-beans.gradle
index e3f6f73b76..48c4d9e3fb 100644
--- a/spring-beans/spring-beans.gradle
+++ b/spring-beans/spring-beans.gradle
@@ -23,7 +23,7 @@ sourceSets {
}
@@ -314,3 +316,20 @@
compileGroovy {
- options.compilerArgs += "-Werror"
+// options.compilerArgs += "-Werror"
}
// This module also builds Kotlin code and the compileKotlin task naturally depends on
EOF
) | patch --strip=1
# Patch 3: Add task createSquishClasspath
(cat <<EOF
diff --git a/build.gradle b/build.gradle
index 6021fa574d..15d29ed699 100644
--- a/build.gradle
+++ b/build.gradle
@@ -431,3 +431,19 @@ configure(rootProject) {
}
}
return version
}
+
+// see https://stackoverflow.com/questions/28986968/generate-classpath-from-all-multiproject-gradle-build-dependencies
+task createSquishClasspath {
+ doLast {
+ def dependencies = new HashSet()
+ dependencies.addAll(subprojects.configurations.compile.resolvedConfiguration.resolvedArtifacts.file.flatten())
+ dependencies.addAll(subprojects.configurations.optional.resolvedConfiguration.resolvedArtifacts.file.flatten())
+ dependencies.addAll(subprojects.configurations.testCompile.resolvedConfiguration.resolvedArtifacts.file.flatten())
+ dependencies.addAll(subprojects.configurations.testRuntime.resolvedConfiguration.resolvedArtifacts.file.flatten())
+ def dependencies = new LinkedHashSet()
+ dependencies.addAll(moduleProjects.configurations.compileClasspath.resolvedConfiguration.resolvedArtifacts.file.flatten())
+ dependencies.addAll(moduleProjects.configurations.testCompileClasspath.resolvedConfiguration.resolvedArtifacts.file.flatten())
+
+ def paths = new ArrayList()
+ paths.addAll(subprojects.jar.outputs.files.asPath)
+ paths.addAll(subprojects.sourceSets.test.output.resourcesDir)
+ paths.addAll(subprojects.sourceSets.test.output.classesDirs.files.flatten())
+ paths.addAll(moduleProjects.jar.outputs.files.asPath)
+ paths.addAll(moduleProjects.sourceSets.test.output.resourcesDir)
+ paths.addAll(moduleProjects.sourceSets.test.output.classesDirs.files.flatten())
+ paths.addAll(dependencies)
+ println paths.join(File.pathSeparator)
+ }
+}
EOF
) | patch
) | patch --strip=1
./gradlew build testClasses -x javadoc -x dokka -x asciidoctor -x test -x testNG -x api -x distZip
./gradlew createSquishClasspath -q > classpath.txt
./gradlew --console=plain --build-cache --no-daemon --max-workers=4 build testClasses -x test -x javadoc -x api -x asciidoctor -x asciidoctorPdf
./gradlew --console=plain --build-cache --no-daemon --max-workers=4 createSquishClasspath -q > classpath.txt
]]></build-command>
<auxclasspath-command>cat classpath.txt</auxclasspath-command>
</project>

View File

@ -55,9 +55,9 @@ function publish_release_documentation_github() {
cd pmd.github.io || { echo "Directory 'pmd.github.io' doesn't exist"; exit 1; }
git init
git config user.name "PMD CI (pmd-bot)"
git config user.email "andreas.dangel+pmd-bot@adangel.org"
git config user.email "pmd-bot@users.noreply.github.com"
git config core.sparsecheckout true
git remote add origin git@github.com:pmd/pmd.github.io.git
git remote add origin git@github.com-pmd.github.io:pmd/pmd.github.io.git
echo "/latest/" > .git/info/sparse-checkout
echo "/sitemap.xml" >> .git/info/sparse-checkout
git pull --depth=1 origin master
@ -65,7 +65,7 @@ function publish_release_documentation_github() {
rsync -ah --stats "../docs/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/" "pmd-${PMD_CI_MAVEN_PROJECT_VERSION}/"
git status
pmd_ci_log_debug "Executing: git add pmd-${PMD_CI_MAVEN_PROJECT_VERSION}"
git add "pmd-${PMD_CI_MAVEN_PROJECT_VERSION}"
git add --sparse "pmd-${PMD_CI_MAVEN_PROJECT_VERSION}"
pmd_ci_log_debug "Executing: git commit..."
git commit -q -m "Added pmd-${PMD_CI_MAVEN_PROJECT_VERSION}"
@ -96,7 +96,7 @@ function publish_release_documentation_github() {
function pmd_doc_publish_to_github_pages() {
echo -e "\n\n"
pmd_ci_log_info "Pushing the new site to github pages..."
git clone --branch gh-pages --depth 1 git@github.com:pmd/pmd.git pmd-gh-pages
git clone --branch gh-pages --depth 1 --origin origin https://github.com/pmd/pmd.git pmd-gh-pages
# clear the files first
rm -rf pmd-gh-pages/*
# copy the new site
@ -104,14 +104,16 @@ function pmd_doc_publish_to_github_pages() {
(
cd pmd-gh-pages || { echo "Directory 'pmd-gh-pages' doesn't exist"; exit 1; }
git config user.name "PMD CI (pmd-bot)"
git config user.email "andreas.dangel+pmd-bot@adangel.org"
git config user.email "pmd-bot@users.noreply.github.com"
git config --local http.https://github.com/.extraheader "AUTHORIZATION: basic $(echo -n "x-access-token:${GITHUB_TOKEN}"|base64)"
git add -A
MSG="Update documentation
${PMD_CI_JOB_URL}
${PMD_CI_PUSH_COMMIT_COMPARE}"
git commit -q -m "$MSG"
git push git@github.com:pmd/pmd.git HEAD:gh-pages
git push origin HEAD:gh-pages
git config --local --unset-all http.https://github.com/.extraheader
pmd_ci_log_success "Successfully pushed site to https://pmd.github.io/pmd/"
)
}

View File

@ -9,12 +9,10 @@ source "$(dirname "$0")/inc/fetch_ci_scripts.bash" && fetch_ci_scripts
# The functions here require the following environment variables:
# PMD_CI_BRANCH
#
# DANGER_GITHUB_API_TOKEN
# GITHUB_TOKEN
# PMD_CI_CHUNK_TOKEN
function regression_tester_setup_ci() {
# note: building spring needs java8. This is setup already by build.sh
gpg --batch --yes --decrypt --passphrase="GnxdjywUEPveyCD1RLiTd7t8CImnefYr" \
--output .ci/files/public-env .ci/files/public-env.gpg
# shellcheck disable=SC1091
@ -69,19 +67,21 @@ function regression_tester_uploadBaseline() {
function regression_tester_executeDanger() {
pmd_ci_log_debug "${FUNCNAME[0]}"
# Create a corresponding remote branch locally
if ! git show-ref --verify --quiet "refs/heads/${PMD_CI_BRANCH}"; then
git fetch --no-tags --depth=1 origin "+refs/heads/${PMD_CI_BRANCH}:refs/remotes/origin/${PMD_CI_BRANCH}"
git branch "${PMD_CI_BRANCH}" "origin/${PMD_CI_BRANCH}"
pmd_ci_log_debug "Created local branch ${PMD_CI_BRANCH}"
fi
# Fetch more commits of the PR for danger and regression tester
git fetch --no-tags --depth=50 origin "+$(git rev-parse HEAD^2):"
# Fetch more commits from master branch for regression tester
if [[ "${PMD_CI_BRANCH}" != "master" ]]; then
git fetch --no-tags --depth=50 origin +master:
git branch master origin/master
fi
# git clone initially only fetched with depth 2. Danger and regression tester
# need more history, so we'll fetch more here
# and create local branches as well (${PMD_CI_BRANCH} and pr-fetch)
pmd_ci_log_info "Fetching 25 commits for ${PMD_CI_BRANCH} and pull/${PMD_CI_PULL_REQUEST_NUMBER}/head"
git fetch --no-tags --depth=25 origin "${PMD_CI_BRANCH}:${PMD_CI_BRANCH}" "pull/${PMD_CI_PULL_REQUEST_NUMBER}/head:pr-fetch"
# if the PR is older, base might have advanced more than 25 commits... fetch more, up to 150
for i in $(seq 1 3); do
if [ -z "$( git merge-base "${PMD_CI_BRANCH}" "pr-fetch" )" ]; then
pmd_ci_log_info "No merge-base yet - fetching more commits... (try $i)"
git fetch --no-tags --deepen=50 origin "${PMD_CI_BRANCH}:" "pull/${PMD_CI_PULL_REQUEST_NUMBER}/head:pr-fetch"
fi
done
pmd_ci_log_info "Merge base is: $( git merge-base "${PMD_CI_BRANCH}" "pr-fetch" )"
pmd_ci_log_info "Running danger on branch ${PMD_CI_BRANCH}"
bundle exec danger --verbose

View File

@ -34,9 +34,9 @@ jobs:
~/.cache
~/work/pmd/target/repositories
vendor/bundle
key: v1-${{ runner.os }}-${{ hashFiles('**/pom.xml') }}
key: v2-${{ runner.os }}-${{ hashFiles('**/pom.xml') }}
restore-keys: |
v1-${{ runner.os }}-
v2-${{ runner.os }}-
- name: Set up Ruby 2.7
uses: ruby/setup-ruby@v1
with:
@ -46,7 +46,7 @@ jobs:
run: |
echo "LANG=en_US.UTF-8" >> $GITHUB_ENV
echo "MAVEN_OPTS=-Dmaven.wagon.httpconnectionManager.ttlSeconds=180 -Dmaven.wagon.http.retryHandler.count=3 -DautoReleaseAfterClose=true -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/14/scripts" >> $GITHUB_ENV
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/17/scripts" >> $GITHUB_ENV
- name: Check Environment
shell: bash
run: |

View File

@ -22,9 +22,10 @@ jobs:
shell: bash
run: |
echo "LANG=en_US.UTF-8" >> $GITHUB_ENV
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/14/scripts" >> $GITHUB_ENV
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/17/scripts" >> $GITHUB_ENV
- name: Sync
run: .ci/git-repo-sync.sh
shell: bash
env:
PMD_CI_SECRET_PASSPHRASE: ${{ secrets.PMD_CI_SECRET_PASSPHRASE }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -21,9 +21,9 @@ jobs:
~/.cache
~/work/pmd/target/repositories
vendor/bundle
key: v1-${{ runner.os }}-${{ hashFiles('**/pom.xml') }}
key: v2-${{ runner.os }}-${{ hashFiles('**/pom.xml') }}
restore-keys: |
v1-${{ runner.os }}-
v2-${{ runner.os }}-
- name: Set up Ruby 2.7
uses: ruby/setup-ruby@v1
with:
@ -33,7 +33,7 @@ jobs:
run: |
echo "LANG=en_US.UTF-8" >> $GITHUB_ENV
echo "MAVEN_OPTS=-Dmaven.wagon.httpconnectionManager.ttlSeconds=180 -Dmaven.wagon.http.retryHandler.count=3 -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/14/scripts" >> $GITHUB_ENV
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/17/scripts" >> $GITHUB_ENV
- name: Check Environment
shell: bash
run: |
@ -48,7 +48,7 @@ jobs:
mkdir -p .ci/inc && \
( [ -e .ci/inc/$f ] || curl -sSL "${PMD_CI_SCRIPTS_URL}/inc/$f" > ".ci/inc/$f" ) && \
source .ci/inc/$f ; \
pmd_ci_openjdk_install_adoptopenjdk 11 ; \
pmd_ci_openjdk_install_adoptium 11 ; \
pmd_ci_openjdk_setdefault 11
shell: bash
- name: Setup tmate session

3
.gitignore vendored
View File

@ -16,5 +16,8 @@ pmd-core/dependency-reduced-pom.xml
vendor
.DS_Store
# node modules for https://allcontributors.org/docs/en/cli/installation
node_modules
# rule docs are generated
docs/pages/pmd/rules

View File

@ -1,2 +1,2 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar

View File

@ -57,4 +57,20 @@ See [pmd-checkstyle-config.xml](https://github.com/pmd/build-tools/blob/master/s
[the eclipse configuration files](https://github.com/pmd/build-tools/tree/master/eclipse) that can
be imported into a fresh workspace.
## Add yourself as contributor
We use [All Contributors](https://allcontributors.org/en).
To add yourself to the table of contributors, follow the
[bot usage instructions](https://allcontributors.org/docs/en/bot/usage) ;).
Or use the CLI:
1. Install the CLI: `npm i` (in PMD's top level directory)
2. Add yourself: `npx all-contributors add <username> <contribution>`
Where `username` is your GitHub username and `contribution` is a `,`-separated list
of contributions. See [Emoji Key](https://allcontributors.org/docs/en/emoji-key) for a list
of valid types. Common types are: "code", "doc", "bug", "blog", "talk", "test", "tutorial".
See also [cli documentation](https://allcontributors.org/docs/en/cli/usage)

View File

@ -12,7 +12,7 @@ def get_args(base_branch, autogen = TRUE, patch_config = './pmd/.ci/files/all-ja
'--patch-branch', 'HEAD',
'--patch-config', patch_config,
'--mode', 'online',
autogen ? '--auto-gen-config' : '--filter-with-patch-config',
# autogen ? '--auto-gen-config' : '--filter-with-patch-config',
'--keep-reports',
'--error-recovery',
'--baseline-download-url', 'https://pmd-code.org/pmd-regression-tester/',

View File

@ -3,8 +3,8 @@ source 'https://rubygems.org/'
# bleeding edge from git
#gem 'pmdtester', :git => 'https://github.com/pmd/pmd-regression-tester.git', branch: 'master'
gem 'pmdtester', '~> 1'
gem 'danger', '~> 5.6', '>= 5.6'
gem 'pmdtester'
gem 'danger'
# This group is only needed for rendering release notes (docs/render_release_notes.rb)
# this happens during release (.ci/build.sh and do-release.sh)

View File

@ -1,7 +1,7 @@
GEM
remote: https://rubygems.org/
specs:
addressable (2.7.0)
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
claide (1.0.3)
claide-plugins (0.9.2)
@ -12,39 +12,60 @@ GEM
concurrent-ruby (1.1.9)
cork (0.3.0)
colored2 (~> 3.1)
danger (5.16.1)
danger (8.4.0)
claide (~> 1.0)
claide-plugins (>= 0.9.2)
colored2 (~> 3.1)
cork (~> 0.1)
faraday (~> 0.9)
faraday-http-cache (~> 1.0)
git (~> 1.5)
kramdown (~> 1.5)
faraday (>= 0.9.0, < 2.0)
faraday-http-cache (~> 2.0)
git (~> 1.7)
kramdown (~> 2.3)
kramdown-parser-gfm (~> 1.0)
no_proxy_fix
octokit (~> 4.7)
terminal-table (~> 1)
terminal-table (>= 1, < 4)
differ (0.1.2)
et-orbi (1.2.4)
et-orbi (1.2.5)
tzinfo
faraday (0.17.4)
faraday (1.8.0)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0.1)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.1)
faraday-patron (~> 1.0)
faraday-rack (~> 1.0)
multipart-post (>= 1.2, < 3)
faraday-http-cache (1.3.1)
faraday (~> 0.8)
fugit (1.5.0)
ruby2_keywords (>= 0.0.4)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-http-cache (2.2.0)
faraday (>= 0.8)
faraday-httpclient (1.0.1)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
fugit (1.5.2)
et-orbi (~> 1.1, >= 1.1.8)
raabro (~> 1.4)
git (1.8.1)
git (1.9.1)
rchardet (~> 1.8)
kramdown (1.17.0)
liquid (5.0.1)
kramdown (2.3.1)
rexml
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
liquid (5.1.0)
logger-colors (1.0.0)
mini_portile2 (2.5.3)
mini_portile2 (2.6.1)
multipart-post (2.1.1)
nap (1.1.0)
no_proxy_fix (0.1.2)
nokogiri (1.11.7)
mini_portile2 (~> 2.5.0)
nokogiri (1.12.5)
mini_portile2 (~> 2.6.1)
racc (~> 1.4)
octokit (4.21.0)
faraday (>= 0.9)
@ -61,27 +82,29 @@ GEM
raabro (1.4.0)
racc (1.5.2)
rchardet (1.8.0)
rouge (3.26.0)
rufus-scheduler (3.7.0)
rexml (3.2.5)
rouge (3.26.1)
ruby2_keywords (0.0.5)
rufus-scheduler (3.8.0)
fugit (~> 1.1, >= 1.1.6)
safe_yaml (1.0.5)
sawyer (0.8.2)
addressable (>= 2.3.5)
faraday (> 0.8, < 2.0)
slop (4.9.1)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
unicode-display_width (1.7.0)
unicode-display_width (2.1.0)
PLATFORMS
ruby
DEPENDENCIES
danger (~> 5.6, >= 5.6)
danger
liquid (>= 4.0.0)
pmdtester (~> 1)
pmdtester
rouge (>= 1.7, < 4)
safe_yaml (>= 1.0)

View File

@ -1,4 +1,4 @@
# PMD
# PMD - source code analyzer
![PMD Logo](https://raw.githubusercontent.com/pmd/pmd/pmd/7.0.x/docs/images/logo/pmd-logo-300px.png)
@ -9,18 +9,42 @@
[![Coverage Status](https://coveralls.io/repos/github/pmd/pmd/badge.svg)](https://coveralls.io/github/pmd/pmd)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/a674ee8642ed44c6ba7633626ee95967)](https://www.codacy.com/app/pmd/pmd?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=pmd/pmd&amp;utm_campaign=Badge_Grade)
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](code_of_conduct.md)
## About
[![Documentation (latest)](https://img.shields.io/badge/docs-latest-green)](https://pmd.github.io/latest/)
**PMD** is a source code analyzer. It finds common programming flaws like unused variables, empty catch blocks,
unnecessary object creation, and so forth. It supports Java, JavaScript, Salesforce.com Apex and Visualforce,
unnecessary object creation, and so forth. It supports many languages. It can be extended with custom rules.
It uses JavaCC and Antlr to parse source files into abstract syntax trees (AST) and runs rules against them to find violations.
Rules can be written in Java or using a XPath query.
It supports Java, JavaScript, Salesforce.com Apex and Visualforce,
Modelica, PLSQL, Apache Velocity, XML, XSL, Scala.
Additionally it includes **CPD**, the copy-paste-detector. CPD finds duplicated code in
C/C++, C#, Dart, Fortran, Go, Groovy, Java, JavaScript, JSP, Kotlin, Lua, Matlab, Modelica,
Objective-C, Perl, PHP, PLSQL, Python, Ruby, Salesforce.com Apex, Scala, Swift, Visualforce and XML.
## Support
In the future we hope to add support for data/control flow analysis and automatic (quick) fixes where
it makes sense.
## 🚀 Installation and Usage
Download the latest binary zip from the [releases](https://github.com/pmd/pmd/releases/latest)
and extract it somewhere.
Execute `bin/run.sh pmd` or `bin\pmd.bat`.
See also [Getting Started](https://pmd.github.io/latest/pmd_userdocs_installation.html)
**Demo:**
This shows how PMD can detect for loops, that can be replaced by for-each loops.
![Demo](docs/images/userdocs/pmd-demo.gif)
There are plugins for Maven and Gradle as well as for various IDEs.
See [Tools / Integrations](https://pmd.github.io/latest/pmd_userdocs_tools.html)
## How to get support?
* How do I? -- Ask a question on [StackOverflow](https://stackoverflow.com/questions/tagged/pmd)
or on [discussions](https://github.com/pmd/pmd/discussions).
@ -31,7 +55,9 @@ Objective-C, Perl, PHP, PLSQL, Python, Ruby, Salesforce.com Apex, Scala, Swift,
* I have a quick question -- ask on our [Gitter chat](https://gitter.im/pmd/pmd).
* Where's your documentation? -- <https://pmd.github.io/latest/>
## Source
## 🤝 Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Our latest source of PMD can be found on [GitHub](https://github.com/pmd/pmd). Fork us!
@ -42,6 +68,17 @@ The rule designer is developed over at [pmd/pmd-designer](https://github.com/pmd
Please see [its README](https://github.com/pmd/pmd-designer#contributing) for
developer documentation.
## Website
## 💵 Financial Contributors
More information can be found on our [Website](https://pmd.github.io).
Become a financial contributor and help us sustain our community. [Contribute](https://opencollective.com/pmd/contribute)
## ✨ Contributors
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification.
Contributions of any kind welcome!
See [credits](docs/pages/pmd/projectdocs/credits.md) for the complete list.
## 📝 License
[BSD Style](LICENSE)

View File

@ -103,7 +103,7 @@ read -r
STATS=$(
echo "### Stats"
echo "* $(git log pmd_releases/"${LAST_VERSION}"..HEAD --oneline --no-merges |wc -l) commits"
echo "* $(curl -s https://api.github.com/repos/pmd/pmd/milestones|jq ".[] | select(.title == \"$RELEASE_VERSION\") | .closed_issues") closed tickets & PRs"
echo "* $(curl -s "https://api.github.com/repos/pmd/pmd/milestones?state=all&direction=desc&per_page=5"|jq ".[] | select(.title == \"$RELEASE_VERSION\") | .closed_issues") closed tickets & PRs"
echo "* Days since last release: $(( ( $(date +%s) - $(git log --max-count=1 --format="%at" pmd_releases/"${LAST_VERSION}") ) / 86400))"
)
@ -221,7 +221,7 @@ This is a {{ site.pmd.release_type }} release.
EOF
git commit -a -m "Prepare next development version"
git commit -a -m "Prepare next development version [skip ci]"
git push origin "${CURRENT_BRANCH}"
./mvnw -B release:clean
echo
@ -245,8 +245,8 @@ tweet="${tweet// /%20}"
tweet="${tweet//:/%3A}"
tweet="${tweet//#/%23}"
tweet="${tweet//\//%2F}"
tweet="${tweet//$'\r'//}"
tweet="${tweet//$'\n'//%0A}"
tweet="${tweet//$'\r'/}"
tweet="${tweet//$'\n'/%0A}"
echo "* Tweet about this release on https://twitter.com/pmd_analyzer:"
echo " <https://twitter.com/intent/tweet?text=$tweet>"
echo

View File

@ -1,13 +1,13 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (6.0.3.7)
activesupport (6.0.4.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
zeitwerk (~> 2.2, >= 2.2.2)
addressable (2.7.0)
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
coffee-script (2.4.1)
coffee-script-source
@ -16,8 +16,8 @@ GEM
colorator (1.1.0)
commonmarker (0.17.13)
ruby-enum (~> 0.5)
concurrent-ruby (1.1.8)
dnsruby (1.61.5)
concurrent-ruby (1.1.9)
dnsruby (1.61.7)
simpleidn (~> 0.1)
em-websocket (0.5.2)
eventmachine (>= 0.12.9)
@ -26,20 +26,30 @@ GEM
ffi (>= 1.15.0)
eventmachine (1.2.7)
execjs (2.8.1)
faraday (1.4.1)
faraday (1.8.0)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0.1)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.1)
faraday-patron (~> 1.0)
faraday-rack (~> 1.0)
multipart-post (>= 1.2, < 3)
ruby2_keywords (>= 0.0.4)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.1.0)
ffi (1.15.0)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
ffi (1.15.4)
forwardable-extended (2.6.0)
gemoji (3.0.1)
github-pages (214)
github-pages-health-check (= 1.17.0)
github-pages (219)
github-pages-health-check (= 1.17.7)
jekyll (= 3.9.0)
jekyll-avatar (= 0.7.0)
jekyll-coffeescript (= 1.1.1)
@ -59,19 +69,19 @@ GEM
jekyll-seo-tag (= 2.7.1)
jekyll-sitemap (= 1.4.0)
jekyll-swiss (= 1.0.0)
jekyll-theme-architect (= 0.1.1)
jekyll-theme-cayman (= 0.1.1)
jekyll-theme-dinky (= 0.1.1)
jekyll-theme-hacker (= 0.1.2)
jekyll-theme-leap-day (= 0.1.1)
jekyll-theme-merlot (= 0.1.1)
jekyll-theme-midnight (= 0.1.1)
jekyll-theme-minimal (= 0.1.1)
jekyll-theme-modernist (= 0.1.1)
jekyll-theme-primer (= 0.5.4)
jekyll-theme-slate (= 0.1.1)
jekyll-theme-tactile (= 0.1.1)
jekyll-theme-time-machine (= 0.1.1)
jekyll-theme-architect (= 0.2.0)
jekyll-theme-cayman (= 0.2.0)
jekyll-theme-dinky (= 0.2.0)
jekyll-theme-hacker (= 0.2.0)
jekyll-theme-leap-day (= 0.2.0)
jekyll-theme-merlot (= 0.2.0)
jekyll-theme-midnight (= 0.2.0)
jekyll-theme-minimal (= 0.2.0)
jekyll-theme-modernist (= 0.2.0)
jekyll-theme-primer (= 0.6.0)
jekyll-theme-slate (= 0.2.0)
jekyll-theme-tactile (= 0.2.0)
jekyll-theme-time-machine (= 0.2.0)
jekyll-titles-from-headings (= 0.5.3)
jemoji (= 0.12.0)
kramdown (= 2.3.1)
@ -82,11 +92,11 @@ GEM
nokogiri (>= 1.10.4, < 2.0)
rouge (= 3.26.0)
terminal-table (~> 1.4)
github-pages-health-check (1.17.0)
github-pages-health-check (1.17.7)
addressable (~> 2.3)
dnsruby (~> 1.60)
octokit (~> 4.0)
public_suffix (>= 2.0.2, < 5.0)
public_suffix (>= 3.0, < 5.0)
typhoeus (~> 1.3)
html-pipeline (2.14.0)
activesupport (>= 2)
@ -152,45 +162,45 @@ GEM
jekyll-sitemap (1.4.0)
jekyll (>= 3.7, < 5.0)
jekyll-swiss (1.0.0)
jekyll-theme-architect (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-cayman (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-dinky (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-hacker (0.1.2)
jekyll-theme-architect (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-leap-day (0.1.1)
jekyll (~> 3.5)
jekyll-theme-cayman (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-merlot (0.1.1)
jekyll (~> 3.5)
jekyll-theme-dinky (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-midnight (0.1.1)
jekyll (~> 3.5)
jekyll-theme-hacker (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-minimal (0.1.1)
jekyll (~> 3.5)
jekyll-theme-leap-day (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-modernist (0.1.1)
jekyll (~> 3.5)
jekyll-theme-merlot (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-primer (0.5.4)
jekyll-theme-midnight (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-minimal (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-modernist (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-primer (0.6.0)
jekyll (> 3.5, < 5.0)
jekyll-github-metadata (~> 2.9)
jekyll-seo-tag (~> 2.0)
jekyll-theme-slate (0.1.1)
jekyll (~> 3.5)
jekyll-theme-slate (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-tactile (0.1.1)
jekyll (~> 3.5)
jekyll-theme-tactile (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-time-machine (0.1.1)
jekyll (~> 3.5)
jekyll-theme-time-machine (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-titles-from-headings (0.5.3)
jekyll (>= 3.3, < 5.0)
@ -205,19 +215,19 @@ GEM
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
liquid (4.0.3)
listen (3.5.1)
listen (3.7.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6)
mini_portile2 (2.5.1)
mini_portile2 (2.6.1)
minima (2.5.1)
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.14.4)
multipart-post (2.1.1)
nokogiri (1.11.5)
mini_portile2 (~> 2.5.0)
nokogiri (1.12.5)
mini_portile2 (~> 2.6.1)
racc (~> 1.4)
octokit (4.21.0)
faraday (>= 0.9)
@ -233,8 +243,8 @@ GEM
rouge (3.26.0)
ruby-enum (0.9.0)
i18n
ruby2_keywords (0.0.4)
rubyzip (2.3.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
safe_yaml (1.0.5)
sass (3.7.4)
sass-listen (~> 4.0.0)
@ -255,8 +265,8 @@ GEM
thread_safe (~> 0.1)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.7)
unicode-display_width (1.7.0)
unf_ext (0.0.8)
unicode-display_width (1.8.0)
zeitwerk (2.4.2)
PLATFORMS

View File

@ -2,8 +2,8 @@ repository: pmd/pmd
pmd:
version: 7.0.0-SNAPSHOT
previous_version: 6.36.0
date: ??-?????-2021
previous_version: 6.41.0
date: ??-?????-2022
release_type: major
# release types: major, minor, bugfix

View File

@ -364,6 +364,9 @@ entries:
- title: PLSQL
url: /pmd_languages_plsql.html
output: web, pdf
- title: Visualforce
url: /pmd_languages_visualforce.html
output: web, pdf
- title: Developer Documentation
output: web, pdf
folderitems:
@ -397,8 +400,14 @@ entries:
- title: Major contributions
output: web, pdf
subfolderitems:
- title: Adding a new language
url: /pmd_devdocs_major_adding_new_language.html
- title: Rule Guidelines
url: /pmd_devdocs_major_rule_guidelines.html
output: web, pdf
- title: Adding a new language (JavaCC)
url: /pmd_devdocs_major_adding_new_language_javacc.html
output: web, pdf
- title: Adding a new language (Antlr)
url: /pmd_devdocs_major_adding_new_language_antlr.html
output: web, pdf
- title: Adding a new CPD language
url: /pmd_devdocs_major_adding_new_cpd_language.html

View File

@ -10,6 +10,22 @@ aliases:
- &needs_typenode "The context node must be a {% jdoc jast::TypeNode %}"
langs:
- name: "Any language"
ns: "pmd"
funs:
- name: fileName
returnType: "xs:string"
shortDescription: "Returns the current filename"
description: "Returns the current simple filename without path but including the extension.
This can be used to write rules that check filename naming conventions.
<p>This function is available since PMD 6.38.0.</p>"
notes: "The function can be called on any node."
examples:
- code: "//b[pmd:fileName() = 'Foo.xml']"
outcome: "Matches any `&lt;b&gt;` tags in files called `Foo.xml`."
- name: "Java"
ns: "pmd-java"
funs:

View File

@ -1098,3 +1098,8 @@ h4.panel-title {
padding-top: 0px;
margin-top: 0px;
}
.post-content .all-contributors-list img {
width: 100px;
height: 100px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 953 KiB

View File

@ -19,7 +19,7 @@ additional_js:
## Overview
## 💡 Overview
<!-- You can link to an individual panel, the id is determined from the title of the panel -->
<!-- See custom/shuffle_panel.html for the details -->
@ -45,18 +45,24 @@ things, PMD can be run:
**CPD**, the **copy-paste detector**, is also distributed with PMD. You can also use it
in a variety of ways, which are [documented here](pmd_userdocs_cpd.html).
## Download
## 💾 Download
The latest release of PMD can be downloaded from our [Github releases page](https://github.com/pmd/pmd/releases/latest).
The Logo is available from the [Logo Project Page](pmd_projectdocs_logo.html).
## Documentation
## 📖 Documentation
The rest of this page exposes the contents of the documentation site thematically,
which you can further scope down using the blue filter buttons. To navigate the site,
you may also use the search bar in the top right, or the sidebar on the left.
## ✨ Contributors
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification.
Contributions of any kind welcome!
See [credits](pmd_projectdocs_credits.html) for the complete list.
<br/>

View File

@ -74,8 +74,15 @@ The default version is always ES6.
#### New Rules
##### Apex
* The Apex rule {% rule "apex/design/UnusedMethod" %} finds unused methods in your code.
##### Java
* {% rule "java/codestyle/UnnecessaryBoxing" %} reports boxing and unboxing
conversions that may be made implicit.
#### Changed Rules
##### Java
@ -89,32 +96,57 @@ The default version is always ES6.
reading and understanding the expressions.
* {% rule "java/bestpractices/LooseCoupling" %}: the rule has a new property to allow some types to be coupled to (`allowedTypes`).
* {% rule "java/errorprone/EmptyCatchBlock" %}: `CloneNotSupportedException` and `InterruptedException` are not special-cased anymore. Rename the exception parameter to `ignored` to ignore them.
* {% rule "java/errorprone/DontImportSun" %}: `sun.misc.Signal` is not special-cased anymore.
* {% rule "java/codestyle/UseDiamondOperator" %}: the property `java7Compatibility` is removed. The rule now handles Java 7
properly without a property.
* {% rule "java/design/SingularField" %}: Properties `checkInnerClasses` and `disallowNotAssignment` are removed. The rule is now more precise and will check these cases properly.
* {% rule "java/design/UseUtilityClass" %}: The property `ignoredAnnotations` has been removed.
#### Deprecated Rules
#### Removed Rules
The following previously deprecated rules have been finally removed:
* AbstractNaming (java-codestyle)
* AvoidFinalLocalVariable (java-codestyle)
* AvoidPrefixingMethodParameters (java-codestyle)
* DataflowAnomalyAnalysis (java-errorprone)
* ForLoopsMustUseBraces (java-codestyle)
* IfElseStmtsMustUseBraces (java-codestyle)
* IfStmtsMustUseBraces (java-codestyle)
* AbstractNaming (java-codestyle) -> use {% rule "java/codestyle/ClassNamingConventions" %}
* AvoidFinalLocalVariable (java-codestyle) -> not replaced
* AvoidPrefixingMethodParameters (java-codestyle) -> use {% rule "java/codestyle/FormalParameterNamingConventions" %}
* AvoidUsingShortType (java-performance) -> not replaced
* BadComparison (java-errorprone) -> use {% rule "java/errorprone/ComparisonWithNaN" %}
* BooleanInstantiation (java-performance) -> use {% rule "java/codestyle/UnnecessaryBoxing" %} and {% rule "java/bestpractices/PrimitiveWrapperInstantiation" %}
* ByteInstantiation (java-performance) -> use {% rule "java/codestyle/UnnecessaryBoxing" %} and {% rule "java/bestpractices/PrimitiveWrapperInstantiation" %}
* CloneThrowsCloneNotSupportedException (java-errorprone) -> not replaced
* DataflowAnomalyAnalysis (java-errorprone) -> not replaced
* DefaultPackage (java-codestyle) -> use {% rule "java/codestyle/CommentDefaultAccessModifier" %}
* DoNotCallSystemExit (java-errorprone) -> use {% rule "java/errorprone/DoNotTerminateVM" %}
* ForLoopsMustUseBraces (java-codestyle) -> use {% rule "java/codestyle/ControlStatementBraces" %}
* IfElseStmtsMustUseBraces (java-codestyle) -> use {% rule "java/codestyle/ControlStatementBraces" %}
* IfStmtsMustUseBraces (java-codestyle) -> use {% rule "java/codestyle/ControlStatementBraces" %}
* IntegerInstantiation (java-performance) -> use {% rule "java/codestyle/UnnecessaryBoxing" %} and {% rule "java/bestpractices/PrimitiveWrapperInstantiation" %}
* InvalidSlf4jMessageFormat (java-errorprone) -> use {% rule "java/errorprone/InvalidLogMessageFormat" %}
* LoggerIsNotStaticFinal (java-errorprone)
* MIsLeadingVariableName (java-codestyle)
* ModifiedCyclomaticComplexity (java-design)
* PositionLiteralsFirstInCaseInsensitiveComparisons (java-bestpractices)
* PositionLiteralsFirstInComparisons (java-bestpractices)
* StdCyclomaticComplexity (java-design)
* LongInstantiation (java-performance) -> use {% rule "java/codestyle/UnnecessaryBoxing" %} and {% rule "java/bestpractices/PrimitiveWrapperInstantiation" %}
* MIsLeadingVariableName (java-codestyle) -> use {% rule "java/codestyle/FieldNamingConventions" %}
* MissingBreakInSwitch (java-errorprone) -> use {% rule "java/errorprone/ImplicitSwitchFallThrough" %}
* ModifiedCyclomaticComplexity (java-design) -> use {% rule "java/design/CyclomaticComplexity" %}
* PositionLiteralsFirstInCaseInsensitiveComparisons (java-bestpractices) -> use {% rule "java/bestpractices/LiteralsFirstInComparisons" %}
* PositionLiteralsFirstInComparisons (java-bestpractices) -> use {% rule "java/bestpractices/LiteralsFirstInComparisons" %}
* ReturnEmptyArrayRatherThanNull (java-errorprone) -> use {% rule "java/errorprone/ReturnEmptyCollectionRatherThanNull" %}
* ShortInstantiation (java-performance) -> use {% rule "java/codestyle/UnnecessaryBoxing" %} and {% rule "java/bestpractices/PrimitiveWrapperInstantiation" %}
* SimplifyBooleanAssertion (java-design) -> use {% rule "java/bestpractices/SimplifiableTestAssertion" %}
* SimplifyStartsWith (java-performance) -> not replaced
* StdCyclomaticComplexity (java-design) -> use {% rule "java/design/CyclomaticComplexity" %}
* SuspiciousConstantFieldName (java-codestyle)
* UnnecessaryWrapperObjectCreation (java-performance) -> use the new rule {% rule "java/codestyle/UnnecessaryBoxing" %}
* UnsynchronizedStaticDateFormatter (java-multithreading)
* UseAssertEqualsInsteadOfAssertTrue (java-bestpractices) -> use {% rule "java/bestpractices/SimplifiableTestAssertion" %}
* UseAssertNullInsteadOfAssertEquals (java-bestpractices) -> use {% rule "java/bestpractices/SimplifiableTestAssertion" %}
* UseAssertSameInsteadOfAssertEquals (java-bestpractices) -> use {% rule "java/bestpractices/SimplifiableTestAssertion" %}
* UseAssertTrueInsteadOfAssertEquals (java-bestpractices) -> use {% rule "java/bestpractices/SimplifiableTestAssertion" %}
* VariableNamingConventions (apex-codestyle)
* VariableNamingConventions (java-codestyle)
* WhileLoopsMustUseBraces (java-codestyle)
* VariableNamingConventions (java-codestyle) -> use {% rule "java/codestyle/FieldNamingConventions" %} and such
* WhileLoopsMustUseBraces (java-codestyle) -> use {% rule "java/codestyle/ControlStatementBraces" %}
### Fixed Issues
@ -165,6 +197,8 @@ The following previously deprecated rules have been finally removed:
* [#3218](https://github.com/pmd/pmd/pull/3218): \[java] Generalize UnnecessaryCast to flag all unnecessary casts
* [#3221](https://github.com/pmd/pmd/issues/3221): \[java] PrematureDeclaration false positive for unused variables
* [#3238](https://github.com/pmd/pmd/issues/3238): \[java] Improve ExprContext, fix FNs of UnnecessaryCast
* java-design
* [#2536](https://github.com/pmd/pmd/issues/2536): \[java] ClassWithOnlyPrivateConstructorsShouldBeFinal can't detect inner class
* java-errorprone
* [#659](https://github.com/pmd/pmd/issues/659): \[java] MissingBreakInSwitch - last default case does not contain a break
* [#1005](https://github.com/pmd/pmd/issues/1005): \[java] CloneMethodMustImplementCloneable triggers for interfaces
@ -175,6 +209,9 @@ The following previously deprecated rules have been finally removed:
* [#2880](https://github.com/pmd/pmd/issues/2880): \[java] CompareObjectsWithEquals - false negative with type res
* [#2894](https://github.com/pmd/pmd/issues/2894): \[java] Improve MissingBreakInSwitch
* [#3071](https://github.com/pmd/pmd/issues/3071): \[java] BrokenNullCheck FP with PMD 6.30.0
* [#3087](https://github.com/pmd/pmd/issues/3087): \[java] UnnecessaryBooleanAssertion overlaps with SimplifiableTestAssertion
* [#3100](https://github.com/pmd/pmd/issues/3100): \[java] UseCorrectExceptionLogging FP in 6.31.0
* [#3173](https://github.com/pmd/pmd/issues/3173): \[java] UseProperClassLoader false positive
* [#3351](https://github.com/pmd/pmd/issues/3351): \[java] ConstructorCallsOverridableMethod ignores abstract methods
* java-multithreading
* [#2537](https://github.com/pmd/pmd/issues/2537): \[java] DontCallThreadRun can't detect the case that call run() in `this.run()`
@ -225,7 +262,8 @@ The metrics framework has been made simpler and more general.
* [#1658](https://github.com/pmd/pmd/pull/1658): \[core] Node support for Antlr-based languages - [Matías Fraga](https://github.com/matifraga)
* [#1698](https://github.com/pmd/pmd/pull/1698): \[core] [swift] Antlr Base Parser adapter and Swift Implementation - [Lucas Soncini](https://github.com/lsoncini)
* [#1774](https://github.com/pmd/pmd/pull/1774): \[core] Antlr visitor rules - [Lucas Soncini](https://github.com/lsoncini)
* [#1877](https://github.com/pmd/pmd/pull/1877): \[swift] Feature/swift rules - [Matias Fraga](https://github.com/matifraga)
* [#1877](https://github.com/pmd/pmd/pull/1877): \[swift] Feature/swift rules - [Matías Fraga](https://github.com/matifraga)
* [#1881](https://github.com/pmd/pmd/pull/1881): \[doc] Add ANTLR documentation - [Matías Fraga](https://github.com/matifraga)
* [#1882](https://github.com/pmd/pmd/pull/1882): \[swift] UnavailableFunction Swift rule - [Tomás de Lucca](https://github.com/tomidelucca)
* [#2830](https://github.com/pmd/pmd/pull/2830): \[apex] Apexlink POC - [Kevin Jones](https://github.com/nawforce)

View File

@ -246,6 +246,103 @@ the breaking API changes will be performed in 7.0.0.
an API is tagged as `@Deprecated` or not in the latest minor release. During the development of 7.0.0,
we may decide to remove some APIs that were not tagged as deprecated, though we'll try to avoid it." %}
#### 6.41.0
##### Command Line Interface
The command line options for PMD and CPD now use GNU-syle long options format. E.g. instead of `-rulesets` the
preferred usage is now `--rulesets`. Alternatively one can still use the short option `-R`.
Some options also have been renamed to a more consistent casing pattern at the same time
(`--fail-on-violation` instead of `-failOnViolation`).
The old single-dash options are still supported but are deprecated and will be removed with PMD 7.
This change makes the command line interface more consistent within PMD and also less surprising
compared to other cli tools.
The changes in detail for PMD:
|old option |new option|
|-------------------------------|----------|
| `-rulesets` | `--rulesets` (or `-R`) |
| `-uri` | `--uri` |
| `-dir` | `--dir` (or `-d`) |
| `-filelist` | `--file-list` |
| `-ignorelist` | `--ignore-list` |
| `-format` | `--format` (or `-f`) |
| `-debug` | `--debug` |
| `-verbose` | `--verbose` |
| `-help` | `--help` |
| `-encoding` | `--encoding` |
| `-threads` | `--threads` |
| `-benchmark` | `--benchmark` |
| `-stress` | `--stress` |
| `-shortnames` | `--short-names` |
| `-showsuppressed` | `--show-suppressed` |
| `-suppressmarker` | `--suppress-marker` |
| `-minimumpriority` | `--minimum-priority` |
| `-property` | `--property` |
| `-reportfile` | `--report-file` |
| `-force-language` | `--force-language` |
| `-auxclasspath` | `--aux-classpath` |
| `-failOnViolation` | `--fail-on-violation` |
| `--failOnViolation` | `--fail-on-violation` |
| `-norulesetcompatibility` | `--no-ruleset-compatibility` |
| `-cache` | `--cache` |
| `-no-cache` | `--no-cache` |
The changes in detail for CPD:
|old option |new option|
|-----------------------|----------|
| `--failOnViolation` | `--fail-on-violation` |
| `-failOnViolation` | `--fail-on-violation` |
| `--filelist` | `--file-list` |
#### 6.40.0
##### Experimental APIs
* The interface {% jdoc apex::lang.apex.ast.ASTCommentContainer %} has been added to the Apex AST.
It provides a way to check whether a node contains at least one comment. Currently this is only implemented for
{% jdoc apex::lang.apex.ast.ASTCatchBlockStatement %} and used by the rule
{% rule apex/errorprone/EmptyCatchBlock %}.
This information is also available via XPath attribute `@ContainsComment`.
#### 6.39.0
No changes.
#### 6.38.0
No changes.
#### 6.37.0
##### PMD CLI
* PMD has a new CLI option `-force-language`. With that a language can be forced to be used for all input files,
irrespective of filenames. When using this option, the automatic language selection by extension is disabled
and all files are tried to be parsed with the given language. Parsing errors are ignored and unparsable files
are skipped.
This option allows to use the xml language for files, that don't use xml as extension.
See also the examples on [PMD CLI reference](pmd_userdocs_cli_reference.html#analyze-other-xml-formats).
##### Experimental APIs
* The AST types and APIs around Sealed Classes are not experimental anymore:
* {% jdoc !!java::lang.java.ast.ASTClassOrInterfaceDeclaration#isSealed() %},
{% jdoc !!java::lang.java.ast.ASTClassOrInterfaceDeclaration#isNonSealed() %},
{% jdoc !!java::lang.java.ast.ASTClassOrInterfaceDeclaration#getPermittedSubclasses() %}
* {% jdoc java::lang.java.ast.ASTPermitsList %}
##### Internal API
Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0.
You can identify them with the `@InternalApi` annotation. You'll also get a deprecation warning.
* The inner class {% jdoc !!core::cpd.TokenEntry.State %} is considered to be internal API.
It will probably be moved away with PMD 7.
#### 6.36.0
No changes.
@ -1324,9 +1421,36 @@ large projects, with many duplications, it was causing `OutOfMemoryError`s (see
is deprecated in favour of {% rule "java/bestpractices/UnusedAssignment" %} (`java-bestpractices`),
which was introduced in PMD 6.26.0.
* The java rule {% rule "java/codestyle/DefaultPackage" %} has been deprecated in favor of
* The java rule `DefaultPackage` (java-codestyle) has been deprecated in favor of
{% rule "java/codestyle/CommentDefaultAccessModifier" %}.
* The Java rule {% rule "java/errorprone/CloneThrowsCloneNotSupportedException" %} has been deprecated without
* The Java rule `CloneThrowsCloneNotSupportedException` (java-errorprone) has been deprecated without
replacement.
* The following Java rules are deprecated and removed from the quickstart ruleset,
as the new rule {% rule java/bestpractices/SimplifiableTestAssertion %} merges
their functionality:
* `UseAssertEqualsInsteadOfAssertTrue` (java-bestpractices)
* `UseAssertNullInsteadOfAssertTrue` (java-bestpractices)
* `UseAssertSameInsteadOfAssertTrue` (java-bestpractices)
* `UseAssertTrueInsteadOfAssertEquals` (java-bestpractices)
* `SimplifyBooleanAssertion` (java-design)
* The Java rule `ReturnEmptyArrayRatherThanNull` (java-errorprone) is deprecated and removed from
the quickstart ruleset, as the new rule {% rule java/errorprone/ReturnEmptyCollectionRatherThanNull %}
supersedes it.
* The following Java rules are deprecated and removed from the quickstart ruleset,
as the new rule {% rule java/bestpractices/PrimitiveWrapperInstantiation %} merges
their functionality:
* java/performance/BooleanInstantiation
* java/performance/ByteInstantiation
* java/performance/IntegerInstantiation
* java/performance/LongInstantiation
* java/performance/ShortInstantiation
* The Java rule java/performance/UnnecessaryWrapperObjectCreation is deprecated
with no planned replacement before PMD 7. In it's current state, the rule is not useful
as it finds only contrived cases of creating a primitive wrapper and unboxing it explicitly
in the same expression. In PMD 7 this and more cases will be covered by a
new rule `UnnecessaryBoxing`.

View File

@ -0,0 +1,156 @@
---
title: Adding PMD support for a new ANTLR grammar based language
short_title: Adding a new language with ANTLR
tags: [devdocs, extending]
summary: "How to add a new language to PMD using ANTLR grammar."
last_updated: July 21, 2019
sidebar: pmd_sidebar
permalink: pmd_devdocs_major_adding_new_language_antlr.html
folder: pmd/devdocs
# needs to be changed to branch master instead of pmd/7.0.x
# https://github.com/pmd/pmd/blob/pmd/7.0.x -> https://github.com/pmd/pmd/blob/master
---
## 1. Start with a new sub-module.
* See pmd-swift for examples.
## 2. Implement an AST parser for your language
* ANTLR will generate the parser for you based on the grammar file. The grammar file needs to be placed in the
folder `src/main/antlr4` in the appropriate sub package `ast` of the language. E.g. for swift, the grammar
file is [Swift.g4](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4)
and is placed in the package `net.sourceforge.pmd.lang.swift.ast`.
## 3. Create AST node classes
* The individual AST nodes are generated, but you need to define the common interface for them.
* You need a need to define the supertype interface for all nodes of the language. For that, we provide
[`AntlrNode`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrNode.java).
* See [`SwiftNode`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftNode.java)
as an example.
* Additionally, you need several base classes:
* a language specific inner node - these nodes represent the production rules from the grammar.
In Antlr, they are called "ParserRuleContext". We call them "InnerNode". Use the
base class from pmd-core
[`BaseAntlrInnerNode`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrInnerNode.java)
. And example is [`SwiftInnerNode`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftInnerNode.java).
* a language specific root node - this provides the root of the AST and our parser will return
subtypes of this node. The root node itself is a "InnerNode".
See [`SwiftRootNode`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftRootNode.java).
* a language specific terminal node.
See [`SwiftTerminalNode`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftTerminalNode.java).
* a language specific error node.
See [`SwiftErrorNode`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftErrorNode.java).
* In order for the generated code to match and use our custom classes, we have a common ant script, that fiddles with
the generated code. The ant script is [`antlr4-wrapper.xml`](https://github.com/pmd/pmd/blob/pmd/7.0.x/antlr4-wrapper.xml) and
does not need to be adjusted - it has plenty of parameters to set. The ant script is added in the
language module's `pom.xml` where the parameters are set (e.g. name of root name class). Have a look at
Swift's example: [`pmd-swift/pom.xml`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/pom.xml).
* You can add additional methods in your "InnerNode" (e.g. `SwiftInnerNode`) that are available on all nodes.
But on most cases you won't need to do anything.
## 4. Generate your parser
* Make sure, you have the property `<antlr4.visitor>true</antlr4.visitor>` in your `pom.xml` file.
* This is just a matter of building the language module. ANTLR is called via ant, and this step is added
to the phase `generate-sources`. So you can just call e.g. `./mvnw generate-source -pl pmd-swift` to
have the parser generated.
* The generated code will be placed under `target/generated-sources/antlr4` and will not be committed to
source control.
* You should review the [swift pom](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/pom.xml).
## 5. Create a TokenManager
* This is needed to support CPD (copy paste detection)
* We provide a default implementation using [`AntlrTokenManager`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java).
* You must create your own "AntlrTokenizer" such as we do with
[`SwiftTokenizer`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java).
* If you wish to filter specific tokens (e.g. comments to support CPD suppression via "CPD-OFF" and "CPD-ON")
you can create your own implementation of
[`AntlrTokenFilter`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/AntlrTokenFilter.java).
You'll need to override then the protected method `getTokenFilter(AntlrTokenManager)`
and return your custom filter. See the tokenizer for C# as an exmaple:
[`CsTokenizer`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java).
If you don't need a custom token filter, you don't need to override the method. It returns the default
`AntlrTokenFilter` which doesn't filter anything.
## 6. Create a PMD parser “adapter”
* Create your own parser, that adapts the ANLTR interface to PMD's parser interface.
* We provide a [`AntlrBaseParser`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseParser.java)
implementation that you need to extend to create your own adapter as we do with
[`PmdSwiftParser`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/PmdSwiftParser.java).
## 7. Create a rule violation factory
* This is an optional step. Most like, the default implementation will do what you need.
The default implementation is [`DefaultRuleViolationFactory`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/impl/DefaultRuleViolationFactory.java).
* The purpose of a rule violation factory is to create a rule violation instance for your handler (spoiler).
In case you want to provide additional data in your rule violation, you can create a custom one. However,
adding additional date here is discouraged, as you would need a custom renderer to actually use this
additional data. Such extensions are not language agnostic.
## 8. Create a version handler
* Now you need to create your version handler, as we did with [`SwiftHandler`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftHandler.java).
* This class is sort of a gateway between PMD and all parsing logic specific to your language. It has 2 purposes:
* `getRuleViolationFactory` method returns an instance of your rule violation factory *(see step #7)*.
By default, this returns the default rule violation factory.
* `getParser` returns an instance of your parser adapter *(see step #6)*.
That's the only method, that needs to be implemented here.
## 9. Create a parser visitor adapter
* A parser visitor adapter is not needed anymore with PMD 7. The visitor interface now provides a default
implementation.
* The visitor for ANTLR based AST is generated along the parser from the ANTLR grammar file. The
base interface for a visitor is [`AstVisitor`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstVisitor.java).
* The generated visitor class for Swift is called `SwiftVisitor`.
* In order to help use this visitor later on, a base visitor class should be created.
See [`SwiftVisitorBase`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftVisitorBase.java)
as an example.
## 10. Create a rule chain visitor
* This step is not needed anymore. For using rule chain, there is no additional adjustment necessary anymore
in the languages.
* This feature has been merged into AbstractRule via the overridable method
{% jdoc !!core::lang.rule.AbstractRule#buildTargetSelector() %}. Individual rules can make use of this optimization
by overriding this method and return an appropriate RuleTargetSelector.
## 11. Make PMD recognize your language
* Create your own subclass of `net.sourceforge.pmd.lang.BaseLanguageModule`, see Swift as an example:
[`SwiftLanguageModule`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftLanguageModule.java).
* Add your default version with `addDefaultVersion` in your language module's constructor.
* Add for each additional version of your language a call to `addVersion` as well.
* Create the service registration via the text file `src/main/resources/META-INF/services/net.sourceforge.pmd.lang.Language`. Add your fully qualified class name as a single line into it.
## 12. Create an abstract rule class for the language
* You need to create your own `AbstractRule` in order to interface your language with PMD's generic rule
execution.
* See [`AbstractSwiftRule`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/AbstractSwiftRule.java) as an example.
* While the rule basically just extends
[`AntlrBaseRule`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRule.java) without adding anything, every language should have its own base class for rule.
This helps to organize the code.
* All other rules for your language should extend this class. The purpose of this class is to provide a visitor
via the method `buildVisitor()` for analyzing the AST. The provided visitor only implements the visit methods
for specific AST nodes. The other node types use the default behavior and you don't need to care about them.
## 13. Create rules
* Creating rules is already pretty well documented in PMD - and its no different for a new language, except you
may have different AST nodes.
* PMD supports 2 types of rules, through visitors or XPath.
* To add a visitor rule:
* You need to extend the abstract rule you created on the previous step, you can use the swift
rule [UnavailableFunctionRule](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java)
as an example. Note, that all rule classes should be suffixed with `Rule` and should be placed
in a package the corresponds to their category.
* To add an XPath rule you can follow our guide [Writing XPath Rules](pmd_userdocs_extending_writing_xpath_rules.html).
## 14. Test the rules
* See UnavailableFunctionRuleTest for example. Each rule has it's own test class.
* You have to create the category rule set for your language *(see pmd-swift/src/main/resources/bestpractices.xml for example)*
* When executing the test class
* this triggers the unit test to read the corresponding XML file with the rule test data
*(see `UnavailableFunctionRule.xml` for example)*
* This test XML file contains sample pieces of code which should trigger a specified number of
violations of this rule. The unit test will execute the rule on this piece of code, and verify
that the number of violations matches.
* To verify the validity of all the created rulesets, create a subclass of `AbstractRuleSetFactoryTest` (*see `RuleSetFactoryTest` in pmd-swift for example)*.
This will load all rulesets and verify, that all required attributes are provided.
*Note:* You'll need to add your ruleset to `categories.properties`, so that it can be found.

View File

@ -1,11 +1,11 @@
---
title: Adding PMD support for a new language
short_title: Adding a new language
title: Adding PMD support for a new JAVACC grammar based language
short_title: Adding a new language with JAVACC
tags: [devdocs, extending]
summary: "How to add a new language to PMD."
summary: "How to add a new language to PMD using JAVACC grammar."
last_updated: October 5, 2019
sidebar: pmd_sidebar
permalink: pmd_devdocs_major_adding_new_language.html
permalink: pmd_devdocs_major_adding_new_language_javacc.html
folder: pmd/devdocs
---
@ -47,10 +47,9 @@ folder: pmd/devdocs
## 8. Create a version handler
* Extend `AbstractLanguageVersionHandler` *(see VmHandler for example)*
* This class is sort of a gateway between PMD and all parsing logic specific to your language. It has 3 purposes:
* This class is sort of a gateway between PMD and all parsing logic specific to your language. It has 2 purposes:
* `getRuleViolationFactory` method returns an instance of your rule violation factory *(see step #7)*
* `getParser` returns an instance of your parser adapter *(see step #6)*
* `getDumpFacade` returns a `VisitorStarter` that allows to dump a text representation of the AST into a writer *(likely for debugging purposes)*
## 9. Create a parser visitor adapter
* If you use JJT to generate your parser, it should also generate an interface for a parser visitor *(see VmParserVisitor for example)*

View File

@ -0,0 +1,77 @@
---
title: Guidelines for standard rules
short_title: Rule guidelines
tags: [devdocs, extending]
summary: "Guidelines for rules that are included in the standard distribution"
last_updated: August, 2021
sidebar: pmd_sidebar
permalink: pmd_devdocs_major_rule_guidelines.html
---
{% include note.html content="
These guidelines are new and most rules don't follow these guidelines yet.
The goal is, that eventually all rules are updated.
" %}
## Why do we need these guidelines?
* To prevent low quality contributions
* To reduce time reviewing rules
They just apply to rules included in the standard distribution.
## Requirements for standard rules
To be included in stock PMD, a rule needs
* Broad applicability. It may be specific to a framework, but then, this framework should be widely used
* Solid documentation. See below
* If it's a performance rule: solid benchmarks. No micro-optimization rules
* No overlap with other rules
## Dos/Don'ts (rule rules)
* Rule naming
* **Don't** put the implementation of the rule in the name, because it will be awkward
if the scope of the rule changes
* Eg. *SwitchStmtShouldHaveDefault* -> since enums are a thing they don't necessarily
need to have a default anymore, they should be exhaustive. So the rule name lies now...
* Eg. *MissingBreakInSwitch* -> it's obvious that this is supposed to find fall-through
switches. Counting breaks is not a clever way to do it, but since it's in the name
we can't change it without renaming the rule.
* **Do** use rule names that name the underlying problem that violations exhibit
* Eg. instead of *SwitchStmtShouldHaveDefault*, use *NonExhaustiveSwitchStatement* -> this
is the problem, the description of the rule will clarify why it is a problem and how
to fix it (add a default, or add branches, or something else in the future)
* Eg. instead of *MissingBreakInSwitch*, use *SwitchCaseFallsThrough*
* **Don't** create several rules for instances of the same problem
* *EmptyIfStmt* and *EmptyWhileStmt* are actually the same problem, namely,
that there's useless syntax in the tree.
* **Don't** limit the rule name to strictly what the rule can do today
* Eg. *UnusedPrivateField* is a bad name. The problem is that there is an unused field,
not that it is private as well. If we had the ability to find unused package-private
fields, we would report them too. So if one day we get that ability,
using a name like *UnusedField* would allow us to keep the name.
* Rule messages
* **Do** write rule messages that neutrally point out a problem or construct that should
be reviewed ("Unnecessary parentheses")
* **Don't** write rule messages that give an order ("Avoid unnecessary parentheses")
especially without explaining why, like here
* **Don't** write rule messages that are tautological ("Unnecessary parentheses should be removed").
The answer to this would be an annoyed "yes I know, so what?".
* **Do** use Markdown in rule descriptions and break lines at a reasonable 80 chars
* **Do** thoroughly comment rule examples. It must be obvious where to look
* **Do** comment your xpath expressions too
## Rule description template
* What the rule reports (1 summary line)
* Why the rule exists and where it might be useful (including, since which language version, etc)
* Blank line
* Explain all assumptions that the rule makes and keywords used in the previous paragraph.
("overridden methods are ignored", "for the purposes of this rule, a 'visible' field is
non-private").
* Describe known limitations if any
* Blank line
* For each property, explain how it modifies the assumptions and why you would want to use it.
**If you can't explain why it's there then it shouldnt be there!**

Some files were not shown because too many files have changed in this diff Show More