Skip to content

Commit 512cd66

Browse files
lahmaariya
authored andcommitted
clean up duplicate parameter detection
1 parent 9b3ad04 commit 512cd66

21 files changed

+43
-2483
lines changed

src/messages.ts

-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ export const Messages = {
5151
StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
5252
StrictModeWith: 'Strict mode code may not include a with statement',
5353
StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
54-
StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
5554
StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
5655
StrictReservedWord: 'Use of future reserved word in strict mode',
5756
StrictVarName: 'Variable name may not be eval or arguments in strict mode',

src/parser.ts

+29-36
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ interface Context {
2020
allowIn: boolean;
2121
allowStrictDirective: boolean;
2222
allowYield: boolean;
23-
await: boolean;
23+
isAsync: boolean;
2424
firstCoverInitializedNameError: RawToken | null;
2525
isAssignmentTarget: boolean;
2626
isBindingElement: boolean;
@@ -144,7 +144,7 @@ export class Parser {
144144

145145
this.context = {
146146
isModule: false,
147-
await: false,
147+
isAsync: false,
148148
allowIn: true,
149149
allowStrictDirective: true,
150150
allowYield: true,
@@ -621,7 +621,7 @@ export class Parser {
621621

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

798798
const previousAllowYield = this.context.allowYield;
799-
const previousAwait = this.context.await;
799+
const previousIsAsync = this.context.isAsync;
800800
this.context.allowYield = false;
801-
this.context.await = true;
801+
this.context.isAsync = true;
802802

803803
const params = this.parseFormalParameters();
804-
if (params.message === Messages.StrictParamDupe) {
805-
this.throwError(Messages.DuplicateParameter);
806-
}
807-
808804
const method = this.parsePropertyMethod(params);
809805
this.context.allowYield = previousAllowYield;
810-
this.context.await = previousAwait;
806+
this.context.isAsync = previousIsAsync;
811807

812808
return this.finalize(node, new Node.AsyncFunctionExpression(null, params.params, method, isGenerator));
813809
}
@@ -1567,7 +1563,7 @@ export class Parser {
15671563
}
15681564
this.context.isAssignmentTarget = false;
15691565
this.context.isBindingElement = false;
1570-
} else if (this.context.await && this.matchContextualKeyword('await')) {
1566+
} else if (this.context.isAsync && this.matchContextualKeyword('await')) {
15711567
expr = this.parseAwaitExpression();
15721568
} else {
15731569
expr = this.parseUpdateExpression();
@@ -1798,9 +1794,9 @@ export class Parser {
17981794
}
17991795
}
18001796

1801-
if (options.message === Messages.StrictParamDupe) {
1797+
if (options.hasDuplicateParameterNames) {
18021798
const token = this.context.strict ? options.stricted : options.firstRestricted;
1803-
this.throwUnexpectedToken(token, options.message);
1799+
this.throwUnexpectedToken(token, Messages.DuplicateParameter);
18041800
}
18051801

18061802
return {
@@ -1853,9 +1849,9 @@ export class Parser {
18531849
this.context.allowStrictDirective = list.simple;
18541850

18551851
const previousAllowYield = this.context.allowYield;
1856-
const previousAwait = this.context.await;
1852+
const previousIsAsync = this.context.isAsync;
18571853
this.context.allowYield = true;
1858-
this.context.await = isAsync;
1854+
this.context.isAsync = isAsync;
18591855

18601856
const node = this.startNode(startToken);
18611857
this.expect('=>');
@@ -1882,7 +1878,7 @@ export class Parser {
18821878
this.context.strict = previousStrict;
18831879
this.context.allowStrictDirective = previousAllowStrictDirective;
18841880
this.context.allowYield = previousAllowYield;
1885-
this.context.await = previousAwait;
1881+
this.context.isAsync = previousIsAsync;
18861882
}
18871883
} else {
18881884

@@ -2233,7 +2229,7 @@ export class Parser {
22332229
this.throwUnexpectedToken(token);
22342230
}
22352231
}
2236-
} else if ((this.context.isModule || this.context.await) && token.type === Token.Identifier && token.value === 'await') {
2232+
} else if ((this.context.isModule || this.context.isAsync) && token.type === Token.Identifier && token.value === 'await') {
22372233
this.tolerateUnexpectedToken(token);
22382234
}
22392235

@@ -2403,7 +2399,7 @@ export class Parser {
24032399
const node = this.createNode();
24042400
this.expectKeyword('for');
24052401
if (this.matchContextualKeyword('await')) {
2406-
if (!this.context.await) {
2402+
if (!this.context.isAsync) {
24072403
this.tolerateUnexpectedToken(this.lookahead);
24082404
}
24092405
_await = true;
@@ -2975,7 +2971,7 @@ export class Parser {
29752971
}
29762972
if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
29772973
options.stricted = param;
2978-
options.message = Messages.StrictParamDupe;
2974+
options.hasDuplicateParameterNames = true;
29792975
}
29802976
} else if (!options.firstRestricted) {
29812977
if (this.scanner.isRestrictedWord(name)) {
@@ -2986,7 +2982,7 @@ export class Parser {
29862982
options.message = Messages.StrictReservedWord;
29872983
} else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
29882984
options.stricted = param;
2989-
options.message = Messages.StrictParamDupe;
2985+
options.hasDuplicateParameterNames = true;
29902986
}
29912987
}
29922988

@@ -3026,6 +3022,7 @@ export class Parser {
30263022
parseFormalParameters(firstRestricted?) {
30273023
const options: any = {
30283024
simple: true,
3025+
hasDuplicateParameterNames: false,
30293026
params: [],
30303027
firstRestricted: firstRestricted
30313028
};
@@ -3046,6 +3043,12 @@ export class Parser {
30463043
}
30473044
this.expect(')');
30483045

3046+
if (options.hasDuplicateParameterNames) {
3047+
if (this.context.strict || this.context.isAsync || !options.simple) {
3048+
this.throwError(Messages.DuplicateParameter);
3049+
}
3050+
}
3051+
30493052
return {
30503053
simple: options.simple,
30513054
params: options.params,
@@ -3109,16 +3112,12 @@ export class Parser {
31093112
}
31103113
}
31113114

3112-
const previousAllowAwait = this.context.await;
3115+
const previousIsAsync = this.context.isAsync;
31133116
const previousAllowYield = this.context.allowYield;
3114-
this.context.await = isAsync;
3117+
this.context.isAsync = isAsync;
31153118
this.context.allowYield = !isGenerator;
31163119

31173120
const formalParameters = this.parseFormalParameters(firstRestricted);
3118-
if (isGenerator && formalParameters.message === Messages.StrictParamDupe) {
3119-
this.throwError(Messages.DuplicateParameter);
3120-
}
3121-
31223121
const params = formalParameters.params;
31233122
const stricted = formalParameters.stricted;
31243123
firstRestricted = formalParameters.firstRestricted;
@@ -3139,7 +3138,7 @@ export class Parser {
31393138

31403139
this.context.strict = previousStrict;
31413140
this.context.allowStrictDirective = previousAllowStrictDirective;
3142-
this.context.await = previousAllowAwait;
3141+
this.context.isAsync = previousIsAsync;
31433142
this.context.allowYield = previousAllowYield;
31443143

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

3169-
const previousAllowAwait = this.context.await;
3168+
const previousIsAsync = this.context.isAsync;
31703169
const previousAllowYield = this.context.allowYield;
3171-
this.context.await = isAsync;
3170+
this.context.isAsync = isAsync;
31723171
this.context.allowYield = !isGenerator;
31733172

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

31923191
const formalParameters = this.parseFormalParameters(firstRestricted);
3193-
if (formalParameters.message === Messages.StrictParamDupe) {
3194-
if (isGenerator || isAsync) {
3195-
this.throwError(Messages.DuplicateParameter);
3196-
}
3197-
}
3198-
31993192
const params = formalParameters.params;
32003193
const stricted = formalParameters.stricted;
32013194
firstRestricted = formalParameters.firstRestricted;
@@ -3215,7 +3208,7 @@ export class Parser {
32153208
}
32163209
this.context.strict = previousStrict;
32173210
this.context.allowStrictDirective = previousAllowStrictDirective;
3218-
this.context.await = previousAllowAwait;
3211+
this.context.isAsync = previousIsAsync;
32193212
this.context.allowYield = previousAllowYield;
32203213

32213214
return isAsync
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"index":14,"lineNumber":1,"column":15,"message":"Error: Line 1: Strict mode function may not have duplicate parameter names","description":"Strict mode function may not have duplicate parameter names"}
1+
{"index":14,"lineNumber":1,"column":15,"message":"Error: Line 1: Duplicate parameter name not allowed in this context","description":"Duplicate parameter name not allowed in this context"}
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"index":10,"lineNumber":1,"column":11,"message":"Error: Line 1: Strict mode function may not have duplicate parameter names","description":"Strict mode function may not have duplicate parameter names"}
1+
{"index":10,"lineNumber":1,"column":11,"message":"Error: Line 1: Duplicate parameter name not allowed in this context","description":"Duplicate parameter name not allowed in this context"}
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"index":6,"lineNumber":1,"column":7,"message":"Error: Line 1: Strict mode function may not have duplicate parameter names","description":"Strict mode function may not have duplicate parameter names"}
1+
{"index":6,"lineNumber":1,"column":7,"message":"Error: Line 1: Duplicate parameter name not allowed in this context","description":"Duplicate parameter name not allowed in this context"}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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"}

0 commit comments

Comments
 (0)