Skip to content

Commit

Permalink
fix: Do not allow TypeCastExpressions w/o parens
Browse files Browse the repository at this point in the history
  • Loading branch information
danez committed Nov 5, 2018
1 parent 1d4d760 commit 70a9fae
Show file tree
Hide file tree
Showing 11 changed files with 26 additions and 27 deletions.
2 changes: 1 addition & 1 deletion packages/babel-parser/src/parser/expression.js
Expand Up @@ -804,7 +804,7 @@ export default class ExpressionParser extends LValParser {
this.state.yieldInPossibleArrowParameters = null;
const params = [this.parseIdentifier()];
this.expect(tt.arrow);
// let foo = bar => {};
// let foo = async bar => {};
this.parseArrowExpression(node, params, true);
this.state.yieldInPossibleArrowParameters = oldYield;
return node;
Expand Down
1 change: 1 addition & 0 deletions packages/babel-parser/src/parser/lval.js
Expand Up @@ -177,6 +177,7 @@ export default class LValParser extends NodeUtils {

toReferencedList(
exprList: $ReadOnlyArray<?Expression>,
isInParens?: boolean, // eslint-disable-line no-unused-vars
): $ReadOnlyArray<?Expression> {
return exprList;
}
Expand Down
36 changes: 11 additions & 25 deletions packages/babel-parser/src/plugins/flow.js
Expand Up @@ -1931,40 +1931,26 @@ export default (superClass: Class<Parser>): Class<Parser> =>
// type casts that we've found that are illegal in this context
toReferencedList(
exprList: $ReadOnlyArray<?N.Expression>,
isInParens?: boolean,
): $ReadOnlyArray<?N.Expression> {
for (let i = 0; i < exprList.length; i++) {
const expr = exprList[i];
if (expr && expr._exprListItem && expr.type === "TypeCastExpression") {
this.raise(expr.start, "Unexpected type cast");
if (
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;
}

// 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(
expr: N.Expression,
isBinding: ?boolean,
Expand Down
1 change: 1 addition & 0 deletions packages/babel-parser/src/plugins/typescript.js
Expand Up @@ -2151,6 +2151,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>

toReferencedList(
exprList: $ReadOnlyArray<?N.Expression>,
isInParens?: boolean, // eslint-disable-line no-unused-vars
): $ReadOnlyArray<?N.Expression> {
for (let i = 0; i < exprList.length; i++) {
const expr = exprList[i];
Expand Down
@@ -0,0 +1 @@
funccall(b: string);
@@ -0,0 +1,3 @@
{
"throws": "The type cast expression is expected to be wrapped with parenthesis (1:10)"
}
@@ -0,0 +1 @@
funccall(a, b: string);
@@ -0,0 +1,3 @@
{
"throws": "The type cast expression is expected to be wrapped with parenthesis (1:13)"
}
@@ -0,0 +1 @@
(A, B: T)
@@ -0,0 +1,3 @@
{
"throws": "The type cast expression is expected to be wrapped with parenthesis (1:5)"
}
1 change: 0 additions & 1 deletion scripts/tests/flow/flow_tests_whitelist.txt
Expand Up @@ -31,7 +31,6 @@ types/annotations_in_comments_invalid/migrated_0003.js
types/annotations/void_is_reserved_param.js
types/member/reserved_words.js
types/parameter_defaults/migrated_0032.js
types/typecasts_invalid/migrated_0001.js
class_method_kinds/polymorphic_getter.js
numbers/underscored_bin.js
numbers/underscored_float.js
Expand Down

0 comments on commit 70a9fae

Please sign in to comment.