[flow] Allow type casts in array patterns inside arrow parameters (#9069)

This commit is contained in:
Nicolò Ribaudo 2018-11-24 12:23:49 +01:00 committed by GitHub
parent d2971a1959
commit 856edbf95f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 1801 additions and 6 deletions

View File

@ -566,7 +566,7 @@ export default class ExpressionParser extends LValParser {
); );
this.state.yieldOrAwaitInPossibleArrowParameters = oldYOAIPAP; this.state.yieldOrAwaitInPossibleArrowParameters = oldYOAIPAP;
} else { } else {
this.toReferencedList(node.arguments); this.toReferencedListDeep(node.arguments);
// We keep the old value if it isn't null, for cases like // We keep the old value if it isn't null, for cases like
// (x = async(yield)) => {} // (x = async(yield)) => {}
@ -891,7 +891,14 @@ export default class ExpressionParser extends LValParser {
true, true,
refShorthandDefaultPos, refShorthandDefaultPos,
); );
this.toReferencedList(node.elements); if (!this.state.maybeInArrowParameters) {
// This could be an array pattern:
// ([a: string, b: string]) => {}
// In this case, we don't have to call toReferencedList. We will
// call it, if needed, when we are sure that it is a parenthesized
// expression by calling toReferencedListDeep.
this.toReferencedList(node.elements);
}
return this.finishNode(node, "ArrayExpression"); return this.finishNode(node, "ArrayExpression");
case tt.braceL: case tt.braceL:
@ -1173,10 +1180,10 @@ export default class ExpressionParser extends LValParser {
} }
if (refNeedsArrowPos.start) this.unexpected(refNeedsArrowPos.start); if (refNeedsArrowPos.start) this.unexpected(refNeedsArrowPos.start);
this.toReferencedListDeep(exprList, /* isParenthesizedExpr */ true);
if (exprList.length > 1) { if (exprList.length > 1) {
val = this.startNodeAt(innerStartPos, innerStartLoc); val = this.startNodeAt(innerStartPos, innerStartLoc);
val.expressions = exprList; val.expressions = exprList;
this.toReferencedList(val.expressions);
this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc); this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
} else { } else {
val = exprList[0]; val = exprList[0];

View File

@ -177,11 +177,26 @@ export default class LValParser extends NodeUtils {
toReferencedList( toReferencedList(
exprList: $ReadOnlyArray<?Expression>, exprList: $ReadOnlyArray<?Expression>,
isInParens?: boolean, // eslint-disable-line no-unused-vars isParenthesizedExpr?: boolean, // eslint-disable-line no-unused-vars
): $ReadOnlyArray<?Expression> { ): $ReadOnlyArray<?Expression> {
return exprList; return exprList;
} }
toReferencedListDeep(
exprList: $ReadOnlyArray<?Expression>,
isParenthesizedExpr?: boolean,
): $ReadOnlyArray<?Expression> {
this.toReferencedList(exprList, isParenthesizedExpr);
for (const expr of exprList) {
if (expr && expr.type === "ArrayExpression") {
this.toReferencedListDeep(expr.elements);
}
}
return exprList;
}
// Parses spread element. // Parses spread element.
parseSpread<T: RestElement | SpreadElement>( parseSpread<T: RestElement | SpreadElement>(

View File

@ -1977,7 +1977,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
// type casts that we've found that are illegal in this context // type casts that we've found that are illegal in this context
toReferencedList( toReferencedList(
exprList: $ReadOnlyArray<?N.Expression>, exprList: $ReadOnlyArray<?N.Expression>,
isInParens?: boolean, isParenthesizedExpr?: boolean,
): $ReadOnlyArray<?N.Expression> { ): $ReadOnlyArray<?N.Expression> {
for (let i = 0; i < exprList.length; i++) { for (let i = 0; i < exprList.length; i++) {
const expr = exprList[i]; const expr = exprList[i];
@ -1985,7 +1985,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
expr && expr &&
expr.type === "TypeCastExpression" && expr.type === "TypeCastExpression" &&
(!expr.extra || !expr.extra.parenthesized) && (!expr.extra || !expr.extra.parenthesized) &&
(exprList.length > 1 || !isInParens) (exprList.length > 1 || !isParenthesizedExpr)
) { ) {
this.raise( this.raise(
expr.typeAnnotation.start, expr.typeAnnotation.start,

View File

@ -0,0 +1 @@
[a: string];

View File

@ -0,0 +1,3 @@
{
"throws": "The type cast expression is expected to be wrapped with parenthesis (1:2)"
}

View File

@ -0,0 +1 @@
([a: string]);

View File

@ -0,0 +1,3 @@
{
"throws": "The type cast expression is expected to be wrapped with parenthesis (1:3)"
}

View File

@ -0,0 +1 @@
([a, [b: string]]);

View File

@ -0,0 +1,3 @@
{
"throws": "The type cast expression is expected to be wrapped with parenthesis (1:7)"
}

View File

@ -0,0 +1 @@
async ([a: string]);

View File

@ -0,0 +1,3 @@
{
"throws": "The type cast expression is expected to be wrapped with parenthesis (1:9)"
}

View File

@ -0,0 +1 @@
async ([a, [b: string]]);

View File

@ -0,0 +1,3 @@
{
"throws": "The type cast expression is expected to be wrapped with parenthesis (1:13)"
}

View File

@ -0,0 +1,14 @@
([a: string]) => {};
([a, [b: string]]) => {};
([a: string] = []) => {};
({ x: [a: string] }) => {};
async ([a: string]) => {};
async ([a, [b: string]]) => {};
async ([a: string] = []) => {};
async ({ x: [a: string] }) => {};
let [a: string] = c;
let [a, [b: string]] = c;
let [a: string] = c;
let { x: [a: string] } = c;

File diff suppressed because it is too large Load Diff