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

[Fix #5388] Add new Style/UnlessLogicalOperators cop. #9386

Merged
merged 1 commit into from Feb 23, 2021

Conversation

caalberts
Copy link
Contributor

@caalberts caalberts commented Jan 17, 2021

[Fix #5388] Add new Style/UnlessLogicalOperators cop.

This cop checks for the use of && and || in an unless condition.

Before submitting the PR make sure the following are checked:

  • The PR relates to only one subject with a clear title and description in grammatically correct, complete sentences.
  • Wrote good commit messages.
  • Commit message starts with [Fix #issue-number] (if the related issue exists).
  • Feature branch is up-to-date with master (if not - rebase it).
  • Squashed related commits together.
  • Added tests.
  • Ran bundle exec rake default. It executes all tests and runs RuboCop on its own code.
  • Added an entry (file) to the changelog folder named {change_type}_{change_description}.md if the new code introduces user-observable changes. See changelog entry format for details.

@bbatsov
Copy link
Collaborator

bbatsov commented Jan 18, 2021

It seems to me it'd better if this cop had some degree of configuration - e.g. it could enforce only simple conditions (no logical operators) or allow something like the currently suggested default.

@caalberts
Copy link
Contributor Author

@bbatsov I agree it would be better to have configurable styles. I just wasn't sure what are the options to go with, so I started with this one first.

Do you have suggestions on what to name the options?

@caalberts caalberts force-pushed the cop-style-unless-mixed-conditions branch from 0114d5f to 3cb2524 Compare January 22, 2021 10:07
@caalberts
Copy link
Contributor Author

@bbatsov I added the 2 configurations suggested. What do you think?

config/default.yml Outdated Show resolved Hide resolved
@caalberts caalberts changed the title Add new Style/UnlessMixedConditions cop. Add new Style/UnlessLogicalOperators cop. Jan 23, 2021
@caalberts caalberts changed the title Add new Style/UnlessLogicalOperators cop. [Fix #5388] Add new Style/UnlessLogicalOperators cop. Jan 23, 2021
@caalberts caalberts requested a review from koic January 23, 2021 08:40
config/default.yml Outdated Show resolved Hide resolved
@bbatsov
Copy link
Collaborator

bbatsov commented Jan 23, 2021

I don't see any tests/mentions of and and or. Obviously we have to cover those as well.

@bbatsov
Copy link
Collaborator

bbatsov commented Feb 12, 2021

@caalberts ping :-)

@caalberts
Copy link
Contributor Author

tests/mentions of and and or

@bbatsov that's a great catch! Thanks for highlighting. I'll update the PR with the necessary changes.

@bbatsov bbatsov self-assigned this Feb 15, 2021
@caalberts caalberts force-pushed the cop-style-unless-mixed-conditions branch 2 times, most recently from c05184a to fcc893a Compare February 20, 2021 08:24
end

def mixed_precedence_and?(node)
node.source.include?('&&') && node.source.include?('and')
Copy link
Contributor Author

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 there is a better way to distinguish a && b && c and a && b and c.

Using node matcher doesn't work because both have the following AST:

(and
  (and
    (send nil :a)
    (send nil :b))
  (send nil :c))

Same goes for a || b || c and a || b or c.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I considered using a node matcher for a and b && c, using (if (and ... (and ...)) ...) to match the following AST:

(and
  (send nil :a)
  (and
    (send nil :b)
    (send nil :c)))

However, if we need to check the node.source anyway, then it's unnecessary to have the node matcher.

Copy link
Collaborator

Choose a reason for hiding this comment

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

That's ok. Technically you don't need to use include?, though as you can do an equality check instead (and I guess it'd be faster).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could you share an example how we can do an equality check on this?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Isn't this just a regular string? How about ==? :-)

@caalberts
Copy link
Contributor Author

@bbatsov Could you take a look again please?

VersionAdded: '<<next>>'
EnforcedStyle: forbid_mixed_logical_operator
SupportedStyles:
- forbid_mixed_logical_operator
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please, make those plural (operators).

module RuboCop
module Cop
module Style
# This cop checks for the use of logical operators in an unless condition.
Copy link
Collaborator

Choose a reason for hiding this comment

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

You can add a bit of rationale here - e.g. this cop exists to discourage hard to read/process usages of unless.

Copy link
Collaborator

Choose a reason for hiding this comment

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

In the rationale you should also briefly explain the purpose of the two supported styles.

class UnlessLogicalOperators < Base
include ConfigurableEnforcedStyle

FORBID_MIXED_LOGICAL_OPERATOR = 'Do not use mixed logical operators in an unless condition.'
Copy link
Collaborator

Choose a reason for hiding this comment

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

Put unless in backticks please.

include ConfigurableEnforcedStyle

FORBID_MIXED_LOGICAL_OPERATOR = 'Do not use mixed logical operators in an unless condition.'
FORBID_LOGICAL_OPERATOR = 'Do not use a logical operator in an unless condition.'
Copy link
Collaborator

Choose a reason for hiding this comment

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

any logical operators

@bbatsov
Copy link
Collaborator

bbatsov commented Feb 20, 2021

Just added a couple more small remarks.

@caalberts caalberts force-pushed the cop-style-unless-mixed-conditions branch from fcc893a to b14d839 Compare February 21, 2021 09:09
@caalberts caalberts force-pushed the cop-style-unless-mixed-conditions branch from b14d839 to 24bde17 Compare February 21, 2021 09:11
@bbatsov bbatsov merged commit 8322f3a into rubocop:master Feb 23, 2021
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.

Feature request: Checks that unless is not used with multiple conditions.
3 participants