Recover from shorthand assign exprs (#13968)

* refactor: avoid duplicate property access

* refactor: tweak parseMember

* polish: recover from shorthand assign in exprs
This commit is contained in:
Huáng Jùnliàng
2021-11-19 10:22:29 -05:00
committed by GitHub
parent d017d43535
commit a470f7b479
27 changed files with 817 additions and 52 deletions

View File

@@ -78,6 +78,7 @@ export const ErrorMessages = makeErrorTemplates(
ImportCallSpreadArgument: "`...` is not allowed in `import()`.",
InvalidBigIntLiteral: "Invalid BigIntLiteral.",
InvalidCodePoint: "Code point out of bounds.",
InvalidCoverInitializedName: "Invalid shorthand property initializer.",
InvalidDecimal: "Invalid decimal.",
InvalidDigit: "Expected number in radix %0.",
InvalidEscapeSequence: "Bad character escape sequence.",

View File

@@ -770,24 +770,17 @@ export default class ExpressionParser extends LValParser {
const node = this.startNodeAt(startPos, startLoc);
node.object = base;
node.computed = computed;
const privateName =
!computed && this.match(tt.privateName) && this.state.value;
const property = computed
? this.parseExpression()
: privateName
? this.parsePrivateName()
: this.parseIdentifier(true);
if (privateName !== false) {
if (node.object.type === "Super") {
if (computed) {
node.property = this.parseExpression();
this.expect(tt.bracketR);
} else if (this.match(tt.privateName)) {
if (base.type === "Super") {
this.raise(startPos, Errors.SuperPrivateField);
}
this.classScope.usePrivateName(privateName, property.start);
}
node.property = property;
if (computed) {
this.expect(tt.bracketR);
this.classScope.usePrivateName(this.state.value, this.state.start);
node.property = this.parsePrivateName();
} else {
node.property = this.parseIdentifier(true);
}
if (state.optionalChainMember) {
@@ -2137,7 +2130,7 @@ export default class ExpressionParser extends LValParser {
if (!prop.computed && prop.key.type === "Identifier") {
// PropertyDefinition:
// IdentifierReference
// CoveredInitializedName
// CoverInitializedName
// Note: `{ eval } = {}` will be checked in `checkLVal` later.
this.checkReservedWord(prop.key.name, prop.key.start, true, false);
@@ -2147,9 +2140,14 @@ export default class ExpressionParser extends LValParser {
startLoc,
cloneIdentifier(prop.key),
);
} else if (this.match(tt.eq) && refExpressionErrors) {
if (refExpressionErrors.shorthandAssign === -1) {
refExpressionErrors.shorthandAssign = this.state.start;
} else if (this.match(tt.eq)) {
const shorthandAssign = this.state.start;
if (refExpressionErrors != null) {
if (refExpressionErrors.shorthandAssign === -1) {
refExpressionErrors.shorthandAssign = shorthandAssign;
}
} else {
this.raise(shorthandAssign, Errors.InvalidCoverInitializedName);
}
prop.value = this.parseMaybeDefault(
startPos,

View File

@@ -270,7 +270,7 @@ export default class UtilParser extends Tokenizer {
return hasErrors;
} else if (hasErrors) {
if (shorthandAssign >= 0) {
this.unexpected(shorthandAssign);
this.raise(shorthandAssign, Errors.InvalidCoverInitializedName);
}
if (doubleProto >= 0) {
this.raise(doubleProto, Errors.DuplicateProto);

View File

@@ -61,11 +61,12 @@ export default class ClassScopeHandler {
elementType: ClassElementTypes,
pos: number,
) {
const classScope = this.current();
let redefined = classScope.privateNames.has(name);
const { privateNames, loneAccessors, undefinedPrivateNames } =
this.current();
let redefined = privateNames.has(name);
if (elementType & CLASS_ELEMENT_KIND_ACCESSOR) {
const accessor = redefined && classScope.loneAccessors.get(name);
const accessor = redefined && loneAccessors.get(name);
if (accessor) {
const oldStatic = accessor & CLASS_ELEMENT_FLAG_STATIC;
const newStatic = elementType & CLASS_ELEMENT_FLAG_STATIC;
@@ -78,9 +79,9 @@ export default class ClassScopeHandler {
// they have the same placement (static or not).
redefined = oldKind === newKind || oldStatic !== newStatic;
if (!redefined) classScope.loneAccessors.delete(name);
if (!redefined) loneAccessors.delete(name);
} else if (!redefined) {
classScope.loneAccessors.set(name, elementType);
loneAccessors.set(name, elementType);
}
}
@@ -88,8 +89,8 @@ export default class ClassScopeHandler {
this.raise(pos, Errors.PrivateNameRedeclaration, name);
}
classScope.privateNames.add(name);
classScope.undefinedPrivateNames.delete(name);
privateNames.add(name);
undefinedPrivateNames.delete(name);
}
usePrivateName(name: string, pos: number) {