eslint 2.11.0 → 2.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +77 -0
- package/README.md +24 -0
- package/conf/eslint-all.js +29 -0
- package/conf/eslint.json +10 -6
- package/lib/ast-utils.js +91 -0
- package/lib/config/config-file.js +9 -4
- package/lib/config/config-ops.js +27 -2
- package/lib/eslint.js +34 -15
- package/lib/file-finder.js +3 -59
- package/lib/ignored-paths.js +38 -4
- package/lib/options.js +1 -1
- package/lib/rules/accessor-pairs.js +1 -1
- package/lib/rules/array-bracket-spacing.js +1 -1
- package/lib/rules/arrow-body-style.js +57 -15
- package/lib/rules/callback-return.js +25 -3
- package/lib/rules/default-case.js +1 -1
- package/lib/rules/eqeqeq.js +1 -1
- package/lib/rules/func-names.js +15 -4
- package/lib/rules/max-len.js +3 -2
- package/lib/rules/max-lines.js +148 -0
- package/lib/rules/max-statements-per-line.js +1 -1
- package/lib/rules/newline-per-chained-call.js +16 -1
- package/lib/rules/no-extra-parens.js +1 -92
- package/lib/rules/no-extra-semi.js +10 -1
- package/lib/rules/no-mixed-operators.js +212 -0
- package/lib/rules/no-multiple-empty-lines.js +40 -9
- package/lib/rules/no-prototype-builtins.js +1 -1
- package/lib/rules/no-script-url.js +1 -1
- package/lib/rules/no-unsafe-finally.js +1 -1
- package/lib/rules/no-useless-rename.js +11 -3
- package/lib/rules/object-curly-newline.js +209 -0
- package/lib/rules/object-shorthand.js +75 -5
- package/lib/rules/one-var.js +3 -0
- package/lib/rules/padded-blocks.js +19 -1
- package/lib/rules/rest-spread-spacing.js +107 -0
- package/lib/rules/unicode-bom.js +1 -1
- package/lib/util/glob-util.js +2 -1
- package/package.json +4 -2
@@ -0,0 +1,212 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Rule to disallow mixed binary operators.
|
3
|
+
* @author Toru Nagashima
|
4
|
+
*/
|
5
|
+
|
6
|
+
"use strict";
|
7
|
+
|
8
|
+
//------------------------------------------------------------------------------
|
9
|
+
// Requirements
|
10
|
+
//------------------------------------------------------------------------------
|
11
|
+
|
12
|
+
var astUtils = require("../ast-utils.js");
|
13
|
+
|
14
|
+
//------------------------------------------------------------------------------
|
15
|
+
// Helpers
|
16
|
+
//------------------------------------------------------------------------------
|
17
|
+
|
18
|
+
var ARITHMETIC_OPERATORS = ["+", "-", "*", "/", "%", "**"];
|
19
|
+
var BITWISE_OPERATORS = ["&", "|", "^", "~", "<<", ">>", ">>>"];
|
20
|
+
var COMPARISON_OPERATORS = ["==", "!=", "===", "!==", ">", ">=", "<", "<="];
|
21
|
+
var LOGICAL_OPERATORS = ["&&", "||"];
|
22
|
+
var RELATIONAL_OPERATORS = ["in", "instanceof"];
|
23
|
+
var ALL_OPERATORS = [].concat(
|
24
|
+
ARITHMETIC_OPERATORS,
|
25
|
+
BITWISE_OPERATORS,
|
26
|
+
COMPARISON_OPERATORS,
|
27
|
+
LOGICAL_OPERATORS,
|
28
|
+
RELATIONAL_OPERATORS
|
29
|
+
);
|
30
|
+
var DEFAULT_GROUPS = [
|
31
|
+
ARITHMETIC_OPERATORS,
|
32
|
+
BITWISE_OPERATORS,
|
33
|
+
COMPARISON_OPERATORS,
|
34
|
+
LOGICAL_OPERATORS,
|
35
|
+
RELATIONAL_OPERATORS
|
36
|
+
];
|
37
|
+
var TARGET_NODE_TYPE = /^(?:Binary|Logical)Expression$/;
|
38
|
+
|
39
|
+
/**
|
40
|
+
* Normalizes options.
|
41
|
+
*
|
42
|
+
* @param {object|undefined} options - A options object to normalize.
|
43
|
+
* @returns {object} Normalized option object.
|
44
|
+
*/
|
45
|
+
function normalizeOptions(options) {
|
46
|
+
var hasGroups = (options && options.groups && options.groups.length > 0);
|
47
|
+
var groups = hasGroups ? options.groups : DEFAULT_GROUPS;
|
48
|
+
var allowSamePrecedence = (options && options.allowSamePrecedence) !== false;
|
49
|
+
|
50
|
+
return {
|
51
|
+
groups: groups,
|
52
|
+
allowSamePrecedence: allowSamePrecedence
|
53
|
+
};
|
54
|
+
}
|
55
|
+
|
56
|
+
/**
|
57
|
+
* Checks whether any group which includes both given operator exists or not.
|
58
|
+
*
|
59
|
+
* @param {Array.<string[]>} groups - A list of groups to check.
|
60
|
+
* @param {string} left - An operator.
|
61
|
+
* @param {string} right - Another operator.
|
62
|
+
* @returns {boolean} `true` if such group existed.
|
63
|
+
*/
|
64
|
+
function includesBothInAGroup(groups, left, right) {
|
65
|
+
return groups.some(function(group) {
|
66
|
+
return group.indexOf(left) !== -1 && group.indexOf(right) !== -1;
|
67
|
+
});
|
68
|
+
}
|
69
|
+
|
70
|
+
//------------------------------------------------------------------------------
|
71
|
+
// Rule Definition
|
72
|
+
//------------------------------------------------------------------------------
|
73
|
+
|
74
|
+
module.exports = {
|
75
|
+
meta: {
|
76
|
+
docs: {
|
77
|
+
description: "disallow mixed binary operators",
|
78
|
+
category: "Stylistic Issues",
|
79
|
+
recommended: false
|
80
|
+
},
|
81
|
+
schema: [
|
82
|
+
{
|
83
|
+
type: "object",
|
84
|
+
properties: {
|
85
|
+
groups: {
|
86
|
+
type: "array",
|
87
|
+
items: {
|
88
|
+
type: "array",
|
89
|
+
items: {enum: ALL_OPERATORS},
|
90
|
+
minItems: 2,
|
91
|
+
uniqueItems: true
|
92
|
+
},
|
93
|
+
uniqueItems: true
|
94
|
+
},
|
95
|
+
allowSamePrecedence: {
|
96
|
+
type: "boolean"
|
97
|
+
}
|
98
|
+
},
|
99
|
+
additionalProperties: false
|
100
|
+
}
|
101
|
+
]
|
102
|
+
},
|
103
|
+
|
104
|
+
create: function(context) {
|
105
|
+
var sourceCode = context.getSourceCode();
|
106
|
+
var options = normalizeOptions(context.options[0]);
|
107
|
+
|
108
|
+
/**
|
109
|
+
* Checks whether a given node should be ignored by options or not.
|
110
|
+
*
|
111
|
+
* @param {ASTNode} node - A node to check. This is a BinaryExpression
|
112
|
+
* node or a LogicalExpression node. This parent node is one of
|
113
|
+
* them, too.
|
114
|
+
* @returns {boolean} `true` if the node should be ignored.
|
115
|
+
*/
|
116
|
+
function shouldIgnore(node) {
|
117
|
+
var a = node;
|
118
|
+
var b = node.parent;
|
119
|
+
|
120
|
+
return (
|
121
|
+
!includesBothInAGroup(options.groups, a.operator, b.operator) ||
|
122
|
+
(
|
123
|
+
options.allowSamePrecedence &&
|
124
|
+
astUtils.getPrecedence(a) === astUtils.getPrecedence(b)
|
125
|
+
)
|
126
|
+
);
|
127
|
+
}
|
128
|
+
|
129
|
+
/**
|
130
|
+
* Checks whether the operator of a given node is mixed with parent
|
131
|
+
* node's operator or not.
|
132
|
+
*
|
133
|
+
* @param {ASTNode} node - A node to check. This is a BinaryExpression
|
134
|
+
* node or a LogicalExpression node. This parent node is one of
|
135
|
+
* them, too.
|
136
|
+
* @returns {boolean} `true` if the node was mixed.
|
137
|
+
*/
|
138
|
+
function isMixedWithParent(node) {
|
139
|
+
return (
|
140
|
+
node.operator !== node.parent.operator &&
|
141
|
+
!astUtils.isParenthesised(sourceCode, node)
|
142
|
+
);
|
143
|
+
}
|
144
|
+
|
145
|
+
/**
|
146
|
+
* Gets the operator token of a given node.
|
147
|
+
*
|
148
|
+
* @param {ASTNode} node - A node to check. This is a BinaryExpression
|
149
|
+
* node or a LogicalExpression node.
|
150
|
+
* @returns {Token} The operator token of the node.
|
151
|
+
*/
|
152
|
+
function getOperatorToken(node) {
|
153
|
+
var token = sourceCode.getTokenAfter(node.left);
|
154
|
+
|
155
|
+
while (token.value === ")") {
|
156
|
+
token = sourceCode.getTokenAfter(token);
|
157
|
+
}
|
158
|
+
|
159
|
+
return token;
|
160
|
+
}
|
161
|
+
|
162
|
+
/**
|
163
|
+
* Reports both the operator of a given node and the operator of the
|
164
|
+
* parent node.
|
165
|
+
*
|
166
|
+
* @param {ASTNode} node - A node to check. This is a BinaryExpression
|
167
|
+
* node or a LogicalExpression node. This parent node is one of
|
168
|
+
* them, too.
|
169
|
+
* @returns {void}
|
170
|
+
*/
|
171
|
+
function reportBothOperators(node) {
|
172
|
+
var parent = node.parent;
|
173
|
+
var left = (parent.left === node) ? node : parent;
|
174
|
+
var right = (parent.left !== node) ? node : parent;
|
175
|
+
var message =
|
176
|
+
"Unexpected mix of '" + left.operator + "' and '" +
|
177
|
+
right.operator + "'.";
|
178
|
+
|
179
|
+
context.report({
|
180
|
+
node: left,
|
181
|
+
loc: getOperatorToken(left).loc.start,
|
182
|
+
message: message
|
183
|
+
});
|
184
|
+
context.report({
|
185
|
+
node: right,
|
186
|
+
loc: getOperatorToken(right).loc.start,
|
187
|
+
message: message
|
188
|
+
});
|
189
|
+
}
|
190
|
+
|
191
|
+
/**
|
192
|
+
* Checks between the operator of this node and the operator of the
|
193
|
+
* parent node.
|
194
|
+
*
|
195
|
+
* @param {ASTNode} node - A node to check.
|
196
|
+
* @returns {void}
|
197
|
+
*/
|
198
|
+
function check(node) {
|
199
|
+
if (TARGET_NODE_TYPE.test(node.parent.type) &&
|
200
|
+
isMixedWithParent(node) &&
|
201
|
+
!shouldIgnore(node)
|
202
|
+
) {
|
203
|
+
reportBothOperators(node);
|
204
|
+
}
|
205
|
+
}
|
206
|
+
|
207
|
+
return {
|
208
|
+
BinaryExpression: check,
|
209
|
+
LogicalExpression: check
|
210
|
+
};
|
211
|
+
}
|
212
|
+
};
|
@@ -17,6 +17,8 @@ module.exports = {
|
|
17
17
|
recommended: false
|
18
18
|
},
|
19
19
|
|
20
|
+
fixable: "whitespace",
|
21
|
+
|
20
22
|
schema: [
|
21
23
|
{
|
22
24
|
type: "object",
|
@@ -76,21 +78,34 @@ module.exports = {
|
|
76
78
|
|
77
79
|
"Program:exit": function checkBlankLines(node) {
|
78
80
|
var lines = sourceCode.lines,
|
79
|
-
|
80
|
-
|
81
|
+
fullLines = sourceCode.text.match(/.*(\r\n|\r|\n|\u2028|\u2029)/g) || [],
|
82
|
+
firstNonBlankLine = -1,
|
83
|
+
trimmedLines = [],
|
84
|
+
linesRangeStart = [],
|
81
85
|
blankCounter = 0,
|
86
|
+
currentLocation,
|
87
|
+
lastLocation,
|
82
88
|
location,
|
83
89
|
firstOfEndingBlankLines,
|
84
|
-
|
85
|
-
|
90
|
+
diff,
|
91
|
+
fix,
|
92
|
+
rangeStart,
|
93
|
+
rangeEnd;
|
94
|
+
|
95
|
+
fix = function(fixer) {
|
96
|
+
return fixer.removeRange([rangeStart, rangeEnd]);
|
97
|
+
};
|
86
98
|
|
99
|
+
linesRangeStart.push(0);
|
87
100
|
lines.forEach(function(str, i) {
|
88
|
-
var
|
101
|
+
var length = i < fullLines.length ? fullLines[i].length : 0,
|
102
|
+
trimmed = str.trim();
|
89
103
|
|
90
104
|
if ((firstNonBlankLine === -1) && (trimmed !== "")) {
|
91
105
|
firstNonBlankLine = i;
|
92
106
|
}
|
93
107
|
|
108
|
+
linesRangeStart.push(linesRangeStart[linesRangeStart.length - 1] + length);
|
94
109
|
trimmedLines.push(trimmed);
|
95
110
|
});
|
96
111
|
|
@@ -122,8 +137,15 @@ module.exports = {
|
|
122
137
|
|
123
138
|
// Aggregate and count blank lines
|
124
139
|
if (firstNonBlankLine > maxBOF) {
|
125
|
-
|
126
|
-
|
140
|
+
diff = firstNonBlankLine - maxBOF;
|
141
|
+
rangeStart = linesRangeStart[firstNonBlankLine - diff];
|
142
|
+
rangeEnd = linesRangeStart[firstNonBlankLine];
|
143
|
+
context.report({
|
144
|
+
node: node,
|
145
|
+
loc: node.loc.start,
|
146
|
+
message: "Too many blank lines at the beginning of file. Max of " + maxBOF + " allowed.",
|
147
|
+
fix: fix
|
148
|
+
});
|
127
149
|
}
|
128
150
|
currentLocation = firstNonBlankLine - 1;
|
129
151
|
|
@@ -144,20 +166,29 @@ module.exports = {
|
|
144
166
|
|
145
167
|
// within the file, not at the end
|
146
168
|
if (blankCounter >= max) {
|
169
|
+
diff = blankCounter - max + 1;
|
170
|
+
rangeStart = linesRangeStart[location.line - diff];
|
171
|
+
rangeEnd = linesRangeStart[location.line];
|
172
|
+
|
147
173
|
context.report({
|
148
174
|
node: node,
|
149
175
|
loc: location,
|
150
|
-
message: "More than " + max + " blank " + (max === 1 ? "line" : "lines") + " not allowed."
|
176
|
+
message: "More than " + max + " blank " + (max === 1 ? "line" : "lines") + " not allowed.",
|
177
|
+
fix: fix
|
151
178
|
});
|
152
179
|
}
|
153
180
|
} else {
|
154
181
|
|
155
182
|
// inside the last blank lines
|
156
183
|
if (blankCounter > maxEOF) {
|
184
|
+
diff = blankCounter - maxEOF + 1;
|
185
|
+
rangeStart = linesRangeStart[location.line - diff];
|
186
|
+
rangeEnd = linesRangeStart[location.line - 1];
|
157
187
|
context.report({
|
158
188
|
node: node,
|
159
189
|
loc: location,
|
160
|
-
message: "Too many blank lines at the end of file. Max of " + maxEOF + " allowed."
|
190
|
+
message: "Too many blank lines at the end of file. Max of " + maxEOF + " allowed.",
|
191
|
+
fix: fix
|
161
192
|
});
|
162
193
|
}
|
163
194
|
}
|
@@ -11,7 +11,7 @@
|
|
11
11
|
module.exports = {
|
12
12
|
meta: {
|
13
13
|
docs: {
|
14
|
-
description: "disallow calling some Object.prototype methods directly on objects",
|
14
|
+
description: "disallow calling some `Object.prototype` methods directly on objects",
|
15
15
|
category: "Possible Errors",
|
16
16
|
recommended: false
|
17
17
|
}
|
@@ -21,7 +21,7 @@ var SENTINEL_NODE_TYPE_CONTINUE = /^(?:Program|(?:Function|Class)(?:Declaration|
|
|
21
21
|
module.exports = {
|
22
22
|
meta: {
|
23
23
|
docs: {
|
24
|
-
description: "disallow control flow statements in finally blocks",
|
24
|
+
description: "disallow control flow statements in `finally` blocks",
|
25
25
|
category: "Possible Errors",
|
26
26
|
recommended: false
|
27
27
|
}
|
@@ -87,7 +87,13 @@ module.exports = {
|
|
87
87
|
return;
|
88
88
|
}
|
89
89
|
|
90
|
-
|
90
|
+
/**
|
91
|
+
* If an ObjectPattern property is computed, we have no idea
|
92
|
+
* if a rename is useless or not. If an ObjectPattern property
|
93
|
+
* lacks a key, it is likely an ExperimentalRestProperty and
|
94
|
+
* so there is no "renaming" occurring here.
|
95
|
+
*/
|
96
|
+
if (properties[i].computed || !properties[i].key) {
|
91
97
|
return;
|
92
98
|
}
|
93
99
|
|
@@ -108,7 +114,8 @@ module.exports = {
|
|
108
114
|
return;
|
109
115
|
}
|
110
116
|
|
111
|
-
if (node.imported.name === node.local.name
|
117
|
+
if (node.imported.name === node.local.name &&
|
118
|
+
node.imported.range[0] !== node.local.range[0]) {
|
112
119
|
reportError(node, node.imported, node.local, "Import");
|
113
120
|
}
|
114
121
|
}
|
@@ -123,7 +130,8 @@ module.exports = {
|
|
123
130
|
return;
|
124
131
|
}
|
125
132
|
|
126
|
-
if (node.local.name === node.exported.name
|
133
|
+
if (node.local.name === node.exported.name &&
|
134
|
+
node.local.range[0] !== node.exported.range[0]) {
|
127
135
|
reportError(node, node.local, node.exported, "Export");
|
128
136
|
}
|
129
137
|
|
@@ -0,0 +1,209 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Rule to require or disallow line breaks inside braces.
|
3
|
+
* @author Toru Nagashima
|
4
|
+
*/
|
5
|
+
|
6
|
+
"use strict";
|
7
|
+
|
8
|
+
//------------------------------------------------------------------------------
|
9
|
+
// Requirements
|
10
|
+
//------------------------------------------------------------------------------
|
11
|
+
|
12
|
+
var astUtils = require("../ast-utils");
|
13
|
+
|
14
|
+
//------------------------------------------------------------------------------
|
15
|
+
// Helpers
|
16
|
+
//------------------------------------------------------------------------------
|
17
|
+
|
18
|
+
// Schema objects.
|
19
|
+
var OPTION_VALUE = {
|
20
|
+
oneOf: [
|
21
|
+
{
|
22
|
+
enum: ["always", "never"]
|
23
|
+
},
|
24
|
+
{
|
25
|
+
type: "object",
|
26
|
+
properties: {
|
27
|
+
multiline: {
|
28
|
+
type: "boolean"
|
29
|
+
},
|
30
|
+
minProperties: {
|
31
|
+
type: "integer",
|
32
|
+
minimum: 0
|
33
|
+
}
|
34
|
+
},
|
35
|
+
additionalProperties: false,
|
36
|
+
minProperties: 1
|
37
|
+
}
|
38
|
+
]
|
39
|
+
};
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Normalizes a given option value.
|
43
|
+
*
|
44
|
+
* @param {string|object|undefined} value - An option value to parse.
|
45
|
+
* @returns {{multiline: boolean, minProperties: number}} Normalized option object.
|
46
|
+
*/
|
47
|
+
function normalizeOptionValue(value) {
|
48
|
+
var multiline = false;
|
49
|
+
var minProperties = Number.POSITIVE_INFINITY;
|
50
|
+
|
51
|
+
if (value) {
|
52
|
+
if (value === "always") {
|
53
|
+
minProperties = 0;
|
54
|
+
} else if (value === "never") {
|
55
|
+
minProperties = Number.POSITIVE_INFINITY;
|
56
|
+
} else {
|
57
|
+
multiline = Boolean(value.multiline);
|
58
|
+
minProperties = value.minProperties || Number.POSITIVE_INFINITY;
|
59
|
+
}
|
60
|
+
} else {
|
61
|
+
multiline = true;
|
62
|
+
}
|
63
|
+
|
64
|
+
return {multiline: multiline, minProperties: minProperties};
|
65
|
+
}
|
66
|
+
|
67
|
+
/**
|
68
|
+
* Normalizes a given option value.
|
69
|
+
*
|
70
|
+
* @param {string|object|undefined} options - An option value to parse.
|
71
|
+
* @returns {{ObjectExpression: {multiline: boolean, minProperties: number}, ObjectPattern: {multiline: boolean, minProperties: number}}} Normalized option object.
|
72
|
+
*/
|
73
|
+
function normalizeOptions(options) {
|
74
|
+
if (options && (options.ObjectExpression || options.ObjectPattern)) {
|
75
|
+
return {
|
76
|
+
ObjectExpression: normalizeOptionValue(options.ObjectExpression),
|
77
|
+
ObjectPattern: normalizeOptionValue(options.ObjectPattern)
|
78
|
+
};
|
79
|
+
}
|
80
|
+
|
81
|
+
var value = normalizeOptionValue(options);
|
82
|
+
|
83
|
+
return {ObjectExpression: value, ObjectPattern: value};
|
84
|
+
}
|
85
|
+
|
86
|
+
//------------------------------------------------------------------------------
|
87
|
+
// Rule Definition
|
88
|
+
//------------------------------------------------------------------------------
|
89
|
+
|
90
|
+
module.exports = {
|
91
|
+
meta: {
|
92
|
+
docs: {
|
93
|
+
description: "enforce consistent line breaks inside braces",
|
94
|
+
category: "Stylistic Issues",
|
95
|
+
recommended: false
|
96
|
+
},
|
97
|
+
fixable: "whitespace",
|
98
|
+
schema: [
|
99
|
+
{
|
100
|
+
oneOf: [
|
101
|
+
OPTION_VALUE,
|
102
|
+
{
|
103
|
+
type: "object",
|
104
|
+
properties: {
|
105
|
+
ObjectExpression: OPTION_VALUE,
|
106
|
+
ObjectPattern: OPTION_VALUE
|
107
|
+
},
|
108
|
+
additionalProperties: false,
|
109
|
+
minProperties: 1
|
110
|
+
}
|
111
|
+
]
|
112
|
+
}
|
113
|
+
]
|
114
|
+
},
|
115
|
+
|
116
|
+
create: function(context) {
|
117
|
+
var sourceCode = context.getSourceCode();
|
118
|
+
var normalizedOptions = normalizeOptions(context.options[0]);
|
119
|
+
|
120
|
+
/**
|
121
|
+
* Reports a given node if it violated this rule.
|
122
|
+
*
|
123
|
+
* @param {ASTNode} node - A node to check. This is an ObjectExpression node or an ObjectPattern node.
|
124
|
+
* @param {{multiline: boolean, minProperties: number}} options - An option object.
|
125
|
+
* @returns {void}
|
126
|
+
*/
|
127
|
+
function check(node) {
|
128
|
+
var options = normalizedOptions[node.type];
|
129
|
+
var openBrace = sourceCode.getFirstToken(node);
|
130
|
+
var closeBrace = sourceCode.getLastToken(node);
|
131
|
+
var first = sourceCode.getTokenOrCommentAfter(openBrace);
|
132
|
+
var last = sourceCode.getTokenOrCommentBefore(closeBrace);
|
133
|
+
var needsLinebreaks = (
|
134
|
+
node.properties.length >= options.minProperties ||
|
135
|
+
(
|
136
|
+
options.multiline &&
|
137
|
+
node.properties.length > 0 &&
|
138
|
+
first.loc.start.line !== last.loc.end.line
|
139
|
+
)
|
140
|
+
);
|
141
|
+
|
142
|
+
/*
|
143
|
+
* Use tokens or comments to check multiline or not.
|
144
|
+
* But use only tokens to check whether line breaks are needed.
|
145
|
+
* This allows:
|
146
|
+
* var obj = { // eslint-disable-line foo
|
147
|
+
* a: 1
|
148
|
+
* }
|
149
|
+
*/
|
150
|
+
first = sourceCode.getTokenAfter(openBrace);
|
151
|
+
last = sourceCode.getTokenBefore(closeBrace);
|
152
|
+
|
153
|
+
if (needsLinebreaks) {
|
154
|
+
if (astUtils.isTokenOnSameLine(openBrace, first)) {
|
155
|
+
context.report({
|
156
|
+
message: "Expected a line break after this open brace.",
|
157
|
+
node: node,
|
158
|
+
loc: openBrace.loc.start,
|
159
|
+
fix: function(fixer) {
|
160
|
+
return fixer.insertTextAfter(openBrace, "\n");
|
161
|
+
}
|
162
|
+
});
|
163
|
+
}
|
164
|
+
if (astUtils.isTokenOnSameLine(last, closeBrace)) {
|
165
|
+
context.report({
|
166
|
+
message: "Expected a line break before this close brace.",
|
167
|
+
node: node,
|
168
|
+
loc: closeBrace.loc.start,
|
169
|
+
fix: function(fixer) {
|
170
|
+
return fixer.insertTextBefore(closeBrace, "\n");
|
171
|
+
}
|
172
|
+
});
|
173
|
+
}
|
174
|
+
} else {
|
175
|
+
if (!astUtils.isTokenOnSameLine(openBrace, first)) {
|
176
|
+
context.report({
|
177
|
+
message: "Unexpected a line break after this open brace.",
|
178
|
+
node: node,
|
179
|
+
loc: openBrace.loc.start,
|
180
|
+
fix: function(fixer) {
|
181
|
+
return fixer.removeRange([
|
182
|
+
openBrace.range[1],
|
183
|
+
first.range[0]
|
184
|
+
]);
|
185
|
+
}
|
186
|
+
});
|
187
|
+
}
|
188
|
+
if (!astUtils.isTokenOnSameLine(last, closeBrace)) {
|
189
|
+
context.report({
|
190
|
+
message: "Unexpected a line break before this close brace.",
|
191
|
+
node: node,
|
192
|
+
loc: closeBrace.loc.start,
|
193
|
+
fix: function(fixer) {
|
194
|
+
return fixer.removeRange([
|
195
|
+
last.range[1],
|
196
|
+
closeBrace.range[0]
|
197
|
+
]);
|
198
|
+
}
|
199
|
+
});
|
200
|
+
}
|
201
|
+
}
|
202
|
+
}
|
203
|
+
|
204
|
+
return {
|
205
|
+
ObjectExpression: check,
|
206
|
+
ObjectPattern: check
|
207
|
+
};
|
208
|
+
}
|
209
|
+
};
|