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:
@@ -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.",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user