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

Add Lint/DuplicateBranch rule #582

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Conversation

Sija
Copy link
Member

@Sija Sija commented Feb 24, 2025

No description provided.

@Sija Sija added the rule label Feb 24, 2025
@Sija Sija added this to the 1.7.0 milestone Feb 24, 2025
@Sija Sija requested a review from veelenga February 24, 2025 15:46
@Sija Sija self-assigned this Feb 24, 2025
@Sija Sija force-pushed the lint-duplicate-branch-rule branch 3 times, most recently from 19818c8 to 3337681 Compare February 25, 2025 01:33
@Sija Sija marked this pull request as ready for review February 25, 2025 01:35
@Sija Sija force-pushed the lint-duplicate-branch-rule branch from 3337681 to bbeb92a Compare February 25, 2025 01:37
Copy link
Member

@veelenga veelenga left a comment

Choose a reason for hiding this comment

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

Review still WIP

@@ -27,7 +27,7 @@ module Ameba
def color : Colorize::Color
case self
in Error then Colorize::ColorANSI::Red
in Warning then Colorize::ColorANSI::Red
in Warning then Colorize::ColorANSI::Red # ameba:disable Lint/DuplicateBranch
Copy link
Member

Choose a reason for hiding this comment

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

can't this be reworked in a way when the disable directive is not needed?

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe this indicates that duplicate paths in a case body should be accepted?

Copy link
Member Author

Choose a reason for hiding this comment

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

@straight-shoota There's already IgnoreConstantBranches option for that.

Copy link
Member Author

Choose a reason for hiding this comment

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

@veelenga Easiest way to do it is changing the color value.

Copy link
Contributor

Choose a reason for hiding this comment

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

Then maybe that option should be enabled by default?

Copy link
Member Author

Choose a reason for hiding this comment

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

@straight-shoota I'm open to see good use cases of this behavior. This case is IMO a great example where this rule uncovers dubious choices, since this branch shouldn't be repeated in the first place.

Copy link
Member Author

Choose a reason for hiding this comment

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

@veelenga I'd suggest leaving it as-is for now and changing the returned value in a separate PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

This btw uncovers the fact that we only have a single rule - Lint/Syntax - with an Error severity.

Copy link
Contributor

@straight-shoota straight-shoota Feb 25, 2025

Choose a reason for hiding this comment

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

As mentioned before, especially case with then branches is often used for mappings. When the set of input values is bigger than the output set, there'll be multiple inputs pointing to the same output. And that's totally fine within the domain model.
However, I don't think there's a clear preference about how to express that in code. Sometimes it might be best to group input values which lead to the same value. Sometimes it's better to keep the input values separate and in their implicit order, for example.
IMO ameba shouldn't take preference here because this is a style matter specific to each individual use case.

Sure, having more strict rules may uncover dubious choices like the example here.
But there's also a high chance of too many false positives.
I think the default behaviour should be cautious to avoid noise. Nobody want's to deal with long reports of false violations.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree. Too many rule violations highlighting too much of the document, especially for things that are IMO more stylistic choices, will turn people away from using ameba and it's editor integrations. If this rule should be added I think it should be disabled by default.

@Sija Sija force-pushed the lint-duplicate-branch-rule branch from bbeb92a to 17feb3b Compare February 25, 2025 15:19
Comment on lines +140 to +143
when Crystal::UninitializedVar then eql?(assign.var)
when Crystal::Assign, Crystal::OpAssign then eql?(assign.target)
when Crystal::MultiAssign
assign.targets.any? { |target| eql?(target) }
Copy link
Contributor

@straight-shoota straight-shoota Feb 25, 2025

Choose a reason for hiding this comment

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

I'm not sure if this change (and similar above) is a good choice.

This aspect has not yet been mentioned in the discussion or anywhere in the documentation and specs: some conditions have an effect on flow typing and merging conditions affects typing.

Here the different branches have technically the same body. But combining them introduce a union type Crystal::Assign | Crystal::OpAssign which can lead to all kinds of potentially unintended consequences.

If we keep the branches separate, the type of assign is restricted to the respective type.

The compiler uses this pattern intentionally in a number of places (including ones dealing with switching over AST nodes). So I would assume it's also intentional here.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't see how this affects dispatch, see here: https://carc.in/#/r/hqb4

@@ -27,7 +27,7 @@ module Ameba
def color : Colorize::Color
case self
in Error then Colorize::ColorANSI::Red
in Warning then Colorize::ColorANSI::Red
in Warning then Colorize::ColorANSI::Red # ameba:disable Lint/DuplicateBranch
Copy link
Contributor

@straight-shoota straight-shoota Feb 25, 2025

Choose a reason for hiding this comment

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

As mentioned before, especially case with then branches is often used for mappings. When the set of input values is bigger than the output set, there'll be multiple inputs pointing to the same output. And that's totally fine within the domain model.
However, I don't think there's a clear preference about how to express that in code. Sometimes it might be best to group input values which lead to the same value. Sometimes it's better to keep the input values separate and in their implicit order, for example.
IMO ameba shouldn't take preference here because this is a style matter specific to each individual use case.

Sure, having more strict rules may uncover dubious choices like the example here.
But there's also a high chance of too many false positives.
I think the default behaviour should be cautious to avoid noise. Nobody want's to deal with long reports of false violations.

@Sija Sija force-pushed the lint-duplicate-branch-rule branch from 17feb3b to 28837ac Compare February 25, 2025 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants