Skip to content

Commit 28f9a6c

Browse files
committed
[Fix] jsx-newline: prevent a crash when allowMultilines
Fixes #3633
1 parent ecadb92 commit 28f9a6c

File tree

3 files changed

+74
-2
lines changed

3 files changed

+74
-2
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
1111
### Fixed
1212
* [`jsx-no-leaked-render`]: preserve RHS parens for multiline jsx elements while fixing ([#3623][] @akulsr0)
1313
* [`jsx-key`]: detect conditional returns ([#3630][] @yialo)
14+
* [`jsx-newline`]: prevent a crash when `allowMultilines ([#3633][] @ljharb)
1415

16+
[#3633]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3633
1517
[#3630]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3630
1618
[#3623]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3623
1719
[#3615]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3615

lib/rules/jsx-newline.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const messages = {
2020
};
2121

2222
function isMultilined(node) {
23-
return node.loc.start.line !== node.loc.end.line;
23+
return node && node.loc.start.line !== node.loc.end.line;
2424
}
2525

2626
module.exports = {
@@ -103,7 +103,6 @@ module.exports = {
103103
const isWithoutNewLine = !/\n\s*\n/.test(firstAdjacentSibling.value);
104104

105105
if (isBlockCommentInCurlyBraces(element)) return;
106-
107106
if (
108107
allowMultilines
109108
&& (

tests/lib/rules/jsx-newline.js

+71
Original file line numberDiff line numberDiff line change
@@ -649,5 +649,76 @@ new RuleTester({ parserOptions }).run('jsx-newline', rule, {
649649
],
650650
options: [{ prevent: true, allowMultilines: true }],
651651
},
652+
{
653+
code: `
654+
const frag: DocumentFragment = (
655+
<Fragment>
656+
<sni-sequence-editor-tool
657+
name="forward"
658+
direction="forward"
659+
type="control"
660+
onClick={ () => this.onClickNavigate('forward') }
661+
/>
662+
<sni-sequence-editor-tool
663+
name="rotate"
664+
direction="left"
665+
type="control"
666+
onClick={ () => this.onClickNavigate('left') }
667+
/>
668+
669+
<sni-sequence-editor-tool
670+
name="rotate"
671+
direction="right"
672+
type="control"
673+
onClick={ (): void => this.onClickNavigate('right') }
674+
/>
675+
676+
<div className="sni-sequence-editor-control-panel__delete" data-name="delete" onClick={ this.onDeleteCommand } />
677+
678+
{
679+
...Array.from(this.children)
680+
}
681+
</Fragment>
682+
)
683+
`,
684+
output: `
685+
const frag: DocumentFragment = (
686+
<Fragment>
687+
<sni-sequence-editor-tool
688+
name="forward"
689+
direction="forward"
690+
type="control"
691+
onClick={ () => this.onClickNavigate('forward') }
692+
/>
693+
694+
<sni-sequence-editor-tool
695+
name="rotate"
696+
direction="left"
697+
type="control"
698+
onClick={ () => this.onClickNavigate('left') }
699+
/>
700+
${' '}
701+
<sni-sequence-editor-tool
702+
name="rotate"
703+
direction="right"
704+
type="control"
705+
onClick={ (): void => this.onClickNavigate('right') }
706+
/>
707+
708+
<div className="sni-sequence-editor-control-panel__delete" data-name="delete" onClick={ this.onDeleteCommand } />
709+
710+
{
711+
...Array.from(this.children)
712+
}
713+
</Fragment>
714+
)
715+
`,
716+
features: ['types'],
717+
options: [{ prevent: true, allowMultilines: true }],
718+
errors: [
719+
{ messageId: 'allowMultilines', line: 10 },
720+
{ messageId: 'prevent', line: 26 },
721+
],
722+
},
652723
]),
653724
});

0 commit comments

Comments
 (0)