Skip to content

Commit d537c06

Browse files
committed
jsx-max-depth: support shorthand fragments
1 parent ac7f3f5 commit d537c06

File tree

2 files changed

+74
-20
lines changed

2 files changed

+74
-20
lines changed

lib/rules/jsx-max-depth.js

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
const has = require('has');
88
const variableUtil = require('../util/variable');
9+
const jsxUtil = require('../util/jsx');
910
const docsUrl = require('../util/docsUrl');
1011

1112
// ------------------------------------------------------------------------------
@@ -39,16 +40,12 @@ module.exports = {
3940
const option = context.options[0] || {};
4041
const maxDepth = has(option, 'max') ? option.max : DEFAULT_DEPTH;
4142

42-
function isJSXElement(node) {
43-
return node.type === 'JSXElement';
44-
}
45-
4643
function isExpression(node) {
4744
return node.type === 'JSXExpressionContainer';
4845
}
4946

5047
function hasJSX(node) {
51-
return isJSXElement(node) || isExpression(node) && isJSXElement(node.expression);
48+
return jsxUtil.isJSX(node) || isExpression(node) && jsxUtil.isJSX(node.expression);
5249
}
5350

5451
function isLeaf(node) {
@@ -60,9 +57,9 @@ module.exports = {
6057
function getDepth(node) {
6158
let count = 0;
6259

63-
while (isJSXElement(node.parent) || isExpression(node.parent)) {
60+
while (jsxUtil.isJSX(node.parent) || isExpression(node.parent)) {
6461
node = node.parent;
65-
if (isJSXElement(node)) {
62+
if (jsxUtil.isJSX(node)) {
6663
count++;
6764
}
6865
}
@@ -82,18 +79,18 @@ module.exports = {
8279
});
8380
}
8481

85-
function findJSXElement(variables, name) {
82+
function findJSXElementOrFragment(variables, name) {
8683
function find(refs) {
8784
let i = refs.length;
8885

8986
while (--i >= 0) {
9087
if (has(refs[i], 'writeExpr')) {
9188
const writeExpr = refs[i].writeExpr;
9289

93-
return isJSXElement(writeExpr)
90+
return jsxUtil.isJSX(writeExpr)
9491
&& writeExpr
9592
|| writeExpr.type === 'Identifier'
96-
&& findJSXElement(variables, writeExpr.name);
93+
&& findJSXElementOrFragment(variables, writeExpr.name);
9794
}
9895
}
9996

@@ -119,24 +116,28 @@ module.exports = {
119116
});
120117
}
121118

119+
function handleJSX(node) {
120+
if (!isLeaf(node)) {
121+
return;
122+
}
123+
124+
const depth = getDepth(node);
125+
if (depth > maxDepth) {
126+
report(node, depth);
127+
}
128+
}
129+
122130
return {
123-
JSXElement: function(node) {
124-
if (!isLeaf(node)) {
125-
return;
126-
}
131+
JSXElement: handleJSX,
132+
JSXFragment: handleJSX,
127133

128-
const depth = getDepth(node);
129-
if (depth > maxDepth) {
130-
report(node, depth);
131-
}
132-
},
133134
JSXExpressionContainer: function(node) {
134135
if (node.expression.type !== 'Identifier') {
135136
return;
136137
}
137138

138139
const variables = variableUtil.variablesInScope(context);
139-
const element = findJSXElement(variables, node.expression.name);
140+
const element = findJSXElementOrFragment(variables, node.expression.name);
140141

141142
if (element) {
142143
const baseDepth = getDepth(node);

tests/lib/rules/jsx-max-depth.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,26 @@ ruleTester.run('jsx-max-depth', rule, {
6161
}, {
6262
code: 'const foo = (x) => <div><em>{x}</em></div>;',
6363
options: [{max: 2}]
64+
}, {
65+
code: [
66+
'<></>'
67+
].join('\n'),
68+
parser: 'babel-eslint'
69+
}, {
70+
code: [
71+
'<>',
72+
' <foo />',
73+
'</>'
74+
].join('\n'),
75+
parser: 'babel-eslint',
76+
options: [{max: 1}]
77+
}, {
78+
code: [
79+
'const x = <><em>x</em></>;',
80+
'<>{x}</>'
81+
].join('\n'),
82+
parser: 'babel-eslint',
83+
options: [{max: 2}]
6484
}],
6585

6686
invalid: [{
@@ -121,6 +141,39 @@ ruleTester.run('jsx-max-depth', rule, {
121141
'{<div><div><span /></div></div>}',
122142
'</div>'
123143
].join('\n'),
144+
parser: 'babel-eslint',
124145
errors: [{message: 'Expected the depth of nested jsx elements to be <= 2, but found 3.'}]
146+
}, {
147+
code: [
148+
'<>',
149+
' <foo />',
150+
'</>'
151+
].join('\n'),
152+
parser: 'babel-eslint',
153+
options: [{max: 0}],
154+
errors: [{message: 'Expected the depth of nested jsx elements to be <= 0, but found 1.'}]
155+
}, {
156+
code: [
157+
'<>',
158+
' <>',
159+
' <bar />',
160+
' </>',
161+
'</>'
162+
].join('\n'),
163+
parser: 'babel-eslint',
164+
options: [{max: 1}],
165+
errors: [{message: 'Expected the depth of nested jsx elements to be <= 1, but found 2.'}]
166+
}, {
167+
code: [
168+
'const x = <><span /></>;',
169+
'let y = x;',
170+
'<>{x}-{y}</>'
171+
].join('\n'),
172+
parser: 'babel-eslint',
173+
options: [{max: 1}],
174+
errors: [
175+
{message: 'Expected the depth of nested jsx elements to be <= 1, but found 2.'},
176+
{message: 'Expected the depth of nested jsx elements to be <= 1, but found 2.'}
177+
]
125178
}]
126179
});

0 commit comments

Comments
 (0)