fix: implement early errors for record and tuple (#11652)

This commit is contained in:
Huáng Jùnliàng
2020-06-19 20:35:27 -04:00
committed by GitHub
parent 2787ee2f96
commit 30835f14db
15 changed files with 307 additions and 43 deletions

View File

@@ -74,19 +74,22 @@ export default class ExpressionParser extends LValParser {
+takeDecorators: (node: N.HasDecorators) => void;
*/
// Check if property __proto__ has been used more than once.
// For object literal, check if property __proto__ has been used more than once.
// If the expression is a destructuring assignment, then __proto__ may appear
// multiple times. Otherwise, __proto__ is a duplicated key.
checkDuplicatedProto(
// For record expression, check if property __proto__ exists
checkProto(
prop: N.ObjectMember | N.SpreadElement,
isRecord: boolean,
protoRef: { used: boolean },
refExpressionErrors: ?ExpressionErrors,
): void {
if (
prop.type === "SpreadElement" ||
prop.type === "ObjectMethod" ||
prop.computed ||
prop.kind ||
// $FlowIgnore
prop.shorthand
) {
@@ -95,9 +98,13 @@ export default class ExpressionParser extends LValParser {
const key = prop.key;
// It is either an Identifier or a String/NumericLiteral
const name = key.type === "Identifier" ? key.name : String(key.value);
const name = key.type === "Identifier" ? key.name : key.value;
if (name === "__proto__") {
if (isRecord) {
this.raise(key.start, Errors.RecordNoProto);
return;
}
if (protoRef.used) {
if (refExpressionErrors) {
// Store the first redefinition's position, otherwise ignore because
@@ -1050,7 +1057,7 @@ export default class ExpressionParser extends LValParser {
this.next();
node.elements = this.parseExprList(
close,
true,
false,
refExpressionErrors,
node,
);
@@ -1554,7 +1561,15 @@ export default class ExpressionParser extends LValParser {
const prop = this.parseObjectMember(isPattern, refExpressionErrors);
if (!isPattern) {
// $FlowIgnore RestElement will never be returned if !isPattern
this.checkDuplicatedProto(prop, propHash, refExpressionErrors);
this.checkProto(prop, isRecord, propHash, refExpressionErrors);
}
if (
isRecord &&
prop.type !== "ObjectProperty" &&
prop.type !== "SpreadElement"
) {
this.raise(prop.start, Errors.InvalidRecordProperty);
}
// $FlowIgnore
@@ -2088,7 +2103,10 @@ export default class ExpressionParser extends LValParser {
allowPlaceholder: ?boolean,
): ?N.Expression {
let elt;
if (allowEmpty && this.match(tt.comma)) {
if (this.match(tt.comma)) {
if (!allowEmpty) {
this.raise(this.state.pos, Errors.UnexpectedToken, ",");
}
elt = null;
} else if (this.match(tt.ellipsis)) {
const spreadNodeStartPos = this.state.start;