diff --git a/.ci/jsoref-spellchecker/whitelist.words b/.ci/jsoref-spellchecker/whitelist.words
index 519e30cb9954..3d29b7febbe8 100644
--- a/.ci/jsoref-spellchecker/whitelist.words
+++ b/.ci/jsoref-spellchecker/whitelist.words
@@ -516,6 +516,7 @@ googlegroups
googlesource
Gorm
govstrangefolder
+GPath
gpg
gradle
gradlew
@@ -866,6 +867,7 @@ multiplevariabledeclarations
Multiset
multithreading
mutableexception
+mutationtest
MVC
mvn
mvnw
@@ -1210,6 +1212,8 @@ sivakumar
Slawinski
slf
slist
+Slurper
+slurpersupport
Sms
smth
snyk
diff --git a/.ci/pitest-suppressions/pitest-ant-suppressions.xml b/.ci/pitest-suppressions/pitest-ant-suppressions.xml
new file mode 100644
index 000000000000..2987c4da44fc
--- /dev/null
+++ b/.ci/pitest-suppressions/pitest-ant-suppressions.xml
@@ -0,0 +1,47 @@
+
+
+
+ CheckstyleAntTask.java
+ com.puppycrawl.tools.checkstyle.ant.CheckstyleAntTask
+ execute
+ org.pitest.mutationtest.engine.gregor.mutators.MathMutator
+ Replaced long subtraction with addition
+ log("Total execution took " + (endTime - startTime) + TIME_SUFFIX,
+
+
+
+ CheckstyleAntTask.java
+ com.puppycrawl.tools.checkstyle.ant.CheckstyleAntTask
+ processFiles
+ org.pitest.mutationtest.engine.gregor.mutators.MathMutator
+ Replaced long subtraction with addition
+ log("To locate the files took " + (endTime - startTime) + TIME_SUFFIX,
+
+
+
+ CheckstyleAntTask.java
+ com.puppycrawl.tools.checkstyle.ant.CheckstyleAntTask
+ processFiles
+ org.pitest.mutationtest.engine.gregor.mutators.MathMutator
+ Replaced long subtraction with addition
+ log("To process the files took " + (processingEndTime - processingStartTime)
+
+
+
+ CheckstyleAntTask.java
+ com.puppycrawl.tools.checkstyle.ant.CheckstyleAntTask$Formatter
+ createDefaultLogger
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (toFile == null || !useFile) {
+
+
+
+ CheckstyleAntTask.java
+ com.puppycrawl.tools.checkstyle.ant.CheckstyleAntTask$Formatter
+ createXmlLogger
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (toFile == null || !useFile) {
+
+
diff --git a/.ci/pitest-suppressions/pitest-coding-1-suppressions.xml b/.ci/pitest-suppressions/pitest-coding-1-suppressions.xml
new file mode 100644
index 000000000000..714ca4c30ca5
--- /dev/null
+++ b/.ci/pitest-suppressions/pitest-coding-1-suppressions.xml
@@ -0,0 +1,137 @@
+
+
+
+ UnnecessaryParenthesesCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.UnnecessaryParenthesesCheck
+ isLambdaSingleParameterSurrounded
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (firstChild != null && firstChild.getType() == TokenTypes.LPAREN) {
+
+
+
+ UnnecessaryParenthesesCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.UnnecessaryParenthesesCheck
+ leaveToken
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE
+ removed conditional - replaced equality check with false
+ if (type != TokenTypes.ASSIGN
+
+
+
+ UnnecessaryParenthesesCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.UnnecessaryParenthesesCheck
+ leaveToken
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ || parent.getType() != TokenTypes.ANNOTATION_MEMBER_VALUE_PAIR) {
+
+
+
+ UnnecessaryParenthesesCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.UnnecessaryParenthesesCheck
+ visitToken
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ else if (type != TokenTypes.ASSIGN
+
+
+
+ UnnecessaryParenthesesCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.UnnecessaryParenthesesCheck
+ visitToken
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (type == TokenTypes.LAMBDA && isLambdaSingleParameterSurrounded(ast)) {
+
+
+
+ VariableDeclarationUsageDistanceCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck
+ calculateDistanceInSingleScope
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ && currentAst.getType() != TokenTypes.RCURLY) {
+
+
+
+ VariableDeclarationUsageDistanceCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck
+ calculateDistanceInSingleScope
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE
+ removed conditional - replaced equality check with false
+ if (!firstUsageFound) {
+
+
+
+ VariableDeclarationUsageDistanceCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck
+ getFirstNodeInsideForWhileDoWhileBlocks
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE
+ removed conditional - replaced equality check with false
+ if (currentNodeType == TokenTypes.SLIST) {
+
+
+
+ VariableDeclarationUsageDistanceCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck
+ getFirstNodeInsideIfBlock
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE
+ removed conditional - replaced equality check with false
+ else if (isChild(currentNode, variable)) {
+
+
+
+ VariableDeclarationUsageDistanceCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck
+ getFirstNodeInsideIfBlock
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE
+ removed conditional - replaced equality check with false
+ if (currentNode.getType() == TokenTypes.LITERAL_IF) {
+
+
+
+ VariableDeclarationUsageDistanceCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck
+ getFirstNodeInsideTryCatchFinallyBlocks
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ && currentNode.getType() == TokenTypes.LITERAL_CATCH) {
+
+
+
+ VariableDeclarationUsageDistanceCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck
+ isChild
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (curNode.getType() == ast.getType() && curNode.getText().equals(ast.getText())) {
+
+
+
+ VariableDeclarationUsageDistanceCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck
+ isInitializationSequence
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ while (result
+
+
+
+ VariableDeclarationUsageDistanceCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck
+ isVariableInOperatorExpr
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (!isVarInOperatorDeclaration && operator.getType() == TokenTypes.LITERAL_IF) {
+
+
+
+ VariableDeclarationUsageDistanceCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck
+ searchVariableUsageExpressions
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ && currentStatementAst.getType() != TokenTypes.RCURLY) {
+
+
diff --git a/.ci/pitest-suppressions/pitest-coding-2-suppressions.xml b/.ci/pitest-suppressions/pitest-coding-2-suppressions.xml
new file mode 100644
index 000000000000..4aea1e541250
--- /dev/null
+++ b/.ci/pitest-suppressions/pitest-coding-2-suppressions.xml
@@ -0,0 +1,182 @@
+
+
+
+ FinalLocalVariableCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck
+ findLastChildWhichContainsSpecifiedToken
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (astIterator.getType() == childType
+
+
+
+ FinalLocalVariableCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck
+ isCaseTokenWithAnotherCaseFollowing
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ result = findLastChildWhichContainsSpecifiedToken(
+
+
+
+ FinalLocalVariableCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck
+ isIfTokenWithAnElseFollowing
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ return ast.getType() == TokenTypes.LITERAL_IF
+
+
+
+ FinalLocalVariableCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck
+ isInTheSameLoop
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ return loop1 != null && loop1 == loop2;
+
+
+
+ FinalLocalVariableCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck
+ updateUninitializedVariables
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ && isSameVariables(storedVariable, variable)
+
+
+
+ FinalLocalVariableCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck
+ visitToken
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ == ast.getParent()) {
+
+
+
+ FinalLocalVariableCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck
+ visitToken
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (ast.getParent().getType() == TokenTypes.SWITCH_RULE
+
+
+
+ HiddenFieldCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck
+ isIgnoredParamOfAbstractMethod
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ && ast.getType() == TokenTypes.PARAMETER_DEF) {
+
+
+
+ HiddenFieldCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck
+ isIgnoredParamOfAbstractMethod
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (method.getType() == TokenTypes.METHOD_DEF) {
+
+
+
+ HiddenFieldCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck
+ isIgnoredSetterParam
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ && methodAST.getType() == TokenTypes.METHOD_DEF
+
+
+
+ HiddenFieldCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck
+ isIgnoredSetterParam
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (ignoreSetter && ast.getType() == TokenTypes.PARAMETER_DEF) {
+
+
+
+ HiddenFieldCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck
+ processLambda
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ && firstChild.getType() == TokenTypes.IDENT) {
+
+
+
+ HiddenFieldCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck
+ visitOtherTokens
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE
+ removed conditional - replaced equality check with false
+ if (type == TokenTypes.CLASS_DEF
+
+
+
+ HiddenFieldCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck
+ visitOtherTokens
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (type == TokenTypes.CLASS_DEF
+
+
+
+ IllegalInstantiationCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.IllegalInstantiationCheck
+ isStandardClass
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ && illegal.startsWith(JAVA_LANG)) {
+
+
+
+ OneStatementPerLineCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.OneStatementPerLineCheck
+ checkIfSemicolonIsInDifferentLineThanPrevious
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE
+ removed conditional - replaced equality check with false
+ && currentStatement.getPreviousSibling().getType() == TokenTypes.RESOURCES;
+
+
+
+ OneStatementPerLineCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.OneStatementPerLineCheck
+ checkIfSemicolonIsInDifferentLineThanPrevious
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE
+ removed conditional - replaced equality check with false
+ currentStatement.getPreviousSibling() != null
+
+
+
+ OneStatementPerLineCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.OneStatementPerLineCheck
+ checkIfSemicolonIsInDifferentLineThanPrevious
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (!hasResourcesPrevSibling && isMultilineStatement(currentStatement)) {
+
+
+
+ OneStatementPerLineCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.OneStatementPerLineCheck
+ isMultilineStatement
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ multiline = !TokenUtil.areOnSameLine(prevSibling, ast)
+
+
+
+ OneStatementPerLineCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.OneStatementPerLineCheck
+ leaveToken
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (countOfSemiInLambda.isEmpty()) {
+
+
diff --git a/.ci/pitest-suppressions/pitest-coding-require-this-check-suppressions.xml b/.ci/pitest-suppressions/pitest-coding-require-this-check-suppressions.xml
new file mode 100644
index 000000000000..3bf571976353
--- /dev/null
+++ b/.ci/pitest-suppressions/pitest-coding-require-this-check-suppressions.xml
@@ -0,0 +1,92 @@
+
+
+
+ RequireThisCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck
+ beginTree
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (toVisit == null) {
+
+
+
+ RequireThisCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck
+ canBeReferencedFromStaticContext
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE
+ removed conditional - replaced equality check with false
+ if (definitionToken.getType() == TokenTypes.STATIC_INIT) {
+
+
+
+ RequireThisCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck
+ canBeReferencedFromStaticContext
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (variableDeclarationFrame.getType() == FrameType.CLASS_FRAME) {
+
+
+
+ RequireThisCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck
+ collectDeclarations
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ && ast.getParent().getType() != TokenTypes.LITERAL_CATCH) {
+
+
+
+ RequireThisCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck
+ endCollectingDeclarations
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE
+ removed conditional - replaced equality check with false
+ if (isAnonymousClassDef(ast)) {
+
+
+
+ RequireThisCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck
+ getCodeBlockDefinitionToken
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ && parent.getType() != TokenTypes.CTOR_DEF
+
+
+
+ RequireThisCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck
+ isAnonymousClassDef
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ && lastChild.getType() == TokenTypes.OBJBLOCK;
+
+
+
+ RequireThisCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck
+ isAstSimilar
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ return left.getType() == right.getType() && left.getText().equals(right.getText());
+
+
+
+ RequireThisCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck
+ isInsideConstructorFrame
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (fieldUsageFrame.getType() == FrameType.BLOCK_FRAME) {
+
+
+
+ RequireThisCheck.java
+ com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck
+ isOverlappingByLocalVariable
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (sibling != null && isAssignToken(parent.getType())) {
+
+
diff --git a/.ci/pitest-suppressions/pitest-common-suppressions.xml b/.ci/pitest-suppressions/pitest-common-suppressions.xml
new file mode 100644
index 000000000000..124e956b306f
--- /dev/null
+++ b/.ci/pitest-suppressions/pitest-common-suppressions.xml
@@ -0,0 +1,92 @@
+
+
+
+ Checker.java
+ com.puppycrawl.tools.checkstyle.Checker
+ processFiles
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE
+ removed conditional - replaced equality check with false
+ if (cacheFile != null && cacheFile.isInCache(fileName, timestamp)
+
+
+
+ Checker.java
+ com.puppycrawl.tools.checkstyle.Checker
+ processFiles
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (cacheFile != null && cacheFile.isInCache(fileName, timestamp)
+
+
+
+ DefaultLogger.java
+ com.puppycrawl.tools.checkstyle.DefaultLogger
+ <init>
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ closeError = errorStreamOptions == OutputStreamOptions.CLOSE;
+
+
+
+ DefaultLogger.java
+ com.puppycrawl.tools.checkstyle.DefaultLogger
+ <init>
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ closeInfo = infoStreamOptions == OutputStreamOptions.CLOSE;
+
+
+
+ DefaultLogger.java
+ com.puppycrawl.tools.checkstyle.DefaultLogger
+ addError
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (severityLevel != SeverityLevel.IGNORE) {
+
+
+
+ DefaultLogger.java
+ com.puppycrawl.tools.checkstyle.DefaultLogger
+ closeStreams
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (closeError) {
+
+
+
+ DefaultLogger.java
+ com.puppycrawl.tools.checkstyle.DefaultLogger
+ closeStreams
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (closeInfo) {
+
+
+
+ PackageObjectFactory.java
+ com.puppycrawl.tools.checkstyle.PackageObjectFactory
+ createModule
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (!name.contains(PACKAGE_SEPARATOR)) {
+
+
+
+ PackageObjectFactory.java
+ com.puppycrawl.tools.checkstyle.PackageObjectFactory
+ createModule
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (instance == null
+
+
+
+ PackageObjectFactory.java
+ com.puppycrawl.tools.checkstyle.PackageObjectFactory
+ createModule
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (thirdPartyNameToFullModuleNames == null) {
+
+
diff --git a/.ci/pitest-suppressions/pitest-header-suppressions.xml b/.ci/pitest-suppressions/pitest-header-suppressions.xml
new file mode 100644
index 000000000000..af1463a5f84e
--- /dev/null
+++ b/.ci/pitest-suppressions/pitest-header-suppressions.xml
@@ -0,0 +1,19 @@
+
+
+
+ RegexpHeaderCheck.java
+ com.puppycrawl.tools.checkstyle.checks.header.RegexpHeaderCheck
+ processFiltered
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE
+ removed conditional - replaced equality check with false
+ isMatch = headerLineNo == headerSize
+
+
+ RegexpHeaderCheck.java
+ com.puppycrawl.tools.checkstyle.checks.header.RegexpHeaderCheck
+ processFiltered
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ || isMatch(line, headerLineNo);
+
+
diff --git a/.ci/pitest-suppressions/pitest-imports-suppressions.xml b/.ci/pitest-suppressions/pitest-imports-suppressions.xml
new file mode 100644
index 000000000000..9789588e9d0e
--- /dev/null
+++ b/.ci/pitest-suppressions/pitest-imports-suppressions.xml
@@ -0,0 +1,47 @@
+
+
+
+ ImportControlLoader.java
+ com.puppycrawl.tools.checkstyle.checks.imports.ImportControlLoader
+ startElement
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE
+ removed conditional - replaced equality check with false
+ else if (ALLOW_ELEMENT_NAME.equals(qName) || "disallow".equals(qName)) {
+
+
+
+ ImportControlLoader.java
+ com.puppycrawl.tools.checkstyle.checks.imports.ImportControlLoader
+ startElement
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ else if (ALLOW_ELEMENT_NAME.equals(qName) || "disallow".equals(qName)) {
+
+
+
+ PkgImportControl.java
+ com.puppycrawl.tools.checkstyle.checks.imports.PkgImportControl
+ <init>
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE
+ removed conditional - replaced equality check with false
+ if (regex || parent.regex) {
+
+
+
+ PkgImportControl.java
+ com.puppycrawl.tools.checkstyle.checks.imports.PkgImportControl
+ <init>
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF
+ removed conditional - replaced equality check with true
+ if (regex || parent.regex) {
+
+
+
+ PkgImportControl.java
+ com.puppycrawl.tools.checkstyle.checks.imports.PkgImportControl
+ matchesExactly
+ org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE
+ removed conditional - replaced equality check with false
+ if (regex) {
+
+
diff --git a/.ci/pitest-suppressions/pitest-indentation-suppressions.xml b/.ci/pitest-suppressions/pitest-indentation-suppressions.xml
new file mode 100644
index 000000000000..08008b531652
--- /dev/null
+++ b/.ci/pitest-suppressions/pitest-indentation-suppressions.xml
@@ -0,0 +1,227 @@
+
+
+
+ AbstractExpressionHandler.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.AbstractExpressionHandler
+ findSubtreeAst
+ org.pitest.mutationtest.engine.gregor.mutators.ConditionalsBoundaryMutator
+ changed conditional boundary
+ if (colNum == null || thisLineColumn < colNum) {
+
+
+
+ AbstractExpressionHandler.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.AbstractExpressionHandler
+ getFirstAstNode
+ org.pitest.mutationtest.engine.gregor.mutators.ConditionalsBoundaryMutator
+ changed conditional boundary
+ && curNode.getColumnNo() < realStart.getColumnNo()) {
+
+
+
+ AbstractExpressionHandler.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.AbstractExpressionHandler
+ getFirstToken
+ org.pitest.mutationtest.engine.gregor.mutators.ConditionalsBoundaryMutator
+ changed conditional boundary
+ if (toTest.getColumnNo() < first.getColumnNo()) {
+
+
+
+ BlockParentHandler.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.BlockParentHandler
+ getLineWrappingIndent
+ org.pitest.mutationtest.engine.gregor.mutators.ReturnValsMutator
+ replaced return of integer sized value with (x == 0 ? 1 : 0)
+ return getIndentCheck().getLineWrappingIndentation();
+
+
+
+ CommentsIndentationCheck.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck
+ findPreviousStatement
+ org.pitest.mutationtest.engine.gregor.mutators.NegateConditionalsMutator
+ negated conditional
+ if (root.getFirstChild().getType() == TokenTypes.LITERAL_NEW) {
+
+
+
+ CommentsIndentationCheck.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck
+ findPreviousStatement
+ org.pitest.mutationtest.engine.gregor.mutators.ConditionalsBoundaryMutator
+ changed conditional boundary
+ if (root.getLineNo() >= comment.getLineNo()) {
+
+
+
+ CommentsIndentationCheck.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck
+ findTokenWhichBeginsTheLine
+ org.pitest.mutationtest.engine.gregor.mutators.NegateConditionalsMutator
+ negated conditional
+ if (isUsingOfObjectReferenceToInvokeMethod(root)) {
+
+
+
+ CommentsIndentationCheck.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck
+ getPrevStatementWhenCommentIsUnderCase
+ org.pitest.mutationtest.engine.gregor.mutators.NegateConditionalsMutator
+ negated conditional
+ if (isUsingOfObjectReferenceToInvokeMethod(blockBody)) {
+
+
+
+ CommentsIndentationCheck.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck
+ isUsingOfObjectReferenceToInvokeMethod
+ org.pitest.mutationtest.engine.gregor.mutators.NegateConditionalsMutator
+ negated conditional
+ && root.getFirstChild().getFirstChild().getFirstChild().getNextSibling() != null;
+
+
+
+ CommentsIndentationCheck.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck
+ isUsingOfObjectReferenceToInvokeMethod
+ org.pitest.mutationtest.engine.gregor.mutators.ReturnValsMutator
+ replaced return of integer sized value with (x == 0 ? 1 : 0)
+ return root.getFirstChild().getFirstChild().getFirstChild() != null
+
+
+
+ CommentsIndentationCheck.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck
+ isUsingOfObjectReferenceToInvokeMethod
+ org.pitest.mutationtest.engine.gregor.mutators.returns.BooleanTrueReturnValsMutator
+ replaced boolean return with true for com/puppycrawl/tools/checkstyle/checks/indentation/CommentsIndentationCheck::isUsingOfObjectReferenceToInvokeMethod
+ return root.getFirstChild().getFirstChild().getFirstChild() != null
+
+
+
+ HandlerFactory.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.HandlerFactory
+ <init>
+ org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator
+ removed call to com/puppycrawl/tools/checkstyle/checks/indentation/HandlerFactory::register
+ register(TokenTypes.INDEX_OP, IndexHandler.class);
+
+
+
+ HandlerFactory.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.HandlerFactory
+ clearCreatedHandlers
+ org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator
+ removed call to java/util/Map::clear
+ createdHandlers.clear();
+
+
+
+ IndentationCheck.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.IndentationCheck
+ beginTree
+ org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator
+ removed call to com/puppycrawl/tools/checkstyle/checks/indentation/HandlerFactory::clearCreatedHandlers
+ handlerFactory.clearCreatedHandlers();
+
+
+
+ IndentationCheck.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.IndentationCheck
+ beginTree
+ org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator
+ removed call to java/util/Deque::clear
+ handlers.clear();
+
+
+
+ IndentationCheck.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.IndentationCheck
+ beginTree
+ org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator
+ removed call to com/puppycrawl/tools/checkstyle/checks/indentation/PrimordialHandler::checkIndentation
+ primordialHandler.checkIndentation();
+
+
+
+ MethodDefHandler.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.MethodDefHandler
+ getMethodDefLineStart
+ org.pitest.mutationtest.engine.gregor.mutators.ConditionalsBoundaryMutator
+ changed conditional boundary
+ if (node.getLineNo() < lineStart) {
+
+
+
+ NewHandler.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.NewHandler
+ shouldIncreaseIndent
+ org.pitest.mutationtest.engine.gregor.mutators.ReturnValsMutator
+ replaced return of integer sized value with (x == 0 ? 1 : 0)
+ return false;
+
+
+
+ NewHandler.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.NewHandler
+ shouldIncreaseIndent
+ org.pitest.mutationtest.engine.gregor.mutators.returns.BooleanTrueReturnValsMutator
+ replaced boolean return with true for com/puppycrawl/tools/checkstyle/checks/indentation/NewHandler::shouldIncreaseIndent
+ return false;
+
+
+
+ SwitchHandler.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.SwitchHandler
+ checkIndentation
+ org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator
+ removed call to com/puppycrawl/tools/checkstyle/checks/indentation/SwitchHandler::checkSwitchExpr
+ checkSwitchExpr();
+
+
+
+ SwitchHandler.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.SwitchHandler
+ checkSwitchExpr
+ org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator
+ removed call to com/puppycrawl/tools/checkstyle/checks/indentation/SwitchHandler::checkExpressionSubtree
+ checkExpressionSubtree(
+
+
+
+ SynchronizedHandler.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.SynchronizedHandler
+ checkIndentation
+ org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator
+ removed call to com/puppycrawl/tools/checkstyle/checks/indentation/SynchronizedHandler::checkSynchronizedExpr
+ checkSynchronizedExpr();
+
+
+
+ SynchronizedHandler.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.SynchronizedHandler
+ checkIndentation
+ org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator
+ removed call to com/puppycrawl/tools/checkstyle/checks/indentation/SynchronizedHandler::checkWrappingIndentation
+ checkWrappingIndentation(getMainAst(),
+
+
+
+ SynchronizedHandler.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.SynchronizedHandler
+ checkSynchronizedExpr
+ org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator
+ removed call to com/puppycrawl/tools/checkstyle/checks/indentation/SynchronizedHandler::checkExpressionSubtree
+ checkExpressionSubtree(syncAst, expected, false, false);
+
+
+
+ TryHandler.java
+ com.puppycrawl.tools.checkstyle.checks.indentation.TryHandler
+ checkIndentation
+ org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator
+ removed call to com/puppycrawl/tools/checkstyle/checks/indentation/TryHandler::checkTryResParen
+ checkTryResParen(getTryResLparen(), "lparen");
+
+
diff --git a/.ci/pitest-suppressions/pitest-javadoc-suppressions.xml b/.ci/pitest-suppressions/pitest-javadoc-suppressions.xml
new file mode 100644
index 000000000000..819839ecc9ca
--- /dev/null
+++ b/.ci/pitest-suppressions/pitest-javadoc-suppressions.xml
@@ -0,0 +1,29 @@
+
+
+
+ AbstractJavadocCheck.java
+ com.puppycrawl.tools.checkstyle.checks.javadoc.AbstractJavadocCheck
+ processTree
+ org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator
+ removed call to com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck::beginJavadocTree
+ beginJavadocTree(root);
+
+
+
+ AbstractJavadocCheck.java
+ com.puppycrawl.tools.checkstyle.checks.javadoc.AbstractJavadocCheck
+ processTree
+ org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator
+ removed call to com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck::finishJavadocTree
+ finishJavadocTree(root);
+
+
+
+ TagParser.java
+ com.puppycrawl.tools.checkstyle.checks.javadoc.TagParser
+ getNextCharPos
+ org.pitest.mutationtest.engine.gregor.mutators.NegateConditionalsMutator
+ negated conditional
+ while (column < currentLineLength
+
+
diff --git a/.ci/pitest.sh b/.ci/pitest-survival-check-html.sh
similarity index 100%
rename from .ci/pitest.sh
rename to .ci/pitest-survival-check-html.sh
diff --git a/.ci/pitest-survival-check-xml.groovy b/.ci/pitest-survival-check-xml.groovy
new file mode 100644
index 000000000000..3fed25eacea0
--- /dev/null
+++ b/.ci/pitest-survival-check-xml.groovy
@@ -0,0 +1,394 @@
+import groovy.io.FileType
+import groovy.transform.EqualsAndHashCode
+import groovy.transform.Field
+import groovy.xml.XmlParser
+import groovy.xml.XmlSlurper
+import groovy.xml.XmlUtil
+import groovy.xml.slurpersupport.GPathResult
+import groovy.xml.slurpersupport.NodeChildren
+
+@Field final static String SEPARATOR = System.getProperty("file.separator")
+
+if (args.length == 2) {
+ parseArgumentAndExecute(args[0], args[1])
+}
+else {
+ parseArgumentAndExecute(args[0], null)
+}
+
+/**
+ * Parse the command line arguments passed in and execute the branch based on the arguments.
+ *
+ * @param argument command line argument
+ */
+private void parseArgumentAndExecute(String argument, String flag) {
+ final Set profiles = getPitestProfiles()
+ final String usageString = """
+ Usage groovy ./.ci/pitest-survival-check-xml.groovy [profile] [-g | --generate-suppression]
+ To see the full list of supported profiles run
+ 'groovy ./.ci/pitest-survival-check-xml.groovy --list'
+ """.stripIndent()
+
+ if (profiles.contains(argument)) {
+ if (flag != null && flag != "-g" && flag != "--generate-suppression") {
+ final String exceptionMessage = "\nUnexpected flag: ${flag}" + usageString
+ throw new IllegalArgumentException(exceptionMessage)
+ }
+ checkPitestReport(argument, flag)
+
+ }
+ else if (argument == "--list") {
+ println "Supported profiles:"
+ profiles.each { println it }
+ }
+ else {
+ final String exceptionMessage = "\nUnexpected argument: ${argument}" + usageString
+ throw new IllegalArgumentException(exceptionMessage)
+ }
+}
+
+/**
+ * Parse the pom.xml file to get all the available pitest profiles.
+ *
+ * @return A set of all available pitest profiles
+ */
+private static Set getPitestProfiles() {
+ final GPathResult mainNode = new XmlSlurper().parse(".${SEPARATOR}pom.xml")
+ final NodeChildren ids = mainNode.profiles.profile.id as NodeChildren
+ final Set profiles = new HashSet<>()
+ ids.each { node ->
+ final GPathResult id = node as GPathResult
+ final String idText = id.text()
+ if (idText.startsWith("pitest-")) {
+ profiles.add(idText)
+ }
+ }
+ return profiles
+}
+
+/**
+ * Check the generated pitest report. Parse the surviving and suppressed mutations and compare
+ * them.
+ *
+ * @param profile the pitest profile to execute
+ * @param flag command line argument flag to determine output format
+ */
+private static void checkPitestReport(String profile, String flag) {
+ final XmlParser xmlParser = new XmlParser()
+ File mutationReportFile = null
+ final String suppressedMutationFileUri =
+ ".${SEPARATOR}.ci${SEPARATOR}pitest-suppressions${SEPARATOR}${profile}-suppressions.xml"
+
+ final File pitReports = new File(".${SEPARATOR}target${SEPARATOR}pit-reports")
+
+ if (!pitReports.exists()) {
+ throw new IllegalStateException(
+ "Pitest report directory does not exist, generate pitest report first")
+ }
+
+ pitReports.eachFileRecurse(FileType.FILES) {
+ if (it.name == 'mutations.xml') {
+ mutationReportFile = it
+ }
+ }
+ final Node mutationReportNode = xmlParser.parse(mutationReportFile)
+ final Set survivingMutations = getSurvivingMutations(mutationReportNode)
+
+ final File suppressionFile = new File(suppressedMutationFileUri)
+ Set suppressedMutations = Collections.emptySet()
+ if (suppressionFile.exists()) {
+ final Node suppressedMutationNode = xmlParser.parse(suppressedMutationFileUri)
+ suppressedMutations = getSuppressedMutations(suppressedMutationNode)
+ }
+ compareMutations(survivingMutations, suppressedMutations, flag)
+}
+
+/**
+ * Get the surviving mutations. All child nodes of the main {@code mutations} node
+ * are parsed.
+ *
+ * @param mainNode the main {@code mutations} node
+ * @return A set of surviving mutations
+ */
+private static Set getSurvivingMutations(Node mainNode) {
+
+ final List children = mainNode.children()
+ final Set survivingMutations = new TreeSet<>()
+
+ children.each { node ->
+ final Node mutationNode = node as Node
+
+ final String mutationStatus = mutationNode.attribute("status")
+
+ if (mutationStatus == "SURVIVED" || mutationStatus == "NO_COVERAGE") {
+ survivingMutations.add(getMutation(mutationNode))
+ }
+ }
+ return survivingMutations
+}
+
+/**
+ * Get the suppressed mutations. All child nodes of the main {@code suppressedMutations} node
+ * are parsed.
+ *
+ * @param mainNode the main {@code suppressedMutations} node
+ * @return A set of suppressed mutations
+ */
+private static Set getSuppressedMutations(Node mainNode) {
+ final List children = mainNode.children()
+ final Set suppressedMutations = new TreeSet<>()
+
+ children.each { node ->
+ final Node mutationNode = node as Node
+ suppressedMutations.add(getMutation(mutationNode))
+ }
+ return suppressedMutations
+}
+
+/**
+ * Construct the {@link Mutation} object from the {@code mutation} XML node.
+ * The {@code mutations.xml} file is parsed to get the {@code mutationNode}.
+ *
+ * @param mutationNode the {@code mutation} XML node
+ * @return {@link Mutation} object represented by the {@code mutation} XML node
+ */
+private static Mutation getMutation(Node mutationNode) {
+ final List childNodes = mutationNode.children()
+
+ String sourceFile = null
+ String mutatedClass = null
+ String mutatedMethod = null
+ String mutator = null
+ String lineContent = null
+ String description = null
+ String mutationClassPackage = null
+ int lineNumber = 0
+ childNodes.each {
+ final Node childNode = it as Node
+ final String text = childNode.name()
+
+ final String childNodeText = XmlUtil.escapeXml(childNode.text())
+ switch (text) {
+ case "sourceFile":
+ sourceFile = childNodeText
+ break
+ case "mutatedClass":
+ mutatedClass = childNodeText
+ mutationClassPackage = mutatedClass.split("[A-Z]")[0]
+ break
+ case "mutatedMethod":
+ mutatedMethod = childNodeText
+ break
+ case "mutator":
+ mutator = childNodeText
+ break
+ case "description":
+ description = childNodeText
+ break
+ case "lineNumber":
+ lineNumber = Integer.parseInt(childNodeText)
+ break
+ case "lineContent":
+ lineContent = childNodeText
+ break
+ }
+ }
+ if (lineContent == null) {
+ final String mutationFileName = mutationClassPackage + sourceFile
+ final String startingPath = ".${SEPARATOR}src${SEPARATOR}main${SEPARATOR}java${SEPARATOR}"
+ final String javaExtension = ".java"
+ final String mutationFilePath = startingPath + mutationFileName
+ .substring(0, mutationFileName.length() - javaExtension.length())
+ .replaceAll("\\.", SEPARATOR) + javaExtension
+
+ final File file = new File(mutationFilePath)
+ lineContent = XmlUtil.escapeXml(file.readLines().get(lineNumber - 1).trim())
+ }
+ if (lineNumber == 0) {
+ lineNumber = -1
+ }
+
+ final String unstableAttributeValue = mutationNode.attribute("unstable")
+ final boolean isUnstable = Boolean.parseBoolean(unstableAttributeValue)
+
+ return new Mutation(sourceFile, mutatedClass, mutatedMethod, mutator, description,
+ lineContent, lineNumber, isUnstable)
+}
+
+/**
+ * Compare surviving and suppressed mutations. The comparison passes successfully
+ * (i.e. nothing is printed on the terminal)
+ * when:
+ *
+ * - Surviving and suppressed mutations are equal.
+ * - There are extra suppressed mutations but they are unstable
+ * i.e. {@code unstable="true"}.
+ *
+ * The comparison fails (i.e. error message is printed) when:
+ *
+ * - Surviving mutations are not present in the suppressed list.
+ * - There are mutations in the suppression list that are not there is surviving list.
+ *
+ *
+ * @param survivingMutations A set of surviving mutations
+ * @param suppressedMutations A set of suppressed mutations
+ * @param flag command line argument flag to determine output format
+ */
+private static void compareMutations(Set survivingMutations,
+ Set suppressedMutations,
+ String flag) {
+ final Set survivingUnsuppressedMutations =
+ setDifference(survivingMutations, suppressedMutations)
+ final Set extraSuppressions =
+ setDifference(suppressedMutations, survivingMutations)
+
+ if (survivingMutations != suppressedMutations
+ && (!survivingUnsuppressedMutations.isEmpty()
+ || hasOnlyStableMutations(extraSuppressions))) {
+ if (!survivingUnsuppressedMutations.isEmpty()) {
+ println "Surviving mutation(s) found:"
+ survivingUnsuppressedMutations.each {
+ printMutation(flag, it)
+ }
+ }
+ if (!extraSuppressions.isEmpty()
+ && extraSuppressions.any { !it.isUnstable() }) {
+ println "\nUnnecessary suppressed mutation(s) found:"
+ extraSuppressions.each {
+ if (!it.isUnstable()) {
+ printMutation(flag, it)
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Whether a set has only stable mutations.
+ *
+ * @param mutations A set of mutations
+ * @return {@code true} if a set has only stable mutations
+ */
+private static boolean hasOnlyStableMutations(Set mutations) {
+ return mutations.every { !it.isUnstable() }
+}
+
+/**
+ * Prints the mutation according to the nature of the flag.
+ *
+ * @param flag command line argument flag to determine output format
+ * @param mutation mutation to print
+ */
+private static void printMutation(String flag, Mutation mutation) {
+ if (flag != null) {
+ println mutation.toXmlString()
+ }
+ else {
+ println mutation
+ }
+}
+
+/**
+ * Determine the difference between 2 sets. The result is {@code setOne - setTwo}.
+ *
+ * @param setOne The first set in the difference
+ * @param setTwo The second set in the difference
+ * @return {@code setOne - setTwo}
+ */
+private static Set setDifference(final Set setOne,
+ final Set setTwo) {
+ final Set result = new HashSet<>(setOne)
+ result.removeIf(mutation -> setTwo.contains(mutation))
+ return result
+}
+
+/**
+ * A class to represent the XML {@code mutation} node.
+ */
+@EqualsAndHashCode(excludes = ["lineNumber", "unstable"])
+record Mutation(String sourceFile, String mutatedClass,
+ String mutatedMethod, String mutator,
+ String description, String lineContent, int lineNumber,
+ boolean unstable)
+ implements Comparable {
+
+ /**
+ * Mutation nodes present in suppressions file do not have a {@code lineNumber}.
+ * The {@code lineNumber} is set to {@code -1} for such mutations.
+ */
+ private static final int LINE_NUMBER_NOT_PRESENT_VALUE = -1
+
+ @Override
+ String toString() {
+ String toString = """
+ Source File: "${sourceFile()}"
+ Class: "${mutatedClass()}"
+ Method: "${mutatedMethod()}"
+ Line Contents: "${lineContent()}"
+ Mutator: "${mutator()}"
+ Description: "${description()}"
+ """.stripIndent()
+ if (lineNumber() != LINE_NUMBER_NOT_PRESENT_VALUE) {
+ toString += 'Line Number: ' + lineNumber()
+ }
+ return toString
+ }
+
+ @Override
+ int compareTo(Mutation other) {
+ int i = sourceFile() <=> other.sourceFile()
+ if (i != 0) {
+ return i
+ }
+
+ i = mutatedClass() <=> other.mutatedClass()
+ if (i != 0) {
+ return i
+ }
+
+ i = mutatedMethod() <=> other.mutatedMethod()
+ if (i != 0) {
+ return i
+ }
+
+ i = lineContent() <=> other.lineContent()
+ if (i != 0) {
+ return i
+ }
+
+ i = mutator() <=> other.mutator()
+ if (i != 0) {
+ return i
+ }
+
+ return description() <=> other.description()
+ }
+
+ /**
+ * XML format of the mutation.
+ *
+ * @return XML format of the mutation
+ */
+ String toXmlString() {
+ return """
+
+ ${sourceFile()}
+ ${mutatedClass()}
+ ${mutatedMethod()}
+ ${mutator()}
+ ${description()}
+ ${lineContent()}
+
+ """.stripIndent(10)
+ }
+
+ /**
+ * Whether the mutation is unstable.
+ *
+ * @return {@code true} if the mutation is unstable
+ */
+ boolean isUnstable() {
+ return unstable
+ }
+
+}
diff --git a/.github/workflows/pitest.yml b/.github/workflows/pitest.yml
index dcda6867facd..ab833bbaccd9 100644
--- a/.github/workflows/pitest.yml
+++ b/.github/workflows/pitest.yml
@@ -44,6 +44,23 @@ jobs:
runs-on: ubuntu-latest
continue-on-error: true
steps:
+ - name: Set up JDK 11
+ uses: actions/setup-java@v1
+ with:
+ java-version: 11
+ - name: Download Groovy 4.0.3
+ uses: sdkman/sdkman-action@master
+ id: sdkman
+ with:
+ candidate: groovy
+ version: 4.0.3
+ - name: Set up Groovy 4.0.3
+ run: |
+ unzip ${{ steps.sdkman.outputs.file }} -d ${{ runner.temp }};
+ mv ${{ runner.temp }}/groovy-4.0.3 ${{ runner.temp }}/groovy
+ GROOVY_HOME=${{ runner.temp }}/groovy
+ echo "GROOVY_HOME=${{ runner.temp }}/groovy" >> $GITHUB_ENV
+ echo "$GROOVY_HOME/bin" >> $GITHUB_PATH
- name: Setup local maven cache
uses: actions/cache@v2
with:
@@ -55,9 +72,19 @@ jobs:
run: |
mvn -e --no-transfer-progress -P"${{ matrix.profile }}" clean test-compile \
org.pitest:pitest-maven:mutationCoverage
- - name: ${{ matrix.profile }}
+ - name: Check ${{ matrix.profile }} with XML report
+ id: pitest-xml-model
run: |
- ./.ci/pitest.sh ${{ matrix.profile }}
+ PITEST_SURVIVAL_CHECK_XML=$(groovy ./.ci/pitest-survival-check-xml.groovy ${{ matrix.profile }})
+ echo "$PITEST_SURVIVAL_CHECK_XML"
+
+ if [[ -n "$PITEST_SURVIVAL_CHECK_XML" ]]; then
+ exit 1
+ fi
+ - name: Check ${{ matrix.profile }} with HTML report
+ if: failure() || success()
+ run: |
+ ./.ci/pitest-survival-check-html.sh ${{ matrix.profile }}
- name: Stage results
if: failure() || github.ref == 'refs/heads/master'
run: |
@@ -69,3 +96,4 @@ jobs:
name: ${{ matrix.profile }}-coverage-report
path: staging
retention-days: 7
+
diff --git a/config/checkstyle_non_main_files_suppressions.xml b/config/checkstyle_non_main_files_suppressions.xml
index 1fa3e6ec94b2..6f37259dc4d8 100644
--- a/config/checkstyle_non_main_files_suppressions.xml
+++ b/config/checkstyle_non_main_files_suppressions.xml
@@ -76,7 +76,7 @@
+ files=".ci[\\/]pitest-survival-check-html.sh"/>
@@ -87,6 +87,9 @@
+
+
+
diff --git a/pom.xml b/pom.xml
index 5686bf860502..11744cbd16c2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -216,6 +216,7 @@
11
1.8.1
10
+ HTML,XML
50000
4
0.16
@@ -2387,6 +2388,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -2431,6 +2433,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -2475,6 +2478,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -2564,6 +2568,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -2666,6 +2671,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -2710,6 +2716,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -2754,6 +2761,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -2798,6 +2806,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -2842,6 +2851,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -2887,6 +2897,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -2941,6 +2952,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -2985,6 +2997,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -3029,6 +3042,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -3073,6 +3087,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -3117,6 +3132,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -3161,6 +3177,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -3205,6 +3222,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -3250,6 +3268,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -3291,6 +3310,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -3376,6 +3396,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -3438,6 +3459,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -3479,6 +3501,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -3572,6 +3595,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -3629,6 +3653,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -3675,6 +3700,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -3784,6 +3810,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -3828,6 +3855,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -3902,6 +3930,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}
@@ -3947,6 +3976,7 @@
${pitest.plugin.timeout.factor}
${pitest.plugin.timeout.constant}
${pitest.plugin.threads}
+ ${pitest.plugin.output.formats}