Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sure babel parser throws exactly same recoverable errors when estree plugin is enabled #12375

Merged
merged 13 commits into from
Dec 3, 2020
Merged
Next Next commit
refactor: introduce isPrivateName and getPrivateNameSV
  • Loading branch information
JLHwung committed Nov 18, 2020
commit 40f488bc608a723896ccace121c0d945085ade7d
11 changes: 7 additions & 4 deletions packages/babel-parser/src/parser/expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ export default class ExpressionParser extends LValParser {
} else if (
(arg.type === "MemberExpression" ||
arg.type === "OptionalMemberExpression") &&
arg.property.type === "PrivateName"
this.isPrivateName(arg.property)
) {
this.raise(node.start, Errors.DeletePrivateField);
}
Expand Down Expand Up @@ -662,11 +662,14 @@ export default class ExpressionParser extends LValParser {
? this.parseExpression()
: this.parseMaybePrivateName(true);

if (property.type === "PrivateName") {
if (this.isPrivateName(property)) {
if (node.object.type === "Super") {
this.raise(startPos, Errors.SuperPrivateField);
}
this.classScope.usePrivateName(property.id.name, property.start);
this.classScope.usePrivateName(
this.getPrivateNameSV(property),
property.start,
);
}
node.property = property;

Expand Down Expand Up @@ -1923,7 +1926,7 @@ export default class ExpressionParser extends LValParser {
? this.parseExprAtom()
: this.parseMaybePrivateName(isPrivateNameAllowed);

if (prop.key.type !== "PrivateName") {
if (!this.isPrivateName(prop.key)) {
// ClassPrivateProperty is never computed, so we don't assign in that case.
prop.computed = false;
}
Expand Down
21 changes: 14 additions & 7 deletions packages/babel-parser/src/parser/statement.js
Original file line number Diff line number Diff line change
Expand Up @@ -1346,7 +1346,7 @@ export default class StatementParser extends ExpressionParser {
method.kind = "method";
this.parseClassElementName(method);

if (method.key.type === "PrivateName") {
if (this.isPrivateName(method.key)) {
// Private generator method
this.pushClassPrivateMethod(classBody, privateMethod, true, false);
return;
Expand All @@ -1370,7 +1370,7 @@ export default class StatementParser extends ExpressionParser {

const containsEsc = this.state.containsEsc;
const key = this.parseClassElementName(member);
const isPrivate = key.type === "PrivateName";
const isPrivate = this.isPrivateName(key);
// Check the key is not a computed expression or string literal.
const isSimple = key.type === "Identifier";
const maybeQuestionTokenStart = this.state.start;
Expand Down Expand Up @@ -1431,7 +1431,7 @@ export default class StatementParser extends ExpressionParser {
this.parseClassElementName(method);
this.parsePostMemberNameModifiers(publicMember);

if (method.key.type === "PrivateName") {
if (this.isPrivateName(method.key)) {
// private async method
this.pushClassPrivateMethod(
classBody,
Expand Down Expand Up @@ -1465,7 +1465,7 @@ export default class StatementParser extends ExpressionParser {
// The so-called parsed name would have been "get/set": get the real name.
this.parseClassElementName(publicMethod);

if (method.key.type === "PrivateName") {
if (this.isPrivateName(method.key)) {
// private getter/setter
this.pushClassPrivateMethod(classBody, privateMethod, false, false);
} else {
Expand Down Expand Up @@ -1508,7 +1508,10 @@ export default class StatementParser extends ExpressionParser {
this.raise(key.start, Errors.StaticPrototype);
}

if (key.type === "PrivateName" && key.id.name === "constructor") {
if (
this.isPrivateName(key) &&
this.getPrivateNameSV(key) === "constructor"
) {
this.raise(key.start, Errors.ConstructorClassPrivateField);
}

Expand Down Expand Up @@ -1571,7 +1574,7 @@ export default class StatementParser extends ExpressionParser {
classBody.body.push(node);

this.classScope.declarePrivateName(
node.key.id.name,
this.getPrivateNameSV(node.key),
CLASS_ELEMENT_OTHER,
node.key.start,
);
Expand Down Expand Up @@ -1627,7 +1630,11 @@ export default class StatementParser extends ExpressionParser {
? CLASS_ELEMENT_STATIC_SETTER
: CLASS_ELEMENT_INSTANCE_SETTER
: CLASS_ELEMENT_OTHER;
this.classScope.declarePrivateName(node.key.id.name, kind, node.key.start);
this.classScope.declarePrivateName(
this.getPrivateNameSV(node.key),
kind,
node.key.start,
);
}

// Overridden in typescript.js
Expand Down
17 changes: 17 additions & 0 deletions packages/babel-parser/src/parser/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,23 @@ export default class UtilParser extends Tokenizer {
this.match(tt.decimal)
);
}

/*
* Test if given node is a PrivateName
* will be overridden in ESTree plugin
*/
isPrivateName(node: Node): boolean {
return node.type === "PrivateName";
}

/*
* Return the string value of a given private name
* WITHOUT `#`
* @see {@link https://tc39.es/proposal-class-fields/#sec-private-names-static-semantics-stringvalue}
*/
getPrivateNameSV(node: Node): string {
return node.id.name;
}
}

/**
Expand Down