diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index df72050b7f..63c5cbe0bb 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -1740,7 +1740,7 @@ export default class ExpressionParser extends LValParser { ); this.parseFunctionParams((node: any), allowModifiers); this.checkYieldAwaitInDefaultParams(); - this.parseFunctionBodyAndFinish(node, type); + this.parseFunctionBodyAndFinish(node, type, true); this.state.yieldPos = oldYieldPos; this.state.awaitPos = oldAwaitPos; @@ -1804,14 +1804,19 @@ export default class ExpressionParser extends LValParser { parseFunctionBodyAndFinish( node: N.BodilessFunctionOrMethodBase, type: string, + isMethod?: boolean = false, ): void { // $FlowIgnore (node is not bodiless if we get here) - this.parseFunctionBody(node); + this.parseFunctionBody(node, false, isMethod); this.finishNode(node, type); } // 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 oldStrict = this.state.strict; 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. this.checkParams( node, - !oldStrict && !useStrict && !allowExpression && !nonSimple, + !oldStrict && !useStrict && !allowExpression && !isMethod && !nonSimple, allowExpression, ); node.body = this.parseBlock(true, false); diff --git a/packages/babel-parser/src/plugins/estree.js b/packages/babel-parser/src/plugins/estree.js index 0a5a276a2b..07891f3086 100644 --- a/packages/babel-parser/src/plugins/estree.js +++ b/packages/babel-parser/src/plugins/estree.js @@ -259,8 +259,12 @@ export default (superClass: Class): Class => return node; } - parseFunctionBody(node: N.Function, allowExpression: ?boolean): void { - super.parseFunctionBody(node, allowExpression); + parseFunctionBody( + node: N.Function, + allowExpression: ?boolean, + isMethod?: boolean = false, + ): void { + super.parseFunctionBody(node, allowExpression, isMethod); node.expression = node.body.type !== "BlockStatement"; } diff --git a/packages/babel-parser/src/plugins/flow.js b/packages/babel-parser/src/plugins/flow.js index f76f043c4b..80961e0938 100644 --- a/packages/babel-parser/src/plugins/flow.js +++ b/packages/babel-parser/src/plugins/flow.js @@ -1544,19 +1544,24 @@ export default (superClass: Class): Class => // Overrides // ================================== - parseFunctionBody(node: N.Function, allowExpressionBody: ?boolean): void { + parseFunctionBody( + node: N.Function, + allowExpressionBody: ?boolean, + isMethod?: boolean = false, + ): void { if (allowExpressionBody) { 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( node: N.BodilessFunctionOrMethodBase, type: string, + isMethod?: boolean = false, ): void { if (this.match(tt.colon)) { const typeNode = this.startNode(); @@ -1573,7 +1578,7 @@ export default (superClass: Class): Class => : null; } - super.parseFunctionBodyAndFinish(node, type); + super.parseFunctionBodyAndFinish(node, type, isMethod); } // interfaces diff --git a/packages/babel-parser/src/plugins/typescript.js b/packages/babel-parser/src/plugins/typescript.js index 4973d1f6be..c511536613 100644 --- a/packages/babel-parser/src/plugins/typescript.js +++ b/packages/babel-parser/src/plugins/typescript.js @@ -1472,6 +1472,7 @@ export default (superClass: Class): Class => parseFunctionBodyAndFinish( node: N.BodilessFunctionOrMethodBase, type: string, + isMethod?: boolean = false, ): void { if (this.match(tt.colon)) { node.returnType = this.tsParseTypeOrTypePredicateAnnotation(tt.colon); @@ -1488,7 +1489,7 @@ export default (superClass: Class): Class => return; } - super.parseFunctionBodyAndFinish(node, type); + super.parseFunctionBodyAndFinish(node, type, isMethod); } parseSubscript( diff --git a/packages/babel-parser/test/fixtures/es2015/class-methods/disallow-duplicate-method-params/input.js b/packages/babel-parser/test/fixtures/es2015/class-methods/disallow-duplicate-method-params/input.js new file mode 100644 index 0000000000..101e2b77cc --- /dev/null +++ b/packages/babel-parser/test/fixtures/es2015/class-methods/disallow-duplicate-method-params/input.js @@ -0,0 +1,3 @@ +class Foo { + bar(a, a) {} +} diff --git a/packages/babel-parser/test/fixtures/es2015/class-methods/disallow-duplicate-method-params/options.json b/packages/babel-parser/test/fixtures/es2015/class-methods/disallow-duplicate-method-params/options.json new file mode 100644 index 0000000000..c7a2c3ba50 --- /dev/null +++ b/packages/babel-parser/test/fixtures/es2015/class-methods/disallow-duplicate-method-params/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Argument name clash (2:11)" +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/es2015/object/disallow-duplicate-method-params/input.js b/packages/babel-parser/test/fixtures/es2015/object/disallow-duplicate-method-params/input.js new file mode 100644 index 0000000000..b916cd4df9 --- /dev/null +++ b/packages/babel-parser/test/fixtures/es2015/object/disallow-duplicate-method-params/input.js @@ -0,0 +1,3 @@ +({ + bar(a, a) {} +}) diff --git a/packages/babel-parser/test/fixtures/es2015/object/disallow-duplicate-method-params/options.json b/packages/babel-parser/test/fixtures/es2015/object/disallow-duplicate-method-params/options.json new file mode 100644 index 0000000000..c7a2c3ba50 --- /dev/null +++ b/packages/babel-parser/test/fixtures/es2015/object/disallow-duplicate-method-params/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Argument name clash (2:11)" +} \ No newline at end of file diff --git a/scripts/tests/test262/test262_whitelist.txt b/scripts/tests/test262/test262_whitelist.txt index ea959b5802..2dc847d203 100644 --- a/scripts/tests/test262/test262_whitelist.txt +++ b/scripts/tests/test262/test262_whitelist.txt @@ -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/super-private-access-invalid.js(default) 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(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(strict mode) language/expressions/object/method-definition/private-name-early-error-async-gen-inside-class.js(default)