Skip to content

Commit

Permalink
fix(parser): fixed bunch of class field edge cases
Browse files Browse the repository at this point in the history
  • Loading branch information
KFlash committed Jun 1, 2019
1 parent 5129b0a commit 75c881a
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 33 deletions.
1 change: 0 additions & 1 deletion src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export const enum Context {
AllowNewTarget = 1 << 26,
DisallowIn = 1 << 27,
InDecoratorContext = 1 << 28,
InClass = 1 << 29,
InSwitchOrIteration = InSwitch | InIteration
}

Expand Down
56 changes: 27 additions & 29 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2353,7 +2353,7 @@ export function parseAssignmentExpression(

nextToken(parser, context | Context.AllowRegExp);

const right = parseExpression(parser, context, /* assignable*/ 1, 0, parser.tokenIndex);
const right = parseExpression(parser, context, /* assignable*/ 1, inClass, parser.tokenIndex);

left = finishNode(parser, context, start, {
type: 'AssignmentExpression',
Expand All @@ -2374,7 +2374,7 @@ export function parseAssignmentExpression(
*/
if ((parser.token & Token.IsBinaryOp) > 0) {
// We start using the binary expression parser for prec >= 4 only!
left = parseBinaryExpression(parser, context, start, /* precedence */ 4, left);
left = parseBinaryExpression(parser, context, inClass, start, /* precedence */ 4, left);
}

/**
Expand Down Expand Up @@ -2438,6 +2438,7 @@ export function parseConditionalExpression(
export function parseBinaryExpression(
parser: ParserState,
context: Context,
inClass: 0 | 1,
start: number,
minPrec: number,
left:
Expand Down Expand Up @@ -2471,9 +2472,10 @@ export function parseBinaryExpression(
right: parseBinaryExpression(
parser,
context,
inClass,
parser.tokenIndex,
prec,
parseLeftHandSideExpression(parser, context, /* assignable */ 0, /* inClass */ 0, parser.tokenIndex)
parseLeftHandSideExpression(parser, context, /* assignable */ 0, inClass, parser.tokenIndex)
),
operator: KeywordDescTable[t & Token.Type] as ESTree.LogicalOperator
} as ESTree.BinaryExpression | ESTree.LogicalExpression);
Expand All @@ -2490,7 +2492,12 @@ export function parseBinaryExpression(
* @param parser Parser object
* @param context Context masks
*/
export function parseUnaryExpression(parser: ParserState, context: Context, start: number): ESTree.UnaryExpression {
export function parseUnaryExpression(
parser: ParserState,
context: Context,
inClass: 0 | 1,
start: number
): ESTree.UnaryExpression {
/**
* UnaryExpression ::
* PostfixExpression
Expand All @@ -2505,9 +2512,9 @@ export function parseUnaryExpression(parser: ParserState, context: Context, star
*/
const unaryOperator = parser.token;
nextToken(parser, context | Context.AllowRegExp);
const arg = parseLeftHandSideExpression(parser, context, /* assignable*/ 0, /* inClass */ 0, parser.tokenIndex);
const arg = parseLeftHandSideExpression(parser, context, /* assignable*/ 0, inClass, parser.tokenIndex);
if (parser.token === Token.Exponentiate) report(parser, Errors.InvalidExponentationLHS);
if (context & Context.InClass) report(parser, Errors.InvalidExponentationLHS);
if (inClass) report(parser, Errors.InvalidExponentationLHS);
if (context & Context.Strict && unaryOperator === Token.DeleteKeyword) {
if (arg.type === 'Identifier') {
report(parser, Errors.StrictDelete);
Expand Down Expand Up @@ -2696,9 +2703,14 @@ export function parseFunctionBody(
* @param parser Parser object
* @param context Context masks
*/
export function parseSuperExpression(parser: ParserState, context: Context, start: number): ESTree.Super {
export function parseSuperExpression(
parser: ParserState,
context: Context,
inClass: 0 | 1,
start: number
): ESTree.Super {
nextToken(parser, context);
if (context & Context.InClass) report(parser, Errors.UnexpectedToken, 'super');
if (inClass) report(parser, Errors.UnexpectedToken, 'super');
switch (parser.token) {
case Token.LeftParen: {
// The super property has to be within a class constructor
Expand Down Expand Up @@ -2897,7 +2909,7 @@ export function parsePrimaryExpressionExtended(
report(parser, Errors.InvalidNewUnary);
}
parser.assignable = AssignmentKind.CannotAssign;
return parseUnaryExpression(parser, context, start);
return parseUnaryExpression(parser, context, inClass, start);
}

/**
Expand Down Expand Up @@ -3033,7 +3045,7 @@ export function parsePrimaryExpressionExtended(
parser.assignable = AssignmentKind.CannotAssign;
return parseNullOrTrueOrFalseLiteral(parser, context, start);
case Token.SuperKeyword:
return parseSuperExpression(parser, context, start);
return parseSuperExpression(parser, context, inClass, start);
case Token.TemplateTail:
return parseTemplateLiteral(parser, context, start);
case Token.TemplateContinuation:
Expand Down Expand Up @@ -3500,13 +3512,8 @@ export function parseFunctionExpression(
const params = parseFormalParametersOrFormalList(parser, context | Context.InArgList, BindingType.ArgumentList);
const body = parseFunctionBody(
parser,
(context |
Context.InGlobal |
Context.TopLevel |
Context.InSwitchOrIteration |
Context.InClass |
Context.DisallowIn) ^
(Context.InGlobal | Context.TopLevel | Context.InSwitchOrIteration | Context.InClass | Context.DisallowIn),
(context | Context.InGlobal | Context.TopLevel | Context.InSwitchOrIteration | Context.DisallowIn) ^
(Context.InGlobal | Context.TopLevel | Context.InSwitchOrIteration | Context.DisallowIn),
0,
firstRestricted
);
Expand Down Expand Up @@ -5907,11 +5914,9 @@ function parseClassElementList(
key = parseComputedPropertyName(parser, context);
} else if (kind & PropertyKind.PrivateField) {
key = parsePrivateName(parser, context, tokenIndex);
context = context | Context.InClass;
if (parser.token !== Token.LeftParen)
return parseFieldDefinition(parser, context, key, kind, decorators, tokenIndex);
} else if (kind & PropertyKind.ClassField) {
context = context | Context.InClass;
if (parser.token !== Token.LeftParen)
return parseFieldDefinition(parser, context, key, kind, decorators, tokenIndex);
}
Expand Down Expand Up @@ -6037,18 +6042,11 @@ export function parseFieldDefinition(

if (parser.token === Token.Arguments) report(parser, Errors.StrictEvalArguments);

value = parsePrimaryExpressionExtended(
parser,
context | Context.InClass,
BindingType.None,
0,
1,
1,
idxAfterAssign
);
value = parsePrimaryExpressionExtended(parser, context, BindingType.None, 0, 1, 1, idxAfterAssign);

if ((parser.token & Token.IsClassField) !== Token.IsClassField) {
value = parseMemberOrUpdateExpression(parser, context, value as any, 0, 0, 0, idxAfterAssign);
value = parseMemberOrUpdateExpression(parser, context, value as any, 0, 0, /* inClass */ 1, idxAfterAssign);

if ((parser.token & Token.IsClassField) !== Token.IsClassField) {
value = parseAssignmentExpression(parser, context, 1, idxAfterAssign, value as any);
}
Expand Down
6 changes: 5 additions & 1 deletion test/parser/next/private_methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ describe('Next - Private methods', () => {
['class C{ #method() { super(); } }', Context.OptionsNext],
['(class C extends Base { async #*a() { } })', Context.OptionsNext],
['class C{ #method() { super(); } }', Context.OptionsNext],
['class C{ #method() { super(); } }', Context.OptionsNext]
['class C{ #method() { super(); } }', Context.OptionsNext],
['class C { #x = () => arguments; }', Context.OptionsNext]
//['function fn() { (() => this)().#x }', Context.OptionsNext],
//['function fn() { something.#x }', Context.OptionsNext],
//['function fn() { this.#x }', Context.OptionsNext],
]);

for (const arg of [
Expand Down
13 changes: 11 additions & 2 deletions test/parser/next/public-fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,15 @@ describe('Next - Public fields', () => {
'a = 0\n *b(){}',
"a = 0\n ['b'](){}",
'static prototype',
'static constructor'
'static constructor',
// 'field = 1 /* no ASI here */ method(){}',
'#x = false ? {} : arguments;',
'x = typeof arguments;',
'x = {} == arguments;',
'x = false ? {} : arguments;',
// 'st\\u0061tic m() {}',
'{ something.#x }',
'class C { x = () => arguments; }'
]) {
it(`class C { ${arg} }`, () => {
t.throws(() => {
Expand Down Expand Up @@ -102,7 +110,8 @@ describe('Next - Public fields', () => {
'await;',
'await = 0;',
'await;\n a;',
`\nx;\ny;\n\n`
`\nx;\ny;\n\n`,
`static ['constructor'];`
]) {
it(`class C { ${arg} }`, () => {
t.doesNotThrow(() => {
Expand Down

0 comments on commit 75c881a

Please sign in to comment.