Trailing comma after rest - The final fix (#10491)
* [parser] Track trailing commas in extras instead of state * Update existing tests * Update test262 whitelist * Improve error message and location * nit * Use lookaheadCharCode
This commit is contained in:
parent
c7add11fdc
commit
34937f13d5
@ -168,9 +168,6 @@ export default class ExpressionParser extends LValParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const oldCommaAfterSpreadAt = this.state.commaAfterSpreadAt;
|
|
||||||
this.state.commaAfterSpreadAt = -1;
|
|
||||||
|
|
||||||
let failOnShorthandAssign;
|
let failOnShorthandAssign;
|
||||||
if (refShorthandDefaultPos) {
|
if (refShorthandDefaultPos) {
|
||||||
failOnShorthandAssign = false;
|
failOnShorthandAssign = false;
|
||||||
@ -230,9 +227,6 @@ export default class ExpressionParser extends LValParser {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (patternErrorMsg) this.checkCommaAfterRestFromSpread();
|
|
||||||
this.state.commaAfterSpreadAt = oldCommaAfterSpreadAt;
|
|
||||||
|
|
||||||
this.next();
|
this.next();
|
||||||
node.right = this.parseMaybeAssign(noIn);
|
node.right = this.parseMaybeAssign(noIn);
|
||||||
return this.finishNode(node, "AssignmentExpression");
|
return this.finishNode(node, "AssignmentExpression");
|
||||||
@ -240,8 +234,6 @@ export default class ExpressionParser extends LValParser {
|
|||||||
this.unexpected(refShorthandDefaultPos.start);
|
this.unexpected(refShorthandDefaultPos.start);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.state.commaAfterSpreadAt = oldCommaAfterSpreadAt;
|
|
||||||
|
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -680,14 +672,12 @@ export default class ExpressionParser extends LValParser {
|
|||||||
let node = this.startNodeAt(startPos, startLoc);
|
let node = this.startNodeAt(startPos, startLoc);
|
||||||
node.callee = base;
|
node.callee = base;
|
||||||
|
|
||||||
const oldCommaAfterSpreadAt = this.state.commaAfterSpreadAt;
|
|
||||||
this.state.commaAfterSpreadAt = -1;
|
|
||||||
|
|
||||||
node.arguments = this.parseCallExpressionArguments(
|
node.arguments = this.parseCallExpressionArguments(
|
||||||
tt.parenR,
|
tt.parenR,
|
||||||
state.maybeAsyncArrow,
|
state.maybeAsyncArrow,
|
||||||
base.type === "Import",
|
base.type === "Import",
|
||||||
base.type !== "Super",
|
base.type !== "Super",
|
||||||
|
node,
|
||||||
);
|
);
|
||||||
if (!state.optionalChainMember) {
|
if (!state.optionalChainMember) {
|
||||||
this.finishCallExpression(node);
|
this.finishCallExpression(node);
|
||||||
@ -698,8 +688,6 @@ export default class ExpressionParser extends LValParser {
|
|||||||
if (state.maybeAsyncArrow && this.shouldParseAsyncArrow()) {
|
if (state.maybeAsyncArrow && this.shouldParseAsyncArrow()) {
|
||||||
state.stop = true;
|
state.stop = true;
|
||||||
|
|
||||||
this.checkCommaAfterRestFromSpread();
|
|
||||||
|
|
||||||
node = this.parseAsyncArrowFromCallExpression(
|
node = this.parseAsyncArrowFromCallExpression(
|
||||||
this.startNodeAt(startPos, startLoc),
|
this.startNodeAt(startPos, startLoc),
|
||||||
node,
|
node,
|
||||||
@ -743,7 +731,6 @@ export default class ExpressionParser extends LValParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.state.maybeInArrowParameters = oldMaybeInArrowParameters;
|
this.state.maybeInArrowParameters = oldMaybeInArrowParameters;
|
||||||
this.state.commaAfterSpreadAt = oldCommaAfterSpreadAt;
|
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
} else if (this.match(tt.backQuote)) {
|
} else if (this.match(tt.backQuote)) {
|
||||||
@ -825,6 +812,7 @@ export default class ExpressionParser extends LValParser {
|
|||||||
possibleAsyncArrow: boolean,
|
possibleAsyncArrow: boolean,
|
||||||
dynamicImport?: boolean,
|
dynamicImport?: boolean,
|
||||||
allowPlaceholder?: boolean,
|
allowPlaceholder?: boolean,
|
||||||
|
nodeForExtra?: ?N.Node,
|
||||||
): $ReadOnlyArray<?N.Expression> {
|
): $ReadOnlyArray<?N.Expression> {
|
||||||
const elts = [];
|
const elts = [];
|
||||||
let innerParenStart;
|
let innerParenStart;
|
||||||
@ -837,13 +825,21 @@ export default class ExpressionParser extends LValParser {
|
|||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
this.expect(tt.comma);
|
this.expect(tt.comma);
|
||||||
if (this.eat(close)) {
|
if (this.match(close)) {
|
||||||
if (dynamicImport) {
|
if (dynamicImport) {
|
||||||
this.raise(
|
this.raise(
|
||||||
this.state.lastTokStart,
|
this.state.lastTokStart,
|
||||||
"Trailing comma is disallowed inside import(...) arguments",
|
"Trailing comma is disallowed inside import(...) arguments",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (nodeForExtra) {
|
||||||
|
this.addExtra(
|
||||||
|
nodeForExtra,
|
||||||
|
"trailingComma",
|
||||||
|
this.state.lastTokStart,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this.next();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -883,7 +879,12 @@ export default class ExpressionParser extends LValParser {
|
|||||||
call: N.CallExpression,
|
call: N.CallExpression,
|
||||||
): N.ArrowFunctionExpression {
|
): N.ArrowFunctionExpression {
|
||||||
this.expect(tt.arrow);
|
this.expect(tt.arrow);
|
||||||
this.parseArrowExpression(node, call.arguments, true);
|
this.parseArrowExpression(
|
||||||
|
node,
|
||||||
|
call.arguments,
|
||||||
|
true,
|
||||||
|
call.extra?.trailingComma,
|
||||||
|
);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1046,6 +1047,7 @@ export default class ExpressionParser extends LValParser {
|
|||||||
tt.bracketR,
|
tt.bracketR,
|
||||||
true,
|
true,
|
||||||
refShorthandDefaultPos,
|
refShorthandDefaultPos,
|
||||||
|
node,
|
||||||
);
|
);
|
||||||
if (!this.state.maybeInArrowParameters) {
|
if (!this.state.maybeInArrowParameters) {
|
||||||
// This could be an array pattern:
|
// This could be an array pattern:
|
||||||
@ -1289,7 +1291,7 @@ export default class ExpressionParser extends LValParser {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.checkCommaAfterRest();
|
this.checkCommaAfterRest(charCodes.rightParenthesis);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@ -1504,7 +1506,11 @@ export default class ExpressionParser extends LValParser {
|
|||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
this.expect(tt.comma);
|
this.expect(tt.comma);
|
||||||
if (this.eat(tt.braceR)) break;
|
if (this.match(tt.braceR)) {
|
||||||
|
this.addExtra(node, "trailingComma", this.state.lastTokStart);
|
||||||
|
this.next();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const prop = this.parseObjectMember(isPattern, refShorthandDefaultPos);
|
const prop = this.parseObjectMember(isPattern, refShorthandDefaultPos);
|
||||||
@ -1572,7 +1578,7 @@ export default class ExpressionParser extends LValParser {
|
|||||||
this.next();
|
this.next();
|
||||||
// Don't use parseRestBinding() as we only allow Identifier here.
|
// Don't use parseRestBinding() as we only allow Identifier here.
|
||||||
prop.argument = this.parseIdentifier();
|
prop.argument = this.parseIdentifier();
|
||||||
this.checkCommaAfterRest();
|
this.checkCommaAfterRest(charCodes.rightCurlyBrace);
|
||||||
return this.finishNode(prop, "RestElement");
|
return this.finishNode(prop, "RestElement");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1856,6 +1862,7 @@ export default class ExpressionParser extends LValParser {
|
|||||||
node: N.ArrowFunctionExpression,
|
node: N.ArrowFunctionExpression,
|
||||||
params: ?(N.Expression[]),
|
params: ?(N.Expression[]),
|
||||||
isAsync: boolean,
|
isAsync: boolean,
|
||||||
|
trailingCommaPos: ?number,
|
||||||
): N.ArrowFunctionExpression {
|
): N.ArrowFunctionExpression {
|
||||||
this.scope.enter(functionFlags(isAsync, false) | SCOPE_ARROW);
|
this.scope.enter(functionFlags(isAsync, false) | SCOPE_ARROW);
|
||||||
this.initFunction(node, isAsync);
|
this.initFunction(node, isAsync);
|
||||||
@ -1867,7 +1874,7 @@ export default class ExpressionParser extends LValParser {
|
|||||||
this.state.yieldPos = -1;
|
this.state.yieldPos = -1;
|
||||||
this.state.awaitPos = -1;
|
this.state.awaitPos = -1;
|
||||||
|
|
||||||
if (params) this.setArrowFunctionParameters(node, params);
|
if (params) this.setArrowFunctionParameters(node, params, trailingCommaPos);
|
||||||
this.parseFunctionBody(node, true);
|
this.parseFunctionBody(node, true);
|
||||||
|
|
||||||
this.scope.exit();
|
this.scope.exit();
|
||||||
@ -1881,11 +1888,13 @@ export default class ExpressionParser extends LValParser {
|
|||||||
setArrowFunctionParameters(
|
setArrowFunctionParameters(
|
||||||
node: N.ArrowFunctionExpression,
|
node: N.ArrowFunctionExpression,
|
||||||
params: N.Expression[],
|
params: N.Expression[],
|
||||||
|
trailingCommaPos: ?number,
|
||||||
): void {
|
): void {
|
||||||
node.params = this.toAssignableList(
|
node.params = this.toAssignableList(
|
||||||
params,
|
params,
|
||||||
true,
|
true,
|
||||||
"arrow function parameters",
|
"arrow function parameters",
|
||||||
|
trailingCommaPos,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2012,6 +2021,7 @@ export default class ExpressionParser extends LValParser {
|
|||||||
close: TokenType,
|
close: TokenType,
|
||||||
allowEmpty?: boolean,
|
allowEmpty?: boolean,
|
||||||
refShorthandDefaultPos?: ?Pos,
|
refShorthandDefaultPos?: ?Pos,
|
||||||
|
nodeForExtra?: ?N.Node,
|
||||||
): $ReadOnlyArray<?N.Expression> {
|
): $ReadOnlyArray<?N.Expression> {
|
||||||
const elts = [];
|
const elts = [];
|
||||||
let first = true;
|
let first = true;
|
||||||
@ -2021,7 +2031,17 @@ export default class ExpressionParser extends LValParser {
|
|||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
this.expect(tt.comma);
|
this.expect(tt.comma);
|
||||||
if (this.eat(close)) break;
|
if (this.match(close)) {
|
||||||
|
if (nodeForExtra) {
|
||||||
|
this.addExtra(
|
||||||
|
nodeForExtra,
|
||||||
|
"trailingComma",
|
||||||
|
this.state.lastTokStart,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this.next();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
elts.push(this.parseExprListItem(allowEmpty, refShorthandDefaultPos));
|
elts.push(this.parseExprListItem(allowEmpty, refShorthandDefaultPos));
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
|
import * as charCodes from "charcodes";
|
||||||
import { types as tt, type TokenType } from "../tokenizer/types";
|
import { types as tt, type TokenType } from "../tokenizer/types";
|
||||||
import type {
|
import type {
|
||||||
TSParameterProperty,
|
TSParameterProperty,
|
||||||
@ -60,6 +61,14 @@ export default class LValParser extends NodeUtils {
|
|||||||
const prop = node.properties[i];
|
const prop = node.properties[i];
|
||||||
const isLast = i === last;
|
const isLast = i === last;
|
||||||
this.toAssignableObjectExpressionProp(prop, isBinding, isLast);
|
this.toAssignableObjectExpressionProp(prop, isBinding, isLast);
|
||||||
|
|
||||||
|
if (
|
||||||
|
isLast &&
|
||||||
|
prop.type === "RestElement" &&
|
||||||
|
node.extra?.trailingComma
|
||||||
|
) {
|
||||||
|
this.raiseRestNotLast(node.extra.trailingComma);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -78,7 +87,12 @@ export default class LValParser extends NodeUtils {
|
|||||||
|
|
||||||
case "ArrayExpression":
|
case "ArrayExpression":
|
||||||
node.type = "ArrayPattern";
|
node.type = "ArrayPattern";
|
||||||
this.toAssignableList(node.elements, isBinding, contextDescription);
|
this.toAssignableList(
|
||||||
|
node.elements,
|
||||||
|
isBinding,
|
||||||
|
contextDescription,
|
||||||
|
node.extra?.trailingComma,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "AssignmentExpression":
|
case "AssignmentExpression":
|
||||||
@ -142,6 +156,7 @@ export default class LValParser extends NodeUtils {
|
|||||||
exprList: Expression[],
|
exprList: Expression[],
|
||||||
isBinding: ?boolean,
|
isBinding: ?boolean,
|
||||||
contextDescription: string,
|
contextDescription: string,
|
||||||
|
trailingCommaPos?: ?number,
|
||||||
): $ReadOnlyArray<Pattern> {
|
): $ReadOnlyArray<Pattern> {
|
||||||
let end = exprList.length;
|
let end = exprList.length;
|
||||||
if (end) {
|
if (end) {
|
||||||
@ -160,6 +175,11 @@ export default class LValParser extends NodeUtils {
|
|||||||
) {
|
) {
|
||||||
this.unexpected(arg.start);
|
this.unexpected(arg.start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (trailingCommaPos) {
|
||||||
|
this.raiseTrailingCommaAfterRest(trailingCommaPos);
|
||||||
|
}
|
||||||
|
|
||||||
--end;
|
--end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,11 +233,6 @@ export default class LValParser extends NodeUtils {
|
|||||||
undefined,
|
undefined,
|
||||||
refNeedsArrowPos,
|
refNeedsArrowPos,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (this.state.commaAfterSpreadAt === -1 && this.match(tt.comma)) {
|
|
||||||
this.state.commaAfterSpreadAt = this.state.start;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.finishNode(node, "SpreadElement");
|
return this.finishNode(node, "SpreadElement");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,7 +249,11 @@ export default class LValParser extends NodeUtils {
|
|||||||
case tt.bracketL: {
|
case tt.bracketL: {
|
||||||
const node = this.startNode();
|
const node = this.startNode();
|
||||||
this.next();
|
this.next();
|
||||||
node.elements = this.parseBindingList(tt.bracketR, true);
|
node.elements = this.parseBindingList(
|
||||||
|
tt.bracketR,
|
||||||
|
charCodes.rightSquareBracket,
|
||||||
|
true,
|
||||||
|
);
|
||||||
return this.finishNode(node, "ArrayPattern");
|
return this.finishNode(node, "ArrayPattern");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,6 +266,7 @@ export default class LValParser extends NodeUtils {
|
|||||||
|
|
||||||
parseBindingList(
|
parseBindingList(
|
||||||
close: TokenType,
|
close: TokenType,
|
||||||
|
closeCharCode: $Values<typeof charCodes>,
|
||||||
allowEmpty?: boolean,
|
allowEmpty?: boolean,
|
||||||
allowModifiers?: boolean,
|
allowModifiers?: boolean,
|
||||||
): $ReadOnlyArray<Pattern | TSParameterProperty> {
|
): $ReadOnlyArray<Pattern | TSParameterProperty> {
|
||||||
@ -265,7 +285,7 @@ export default class LValParser extends NodeUtils {
|
|||||||
break;
|
break;
|
||||||
} else if (this.match(tt.ellipsis)) {
|
} else if (this.match(tt.ellipsis)) {
|
||||||
elts.push(this.parseAssignableListItemTypes(this.parseRestBinding()));
|
elts.push(this.parseAssignableListItemTypes(this.parseRestBinding()));
|
||||||
this.checkCommaAfterRest();
|
this.checkCommaAfterRest(closeCharCode);
|
||||||
this.expect(close);
|
this.expect(close);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@ -455,19 +475,21 @@ export default class LValParser extends NodeUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkCommaAfterRest(): void {
|
checkCommaAfterRest(close: $Values<typeof charCodes>): void {
|
||||||
if (this.match(tt.comma)) {
|
if (this.match(tt.comma)) {
|
||||||
this.raiseRestNotLast(this.state.start);
|
if (this.lookaheadCharCode() === close) {
|
||||||
}
|
this.raiseTrailingCommaAfterRest(this.state.start);
|
||||||
}
|
} else {
|
||||||
|
this.raiseRestNotLast(this.state.start);
|
||||||
checkCommaAfterRestFromSpread(): void {
|
}
|
||||||
if (this.state.commaAfterSpreadAt > -1) {
|
|
||||||
this.raiseRestNotLast(this.state.commaAfterSpreadAt);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
raiseRestNotLast(pos: number) {
|
raiseRestNotLast(pos: number) {
|
||||||
this.raise(pos, `Rest element must be last element`);
|
this.raise(pos, `Rest element must be last element`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
raiseTrailingCommaAfterRest(pos: number) {
|
||||||
|
this.raise(pos, `Unexpected trailing comma after rest element`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1105,6 +1105,7 @@ export default class StatementParser extends ExpressionParser {
|
|||||||
this.expect(tt.parenL);
|
this.expect(tt.parenL);
|
||||||
node.params = this.parseBindingList(
|
node.params = this.parseBindingList(
|
||||||
tt.parenR,
|
tt.parenR,
|
||||||
|
charCodes.rightParenthesis,
|
||||||
/* allowEmpty */ false,
|
/* allowEmpty */ false,
|
||||||
allowModifiers,
|
allowModifiers,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1798,6 +1798,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
((node.params: any): N.Expression[]),
|
((node.params: any): N.Expression[]),
|
||||||
true,
|
true,
|
||||||
"arrow function parameters",
|
"arrow function parameters",
|
||||||
|
node.extra?.trailingComma,
|
||||||
);
|
);
|
||||||
// Enter scope, as checkParams defines bindings
|
// Enter scope, as checkParams defines bindings
|
||||||
this.scope.enter(functionFlags(false, false) | SCOPE_ARROW);
|
this.scope.enter(functionFlags(false, false) | SCOPE_ARROW);
|
||||||
@ -1820,6 +1821,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
((node.params: any): N.Expression[]),
|
((node.params: any): N.Expression[]),
|
||||||
true,
|
true,
|
||||||
"arrow function parameters",
|
"arrow function parameters",
|
||||||
|
node.extra?.trailingComma,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return [arrows, []];
|
return [arrows, []];
|
||||||
@ -1831,6 +1833,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
((node.params: any): N.Expression[]),
|
((node.params: any): N.Expression[]),
|
||||||
true,
|
true,
|
||||||
"arrow function parameters",
|
"arrow function parameters",
|
||||||
|
node.extra?.trailingComma,
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -2005,6 +2008,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
exprList: N.Expression[],
|
exprList: N.Expression[],
|
||||||
isBinding: ?boolean,
|
isBinding: ?boolean,
|
||||||
contextDescription: string,
|
contextDescription: string,
|
||||||
|
trailingCommaPos?: ?number,
|
||||||
): $ReadOnlyArray<N.Pattern> {
|
): $ReadOnlyArray<N.Pattern> {
|
||||||
for (let i = 0; i < exprList.length; i++) {
|
for (let i = 0; i < exprList.length; i++) {
|
||||||
const expr = exprList[i];
|
const expr = exprList[i];
|
||||||
@ -2012,7 +2016,12 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
exprList[i] = this.typeCastToParameter(expr);
|
exprList[i] = this.typeCastToParameter(expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return super.toAssignableList(exprList, isBinding, contextDescription);
|
return super.toAssignableList(
|
||||||
|
exprList,
|
||||||
|
isBinding,
|
||||||
|
contextDescription,
|
||||||
|
trailingCommaPos,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is a list of nodes, from something like a call expression, we need to filter the
|
// this is a list of nodes, from something like a call expression, we need to filter the
|
||||||
|
|||||||
@ -363,21 +363,23 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
tsParseBindingListForSignature(): $ReadOnlyArray<
|
tsParseBindingListForSignature(): $ReadOnlyArray<
|
||||||
N.Identifier | N.RestElement | N.ObjectPattern | N.ArrayPattern,
|
N.Identifier | N.RestElement | N.ObjectPattern | N.ArrayPattern,
|
||||||
> {
|
> {
|
||||||
return this.parseBindingList(tt.parenR).map(pattern => {
|
return this.parseBindingList(tt.parenR, charCodes.rightParenthesis).map(
|
||||||
if (
|
pattern => {
|
||||||
pattern.type !== "Identifier" &&
|
if (
|
||||||
pattern.type !== "RestElement" &&
|
pattern.type !== "Identifier" &&
|
||||||
pattern.type !== "ObjectPattern" &&
|
pattern.type !== "RestElement" &&
|
||||||
pattern.type !== "ArrayPattern"
|
pattern.type !== "ObjectPattern" &&
|
||||||
) {
|
pattern.type !== "ArrayPattern"
|
||||||
throw this.unexpected(
|
) {
|
||||||
pattern.start,
|
throw this.unexpected(
|
||||||
"Name in a signature must be an Identifier, ObjectPattern or ArrayPattern," +
|
pattern.start,
|
||||||
`instead got ${pattern.type}`,
|
"Name in a signature must be an Identifier, ObjectPattern or ArrayPattern," +
|
||||||
);
|
`instead got ${pattern.type}`,
|
||||||
}
|
);
|
||||||
return pattern;
|
}
|
||||||
});
|
return pattern;
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
tsParseTypeMemberSemicolon(): void {
|
tsParseTypeMemberSemicolon(): void {
|
||||||
@ -586,7 +588,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
const restNode: N.TsRestType = this.startNode();
|
const restNode: N.TsRestType = this.startNode();
|
||||||
this.next(); // skips ellipsis
|
this.next(); // skips ellipsis
|
||||||
restNode.typeAnnotation = this.tsParseType();
|
restNode.typeAnnotation = this.tsParseType();
|
||||||
this.checkCommaAfterRest();
|
this.checkCommaAfterRest(charCodes.rightSquareBracket);
|
||||||
return this.finishNode(restNode, "TSRestType");
|
return this.finishNode(restNode, "TSRestType");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2363,11 +2365,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toAssignableList(
|
toAssignableList(exprList: N.Expression[]): $ReadOnlyArray<N.Pattern> {
|
||||||
exprList: N.Expression[],
|
|
||||||
isBinding: ?boolean,
|
|
||||||
contextDescription: string,
|
|
||||||
): $ReadOnlyArray<N.Pattern> {
|
|
||||||
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) continue;
|
if (!expr) continue;
|
||||||
@ -2384,7 +2382,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return super.toAssignableList(exprList, isBinding, contextDescription);
|
return super.toAssignableList(...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
typeCastToParameter(node: N.TsTypeCastExpression): N.Node {
|
typeCastToParameter(node: N.TsTypeCastExpression): N.Node {
|
||||||
|
|||||||
@ -55,11 +55,6 @@ export default class State {
|
|||||||
// ^
|
// ^
|
||||||
noArrowParamsConversionAt: number[] = [];
|
noArrowParamsConversionAt: number[] = [];
|
||||||
|
|
||||||
// A comma after "...a" is only allowed in spread, but not in rest.
|
|
||||||
// Since we parse destructuring patterns as array/object literals
|
|
||||||
// and then convert them, we need to track it.
|
|
||||||
commaAfterSpreadAt: number = -1;
|
|
||||||
|
|
||||||
// Flags to track
|
// Flags to track
|
||||||
inParameters: boolean = false;
|
inParameters: boolean = false;
|
||||||
maybeInArrowParameters: boolean = false;
|
maybeInArrowParameters: boolean = false;
|
||||||
|
|||||||
@ -373,7 +373,10 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 140
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -494,7 +497,10 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 200
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@ -74,6 +74,9 @@
|
|||||||
},
|
},
|
||||||
"name": "fn"
|
"name": "fn"
|
||||||
},
|
},
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 11
|
||||||
|
},
|
||||||
"arguments": [
|
"arguments": [
|
||||||
{
|
{
|
||||||
"type": "Identifier",
|
"type": "Identifier",
|
||||||
|
|||||||
@ -74,6 +74,9 @@
|
|||||||
},
|
},
|
||||||
"name": "fn"
|
"name": "fn"
|
||||||
},
|
},
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 7
|
||||||
|
},
|
||||||
"arguments": [
|
"arguments": [
|
||||||
{
|
{
|
||||||
"type": "Identifier",
|
"type": "Identifier",
|
||||||
|
|||||||
@ -181,6 +181,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 35
|
||||||
|
},
|
||||||
"trailingComments": [
|
"trailingComments": [
|
||||||
{
|
{
|
||||||
"type": "CommentBlock",
|
"type": "CommentBlock",
|
||||||
|
|||||||
@ -309,7 +309,10 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 66
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@ -163,7 +163,10 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 13
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"trailingComments": [
|
"trailingComments": [
|
||||||
|
|||||||
@ -110,7 +110,10 @@
|
|||||||
},
|
},
|
||||||
"value": 42
|
"value": 42
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 8
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -150,7 +150,10 @@
|
|||||||
},
|
},
|
||||||
"value": 3
|
"value": 3
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 13
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -151,7 +151,10 @@
|
|||||||
},
|
},
|
||||||
"value": 3
|
"value": 3
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 14
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"throws": "Rest element must be last element (1:5)"
|
"throws": "Unexpected trailing comma after rest element (1:5)"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1 @@
|
|||||||
|
for ([...a,] in []);
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"throws": "Unexpected trailing comma after rest element (1:10)"
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
[[...a,]] = [];
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"throws": "Unexpected trailing comma after rest element (1:6)"
|
||||||
|
}
|
||||||
@ -90,7 +90,10 @@
|
|||||||
"name": "a"
|
"name": "a"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 5
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"throws": "Rest element must be last element (1:8)"
|
"throws": "Unexpected trailing comma after rest element (1:8)"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -91,7 +91,10 @@
|
|||||||
"name": "x"
|
"name": "x"
|
||||||
},
|
},
|
||||||
null
|
null
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 3
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"right": {
|
"right": {
|
||||||
"type": "NumericLiteral",
|
"type": "NumericLiteral",
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"throws": "Rest element must be last element (1:11)"
|
"throws": "Unexpected trailing comma after rest element (1:11)"
|
||||||
}
|
}
|
||||||
@ -74,6 +74,9 @@
|
|||||||
},
|
},
|
||||||
"name": "log"
|
"name": "log"
|
||||||
},
|
},
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 13
|
||||||
|
},
|
||||||
"arguments": [
|
"arguments": [
|
||||||
{
|
{
|
||||||
"type": "Identifier",
|
"type": "Identifier",
|
||||||
|
|||||||
@ -183,7 +183,10 @@
|
|||||||
"shorthand": true
|
"shorthand": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 10
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"init": {
|
"init": {
|
||||||
"type": "Identifier",
|
"type": "Identifier",
|
||||||
|
|||||||
@ -289,6 +289,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"extra": {
|
"extra": {
|
||||||
|
"trailingComma": 21,
|
||||||
"parenthesized": true,
|
"parenthesized": true,
|
||||||
"parenStart": 0
|
"parenStart": 0
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"throws": "Rest element must be last element (1:16)"
|
"throws": "Unexpected trailing comma after rest element (1:16)"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1 @@
|
|||||||
|
for ({...a,} in []);
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"throws": "Rest element must be last element (1:10)"
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
[{...a,}] = [];
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"throws": "Rest element must be last element (1:6)"
|
||||||
|
}
|
||||||
@ -92,6 +92,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"extra": {
|
"extra": {
|
||||||
|
"trailingComma": 6,
|
||||||
"parenthesized": true,
|
"parenthesized": true,
|
||||||
"parenStart": 0
|
"parenStart": 0
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,7 +78,10 @@
|
|||||||
"elements": [
|
"elements": [
|
||||||
null,
|
null,
|
||||||
null
|
null
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 3
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"body": {
|
"body": {
|
||||||
|
|||||||
@ -75,7 +75,10 @@
|
|||||||
"elements": [
|
"elements": [
|
||||||
null,
|
null,
|
||||||
null
|
null
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 2
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"right": {
|
"right": {
|
||||||
"type": "NumericLiteral",
|
"type": "NumericLiteral",
|
||||||
|
|||||||
@ -166,6 +166,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"extra": {
|
"extra": {
|
||||||
|
"trailingComma": 33,
|
||||||
"parenthesized": true,
|
"parenthesized": true,
|
||||||
"parenStart": 0
|
"parenStart": 0
|
||||||
}
|
}
|
||||||
|
|||||||
@ -169,6 +169,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"extra": {
|
"extra": {
|
||||||
|
"trailingComma": 35,
|
||||||
"parenthesized": true,
|
"parenthesized": true,
|
||||||
"parenStart": 0
|
"parenStart": 0
|
||||||
}
|
}
|
||||||
|
|||||||
@ -128,7 +128,10 @@
|
|||||||
"shorthand": true
|
"shorthand": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 6
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"init": {
|
"init": {
|
||||||
"type": "NumericLiteral",
|
"type": "NumericLiteral",
|
||||||
|
|||||||
@ -110,7 +110,10 @@
|
|||||||
},
|
},
|
||||||
"value": 42
|
"value": 42
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 8
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -150,7 +150,10 @@
|
|||||||
},
|
},
|
||||||
"value": 3
|
"value": 3
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 13
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -151,7 +151,10 @@
|
|||||||
},
|
},
|
||||||
"value": 3
|
"value": 3
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 14
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"throws": "Trailing comma is disallowed inside import(...) arguments (1:13)"
|
"throws": "Trailing comma is disallowed inside import(...) arguments (1:12)"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -157,7 +157,10 @@
|
|||||||
},
|
},
|
||||||
"value": 123
|
"value": 123
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 24
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@ -187,7 +187,6 @@
|
|||||||
"column": 23
|
"column": 23
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"attributes": [],
|
|
||||||
"name": {
|
"name": {
|
||||||
"type": "JSXIdentifier",
|
"type": "JSXIdentifier",
|
||||||
"start": 29,
|
"start": 29,
|
||||||
@ -204,6 +203,7 @@
|
|||||||
},
|
},
|
||||||
"name": "Foo"
|
"name": "Foo"
|
||||||
},
|
},
|
||||||
|
"attributes": [],
|
||||||
"selfClosing": true
|
"selfClosing": true
|
||||||
},
|
},
|
||||||
"closingElement": null,
|
"closingElement": null,
|
||||||
@ -263,7 +263,10 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 39
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@ -450,7 +450,10 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"extra": {
|
||||||
|
"trailingComma": 77
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@ -646,11 +646,3 @@ language/statements/class/elements/syntax/early-errors/invalid-names/method-outt
|
|||||||
language/statements/class/elements/syntax/early-errors/invalid-names/method-outter-member-expression-bad-reference.js(strict mode)
|
language/statements/class/elements/syntax/early-errors/invalid-names/method-outter-member-expression-bad-reference.js(strict mode)
|
||||||
language/statements/class/elements/syntax/early-errors/invalid-names/method-outter-member-expression-this.js(default)
|
language/statements/class/elements/syntax/early-errors/invalid-names/method-outter-member-expression-this.js(default)
|
||||||
language/statements/class/elements/syntax/early-errors/invalid-names/method-outter-member-expression-this.js(strict mode)
|
language/statements/class/elements/syntax/early-errors/invalid-names/method-outter-member-expression-this.js(strict mode)
|
||||||
language/statements/for-in/dstr/array-rest-before-elision.js(default)
|
|
||||||
language/statements/for-in/dstr/array-rest-before-elision.js(strict mode)
|
|
||||||
language/statements/for-in/dstr/array-rest-elision-invalid.js(default)
|
|
||||||
language/statements/for-in/dstr/array-rest-elision-invalid.js(strict mode)
|
|
||||||
language/statements/for-of/dstr/array-rest-before-elision.js(default)
|
|
||||||
language/statements/for-of/dstr/array-rest-before-elision.js(strict mode)
|
|
||||||
language/statements/for-of/dstr/array-rest-elision-invalid.js(default)
|
|
||||||
language/statements/for-of/dstr/array-rest-elision-invalid.js(strict mode)
|
|
||||||
Loading…
x
Reference in New Issue
Block a user