Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce CanonicalClassNameUsage check #881

Merged
merged 2 commits into from
Dec 18, 2023

Conversation

Stephan202
Copy link
Member

@Stephan202 Stephan202 commented Nov 12, 2023

Suggested commit message:

Introduce `CanonicalClassNameUsage` check (#881)

Error Prone checks deal with source code and type matchers, both of
which generally involve canonical type names, rather than the strings
produced by `Class#getName()`. This distinction is particularly relevant
when dealing with nested types.

@Stephan202 Stephan202 added this to the 0.15.0 milestone Nov 12, 2023
@Stephan202 Stephan202 requested a review from rickie November 12, 2023 21:11
Copy link

Looks good. All 15 mutations in this change were killed.

class surviving killed
🎉tech.picnic.errorprone.bugpatterns.CanonicalClassNameUsage 0 14
🎉tech.picnic.errorprone.bugpatterns.PrimitiveComparison 0 1

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

Copy link
Contributor

@mohamedsamehsalah mohamedsamehsalah left a comment

Choose a reason for hiding this comment

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

LGTM 🚀

Left one question.


@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
if (!GET_NAME_INVOCATION.matches(tree, state) || !isPassedToCanonicalNameUsingType(state)) {
Copy link
Contributor

@mohamedsamehsalah mohamedsamehsalah Dec 2, 2023

Choose a reason for hiding this comment

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

Acording to Class#getCanonicalName docs, the method can return null for local, anonymous & hidden classes.

I wonder do we need to add a CanonicalNameIsNotNull check here ?

But I guess the idea is that methods that accept canonical names are aware of the API...

Copy link
Member

@rickie rickie Dec 5, 2023

Choose a reason for hiding this comment

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

Oeh nice that you think about such edge cases 🚀 !

Interesting it will indeed not work if we rewrite new Object(){}.getClass().getName() as it will return null. However, it does not really make sense to write such code in one of the methods that we flag, which are specific methods from tech.picnic.errorprone or com.google.errorprone. So I think for now it's fine to not flag this 🤔.

Copy link
Member Author

Choose a reason for hiding this comment

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

Nice catch @mohamedsamehsalah! In practice we're interested in matching .getName() on class literals I see, so we can add an additional constraint for that; then the result will never be null.

Copy link
Member

@rickie rickie left a comment

Choose a reason for hiding this comment

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

Code looks nice! Good improvement 🚀!

public final class CanonicalClassNameUsage extends BugChecker
implements MethodInvocationTreeMatcher {
private static final long serialVersionUID = 1L;
private static final Matcher<ExpressionTree> GET_NAME_INVOCATION =
Copy link
Member

Choose a reason for hiding this comment

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

For these situations we use both _INVOCATION and _METHOD. I feel INVOCATION fits better here. Maybe we should apply this consistently 🤔.

Copy link
Member Author

Choose a reason for hiding this comment

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

Indeed; I had the same feeling. Last I looked into this (won't do another pass now) there were more inconsistencies, so perhaps this is something to review in a separate PR.

@rickie rickie force-pushed the sschroevers/canonical-class-name-usage branch from 2e67804 to 1fa3951 Compare December 5, 2023 12:55
Copy link

github-actions bot commented Dec 5, 2023

Looks good. All 15 mutations in this change were killed.

class surviving killed
🎉tech.picnic.errorprone.bugpatterns.CanonicalClassNameUsage 0 14
🎉tech.picnic.errorprone.bugpatterns.PrimitiveComparison 0 1

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@Stephan202 Stephan202 force-pushed the sschroevers/canonical-class-name-usage branch from 1fa3951 to 2695c4d Compare December 16, 2023 16:21
Copy link
Member Author

@Stephan202 Stephan202 left a comment

Choose a reason for hiding this comment

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

Tnx for the reviews @mohamedsamehsalah and @rickie! I rebased and added a commit.

public final class CanonicalClassNameUsage extends BugChecker
implements MethodInvocationTreeMatcher {
private static final long serialVersionUID = 1L;
private static final Matcher<ExpressionTree> GET_NAME_INVOCATION =
Copy link
Member Author

Choose a reason for hiding this comment

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

Indeed; I had the same feeling. Last I looked into this (won't do another pass now) there were more inconsistencies, so perhaps this is something to review in a separate PR.


@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
if (!GET_NAME_INVOCATION.matches(tree, state) || !isPassedToCanonicalNameUsingType(state)) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Nice catch @mohamedsamehsalah! In practice we're interested in matching .getName() on class literals I see, so we can add an additional constraint for that; then the result will never be null.

Copy link

Looks good. All 15 mutations in this change were killed.

class surviving killed
🎉tech.picnic.errorprone.bugpatterns.CanonicalClassNameUsage 0 14
🎉tech.picnic.errorprone.bugpatterns.PrimitiveComparison 0 1

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

Error Prone checks deal with source code and type matchers, both of
which generally involve canonical type names, rather than the strings
produced by `Class#getName()`. This distinction is particularly relevant
when dealing with nested types.
@rickie rickie force-pushed the sschroevers/canonical-class-name-usage branch from 2695c4d to 9307a2e Compare December 18, 2023 08:06
Copy link

Copy link

Looks good. All 15 mutations in this change were killed.

class surviving killed
🎉tech.picnic.errorprone.bugpatterns.CanonicalClassNameUsage 0 14
🎉tech.picnic.errorprone.bugpatterns.PrimitiveComparison 0 1

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@rickie rickie merged commit 626246b into master Dec 18, 2023
16 checks passed
@rickie rickie deleted the sschroevers/canonical-class-name-usage branch December 18, 2023 08:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

3 participants