Skip to content

Commit

Permalink
fix(parser): simplified some logic
Browse files Browse the repository at this point in the history
  • Loading branch information
KFlash committed Jun 2, 2019
1 parent 48077ab commit 7978118
Show file tree
Hide file tree
Showing 8 changed files with 420 additions and 44 deletions.
68 changes: 27 additions & 41 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5846,22 +5846,24 @@ function parseClassElementList(
}
} else if (token === Token.LeftBracket) {
kind = PropertyKind.Computed;
key = parseComputedPropertyName(parser, context);
} else if ((token & Token.IsStringOrNumber) === Token.IsStringOrNumber) {
key = parseLiteral(parser, context, tokenIndex);
} else if (token === Token.Multiply) {
kind |= PropertyKind.Generator;
nextToken(parser, context);
nextToken(parser, context); // skip: '*'
} else if (context & Context.OptionsNext && parser.token === Token.PrivateField) {
kind |= PropertyKind.PrivateField;
key = parsePrivateName(parser, context, tokenIndex);
context = context | Context.InClass;
} else if (context & Context.OptionsNext && (parser.token & Token.IsClassField) === Token.IsClassField) {
kind |= PropertyKind.ClassField;
context = context | Context.InClass;
} else {
report(parser, Errors.UnexpectedToken, KeywordDescTable[parser.token & Token.Type]);
}

if (kind & (PropertyKind.Generator | PropertyKind.Async | PropertyKind.GetSet)) {
if (kind & PropertyKind.Generator && parser.token === Token.LeftParen) report(parser, Errors.InvalidKeyToken);

if (parser.token & Token.IsIdentifier) {
key = parseIdentifier(parser, context, parser.tokenIndex);
} else if ((parser.token & Token.IsStringOrNumber) === Token.IsStringOrNumber) {
Expand All @@ -5872,50 +5874,34 @@ function parseClassElementList(
} else if (context & Context.OptionsNext && parser.token === Token.PrivateField) {
kind |= PropertyKind.PrivateField;
key = parsePrivateName(parser, context, tokenIndex);
} else if (parser.token === Token.RightBrace) {
report(parser, Errors.NoIdentOrDynamicName);
}
} else if (kind & PropertyKind.Computed) {
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);
} else report(parser, Errors.InvalidKeyToken);
}

