eslint 1.7.0 → 1.8.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/README.md +1 -0
- package/conf/eslint.json +2 -0
- package/lib/cli-engine.js +80 -13
- package/lib/cli.js +12 -10
- package/lib/eslint.js +14 -14
- package/lib/logging.js +25 -0
- package/lib/options.js +7 -2
- package/lib/rules/array-bracket-spacing.js +2 -2
- package/lib/rules/arrow-body-style.js +71 -0
- package/lib/rules/comma-dangle.js +26 -10
- package/lib/rules/comma-spacing.js +72 -36
- package/lib/rules/eol-last.js +10 -4
- package/lib/rules/id-match.js +2 -1
- package/lib/rules/indent.js +10 -8
- package/lib/rules/key-spacing.js +13 -25
- package/lib/rules/no-arrow-condition.js +88 -0
- package/lib/rules/no-extend-native.js +3 -3
- package/lib/rules/no-magic-numbers.js +25 -2
- package/lib/rules/no-mixed-spaces-and-tabs.js +23 -19
- package/lib/rules/no-multiple-empty-lines.js +39 -13
- package/lib/rules/no-plusplus.js +22 -1
- package/lib/rules/no-shadow.js +21 -3
- package/lib/rules/space-in-parens.js +145 -200
- package/lib/rules/valid-jsdoc.js +36 -19
- package/lib/testers/rule-tester.js +62 -7
- package/lib/util/source-code.js +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
@@ -69,6 +69,7 @@ These folks keep the project moving and are resources for help:
|
|
69
69
|
* Ian VanSchooten ([@ianvs](https://github.com/ianvs)) - committer
|
70
70
|
* Toru Nagashima ([@mysticatea](https://github.com/mysticatea)) - committer
|
71
71
|
* Burak Yiğit Kaya ([@byk](https://github.com/byk)) - committer
|
72
|
+
* Alberto Rodríguez ([@alberto](https://github.com/alberto)) - committer
|
72
73
|
|
73
74
|
## Releases
|
74
75
|
|
package/conf/eslint.json
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
"rules": {
|
5
5
|
"no-alert": 0,
|
6
6
|
"no-array-constructor": 0,
|
7
|
+
"no-arrow-condition": 0,
|
7
8
|
"no-bitwise": 0,
|
8
9
|
"no-caller": 0,
|
9
10
|
"no-catch-shadow": 0,
|
@@ -110,6 +111,7 @@
|
|
110
111
|
"no-magic-numbers": 0,
|
111
112
|
|
112
113
|
"array-bracket-spacing": [0, "never"],
|
114
|
+
"arrow-body-style": [0, "as-needed"],
|
113
115
|
"arrow-parens": 0,
|
114
116
|
"arrow-spacing": 0,
|
115
117
|
"accessor-pairs": 0,
|
package/lib/cli-engine.js
CHANGED
@@ -90,6 +90,10 @@ var defaultOptions = {
|
|
90
90
|
ignorePath: null,
|
91
91
|
parser: DEFAULT_PARSER,
|
92
92
|
cache: false,
|
93
|
+
// in order to honor the cacheFile option if specified
|
94
|
+
// this option should not have a default value otherwise
|
95
|
+
// it will always be used
|
96
|
+
cacheLocation: "",
|
93
97
|
cacheFile: ".eslintcache",
|
94
98
|
fix: false
|
95
99
|
},
|
@@ -338,6 +342,78 @@ function processPath(extensions) {
|
|
338
342
|
};
|
339
343
|
}
|
340
344
|
|
345
|
+
/**
|
346
|
+
* create a md5Hash of a given string
|
347
|
+
* @param {string} str the string to calculate the hash for
|
348
|
+
* @returns {string} the calculated hash
|
349
|
+
*/
|
350
|
+
function md5Hash(str) {
|
351
|
+
return crypto
|
352
|
+
.createHash("md5")
|
353
|
+
.update(str, "utf8")
|
354
|
+
.digest("hex");
|
355
|
+
}
|
356
|
+
|
357
|
+
/**
|
358
|
+
* return the cacheFile to be used by eslint, based on whether the provided parameter is
|
359
|
+
* a directory or looks like a directory (ends in `path.sep`), in which case the file
|
360
|
+
* name will be the `cacheFile/.cache_hashOfCWD`
|
361
|
+
*
|
362
|
+
* if cacheFile points to a file or looks like a file then in will just use that file
|
363
|
+
*
|
364
|
+
* @param {string} cacheFile The name of file to be used to store the cache
|
365
|
+
* @returns {string} the resolved path to the cache file
|
366
|
+
*/
|
367
|
+
function getCacheFile(cacheFile) {
|
368
|
+
// make sure the path separators are normalized for the environment/os
|
369
|
+
// keeping the trailing path separator if present
|
370
|
+
cacheFile = path.normalize(cacheFile);
|
371
|
+
|
372
|
+
var resolvedCacheFile = path.resolve(cacheFile);
|
373
|
+
var looksLikeADirectory = cacheFile[cacheFile.length - 1 ] === path.sep;
|
374
|
+
|
375
|
+
/**
|
376
|
+
* return the name for the cache file in case the provided parameter is a directory
|
377
|
+
* @returns {string} the resolved path to the cacheFile
|
378
|
+
*/
|
379
|
+
function getCacheFileForDirectory() {
|
380
|
+
return path.join(resolvedCacheFile, ".cache_" + md5Hash(process.cwd()));
|
381
|
+
}
|
382
|
+
|
383
|
+
var fileStats;
|
384
|
+
|
385
|
+
try {
|
386
|
+
fileStats = fs.lstatSync(resolvedCacheFile);
|
387
|
+
} catch (ex) {
|
388
|
+
fileStats = null;
|
389
|
+
}
|
390
|
+
|
391
|
+
|
392
|
+
// in case the file exists we need to verify if the provided path
|
393
|
+
// is a directory or a file. If it is a directory we want to create a file
|
394
|
+
// inside that directory
|
395
|
+
if (fileStats) {
|
396
|
+
// is a directory or is a file, but the original file the user provided
|
397
|
+
// looks like a directory but `path.resolve` removed the `last path.sep`
|
398
|
+
// so we need to still treat this like a directory
|
399
|
+
if (fileStats.isDirectory() || looksLikeADirectory) {
|
400
|
+
return getCacheFileForDirectory();
|
401
|
+
}
|
402
|
+
// is file so just use that file
|
403
|
+
return resolvedCacheFile;
|
404
|
+
}
|
405
|
+
|
406
|
+
// here we known the file or directory doesn't exist,
|
407
|
+
// so we will try to infer if its a directory if it looks like a directory
|
408
|
+
// for the current operating system.
|
409
|
+
|
410
|
+
// if the last character passed is a path separator we assume is a directory
|
411
|
+
if (looksLikeADirectory) {
|
412
|
+
return getCacheFileForDirectory();
|
413
|
+
}
|
414
|
+
|
415
|
+
return resolvedCacheFile;
|
416
|
+
}
|
341
417
|
|
342
418
|
//------------------------------------------------------------------------------
|
343
419
|
// Public Interface
|
@@ -356,12 +432,15 @@ function CLIEngine(options) {
|
|
356
432
|
*/
|
357
433
|
this.options = assign(Object.create(defaultOptions), options || {});
|
358
434
|
|
435
|
+
|
436
|
+
var cacheFile = getCacheFile(this.options.cacheLocation || this.options.cacheFile);
|
437
|
+
|
359
438
|
/**
|
360
439
|
* cache used to not operate on files that haven't changed since last successful
|
361
440
|
* execution (e.g. file passed with no errors and no warnings
|
362
441
|
* @type {Object}
|
363
442
|
*/
|
364
|
-
this._fileCache = fileEntryCache.create(
|
443
|
+
this._fileCache = fileEntryCache.create(cacheFile); // eslint-disable-line no-underscore-dangle
|
365
444
|
|
366
445
|
if (!this.options.cache) {
|
367
446
|
this._fileCache.destroy(); // eslint-disable-line no-underscore-dangle
|
@@ -511,18 +590,6 @@ CLIEngine.prototype = {
|
|
511
590
|
ignore: ignoredPathsList
|
512
591
|
};
|
513
592
|
|
514
|
-
/**
|
515
|
-
* create a md5Hash of a given string
|
516
|
-
* @param {string} str the string to calculate the hash for
|
517
|
-
* @returns {string} the calculated hash
|
518
|
-
*/
|
519
|
-
function md5Hash(str) {
|
520
|
-
return crypto
|
521
|
-
.createHash("md5")
|
522
|
-
.update(str)
|
523
|
-
.digest("hex");
|
524
|
-
}
|
525
|
-
|
526
593
|
/**
|
527
594
|
* Calculates the hash of the config file used to validate a given file
|
528
595
|
* @param {string} filename The path of the file to retrieve a config object for to calculate the hash
|
package/lib/cli.js
CHANGED
@@ -22,7 +22,8 @@ var fs = require("fs"),
|
|
22
22
|
|
23
23
|
options = require("./options"),
|
24
24
|
CLIEngine = require("./cli-engine"),
|
25
|
-
mkdirp = require("mkdirp")
|
25
|
+
mkdirp = require("mkdirp"),
|
26
|
+
log = require("./logging");
|
26
27
|
|
27
28
|
//------------------------------------------------------------------------------
|
28
29
|
// Helpers
|
@@ -52,6 +53,7 @@ function translateOptions(cliOptions) {
|
|
52
53
|
parser: cliOptions.parser,
|
53
54
|
cache: cliOptions.cache,
|
54
55
|
cacheFile: cliOptions.cacheFile,
|
56
|
+
cacheLocation: cliOptions.cacheLocation,
|
55
57
|
fix: cliOptions.fix
|
56
58
|
};
|
57
59
|
}
|
@@ -72,7 +74,7 @@ function printResults(engine, results, format, outputFile) {
|
|
72
74
|
|
73
75
|
formatter = engine.getFormatter(format);
|
74
76
|
if (!formatter) {
|
75
|
-
|
77
|
+
log.error("Could not find formatter '%s'.", format);
|
76
78
|
return false;
|
77
79
|
}
|
78
80
|
|
@@ -83,7 +85,7 @@ function printResults(engine, results, format, outputFile) {
|
|
83
85
|
filePath = path.resolve(process.cwd(), outputFile);
|
84
86
|
|
85
87
|
if (fs.existsSync(filePath) && fs.statSync(filePath).isDirectory()) {
|
86
|
-
|
88
|
+
log.error("Cannot write to output file path, it is a directory: %s", outputFile);
|
87
89
|
return false;
|
88
90
|
}
|
89
91
|
|
@@ -91,11 +93,11 @@ function printResults(engine, results, format, outputFile) {
|
|
91
93
|
mkdirp.sync(path.dirname(filePath));
|
92
94
|
fs.writeFileSync(filePath, output);
|
93
95
|
} catch (ex) {
|
94
|
-
|
96
|
+
log.error("There was a problem writing the output file:\n%s", ex);
|
95
97
|
return false;
|
96
98
|
}
|
97
99
|
} else {
|
98
|
-
|
100
|
+
log.info(output);
|
99
101
|
}
|
100
102
|
}
|
101
103
|
|
@@ -130,7 +132,7 @@ var cli = {
|
|
130
132
|
try {
|
131
133
|
currentOptions = options.parse(args);
|
132
134
|
} catch (error) {
|
133
|
-
|
135
|
+
log.error(error.message);
|
134
136
|
return 1;
|
135
137
|
}
|
136
138
|
|
@@ -138,11 +140,11 @@ var cli = {
|
|
138
140
|
|
139
141
|
if (currentOptions.version) { // version from package.json
|
140
142
|
|
141
|
-
|
143
|
+
log.info("v" + require("../package.json").version);
|
142
144
|
|
143
145
|
} else if (currentOptions.help || (!files.length && !text)) {
|
144
146
|
|
145
|
-
|
147
|
+
log.info(options.generateHelp());
|
146
148
|
|
147
149
|
} else {
|
148
150
|
|
@@ -150,7 +152,7 @@ var cli = {
|
|
150
152
|
|
151
153
|
// disable --fix for piped-in code until we know how to do it correctly
|
152
154
|
if (text && currentOptions.fix) {
|
153
|
-
|
155
|
+
log.error("The --fix option is not available for piped-in code.");
|
154
156
|
return 1;
|
155
157
|
}
|
156
158
|
|
@@ -171,7 +173,7 @@ var cli = {
|
|
171
173
|
tooManyWarnings = currentOptions.maxWarnings >= 0 && report.warningCount > currentOptions.maxWarnings;
|
172
174
|
|
173
175
|
if (!report.errorCount && tooManyWarnings) {
|
174
|
-
|
176
|
+
log.error("ESLint found too many warnings (maximum: %s).", currentOptions.maxWarnings);
|
175
177
|
}
|
176
178
|
|
177
179
|
return (report.errorCount || tooManyWarnings) ? 1 : 0;
|
package/lib/eslint.js
CHANGED
@@ -637,6 +637,20 @@ module.exports = (function() {
|
|
637
637
|
this.reset();
|
638
638
|
}
|
639
639
|
|
640
|
+
// search and apply "eslint-env *".
|
641
|
+
var envInFile = findEslintEnv(text || textOrSourceCode.text);
|
642
|
+
if (envInFile) {
|
643
|
+
if (!config || !config.env) {
|
644
|
+
config = assign({}, config || {}, {env: envInFile});
|
645
|
+
} else {
|
646
|
+
config = assign({}, config);
|
647
|
+
config.env = assign({}, config.env, envInFile);
|
648
|
+
}
|
649
|
+
}
|
650
|
+
|
651
|
+
// process initial config to make it safe to extend
|
652
|
+
config = prepareConfig(config || {});
|
653
|
+
|
640
654
|
// only do this for text
|
641
655
|
if (text !== null) {
|
642
656
|
|
@@ -646,20 +660,6 @@ module.exports = (function() {
|
|
646
660
|
return messages;
|
647
661
|
}
|
648
662
|
|
649
|
-
// search and apply "eslint-env *".
|
650
|
-
var envInFile = findEslintEnv(text);
|
651
|
-
if (envInFile) {
|
652
|
-
if (!config || !config.env) {
|
653
|
-
config = assign({}, config || {}, {env: envInFile});
|
654
|
-
} else {
|
655
|
-
config = assign({}, config);
|
656
|
-
config.env = assign({}, config.env, envInFile);
|
657
|
-
}
|
658
|
-
}
|
659
|
-
|
660
|
-
// process initial config to make it safe to extend
|
661
|
-
config = prepareConfig(config || {});
|
662
|
-
|
663
663
|
ast = parse(text.replace(/^#!([^\r\n]+)/, function(match, captured) {
|
664
664
|
shebang = captured;
|
665
665
|
return "//" + captured;
|
package/lib/logging.js
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Handle logging for Eslint
|
3
|
+
* @author Gyandeep Singh
|
4
|
+
* @copyright 2015 Gyandeep Singh. All rights reserved.
|
5
|
+
*/
|
6
|
+
"use strict";
|
7
|
+
|
8
|
+
/* istanbul ignore next */
|
9
|
+
module.exports = {
|
10
|
+
/**
|
11
|
+
* Cover for console.log
|
12
|
+
* @returns {void}
|
13
|
+
*/
|
14
|
+
info: function() {
|
15
|
+
console.log.apply(console, Array.prototype.slice.call(arguments));
|
16
|
+
},
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Cover for console.error
|
20
|
+
* @returns {void}
|
21
|
+
*/
|
22
|
+
error: function() {
|
23
|
+
console.error.apply(console, Array.prototype.slice.call(arguments));
|
24
|
+
}
|
25
|
+
};
|
package/lib/options.js
CHANGED
@@ -69,9 +69,14 @@ module.exports = optionator({
|
|
69
69
|
},
|
70
70
|
{
|
71
71
|
option: "cache-file",
|
72
|
-
type: "String",
|
72
|
+
type: "path::String",
|
73
73
|
default: ".eslintcache",
|
74
|
-
description: "Path to the cache file"
|
74
|
+
description: "Path to the cache file. Deprecated: use --cache-location"
|
75
|
+
},
|
76
|
+
{
|
77
|
+
option: "cache-location",
|
78
|
+
type: "path::String",
|
79
|
+
description: "Path to the cache file or directory"
|
75
80
|
},
|
76
81
|
{
|
77
82
|
heading: "Specifying rules and plugins"
|
@@ -116,7 +116,7 @@ module.exports = function(context) {
|
|
116
116
|
* @returns {boolean} Whether or not the node is an object type.
|
117
117
|
*/
|
118
118
|
function isObjectType(node) {
|
119
|
-
return node.type === "ObjectExpression" || node.type === "ObjectPattern";
|
119
|
+
return node && (node.type === "ObjectExpression" || node.type === "ObjectPattern");
|
120
120
|
}
|
121
121
|
|
122
122
|
/**
|
@@ -125,7 +125,7 @@ module.exports = function(context) {
|
|
125
125
|
* @returns {boolean} Whether or not the node is an array type.
|
126
126
|
*/
|
127
127
|
function isArrayType(node) {
|
128
|
-
return node.type === "ArrayExpression" || node.type === "ArrayPattern";
|
128
|
+
return node && (node.type === "ArrayExpression" || node.type === "ArrayPattern");
|
129
129
|
}
|
130
130
|
|
131
131
|
/**
|
@@ -0,0 +1,71 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Rule to require braces in arrow function body.
|
3
|
+
* @author Alberto Rodríguez
|
4
|
+
* @copyright 2015 Alberto Rodríguez. All rights reserved.
|
5
|
+
* See LICENSE file in root directory for full license.
|
6
|
+
*/
|
7
|
+
"use strict";
|
8
|
+
|
9
|
+
//------------------------------------------------------------------------------
|
10
|
+
// Rule Definition
|
11
|
+
//------------------------------------------------------------------------------
|
12
|
+
|
13
|
+
module.exports = function(context) {
|
14
|
+
var always = context.options[0] === "always";
|
15
|
+
var asNeeded = !context.options[0] || context.options[0] === "as-needed";
|
16
|
+
|
17
|
+
/**
|
18
|
+
* Determines whether a arrow function body needs braces
|
19
|
+
* @param {ASTNode} node The arrow function node.
|
20
|
+
* @returns {void}
|
21
|
+
*/
|
22
|
+
function validate(node) {
|
23
|
+
var arrowBody = node.body;
|
24
|
+
if (arrowBody.type === "BlockStatement") {
|
25
|
+
var blockBody = arrowBody.body;
|
26
|
+
|
27
|
+
if (blockBody.length > 1) {
|
28
|
+
return;
|
29
|
+
}
|
30
|
+
|
31
|
+
if (blockBody.length === 0) {
|
32
|
+
var hasComments = context.getComments(arrowBody).trailing.length > 0;
|
33
|
+
if (hasComments) {
|
34
|
+
return;
|
35
|
+
}
|
36
|
+
|
37
|
+
context.report({
|
38
|
+
node: node,
|
39
|
+
loc: arrowBody.loc.start,
|
40
|
+
message: "Unexpected empty block in arrow body."
|
41
|
+
});
|
42
|
+
} else {
|
43
|
+
if (asNeeded && blockBody[0].type === "ReturnStatement") {
|
44
|
+
context.report({
|
45
|
+
node: node,
|
46
|
+
loc: arrowBody.loc.start,
|
47
|
+
message: "Unexpected block statement surrounding arrow body."
|
48
|
+
});
|
49
|
+
}
|
50
|
+
}
|
51
|
+
} else {
|
52
|
+
if (always) {
|
53
|
+
context.report({
|
54
|
+
node: node,
|
55
|
+
loc: arrowBody.loc.start,
|
56
|
+
message: "Expected block statement surrounding arrow body."
|
57
|
+
});
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
return {
|
63
|
+
"ArrowFunctionExpression": validate
|
64
|
+
};
|
65
|
+
};
|
66
|
+
|
67
|
+
module.exports.schema = [
|
68
|
+
{
|
69
|
+
"enum": ["always", "as-needed"]
|
70
|
+
}
|
71
|
+
];
|
@@ -16,12 +16,12 @@
|
|
16
16
|
/**
|
17
17
|
* Gets the last element of a given array.
|
18
18
|
*
|
19
|
-
* @param {
|
20
|
-
* @returns {
|
19
|
+
* @param {*[]} xs - An array to get.
|
20
|
+
* @returns {*} The last element, or undefined.
|
21
21
|
*/
|
22
22
|
function getLast(xs) {
|
23
23
|
if (xs.length === 0) {
|
24
|
-
return
|
24
|
+
return null;
|
25
25
|
}
|
26
26
|
return xs[xs.length - 1];
|
27
27
|
}
|
@@ -79,9 +79,9 @@ module.exports = function(context) {
|
|
79
79
|
return false;
|
80
80
|
}
|
81
81
|
|
82
|
-
var sourceCode = context.getSourceCode()
|
83
|
-
|
84
|
-
|
82
|
+
var sourceCode = context.getSourceCode(),
|
83
|
+
penultimateToken = sourceCode.getLastToken(lastItem),
|
84
|
+
lastToken = sourceCode.getLastToken(node);
|
85
85
|
|
86
86
|
if (lastToken.value === ",") {
|
87
87
|
penultimateToken = lastToken;
|
@@ -105,8 +105,16 @@ module.exports = function(context) {
|
|
105
105
|
return;
|
106
106
|
}
|
107
107
|
|
108
|
-
var sourceCode = context.getSourceCode()
|
109
|
-
|
108
|
+
var sourceCode = context.getSourceCode(),
|
109
|
+
trailingToken;
|
110
|
+
|
111
|
+
// last item can be surrounded by parentheses for object and array literals
|
112
|
+
if (node.type === "ObjectExpression" || node.type === "ArrayExpression") {
|
113
|
+
trailingToken = sourceCode.getTokenBefore(sourceCode.getLastToken(node));
|
114
|
+
} else {
|
115
|
+
trailingToken = sourceCode.getTokenAfter(lastItem);
|
116
|
+
}
|
117
|
+
|
110
118
|
if (trailingToken.value === ",") {
|
111
119
|
context.report(
|
112
120
|
lastItem,
|
@@ -137,8 +145,16 @@ module.exports = function(context) {
|
|
137
145
|
return;
|
138
146
|
}
|
139
147
|
|
140
|
-
var sourceCode = context.getSourceCode()
|
141
|
-
|
148
|
+
var sourceCode = context.getSourceCode(),
|
149
|
+
trailingToken;
|
150
|
+
|
151
|
+
// last item can be surrounded by parentheses for object and array literals
|
152
|
+
if (node.type === "ObjectExpression" || node.type === "ArrayExpression") {
|
153
|
+
trailingToken = sourceCode.getTokenBefore(sourceCode.getLastToken(node));
|
154
|
+
} else {
|
155
|
+
trailingToken = sourceCode.getTokenAfter(lastItem);
|
156
|
+
}
|
157
|
+
|
142
158
|
if (trailingToken.value !== ",") {
|
143
159
|
context.report(
|
144
160
|
lastItem,
|
@@ -41,42 +41,6 @@ module.exports = function(context) {
|
|
41
41
|
return !!token && (token.type === "Punctuator") && (token.value === ",");
|
42
42
|
}
|
43
43
|
|
44
|
-
/**
|
45
|
-
* Reports a spacing error with an appropriate message.
|
46
|
-
* @param {ASTNode} node The binary expression node to report.
|
47
|
-
* @param {string} dir Is the error "before" or "after" the comma?
|
48
|
-
* @returns {void}
|
49
|
-
* @private
|
50
|
-
*/
|
51
|
-
function report(node, dir) {
|
52
|
-
context.report(node, options[dir] ?
|
53
|
-
"A space is required " + dir + " ','." :
|
54
|
-
"There should be no space " + dir + " ','.");
|
55
|
-
}
|
56
|
-
|
57
|
-
/**
|
58
|
-
* Validates the spacing around a comma token.
|
59
|
-
* @param {Object} tokens - The tokens to be validated.
|
60
|
-
* @param {Token} tokens.comma The token representing the comma.
|
61
|
-
* @param {Token} [tokens.left] The last token before the comma.
|
62
|
-
* @param {Token} [tokens.right] The first token after the comma.
|
63
|
-
* @param {Token|ASTNode} reportItem The item to use when reporting an error.
|
64
|
-
* @returns {void}
|
65
|
-
* @private
|
66
|
-
*/
|
67
|
-
function validateCommaItemSpacing(tokens, reportItem) {
|
68
|
-
if (tokens.left && astUtils.isTokenOnSameLine(tokens.left, tokens.comma) &&
|
69
|
-
(options.before !== sourceCode.isSpaceBetweenTokens(tokens.left, tokens.comma))
|
70
|
-
) {
|
71
|
-
report(reportItem, "before");
|
72
|
-
}
|
73
|
-
if (tokens.right && astUtils.isTokenOnSameLine(tokens.comma, tokens.right) &&
|
74
|
-
(options.after !== sourceCode.isSpaceBetweenTokens(tokens.comma, tokens.right))
|
75
|
-
) {
|
76
|
-
report(reportItem, "after");
|
77
|
-
}
|
78
|
-
}
|
79
|
-
|
80
44
|
/**
|
81
45
|
* Determines if a given source index is in a comment or not by checking
|
82
46
|
* the index against the comment range. Since the check goes straight
|
@@ -90,6 +54,7 @@ module.exports = function(context) {
|
|
90
54
|
function isIndexInComment(index, comments) {
|
91
55
|
|
92
56
|
var comment;
|
57
|
+
lastCommentIndex = 0;
|
93
58
|
|
94
59
|
while (lastCommentIndex < comments.length) {
|
95
60
|
|
@@ -108,6 +73,77 @@ module.exports = function(context) {
|
|
108
73
|
return false;
|
109
74
|
}
|
110
75
|
|
76
|
+
|
77
|
+
/**
|
78
|
+
* Reports a spacing error with an appropriate message.
|
79
|
+
* @param {ASTNode} node The binary expression node to report.
|
80
|
+
* @param {string} dir Is the error "before" or "after" the comma?
|
81
|
+
* @param {ASTNode} otherNode The node at the left or right of `node`
|
82
|
+
* @returns {void}
|
83
|
+
* @private
|
84
|
+
*/
|
85
|
+
function report(node, dir, otherNode) {
|
86
|
+
context.report({
|
87
|
+
node: node,
|
88
|
+
fix: function(fixer) {
|
89
|
+
if (options[dir]) {
|
90
|
+
if (dir === "before") {
|
91
|
+
return fixer.insertTextBefore(node, " ");
|
92
|
+
} else {
|
93
|
+
return fixer.insertTextAfter(node, " ");
|
94
|
+
}
|
95
|
+
} else {
|
96
|
+
/*
|
97
|
+
* Comments handling
|
98
|
+
*/
|
99
|
+
var start, end;
|
100
|
+
var newText = "";
|
101
|
+
|
102
|
+
if (dir === "before") {
|
103
|
+
start = otherNode.range[1];
|
104
|
+
end = node.range[0];
|
105
|
+
} else {
|
106
|
+
start = node.range[1];
|
107
|
+
end = otherNode.range[0];
|
108
|
+
}
|
109
|
+
|
110
|
+
for (var i = start; i < end; i++) {
|
111
|
+
if (isIndexInComment(i, allComments)) {
|
112
|
+
newText += context.getSource()[i];
|
113
|
+
}
|
114
|
+
}
|
115
|
+
return fixer.replaceTextRange([start, end], newText);
|
116
|
+
}
|
117
|
+
},
|
118
|
+
message: options[dir] ?
|
119
|
+
"A space is required " + dir + " ','." :
|
120
|
+
"There should be no space " + dir + " ','."
|
121
|
+
});
|
122
|
+
}
|
123
|
+
|
124
|
+
/**
|
125
|
+
* Validates the spacing around a comma token.
|
126
|
+
* @param {Object} tokens - The tokens to be validated.
|
127
|
+
* @param {Token} tokens.comma The token representing the comma.
|
128
|
+
* @param {Token} [tokens.left] The last token before the comma.
|
129
|
+
* @param {Token} [tokens.right] The first token after the comma.
|
130
|
+
* @param {Token|ASTNode} reportItem The item to use when reporting an error.
|
131
|
+
* @returns {void}
|
132
|
+
* @private
|
133
|
+
*/
|
134
|
+
function validateCommaItemSpacing(tokens, reportItem) {
|
135
|
+
if (tokens.left && astUtils.isTokenOnSameLine(tokens.left, tokens.comma) &&
|
136
|
+
(options.before !== sourceCode.isSpaceBetweenTokens(tokens.left, tokens.comma))
|
137
|
+
) {
|
138
|
+
report(reportItem, "before", tokens.left);
|
139
|
+
}
|
140
|
+
if (tokens.right && astUtils.isTokenOnSameLine(tokens.comma, tokens.right) &&
|
141
|
+
(options.after !== sourceCode.isSpaceBetweenTokens(tokens.comma, tokens.right))
|
142
|
+
) {
|
143
|
+
report(reportItem, "after", tokens.right);
|
144
|
+
}
|
145
|
+
}
|
146
|
+
|
111
147
|
/**
|
112
148
|
* Adds null elements of the given ArrayExpression or ArrayPattern node to the ignore list.
|
113
149
|
* @param {ASTNode} node An ArrayExpression or ArrayPattern node.
|
package/lib/rules/eol-last.js
CHANGED
@@ -18,8 +18,10 @@ module.exports = function(context) {
|
|
18
18
|
|
19
19
|
"Program": function checkBadEOF(node) {
|
20
20
|
// Get the whole source code, not for node only.
|
21
|
-
var src = context.getSource(),
|
22
|
-
|
21
|
+
var src = context.getSource(),
|
22
|
+
location = {column: 1},
|
23
|
+
linebreakStyle = context.options[0] || "unix",
|
24
|
+
linebreak = linebreakStyle === "unix" ? "\n" : "\r\n";
|
23
25
|
if (src.length === 0) {
|
24
26
|
return;
|
25
27
|
}
|
@@ -32,7 +34,7 @@ module.exports = function(context) {
|
|
32
34
|
loc: location,
|
33
35
|
message: "Newline required at end of file but not found.",
|
34
36
|
fix: function(fixer) {
|
35
|
-
return fixer.insertTextAfterRange([0, src.length],
|
37
|
+
return fixer.insertTextAfterRange([0, src.length], linebreak);
|
36
38
|
}
|
37
39
|
});
|
38
40
|
}
|
@@ -42,4 +44,8 @@ module.exports = function(context) {
|
|
42
44
|
|
43
45
|
};
|
44
46
|
|
45
|
-
module.exports.schema = [
|
47
|
+
module.exports.schema = [
|
48
|
+
{
|
49
|
+
"enum": ["unix", "windows"]
|
50
|
+
}
|
51
|
+
];
|
package/lib/rules/id-match.js
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
* @fileoverview Rule to flag non-matching identifiers
|
3
3
|
* @author Matthieu Larcher
|
4
4
|
* @copyright 2015 Matthieu Larcher. All rights reserved.
|
5
|
+
* See LICENSE in root directory for full license.
|
5
6
|
*/
|
6
7
|
|
7
8
|
"use strict";
|
@@ -121,7 +122,7 @@ module.exports.schema = [
|
|
121
122
|
"type": "object",
|
122
123
|
"properties": {
|
123
124
|
"properties": {
|
124
|
-
"
|
125
|
+
"type": "boolean"
|
125
126
|
}
|
126
127
|
}
|
127
128
|
}
|