Fix flow errors with Logical Assignment Operators (#7629)

* Fix flow errors with logical assignment

* Fix column numbers
This commit is contained in:
Justin Ridgewell 2018-03-25 22:47:48 +01:00 committed by GitHub
parent a7bddc02ba
commit ab7d1231ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 20 deletions

View File

@ -151,7 +151,16 @@ export default class ExpressionParser extends LValParser {
}
if (this.state.type.isAssign) {
const node = this.startNodeAt(startPos, startLoc);
node.operator = this.state.value;
const operator = this.state.value;
node.operator = operator;
if (operator === "??=") {
this.expectPlugin("nullishCoalescingOperator");
this.expectPlugin("logicalAssignment");
}
if (operator === "||=" || operator === "&&=") {
this.expectPlugin("logicalAssignment");
}
node.left = this.match(tt.eq)
? this.toAssignable(left, undefined, "assignment expression")
: left;
@ -271,11 +280,12 @@ export default class ExpressionParser extends LValParser {
if (prec != null && (!noIn || !this.match(tt._in))) {
if (prec > minPrec) {
const node = this.startNodeAt(leftStartPos, leftStartLoc);
const operator = this.state.value;
node.left = left;
node.operator = this.state.value;
node.operator = operator;
if (
node.operator === "**" &&
operator === "**" &&
left.type === "UnaryExpression" &&
left.extra &&
!left.extra.parenthesizedArgument &&
@ -288,13 +298,18 @@ export default class ExpressionParser extends LValParser {
}
const op = this.state.type;
if (op === tt.nullishCoalescing) {
this.expectPlugin("nullishCoalescingOperator");
} else if (op === tt.pipeline) {
this.expectPlugin("pipelineOperator");
}
this.next();
const startPos = this.state.start;
const startLoc = this.state.startLoc;
if (node.operator === "|>") {
this.expectPlugin("pipelineOperator");
if (op === tt.pipeline) {
// Support syntax such as 10 |> x => x + 1
this.state.potentialArrowAt = startPos;
}

View File

@ -464,18 +464,14 @@ export default class Tokenizer extends LocationParser {
const next = this.input.charCodeAt(this.state.pos + 1);
if (next === code) {
const assign =
this.input.charCodeAt(this.state.pos + 2) === charCodes.equalsTo;
if (assign) {
// $FlowFixMe
this.expectPlugin("logicalAssignment");
if (this.input.charCodeAt(this.state.pos + 2) === charCodes.equalsTo) {
this.finishOp(tt.assign, 3);
} else {
this.finishOp(
code === charCodes.verticalBar ? tt.logicalOR : tt.logicalAND,
2,
);
}
this.finishOp(
assign
? tt.assign
: code === charCodes.verticalBar ? tt.logicalOR : tt.logicalAND,
assign ? 3 : 2,
);
return;
}
@ -607,11 +603,8 @@ export default class Tokenizer extends LocationParser {
const next = this.input.charCodeAt(this.state.pos + 1);
const next2 = this.input.charCodeAt(this.state.pos + 2);
if (next === charCodes.questionMark) {
this.expectPlugin("nullishCoalescingOperator");
if (next2 === charCodes.equalsTo) {
// '??='
this.expectPlugin("logicalAssignment");
this.finishOp(tt.assign, 3);
} else {
// '??'

View File

@ -1,3 +1,3 @@
{
"throws": "This experimental syntax requires enabling the parser plugin: 'pipelineOperator' (1:5)"
"throws": "This experimental syntax requires enabling the parser plugin: 'pipelineOperator' (1:2)"
}