if (parser.tokenValue === 'constructor') {
if ((kind & PropertyKind.Static) === 0) {
if (
(kind & PropertyKind.Computed) === 0 &&
kind & (PropertyKind.GetSet | PropertyKind.Async | PropertyKind.ClassField | PropertyKind.Generator)
) {
report(parser, Errors.InvalidConstructor, 'accessor');
}
if ((kind & PropertyKind.Computed) < 1) {
if (parser.tokenValue === 'constructor') {
if ((parser.token & Token.IsClassField) === Token.IsClassField) {
report(parser, Errors.InvalidClassFieldConstructor);
} else if ((kind & PropertyKind.Static) < 1) {
if (kind & (PropertyKind.GetSet | PropertyKind.Async | PropertyKind.ClassField | PropertyKind.Generator)) {
report(parser, Errors.InvalidConstructor, 'accessor');
}

if ((context & Context.SuperCall) === 0 && (kind & PropertyKind.Computed) === 0) {
if (parser.flags & Flags.HasConstructor) report(parser, Errors.DuplicateConstructor);
else parser.flags |= Flags.HasConstructor;
if ((context & Context.SuperCall) < 1) {
if (parser.flags & Flags.HasConstructor) report(parser, Errors.DuplicateConstructor);
else parser.flags |= Flags.HasConstructor;
}
}
kind |= PropertyKind.Constructor;
} else if (
(kind & PropertyKind.PrivateField) < 1 &&
kind & (PropertyKind.Static | PropertyKind.GetSet | PropertyKind.Generator | PropertyKind.Async) &&
parser.tokenValue === 'prototype'
) {
report(parser, Errors.StaticPrototype);
}
kind |= PropertyKind.Constructor;
}

if (
(kind & (PropertyKind.PrivateField | PropertyKind.Computed)) === 0 &&
kind & (PropertyKind.Static | PropertyKind.Generator | PropertyKind.Async | PropertyKind.GetSet) &&
parser.tokenValue === 'prototype'
) {
report(parser, Errors.StaticPrototype);
}

if (context & Context.OptionsNext && parser.token !== Token.LeftParen) {
if ((kind & PropertyKind.Computed) === 0 && parser.tokenValue === 'constructor')
report(parser, Errors.InvalidClassFieldConstructor);
return parseFieldDefinition(parser, context, key, kind, decorators, tokenIndex);
}

Expand All @@ -5925,7 +5911,7 @@ function parseClassElementList(
? finishNode(parser, context, start, {
type: 'MethodDefinition',
kind:
(kind & PropertyKind.Static) === 0 && kind & PropertyKind.Constructor
(kind & PropertyKind.Static) < 1 && kind & PropertyKind.Constructor
? 'constructor'
: kind & PropertyKind.Getter
? 'get'
Expand All @@ -5941,7 +5927,7 @@ function parseClassElementList(
: finishNode(parser, context, start, {
type: 'MethodDefinition',
kind:
(kind & PropertyKind.Static) === 0 && kind & PropertyKind.Constructor
(kind & PropertyKind.Static) < 1 && kind & PropertyKind.Constructor
? 'constructor'
: kind & PropertyKind.Getter
? 'get'
Expand Down
5 changes: 4 additions & 1 deletion test/parser/declarations/var.ts
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,10 @@ describe('Declarations - Var', () => {
'[a, b] = [, 2];',
'var {a: [x1, y1], b: [x2, y2] } = c;',
'var rect = {};',
'var x = -1;'
'var x = -1;',
'var {[a]: [b]} = c',
'var {[a]: b} = c',
'var {a: [b]} = c'
]) {
it(`${arg}`, () => {
t.doesNotThrow(() => {
Expand Down
41 changes: 40 additions & 1 deletion test/parser/expressions/class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -611,14 +611,53 @@ describe('Expressions - Class', () => {
['(class A {*prototype(){}})', Context.None],
['class x { get prototype(){} }', Context.None],
['(class x { async prototype(){} })', Context.None],
['(class A {*prototype(){}})', Context.None],
['class x { static set prototype(x){} }', Context.None],
['class x { static *prototype(){} }', Context.None],
['class x { static prototype(){} }', Context.None],
['class x { static async *prototype(){} }', Context.None],
['class x { static async *prot\\u006ftype(){} }', Context.None],
['class x { static "prototype"(){} }', Context.None],
['class w { t.x(){} }', Context.None],
['class x extends ()=>1 {}', Context.None],
['class X { async constructor() {} }', Context.None],
['class x{ async static static(){} }', Context.None],
['class x { static static f(){} }', Context.None],
['class x { * * f(){} }', Context.None],
['class x { set set f(x){} }', Context.None],
['class x { static prototype(){} }', Context.None],
['class x { async get foo(){ }}', Context.None],
['class x { static / foo(){} }', Context.None],
['class x{[yield](a){}}', Context.None],
['class x{*[yield](a){}}', Context.None],
['class x extends yield {}', Context.None],
['function *f(){ class x extends yield {} }', Context.None],
['for (class x extends a in b {} in c);', Context.None],
['for (class x { [a](){} } in c);', Context.None],
['class x extends y { [super.foo](){} }', Context.None],
['class x extends super.foo {}', Context.None],
['class x { [super()](){} }', Context.None],
// ['class x extends y { [super()](){} }', Context.None],
['class a { constructor(){ class x { [super()](){} } }}', Context.None],
//['class a { constructor(){ class x extends y { [super()](){} } }}', Context.None],
['class a { constructor(){ class x extends super() {} }}', Context.None],
['class x \n /foo/ {}', Context.None],
['class x { x \n /foo/ }', Context.None],
['class x { set \n /foo/ }', Context.None],
['class x { y(z, \n /foo/){} }', Context.None],
['class x { y()\n /foo/{} }', Context.None],
['class x { y() {}\n /foo/ }', Context.None],
['let c = class x { \n /foo/ }', Context.None],
['let c = class x { get \n /foo/ }', Context.None],
['class A {"x"){}}', Context.None],
['class A {"x"{}}', Context.None],
['(class A {async prototype(){}})', Context.None],
['(class A {constructor(){}; constructor(){}})', Context.None],
['(class A {a(){}; constructor(){}; constructor(){}})', Context.None],
['(class A {a(){}; constructor(){}; a(){}; a(){}; a(){}; constructor(){}; a(){}})', Context.None],
['(class A {static constructor(){}; constructor(){}; constructor(){}})', Context.None],
['(class A {foo, bar(){}})', Context.None],
['(class A {foo})', Context.None],
['class A {async get foo(){}}', Context.None],
['(class A {foo = x})', Context.None],
['(class A {async *prototype(){}})', Context.None],
['(class A {set constructor(x){}})', Context.None],
Expand Down
1 change: 0 additions & 1 deletion test/parser/expressions/generators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ describe('Expressions - Generators', () => {
'yield / yield',
'+ yield',
'+ yield 3',
'yield\n*3',
'yield\n{yield: 42}',
'yield /* comment */\n {yield: 42}',
'yield //comment\n {yield: 42}',
Expand Down
121 changes: 121 additions & 0 deletions test/parser/expressions/member.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,127 @@ describe('Expressions - Member', () => {
]
}
],
[
'x[a, b]',
Context.OptionsRanges,
{
type: 'Program',
sourceType: 'script',
body: [
{
type: 'ExpressionStatement',
expression: {
type: 'MemberExpression',
object: {
type: 'Identifier',
name: 'x',
start: 0,
end: 1
},
computed: true,
property: {
type: 'SequenceExpression',
expressions: [
{
type: 'Identifier',
name: 'a',
start: 2,
end: 3
},
{
type: 'Identifier',
name: 'b',
start: 5,
end: 6
}
],
start: 2,
end: 6
},
start: 0,
end: 7
},
start: 0,
end: 7
}
],
start: 0,
end: 7
}
],
[
'(2[x,x],x)>x',
Context.OptionsRanges,
{
type: 'Program',
sourceType: 'script',
body: [
{
type: 'ExpressionStatement',
expression: {
type: 'BinaryExpression',
left: {
type: 'SequenceExpression',
expressions: [
{
type: 'MemberExpression',
object: {
type: 'Literal',
value: 2,
start: 1,
end: 2
},
computed: true,
property: {
type: 'SequenceExpression',
expressions: [
{
type: 'Identifier',
name: 'x',
start: 3,
end: 4
},
{
type: 'Identifier',
name: 'x',
start: 5,
end: 6
}
],
start: 3,
end: 6
},
start: 1,
end: 7
},
{
type: 'Identifier',
name: 'x',
start: 8,
end: 9
}
],
start: 1,
end: 9
},
right: {
type: 'Identifier',
name: 'x',
start: 11,
end: 12
},
operator: '>',
start: 0,
end: 12
},
start: 0,
end: 12
}
],
start: 0,
end: 12
}
],
[
'foo.bar',
Context.None,
Expand Down
Loading

0 comments on commit 7978118

Please sign in to comment.