diff --git a/lib/rules/decorator-position.js b/lib/rules/decorator-position.js index 223f9581..c82f5044 100644 --- a/lib/rules/decorator-position.js +++ b/lib/rules/decorator-position.js @@ -94,6 +94,7 @@ module.exports = { // // NOTE: implementing this will need a breaking change // { +// printWidth: 50, // properties: 'prefer-inline', // methods: 'above', // overrides: { @@ -204,8 +205,6 @@ function placeDecoratorsBesideProperty(context, node, options) { continue; } const config = normalizeConfig(decoratorConfig, INTENT.SAME_LINE); - const info = decoratorInfo(node, config); - const decorator = node.decorators[0]; const token = context.getSourceCode().getTokenAfter(decorator, { includeComments: true }); @@ -217,6 +216,16 @@ function placeDecoratorsBesideProperty(context, node, options) { const totalLineLength = calculateTotalLineLength(context, node, token) + whitespaceLength; const lessThanOrEqualToPrintWidth = totalLineLength <= Number(options.printWidth); + if (!lessThanOrEqualToPrintWidth) { + const forwardOptions = { + ...options, + }; + forwardOptions.overrides[ABOVE] = options.overrides[PREFER_INLINE]; + placeDecoratorsAboveProperty(context, node, forwardOptions); + } + + const info = decoratorInfo(node, config); + if (!info.needsTransform) { continue; } @@ -249,40 +258,29 @@ function placeDecoratorsAboveProperty(context, node, options) { const info = decoratorInfo(node, config); const decorator = node.decorators[0]; - const token = context.getSourceCode().getTokenAfter(decorator, { includeComments: true }); - const whitespaceStart = decorator.range[1]; - const whitespaceEnd = token.range[0] - 1; - - const whitespaceLength = whitespaceEnd - whitespaceStart; - // eslint-disable-next-line no-unused-vars - const totalLineLength = calculateTotalLineLength(context, node, token) + whitespaceLength; - const greaterThanOrEqualToPrintWidth = true; - - if (greaterThanOrEqualToPrintWidth) { - if (!info.needsTransform) { - continue; - } + if (!info.needsTransform) { + continue; + } - context.report({ - node, - message: `Expected @${info.name} to be on the line above.`, + context.report({ + node, + message: `Expected @${info.name} to be on the line above.`, - fix(fixer) { - const indentation = decorator.loc.start.column - 1; - const padding = indentation > 0 ? ' '.repeat(indentation) : ''; - const token = context.getSourceCode().getTokenAfter(decorator, { includeComments: true }); + fix(fixer) { + const indentation = decorator.loc.start.column - 1; + const padding = indentation > 0 ? ' '.repeat(indentation) : ''; + const token = context.getSourceCode().getTokenAfter(decorator, { includeComments: true }); - const whitespaceStart = decorator.range[1]; - const whitespaceEnd = token.range[0] - 1; + const whitespaceStart = decorator.range[1]; + const whitespaceEnd = token.range[0] - 1; - // delete the space(s) between the decorator and the - // decorated thing with a newline, matching the - // indentation of the decorator - return fixer.replaceTextRange([whitespaceStart, whitespaceEnd], `\n${padding}`); - }, - }); - } + // delete the space(s) between the decorator and the + // decorated thing with a newline, matching the + // indentation of the decorator + return fixer.replaceTextRange([whitespaceStart, whitespaceEnd], `\n${padding}`); + }, + }); } } @@ -338,9 +336,8 @@ function lineLength(userOptions, filePath) { const prettierOptions = Object.assign({}, prettierRcOptions, eslintPrettierOptions, { filePath, }); - const r = Object.assign({}, prettierOptions, userOptions); - // console.log(r); - return r; + + return Object.assign({}, prettierOptions, userOptions); } function normalizeConfig(config, intent) { diff --git a/package.json b/package.json index 0f04016b..1780aa6c 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,8 @@ "lint:js": "eslint . --cache", "start": "yarn run test:watch", "test": "jest", - "test:debug": "node --inspect node_modules/.bin/jest --watch --runInBand", - "test:debug-watch": "node --inspect node_modules/.bin/jest --runInBand", + "test:debug": "node --inspect node_modules/.bin/jest --runInBand", + "test:debug-watch": "node --inspect node_modules/.bin/jest --watch --runInBand", "test:coverage": "jest --coverage", "test:watch": "jest --watchAll", "update": "node ./scripts/update-rules.js", diff --git a/tests/lib/rules/decorator-position.js b/tests/lib/rules/decorator-position.js index dd914e56..acbd6b2d 100644 --- a/tests/lib/rules/decorator-position.js +++ b/tests/lib/rules/decorator-position.js @@ -115,6 +115,28 @@ ruleTester.run('JS: decorator-position', rule, { `, options: [{ overrides: { 'prefer-inline': ['@foo'] } }], }, + { + code: stripIndent` + class Foo { + @foo('bizbangbarbazboo') fizz; + + @action('bidgbarbazboo') fizz; + } + `, + options: [{ printWidth: 30 }], + }, + { + code: stripIndent` + class Foo { + @foo('bizbangbarbazboo') + fizz; + + @action('bidgbarbazboo') + fizz; + } + `, + options: [{ printWidth: 10 }], + }, { code: stripIndent` class Foo { @@ -133,6 +155,21 @@ ruleTester.run('JS: decorator-position', rule, { }, ], invalid: [ + { + code: stripIndent` + class Foo { + @alias('foo.bar.baz.someReallyLongPropertyNameThatIsTooLongToBeInlineOrItBreaksPrettier') foo; + } + `, + options: [{ printWidth: 50 }], + errors: [{ message: 'Expected @alias to be on the line above.' }], + output: stripIndent` + class Foo { + @alias('foo.bar.baz.someReallyLongPropertyNameThatIsTooLongToBeInlineOrItBreaksPrettier') + foo; + } + `, + }, { code: stripIndent` class Foo {