Fix parenthesis for nullish coalescing (#10269)
* ♻️ added condition to check for left and right of nullish coalescing operator and if any is a logical expression without a paren then throw an error * 🐛 bugs fixed and test cases updated for babel parser * ♻️ code comments added * 🐛 spell error rectified * ♻️ failing test updated * 🐛 push tests after make build * Skip nullish-coalescing flow precedence tests They're now incorrect * ♻️ error message updated, binop priority of other logical operators +1 from ?? and * ♻️ increaed the binOp for in and instanceOf, added logic to print the brackets in an ?? && || expression, test cases added * 🐛 failing test fixed and comments updated * ♻️ new lines added between tests * ♻️ basic tests for checking the binOp of instanceOf, in and relational operators to be equal added * ♻️ new lines added in between tests
This commit is contained in:
committed by
Nicolò Ribaudo
parent
3e8a5c5e28
commit
b02e35c19a
@@ -380,6 +380,39 @@ export default class ExpressionParser extends LValParser {
|
||||
|
||||
node.right = this.parseExprOpRightExpr(op, prec, noIn);
|
||||
|
||||
/* this check is for all ?? operators
|
||||
* a ?? b && c for this example
|
||||
* b && c => This is considered as a logical expression in the ast tree
|
||||
* a => Identifier
|
||||
* so for ?? operator we need to check in this case the right expression to have parenthesis
|
||||
* second case a && b ?? c
|
||||
* here a && b => This is considered as a logical expression in the ast tree
|
||||
* c => identifer
|
||||
* so now here for ?? operator we need to check the left expression to have parenthesis
|
||||
* if the parenthesis is missing we raise an error and throw it
|
||||
*/
|
||||
if (op === tt.nullishCoalescing) {
|
||||
if (
|
||||
left.type === "LogicalExpression" &&
|
||||
left.operator !== "??" &&
|
||||
!(left.extra && left.extra.parenthesized)
|
||||
) {
|
||||
throw this.raise(
|
||||
left.start,
|
||||
`Nullish coalescing operator(??) requires parens when mixing with logical operators`,
|
||||
);
|
||||
} else if (
|
||||
node.right.type === "LogicalExpression" &&
|
||||
node.right.operator !== "??" &&
|
||||
!(node.right.extra && node.right.extra.parenthesized)
|
||||
) {
|
||||
throw this.raise(
|
||||
node.right.start,
|
||||
`Nullish coalescing operator(??) requires parens when mixing with logical operators`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.finishNode(
|
||||
node,
|
||||
op === tt.logicalOR ||
|
||||
|
||||
@@ -139,21 +139,21 @@ export const types: { [name: string]: TokenType } = {
|
||||
tilde: new TokenType("~", { beforeExpr, prefix, startsExpr }),
|
||||
pipeline: createBinop("|>", 0),
|
||||
nullishCoalescing: createBinop("??", 1),
|
||||
logicalOR: createBinop("||", 1),
|
||||
logicalAND: createBinop("&&", 2),
|
||||
bitwiseOR: createBinop("|", 3),
|
||||
bitwiseXOR: createBinop("^", 4),
|
||||
bitwiseAND: createBinop("&", 5),
|
||||
equality: createBinop("==/!=/===/!==", 6),
|
||||
relational: createBinop("</>/<=/>=", 7),
|
||||
bitShift: createBinop("<</>>/>>>", 8),
|
||||
plusMin: new TokenType("+/-", { beforeExpr, binop: 9, prefix, startsExpr }),
|
||||
modulo: createBinop("%", 10),
|
||||
star: createBinop("*", 10),
|
||||
slash: createBinop("/", 10),
|
||||
logicalOR: createBinop("||", 2),
|
||||
logicalAND: createBinop("&&", 3),
|
||||
bitwiseOR: createBinop("|", 4),
|
||||
bitwiseXOR: createBinop("^", 5),
|
||||
bitwiseAND: createBinop("&", 6),
|
||||
equality: createBinop("==/!=/===/!==", 7),
|
||||
relational: createBinop("</>/<=/>=", 8),
|
||||
bitShift: createBinop("<</>>/>>>", 9),
|
||||
plusMin: new TokenType("+/-", { beforeExpr, binop: 10, prefix, startsExpr }),
|
||||
modulo: createBinop("%", 11),
|
||||
star: createBinop("*", 11),
|
||||
slash: createBinop("/", 11),
|
||||
exponent: new TokenType("**", {
|
||||
beforeExpr,
|
||||
binop: 11,
|
||||
binop: 12,
|
||||
rightAssociative: true,
|
||||
}),
|
||||
|
||||
@@ -188,8 +188,8 @@ export const types: { [name: string]: TokenType } = {
|
||||
_null: createKeyword("null", { startsExpr }),
|
||||
_true: createKeyword("true", { startsExpr }),
|
||||
_false: createKeyword("false", { startsExpr }),
|
||||
_in: createKeyword("in", { beforeExpr, binop: 7 }),
|
||||
_instanceof: createKeyword("instanceof", { beforeExpr, binop: 7 }),
|
||||
_in: createKeyword("in", { beforeExpr, binop: 8 }),
|
||||
_instanceof: createKeyword("instanceof", { beforeExpr, binop: 8 }),
|
||||
_typeof: createKeyword("typeof", { beforeExpr, prefix, startsExpr }),
|
||||
_void: createKeyword("void", { beforeExpr, prefix, startsExpr }),
|
||||
_delete: createKeyword("delete", { beforeExpr, prefix, startsExpr }),
|
||||
|
||||
Reference in New Issue
Block a user