Fix parsing of private fields (#566)

The computed key is not part of the spec.
key for ClassProperties is an Expression
Do not parse computed and literal keys for PrivateClassProperties
This commit is contained in:
Daniel Tschinder
2017-06-06 17:42:07 +02:00
committed by Henry Zhu
parent 37793d5be7
commit 69cba43f82
18 changed files with 38 additions and 1919 deletions

View File

@@ -578,7 +578,7 @@ export default class ExpressionParser extends LValParser {
if (this.hasPlugin("classPrivateProperties")) {
return this.parseMaybePrivateName();
} else {
this.unexpected();
throw this.unexpected();
}
case tt._new:
@@ -1011,20 +1011,19 @@ export default class ExpressionParser extends LValParser {
if (!node) this.unexpected();
}
parsePropertyName(prop: N.ObjectOrClassMember): N.Identifier {
parsePropertyName(prop: N.ObjectOrClassMember): N.Expression {
if (this.eat(tt.bracketL)) {
// $FlowFixMe (ClassPrivateMember shouldn't be allowed to be computed!)
prop.computed = true;
prop.key = this.parseMaybeAssign();
this.expect(tt.bracketR);
} else {
// $FlowFixMe (ClassPrivateMember shouldn't be allowed to be computed!)
prop.computed = false;
const oldInPropertyName = this.state.inPropertyName;
this.state.inPropertyName = true;
prop.key = (this.match(tt.num) || this.match(tt.string)) ? this.parseExprAtom() : this.parseIdentifier(true);
this.state.inPropertyName = oldInPropertyName;
}
return prop.key;
}

View File

@@ -642,9 +642,7 @@ export default class StatementParser extends ExpressionParser {
isNonstaticConstructor(method: N.ClassMethod | N.ClassProperty): boolean {
return !method.computed && !method.static && (
// $FlowFixMe ('key' downcasting)
(method.key.name === "constructor") || // Identifier
// $FlowFixMe ('key' downcasting)
(method.key.value === "constructor") // Literal
);
}
@@ -707,7 +705,7 @@ export default class StatementParser extends ExpressionParser {
if (this.hasPlugin("classPrivateProperties") && this.match(tt.hash)) { // Private property
this.next();
const privateProp: N.ClassPrivateProperty = memberAny;
this.parsePropertyName(privateProp);
privateProp.key = this.parseIdentifier(true);
classBody.body.push(this.parsePrivateClassProperty(privateProp));
return;
}
@@ -749,7 +747,6 @@ export default class StatementParser extends ExpressionParser {
const isSimple = this.match(tt.name);
const key = this.parsePropertyName(methodOrProp);
// $FlowFixMe ('key' downcasting)
if (!methodOrProp.computed && methodOrProp.static && (methodOrProp.key.name === "prototype" || methodOrProp.key.value === "prototype")) {
this.raise(methodOrProp.key.start, "Classes may not have static property named prototype");
}

View File

@@ -1294,7 +1294,6 @@ export default (superClass: Class<Parser>): Class<Parser> => class extends super
parsePropertyName(node: N.ObjectOrClassMember): N.Identifier {
const variance = this.flowParseVariance();
const key = super.parsePropertyName(node);
// $FlowFixMe (variance not defined on ClassPrivateProperty)
node.variance = variance;
return key;
}

View File

@@ -339,7 +339,7 @@ export type ObjectExpression = NodeBase & {
properties: $ReadOnlyArray<ObjectProperty | ObjectMethod | SpreadElement>;
};
export type ObjectOrClassMember = ClassMethod | ClassProperty | ClassPrivateProperty | ObjectMember;
export type ObjectOrClassMember = ClassMethod | ClassProperty | ObjectMember;
export type ObjectMember = ObjectProperty | ObjectMethod;
@@ -359,7 +359,7 @@ export type ObjectProperty = ObjectMemberBase & {
shorthand: boolean;
};
export type ObjectMethod = ObjectMemberBase & MethodBase & {
export type ObjectMethod = ObjectMemberBase & MethodBase & {
type: "ObjectMethod";
kind: "get" | "set" | "method"; // Never "constructor"
};
@@ -579,7 +579,7 @@ export type ClassMethod = MethodBase & ClassMemberBase & {
export type ClassProperty = ClassMemberBase & {
type: "ClassProperty";
key: Identifier;
key: Expression;
value: ?Expression; // TODO: Not in spec that this is nullable.
typeAnnotation?: ?FlowTypeAnnotation; // TODO: Not in spec