eslint 7.0.0-alpha.2 → 7.1.0
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 +332 -0
- package/README.md +9 -10
- package/bin/eslint.js +115 -77
- package/conf/category-list.json +0 -1
- package/conf/environments.js +2 -1
- package/lib/api.js +2 -0
- package/lib/cli-engine/cascading-config-array-factory.js +16 -2
- package/lib/cli-engine/cli-engine.js +53 -47
- package/lib/cli-engine/config-array/config-array.js +30 -1
- package/lib/cli-engine/config-array/ignore-pattern.js +7 -1
- package/lib/cli-engine/config-array-factory.js +244 -235
- package/lib/cli.js +181 -95
- package/lib/eslint/eslint.js +656 -0
- package/lib/eslint/index.js +7 -0
- package/lib/init/autoconfig.js +4 -4
- package/lib/init/config-file.js +2 -2
- package/lib/init/config-initializer.js +3 -4
- package/lib/init/source-code-utils.js +2 -2
- package/lib/linter/linter.js +2 -1
- package/lib/linter/node-event-generator.js +2 -2
- package/lib/options.js +0 -1
- package/lib/rule-tester/rule-tester.js +132 -22
- package/lib/rules/accessor-pairs.js +1 -1
- package/lib/rules/array-callback-return.js +3 -18
- package/lib/rules/arrow-parens.js +19 -3
- package/lib/rules/block-spacing.js +19 -2
- package/lib/rules/callback-return.js +4 -0
- package/lib/rules/camelcase.js +38 -1
- package/lib/rules/comma-style.js +3 -8
- package/lib/rules/func-call-spacing.js +4 -3
- package/lib/rules/getter-return.js +2 -12
- package/lib/rules/global-require.js +4 -0
- package/lib/rules/handle-callback-err.js +4 -0
- package/lib/rules/id-blacklist.js +138 -102
- package/lib/rules/index.js +1 -0
- package/lib/rules/key-spacing.js +1 -1
- package/lib/rules/linebreak-style.js +8 -2
- package/lib/rules/max-lines-per-function.js +1 -1
- package/lib/rules/new-cap.js +1 -1
- package/lib/rules/newline-per-chained-call.js +6 -3
- package/lib/rules/no-alert.js +5 -3
- package/lib/rules/no-buffer-constructor.js +4 -0
- package/lib/rules/no-empty-function.js +4 -2
- package/lib/rules/no-eval.js +2 -1
- package/lib/rules/no-extra-bind.js +1 -1
- package/lib/rules/no-extra-boolean-cast.js +102 -23
- package/lib/rules/no-extra-parens.js +9 -5
- package/lib/rules/no-implied-eval.js +83 -101
- package/lib/rules/no-inner-declarations.js +31 -39
- package/lib/rules/no-lone-blocks.js +1 -1
- package/lib/rules/no-loss-of-precision.js +198 -0
- package/lib/rules/no-magic-numbers.js +72 -37
- package/lib/rules/no-mixed-requires.js +4 -0
- package/lib/rules/no-new-func.js +22 -19
- package/lib/rules/no-new-object.js +15 -3
- package/lib/rules/no-new-require.js +4 -0
- package/lib/rules/no-new-symbol.js +2 -1
- package/lib/rules/no-new-wrappers.js +1 -1
- package/lib/rules/no-obj-calls.js +24 -5
- package/lib/rules/no-path-concat.js +4 -0
- package/lib/rules/no-plusplus.js +39 -3
- package/lib/rules/no-process-env.js +4 -0
- package/lib/rules/no-process-exit.js +4 -0
- package/lib/rules/no-prototype-builtins.js +1 -1
- package/lib/rules/no-restricted-modules.js +4 -0
- package/lib/rules/no-sync.js +4 -0
- package/lib/rules/no-unexpected-multiline.js +22 -12
- package/lib/rules/no-useless-concat.js +1 -1
- package/lib/rules/one-var-declaration-per-line.js +1 -1
- package/lib/rules/operator-assignment.js +3 -3
- package/lib/rules/operator-linebreak.js +4 -16
- package/lib/rules/padded-blocks.js +17 -4
- package/lib/rules/prefer-numeric-literals.js +3 -3
- package/lib/rules/prefer-object-spread.js +2 -2
- package/lib/rules/require-await.js +1 -1
- package/lib/rules/rest-spread-spacing.js +3 -6
- package/lib/rules/semi-spacing.js +32 -8
- package/lib/rules/space-before-function-paren.js +5 -2
- package/lib/rules/template-curly-spacing.js +59 -42
- package/lib/rules/utils/ast-utils.js +116 -10
- package/lib/rules/yoda.js +101 -51
- package/lib/shared/relative-module-resolver.js +1 -0
- package/lib/shared/types.js +9 -2
- package/lib/source-code/source-code.js +1 -0
- package/messages/extend-config-missing.txt +1 -1
- package/messages/no-config-found.txt +1 -1
- package/messages/plugin-conflict.txt +7 -0
- package/messages/plugin-missing.txt +1 -1
- package/messages/whitespace-found.txt +1 -1
- package/package.json +27 -26
@@ -7,6 +7,9 @@
|
|
7
7
|
|
8
8
|
const { isNumericLiteral } = require("./utils/ast-utils");
|
9
9
|
|
10
|
+
// Maximum array length by the ECMAScript Specification.
|
11
|
+
const MAX_ARRAY_LENGTH = 2 ** 32 - 1;
|
12
|
+
|
10
13
|
//------------------------------------------------------------------------------
|
11
14
|
// Rule Definition
|
12
15
|
//------------------------------------------------------------------------------
|
@@ -76,83 +79,115 @@ module.exports = {
|
|
76
79
|
ignore = (config.ignore || []).map(normalizeIgnoreValue),
|
77
80
|
ignoreArrayIndexes = !!config.ignoreArrayIndexes;
|
78
81
|
|
82
|
+
const okTypes = detectObjects ? [] : ["ObjectExpression", "Property", "AssignmentExpression"];
|
83
|
+
|
79
84
|
/**
|
80
|
-
* Returns whether the
|
81
|
-
* @param {number}
|
82
|
-
* @returns {boolean} true if the
|
85
|
+
* Returns whether the rule is configured to ignore the given value
|
86
|
+
* @param {bigint|number} value The value to check
|
87
|
+
* @returns {boolean} true if the value is ignored
|
83
88
|
*/
|
84
|
-
function
|
85
|
-
return ignore.indexOf(
|
89
|
+
function isIgnoredValue(value) {
|
90
|
+
return ignore.indexOf(value) !== -1;
|
86
91
|
}
|
87
92
|
|
88
93
|
/**
|
89
|
-
* Returns whether the
|
90
|
-
* @param {ASTNode}
|
91
|
-
* @
|
92
|
-
* @returns {boolean} true if the number should be ignored
|
94
|
+
* Returns whether the given node is used as a radix within parseInt() or Number.parseInt()
|
95
|
+
* @param {ASTNode} fullNumberNode `Literal` or `UnaryExpression` full number node
|
96
|
+
* @returns {boolean} true if the node is radix
|
93
97
|
*/
|
94
|
-
function
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
98
|
+
function isParseIntRadix(fullNumberNode) {
|
99
|
+
const parent = fullNumberNode.parent;
|
100
|
+
|
101
|
+
return parent.type === "CallExpression" && fullNumberNode === parent.arguments[1] &&
|
102
|
+
(
|
103
|
+
parent.callee.name === "parseInt" ||
|
104
|
+
(
|
105
|
+
parent.callee.type === "MemberExpression" &&
|
106
|
+
parent.callee.object.name === "Number" &&
|
107
|
+
parent.callee.property.name === "parseInt"
|
108
|
+
)
|
109
|
+
);
|
100
110
|
}
|
101
111
|
|
102
112
|
/**
|
103
|
-
* Returns whether the
|
104
|
-
*
|
105
|
-
*
|
113
|
+
* Returns whether the given node is a direct child of a JSX node.
|
114
|
+
* In particular, it aims to detect numbers used as prop values in JSX tags.
|
115
|
+
* Example: <input maxLength={10} />
|
116
|
+
* @param {ASTNode} fullNumberNode `Literal` or `UnaryExpression` full number node
|
117
|
+
* @returns {boolean} true if the node is a JSX number
|
106
118
|
*/
|
107
|
-
function
|
108
|
-
return parent.type.indexOf("JSX") === 0;
|
119
|
+
function isJSXNumber(fullNumberNode) {
|
120
|
+
return fullNumberNode.parent.type.indexOf("JSX") === 0;
|
109
121
|
}
|
110
122
|
|
111
123
|
/**
|
112
|
-
* Returns whether the
|
113
|
-
*
|
114
|
-
*
|
124
|
+
* Returns whether the given node is used as an array index.
|
125
|
+
* Value must coerce to a valid array index name: "0", "1", "2" ... "4294967294".
|
126
|
+
*
|
127
|
+
* All other values, like "-1", "2.5", or "4294967295", are just "normal" object properties,
|
128
|
+
* which can be created and accessed on an array in addition to the array index properties,
|
129
|
+
* but they don't affect array's length and are not considered by methods such as .map(), .forEach() etc.
|
130
|
+
*
|
131
|
+
* The maximum array length by the specification is 2 ** 32 - 1 = 4294967295,
|
132
|
+
* thus the maximum valid index is 2 ** 32 - 2 = 4294967294.
|
133
|
+
*
|
134
|
+
* All notations are allowed, as long as the value coerces to one of "0", "1", "2" ... "4294967294".
|
135
|
+
*
|
136
|
+
* Valid examples:
|
137
|
+
* a[0], a[1], a[1.2e1], a[0xAB], a[0n], a[1n]
|
138
|
+
* a[-0] (same as a[0] because -0 coerces to "0")
|
139
|
+
* a[-0n] (-0n evaluates to 0n)
|
140
|
+
*
|
141
|
+
* Invalid examples:
|
142
|
+
* a[-1], a[-0xAB], a[-1n], a[2.5], a[1.23e1], a[12e-1]
|
143
|
+
* a[4294967295] (above the max index, it's an access to a regular property a["4294967295"])
|
144
|
+
* a[999999999999999999999] (even if it wasn't above the max index, it would be a["1e+21"])
|
145
|
+
* a[1e310] (same as a["Infinity"])
|
146
|
+
* @param {ASTNode} fullNumberNode `Literal` or `UnaryExpression` full number node
|
147
|
+
* @param {bigint|number} value Value expressed by the fullNumberNode
|
148
|
+
* @returns {boolean} true if the node is a valid array index
|
115
149
|
*/
|
116
|
-
function
|
117
|
-
const parent =
|
150
|
+
function isArrayIndex(fullNumberNode, value) {
|
151
|
+
const parent = fullNumberNode.parent;
|
118
152
|
|
119
|
-
return
|
120
|
-
|
153
|
+
return parent.type === "MemberExpression" && parent.property === fullNumberNode &&
|
154
|
+
(Number.isInteger(value) || typeof value === "bigint") &&
|
155
|
+
value >= 0 && value < MAX_ARRAY_LENGTH;
|
121
156
|
}
|
122
157
|
|
123
158
|
return {
|
124
159
|
Literal(node) {
|
125
|
-
const okTypes = detectObjects ? [] : ["ObjectExpression", "Property", "AssignmentExpression"];
|
126
|
-
|
127
160
|
if (!isNumericLiteral(node)) {
|
128
161
|
return;
|
129
162
|
}
|
130
163
|
|
131
164
|
let fullNumberNode;
|
132
|
-
let parent;
|
133
165
|
let value;
|
134
166
|
let raw;
|
135
167
|
|
136
|
-
//
|
168
|
+
// Treat unary minus as a part of the number
|
137
169
|
if (node.parent.type === "UnaryExpression" && node.parent.operator === "-") {
|
138
170
|
fullNumberNode = node.parent;
|
139
|
-
parent = fullNumberNode.parent;
|
140
171
|
value = -node.value;
|
141
172
|
raw = `-${node.raw}`;
|
142
173
|
} else {
|
143
174
|
fullNumberNode = node;
|
144
|
-
parent = node.parent;
|
145
175
|
value = node.value;
|
146
176
|
raw = node.raw;
|
147
177
|
}
|
148
178
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
179
|
+
// Always allow radix arguments and JSX props
|
180
|
+
if (
|
181
|
+
isIgnoredValue(value) ||
|
182
|
+
isParseIntRadix(fullNumberNode) ||
|
183
|
+
isJSXNumber(fullNumberNode) ||
|
184
|
+
(ignoreArrayIndexes && isArrayIndex(fullNumberNode, value))
|
185
|
+
) {
|
153
186
|
return;
|
154
187
|
}
|
155
188
|
|
189
|
+
const parent = fullNumberNode.parent;
|
190
|
+
|
156
191
|
if (parent.type === "VariableDeclarator") {
|
157
192
|
if (enforceConst && parent.parent.kind !== "const") {
|
158
193
|
context.report({
|
package/lib/rules/no-new-func.js
CHANGED
@@ -29,26 +29,29 @@ module.exports = {
|
|
29
29
|
|
30
30
|
create(context) {
|
31
31
|
|
32
|
-
//--------------------------------------------------------------------------
|
33
|
-
// Helpers
|
34
|
-
//--------------------------------------------------------------------------
|
35
|
-
|
36
|
-
/**
|
37
|
-
* Reports a node.
|
38
|
-
* @param {ASTNode} node The node to report
|
39
|
-
* @returns {void}
|
40
|
-
* @private
|
41
|
-
*/
|
42
|
-
function report(node) {
|
43
|
-
context.report({
|
44
|
-
node,
|
45
|
-
messageId: "noFunctionConstructor"
|
46
|
-
});
|
47
|
-
}
|
48
|
-
|
49
32
|
return {
|
50
|
-
"
|
51
|
-
|
33
|
+
"Program:exit"() {
|
34
|
+
const globalScope = context.getScope();
|
35
|
+
const variable = globalScope.set.get("Function");
|
36
|
+
|
37
|
+
if (variable && variable.defs.length === 0) {
|
38
|
+
variable.references.forEach(ref => {
|
39
|
+
const node = ref.identifier;
|
40
|
+
const { parent } = node;
|
41
|
+
|
42
|
+
if (
|
43
|
+
parent &&
|
44
|
+
(parent.type === "NewExpression" || parent.type === "CallExpression") &&
|
45
|
+
node === parent.callee
|
46
|
+
) {
|
47
|
+
context.report({
|
48
|
+
node: parent,
|
49
|
+
messageId: "noFunctionConstructor"
|
50
|
+
});
|
51
|
+
}
|
52
|
+
});
|
53
|
+
}
|
54
|
+
}
|
52
55
|
};
|
53
56
|
|
54
57
|
}
|
@@ -5,6 +5,12 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
+
//------------------------------------------------------------------------------
|
9
|
+
// Requirements
|
10
|
+
//------------------------------------------------------------------------------
|
11
|
+
|
12
|
+
const astUtils = require("./utils/ast-utils");
|
13
|
+
|
8
14
|
//------------------------------------------------------------------------------
|
9
15
|
// Rule Definition
|
10
16
|
//------------------------------------------------------------------------------
|
@@ -28,10 +34,17 @@ module.exports = {
|
|
28
34
|
},
|
29
35
|
|
30
36
|
create(context) {
|
31
|
-
|
32
37
|
return {
|
33
|
-
|
34
38
|
NewExpression(node) {
|
39
|
+
const variable = astUtils.getVariableByName(
|
40
|
+
context.getScope(),
|
41
|
+
node.callee.name
|
42
|
+
);
|
43
|
+
|
44
|
+
if (variable && variable.identifiers.length > 0) {
|
45
|
+
return;
|
46
|
+
}
|
47
|
+
|
35
48
|
if (node.callee.name === "Object") {
|
36
49
|
context.report({
|
37
50
|
node,
|
@@ -40,6 +53,5 @@ module.exports = {
|
|
40
53
|
}
|
41
54
|
}
|
42
55
|
};
|
43
|
-
|
44
56
|
}
|
45
57
|
};
|
@@ -37,8 +37,9 @@ module.exports = {
|
|
37
37
|
if (variable && variable.defs.length === 0) {
|
38
38
|
variable.references.forEach(ref => {
|
39
39
|
const node = ref.identifier;
|
40
|
+
const parent = node.parent;
|
40
41
|
|
41
|
-
if (
|
42
|
+
if (parent && parent.type === "NewExpression" && parent.callee === node) {
|
42
43
|
context.report({
|
43
44
|
node,
|
44
45
|
messageId: "noNewSymbol"
|
@@ -32,7 +32,7 @@ module.exports = {
|
|
32
32
|
return {
|
33
33
|
|
34
34
|
NewExpression(node) {
|
35
|
-
const wrapperObjects = ["String", "Number", "Boolean"
|
35
|
+
const wrapperObjects = ["String", "Number", "Boolean"];
|
36
36
|
|
37
37
|
if (wrapperObjects.indexOf(node.callee.name) > -1) {
|
38
38
|
context.report({
|
@@ -9,7 +9,8 @@
|
|
9
9
|
// Requirements
|
10
10
|
//------------------------------------------------------------------------------
|
11
11
|
|
12
|
-
const { CALL, ReferenceTracker } = require("eslint-utils");
|
12
|
+
const { CALL, CONSTRUCT, ReferenceTracker } = require("eslint-utils");
|
13
|
+
const getPropertyName = require("./utils/ast-utils").getStaticPropertyName;
|
13
14
|
|
14
15
|
//------------------------------------------------------------------------------
|
15
16
|
// Helpers
|
@@ -17,6 +18,18 @@ const { CALL, ReferenceTracker } = require("eslint-utils");
|
|
17
18
|
|
18
19
|
const nonCallableGlobals = ["Atomics", "JSON", "Math", "Reflect"];
|
19
20
|
|
21
|
+
/**
|
22
|
+
* Returns the name of the node to report
|
23
|
+
* @param {ASTNode} node A node to report
|
24
|
+
* @returns {string} name to report
|
25
|
+
*/
|
26
|
+
function getReportNodeName(node) {
|
27
|
+
if (node.callee.type === "MemberExpression") {
|
28
|
+
return getPropertyName(node.callee);
|
29
|
+
}
|
30
|
+
return node.callee.name;
|
31
|
+
}
|
32
|
+
|
20
33
|
//------------------------------------------------------------------------------
|
21
34
|
// Rule Definition
|
22
35
|
//------------------------------------------------------------------------------
|
@@ -35,7 +48,8 @@ module.exports = {
|
|
35
48
|
schema: [],
|
36
49
|
|
37
50
|
messages: {
|
38
|
-
unexpectedCall: "'{{name}}' is not a function."
|
51
|
+
unexpectedCall: "'{{name}}' is not a function.",
|
52
|
+
unexpectedRefCall: "'{{name}}' is reference to '{{ref}}', which is not a function."
|
39
53
|
}
|
40
54
|
},
|
41
55
|
|
@@ -49,12 +63,17 @@ module.exports = {
|
|
49
63
|
|
50
64
|
for (const g of nonCallableGlobals) {
|
51
65
|
traceMap[g] = {
|
52
|
-
[CALL]: true
|
66
|
+
[CALL]: true,
|
67
|
+
[CONSTRUCT]: true
|
53
68
|
};
|
54
69
|
}
|
55
70
|
|
56
|
-
for (const { node } of tracker.iterateGlobalReferences(traceMap)) {
|
57
|
-
|
71
|
+
for (const { node, path } of tracker.iterateGlobalReferences(traceMap)) {
|
72
|
+
const name = getReportNodeName(node);
|
73
|
+
const ref = path[0];
|
74
|
+
const messageId = name === ref ? "unexpectedCall" : "unexpectedRefCall";
|
75
|
+
|
76
|
+
context.report({ node, messageId, data: { name, ref } });
|
58
77
|
}
|
59
78
|
}
|
60
79
|
};
|
package/lib/rules/no-plusplus.js
CHANGED
@@ -6,6 +6,41 @@
|
|
6
6
|
|
7
7
|
"use strict";
|
8
8
|
|
9
|
+
//------------------------------------------------------------------------------
|
10
|
+
// Helpers
|
11
|
+
//------------------------------------------------------------------------------
|
12
|
+
|
13
|
+
/**
|
14
|
+
* Determines whether the given node is the update node of a `ForStatement`.
|
15
|
+
* @param {ASTNode} node The node to check.
|
16
|
+
* @returns {boolean} `true` if the node is `ForStatement` update.
|
17
|
+
*/
|
18
|
+
function isForStatementUpdate(node) {
|
19
|
+
const parent = node.parent;
|
20
|
+
|
21
|
+
return parent.type === "ForStatement" && parent.update === node;
|
22
|
+
}
|
23
|
+
|
24
|
+
/**
|
25
|
+
* Determines whether the given node is considered to be a for loop "afterthought" by the logic of this rule.
|
26
|
+
* In particular, it returns `true` if the given node is either:
|
27
|
+
* - The update node of a `ForStatement`: for (;; i++) {}
|
28
|
+
* - An operand of a sequence expression that is the update node: for (;; foo(), i++) {}
|
29
|
+
* - An operand of a sequence expression that is child of another sequence expression, etc.,
|
30
|
+
* up to the sequence expression that is the update node: for (;; foo(), (bar(), (baz(), i++))) {}
|
31
|
+
* @param {ASTNode} node The node to check.
|
32
|
+
* @returns {boolean} `true` if the node is a for loop afterthought.
|
33
|
+
*/
|
34
|
+
function isForLoopAfterthought(node) {
|
35
|
+
const parent = node.parent;
|
36
|
+
|
37
|
+
if (parent.type === "SequenceExpression") {
|
38
|
+
return isForLoopAfterthought(parent);
|
39
|
+
}
|
40
|
+
|
41
|
+
return isForStatementUpdate(node);
|
42
|
+
}
|
43
|
+
|
9
44
|
//------------------------------------------------------------------------------
|
10
45
|
// Rule Definition
|
11
46
|
//------------------------------------------------------------------------------
|
@@ -42,18 +77,19 @@ module.exports = {
|
|
42
77
|
create(context) {
|
43
78
|
|
44
79
|
const config = context.options[0];
|
45
|
-
let
|
80
|
+
let allowForLoopAfterthoughts = false;
|
46
81
|
|
47
82
|
if (typeof config === "object") {
|
48
|
-
|
83
|
+
allowForLoopAfterthoughts = config.allowForLoopAfterthoughts === true;
|
49
84
|
}
|
50
85
|
|
51
86
|
return {
|
52
87
|
|
53
88
|
UpdateExpression(node) {
|
54
|
-
if (
|
89
|
+
if (allowForLoopAfterthoughts && isForLoopAfterthought(node)) {
|
55
90
|
return;
|
56
91
|
}
|
92
|
+
|
57
93
|
context.report({
|
58
94
|
node,
|
59
95
|
messageId: "unexpectedUnaryOp",
|
package/lib/rules/no-sync.js
CHANGED
@@ -53,7 +53,11 @@ module.exports = {
|
|
53
53
|
const nodeExpressionEnd = sourceCode.getTokenBefore(openParen);
|
54
54
|
|
55
55
|
if (openParen.loc.start.line !== nodeExpressionEnd.loc.end.line) {
|
56
|
-
context.report({
|
56
|
+
context.report({
|
57
|
+
node,
|
58
|
+
loc: openParen.loc,
|
59
|
+
messageId
|
60
|
+
});
|
57
61
|
}
|
58
62
|
}
|
59
63
|
|
@@ -71,18 +75,24 @@ module.exports = {
|
|
71
75
|
},
|
72
76
|
|
73
77
|
TaggedTemplateExpression(node) {
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
78
|
+
const { quasi } = node;
|
79
|
+
|
80
|
+
// handles common tags, parenthesized tags, and typescript's generic type arguments
|
81
|
+
const tokenBefore = sourceCode.getTokenBefore(quasi);
|
82
|
+
|
83
|
+
if (tokenBefore.loc.end.line !== quasi.loc.start.line) {
|
84
|
+
context.report({
|
85
|
+
node,
|
86
|
+
loc: {
|
87
|
+
start: quasi.loc.start,
|
88
|
+
end: {
|
89
|
+
line: quasi.loc.start.line,
|
90
|
+
column: quasi.loc.start.column + 1
|
91
|
+
}
|
92
|
+
},
|
93
|
+
messageId: "taggedTemplate"
|
94
|
+
});
|
83
95
|
}
|
84
|
-
|
85
|
-
context.report({ node, loc: node.loc.start, messageId: "taggedTemplate" });
|
86
96
|
},
|
87
97
|
|
88
98
|
CallExpression(node) {
|
@@ -214,12 +214,12 @@ module.exports = {
|
|
214
214
|
) {
|
215
215
|
rightText = `${sourceCode.text.slice(operatorToken.range[1], node.right.range[0])}(${sourceCode.getText(node.right)})`;
|
216
216
|
} else {
|
217
|
-
const
|
217
|
+
const tokenAfterOperator = sourceCode.getTokenAfter(operatorToken, { includeComments: true });
|
218
218
|
let rightTextPrefix = "";
|
219
219
|
|
220
220
|
if (
|
221
|
-
operatorToken.range[1] ===
|
222
|
-
!astUtils.canTokensBeAdjacent({ type: "Punctuator", value: newOperator },
|
221
|
+
operatorToken.range[1] === tokenAfterOperator.range[0] &&
|
222
|
+
!astUtils.canTokensBeAdjacent({ type: "Punctuator", value: newOperator }, tokenAfterOperator)
|
223
223
|
) {
|
224
224
|
rightTextPrefix = " "; // foo+=+bar -> foo= foo+ +bar
|
225
225
|
}
|
@@ -172,10 +172,7 @@ module.exports = {
|
|
172
172
|
// lone operator
|
173
173
|
context.report({
|
174
174
|
node,
|
175
|
-
loc:
|
176
|
-
line: operatorToken.loc.end.line,
|
177
|
-
column: operatorToken.loc.end.column
|
178
|
-
},
|
175
|
+
loc: operatorToken.loc,
|
179
176
|
messageId: "badLinebreak",
|
180
177
|
data: {
|
181
178
|
operator
|
@@ -187,10 +184,7 @@ module.exports = {
|
|
187
184
|
|
188
185
|
context.report({
|
189
186
|
node,
|
190
|
-
loc:
|
191
|
-
line: operatorToken.loc.end.line,
|
192
|
-
column: operatorToken.loc.end.column
|
193
|
-
},
|
187
|
+
loc: operatorToken.loc,
|
194
188
|
messageId: "operatorAtBeginning",
|
195
189
|
data: {
|
196
190
|
operator
|
@@ -202,10 +196,7 @@ module.exports = {
|
|
202
196
|
|
203
197
|
context.report({
|
204
198
|
node,
|
205
|
-
loc:
|
206
|
-
line: operatorToken.loc.end.line,
|
207
|
-
column: operatorToken.loc.end.column
|
208
|
-
},
|
199
|
+
loc: operatorToken.loc,
|
209
200
|
messageId: "operatorAtEnd",
|
210
201
|
data: {
|
211
202
|
operator
|
@@ -217,10 +208,7 @@ module.exports = {
|
|
217
208
|
|
218
209
|
context.report({
|
219
210
|
node,
|
220
|
-
loc:
|
221
|
-
line: operatorToken.loc.end.line,
|
222
|
-
column: operatorToken.loc.end.column
|
223
|
-
},
|
211
|
+
loc: operatorToken.loc,
|
224
212
|
messageId: "noLinebreak",
|
225
213
|
data: {
|
226
214
|
operator
|