eslint 3.14.0 → 3.16.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 +68 -0
- package/README.md +1 -1
- package/conf/{eslint.json → eslint-recommended.js} +86 -71
- package/lib/ast-utils.js +192 -24
- package/lib/cli.js +2 -2
- package/lib/code-path-analysis/code-path-state.js +2 -2
- package/lib/config/autoconfig.js +3 -3
- package/lib/config/config-file.js +31 -24
- package/lib/config/config-initializer.js +1 -1
- package/lib/config/config-validator.js +6 -6
- package/lib/config.js +3 -2
- package/lib/eslint.js +18 -18
- package/lib/formatters/checkstyle.js +2 -2
- package/lib/formatters/compact.js +2 -2
- package/lib/formatters/junit.js +2 -2
- package/lib/formatters/tap.js +2 -2
- package/lib/formatters/unix.js +2 -2
- package/lib/formatters/visualstudio.js +2 -2
- package/lib/rules/arrow-body-style.js +7 -4
- package/lib/rules/arrow-spacing.js +7 -6
- package/lib/rules/block-spacing.js +2 -2
- package/lib/rules/brace-style.js +42 -22
- package/lib/rules/capitalized-comments.js +6 -6
- package/lib/rules/comma-spacing.js +16 -16
- package/lib/rules/consistent-return.js +1 -1
- package/lib/rules/constructor-super.js +3 -3
- package/lib/rules/curly.js +11 -7
- package/lib/rules/default-case.js +3 -3
- package/lib/rules/eqeqeq.js +15 -6
- package/lib/rules/func-call-spacing.js +10 -13
- package/lib/rules/func-name-matching.js +1 -1
- package/lib/rules/generator-star-spacing.js +18 -19
- package/lib/rules/global-require.js +2 -2
- package/lib/rules/id-blacklist.js +2 -2
- package/lib/rules/id-length.js +3 -3
- package/lib/rules/id-match.js +2 -2
- package/lib/rules/indent.js +21 -20
- package/lib/rules/key-spacing.js +20 -23
- package/lib/rules/keyword-spacing.js +2 -13
- package/lib/rules/line-comment-position.js +1 -1
- package/lib/rules/linebreak-style.js +7 -1
- package/lib/rules/lines-around-comment.js +4 -4
- package/lib/rules/lines-around-directive.js +3 -3
- package/lib/rules/max-lines.js +2 -2
- package/lib/rules/max-statements-per-line.js +7 -6
- package/lib/rules/new-cap.js +2 -2
- package/lib/rules/newline-after-var.js +7 -2
- package/lib/rules/newline-before-return.js +2 -2
- package/lib/rules/newline-per-chained-call.js +3 -1
- package/lib/rules/no-cond-assign.js +3 -3
- package/lib/rules/no-extend-native.js +3 -3
- package/lib/rules/no-extra-bind.js +3 -4
- package/lib/rules/no-extra-boolean-cast.js +8 -0
- package/lib/rules/no-extra-parens.js +29 -8
- package/lib/rules/no-inner-declarations.js +4 -4
- package/lib/rules/no-irregular-whitespace.js +7 -1
- package/lib/rules/no-lone-blocks.js +10 -10
- package/lib/rules/no-mixed-operators.js +1 -7
- package/lib/rules/no-mixed-requires.js +4 -4
- package/lib/rules/no-multi-spaces.js +4 -1
- package/lib/rules/no-multi-str.js +7 -3
- package/lib/rules/no-redeclare.js +7 -7
- package/lib/rules/no-return-assign.js +7 -14
- package/lib/rules/no-sequences.js +7 -6
- package/lib/rules/no-trailing-spaces.js +8 -2
- package/lib/rules/no-undefined.js +45 -6
- package/lib/rules/no-unexpected-multiline.js +9 -8
- package/lib/rules/no-unneeded-ternary.js +5 -1
- package/lib/rules/no-unused-labels.js +17 -2
- package/lib/rules/no-unused-vars.js +34 -19
- package/lib/rules/no-use-before-define.js +33 -29
- package/lib/rules/no-useless-computed-key.js +8 -3
- package/lib/rules/no-useless-concat.js +10 -7
- package/lib/rules/no-useless-escape.js +1 -1
- package/lib/rules/no-useless-return.js +1 -7
- package/lib/rules/no-var.js +11 -0
- package/lib/rules/no-whitespace-before-property.js +5 -16
- package/lib/rules/object-curly-newline.js +2 -2
- package/lib/rules/object-curly-spacing.js +7 -25
- package/lib/rules/object-property-newline.js +3 -3
- package/lib/rules/object-shorthand.js +10 -10
- package/lib/rules/operator-assignment.js +2 -2
- package/lib/rules/operator-linebreak.js +8 -10
- package/lib/rules/padded-blocks.js +7 -4
- package/lib/rules/prefer-spread.js +1 -1
- package/lib/rules/prefer-template.js +1 -1
- package/lib/rules/quotes.js +10 -6
- package/lib/rules/semi-spacing.js +4 -0
- package/lib/rules/sort-imports.js +4 -4
- package/lib/rules/sort-vars.js +2 -2
- package/lib/rules/space-before-function-paren.js +8 -5
- package/lib/rules/space-in-parens.js +8 -8
- package/lib/rules/spaced-comment.js +10 -10
- package/lib/rules/strict.js +2 -2
- package/lib/rules/template-tag-spacing.js +77 -0
- package/lib/rules/unicode-bom.js +1 -1
- package/lib/rules/wrap-iife.js +5 -5
- package/lib/rules/yoda.js +2 -7
- package/lib/rules.js +2 -2
- package/lib/testers/rule-tester.js +25 -18
- package/lib/token-store/backward-token-comment-cursor.js +57 -0
- package/lib/token-store/backward-token-cursor.js +56 -0
- package/lib/token-store/cursor.js +76 -0
- package/lib/token-store/cursors.js +92 -0
- package/lib/token-store/decorative-cursor.js +39 -0
- package/lib/token-store/filter-cursor.js +43 -0
- package/lib/token-store/forward-token-comment-cursor.js +57 -0
- package/lib/token-store/forward-token-cursor.js +61 -0
- package/lib/token-store/index.js +604 -0
- package/lib/token-store/limit-cursor.js +40 -0
- package/lib/token-store/padded-token-cursor.js +38 -0
- package/lib/token-store/skip-cursor.js +42 -0
- package/lib/token-store/utils.js +100 -0
- package/lib/util/glob.js +1 -1
- package/lib/util/source-code-fixer.js +46 -44
- package/lib/util/source-code.js +35 -19
- package/messages/extend-config-missing.txt +3 -0
- package/package.json +3 -3
- package/lib/token-store.js +0 -203
@@ -23,7 +23,7 @@ const fs = require("fs"),
|
|
23
23
|
stripBom = require("strip-bom"),
|
24
24
|
stripComments = require("strip-json-comments"),
|
25
25
|
stringify = require("json-stable-stringify"),
|
26
|
-
defaultOptions = require("../../conf/eslint
|
26
|
+
defaultOptions = require("../../conf/eslint-recommended"),
|
27
27
|
requireUncached = require("require-uncached");
|
28
28
|
|
29
29
|
const debug = require("debug")("eslint:config-file");
|
@@ -364,10 +364,10 @@ function applyExtends(config, filePath, relativeTo) {
|
|
364
364
|
if (parentPath === "eslint:recommended") {
|
365
365
|
|
366
366
|
/*
|
367
|
-
* Add an explicit substitution for eslint:recommended to
|
368
|
-
*
|
367
|
+
* Add an explicit substitution for eslint:recommended to
|
368
|
+
* conf/eslint-recommended.js.
|
369
369
|
*/
|
370
|
-
parentPath = path.resolve(__dirname, "../../conf/eslint.
|
370
|
+
parentPath = path.resolve(__dirname, "../../conf/eslint-recommended.js");
|
371
371
|
} else if (parentPath === "eslint:all") {
|
372
372
|
|
373
373
|
/*
|
@@ -380,9 +380,9 @@ function applyExtends(config, filePath, relativeTo) {
|
|
380
380
|
* If the `extends` path is relative, use the directory of the current configuration
|
381
381
|
* file as the reference point. Otherwise, use as-is.
|
382
382
|
*/
|
383
|
-
parentPath = (!path.isAbsolute(parentPath)
|
384
|
-
path.join(relativeTo || path.dirname(filePath), parentPath)
|
385
|
-
parentPath
|
383
|
+
parentPath = (!path.isAbsolute(parentPath)
|
384
|
+
? path.join(relativeTo || path.dirname(filePath), parentPath)
|
385
|
+
: parentPath
|
386
386
|
);
|
387
387
|
}
|
388
388
|
|
@@ -390,6 +390,13 @@ function applyExtends(config, filePath, relativeTo) {
|
|
390
390
|
debug(`Loading ${parentPath}`);
|
391
391
|
return ConfigOps.merge(load(parentPath, false, relativeTo), previousValue);
|
392
392
|
} catch (e) {
|
393
|
+
if (parentPath.indexOf("plugin:") === 0 || parentPath.indexOf("eslint:") === 0) {
|
394
|
+
e.message = `Failed to load config "${parentPath}" to extend from.`;
|
395
|
+
e.messageTemplate = "extend-config-missing";
|
396
|
+
e.messageData = {
|
397
|
+
configName: parentPath
|
398
|
+
};
|
399
|
+
}
|
393
400
|
|
394
401
|
/*
|
395
402
|
* If the file referenced by `extends` failed to load, add the path
|
@@ -461,24 +468,24 @@ function normalizePackageName(name, prefix) {
|
|
461
468
|
function resolve(filePath, relativeTo) {
|
462
469
|
if (isFilePath(filePath)) {
|
463
470
|
return { filePath: path.resolve(relativeTo || "", filePath) };
|
464
|
-
} else {
|
465
|
-
let normalizedPackageName;
|
466
|
-
|
467
|
-
if (filePath.indexOf("plugin:") === 0) {
|
468
|
-
const packagePath = filePath.substr(7, filePath.lastIndexOf("/") - 7);
|
469
|
-
const configName = filePath.substr(filePath.lastIndexOf("/") + 1, filePath.length - filePath.lastIndexOf("/") - 1);
|
470
|
-
|
471
|
-
normalizedPackageName = normalizePackageName(packagePath, "eslint-plugin");
|
472
|
-
debug(`Attempting to resolve ${normalizedPackageName}`);
|
473
|
-
filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo));
|
474
|
-
return { filePath, configName };
|
475
|
-
} else {
|
476
|
-
normalizedPackageName = normalizePackageName(filePath, "eslint-config");
|
477
|
-
debug(`Attempting to resolve ${normalizedPackageName}`);
|
478
|
-
filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo));
|
479
|
-
return { filePath };
|
480
|
-
}
|
481
471
|
}
|
472
|
+
let normalizedPackageName;
|
473
|
+
|
474
|
+
if (filePath.indexOf("plugin:") === 0) {
|
475
|
+
const packagePath = filePath.substr(7, filePath.lastIndexOf("/") - 7);
|
476
|
+
const configName = filePath.substr(filePath.lastIndexOf("/") + 1, filePath.length - filePath.lastIndexOf("/") - 1);
|
477
|
+
|
478
|
+
normalizedPackageName = normalizePackageName(packagePath, "eslint-plugin");
|
479
|
+
debug(`Attempting to resolve ${normalizedPackageName}`);
|
480
|
+
filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo));
|
481
|
+
return { filePath, configName };
|
482
|
+
}
|
483
|
+
normalizedPackageName = normalizePackageName(filePath, "eslint-config");
|
484
|
+
debug(`Attempting to resolve ${normalizedPackageName}`);
|
485
|
+
filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo));
|
486
|
+
return { filePath };
|
487
|
+
|
488
|
+
|
482
489
|
|
483
490
|
}
|
484
491
|
|
@@ -17,7 +17,7 @@ const util = require("util"),
|
|
17
17
|
ConfigOps = require("./config-ops"),
|
18
18
|
getSourceCodeOfFiles = require("../util/source-code-util").getSourceCodeOfFiles,
|
19
19
|
npmUtil = require("../util/npm-util"),
|
20
|
-
recConfig = require("../../conf/eslint
|
20
|
+
recConfig = require("../../conf/eslint-recommended"),
|
21
21
|
log = require("../logging");
|
22
22
|
|
23
23
|
const debug = require("debug")("eslint:config-initializer");
|
@@ -40,13 +40,13 @@ function getRuleOptionsSchema(id) {
|
|
40
40
|
minItems: 0,
|
41
41
|
maxItems: schema.length
|
42
42
|
};
|
43
|
-
} else {
|
44
|
-
return {
|
45
|
-
type: "array",
|
46
|
-
minItems: 0,
|
47
|
-
maxItems: 0
|
48
|
-
};
|
49
43
|
}
|
44
|
+
return {
|
45
|
+
type: "array",
|
46
|
+
minItems: 0,
|
47
|
+
maxItems: 0
|
48
|
+
};
|
49
|
+
|
50
50
|
}
|
51
51
|
|
52
52
|
// Given a full schema, leave it alone
|
package/lib/config.js
CHANGED
@@ -234,8 +234,9 @@ class Config {
|
|
234
234
|
}
|
235
235
|
|
236
236
|
/**
|
237
|
-
* Build a config object merging the base config (conf/eslint
|
238
|
-
* environments config (conf/environments.js) and eventually the user
|
237
|
+
* Build a config object merging the base config (conf/eslint-recommended),
|
238
|
+
* the environments config (conf/environments.js) and eventually the user
|
239
|
+
* config.
|
239
240
|
* @param {string} filePath a file in whose directory we start looking for a local config
|
240
241
|
* @returns {Object} config object
|
241
242
|
*/
|
package/lib/eslint.js
CHANGED
@@ -14,7 +14,7 @@ const assert = require("assert"),
|
|
14
14
|
escope = require("escope"),
|
15
15
|
levn = require("levn"),
|
16
16
|
blankScriptAST = require("../conf/blank-script.json"),
|
17
|
-
DEFAULT_PARSER = require("../conf/eslint
|
17
|
+
DEFAULT_PARSER = require("../conf/eslint-recommended").parser,
|
18
18
|
replacements = require("../conf/replacements.json"),
|
19
19
|
CodePathAnalyzer = require("./code-path-analysis/code-path-analyzer"),
|
20
20
|
ConfigOps = require("./config/config-ops"),
|
@@ -528,9 +528,9 @@ function createStubRule(message) {
|
|
528
528
|
|
529
529
|
if (message) {
|
530
530
|
return createRuleModule;
|
531
|
-
} else {
|
532
|
-
throw new Error("No message passed to stub rule");
|
533
531
|
}
|
532
|
+
throw new Error("No message passed to stub rule");
|
533
|
+
|
534
534
|
}
|
535
535
|
|
536
536
|
/**
|
@@ -660,9 +660,9 @@ module.exports = (function() {
|
|
660
660
|
try {
|
661
661
|
if (typeof parser.parseForESLint === "function") {
|
662
662
|
return parser.parseForESLint(text, parserOptions);
|
663
|
-
} else {
|
664
|
-
return parser.parse(text, parserOptions);
|
665
663
|
}
|
664
|
+
return parser.parse(text, parserOptions);
|
665
|
+
|
666
666
|
} catch (ex) {
|
667
667
|
|
668
668
|
// If the message includes a leading line number, strip it:
|
@@ -695,9 +695,9 @@ module.exports = (function() {
|
|
695
695
|
return ruleConfig;
|
696
696
|
} else if (Array.isArray(ruleConfig)) {
|
697
697
|
return ruleConfig[0];
|
698
|
-
} else {
|
699
|
-
return 0;
|
700
698
|
}
|
699
|
+
return 0;
|
700
|
+
|
701
701
|
}
|
702
702
|
|
703
703
|
/**
|
@@ -708,9 +708,9 @@ module.exports = (function() {
|
|
708
708
|
function getRuleOptions(ruleConfig) {
|
709
709
|
if (Array.isArray(ruleConfig)) {
|
710
710
|
return ruleConfig.slice(1);
|
711
|
-
} else {
|
712
|
-
return [];
|
713
711
|
}
|
712
|
+
return [];
|
713
|
+
|
714
714
|
}
|
715
715
|
|
716
716
|
// set unlimited listeners (see https://github.com/eslint/eslint/issues/524)
|
@@ -864,8 +864,8 @@ module.exports = (function() {
|
|
864
864
|
(parseResult && parseResult.services ? parseResult.services : {})
|
865
865
|
);
|
866
866
|
|
867
|
-
const rule = ruleCreator.create ? ruleCreator.create(ruleContext)
|
868
|
-
ruleCreator(ruleContext);
|
867
|
+
const rule = ruleCreator.create ? ruleCreator.create(ruleContext)
|
868
|
+
: ruleCreator(ruleContext);
|
869
869
|
|
870
870
|
// add all the node types as listeners
|
871
871
|
Object.keys(rule).forEach(nodeType => {
|
@@ -939,9 +939,9 @@ module.exports = (function() {
|
|
939
939
|
|
940
940
|
if (lineDiff === 0) {
|
941
941
|
return a.column - b.column;
|
942
|
-
} else {
|
943
|
-
return lineDiff;
|
944
942
|
}
|
943
|
+
return lineDiff;
|
944
|
+
|
945
945
|
});
|
946
946
|
|
947
947
|
return messages;
|
@@ -1109,9 +1109,9 @@ module.exports = (function() {
|
|
1109
1109
|
if (scope) {
|
1110
1110
|
if (scope.type === "function-expression-name") {
|
1111
1111
|
return scope.childScopes[0];
|
1112
|
-
} else {
|
1113
|
-
return scope;
|
1114
1112
|
}
|
1113
|
+
return scope;
|
1114
|
+
|
1115
1115
|
}
|
1116
1116
|
|
1117
1117
|
}
|
@@ -1161,9 +1161,9 @@ module.exports = (function() {
|
|
1161
1161
|
api.getFilename = function() {
|
1162
1162
|
if (typeof currentFilename === "string") {
|
1163
1163
|
return currentFilename;
|
1164
|
-
} else {
|
1165
|
-
return "<input>";
|
1166
1164
|
}
|
1165
|
+
return "<input>";
|
1166
|
+
|
1167
1167
|
};
|
1168
1168
|
|
1169
1169
|
/**
|
@@ -1192,7 +1192,7 @@ module.exports = (function() {
|
|
1192
1192
|
* @returns {Object} Object mapping rule IDs to their default configurations
|
1193
1193
|
*/
|
1194
1194
|
api.defaults = function() {
|
1195
|
-
return require("../conf/eslint
|
1195
|
+
return require("../conf/eslint-recommended");
|
1196
1196
|
};
|
1197
1197
|
|
1198
1198
|
/**
|
@@ -19,9 +19,9 @@ const xmlEscape = require("../util/xml-escape");
|
|
19
19
|
function getMessageType(message) {
|
20
20
|
if (message.fatal || message.severity === 2) {
|
21
21
|
return "error";
|
22
|
-
} else {
|
23
|
-
return "warning";
|
24
22
|
}
|
23
|
+
return "warning";
|
24
|
+
|
25
25
|
}
|
26
26
|
|
27
27
|
//------------------------------------------------------------------------------
|
package/lib/formatters/junit.js
CHANGED
@@ -19,9 +19,9 @@ const xmlEscape = require("../util/xml-escape");
|
|
19
19
|
function getMessageType(message) {
|
20
20
|
if (message.fatal || message.severity === 2) {
|
21
21
|
return "Error";
|
22
|
-
} else {
|
23
|
-
return "Warning";
|
24
22
|
}
|
23
|
+
return "Warning";
|
24
|
+
|
25
25
|
}
|
26
26
|
|
27
27
|
//------------------------------------------------------------------------------
|
package/lib/formatters/tap.js
CHANGED
package/lib/formatters/unix.js
CHANGED
@@ -4,6 +4,12 @@
|
|
4
4
|
*/
|
5
5
|
"use strict";
|
6
6
|
|
7
|
+
//------------------------------------------------------------------------------
|
8
|
+
// Requirements
|
9
|
+
//------------------------------------------------------------------------------
|
10
|
+
|
11
|
+
const astUtils = require("../ast-utils");
|
12
|
+
|
7
13
|
//------------------------------------------------------------------------------
|
8
14
|
// Rule Definition
|
9
15
|
//------------------------------------------------------------------------------
|
@@ -136,10 +142,7 @@ module.exports = {
|
|
136
142
|
loc: arrowBody.loc.start,
|
137
143
|
message: "Expected block statement surrounding arrow body.",
|
138
144
|
fix(fixer) {
|
139
|
-
const lastTokenBeforeBody = sourceCode.
|
140
|
-
.reverse()
|
141
|
-
.find(token => token.value !== "(");
|
142
|
-
|
145
|
+
const lastTokenBeforeBody = sourceCode.getLastTokenBetween(sourceCode.getFirstToken(node), arrowBody, astUtils.isNotOpeningParenToken);
|
143
146
|
const firstBodyToken = sourceCode.getTokenAfter(lastTokenBeforeBody);
|
144
147
|
|
145
148
|
return fixer.replaceTextRange(
|
@@ -4,6 +4,12 @@
|
|
4
4
|
*/
|
5
5
|
"use strict";
|
6
6
|
|
7
|
+
//------------------------------------------------------------------------------
|
8
|
+
// Requirements
|
9
|
+
//------------------------------------------------------------------------------
|
10
|
+
|
11
|
+
const astUtils = require("../ast-utils");
|
12
|
+
|
7
13
|
//------------------------------------------------------------------------------
|
8
14
|
// Rule Definition
|
9
15
|
//------------------------------------------------------------------------------
|
@@ -51,12 +57,7 @@ module.exports = {
|
|
51
57
|
* @returns {Object} Tokens of arrow and before/after arrow.
|
52
58
|
*/
|
53
59
|
function getTokens(node) {
|
54
|
-
|
55
|
-
|
56
|
-
// skip '(' tokens.
|
57
|
-
while (arrow.value !== "=>") {
|
58
|
-
arrow = sourceCode.getTokenBefore(arrow);
|
59
|
-
}
|
60
|
+
const arrow = sourceCode.getTokenBefore(node.body, astUtils.isArrowToken);
|
60
61
|
|
61
62
|
return {
|
62
63
|
before: sourceCode.getTokenBefore(arrow),
|
@@ -74,8 +74,8 @@ module.exports = {
|
|
74
74
|
// Gets braces and the first/last token of content.
|
75
75
|
const openBrace = getOpenBrace(node);
|
76
76
|
const closeBrace = sourceCode.getLastToken(node);
|
77
|
-
const firstToken = sourceCode.
|
78
|
-
const lastToken = sourceCode.
|
77
|
+
const firstToken = sourceCode.getTokenAfter(openBrace, { includeComments: true });
|
78
|
+
const lastToken = sourceCode.getTokenBefore(closeBrace, { includeComments: true });
|
79
79
|
|
80
80
|
// Skip if the node is invalid or empty.
|
81
81
|
if (openBrace.type !== "Punctuator" ||
|
package/lib/rules/brace-style.js
CHANGED
@@ -62,7 +62,7 @@ module.exports = {
|
|
62
62
|
function removeNewlineBetween(firstToken, secondToken) {
|
63
63
|
const textRange = [firstToken.range[1], secondToken.range[0]];
|
64
64
|
const textBetween = sourceCode.text.slice(textRange[0], textRange[1]);
|
65
|
-
const NEWLINE_REGEX =
|
65
|
+
const NEWLINE_REGEX = astUtils.createGlobalLinebreakMatcher();
|
66
66
|
|
67
67
|
// Don't do a fix if there is a comment between the tokens
|
68
68
|
return fixer => fixer.replaceTextRange(textRange, textBetween.trim() ? null : textBetween.replace(NEWLINE_REGEX, ""));
|
@@ -78,7 +78,6 @@ module.exports = {
|
|
78
78
|
const tokenBeforeOpeningCurly = sourceCode.getTokenBefore(openingCurly);
|
79
79
|
const tokenAfterOpeningCurly = sourceCode.getTokenAfter(openingCurly);
|
80
80
|
const tokenBeforeClosingCurly = sourceCode.getTokenBefore(closingCurly);
|
81
|
-
const tokenAfterClosingCurly = sourceCode.getTokenAfter(closingCurly);
|
82
81
|
const singleLineException = params.allowSingleLine && astUtils.isTokenOnSameLine(openingCurly, closingCurly);
|
83
82
|
|
84
83
|
if (style !== "allman" && !astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly)) {
|
@@ -112,23 +111,30 @@ module.exports = {
|
|
112
111
|
fix: fixer => fixer.insertTextBefore(closingCurly, "\n")
|
113
112
|
});
|
114
113
|
}
|
114
|
+
}
|
115
115
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
}
|
116
|
+
/**
|
117
|
+
* Validates the location of a token that appears before a keyword (e.g. a newline before `else`)
|
118
|
+
* @param {Token} curlyToken The closing curly token. This is assumed to precede a keyword token (such as `else` or `finally`).
|
119
|
+
* @returns {void}
|
120
|
+
*/
|
121
|
+
function validateCurlyBeforeKeyword(curlyToken) {
|
122
|
+
const keywordToken = sourceCode.getTokenAfter(curlyToken);
|
124
123
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
124
|
+
if (style === "1tbs" && !astUtils.isTokenOnSameLine(curlyToken, keywordToken)) {
|
125
|
+
context.report({
|
126
|
+
node: curlyToken,
|
127
|
+
message: CLOSE_MESSAGE,
|
128
|
+
fix: removeNewlineBetween(curlyToken, keywordToken)
|
129
|
+
});
|
130
|
+
}
|
131
|
+
|
132
|
+
if (style !== "1tbs" && astUtils.isTokenOnSameLine(curlyToken, keywordToken)) {
|
133
|
+
context.report({
|
134
|
+
node: curlyToken,
|
135
|
+
message: CLOSE_MESSAGE_STROUSTRUP_ALLMAN,
|
136
|
+
fix: fixer => fixer.insertTextAfter(curlyToken, "\n")
|
137
|
+
});
|
132
138
|
}
|
133
139
|
}
|
134
140
|
|
@@ -138,11 +144,7 @@ module.exports = {
|
|
138
144
|
|
139
145
|
return {
|
140
146
|
BlockStatement(node) {
|
141
|
-
if (
|
142
|
-
node.parent.type !== "BlockStatement" &&
|
143
|
-
node.parent.type !== "SwitchCase" &&
|
144
|
-
node.parent.type !== "Program"
|
145
|
-
) {
|
147
|
+
if (!astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)) {
|
146
148
|
validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node));
|
147
149
|
}
|
148
150
|
},
|
@@ -154,6 +156,24 @@ module.exports = {
|
|
154
156
|
const openingCurly = sourceCode.getTokenBefore(node.cases.length ? node.cases[0] : closingCurly);
|
155
157
|
|
156
158
|
validateCurlyPair(openingCurly, closingCurly);
|
159
|
+
},
|
160
|
+
IfStatement(node) {
|
161
|
+
if (node.consequent.type === "BlockStatement" && node.alternate) {
|
162
|
+
|
163
|
+
// Handle the keyword after the `if` block (before `else`)
|
164
|
+
validateCurlyBeforeKeyword(sourceCode.getLastToken(node.consequent));
|
165
|
+
}
|
166
|
+
},
|
167
|
+
TryStatement(node) {
|
168
|
+
|
169
|
+
// Handle the keyword after the `try` block (before `catch` or `finally`)
|
170
|
+
validateCurlyBeforeKeyword(sourceCode.getLastToken(node.block));
|
171
|
+
|
172
|
+
if (node.handler && node.finalizer) {
|
173
|
+
|
174
|
+
// Handle the keyword after the `catch` block (before `finally`)
|
175
|
+
validateCurlyBeforeKeyword(sourceCode.getLastToken(node.handler.body));
|
176
|
+
}
|
157
177
|
}
|
158
178
|
};
|
159
179
|
}
|
@@ -163,8 +163,8 @@ module.exports = {
|
|
163
163
|
* otherwise.
|
164
164
|
*/
|
165
165
|
function isInlineComment(comment) {
|
166
|
-
const previousToken = sourceCode.
|
167
|
-
nextToken = sourceCode.
|
166
|
+
const previousToken = sourceCode.getTokenBefore(comment, { includeComments: true }),
|
167
|
+
nextToken = sourceCode.getTokenAfter(comment, { includeComments: true });
|
168
168
|
|
169
169
|
return Boolean(
|
170
170
|
previousToken &&
|
@@ -181,7 +181,7 @@ module.exports = {
|
|
181
181
|
* @returns {boolean} True if the comment follows a valid comment.
|
182
182
|
*/
|
183
183
|
function isConsecutiveComment(comment) {
|
184
|
-
const previousTokenOrComment = sourceCode.
|
184
|
+
const previousTokenOrComment = sourceCode.getTokenBefore(comment, { includeComments: true });
|
185
185
|
|
186
186
|
return Boolean(
|
187
187
|
previousTokenOrComment &&
|
@@ -264,9 +264,9 @@ module.exports = {
|
|
264
264
|
commentValid = isCommentValid(comment, options);
|
265
265
|
|
266
266
|
if (!commentValid) {
|
267
|
-
const message = capitalize === "always"
|
268
|
-
ALWAYS_MESSAGE
|
269
|
-
NEVER_MESSAGE;
|
267
|
+
const message = capitalize === "always"
|
268
|
+
? ALWAYS_MESSAGE
|
269
|
+
: NEVER_MESSAGE;
|
270
270
|
|
271
271
|
context.report({
|
272
272
|
node: null, // Intentionally using loc instead
|
@@ -78,27 +78,27 @@ module.exports = {
|
|
78
78
|
if (options[dir]) {
|
79
79
|
if (dir === "before") {
|
80
80
|
return fixer.insertTextBefore(node, " ");
|
81
|
-
} else {
|
82
|
-
return fixer.insertTextAfter(node, " ");
|
83
81
|
}
|
84
|
-
|
85
|
-
let start, end;
|
86
|
-
const newText = "";
|
82
|
+
return fixer.insertTextAfter(node, " ");
|
87
83
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
} else {
|
92
|
-
start = node.range[1];
|
93
|
-
end = otherNode.range[0];
|
94
|
-
}
|
84
|
+
}
|
85
|
+
let start, end;
|
86
|
+
const newText = "";
|
95
87
|
|
96
|
-
|
88
|
+
if (dir === "before") {
|
89
|
+
start = otherNode.range[1];
|
90
|
+
end = node.range[0];
|
91
|
+
} else {
|
92
|
+
start = node.range[1];
|
93
|
+
end = otherNode.range[0];
|
97
94
|
}
|
95
|
+
|
96
|
+
return fixer.replaceTextRange([start, end], newText);
|
97
|
+
|
98
98
|
},
|
99
|
-
message: options[dir]
|
100
|
-
"A space is required {{dir}} ','."
|
101
|
-
"There should be no space {{dir}} ','.",
|
99
|
+
message: options[dir]
|
100
|
+
? "A space is required {{dir}} ','."
|
101
|
+
: "There should be no space {{dir}} ','.",
|
102
102
|
data: {
|
103
103
|
dir
|
104
104
|
}
|
@@ -104,7 +104,7 @@ module.exports = {
|
|
104
104
|
} else if (node.type === "ArrowFunctionExpression") {
|
105
105
|
|
106
106
|
// `=>` token
|
107
|
-
loc = context.getSourceCode().getTokenBefore(node.body).loc.start;
|
107
|
+
loc = context.getSourceCode().getTokenBefore(node.body, astUtils.isArrowToken).loc.start;
|
108
108
|
type = "function";
|
109
109
|
} else if (
|
110
110
|
node.parent.type === "MethodDefinition" ||
|
@@ -209,9 +209,9 @@ module.exports = {
|
|
209
209
|
|
210
210
|
if (!calledInEveryPaths) {
|
211
211
|
context.report({
|
212
|
-
message: calledInSomePaths
|
213
|
-
"Lacked a call of 'super()' in some code paths."
|
214
|
-
"Expected to call 'super()'.",
|
212
|
+
message: calledInSomePaths
|
213
|
+
? "Lacked a call of 'super()' in some code paths."
|
214
|
+
: "Expected to call 'super()'.",
|
215
215
|
node: node.parent
|
216
216
|
});
|
217
217
|
}
|
package/lib/rules/curly.js
CHANGED
@@ -94,19 +94,23 @@ module.exports = {
|
|
94
94
|
return first.loc.start.line === last.loc.end.line;
|
95
95
|
}
|
96
96
|
|
97
|
+
/**
|
98
|
+
* Checks if the given token is an `else` token or not.
|
99
|
+
*
|
100
|
+
* @param {Token} token - The token to check.
|
101
|
+
* @returns {boolean} `true` if the token is an `else` token.
|
102
|
+
*/
|
103
|
+
function isElseKeywordToken(token) {
|
104
|
+
return token.value === "else" && token.type === "Keyword";
|
105
|
+
}
|
106
|
+
|
97
107
|
/**
|
98
108
|
* Gets the `else` keyword token of a given `IfStatement` node.
|
99
109
|
* @param {ASTNode} node - A `IfStatement` node to get.
|
100
110
|
* @returns {Token} The `else` keyword token.
|
101
111
|
*/
|
102
112
|
function getElseKeyword(node) {
|
103
|
-
|
104
|
-
|
105
|
-
while (token.type !== "Keyword" || token.value !== "else") {
|
106
|
-
token = sourceCode.getTokenAfter(token);
|
107
|
-
}
|
108
|
-
|
109
|
-
return token;
|
113
|
+
return node.alternate && sourceCode.getFirstTokenBetween(node.consequent, node.alternate, isElseKeywordToken);
|
110
114
|
}
|
111
115
|
|
112
116
|
/**
|
@@ -31,9 +31,9 @@ module.exports = {
|
|
31
31
|
|
32
32
|
create(context) {
|
33
33
|
const options = context.options[0] || {};
|
34
|
-
const commentPattern = options.commentPattern
|
35
|
-
new RegExp(options.commentPattern)
|
36
|
-
DEFAULT_COMMENT_PATTERN;
|
34
|
+
const commentPattern = options.commentPattern
|
35
|
+
? new RegExp(options.commentPattern)
|
36
|
+
: DEFAULT_COMMENT_PATTERN;
|
37
37
|
|
38
38
|
const sourceCode = context.getSourceCode();
|
39
39
|
|