Skip to content

Issue #13109: Kill mutation for UnusedLocalVariableCheck 2#13145

Merged
romani merged 1 commit intocheckstyle:masterfrom
Kevin222004:ul2
Jun 24, 2023
Merged

Issue #13109: Kill mutation for UnusedLocalVariableCheck 2#13145
romani merged 1 commit intocheckstyle:masterfrom
Kevin222004:ul2

Conversation

@Kevin222004
Copy link
Copy Markdown
Contributor

@Kevin222004 Kevin222004 commented Jun 3, 2023

Issue #13109: Kill mutation for UnusedLocalVariableCheck 2


check:-

https://checkstyle.org/config_coding.html#UnusedLocalVariable


Mutation Covered :-

<mutation unstable="false">
<sourceFile>UnusedLocalVariableCheck.java</sourceFile>
<mutatedClass>com.puppycrawl.tools.checkstyle.checks.coding.UnusedLocalVariableCheck</mutatedClass>
<mutatedMethod>addInstanceOrClassVar</mutatedMethod>
<mutator>org.pitest.mutationtest.engine.gregor.mutators.NonVoidMethodCallMutator</mutator>
<description>removed call to com/puppycrawl/tools/checkstyle/api/DetailAST::findFirstToken</description>
<lineContent>varDefAst.findFirstToken(TokenTypes.TYPE), findScopeOfVariable(varDefAst));</lineContent>
</mutation>
<mutation unstable="false">
<sourceFile>UnusedLocalVariableCheck.java</sourceFile>
<mutatedClass>com.puppycrawl.tools.checkstyle.checks.coding.UnusedLocalVariableCheck</mutatedClass>
<mutatedMethod>addInstanceOrClassVar</mutatedMethod>
<mutator>org.pitest.mutationtest.engine.gregor.mutators.NonVoidMethodCallMutator</mutator>
<description>removed call to com/puppycrawl/tools/checkstyle/checks/coding/UnusedLocalVariableCheck::findScopeOfVariable</description>
<lineContent>varDefAst.findFirstToken(TokenTypes.TYPE), findScopeOfVariable(varDefAst));</lineContent>
</mutation>
<mutation unstable="false">
<sourceFile>UnusedLocalVariableCheck.java</sourceFile>
<mutatedClass>com.puppycrawl.tools.checkstyle.checks.coding.UnusedLocalVariableCheck</mutatedClass>
<mutatedMethod>addInstanceOrClassVar</mutatedMethod>
<mutator>org.pitest.mutationtest.engine.gregor.mutators.experimental.ArgumentPropagationMutator</mutator>
<description>replaced call to com/puppycrawl/tools/checkstyle/checks/coding/UnusedLocalVariableCheck::findScopeOfVariable with argument</description>
<lineContent>varDefAst.findFirstToken(TokenTypes.TYPE), findScopeOfVariable(varDefAst));</lineContent>
</mutation>
<mutation unstable="false">
<sourceFile>UnusedLocalVariableCheck.java</sourceFile>
<mutatedClass>com.puppycrawl.tools.checkstyle.checks.coding.UnusedLocalVariableCheck</mutatedClass>
<mutatedMethod>addInstanceOrClassVar</mutatedMethod>
<mutator>org.pitest.mutationtest.engine.gregor.mutators.experimental.NakedReceiverMutator</mutator>
<description>replaced call to com/puppycrawl/tools/checkstyle/api/DetailAST::findFirstToken with receiver</description>
<lineContent>varDefAst.findFirstToken(TokenTypes.TYPE), findScopeOfVariable(varDefAst));</lineContent>
</mutation>


Explaination :-

This might not be a good changes but still,

Here in the method

private void addInstanceOrClassVar(DetailAST varDefAst) {
final DetailAST parentAst = varDefAst.getParent();
if (isNonLocalTypeDeclaration(parentAst.getParent())
&& !isPrivateInstanceVariable(varDefAst)) {
final DetailAST ident = varDefAst.findFirstToken(TokenTypes.IDENT);
final VariableDesc desc = new VariableDesc(ident.getText(),
varDefAst.findFirstToken(TokenTypes.TYPE), findScopeOfVariable(varDefAst));
typeDeclAstToTypeDeclDesc.get(parentAst.getParent()).addInstOrClassVar(desc);
}
}

the code

final VariableDesc desc = new VariableDesc(ident.getTe(),
                    varDefAst.findFirstToken(TokenTypes.TYPE), findScopeOfVariable(varDefAst));

is mutated as

            final VariableDesc desc = new VariableDesc(ident.getText(),
                    null, null);

Know if we look at class VariableDec constructor

