diff --git a/src/common/util.js b/src/common/util.js index fece29049946..e4817c87059e 100644 --- a/src/common/util.js +++ b/src/common/util.js @@ -786,6 +786,27 @@ function addTrailingComment(node, comment) { addCommentHelper(node, comment); } +function isWithinParentArrayProperty(path, propertyName) { + const node = path.getValue(); + const parent = path.getParentNode(); + + if (parent == null) { + return false; + } + + if ( + !( + parent[propertyName] && + Object.prototype.toString.call(parent[propertyName]) === "[object Array]" + ) + ) { + return false; + } + + const key = path.getName(); + return parent[propertyName][key] === node; +} + module.exports = { punctuationRegex, punctuationCharRange, @@ -823,5 +844,6 @@ module.exports = { matchAncestorTypes, addLeadingComment, addDanglingComment, - addTrailingComment + addTrailingComment, + isWithinParentArrayProperty }; diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index bed172c6ad1b..672851499d64 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -20,7 +20,8 @@ const { getPenultimate, startsWithNoLookaheadToken, getIndentSize, - matchAncestorTypes + matchAncestorTypes, + isWithinParentArrayProperty } = require("../common/util"); const { isNextLineEmpty, @@ -94,7 +95,12 @@ function genericPrint(path, options, printPath, args) { // responsible for printing node.decorators. !getParentExportDeclaration(path) ) { - let separator = hardline; + const separator = + node.decorators.length === 1 && + isWithinParentArrayProperty(path, "params") + ? line + : hardline; + path.each(decoratorPath => { let decorator = decoratorPath.getValue(); if (decorator.expression) { @@ -103,27 +109,6 @@ function genericPrint(path, options, printPath, args) { decorator = decorator.callee; } - if ( - node.decorators.length === 1 && - node.type !== "ClassDeclaration" && - node.type !== "MethodDefinition" && - node.type !== "ClassMethod" && - (decorator.type === "Identifier" || - decorator.type === "MemberExpression" || - decorator.type === "OptionalMemberExpression" || - ((decorator.type === "CallExpression" || - decorator.type === "OptionalCallExpression") && - (decorator.arguments.length === 0 || - (decorator.arguments.length === 1 && - (isStringLiteral(decorator.arguments[0]) || - decorator.arguments[0].type === "Identifier" || - decorator.arguments[0].type === "MemberExpression" || - decorator.arguments[0].type === - "OptionalMemberExpression"))))) - ) { - separator = line; - } - decorators.push(printPath(decoratorPath), separator); }, "decorators"); } else if ( diff --git a/tests/decorators-ts/__snapshots__/jsfmt.spec.js.snap b/tests/decorators-ts/__snapshots__/jsfmt.spec.js.snap index 8dc3d3243305..6db27015db0f 100644 --- a/tests/decorators-ts/__snapshots__/jsfmt.spec.js.snap +++ b/tests/decorators-ts/__snapshots__/jsfmt.spec.js.snap @@ -161,7 +161,8 @@ class Greeter { } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class Greeter { - @format("Hello, %s") greeting: string; + @format("Hello, %s") + greeting: string; constructor(message: string) { this.greeting = message; @@ -200,15 +201,20 @@ export class Board { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @Entity() export class Board { - @PrimaryGeneratedColumn() id: number; + @PrimaryGeneratedColumn() + id: number; - @Column() slug: string; + @Column() + slug: string; - @Column() name: string; + @Column() + name: string; - @Column() theme: string; + @Column() + theme: string; - @Column() description: string; + @Column() + description: string; @OneToMany(type => Topic, topic => topic.board) topics: Topic[]; diff --git a/tests/decorators/__snapshots__/jsfmt.spec.js.snap b/tests/decorators/__snapshots__/jsfmt.spec.js.snap index c3ee92f2dd0d..24fa574b0d2b 100644 --- a/tests/decorators/__snapshots__/jsfmt.spec.js.snap +++ b/tests/decorators/__snapshots__/jsfmt.spec.js.snap @@ -108,8 +108,10 @@ import { observable } from "mobx"; @observer class OrderLine { - @observable price: number = 0; - @observable amount: number = 1; + @observable + price: number = 0; + @observable + amount: number = 1; constructor(price) { this.price = price; diff --git a/tests/typescript/conformance/types/decorator/__snapshots__/jsfmt.spec.js.snap b/tests/typescript/conformance/types/decorator/__snapshots__/jsfmt.spec.js.snap index 71b1bc3e6e4b..d16da936bd6e 100644 --- a/tests/typescript/conformance/types/decorator/__snapshots__/jsfmt.spec.js.snap +++ b/tests/typescript/conformance/types/decorator/__snapshots__/jsfmt.spec.js.snap @@ -8,6 +8,7 @@ enum E {} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ declare function dec(target: T): T; -@dec enum E {} +@dec +enum E {} `; diff --git a/tests/typescript_decorators/__snapshots__/jsfmt.spec.js.snap b/tests/typescript_decorators/__snapshots__/jsfmt.spec.js.snap index db62fff8f83a..ed10bea50a70 100644 --- a/tests/typescript_decorators/__snapshots__/jsfmt.spec.js.snap +++ b/tests/typescript_decorators/__snapshots__/jsfmt.spec.js.snap @@ -49,7 +49,8 @@ export class TabCompletionController {} selector: "angular-component" }) class AngularComponent { - @Input() myInput: string; + @Input() + myInput: string; } `; @@ -217,10 +218,14 @@ class Class2 { } class Class3 { - @d1 fieldA; - @d2(foo) fieldB; - @d3.bar fieldC; - @d4.baz() fieldD; + @d1 + fieldA; + @d2(foo) + fieldB; + @d3.bar + fieldC; + @d4.baz() + fieldD; constructor( @d1 private x: number,