eslint 1.7.3 → 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 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(path.resolve(this.options.cacheFile)); // eslint-disable-line no-underscore-dangle
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
- console.error("Could not find formatter '%s'.", format);
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
- console.error("Cannot write to output file path, it is a directory: %s", outputFile);
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
- console.error("There was a problem writing the output file:\n%s", ex);
96
+ log.error("There was a problem writing the output file:\n%s", ex);
95
97
  return false;
96
98
  }
97
99
  } else {
98
- console.log(output);
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
- console.error(error.message);
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
- console.log("v" + require("../package.json").version);
143
+ log.info("v" + require("../package.json").version);
142
144
 
143
145
  } else if (currentOptions.help || (!files.length && !text)) {
144
146
 
145
- console.log(options.generateHelp());
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
- console.error("The --fix option is not available for piped-in code.");
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
- console.error("ESLint found too many warnings (maximum: %s).", currentOptions.maxWarnings);
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
+ ];
@@ -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.
@@ -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(), location = {column: 1};
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], "\n");
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
+ ];
@@ -0,0 +1,88 @@
1
+ /**
2
+ * @fileoverview A rule to warn against using arrow functions in conditions.
3
+ * @author Jxck <https://github.com/Jxck>
4
+ * @copyright 2015 Luke Karrys. All rights reserved.
5
+ * The MIT License (MIT)
6
+
7
+ * Copyright (c) 2015 Jxck
8
+
9
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ * of this software and associated documentation files (the "Software"), to deal
11
+ * in the Software without restriction, including without limitation the rights
12
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ * copies of the Software, and to permit persons to whom the Software is
14
+ * furnished to do so, subject to the following conditions:
15
+
16
+ * The above copyright notice and this permission notice shall be included in all
17
+ * copies or substantial portions of the Software.
18
+
19
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ * SOFTWARE.
26
+ */
27
+
28
+ "use strict";
29
+
30
+ //------------------------------------------------------------------------------
31
+ // Helpers
32
+ //------------------------------------------------------------------------------
33
+
34
+ /**
35
+ * Checks whether or not a node is an arrow function expression.
36
+ * @param {ASTNode} node - node to test
37
+ * @returns {boolean} `true` if the node is an arrow function expression.
38
+ */
39
+ function isArrowFunction(node) {
40
+ return node.test && node.test.type === "ArrowFunctionExpression";
41
+ }
42
+
43
+ /**
44
+ * Checks whether or not a node is a conditional expression.
45
+ * @param {ASTNode} node - node to test
46
+ * @returns {boolean} `true` if the node is a conditional expression.
47
+ */
48
+ function isConditional(node) {
49
+ return node.body && node.body.type === "ConditionalExpression";
50
+ }
51
+
52
+ //------------------------------------------------------------------------------
53
+ // Rule Definition
54
+ //------------------------------------------------------------------------------
55
+
56
+ module.exports = function(context) {
57
+ /**
58
+ * Reports if a conditional statement is an arrow function.
59
+ * @param {ASTNode} node - A node to check and report.
60
+ * @returns {void}
61
+ */
62
+ function checkCondition(node) {
63
+ if (isArrowFunction(node)) {
64
+ context.report(node, "Arrow function `=>` used inside {{statementType}} instead of comparison operator.", {statementType: node.type});
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Reports if an arrow function contains an ambiguous conditional.
70
+ * @param {ASTNode} node - A node to check and report.
71
+ * @returns {void}
72
+ */
73
+ function checkArrowFunc(node) {
74
+ if (isConditional(node)) {
75
+ context.report(node, "Arrow function used ambiguously with a conditional expression.");
76
+ }
77
+ }
78
+
79
+ return {
80
+ "IfStatement": checkCondition,
81
+ "WhileStatement": checkCondition,
82
+ "ForStatement": checkCondition,
83
+ "ConditionalExpression": checkCondition,
84
+ "ArrowFunctionExpression": checkArrowFunc
85
+ };
86
+ };
87
+
88
+ module.exports.schema = [];