Skip to content

Commit 8d86f11

Browse files
committed
Rename wrap-multilines to jsx-wrap-multilines
This rule is JSX-specific, not React-specific. Changing its name makes this clearer. I've kept the old one around as deprecated. We can remove it at the next major version bump. Addresses jsx-eslint#686. Fixes jsx-eslint#668.
1 parent 42d81ae commit 8d86f11

File tree

6 files changed

+123
-76
lines changed

6 files changed

+123
-76
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ Finally, enable all of the rules that you would like to use. Use [our preset](#
101101
* [react/self-closing-comp](docs/rules/self-closing-comp.md): Prevent extra closing tags for components without children
102102
* [react/sort-comp](docs/rules/sort-comp.md): Enforce component methods order
103103
* [react/sort-prop-types](docs/rules/sort-prop-types.md): Enforce propTypes declarations alphabetical sorting
104-
* [react/wrap-multilines](docs/rules/wrap-multilines.md): Prevent missing parentheses around multilines JSX (fixable)
105104

106105
## JSX-specific rules
107106

@@ -128,6 +127,7 @@ Finally, enable all of the rules that you would like to use. Use [our preset](#
128127
* [react/jsx-space-before-closing](docs/rules/jsx-space-before-closing.md): Validate spacing before closing bracket in JSX (fixable)
129128
* [react/jsx-uses-react](docs/rules/jsx-uses-react.md): Prevent React to be incorrectly marked as unused
130129
* [react/jsx-uses-vars](docs/rules/jsx-uses-vars.md): Prevent variables used in JSX to be incorrectly marked as unused
130+
* [react/jsx-wrap-multilines](docs/rules/jsx-wrap-multilines.md): Prevent missing parentheses around multilines JSX (fixable)
131131

132132
## React Native rules
133133

docs/rules/wrap-multilines.md renamed to docs/rules/jsx-wrap-multilines.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Prevent missing parentheses around multiline JSX (wrap-multilines)
1+
# Prevent missing parentheses around multiline JSX (jsx-wrap-multilines)
22

33
Wrapping multiline JSX in parentheses can improve readability and/or convenience. It optionally takes a second parameter in the form of an object, containing places to apply the rule. By default, `"declaration"`, `"assignment"`, and `"return"` syntax is checked, but these can be explicitly disabled. Any syntax type missing in the object will follow the default behavior (become enabled).
44

index.js

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module.exports = {
77
'prop-types': require('./lib/rules/prop-types'),
88
'display-name': require('./lib/rules/display-name'),
99
'wrap-multilines': require('./lib/rules/wrap-multilines'),
10+
'jsx-wrap-multilines': require('./lib/rules/jsx-wrap-multilines'),
1011
'self-closing-comp': require('./lib/rules/self-closing-comp'),
1112
'no-comment-textnodes': require('./lib/rules/no-comment-textnodes'),
1213
'jsx-no-comment-textnodes': require('./lib/rules/jsx-no-comment-textnodes'),

lib/rules/jsx-wrap-multilines.js

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/**
2+
* @fileoverview Prevent missing parentheses around multilines JSX
3+
* @author Yannick Croissant
4+
*/
5+
'use strict';
6+
7+
// ------------------------------------------------------------------------------
8+
// Constants
9+
// ------------------------------------------------------------------------------
10+
11+
var DEFAULTS = {
12+
declaration: true,
13+
assignment: true,
14+
return: true
15+
};
16+
17+
// ------------------------------------------------------------------------------
18+
// Rule Definition
19+
// ------------------------------------------------------------------------------
20+
21+
module.exports = function(context) {
22+
23+
var sourceCode = context.getSourceCode();
24+
25+
function isParenthesised(node) {
26+
var previousToken = sourceCode.getTokenBefore(node);
27+
var nextToken = sourceCode.getTokenAfter(node);
28+
29+
return previousToken && nextToken &&
30+
previousToken.value === '(' && previousToken.range[1] <= node.range[0] &&
31+
nextToken.value === ')' && nextToken.range[0] >= node.range[1];
32+
}
33+
34+
function isMultilines(node) {
35+
return node.loc.start.line !== node.loc.end.line;
36+
}
37+
38+
function check(node) {
39+
if (!node || node.type !== 'JSXElement') {
40+
return;
41+
}
42+
43+
if (!isParenthesised(node) && isMultilines(node)) {
44+
context.report({
45+
node: node,
46+
message: 'Missing parentheses around multilines JSX',
47+
fix: function(fixer) {
48+
return fixer.replaceText(node, '(' + sourceCode.getText(node) + ')');
49+
}
50+
});
51+
}
52+
}
53+
54+
function isEnabled(type) {
55+
var userOptions = context.options[0] || {};
56+
if (({}).hasOwnProperty.call(userOptions, type)) {
57+
return userOptions[type];
58+
}
59+
return DEFAULTS[type];
60+
}
61+
62+
// --------------------------------------------------------------------------
63+
// Public
64+
// --------------------------------------------------------------------------
65+
66+
return {
67+
68+
VariableDeclarator: function(node) {
69+
if (isEnabled('declaration')) {
70+
check(node.init);
71+
}
72+
},
73+
74+
AssignmentExpression: function(node) {
75+
if (isEnabled('assignment')) {
76+
check(node.right);
77+
}
78+
},
79+
80+
ReturnStatement: function(node) {
81+
if (isEnabled('return')) {
82+
check(node.argument);
83+
}
84+
}
85+
};
86+
87+
};
88+
89+
module.exports.schema = [{
90+
type: 'object',
91+
properties: {
92+
declaration: {
93+
type: 'boolean'
94+
},
95+
assignment: {
96+
type: 'boolean'
97+
},
98+
return: {
99+
type: 'boolean'
100+
}
101+
},
102+
additionalProperties: false
103+
}];

lib/rules/wrap-multilines.js

+15-72
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,32 @@
11
/**
22
* @fileoverview Prevent missing parentheses around multilines JSX
33
* @author Yannick Croissant
4+
* @deprecated
45
*/
56
'use strict';
67

7-
// ------------------------------------------------------------------------------
8-
// Constants
9-
// ------------------------------------------------------------------------------
10-
11-
var DEFAULTS = {
12-
declaration: true,
13-
assignment: true,
14-
return: true
15-
};
16-
178
// ------------------------------------------------------------------------------
189
// Rule Definition
1910
// ------------------------------------------------------------------------------
2011

21-
module.exports = function(context) {
22-
23-
var sourceCode = context.getSourceCode();
12+
var util = require('util');
13+
var jsxWrapMultilines = require('./jsx-wrap-multilines');
14+
var isWarnedForDeprecation = false;
2415

25-
function isParenthesised(node) {
26-
var previousToken = sourceCode.getTokenBefore(node);
27-
var nextToken = sourceCode.getTokenAfter(node);
28-
29-
return previousToken && nextToken &&
30-
previousToken.value === '(' && previousToken.range[1] <= node.range[0] &&
31-
nextToken.value === ')' && nextToken.range[0] >= node.range[1];
32-
}
33-
34-
function isMultilines(node) {
35-
return node.loc.start.line !== node.loc.end.line;
36-
}
37-
38-
function check(node) {
39-
if (!node || node.type !== 'JSXElement') {
40-
return;
41-
}
42-
43-
if (!isParenthesised(node) && isMultilines(node)) {
44-
context.report({
45-
node: node,
46-
message: 'Missing parentheses around multilines JSX',
47-
fix: function(fixer) {
48-
return fixer.replaceText(node, '(' + sourceCode.getText(node) + ')');
49-
}
50-
});
51-
}
52-
}
53-
54-
function isEnabled(type) {
55-
var userOptions = context.options[0] || {};
56-
if (({}).hasOwnProperty.call(userOptions, type)) {
57-
return userOptions[type];
58-
}
59-
return DEFAULTS[type];
60-
}
61-
62-
// --------------------------------------------------------------------------
63-
// Public
64-
// --------------------------------------------------------------------------
65-
66-
return {
67-
68-
VariableDeclarator: function(node) {
69-
if (isEnabled('declaration')) {
70-
check(node.init);
71-
}
72-
},
73-
74-
AssignmentExpression: function(node) {
75-
if (isEnabled('assignment')) {
76-
check(node.right);
16+
module.exports = function(context) {
17+
return util._extend(jsxWrapMultilines(context), {
18+
Program: function() {
19+
if (isWarnedForDeprecation || /\=-(f|-format)=/.test(process.argv.join('='))) {
20+
return;
7721
}
78-
},
7922

80-
ReturnStatement: function(node) {
81-
if (isEnabled('return')) {
82-
check(node.argument);
83-
}
23+
/* eslint-disable no-console */
24+
console.log('The react/wrap-multilines rule is deprecated. Please ' +
25+
'use the react/jsx-wrap-multilines rule instead.');
26+
/* eslint-enable no-console */
27+
isWarnedForDeprecation = true;
8428
}
85-
};
86-
29+
});
8730
};
8831

8932
module.exports.schema = [{

tests/lib/rules/wrap-multilines.js renamed to tests/lib/rules/jsx-wrap-multilines.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// Requirements
99
// ------------------------------------------------------------------------------
1010

11-
var rule = require('../../../lib/rules/wrap-multilines');
11+
var rule = require('../../../lib/rules/jsx-wrap-multilines');
1212
var RuleTester = require('eslint').RuleTester;
1313

1414
var parserOptions = {
@@ -78,7 +78,7 @@ var ASSIGNMENT_NO_PAREN = '\
7878
// ------------------------------------------------------------------------------
7979

8080
var ruleTester = new RuleTester();
81-
ruleTester.run('wrap-multilines', rule, {
81+
ruleTester.run('jsx-wrap-multilines', rule, {
8282

8383
valid: [
8484
{

0 commit comments

Comments
 (0)