Merge branch 'text-utils-javacc' into text-utils-comments
This commit is contained in:
6491
.all-contributorsrc
Normal file
6491
.all-contributorsrc
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
27
.ci/build.sh
27
.ci/build.sh
@ -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 \
|
||||
|
@ -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"/>
|
||||
|
@ -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>
|
||||
|
@ -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/"
|
||||
)
|
||||
}
|
||||
|
@ -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
|
||||
|
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@ -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: |
|
||||
|
3
.github/workflows/git-repo-sync.yml
vendored
3
.github/workflows/git-repo-sync.yml
vendored
@ -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 }}
|
||||
|
8
.github/workflows/troubleshooting.yml
vendored
8
.github/workflows/troubleshooting.yml
vendored
@ -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
3
.gitignore
vendored
@ -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
|
||||
|
2
.mvn/wrapper/maven-wrapper.properties
vendored
2
.mvn/wrapper/maven-wrapper.properties
vendored
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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/',
|
||||
|
4
Gemfile
4
Gemfile
@ -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)
|
||||
|
73
Gemfile.lock
73
Gemfile.lock
@ -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)
|
||||
|
||||
|
53
README.md
53
README.md
@ -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&utm_medium=referral&utm_content=pmd/pmd&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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 `<b>` tags in files called `Foo.xml`."
|
||||
|
||||
|
||||
- name: "Java"
|
||||
ns: "pmd-java"
|
||||
funs:
|
||||
|
@ -1098,3 +1098,8 @@ h4.panel-title {
|
||||
padding-top: 0px;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.post-content .all-contributors-list img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
BIN
docs/images/userdocs/pmd-demo.gif
Normal file
BIN
docs/images/userdocs/pmd-demo.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 953 KiB |
@ -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/>
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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`.
|
||||
|
@ -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 it’s 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.
|
@ -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)*
|
@ -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 shouldn’t be there!**
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user