private VariableDesc(String name, DetailAST typeAst, DetailAST scope) {
this.name = name;
this.typeAst = typeAst;
this.scope = scope;

2nd and 3rd parameter is being registered as typeAst and scope.

know if we see in the whole check the usage of typeAst and scope of variableDesc class is only to log the violation at

private void logViolations(DetailAST scopeAst, Deque<VariableDesc> variablesStack) {
while (!variablesStack.isEmpty() && variablesStack.peek().getScope() == scopeAst) {
final VariableDesc variableDesc = variablesStack.pop();
if (!variableDesc.isUsed()
&& !variableDesc.isInstVarOrClassVar()) {
final DetailAST typeAst = variableDesc.getTypeAst();
log(typeAst, MSG_UNUSED_LOCAL_VARIABLE, variableDesc.getName());
}
}
}

hence their is no other usage of this.

know the method will only register instance variables and class variables on which we are throwing violation

/**
* Add instance variables and class variables to the
* {@link TypeDeclDesc#instanceAndClassVarStack}.
*
* @param varDefAst ast node of type {@link TokenTypes#VARIABLE_DEF}
*/
private void addInstanceOrClassVar(DetailAST varDefAst) {

As per my analysis using input it is not possible to cover this.


Diff Regression config: https://gist.githubusercontent.com/Kevin222004/0dbdfb487f8e9a050ed0e6356f1a35b4/raw/31f7927f400e11e4285e86fd086b373095227848/unusedLocal.xml
Diff Regression projects: https://gist.githubusercontent.com/Kevin222004/21e3934e85f802e2fbd48af06d122364/raw/604256badd733d8568064f371d55657c04b00dfd/test-projects-2.properties
Report label: Latest-Report-2

@Kevin222004 Kevin222004 marked this pull request as draft June 3, 2023 19:54
@Kevin222004
Copy link
Copy Markdown
Contributor Author

Github, generate report

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jun 3, 2023

@Kevin222004
Copy link
Copy Markdown
Contributor Author

Github, generate report

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jun 4, 2023

@Kevin222004
Copy link
Copy Markdown
Contributor Author

Github, generate report

@Kevin222004
Copy link
Copy Markdown
Contributor Author

please correct me if I missed anything

@Kevin222004 Kevin222004 marked this pull request as ready for review June 8, 2023 13:18
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jun 8, 2023

@Kevin222004
Copy link
Copy Markdown
Contributor Author

Github, generate report

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jun 8, 2023

@Kevin222004
Copy link
Copy Markdown
Contributor Author

@romani This is ready fir review

@romani
Copy link
Copy Markdown
Member

romani commented Jun 11, 2023

@Kevin222004 , Checker is not happy.

@Kevin222004
Copy link
Copy Markdown
Contributor Author

Can u please re run circle ci they are not related to changes I guess

@nrmancuso
Copy link
Copy Markdown
Contributor

@Kevin222004 reran CircleCI, all workflows there are green. Failure in semaphore is known and not related to your changes.

Copy link
Copy Markdown
Member

@Vyom-Yadav Vyom-Yadav left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

final DetailAST ident = varDefAst.findFirstToken(TokenTypes.IDENT);
final VariableDesc desc = new VariableDesc(ident.getText(),
varDefAst.findFirstToken(TokenTypes.TYPE), findScopeOfVariable(varDefAst));
null, null);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I too analyzed the code and yes, changing it to null won't have any effect because:

  1. DetailAST typeAst is only used while logging violations, and we only log violations for local variables, and this VariableDesc is for an instance or class variable.
  2. DetailAST scope. We never use the initially set scope. When we use scope, we update it to our value before using it. See
    public Deque<VariableDesc> getUpdatedCopyOfVarStack(DetailAST literalNewAst) {
    final DetailAST updatedScope = literalNewAst.getLastChild();
    final Deque<VariableDesc> instAndClassVarDeque = new ArrayDeque<>();
    instanceAndClassVarStack.forEach(instVar -> {
    final VariableDesc variableDesc = new VariableDesc(instVar.getName(),
    instVar.getTypeAst(), updatedScope);
    variableDesc.registerAsInstOrClassVar();
    instAndClassVarDeque.push(variableDesc);
    });
    return instAndClassVarDeque;
    }
    we use updatedScope instead.

So all in all, we can safely do these changes BUT this is not a good design. The design of the check should be altered to not have situations like these. This is out of the scope of this summer's project, a separate issue to enhance the design of the check should be created.


LGTM!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I don't have time now to investigate in detail.

We will deal with this in separate project

@rdiachenko
Copy link
Copy Markdown
Member

@Kevin222004 please resolve conflicts

@Kevin222004
Copy link
Copy Markdown
Contributor Author

Conflict resolved

final DetailAST ident = varDefAst.findFirstToken(TokenTypes.IDENT);
final VariableDesc desc = new VariableDesc(ident.getText(),
varDefAst.findFirstToken(TokenTypes.TYPE), findScopeOfVariable(varDefAst));
null, null);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering VariableDesc is a nested private class, can we introduce another constructor VariableDesc(String name) and remove those null arguments?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rdiachenko done
There is no such solution for new surviving mutation.
hcoles/pitest#1230

Copy link
Copy Markdown
Member

@rdiachenko rdiachenko Jun 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Kevin222004 you can reuse another constructor to set values, please update it to the following:

private VariableDesc(String name) {
    this(name, null, null);
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not ?

private VariableDesc(String name) {
            this.name = name;
        }

And it will avoid Checker problems mostlikely

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member

@romani romani Jun 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see reply to #13145 (comment)

If code is by design, we should just explain Checker that fields are nullable.

Copy link
Copy Markdown
Contributor Author

@Kevin222004 Kevin222004 Jun 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@romani I have tried what you say it leads to other new suppression and after solving it it leads to some other suppression I request you to not cover this here please if you want to check I can update the pr.
If you want to complete it allow me to create a new pr and complete it please do not cover this pr.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@romani ping

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@romani ping

@Vyom-Yadav
Copy link
Copy Markdown
Member

@Kevin222004 Please fix CI failures.

Copy link
Copy Markdown
Member

@rdiachenko rdiachenko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@rdiachenko rdiachenko assigned romani and unassigned rdiachenko Jun 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants