fix: Do not allow TypeCastExpressions w/o parens (#8956)

This commit is contained in:
Daniel Tschinder 2018-11-05 15:34:24 -08:00 committed by GitHub
parent b95cbc4a8e
commit e3b2c1afff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 26 additions and 27 deletions

View File

@ -804,7 +804,7 @@ export default class ExpressionParser extends LValParser {
this.state.yieldInPossibleArrowParameters = null; this.state.yieldInPossibleArrowParameters = null;
const params = [this.parseIdentifier()]; const params = [this.parseIdentifier()];
this.expect(tt.arrow); this.expect(tt.arrow);
// let foo = bar => {}; // let foo = async bar => {};
this.parseArrowExpression(node, params, true); this.parseArrowExpression(node, params, true);
this.state.yieldInPossibleArrowParameters = oldYield; this.state.yieldInPossibleArrowParameters = oldYield;
return node; return node;

View File

@ -177,6 +177,7 @@ export default class LValParser extends NodeUtils {
toReferencedList( toReferencedList(
exprList: $ReadOnlyArray<?Expression>, exprList: $ReadOnlyArray<?Expression>,
isInParens?: boolean, // eslint-disable-line no-unused-vars
): $ReadOnlyArray<?Expression> { ): $ReadOnlyArray<?Expression> {
return exprList; return exprList;
} }

View File

@ -1976,40 +1976,26 @@ 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,
): $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];
if (expr && expr._exprListItem && expr.type === "TypeCastExpression") { if (
this.raise(expr.start, "Unexpected type cast"); expr &&
expr.type === "TypeCastExpression" &&
(!expr.extra || !expr.extra.parenthesized) &&
(exprList.length > 1 || !isInParens)
) {
this.raise(
expr.typeAnnotation.start,
"The type cast expression is expected to be wrapped with parenthesis",
);
} }
} }
return exprList; return exprList;
} }
// parse an item inside a expression list eg. `(NODE, NODE)` where NODE represents
// the position where this function is called
parseExprListItem(
allowEmpty: ?boolean,
refShorthandDefaultPos: ?Pos,
refNeedsArrowPos: ?Pos,
): ?N.Expression {
const container = this.startNode();
const node = super.parseExprListItem(
allowEmpty,
refShorthandDefaultPos,
refNeedsArrowPos,
);
if (this.match(tt.colon)) {
container._exprListItem = true;
container.expression = node;
container.typeAnnotation = this.flowParseTypeAnnotation();
return this.finishNode(container, "TypeCastExpression");
} else {
return node;
}
}
checkLVal( checkLVal(
expr: N.Expression, expr: N.Expression,
isBinding: ?boolean, isBinding: ?boolean,

View File

@ -2151,6 +2151,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
toReferencedList( toReferencedList(
exprList: $ReadOnlyArray<?N.Expression>, exprList: $ReadOnlyArray<?N.Expression>,
isInParens?: boolean, // eslint-disable-line no-unused-vars
): $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];

View File

@ -0,0 +1 @@
funccall(b: string);

View File

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

View File

@ -0,0 +1 @@
funccall(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 @@
(A, B: T)

View File

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

View File

@ -30,7 +30,6 @@ types/annotations_in_comments_invalid/migrated_0003.js
types/annotations/void_is_reserved_param.js types/annotations/void_is_reserved_param.js
types/member/reserved_words.js types/member/reserved_words.js
types/parameter_defaults/migrated_0032.js types/parameter_defaults/migrated_0032.js
types/typecasts_invalid/migrated_0001.js
class_method_kinds/polymorphic_getter.js class_method_kinds/polymorphic_getter.js
numbers/underscored_bin.js numbers/underscored_bin.js
numbers/underscored_float.js numbers/underscored_float.js