Skip to content

Commit

Permalink
clean up duplicate parameter detection
Browse files Browse the repository at this point in the history
  • Loading branch information
lahma committed Aug 22, 2021
1 parent ce48f3d commit 167f374
Show file tree
Hide file tree
Showing 21 changed files with 38 additions and 2,483 deletions.
1 change: 0 additions & 1 deletion src/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ export const Messages = {
StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
StrictModeWith: 'Strict mode code may not include a with statement',
StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
StrictReservedWord: 'Use of future reserved word in strict mode',
StrictVarName: 'Variable name may not be eval or arguments in strict mode',
Expand Down
65 changes: 29 additions & 36 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ interface Context {
allowIn: boolean;
allowStrictDirective: boolean;
allowYield: boolean;
await: boolean;
isAsync: boolean;
firstCoverInitializedNameError: RawToken | null;
isAssignmentTarget: boolean;
isBindingElement: boolean;
Expand Down Expand Up @@ -144,7 +144,7 @@ export class Parser {

this.context = {
isModule: false,
await: false,
isAsync: false,
allowIn: true,
allowStrictDirective: true,
allowYield: true,
Expand Down Expand Up @@ -621,7 +621,7 @@ export class Parser {

switch (this.lookahead.type) {
case Token.Identifier:
if ((this.context.isModule || this.context.await) && this.lookahead.value === 'await') {
if ((this.context.isModule || this.context.isAsync) && this.lookahead.value === 'await') {
this.tolerateUnexpectedToken(this.lookahead);
}
expr = this.matchAsyncFunction() ? this.parseFunctionExpression() : this.finalize(node, new Node.Identifier(this.nextToken().value));
Expand Down Expand Up @@ -796,18 +796,14 @@ export class Parser {
const node = this.createNode();

const previousAllowYield = this.context.allowYield;
const previousAwait = this.context.await;
const previousIsAsync = this.context.isAsync;
this.context.allowYield = false;
this.context.await = true;
this.context.isAsync = true;

const params = this.parseFormalParameters();
if (params.message === Messages.StrictParamDupe) {
this.throwError(Messages.DuplicateParameter);
}

const method = this.parsePropertyMethod(params);
this.context.allowYield = previousAllowYield;
this.context.await = previousAwait;
this.context.isAsync = previousIsAsync;

return this.finalize(node, new Node.AsyncFunctionExpression(null, params.params, method, isGenerator));
}
Expand Down Expand Up @@ -1567,7 +1563,7 @@ export class Parser {
}
this.context.isAssignmentTarget = false;
this.context.isBindingElement = false;
} else if (this.context.await && this.matchContextualKeyword('await')) {
} else if (this.context.isAsync && this.matchContextualKeyword('await')) {
expr = this.parseAwaitExpression();
} else {
expr = this.parseUpdateExpression();
Expand Down Expand Up @@ -1798,9 +1794,9 @@ export class Parser {
}
}

if (options.message === Messages.StrictParamDupe) {
if (options.hasDuplicateParameterNames) {
const token = this.context.strict ? options.stricted : options.firstRestricted;
this.throwUnexpectedToken(token, options.message);
this.throwUnexpectedToken(token, Messages.DuplicateParameter);
}

return {
Expand Down Expand Up @@ -1853,9 +1849,9 @@ export class Parser {
this.context.allowStrictDirective = list.simple;

const previousAllowYield = this.context.allowYield;
const previousAwait = this.context.await;
const previousIsAsync = this.context.isAsync;
this.context.allowYield = true;
this.context.await = isAsync;
this.context.isAsync = isAsync;

const node = this.startNode(startToken);
this.expect('=>');
Expand All @@ -1882,7 +1878,7 @@ export class Parser {
this.context.strict = previousStrict;
this.context.allowStrictDirective = previousAllowStrictDirective;
this.context.allowYield = previousAllowYield;
this.context.await = previousAwait;
this.context.isAsync = previousIsAsync;
}
} else {

Expand Down Expand Up @@ -2233,7 +2229,7 @@ export class Parser {
this.throwUnexpectedToken(token);
}
}
} else if ((this.context.isModule || this.context.await) && token.type === Token.Identifier && token.value === 'await') {
} else if ((this.context.isModule || this.context.isAsync) && token.type === Token.Identifier && token.value === 'await') {
this.tolerateUnexpectedToken(token);
}

Expand Down Expand Up @@ -2403,7 +2399,7 @@ export class Parser {
const node = this.createNode();
this.expectKeyword('for');
if (this.matchContextualKeyword('await')) {
if (!this.context.await) {
if (!this.context.isAsync) {
this.tolerateUnexpectedToken(this.lookahead);
}
_await = true;
Expand Down Expand Up @@ -2975,7 +2971,7 @@ export class Parser {
}
if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
options.stricted = param;
options.message = Messages.StrictParamDupe;
options.hasDuplicateParameterNames = true;
}
} else if (!options.firstRestricted) {
if (this.scanner.isRestrictedWord(name)) {
Expand All @@ -2986,7 +2982,7 @@ export class Parser {
options.message = Messages.StrictReservedWord;
} else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
options.stricted = param;
options.message = Messages.StrictParamDupe;
options.hasDuplicateParameterNames = true;
}
}

Expand Down Expand Up @@ -3026,6 +3022,7 @@ export class Parser {
parseFormalParameters(firstRestricted?) {
const options: any = {
simple: true,
hasDuplicateParameterNames: false,
params: [],
firstRestricted: firstRestricted
};
Expand All @@ -3046,6 +3043,12 @@ export class Parser {
}
this.expect(')');

if (options.hasDuplicateParameterNames) {
if (this.context.strict || this.context.isAsync || !options.simple) {
this.throwError(Messages.DuplicateParameter);
}
}

return {
simple: options.simple,
params: options.params,
Expand Down Expand Up @@ -3109,16 +3112,12 @@ export class Parser {
}
}

const previousAllowAwait = this.context.await;
const previousIsAsync = this.context.isAsync;
const previousAllowYield = this.context.allowYield;
this.context.await = isAsync;
this.context.isAsync = isAsync;
this.context.allowYield = !isGenerator;

const formalParameters = this.parseFormalParameters(firstRestricted);
if (isGenerator && formalParameters.message === Messages.StrictParamDupe) {
this.throwError(Messages.DuplicateParameter);
}

const params = formalParameters.params;
const stricted = formalParameters.stricted;
firstRestricted = formalParameters.firstRestricted;
Expand All @@ -3139,7 +3138,7 @@ export class Parser {

this.context.strict = previousStrict;
this.context.allowStrictDirective = previousAllowStrictDirective;
this.context.await = previousAllowAwait;
this.context.isAsync = previousIsAsync;
this.context.allowYield = previousAllowYield;

return isAsync
Expand All @@ -3166,9 +3165,9 @@ export class Parser {
let id: Node.Identifier | null = null;
let firstRestricted;

const previousAllowAwait = this.context.await;
const previousIsAsync = this.context.isAsync;
const previousAllowYield = this.context.allowYield;
this.context.await = isAsync;
this.context.isAsync = isAsync;
this.context.allowYield = !isGenerator;

if (!this.match('(')) {
Expand All @@ -3190,12 +3189,6 @@ export class Parser {
}

const formalParameters = this.parseFormalParameters(firstRestricted);
if (formalParameters.message === Messages.StrictParamDupe) {
if (isGenerator || isAsync) {
this.throwError(Messages.DuplicateParameter);
}
}

const params = formalParameters.params;
const stricted = formalParameters.stricted;
firstRestricted = formalParameters.firstRestricted;
Expand All @@ -3215,7 +3208,7 @@ export class Parser {
}
this.context.strict = previousStrict;
this.context.allowStrictDirective = previousAllowStrictDirective;
this.context.await = previousAllowAwait;
this.context.isAsync = previousIsAsync;
this.context.allowYield = previousAllowYield;

return isAsync
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"index":31,"lineNumber":2,"column":18,"message":"Error: Line 2: Duplicate parameter name not allowed in this context","description":"Duplicate parameter name not allowed in this context"}
Loading

0 comments on commit 167f374

Please sign in to comment.