eslint 4.7.2 → 4.11.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 +123 -0
- package/README.md +34 -19
- package/conf/default-cli-options.js +7 -4
- package/conf/eslint-recommended.js +2 -0
- package/lib/ast-utils.js +83 -42
- package/lib/cli-engine.js +53 -17
- package/lib/cli.js +17 -9
- package/lib/code-path-analysis/code-path-analyzer.js +8 -4
- package/lib/code-path-analysis/code-path-segment.js +43 -41
- package/lib/code-path-analysis/code-path-state.js +7 -2
- package/lib/config/autoconfig.js +14 -12
- package/lib/config/config-file.js +8 -51
- package/lib/config/config-initializer.js +10 -6
- package/lib/config/config-ops.js +21 -21
- package/lib/config/config-rule.js +24 -24
- package/lib/config/config-validator.js +38 -36
- package/lib/config/plugins.js +8 -35
- package/lib/config.js +12 -8
- package/lib/formatters/html-template-message.html +1 -1
- package/lib/formatters/html-template-page.html +3 -1
- package/lib/formatters/html.js +2 -1
- package/lib/formatters/junit.js +21 -15
- package/lib/formatters/tap.js +5 -3
- package/lib/ignored-paths.js +5 -3
- package/lib/linter.js +42 -42
- package/lib/logging.js +2 -2
- package/lib/options.js +12 -0
- package/lib/rules/.eslintrc.yml +2 -2
- package/lib/rules/array-bracket-newline.js +39 -25
- package/lib/rules/array-bracket-spacing.js +28 -28
- package/lib/rules/array-callback-return.js +13 -9
- package/lib/rules/array-element-newline.js +8 -8
- package/lib/rules/arrow-body-style.js +12 -6
- package/lib/rules/arrow-parens.js +4 -2
- package/lib/rules/block-spacing.js +1 -1
- package/lib/rules/brace-style.js +14 -14
- package/lib/rules/callback-return.js +2 -1
- package/lib/rules/capitalized-comments.js +2 -1
- package/lib/rules/comma-style.js +3 -1
- package/lib/rules/computed-property-spacing.js +22 -22
- package/lib/rules/consistent-return.js +4 -4
- package/lib/rules/consistent-this.js +4 -2
- package/lib/rules/curly.js +13 -9
- package/lib/rules/dot-notation.js +56 -35
- package/lib/rules/func-call-spacing.js +4 -2
- package/lib/rules/generator-star-spacing.js +3 -3
- package/lib/rules/getter-return.js +2 -1
- package/lib/rules/indent-legacy.js +25 -14
- package/lib/rules/indent.js +101 -91
- package/lib/rules/key-spacing.js +5 -3
- package/lib/rules/lines-around-comment.js +33 -4
- package/lib/rules/lines-around-directive.js +16 -12
- package/lib/rules/lines-between-class-members.js +91 -0
- package/lib/rules/max-len.js +2 -3
- package/lib/rules/max-statements-per-line.js +5 -3
- package/lib/rules/multiline-comment-style.js +294 -0
- package/lib/rules/new-cap.js +2 -1
- package/lib/rules/newline-after-var.js +8 -6
- package/lib/rules/newline-before-return.js +13 -9
- package/lib/rules/no-alert.js +7 -15
- package/lib/rules/no-await-in-loop.js +17 -9
- package/lib/rules/no-bitwise.js +5 -3
- package/lib/rules/no-catch-shadow.js +4 -2
- package/lib/rules/no-console.js +2 -1
- package/lib/rules/no-constant-condition.js +2 -2
- package/lib/rules/no-control-regex.js +2 -1
- package/lib/rules/no-else-return.js +60 -19
- package/lib/rules/no-empty-character-class.js +11 -11
- package/lib/rules/no-extra-parens.js +22 -11
- package/lib/rules/no-extra-semi.js +5 -3
- package/lib/rules/no-global-assign.js +4 -2
- package/lib/rules/no-implicit-coercion.js +6 -6
- package/lib/rules/no-implied-eval.js +2 -1
- package/lib/rules/no-label-var.js +4 -2
- package/lib/rules/no-lone-blocks.js +3 -3
- package/lib/rules/no-lonely-if.js +2 -1
- package/lib/rules/no-loop-func.js +10 -7
- package/lib/rules/no-mixed-requires.js +8 -4
- package/lib/rules/no-native-reassign.js +4 -2
- package/lib/rules/no-param-reassign.js +4 -2
- package/lib/rules/no-regex-spaces.js +1 -1
- package/lib/rules/no-restricted-imports.js +86 -17
- package/lib/rules/no-restricted-modules.js +84 -15
- package/lib/rules/no-restricted-properties.js +10 -10
- package/lib/rules/no-return-await.js +6 -6
- package/lib/rules/no-self-assign.js +4 -2
- package/lib/rules/no-sequences.js +6 -4
- package/lib/rules/no-trailing-spaces.js +14 -8
- package/lib/rules/no-unneeded-ternary.js +3 -1
- package/lib/rules/no-unreachable.js +4 -2
- package/lib/rules/no-unused-labels.js +2 -1
- package/lib/rules/no-use-before-define.js +13 -11
- package/lib/rules/no-useless-call.js +1 -25
- package/lib/rules/no-useless-computed-key.js +2 -1
- package/lib/rules/no-useless-escape.js +31 -23
- package/lib/rules/no-useless-return.js +14 -8
- package/lib/rules/no-var.js +11 -0
- package/lib/rules/no-whitespace-before-property.js +4 -2
- package/lib/rules/object-curly-newline.js +9 -2
- package/lib/rules/object-curly-spacing.js +20 -20
- package/lib/rules/object-shorthand.js +47 -35
- package/lib/rules/operator-assignment.js +9 -9
- package/lib/rules/operator-linebreak.js +15 -11
- package/lib/rules/padding-line-between-statements.js +6 -4
- package/lib/rules/prefer-arrow-callback.js +12 -10
- package/lib/rules/prefer-const.js +18 -10
- package/lib/rules/prefer-destructuring.js +4 -2
- package/lib/rules/prefer-numeric-literals.js +4 -2
- package/lib/rules/prefer-promise-reject-errors.js +16 -16
- package/lib/rules/prefer-rest-params.js +4 -2
- package/lib/rules/prefer-spread.js +1 -25
- package/lib/rules/prefer-template.js +33 -29
- package/lib/rules/quote-props.js +8 -8
- package/lib/rules/require-jsdoc.js +11 -18
- package/lib/rules/semi-style.js +44 -19
- package/lib/rules/semi.js +5 -3
- package/lib/rules/sort-imports.js +11 -6
- package/lib/rules/space-unary-ops.js +67 -69
- package/lib/rules/strict.js +8 -8
- package/lib/rules/valid-jsdoc.js +39 -33
- package/lib/rules/valid-typeof.js +4 -4
- package/lib/rules/wrap-iife.js +4 -4
- package/lib/rules/yoda.js +9 -7
- package/lib/testers/rule-tester.js +63 -40
- package/lib/token-store/backward-token-cursor.js +5 -3
- package/lib/token-store/forward-token-cursor.js +5 -3
- package/lib/token-store/utils.js +8 -4
- package/lib/util/apply-disable-directives.js +56 -27
- package/lib/util/glob.js +1 -1
- package/lib/util/naming.js +112 -0
- package/lib/util/node-event-generator.js +13 -27
- package/lib/util/safe-emitter.js +54 -0
- package/lib/util/source-code-fixer.js +4 -2
- package/lib/util/source-code.js +70 -65
- package/messages/no-config-found.txt +1 -1
- package/package.json +8 -8
- package/lib/internal-rules/.eslintrc.yml +0 -3
- package/lib/internal-rules/internal-consistent-docs-description.js +0 -130
- package/lib/internal-rules/internal-no-invalid-meta.js +0 -188
@@ -96,8 +96,10 @@ module.exports = {
|
|
96
96
|
|
97
97
|
if (+(newPrefix + node.arguments[0].value) !== parseInt(node.arguments[0].value, node.arguments[1].value)) {
|
98
98
|
|
99
|
-
|
100
|
-
|
99
|
+
/*
|
100
|
+
* If the newly-produced literal would be invalid, (e.g. 0b1234),
|
101
|
+
* or it would yield an incorrect parseInt result for some other reason, don't make a fix.
|
102
|
+
*/
|
101
103
|
return null;
|
102
104
|
}
|
103
105
|
return fixer.replaceText(node, prefixMap[node.arguments[1].value] + node.arguments[0].value);
|
@@ -38,10 +38,10 @@ module.exports = {
|
|
38
38
|
//----------------------------------------------------------------------
|
39
39
|
|
40
40
|
/**
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
* Checks the argument of a reject() or Promise.reject() CallExpression, and reports it if it can't be an Error
|
42
|
+
* @param {ASTNode} callExpression A CallExpression node which is used to reject a Promise
|
43
|
+
* @returns {void}
|
44
|
+
*/
|
45
45
|
function checkRejectCall(callExpression) {
|
46
46
|
if (!callExpression.arguments.length && ALLOW_EMPTY_REJECT) {
|
47
47
|
return;
|
@@ -59,10 +59,10 @@ module.exports = {
|
|
59
59
|
}
|
60
60
|
|
61
61
|
/**
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
62
|
+
* Determines whether a function call is a Promise.reject() call
|
63
|
+
* @param {ASTNode} node A CallExpression node
|
64
|
+
* @returns {boolean} `true` if the call is a Promise.reject() call
|
65
|
+
*/
|
66
66
|
function isPromiseRejectCall(node) {
|
67
67
|
return node.callee.type === "MemberExpression" &&
|
68
68
|
node.callee.object.type === "Identifier" && node.callee.object.name === "Promise" &&
|
@@ -96,14 +96,14 @@ module.exports = {
|
|
96
96
|
context.getDeclaredVariables(node.arguments[0])
|
97
97
|
|
98
98
|
/*
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
99
|
+
* Find the first variable that matches the second parameter's name.
|
100
|
+
* If the first parameter has the same name as the second parameter, then the variable will actually
|
101
|
+
* be "declared" when the first parameter is evaluated, but then it will be immediately overwritten
|
102
|
+
* by the second parameter. It's not possible for an expression with the variable to be evaluated before
|
103
|
+
* the variable is overwritten, because functions with duplicate parameters cannot have destructuring or
|
104
|
+
* default assignments in their parameter lists. Therefore, it's not necessary to explicitly account for
|
105
|
+
* this case.
|
106
|
+
*/
|
107
107
|
.find(variable => variable.name === node.arguments[0].params[1].name)
|
108
108
|
|
109
109
|
// Get the references to that variable.
|
@@ -22,8 +22,10 @@ function getVariableOfArguments(scope) {
|
|
22
22
|
|
23
23
|
if (variable.name === "arguments") {
|
24
24
|
|
25
|
-
|
26
|
-
|
25
|
+
/*
|
26
|
+
* If there was a parameter which is named "arguments", the implicit "arguments" is not defined.
|
27
|
+
* So does fast return with null.
|
28
|
+
*/
|
27
29
|
return (variable.identifiers.length === 0) ? variable : null;
|
28
30
|
}
|
29
31
|
}
|
@@ -28,30 +28,6 @@ function isVariadicApplyCalling(node) {
|
|
28
28
|
);
|
29
29
|
}
|
30
30
|
|
31
|
-
/**
|
32
|
-
* Checks whether or not the tokens of two given nodes are same.
|
33
|
-
* @param {ASTNode} left - A node 1 to compare.
|
34
|
-
* @param {ASTNode} right - A node 2 to compare.
|
35
|
-
* @param {SourceCode} sourceCode - The ESLint source code object.
|
36
|
-
* @returns {boolean} the source code for the given node.
|
37
|
-
*/
|
38
|
-
function equalTokens(left, right, sourceCode) {
|
39
|
-
const tokensL = sourceCode.getTokens(left);
|
40
|
-
const tokensR = sourceCode.getTokens(right);
|
41
|
-
|
42
|
-
if (tokensL.length !== tokensR.length) {
|
43
|
-
return false;
|
44
|
-
}
|
45
|
-
for (let i = 0; i < tokensL.length; ++i) {
|
46
|
-
if (tokensL[i].type !== tokensR[i].type ||
|
47
|
-
tokensL[i].value !== tokensR[i].value
|
48
|
-
) {
|
49
|
-
return false;
|
50
|
-
}
|
51
|
-
}
|
52
|
-
|
53
|
-
return true;
|
54
|
-
}
|
55
31
|
|
56
32
|
/**
|
57
33
|
* Checks whether or not `thisArg` is not changed by `.apply()`.
|
@@ -64,7 +40,7 @@ function isValidThisArg(expectedThis, thisArg, context) {
|
|
64
40
|
if (!expectedThis) {
|
65
41
|
return astUtils.isNullOrUndefined(thisArg);
|
66
42
|
}
|
67
|
-
return equalTokens(expectedThis, thisArg, context);
|
43
|
+
return astUtils.equalTokens(expectedThis, thisArg, context);
|
68
44
|
}
|
69
45
|
|
70
46
|
//------------------------------------------------------------------------------
|
@@ -37,10 +37,10 @@ function getTopConcatBinaryExpression(node) {
|
|
37
37
|
}
|
38
38
|
|
39
39
|
/**
|
40
|
-
* Checks whether or not a given binary expression has string literals.
|
41
|
-
* @param {ASTNode} node - A node to check.
|
42
|
-
* @returns {boolean} `true` if the node has string literals.
|
43
|
-
*/
|
40
|
+
* Checks whether or not a given binary expression has string literals.
|
41
|
+
* @param {ASTNode} node - A node to check.
|
42
|
+
* @returns {boolean} `true` if the node has string literals.
|
43
|
+
*/
|
44
44
|
function hasStringLiteral(node) {
|
45
45
|
if (isConcatenation(node)) {
|
46
46
|
|
@@ -65,10 +65,10 @@ function hasNonStringLiteral(node) {
|
|
65
65
|
}
|
66
66
|
|
67
67
|
/**
|
68
|
-
* Determines whether a given node will start with a template curly expression (`${}`) when being converted to a template literal.
|
69
|
-
* @param {ASTNode} node The node that will be fixed to a template literal
|
70
|
-
* @returns {boolean} `true` if the node will start with a template curly.
|
71
|
-
*/
|
68
|
+
* Determines whether a given node will start with a template curly expression (`${}`) when being converted to a template literal.
|
69
|
+
* @param {ASTNode} node The node that will be fixed to a template literal
|
70
|
+
* @returns {boolean} `true` if the node will start with a template curly.
|
71
|
+
*/
|
72
72
|
function startsWithTemplateCurly(node) {
|
73
73
|
if (node.type === "BinaryExpression") {
|
74
74
|
return startsWithTemplateCurly(node.left);
|
@@ -80,10 +80,10 @@ function startsWithTemplateCurly(node) {
|
|
80
80
|
}
|
81
81
|
|
82
82
|
/**
|
83
|
-
* Determines whether a given node end with a template curly expression (`${}`) when being converted to a template literal.
|
84
|
-
* @param {ASTNode} node The node that will be fixed to a template literal
|
85
|
-
* @returns {boolean} `true` if the node will end with a template curly.
|
86
|
-
*/
|
83
|
+
* Determines whether a given node end with a template curly expression (`${}`) when being converted to a template literal.
|
84
|
+
* @param {ASTNode} node The node that will be fixed to a template literal
|
85
|
+
* @returns {boolean} `true` if the node will end with a template curly.
|
86
|
+
*/
|
87
87
|
function endsWithTemplateCurly(node) {
|
88
88
|
if (node.type === "BinaryExpression") {
|
89
89
|
return startsWithTemplateCurly(node.right);
|
@@ -116,11 +116,11 @@ module.exports = {
|
|
116
116
|
let done = Object.create(null);
|
117
117
|
|
118
118
|
/**
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
119
|
+
* Gets the non-token text between two nodes, ignoring any other tokens that appear between the two tokens.
|
120
|
+
* @param {ASTNode} node1 The first node
|
121
|
+
* @param {ASTNode} node2 The second node
|
122
|
+
* @returns {string} The text between the nodes, excluding other tokens
|
123
|
+
*/
|
124
124
|
function getTextBetween(node1, node2) {
|
125
125
|
const allTokens = [node1].concat(sourceCode.getTokensBetween(node1, node2)).concat(node2);
|
126
126
|
const sourceText = sourceCode.getText();
|
@@ -129,19 +129,21 @@ module.exports = {
|
|
129
129
|
}
|
130
130
|
|
131
131
|
/**
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
132
|
+
* Returns a template literal form of the given node.
|
133
|
+
* @param {ASTNode} currentNode A node that should be converted to a template literal
|
134
|
+
* @param {string} textBeforeNode Text that should appear before the node
|
135
|
+
* @param {string} textAfterNode Text that should appear after the node
|
136
|
+
* @returns {string} A string form of this node, represented as a template literal
|
137
|
+
*/
|
138
138
|
function getTemplateLiteral(currentNode, textBeforeNode, textAfterNode) {
|
139
139
|
if (currentNode.type === "Literal" && typeof currentNode.value === "string") {
|
140
140
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
141
|
+
/*
|
142
|
+
* If the current node is a string literal, escape any instances of ${ or ` to prevent them from being interpreted
|
143
|
+
* as a template placeholder. However, if the code already contains a backslash before the ${ or `
|
144
|
+
* for some reason, don't add another backslash, because that would change the meaning of the code (it would cause
|
145
|
+
* an actual backslash character to appear before the dollar sign).
|
146
|
+
*/
|
145
147
|
return `\`${currentNode.raw.slice(1, -1).replace(/\\*(\${|`)/g, matched => {
|
146
148
|
if (matched.lastIndexOf("\\") % 2) {
|
147
149
|
return `\\${matched}`;
|
@@ -178,8 +180,10 @@ module.exports = {
|
|
178
180
|
getTemplateLiteral(currentNode.right, textBeforePlus + textAfterPlus, textAfterNode).slice(1);
|
179
181
|
}
|
180
182
|
|
181
|
-
|
182
|
-
|
183
|
+
/*
|
184
|
+
* Otherwise, these nodes should not be combined into a template curly, since there is nowhere to put
|
185
|
+
* the text between them.
|
186
|
+
*/
|
183
187
|
return `${getTemplateLiteral(currentNode.left, textBeforeNode, null)}${textBeforePlus}+${textAfterPlus}${getTemplateLiteral(currentNode.right, textAfterNode, null)}`;
|
184
188
|
}
|
185
189
|
|
package/lib/rules/quote-props.js
CHANGED
@@ -104,19 +104,19 @@ module.exports = {
|
|
104
104
|
}
|
105
105
|
|
106
106
|
/**
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
107
|
+
* Returns a string representation of a property node with quotes removed
|
108
|
+
* @param {ASTNode} key Key AST Node, which may or may not be quoted
|
109
|
+
* @returns {string} A replacement string for this property
|
110
|
+
*/
|
111
111
|
function getUnquotedKey(key) {
|
112
112
|
return key.type === "Identifier" ? key.name : key.value;
|
113
113
|
}
|
114
114
|
|
115
115
|
/**
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
116
|
+
* Returns a string representation of a property node with quotes added
|
117
|
+
* @param {ASTNode} key Key AST Node, which may or may not be quoted
|
118
|
+
* @returns {string} A replacement string for this property
|
119
|
+
*/
|
120
120
|
function getQuotedKey(key) {
|
121
121
|
if (key.type === "Literal" && typeof key.value === "string") {
|
122
122
|
|
@@ -30,6 +30,9 @@ module.exports = {
|
|
30
30
|
},
|
31
31
|
ArrowFunctionExpression: {
|
32
32
|
type: "boolean"
|
33
|
+
},
|
34
|
+
FunctionExpression: {
|
35
|
+
type: "boolean"
|
33
36
|
}
|
34
37
|
},
|
35
38
|
additionalProperties: false
|
@@ -45,7 +48,9 @@ module.exports = {
|
|
45
48
|
const DEFAULT_OPTIONS = {
|
46
49
|
FunctionDeclaration: true,
|
47
50
|
MethodDefinition: false,
|
48
|
-
ClassDeclaration: false
|
51
|
+
ClassDeclaration: false,
|
52
|
+
ArrowFunctionExpression: false,
|
53
|
+
FunctionExpression: false
|
49
54
|
};
|
50
55
|
const options = Object.assign(DEFAULT_OPTIONS, context.options[0] && context.options[0].require || {});
|
51
56
|
|
@@ -58,21 +63,6 @@ module.exports = {
|
|
58
63
|
context.report({ node, message: "Missing JSDoc comment." });
|
59
64
|
}
|
60
65
|
|
61
|
-
/**
|
62
|
-
* Check if the jsdoc comment is present for class methods
|
63
|
-
* @param {ASTNode} node node to examine
|
64
|
-
* @returns {void}
|
65
|
-
*/
|
66
|
-
function checkClassMethodJsDoc(node) {
|
67
|
-
if (node.parent.type === "MethodDefinition") {
|
68
|
-
const jsdocComment = source.getJSDocComment(node);
|
69
|
-
|
70
|
-
if (!jsdocComment) {
|
71
|
-
report(node);
|
72
|
-
}
|
73
|
-
}
|
74
|
-
}
|
75
|
-
|
76
66
|
/**
|
77
67
|
* Check if the jsdoc comment is present or not.
|
78
68
|
* @param {ASTNode} node node to examine
|
@@ -93,8 +83,11 @@ module.exports = {
|
|
93
83
|
}
|
94
84
|
},
|
95
85
|
FunctionExpression(node) {
|
96
|
-
if (
|
97
|
-
|
86
|
+
if (
|
87
|
+
(options.MethodDefinition && node.parent.type === "MethodDefinition") ||
|
88
|
+
(options.FunctionExpression && (node.parent.type === "VariableDeclarator" || (node.parent.type === "Property" && node === node.parent.value)))
|
89
|
+
) {
|
90
|
+
checkJsDoc(node);
|
98
91
|
}
|
99
92
|
},
|
100
93
|
ClassDeclaration(node) {
|
package/lib/rules/semi-style.js
CHANGED
@@ -18,13 +18,51 @@ const astUtils = require("../ast-utils");
|
|
18
18
|
const SELECTOR = `:matches(${
|
19
19
|
[
|
20
20
|
"BreakStatement", "ContinueStatement", "DebuggerStatement",
|
21
|
-
"DoWhileStatement", "
|
21
|
+
"DoWhileStatement", "ExportAllDeclaration",
|
22
22
|
"ExportDefaultDeclaration", "ExportNamedDeclaration",
|
23
23
|
"ExpressionStatement", "ImportDeclaration", "ReturnStatement",
|
24
24
|
"ThrowStatement", "VariableDeclaration"
|
25
25
|
].join(",")
|
26
26
|
})`;
|
27
27
|
|
28
|
+
/**
|
29
|
+
* Get the child node list of a given node.
|
30
|
+
* This returns `Program#body`, `BlockStatement#body`, or `SwitchCase#consequent`.
|
31
|
+
* This is used to check whether a node is the first/last child.
|
32
|
+
* @param {Node} node A node to get child node list.
|
33
|
+
* @returns {Node[]|null} The child node list.
|
34
|
+
*/
|
35
|
+
function getChildren(node) {
|
36
|
+
const t = node.type;
|
37
|
+
|
38
|
+
if (t === "BlockStatement" || t === "Program") {
|
39
|
+
return node.body;
|
40
|
+
}
|
41
|
+
if (t === "SwitchCase") {
|
42
|
+
return node.consequent;
|
43
|
+
}
|
44
|
+
return null;
|
45
|
+
}
|
46
|
+
|
47
|
+
/**
|
48
|
+
* Check whether a given node is the last statement in the parent block.
|
49
|
+
* @param {Node} node A node to check.
|
50
|
+
* @returns {boolean} `true` if the node is the last statement in the parent block.
|
51
|
+
*/
|
52
|
+
function isLastChild(node) {
|
53
|
+
const t = node.parent.type;
|
54
|
+
|
55
|
+
if (t === "IfStatement" && node.parent.consequent === node && node.parent.alternate) { // before `else` keyword.
|
56
|
+
return true;
|
57
|
+
}
|
58
|
+
if (t === "DoWhileStatement") { // before `while` keyword.
|
59
|
+
return true;
|
60
|
+
}
|
61
|
+
const nodeList = getChildren(node.parent);
|
62
|
+
|
63
|
+
return nodeList !== null && nodeList[nodeList.length - 1] === node; // before `}` or etc.
|
64
|
+
}
|
65
|
+
|
28
66
|
module.exports = {
|
29
67
|
meta: {
|
30
68
|
docs: {
|
@@ -40,23 +78,6 @@ module.exports = {
|
|
40
78
|
const sourceCode = context.getSourceCode();
|
41
79
|
const option = context.options[0] || "last";
|
42
80
|
|
43
|
-
/**
|
44
|
-
* Check whether comments exist between the given 2 tokens.
|
45
|
-
* @param {Token} left The left token to check.
|
46
|
-
* @param {Token} right The right token to check.
|
47
|
-
* @returns {boolean} `true` if comments exist between the given 2 tokens.
|
48
|
-
*/
|
49
|
-
function commentsExistBetween(left, right) {
|
50
|
-
return sourceCode.getFirstTokenBetween(
|
51
|
-
left,
|
52
|
-
right,
|
53
|
-
{
|
54
|
-
includeComments: true,
|
55
|
-
filter: astUtils.isCommentToken
|
56
|
-
}
|
57
|
-
) !== null;
|
58
|
-
}
|
59
|
-
|
60
81
|
/**
|
61
82
|
* Check the given semicolon token.
|
62
83
|
* @param {Token} semiToken The semicolon token to check.
|
@@ -79,7 +100,7 @@ module.exports = {
|
|
79
100
|
: "the beginning of the next line"
|
80
101
|
},
|
81
102
|
fix(fixer) {
|
82
|
-
if (prevToken && nextToken && commentsExistBetween(prevToken, nextToken)) {
|
103
|
+
if (prevToken && nextToken && sourceCode.commentsExistBetween(prevToken, nextToken)) {
|
83
104
|
return null;
|
84
105
|
}
|
85
106
|
|
@@ -95,6 +116,10 @@ module.exports = {
|
|
95
116
|
|
96
117
|
return {
|
97
118
|
[SELECTOR](node) {
|
119
|
+
if (option === "first" && isLastChild(node)) {
|
120
|
+
return;
|
121
|
+
}
|
122
|
+
|
98
123
|
const lastToken = sourceCode.getLastToken(node);
|
99
124
|
|
100
125
|
if (astUtils.isSemicolonToken(lastToken)) {
|
package/lib/rules/semi.js
CHANGED
@@ -93,9 +93,11 @@ module.exports = {
|
|
93
93
|
loc = loc.start;
|
94
94
|
fix = function(fixer) {
|
95
95
|
|
96
|
-
|
97
|
-
|
98
|
-
|
96
|
+
/*
|
97
|
+
* Expand the replacement range to include the surrounding
|
98
|
+
* tokens to avoid conflicting with no-extra-semi.
|
99
|
+
* https://github.com/eslint/eslint/issues/7928
|
100
|
+
*/
|
99
101
|
return new FixTracker(fixer, sourceCode)
|
100
102
|
.retainSurroundingTokens(lastToken)
|
101
103
|
.remove(lastToken);
|
@@ -67,9 +67,11 @@ module.exports = {
|
|
67
67
|
function usedMemberSyntax(node) {
|
68
68
|
if (node.specifiers.length === 0) {
|
69
69
|
return "none";
|
70
|
-
}
|
70
|
+
}
|
71
|
+
if (node.specifiers[0].type === "ImportNamespaceSpecifier") {
|
71
72
|
return "all";
|
72
|
-
}
|
73
|
+
}
|
74
|
+
if (node.specifiers.length === 1) {
|
73
75
|
return "single";
|
74
76
|
}
|
75
77
|
return "multiple";
|
@@ -111,9 +113,11 @@ module.exports = {
|
|
111
113
|
currentLocalMemberName = currentLocalMemberName && currentLocalMemberName.toLowerCase();
|
112
114
|
}
|
113
115
|
|
114
|
-
|
115
|
-
|
116
|
-
|
116
|
+
/*
|
117
|
+
* When the current declaration uses a different member syntax,
|
118
|
+
* then check if the ordering is correct.
|
119
|
+
* Otherwise, make a default string compare (like rule sort-vars to be consistent) of the first used local member name.
|
120
|
+
*/
|
117
121
|
if (currentMemberSyntaxGroupIndex !== previousMemberSyntaxGroupIndex) {
|
118
122
|
if (currentMemberSyntaxGroupIndex < previousMemberSyntaxGroupIndex) {
|
119
123
|
context.report({
|
@@ -149,7 +153,8 @@ module.exports = {
|
|
149
153
|
message: "Member '{{memberName}}' of the import declaration should be sorted alphabetically.",
|
150
154
|
data: { memberName: importSpecifiers[firstUnsortedIndex].local.name },
|
151
155
|
fix(fixer) {
|
152
|
-
if (importSpecifiers.some(specifier =>
|
156
|
+
if (importSpecifiers.some(specifier =>
|
157
|
+
sourceCode.getCommentsBefore(specifier).length || sourceCode.getCommentsAfter(specifier).length)) {
|
153
158
|
|
154
159
|
// If there are comments in the ImportSpecifier list, don't rearrange the specifiers.
|
155
160
|
return null;
|