Skip to content

Commit

Permalink
fix(parser): removed unused code and improved test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
KFlash committed Jul 24, 2019
1 parent 98c6ee7 commit 7b4b56f
Show file tree
Hide file tree
Showing 18 changed files with 983 additions and 5,219 deletions.
348 changes: 192 additions & 156 deletions package-lock.json

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,23 +61,23 @@
},
"devDependencies": {
"@types/mocha": "^5.2.7",
"@types/node": "^12.0.10",
"@typescript-eslint/eslint-plugin": "^1.11.0",
"@typescript-eslint/parser": "^1.11.0",
"@types/node": "^12.6.8",
"@typescript-eslint/eslint-plugin": "^1.13.0",
"@typescript-eslint/parser": "^1.13.0",
"chalk": "^2.4.2",
"coveralls": "^3.0.4",
"cross-env": "^5.2.0",
"eslint": "^6.0.1",
"eslint-plugin-import": "^2.18.0",
"eslint": "^6.1.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-node": "^9.1.0",
"glob": "^7.1.4",
"husky": "^2.7.0",
"mocha": "^6.1.4",
"husky": "^3.0.1",
"mocha": "^6.2.0",
"nyc": "^14.1.1",
"path": "^0.12.7",
"prettier": "^1.18.2",
"rimraf": "^2.6.3",
"rollup": "^1.16.7",
"rollup": "^1.17.0",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-terser": "^5.1.1",
"rollup-plugin-typescript2": "^0.22.0",
Expand Down
20 changes: 1 addition & 19 deletions src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -652,31 +652,13 @@ export function addBlockName(
if (scope.type & ScopeKind.ArrowParams && value && (value & BindingKind.EmptyBinding) === 0) {
if (type & BindingKind.ArgumentList) {
scope.scopeError = recordScopeError(parser, Errors.Unexpected);
} else if ((type & (BindingKind.CatchIdentifier | BindingKind.CatchPattern)) === 0) {
report(parser, Errors.DuplicateBinding, name);
}
}

if (type & (BindingKind.CatchIdentifier | BindingKind.CatchPattern)) {
if (value & (BindingKind.CatchIdentifier | BindingKind.CatchPattern)) report(parser, Errors.ShadowedCatchClause, name);
} else if (scope.type & ScopeKind.CatchBody) {
if (scope.type & ScopeKind.CatchBody) {
if ((scope as any).parent['#' + name] & BindingKind.CatchIdentifierOrPattern) report(parser, Errors.ShadowedCatchClause, name);
}

let currentScope: any = scope.parent;

while (currentScope && (currentScope.type & ScopeKind.FuncRoot) !== ScopeKind.FuncRoot) {
const value = currentScope['#' + name];
if (currentScope.type & ScopeKind.ArrowParams) {
if (value && (value & BindingKind.EmptyBinding) === 0 && (type & BindingKind.CatchIdentifierOrPattern) === 0 ) {
report(parser, Errors.DuplicateBinding, name);
} else if (type & BindingKind.ArgumentList) {
currentScope.scopeError = recordScopeError(parser, Errors.Unexpected);
}
}
currentScope = currentScope.parent;
}

(scope as any)['#' + name] = type;
}

Expand Down
165 changes: 74 additions & 91 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1806,113 +1806,96 @@ export function parseLetIdentOrVarDeclarationStatement(
): ESTree.VariableDeclaration | ESTree.LabeledStatement | ESTree.ExpressionStatement {
const { token, tokenValue } = parser;
let expr: ESTree.Identifier | ESTree.Expression = parseIdentifier(parser, context, 0, start, line, column);
// If the next token is an identifier, `[`, or `{`, this is not
// a `let` declaration, and we parse it as an identifier.
if (
(parser.token & (Token.IsIdentifier | Token.IsPatternStart)) === 0 ||
(parser.flags & Flags.NewLine && parser.token & Token.IsIdentifier)
) {
parser.assignable = AssignmentKind.Assignable;

if (context & Context.Strict) report(parser, Errors.UnexpectedLetStrictReserved);

/** LabelledStatement[Yield, Await, Return]:
*
* ExpressionStatement | LabelledStatement ::
* Expression ';'
* Identifier ':' Statement
*
* ExpressionStatement[Yield] :
* [lookahead notin {{, function, class, let [}] Expression[In, ?Yield] ;
if (parser.token & (Token.IsIdentifier | Token.IsPatternStart)) {
/* VariableDeclarations ::
* ('let') (Identifier ('=' AssignmentExpression)?)+[',']
*/
const declarations = parseVariableDeclarationList(parser, context, scope, BindingKind.Let, BindingOrigin.Statement);

if (parser.token === Token.Colon) {
return parseLabelledStatement(
parser,
context,
scope,
origin,
{},
tokenValue,
expr,
token,
0,
start,
line,
column
);
}
matchOrInsertSemicolon(parser, context | Context.AllowRegExp);

/**
* ArrowFunction :
* ArrowParameters => ConciseBody
*
* ConciseBody :
* [lookahead not {] AssignmentExpression
* { FunctionBody }
*
*/
if (parser.token === Token.Arrow) {
let scope: ScopeState | undefined = void 0;
return finishNode(parser, context, start, line, column, {
type: 'VariableDeclaration',
kind: 'let',
declarations
});
}
// 'Let' as identifier
parser.assignable = AssignmentKind.Assignable;

if (context & Context.OptionsLexical) scope = createArrowScope(parser, context, tokenValue);
if (context & Context.Strict) report(parser, Errors.UnexpectedLetStrictReserved);

parser.flags = (parser.flags | Flags.SimpleParameterList) ^ Flags.SimpleParameterList;
/** LabelledStatement[Yield, Await, Return]:
*
* ExpressionStatement | LabelledStatement ::
* Expression ';'
* Identifier ':' Statement
*
* ExpressionStatement[Yield] :
* [lookahead notin {{, function, class, let [}] Expression[In, ?Yield] ;
*/

expr = parseArrowFunctionExpression(parser, context, scope, [expr], /* isAsync */ 0, start, line, column);
} else {
/**
* UpdateExpression ::
* ('++' | '--')? LeftHandSideExpression
*
* MemberExpression ::
* (PrimaryExpression | FunctionLiteral | ClassLiteral)
* ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
*
* CallExpression ::
* (SuperCall | ImportCall)
* ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
*
* LeftHandSideExpression ::
* (NewExpression | MemberExpression) ...
*/

expr = parseMemberOrUpdateExpression(parser, context, expr, 0, start, line, column);

/**
* AssignmentExpression :
* 1. ConditionalExpression
* 2. LeftHandSideExpression = AssignmentExpression
*
*/
expr = parseAssignmentExpression(parser, context, 0, start, line, column, expr as ESTree.ArgumentExpression);
}
if (parser.token === Token.Colon) {
return parseLabelledStatement(parser, context, scope, origin, {}, tokenValue, expr, token, 0, start, line, column);
}

/** Sequence expression
/**
* ArrowFunction :
* ArrowParameters => ConciseBody
*
* ConciseBody :
* [lookahead not {] AssignmentExpression
* { FunctionBody }
*
*/
if (parser.token === Token.Arrow) {
let scope: ScopeState | undefined = void 0;

if (context & Context.OptionsLexical) scope = createArrowScope(parser, context, tokenValue);

parser.flags = (parser.flags | Flags.SimpleParameterList) ^ Flags.SimpleParameterList;

expr = parseArrowFunctionExpression(parser, context, scope, [expr], /* isAsync */ 0, start, line, column);
} else {
/**
* UpdateExpression ::
* ('++' | '--')? LeftHandSideExpression
*
* MemberExpression ::
* (PrimaryExpression | FunctionLiteral | ClassLiteral)
* ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
*
* CallExpression ::
* (SuperCall | ImportCall)
* ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
*
* LeftHandSideExpression ::
* (NewExpression | MemberExpression) ...
*/
if (parser.token === Token.Comma) {
expr = parseSequenceExpression(parser, context, 0, start, line, column, expr);
}

expr = parseMemberOrUpdateExpression(parser, context, expr, 0, start, line, column);

/**
* ExpressionStatement[Yield, Await]:
* [lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }]Expression[+In, ?Yield, ?Await]
* AssignmentExpression :
* 1. ConditionalExpression
* 2. LeftHandSideExpression = AssignmentExpression
*
*/
return parseExpressionStatement(parser, context, expr, start, line, column);
expr = parseAssignmentExpression(parser, context, 0, start, line, column, expr as ESTree.ArgumentExpression);
}

/* VariableDeclarations ::
* ('let') (Identifier ('=' AssignmentExpression)?)+[',']
/** Sequence expression
*/
const declarations = parseVariableDeclarationList(parser, context, scope, BindingKind.Let, BindingOrigin.Statement);

matchOrInsertSemicolon(parser, context | Context.AllowRegExp);
if (parser.token === Token.Comma) {
expr = parseSequenceExpression(parser, context, 0, start, line, column, expr);
}

return finishNode(parser, context, start, line, column, {
type: 'VariableDeclaration',
kind: 'let',
declarations
});
/**
* ExpressionStatement[Yield, Await]:
* [lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }]Expression[+In, ?Yield, ?Await]
*/
return parseExpressionStatement(parser, context, expr, start, line, column);
}

/**
Expand Down
19 changes: 19 additions & 0 deletions test/parser/declarations/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ describe('Declarations - const', () => {
}

for (const arg of [
'const a = Infinity;',
'const b = -Infinity;',
'const c = +Infinity;',
'const d = /abc/;',
'const e = /abc/g;',
'const f = /abc/gi;',
'const [] = x;',
'const [,] = x;',
'const [,,] = x;',
Expand Down Expand Up @@ -201,6 +207,19 @@ describe('Declarations - const', () => {
['for (const {};;);', Context.None],
['const {};', Context.None],
['const foo;', Context.None],
[`do const x = 1; while (false)`, Context.None],
['while (false) const x = 1;', Context.None],
['label: const x;', Context.None],
['while (false) const x;', Context.None],
['const [...x = []] = [];', Context.None],
['const [...[x], y] = [1, 2, 3];', Context.None],
['const x, y = 1;', Context.None],
['do const x = 1; while (false)', Context.None],
['const [...{ x }, y] = [1, 2, 3];', Context.None],
['const [...x, y] = [1, 2, 3];', Context.None],
// Babylon PR: https://github.com/babel/babylon/pull/195
['const { foo: enum } = bar();', Context.None],
['function foo({ bar: enum }) {}', Context.None],
['const foo', Context.None],
['const foo, bar;', Context.None],
['const foo, bar', Context.None],
Expand Down
Loading

0 comments on commit 7b4b56f

Please sign in to comment.