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
New rule: no mixed logical operators #6023
Comments
The last passing example is at an intersection of rules. Not sure if that is considered a conflict, or not. a || (b && c)
The exception option allows extra parentheses. I think you are proposing a rule which requires them when a logical expression contains operators with different precedence. |
@jfmengels Was thinking about some more neutrally-named rules like |
Ah, I though that the logical AND and the logical OR had the same precedence, but you're right, they don't (OR has lower precedence). I was not thinking it that far ahead, simply trying to handle this simple case. I did wonder whether the rule should also apply to operators like addition/multiplication, but didn't want to make it way more complicated than it should be (though open to discussion on this).
I'm not too familiar with JSCS' rules, but could unfortunately not find any resembling this. The difference between this rule and |
For my own learning, I will search for a rule which has options to disallow, require, or allow something. Was just reading about |
I'm a champion. This rule is opposite of a part of This is not a JSCS compatibility issue. |
Isn't this just an issue of order of operations rather than logical operator mixing? |
That would work for me 👍
Hmm, in a way I guess... But even if you're ordering operations like |
@mysticatea if this is opposite of @jfmengels are you willing to create this rule if it's accepted? (See http://eslint.org/docs/developer-guide/contributing/new-rules) We still need three 👍s from the team to implement. |
Absolutely. I understand the conflict with |
@nzakas |
@mysticatea okay, thanks for explaining. Again, let's make sure that we think this rule proposal is extremely important to be included in ESLint. |
I think this is a stylistic preferences that is hard to enforce 100% correctly (as in, I, for example, prefer to wrap nested logical operators like that only in a case I have more then 2 of them), I think this might be better as a plugin. |
@eslint/eslint-team we need some more opinions here. |
Agree with #6023 (comment) that there would be differences of opinion when a rule should require the extra parentheses. In the existing doc, I intend to give stronger explanation for benefits of following config which allows extra parens in cases like the original problem:
But leave it to human code reviewer on teams to decide exactly how much they need. |
|
Okay, @mysticatea feels strongly, do it 👍 |
@nzakas Is this accepted? |
I'm a champion, but I have not gotten 3 👍s from core team yet. If this is accepted, I will work on this. |
Here's another one 👍 |
👍 |
@michaelficarra expressed disagreement about this, so I think the 3 votes aren't enough in this case. |
I don't see how this is specific to logical operators. Any infix operators with mixed precedence can cause an issue if left unparenthesised. For instance, I may intend |
One could argue that there's a difference in comprehensibility between That said, I agree with @michaelficarra and wonder if no-extra-parens
|
Yes, an active dissent means we need to talk through this some more. |
Thank you, everyone, I'm happy 😄 I did not have the rule's idea for parentheses of arithmetic operators. no-mixed-operatorsEnclosing complex expressions by parentheses makes more clarity of developer's intention, then the code would get more readability. This rule warns a use of mixed operators in a expression. var foo = a && b || c || d; /*error Unexpected a mix of `&&` and `||`.*/ This rule checks Options{
"no-mixed-operators": ["error", {
"ignore": []
}]
}
Examples/*eslint no-mixed-operators: "error" */
// ✘ BAD
var foo = a && b || c || d;
var foo = a + b * c;
// ✔ GOOD
var foo = (a && b) || c || d;
var foo = a && (b || c || d);
var foo = a + (b * c);
var foo = (a + b) * c; /*eslint no-mixed-operators: ["error", {"ignore": ["+", "-", "*", "/"]}] */
// ✘ BAD
var foo = a && b || c || d;
// ✔ GOOD
var foo = (a && b) || c || d;
var foo = a && (b || c || d);
var foo = a + b * c;
var foo = a + (b * c);
var foo = (a + b) * c; Hmm, the option to make comparison group might be wanted. (e.g. bit operators group, logical operators group, ...) |
I rethought my proposal. The new proposal has no-mixed-operatorsEnclosing complex expressions by parentheses makes more clarity of developer's intention, then the code would get more readability. This rule warns a use of mixed operators in an expression. var foo = a && b || c || d; /*error Unexpected a mix of `&&` and `||`.*/ This rule checks Options{
"no-mixed-operators": ["error", {
"groups": []
}]
}
Examples/*eslint no-mixed-operators: "error" */
// ✘ BAD
var foo = a && b || c > 0 || d + 1 === 0;
var foo = a + b * c;
// ✔ GOOD
var foo = (a && b) || (c > 0) || ((d + 1) === 0);
var foo = a && (b || (c > 0) || ((d + 1) === 0));
var foo = a + (b * c);
var foo = (a + b) * c; /*eslint no-mixed-operators: ["error", {"groups": [["+", "-", "*", "/"], ["||", "&&"]]}] */
// ✘ BAD
var foo = a && b || c > 0 || d + 1 === 0;
var foo = a + b * c;
// ✔ GOOD
var foo = (a && b) || c > 0 || d + 1 === 0;
var foo = a && (b || c > 0 || d + 1 === 0);
var foo = a + (b * c);
var foo = (a + b) * c; /*eslint no-mixed-operators: ["error", {"groups": [["||", "&&"]]}] */
// ✘ BAD
var foo = a && b || c > 0 || d + 1 === 0;
// ✔ GOOD
var foo = (a && b) || c > 0 || d + 1 === 0;
var foo = a && (b || c > 0 || d + 1 === 0);
var foo = a + b * c;
var foo = a + (b * c);
var foo = (a + b) * c; |
I really like the groups proposal but I think we may want to have a couple of keywords as shorthand: |
@mysticatea I'm not sure I got this: In both your examples, would And i was about to propose the same thing as @mikesherov: keywords/"presets" of operators. I think that a lot of people would not think of adding the |
Thank you for the feedbacks! Presets idea looks great!
|
@mysticatea That's not a breaking change, since they were not using the operator before it was added to the language. You can think of it as the operator always having been in the preset. |
It is for people who were using |
@jfmengels No, the rule will support whatever is supported by the default parser. If someone uses a different parser, they need to use different rules. This project cannot be concerned with making each of its rules work with every imaginable parser. |
presets should definitely include new operators as they're added to the language. exponentiation operator is a mathematical operator. To not have it in the |
Honestly, I want not to add presets for this time. JS has keyword operators, so presets may be confusable.
Instead, documents show categories of operators (copyable). |
I updated the reference implementation. The default value of options has changed. May this go forward? |
Marking as accepted since there's a champion and 3 +1s from the team. |
We need to resolve the disagreement before moving forward. @michaelficarra are your concerns addressed? |
@nzakas Yes, my concern was that this rule only applied to logical operators. Now that it has been re-envisioned to lint all binary operators, it's fine. |
Thank you very much! ✨ |
I'm proposing a rule that warns when logical operators like
&&
and||
are mixed. The purpose is to avoid errors like the one fixed here:In this example, we are mixing
&&
and||
. We are probably expecting not to enter inside theif
block ifa
is falsya.b
is neither1
nor2
but what the actual operation will be is
(a && a.b === 1) || a.b === 2
. Meaning, ifa
isundefined
, then we will be evaluatinga.b === 2
, which will create an error.If we had wrapped our different conditions in parentheses
a && (a.b === 1 || a.b === 2)
, then this would have resulted in the wanted behavior.Fail
Pass
I think the rule is pretty generic and can help avoid "easy" mistakes, and therefore has it's place in ESLint. I don't mind adding it to a custom plugin otherwise. I'd be happy to write the rule :)
The text was updated successfully, but these errors were encountered: