: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
var expr = this.parseAssignmentExpression();
value = this.finalize(this.startNode(keyToken), new Node.AssignmentPattern(init, expr));
else if (!this.match(':')) {
value = this.parsePatternWithDefault(params, kind);
computed = this.match('[');
key = this.parseObjectPropertyKey();
value = this.parsePatternWithDefault(params, kind);
return this.finalize(node, new Node.Property('init', key, computed, value, method, shorthand));
Parser.prototype.parseObjectPattern = function (params, kind) {
var node = this.createNode();
while (!this.match('}')) {
properties.push(this.parsePropertyPattern(params, kind));
return this.finalize(node, new Node.ObjectPattern(properties));
Parser.prototype.parsePattern = function (params, kind) {
pattern = this.parseArrayPattern(params, kind);
else if (this.match('{')) {
pattern = this.parseObjectPattern(params, kind);
if (this.matchKeyword('let') && (kind === 'const' || kind === 'let')) {
this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.LetInLexicalBinding);
params.push(this.lookahead);
pattern = this.parseVariableIdentifier(kind);
Parser.prototype.parsePatternWithDefault = function (params, kind) {
var startToken = this.lookahead;
var pattern = this.parsePattern(params, kind);
var previousAllowYield = this.context.allowYield;
this.context.allowYield = true;
var right = this.isolateCoverGrammar(this.parseAssignmentExpression);
this.context.allowYield = previousAllowYield;
pattern = this.finalize(this.startNode(startToken), new Node.AssignmentPattern(pattern, right));
// https://tc39.github.io/ecma262/#sec-variable-statement
Parser.prototype.parseVariableIdentifier = function (kind) {
var node = this.createNode();
var token = this.nextToken();
if (token.type === 4 /* Keyword */ && token.value === 'yield') {
if (this.context.strict) {
this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord);
else if (!this.context.allowYield) {
this.throwUnexpectedToken(token);
else if (token.type !== 3 /* Identifier */) {
if (this.context.strict && token.type === 4 /* Keyword */ && this.scanner.isStrictModeReservedWord(token.value)) {
this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord);
if (this.context.strict || token.value !== 'let' || kind !== 'var') {
this.throwUnexpectedToken(token);
else if ((this.context.isModule || this.context.await) && token.type === 3 /* Identifier */ && token.value === 'await') {
this.tolerateUnexpectedToken(token);
return this.finalize(node, new Node.Identifier(token.value));
Parser.prototype.parseVariableDeclaration = function (options) {
var node = this.createNode();
var id = this.parsePattern(params, 'var');
if (this.context.strict && id.type === syntax_1.Syntax.Identifier) {
if (this.scanner.isRestrictedWord(id.name)) {
this.tolerateError(messages_1.Messages.StrictVarName);
init = this.isolateCoverGrammar(this.parseAssignmentExpression);
else if (id.type !== syntax_1.Syntax.Identifier && !options.inFor) {
return this.finalize(node, new Node.VariableDeclarator(id, init));
Parser.prototype.parseVariableDeclarationList = function (options) {
var opt = { inFor: options.inFor };
list.push(this.parseVariableDeclaration(opt));
while (this.match(',')) {
list.push(this.parseVariableDeclaration(opt));
Parser.prototype.parseVariableStatement = function () {
var node = this.createNode();
this.expectKeyword('var');
var declarations = this.parseVariableDeclarationList({ inFor: false });
return this.finalize(node, new Node.VariableDeclaration(declarations, 'var'));
// https://tc39.github.io/ecma262/#sec-empty-statement
Parser.prototype.parseEmptyStatement = function () {
var node = this.createNode();
return this.finalize(node, new Node.EmptyStatement());
// https://tc39.github.io/ecma262/#sec-expression-statement
Parser.prototype.parseExpressionStatement = function () {
var node = this.createNode();
var expr = this.parseExpression();
return this.finalize(node, new Node.ExpressionStatement(expr));
// https://tc39.github.io/ecma262/#sec-if-statement
Parser.prototype.parseIfClause = function () {
if (this.context.strict && this.matchKeyword('function')) {
this.tolerateError(messages_1.Messages.StrictFunction);
return this.parseStatement();
Parser.prototype.parseIfStatement = function () {
var node = this.createNode();
this.expectKeyword('if');
var test = this.parseExpression();
if (!this.match(')') && this.config.tolerant) {
this.tolerateUnexpectedToken(this.nextToken());
consequent = this.finalize(this.createNode(), new Node.EmptyStatement());
consequent = this.parseIfClause();
if (this.matchKeyword('else')) {
alternate = this.parseIfClause();
return this.finalize(node, new Node.IfStatement(test, consequent, alternate));
// https://tc39.github.io/ecma262/#sec-do-while-statement
Parser.prototype.parseDoWhileStatement = function () {
var node = this.createNode();
this.expectKeyword('do');
var previousInIteration = this.context.inIteration;
this.context.inIteration = true;
var body = this.parseStatement();
this.context.inIteration = previousInIteration;
this.expectKeyword('while');
var test = this.parseExpression();
if (!this.match(')') && this.config.tolerant) {
this.tolerateUnexpectedToken(this.nextToken());
return this.finalize(node, new Node.DoWhileStatement(body, test));
// https://tc39.github.io/ecma262/#sec-while-statement
Parser.prototype.parseWhileStatement = function () {
var node = this.createNode();
this.expectKeyword('while');
var test = this.parseExpression();
if (!this.match(')') && this.config.tolerant) {
this.tolerateUnexpectedToken(this.nextToken());
body = this.finalize(this.createNode(), new Node.EmptyStatement());
var previousInIteration = this.context.inIteration;
this.context.inIteration = true;
body = this.parseStatement();
this.context.inIteration = previousInIteration;
return this.finalize(node, new Node.WhileStatement(test, body));
// https://tc39.github.io/ecma262/#sec-for-statement
// https://tc39.github.io/ecma262/#sec-for-in-and-for-of-statements
Parser.prototype.parseForStatement = function () {
var node = this.createNode();
this.expectKeyword('for');
if (this.matchKeyword('var')) {
init = this.createNode();
var previousAllowIn = this.context.allowIn;
this.context.allowIn = false;
var declarations = this.parseVariableDeclarationList({ inFor: true });
this.context.allowIn = previousAllowIn;
if (declarations.length === 1 && this.matchKeyword('in')) {
var decl = declarations[0];
if (decl.init && (decl.id.type === syntax_1.Syntax.ArrayPattern || decl.id.type === syntax_1.Syntax.ObjectPattern || this.context.strict)) {
this.tolerateError(messages_1.Messages.ForInOfLoopInitializer, 'for-in');
init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var'));
right = this.parseExpression();
else if (declarations.length === 1 && declarations[0].init === null && this.matchContextualKeyword('of')) {
init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var'));
right = this.parseAssignmentExpression();
init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var'));
else if (this.matchKeyword('const') || this.matchKeyword('let')) {
init = this.createNode();
var kind = this.nextToken().value;
if (!this.context.strict && this.lookahead.value === 'in') {
init = this.finalize(init, new Node.Identifier(kind));
right = this.parseExpression();
var previousAllowIn = this.context.allowIn;
this.context.allowIn = false;
var declarations = this.parseBindingList(kind, { inFor: true });
this.context.allowIn = previousAllowIn;
if (declarations.length === 1 && declarations[0].init === null && this.matchKeyword('in')) {
init = this.finalize(init, new Node.VariableDeclaration(declarations, kind));
right = this.parseExpression();
else if (declarations.length === 1 && declarations[0].init === null && this.matchContextualKeyword('of')) {
init = this.finalize(init, new Node.VariableDeclaration(declarations, kind));
right = this.parseAssignmentExpression();
init = this.finalize(init, new Node.VariableDeclaration(declarations, kind));
var initStartToken = this.lookahead;
var previousAllowIn = this.context.allowIn;
this.context.allowIn = false;
init = this.inheritCoverGrammar(this.parseAssignmentExpression);
this.context.allowIn = previousAllowIn;
if (this.matchKeyword('in')) {
if (!this.context.isAssignmentTarget || init.type === syntax_1.Syntax.AssignmentExpression) {
this.tolerateError(messages_1.Messages.InvalidLHSInForIn);
this.reinterpretExpressionAsPattern(init);
right = this.parseExpression();
else if (this.matchContextualKeyword('of')) {
if (!this.context.isAssignmentTarget || init.type === syntax_1.Syntax.AssignmentExpression) {
this.tolerateError(messages_1.Messages.InvalidLHSInForLoop);
this.reinterpretExpressionAsPattern(init);
right = this.parseAssignmentExpression();
while (this.match(',')) {
initSeq.push(this.isolateCoverGrammar(this.parseAssignmentExpression));
init = this.finalize(this.startNode(initStartToken), new Node.SequenceExpression(initSeq));
if (typeof left === 'undefined') {
test = this.parseExpression();
update = this.parseExpression();
if (!this.match(')') && this.config.tolerant) {
this.tolerateUnexpectedToken(this.nextToken());
body = this.finalize(this.createNode(), new Node.EmptyStatement());
var previousInIteration = this.context.inIteration;
this.context.inIteration = true;
body = this.isolateCoverGrammar(this.parseStatement);
this.context.inIteration = previousInIteration;
return (typeof left === 'undefined') ?
this.finalize(node, new Node.ForStatement(init, test, update, body)) :
forIn ? this.finalize(node, new Node.ForInStatement(left, right, body)) :
this.finalize(node, new Node.ForOfStatement(left, right, body));
// https://tc39.github.io/ecma262/#sec-continue-statement
Parser.prototype.parseContinueStatement = function () {
var node = this.createNode();
this.expectKeyword('continue');
if (this.lookahead.type === 3 /* Identifier */ && !this.hasLineTerminator) {
var id = this.parseVariableIdentifier();
if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) {
this.throwError(messages_1.Messages.UnknownLabel, id.name);
if (label === null && !this.context.inIteration) {
this.throwError(messages_1.Messages.IllegalContinue);
return this.finalize(node, new Node.ContinueStatement(label));
// https://tc39.github.io/ecma262/#sec-break-statement
Parser.prototype.parseBreakStatement = function () {
var node = this.createNode();
this.expectKeyword('break');
if (this.lookahead.type === 3 /* Identifier */ && !this.hasLineTerminator) {
var id = this.parseVariableIdentifier();
if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) {
this.throwError(messages_1.Messages.UnknownLabel, id.name);
if (label === null && !this.context.inIteration && !this.context.inSwitch) {
this.throwError(messages_1.Messages.IllegalBreak);
return this.finalize(node, new Node.BreakStatement(label));
// https://tc39.github.io/ecma262/#sec-return-statement
Parser.prototype.parseReturnStatement = function () {
if (!this.context.inFunctionBody) {
this.tolerateError(messages_1.Messages.IllegalReturn);
var node = this.createNode();
this.expectKeyword('return');
var hasArgument = !this.match(';') && !this.match('}') &&
!this.hasLineTerminator && this.lookahead.type !== 2 /* EOF */;
var argument = hasArgument ? this.parseExpression() : null;
return this.finalize(node, new Node.ReturnStatement(argument));
// https://tc39.github.io/ecma262/#sec-with-statement
Parser.prototype.parseWithStatement = function () {
if (this.context.strict) {
this.tolerateError(messages_1.Messages.StrictModeWith);
var node = this.createNode();
this.expectKeyword('with');
var object = this.parseExpression();
if (!this.match(')') && this.config.tolerant) {
this.tolerateUnexpectedToken(this.nextToken());
body = this.finalize(this.createNode(), new Node.EmptyStatement());
body = this.parseStatement();
return this.finalize(node, new Node.WithStatement(object, body));
// https://tc39.github.io/ecma262/#sec-switch-statement
Parser.prototype.parseSwitchCase = function () {
var node = this.createNode();
if (this.matchKeyword('default')) {
this.expectKeyword('case');
test = this.parseExpression();
if (this.match('}') || this.matchKeyword('default') || this.matchKeyword('case')) {
consequent.push(this.parseStatementListItem());
return this.finalize(node, new Node.SwitchCase(test, consequent));
Parser.prototype.parseSwitchStatement = function () {
var node = this.createNode();
this.expectKeyword('switch');
var discriminant = this.parseExpression();
var previousInSwitch = this.context.inSwitch;
this.context.inSwitch = true;
var defaultFound = false;
var clause = this.parseSwitchCase();
if (clause.test === null) {
this.throwError(messages_1.Messages.MultipleDefaultsInSwitch);
this.context.inSwitch = previousInSwitch;
return this.finalize(node, new Node.SwitchStatement(discriminant, cases));
// https://tc39.github.io/ecma262/#sec-labelled-statements
Parser.prototype.parseLabelledStatement = function () {
var node = this.createNode();
var expr = this.parseExpression();
if ((expr.type === syntax_1.Syntax.Identifier) && this.match(':')) {
if (Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) {
this.throwError(messages_1.Messages.Redeclaration, 'Label', id.name);
this.context.labelSet[key] = true;
if (this.matchKeyword('class')) {
this.tolerateUnexpectedToken(this.lookahead);
body = this.parseClassDeclaration();
else if (this.matchKeyword('function')) {
var token = this.lookahead;