Disallow duplicate params in methods (#9599)

* Disallow duplicate params in methods

* Fix plugins
This commit is contained in:
Daniel Tschinder 2019-02-27 15:54:07 -08:00 committed by GitHub
parent 5cb280f986
commit 208195f425
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 38 additions and 13 deletions

View File

@ -1740,7 +1740,7 @@ export default class ExpressionParser extends LValParser {
); );
this.parseFunctionParams((node: any), allowModifiers); this.parseFunctionParams((node: any), allowModifiers);
this.checkYieldAwaitInDefaultParams(); this.checkYieldAwaitInDefaultParams();
this.parseFunctionBodyAndFinish(node, type); this.parseFunctionBodyAndFinish(node, type, true);
this.state.yieldPos = oldYieldPos; this.state.yieldPos = oldYieldPos;
this.state.awaitPos = oldAwaitPos; this.state.awaitPos = oldAwaitPos;
@ -1804,14 +1804,19 @@ export default class ExpressionParser extends LValParser {
parseFunctionBodyAndFinish( parseFunctionBodyAndFinish(
node: N.BodilessFunctionOrMethodBase, node: N.BodilessFunctionOrMethodBase,
type: string, type: string,
isMethod?: boolean = false,
): void { ): void {
// $FlowIgnore (node is not bodiless if we get here) // $FlowIgnore (node is not bodiless if we get here)
this.parseFunctionBody(node); this.parseFunctionBody(node, false, isMethod);
this.finishNode(node, type); this.finishNode(node, type);
} }
// Parse function body and check parameters. // Parse function body and check parameters.
parseFunctionBody(node: N.Function, allowExpression: ?boolean): void { parseFunctionBody(
node: N.Function,
allowExpression: ?boolean,
isMethod?: boolean = false,
): void {
const isExpression = allowExpression && !this.match(tt.braceL); const isExpression = allowExpression && !this.match(tt.braceL);
const oldStrict = this.state.strict; const oldStrict = this.state.strict;
let useStrict = false; let useStrict = false;
@ -1853,7 +1858,7 @@ export default class ExpressionParser extends LValParser {
// if a let/const declaration in the function clashes with one of the params. // if a let/const declaration in the function clashes with one of the params.
this.checkParams( this.checkParams(
node, node,
!oldStrict && !useStrict && !allowExpression && !nonSimple, !oldStrict && !useStrict && !allowExpression && !isMethod && !nonSimple,
allowExpression, allowExpression,
); );
node.body = this.parseBlock(true, false); node.body = this.parseBlock(true, false);

View File

@ -259,8 +259,12 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return node; return node;
} }
parseFunctionBody(node: N.Function, allowExpression: ?boolean): void { parseFunctionBody(
super.parseFunctionBody(node, allowExpression); node: N.Function,
allowExpression: ?boolean,
isMethod?: boolean = false,
): void {
super.parseFunctionBody(node, allowExpression, isMethod);
node.expression = node.body.type !== "BlockStatement"; node.expression = node.body.type !== "BlockStatement";
} }

View File

@ -1544,19 +1544,24 @@ export default (superClass: Class<Parser>): Class<Parser> =>
// Overrides // Overrides
// ================================== // ==================================
parseFunctionBody(node: N.Function, allowExpressionBody: ?boolean): void { parseFunctionBody(
node: N.Function,
allowExpressionBody: ?boolean,
isMethod?: boolean = false,
): void {
if (allowExpressionBody) { if (allowExpressionBody) {
return this.forwardNoArrowParamsConversionAt(node, () => return this.forwardNoArrowParamsConversionAt(node, () =>
super.parseFunctionBody(node, true), super.parseFunctionBody(node, true, isMethod),
); );
} }
return super.parseFunctionBody(node, false); return super.parseFunctionBody(node, false, isMethod);
} }
parseFunctionBodyAndFinish( parseFunctionBodyAndFinish(
node: N.BodilessFunctionOrMethodBase, node: N.BodilessFunctionOrMethodBase,
type: string, type: string,
isMethod?: boolean = false,
): void { ): void {
if (this.match(tt.colon)) { if (this.match(tt.colon)) {
const typeNode = this.startNode(); const typeNode = this.startNode();
@ -1573,7 +1578,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
: null; : null;
} }
super.parseFunctionBodyAndFinish(node, type); super.parseFunctionBodyAndFinish(node, type, isMethod);
} }
// interfaces // interfaces

View File

@ -1472,6 +1472,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
parseFunctionBodyAndFinish( parseFunctionBodyAndFinish(
node: N.BodilessFunctionOrMethodBase, node: N.BodilessFunctionOrMethodBase,
type: string, type: string,
isMethod?: boolean = false,
): void { ): void {
if (this.match(tt.colon)) { if (this.match(tt.colon)) {
node.returnType = this.tsParseTypeOrTypePredicateAnnotation(tt.colon); node.returnType = this.tsParseTypeOrTypePredicateAnnotation(tt.colon);
@ -1488,7 +1489,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return; return;
} }
super.parseFunctionBodyAndFinish(node, type); super.parseFunctionBodyAndFinish(node, type, isMethod);
} }
parseSubscript( parseSubscript(

View File

@ -0,0 +1,3 @@
class Foo {
bar(a, a) {}
}

View File

@ -0,0 +1,3 @@
{
"throws": "Argument name clash (2:11)"
}

View File

@ -0,0 +1,3 @@
({
bar(a, a) {}
})

View File

@ -0,0 +1,3 @@
{
"throws": "Argument name clash (2:11)"
}

View File

@ -406,10 +406,8 @@ language/expressions/class/elements/syntax/early-errors/invalid-names/method-out
language/expressions/class/elements/syntax/early-errors/invalid-names/method-outter-member-expression-this.js(strict mode) language/expressions/class/elements/syntax/early-errors/invalid-names/method-outter-member-expression-this.js(strict mode)
language/expressions/class/elements/syntax/early-errors/super-private-access-invalid.js(default) language/expressions/class/elements/syntax/early-errors/super-private-access-invalid.js(default)
language/expressions/class/elements/syntax/early-errors/super-private-access-invalid.js(strict mode) language/expressions/class/elements/syntax/early-errors/super-private-access-invalid.js(strict mode)
language/expressions/object/method-definition/early-errors-object-async-method-duplicate-parameters.js(default)
language/expressions/object/method-definition/early-errors-object-method-async-lineterminator.js(default) language/expressions/object/method-definition/early-errors-object-method-async-lineterminator.js(default)
language/expressions/object/method-definition/early-errors-object-method-async-lineterminator.js(strict mode) language/expressions/object/method-definition/early-errors-object-method-async-lineterminator.js(strict mode)
language/expressions/object/method-definition/early-errors-object-method-duplicate-parameters.js(default)
language/expressions/object/method-definition/private-name-early-error-async-fn-inside-class.js(default) language/expressions/object/method-definition/private-name-early-error-async-fn-inside-class.js(default)
language/expressions/object/method-definition/private-name-early-error-async-fn-inside-class.js(strict mode) language/expressions/object/method-definition/private-name-early-error-async-fn-inside-class.js(strict mode)
language/expressions/object/method-definition/private-name-early-error-async-gen-inside-class.js(default) language/expressions/object/method-definition/private-name-early-error-async-gen-inside-class.js(default)