From 888c7a52dde24944f93e81b43d0b23948c7c4fb4 Mon Sep 17 00:00:00 2001 From: Christopher Chedeau Date: Wed, 25 Jan 2017 13:30:09 -0800 Subject: [PATCH] Put decorators on the same line (#459) Mobx is the only popular JavaScript library that I know about which uses decorators. They put things on the same line so we should follow their conventions. The logic implemented here is the following: if there is one decorator, it's on the same line. If there is more than one, they are each on their own line. Fixes #325 --- src/printer.js | 5 +- .../__snapshots__/jsfmt.spec.js.snap | 64 +++++++++++++++++++ tests/decorators/jsfmt.spec.js | 1 + tests/decorators/mobx.js | 14 ++++ tests/decorators/multiple.js | 6 ++ tests/decorators/redux.js | 5 ++ 6 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 tests/decorators/__snapshots__/jsfmt.spec.js.snap create mode 100644 tests/decorators/jsfmt.spec.js create mode 100644 tests/decorators/mobx.js create mode 100644 tests/decorators/multiple.js create mode 100644 tests/decorators/redux.js diff --git a/src/printer.js b/src/printer.js index 93aae542d..b2ce78ee1 100644 --- a/src/printer.js +++ b/src/printer.js @@ -51,9 +51,12 @@ function genericPrint(path, options, printPath) { // responsible for printing node.decorators. !util.getParentExportDeclaration(path) ) { + const separator = node.decorators.length === 1 && + node.decorators[0].expression.type === "Identifier" + ? " " : hardline; path.each( function(decoratorPath) { - parts.push(printPath(decoratorPath), line); + parts.push(printPath(decoratorPath), separator); }, "decorators" ); diff --git a/tests/decorators/__snapshots__/jsfmt.spec.js.snap b/tests/decorators/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..7f0de6828 --- /dev/null +++ b/tests/decorators/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,64 @@ +exports[`test mobx.js 1`] = ` +"import {observable} from \"mobx\"; + +@observer class OrderLine { + @observable price:number = 0; + @observable amount:number = 1; + + constructor(price) { + this.price = price; + } + + @computed get total() { + return this.price * this.amount; + } +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +import { observable } from \"mobx\"; + +@observer class OrderLine { + @observable price: number = 0; + @observable amount: number = 1; + + constructor(price) { + this.price = price; + } + + @computed get total() { + return this.price * this.amount; + } +} +" +`; + +exports[`test multiple.js 1`] = ` +"const dog = { + @readonly + @nonenumerable + @doubledValue + legs: 4 +}; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +const dog = { + @readonly + @nonenumerable + @doubledValue + legs: 4 +}; +" +`; + +exports[`test redux.js 1`] = ` +"@connect(mapStateToProps, mapDispatchToProps) +export class MyApp extends React.Component {} + +@connect(state => ({ todos: state.todos })) +export class Home extends React.Component {} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +@connect(mapStateToProps, mapDispatchToProps) +export class MyApp extends React.Component {} + +@connect(state => ({ todos: state.todos })) +export class Home extends React.Component {} +" +`; diff --git a/tests/decorators/jsfmt.spec.js b/tests/decorators/jsfmt.spec.js new file mode 100644 index 000000000..939578260 --- /dev/null +++ b/tests/decorators/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, {parser: 'babylon'}); diff --git a/tests/decorators/mobx.js b/tests/decorators/mobx.js new file mode 100644 index 000000000..adb461b0e --- /dev/null +++ b/tests/decorators/mobx.js @@ -0,0 +1,14 @@ +import {observable} from "mobx"; + +@observer class OrderLine { + @observable price:number = 0; + @observable amount:number = 1; + + constructor(price) { + this.price = price; + } + + @computed get total() { + return this.price * this.amount; + } +} diff --git a/tests/decorators/multiple.js b/tests/decorators/multiple.js new file mode 100644 index 000000000..3a41e7b8d --- /dev/null +++ b/tests/decorators/multiple.js @@ -0,0 +1,6 @@ +const dog = { + @readonly + @nonenumerable + @doubledValue + legs: 4 +}; diff --git a/tests/decorators/redux.js b/tests/decorators/redux.js new file mode 100644 index 000000000..481658f81 --- /dev/null +++ b/tests/decorators/redux.js @@ -0,0 +1,5 @@ +@connect(mapStateToProps, mapDispatchToProps) +export class MyApp extends React.Component {} + +@connect(state => ({ todos: state.todos })) +export class Home extends React.Component {}