From 9c1e65252968d98097ccc9bc31bddef307499fe0 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Tue, 15 Dec 2020 20:19:04 -0800 Subject: [PATCH] [Fix] `jsx-wrap-multilines`: fix crash with `declaration`s that are on a new line after `=` Fixes #2875. --- CHANGELOG.md | 2 ++ lib/rules/jsx-wrap-multilines.js | 5 +++-- tests/lib/rules/jsx-wrap-multilines.js | 20 ++++++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0778fe32a..42bb7d9699 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel * [`jsx-key`]: added `checkKeyMustBeforeSpread` option for new jsx transform ([#2835][] @morlay) * [`jsx-newline`]: add new rule ([#2693][] @jzabala) * [`jsx-no-constructed-context-values`]: add new rule which checks when the value passed to a Context Provider will cause needless rerenders ([#2763][] @dylanOshima) +* [`jsx-wrap-multilines`]: fix crash with `declaration`s that are on a new line after `=` ([#2875][] @ljharb) ### Fixed * [`display-name`]/component detection: avoid a crash on anonymous components ([#2840][] @ljharb) @@ -18,6 +19,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel * [`no-typos`]: avoid crash with computed method name ([#2870][] @ljharb, @AriPerkkio) * [`jsx-max-depth`]: avoid crash with childless jsx child ([#2869][] @ljharb, @AriPerkkio) +[#2871]: https://github.com/yannickcr/eslint-plugin-react/issues/2875 [#2871]: https://github.com/yannickcr/eslint-plugin-react/issues/2871 [#2870]: https://github.com/yannickcr/eslint-plugin-react/issues/2870 [#2869]: https://github.com/yannickcr/eslint-plugin-react/issues/2869 diff --git a/lib/rules/jsx-wrap-multilines.js b/lib/rules/jsx-wrap-multilines.js index 4a8eb65f53..6fc16908cf 100644 --- a/lib/rules/jsx-wrap-multilines.js +++ b/lib/rules/jsx-wrap-multilines.js @@ -157,14 +157,15 @@ module.exports = { if (!isParenthesised(node)) { const tokenBefore = sourceCode.getTokenBefore(node, {includeComments: true}); const tokenAfter = sourceCode.getTokenAfter(node, {includeComments: true}); - if (tokenBefore.loc.end.line < node.loc.start.line) { + const start = node.loc.start; + if (tokenBefore.loc.end.line < start.line) { // Strip newline after operator if parens newline is specified report( node, MISSING_PARENS, (fixer) => fixer.replaceTextRange( [tokenBefore.range[0], tokenAfter && (tokenAfter.value === ';' || tokenAfter.value === '}') ? tokenAfter.range[0] : node.range[1]], - `${trimTokenBeforeNewline(node, tokenBefore)}(\n${' '.repeat(node.loc.start.column)}${sourceCode.getText(node)}\n${' '.repeat(node.loc.start.column - 2)})` + `${trimTokenBeforeNewline(node, tokenBefore)}(\n${start.column > 0 ? ' '.repeat(start.column) : ''}${sourceCode.getText(node)}\n${start.column > 0 ? ' '.repeat(start.column - 2) : ''})` ) ); } else { diff --git a/tests/lib/rules/jsx-wrap-multilines.js b/tests/lib/rules/jsx-wrap-multilines.js index ff43136f2b..b653b8f391 100644 --- a/tests/lib/rules/jsx-wrap-multilines.js +++ b/tests/lib/rules/jsx-wrap-multilines.js @@ -1250,5 +1250,25 @@ ruleTester.run('jsx-wrap-multilines', rule, { output: ARROW_WITH_LOGICAL_AUTOFIX, options: [{logical: 'parens-new-line'}], errors: [{message: MISSING_PARENS}] + }, { + code: [ + 'import React from \'react\';', + '', + 'const A =', + '
', + ' B', + '
;' + ].join('\n'), + output: [ + 'import React from \'react\';', + '', + 'const A = (', + '
', + ' B', + '
', + ');' + ].join('\n'), + options: [{declaration: 'parens-new-line'}], + errors: [{message: MISSING_PARENS}] }] });