diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js index 6155f0a7999d..066d6e155f8a 100644 --- a/src/language-js/needs-parens.js +++ b/src/language-js/needs-parens.js @@ -783,6 +783,15 @@ function needsParens(path, options) { case "MemberExpression": case "TaggedTemplateExpression": case "TSNonNullExpression": + if ( + name === "expression" && + parent.type === "Decorator" && + isMemberExpression(node) && + node.computed + ) { + return true; + } + if ( name === "callee" && (parent.type === "BindExpression" || parent.type === "NewExpression") diff --git a/tests/format/js/decorators/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/decorators/__snapshots__/jsfmt.spec.js.snap index 913adbb6d37d..26972c70eaf3 100644 --- a/tests/format/js/decorators/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/js/decorators/__snapshots__/jsfmt.spec.js.snap @@ -162,6 +162,146 @@ export class Bar {} ================================================================================ `; +exports[`member-expression.js [acorn] format 1`] = ` +"Unexpected character '@' (3:5) + 1 | [ + 2 | class { +> 3 | @(decorators[0]) + | ^ + 4 | method() {} + 5 | }, + 6 |" +`; + +exports[`member-expression.js [espree] format 1`] = ` +"Unexpected character '@' (3:5) + 1 | [ + 2 | class { +> 3 | @(decorators[0]) + | ^ + 4 | method() {} + 5 | }, + 6 |" +`; + +exports[`member-expression.js format 1`] = ` +====================================options===================================== +parsers: ["babel"] +printWidth: 80 + | printWidth +=====================================input====================================== +[ + class { + @(decorators[0]) + method() {} + }, + + class { + @(decorators?.[0]) + method() {} + }, + + class { + @(decorators.at(0)) + method() {} + }, + + class { + @(decorators?.at(0)) + method() {} + }, + + class { + @(decorators.first) + method() {} + }, + + class { + @(decorators?.first) + method() {} + }, + + class { + @(decorators[first]) + method() {} + }, + + class { + @(decorators["first"]) + method() {} + }, + + @(decorators[first]) + class { + method() {} + }, + + @(decorators[0]) + class { + method() {} + }, +] + +=====================================output===================================== +[ + class { + @decorators[0] + method() {} + }, + + class { + @(decorators?.[0]) + method() {} + }, + + class { + @decorators.at(0) + method() {} + }, + + class { + @(decorators?.at(0)) + method() {} + }, + + class { + @decorators.first + method() {} + }, + + class { + @(decorators?.first) + method() {} + }, + + class { + @decorators[first] + method() {} + }, + + class { + @decorators["first"] + method() {} + }, + + ( + @decorators[first] + class { + method() {} + } + ), + + ( + @decorators[0] + class { + method() {} + } + ), +]; + +================================================================================ +`; + exports[`methods.js [acorn] format 1`] = ` "Unexpected character '@' (3:3) 1 | diff --git a/tests/format/js/decorators/member-expression.js b/tests/format/js/decorators/member-expression.js new file mode 100644 index 000000000000..9f17787a349d --- /dev/null +++ b/tests/format/js/decorators/member-expression.js @@ -0,0 +1,51 @@ +[ + class { + @(decorators[0]) + method() {} + }, + + class { + @(decorators?.[0]) + method() {} + }, + + class { + @(decorators.at(0)) + method() {} + }, + + class { + @(decorators?.at(0)) + method() {} + }, + + class { + @(decorators.first) + method() {} + }, + + class { + @(decorators?.first) + method() {} + }, + + class { + @(decorators[first]) + method() {} + }, + + class { + @(decorators["first"]) + method() {} + }, + + @(decorators[first]) + class { + method() {} + }, + + @(decorators[0]) + class { + method() {} + }, +]