eslint 7.0.0-alpha.3 → 7.2.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.
Files changed (89) hide show
  1. package/CHANGELOG.md +303 -0
  2. package/README.md +10 -11
  3. package/bin/eslint.js +115 -77
  4. package/conf/category-list.json +0 -1
  5. package/lib/api.js +2 -0
  6. package/lib/cli-engine/cascading-config-array-factory.js +12 -0
  7. package/lib/cli-engine/cli-engine.js +53 -48
  8. package/lib/cli-engine/config-array/config-array.js +1 -1
  9. package/lib/cli-engine/config-array/ignore-pattern.js +7 -1
  10. package/lib/cli-engine/config-array-factory.js +3 -3
  11. package/lib/cli.js +181 -95
  12. package/lib/eslint/eslint.js +656 -0
  13. package/lib/eslint/index.js +7 -0
  14. package/lib/init/autoconfig.js +4 -4
  15. package/lib/init/config-initializer.js +5 -10
  16. package/lib/init/source-code-utils.js +2 -2
  17. package/lib/linter/code-path-analysis/code-path-analyzer.js +2 -2
  18. package/lib/linter/code-path-analysis/code-path-state.js +34 -12
  19. package/lib/linter/config-comment-parser.js +1 -1
  20. package/lib/linter/linter.js +2 -1
  21. package/lib/options.js +0 -1
  22. package/lib/rule-tester/rule-tester.js +6 -1
  23. package/lib/rules/accessor-pairs.js +1 -1
  24. package/lib/rules/array-callback-return.js +3 -18
  25. package/lib/rules/arrow-parens.js +19 -3
  26. package/lib/rules/block-spacing.js +19 -2
  27. package/lib/rules/callback-return.js +4 -0
  28. package/lib/rules/comma-style.js +3 -8
  29. package/lib/rules/func-call-spacing.js +22 -6
  30. package/lib/rules/getter-return.js +2 -12
  31. package/lib/rules/global-require.js +4 -0
  32. package/lib/rules/handle-callback-err.js +4 -0
  33. package/lib/rules/index.js +1 -0
  34. package/lib/rules/key-spacing.js +1 -1
  35. package/lib/rules/keyword-spacing.js +9 -2
  36. package/lib/rules/linebreak-style.js +8 -2
  37. package/lib/rules/max-lines-per-function.js +1 -1
  38. package/lib/rules/multiline-ternary.js +44 -25
  39. package/lib/rules/new-cap.js +1 -1
  40. package/lib/rules/newline-per-chained-call.js +6 -3
  41. package/lib/rules/no-buffer-constructor.js +4 -0
  42. package/lib/rules/no-control-regex.js +1 -1
  43. package/lib/rules/no-empty-function.js +1 -1
  44. package/lib/rules/no-extra-boolean-cast.js +3 -0
  45. package/lib/rules/no-extra-parens.js +35 -3
  46. package/lib/rules/no-inner-declarations.js +31 -39
  47. package/lib/rules/no-invalid-regexp.js +1 -1
  48. package/lib/rules/no-lone-blocks.js +1 -1
  49. package/lib/rules/no-loss-of-precision.js +198 -0
  50. package/lib/rules/no-misleading-character-class.js +1 -1
  51. package/lib/rules/no-mixed-operators.js +3 -2
  52. package/lib/rules/no-mixed-requires.js +4 -0
  53. package/lib/rules/no-mixed-spaces-and-tabs.js +14 -6
  54. package/lib/rules/no-new-func.js +22 -19
  55. package/lib/rules/no-new-object.js +15 -3
  56. package/lib/rules/no-new-require.js +4 -0
  57. package/lib/rules/no-new-symbol.js +2 -1
  58. package/lib/rules/no-path-concat.js +4 -0
  59. package/lib/rules/no-process-env.js +4 -0
  60. package/lib/rules/no-process-exit.js +4 -0
  61. package/lib/rules/no-regex-spaces.js +1 -1
  62. package/lib/rules/no-restricted-exports.js +6 -0
  63. package/lib/rules/no-restricted-modules.js +4 -0
  64. package/lib/rules/no-sync.js +4 -0
  65. package/lib/rules/no-unexpected-multiline.js +22 -12
  66. package/lib/rules/no-unneeded-ternary.js +6 -4
  67. package/lib/rules/no-unused-expressions.js +1 -1
  68. package/lib/rules/no-unused-vars.js +3 -1
  69. package/lib/rules/no-useless-backreference.js +1 -1
  70. package/lib/rules/no-useless-concat.js +1 -1
  71. package/lib/rules/one-var-declaration-per-line.js +1 -1
  72. package/lib/rules/padded-blocks.js +17 -4
  73. package/lib/rules/prefer-named-capture-group.js +1 -1
  74. package/lib/rules/quote-props.js +2 -2
  75. package/lib/rules/rest-spread-spacing.js +3 -6
  76. package/lib/rules/semi-spacing.js +32 -8
  77. package/lib/rules/space-before-function-paren.js +5 -2
  78. package/lib/rules/template-tag-spacing.js +8 -2
  79. package/lib/rules/utils/ast-utils.js +106 -9
  80. package/lib/rules/yoda.js +101 -51
  81. package/lib/shared/relative-module-resolver.js +1 -0
  82. package/lib/shared/types.js +7 -0
  83. package/lib/source-code/source-code.js +1 -0
  84. package/messages/extend-config-missing.txt +1 -1
  85. package/messages/no-config-found.txt +1 -1
  86. package/messages/plugin-conflict.txt +1 -1
  87. package/messages/plugin-missing.txt +1 -1
  88. package/messages/whitespace-found.txt +1 -1
  89. package/package.json +27 -26
@@ -15,6 +15,7 @@ const util = require("util"),
15
15
  inquirer = require("inquirer"),
16
16
  ProgressBar = require("progress"),
17
17
  semver = require("semver"),
18
+ espree = require("espree"),
18
19
  recConfig = require("../../conf/eslint-recommended"),
19
20
  ConfigOps = require("../shared/config-ops"),
20
21
  log = require("../shared/logging"),
@@ -31,8 +32,6 @@ const debug = require("debug")("eslint:config-initializer");
31
32
  // Private
32
33
  //------------------------------------------------------------------------------
33
34
 
34
- const DEFAULT_ECMA_VERSION = 2018;
35
-
36
35
  /* istanbul ignore next: hard to test fs function */
37
36
  /**
38
37
  * Create .eslintrc file in the current working directory
@@ -265,13 +264,8 @@ function processAnswers(answers) {
265
264
  extends: []
266
265
  };
267
266
 
268
- // set the latest ECMAScript version
269
- config.parserOptions.ecmaVersion = DEFAULT_ECMA_VERSION;
270
- config.env.es6 = true;
271
- config.globals = {
272
- Atomics: "readonly",
273
- SharedArrayBuffer: "readonly"
274
- };
267
+ config.parserOptions.ecmaVersion = espree.latestEcmaVersion;
268
+ config.env.es2020 = true;
275
269
 
276
270
  // set the module type
277
271
  if (answers.moduleType === "esm") {
@@ -328,6 +322,7 @@ function processAnswers(answers) {
328
322
  }
329
323
  if (answers.typescript && config.extends.includes("eslint:recommended")) {
330
324
  config.extends.push("plugin:@typescript-eslint/eslint-recommended");
325
+ config.extends.push("plugin:@typescript-eslint/recommended");
331
326
  }
332
327
 
333
328
  // normalize extends
@@ -351,7 +346,7 @@ function getLocalESLintVersion() {
351
346
  const eslint = require(eslintPath);
352
347
 
353
348
  return eslint.linter.version || null;
354
- } catch (_err) {
349
+ } catch {
355
350
  return null;
356
351
  }
357
352
  }
@@ -23,7 +23,7 @@ const { CLIEngine } = require("../cli-engine");
23
23
  * TODO1: Expose the API that enumerates target files.
24
24
  * TODO2: Extract the creation logic of `SourceCode` from `Linter` class.
25
25
  */
26
- const { getCLIEngineInternalSlots } = require("../cli-engine/cli-engine"); // eslint-disable-line no-restricted-modules
26
+ const { getCLIEngineInternalSlots } = require("../cli-engine/cli-engine"); // eslint-disable-line node/no-restricted-require
27
27
 
28
28
  const debug = require("debug")("eslint:source-code-utils");
29
29
 
@@ -97,7 +97,7 @@ function getSourceCodeOfFiles(patterns, options, callback) {
97
97
  sourceCodes[filename] = sourceCode;
98
98
  }
99
99
  if (callback) {
100
- callback(filenames.length); // eslint-disable-line callback-return
100
+ callback(filenames.length); // eslint-disable-line node/callback-return
101
101
  }
102
102
  });
103
103
 
@@ -33,10 +33,10 @@ function isCaseNode(node) {
33
33
  * Checks whether the given logical operator is taken into account for the code
34
34
  * path analysis.
35
35
  * @param {string} operator The operator found in the LogicalExpression node
36
- * @returns {boolean} `true` if the operator is "&&" or "||"
36
+ * @returns {boolean} `true` if the operator is "&&" or "||" or "??"
37
37
  */
38
38
  function isHandledLogicalOperator(operator) {
39
- return operator === "&&" || operator === "||";
39
+ return operator === "&&" || operator === "||" || operator === "??";
40
40
  }
41
41
 
42
42
  /**
@@ -201,6 +201,7 @@ function finalizeTestSegmentsOfFor(context, choiceContext, head) {
201
201
  if (!choiceContext.processed) {
202
202
  choiceContext.trueForkContext.add(head);
203
203
  choiceContext.falseForkContext.add(head);
204
+ choiceContext.qqForkContext.add(head);
204
205
  }
205
206
 
206
207
  if (context.test !== true) {
@@ -351,6 +352,7 @@ class CodePathState {
351
352
  isForkingAsResult,
352
353
  trueForkContext: ForkContext.newEmpty(this.forkContext),
353
354
  falseForkContext: ForkContext.newEmpty(this.forkContext),
355
+ qqForkContext: ForkContext.newEmpty(this.forkContext),
354
356
  processed: false
355
357
  };
356
358
  }
@@ -370,6 +372,7 @@ class CodePathState {
370
372
  switch (context.kind) {
371
373
  case "&&":
372
374
  case "||":
375
+ case "??":
373
376
 
374
377
  /*
375
378
  * If any result were not transferred from child contexts,
@@ -379,6 +382,7 @@ class CodePathState {
379
382
  if (!context.processed) {
380
383
  context.trueForkContext.add(headSegments);
381
384
  context.falseForkContext.add(headSegments);
385
+ context.qqForkContext.add(headSegments);
382
386
  }
383
387
 
384
388
  /*
@@ -390,6 +394,7 @@ class CodePathState {
390
394
 
391
395
  parentContext.trueForkContext.addAll(context.trueForkContext);
392
396
  parentContext.falseForkContext.addAll(context.falseForkContext);
397
+ parentContext.qqForkContext.addAll(context.qqForkContext);
393
398
  parentContext.processed = true;
394
399
 
395
400
  return context;
@@ -456,13 +461,24 @@ class CodePathState {
456
461
  * This got segments already from the child choice context.
457
462
  * Creates the next path from own true/false fork context.
458
463
  */
459
- const prevForkContext =
460
- context.kind === "&&" ? context.trueForkContext
461
- /* kind === "||" */ : context.falseForkContext;
464
+ let prevForkContext;
465
+
466
+ switch (context.kind) {
467
+ case "&&": // if true then go to the right-hand side.
468
+ prevForkContext = context.trueForkContext;
469
+ break;
470
+ case "||": // if false then go to the right-hand side.
471
+ prevForkContext = context.falseForkContext;
472
+ break;
473
+ case "??": // Both true/false can short-circuit, so needs the third path to go to the right-hand side. That's qqForkContext.
474
+ prevForkContext = context.qqForkContext;
475
+ break;
476
+ default:
477
+ throw new Error("unreachable");
478
+ }
462
479
 
463
480
  forkContext.replaceHead(prevForkContext.makeNext(0, -1));
464
481
  prevForkContext.clear();
465
-
466
482
  context.processed = false;
467
483
  } else {
468
484
 
@@ -471,14 +487,19 @@ class CodePathState {
471
487
  * So addresses the head segments.
472
488
  * The head segments are the path of the left-hand operand.
473
489
  */
474
- if (context.kind === "&&") {
475
-
476
- // The path does short-circuit if false.
477
- context.falseForkContext.add(forkContext.head);
478
- } else {
479
-
480
- // The path does short-circuit if true.
481
- context.trueForkContext.add(forkContext.head);
490
+ switch (context.kind) {
491
+ case "&&": // the false path can short-circuit.
492
+ context.falseForkContext.add(forkContext.head);
493
+ break;
494
+ case "||": // the true path can short-circuit.
495
+ context.trueForkContext.add(forkContext.head);
496
+ break;
497
+ case "??": // both can short-circuit.
498
+ context.trueForkContext.add(forkContext.head);
499
+ context.falseForkContext.add(forkContext.head);
500
+ break;
501
+ default:
502
+ throw new Error("unreachable");
482
503
  }
483
504
 
484
505
  forkContext.replaceHead(forkContext.makeNext(-1, -1));
@@ -501,6 +522,7 @@ class CodePathState {
501
522
  if (!context.processed) {
502
523
  context.trueForkContext.add(forkContext.head);
503
524
  context.falseForkContext.add(forkContext.head);
525
+ context.qqForkContext.add(forkContext.head);
504
526
  }
505
527
 
506
528
  context.processed = false;
@@ -78,7 +78,7 @@ module.exports = class ConfigCommentParser {
78
78
  config: items
79
79
  };
80
80
  }
81
- } catch (ex) {
81
+ } catch {
82
82
 
83
83
  debug("Levn parsing failed; falling back to manual parsing.");
84
84
 
@@ -938,7 +938,8 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserOptions, parser
938
938
  });
939
939
  });
940
940
 
941
- const eventGenerator = new CodePathAnalyzer(new NodeEventGenerator(emitter));
941
+ // only run code path analyzer if the top level node is "Program", skip otherwise
942
+ const eventGenerator = nodeQueue[0].node.type === "Program" ? new CodePathAnalyzer(new NodeEventGenerator(emitter)) : new NodeEventGenerator(emitter);
942
943
 
943
944
  nodeQueue.forEach(traversalInfo => {
944
945
  currentNode = traversalInfo.node;
package/lib/options.js CHANGED
@@ -46,7 +46,6 @@ module.exports = optionator({
46
46
  {
47
47
  option: "ext",
48
48
  type: "[String]",
49
- default: ".js",
50
49
  description: "Specify JavaScript file extensions"
51
50
  },
52
51
  {
@@ -563,7 +563,12 @@ class RuleTester {
563
563
  output = SourceCodeFixer.applyFixes(code, messages).output;
564
564
  const errorMessageInFix = linter.verify(output, config, filename).find(m => m.fatal);
565
565
 
566
- assert(!errorMessageInFix, `A fatal parsing error occurred in autofix: ${errorMessageInFix && errorMessageInFix.message}`);
566
+ assert(!errorMessageInFix, [
567
+ "A fatal parsing error occurred in autofix.",
568
+ `Error: ${errorMessageInFix && errorMessageInFix.message}`,
569
+ "Autofix output:",
570
+ output
571
+ ].join("\n"));
567
572
  } else {
568
573
  output = code;
569
574
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @fileoverview Rule to flag wrapping non-iife in parens
2
+ * @fileoverview Rule to enforce getter and setter pairs in objects and classes.
3
3
  * @author Gyandeep Singh
4
4
  */
5
5
 
@@ -29,22 +29,6 @@ function isReachable(segment) {
29
29
  return segment.reachable;
30
30
  }
31
31
 
32
- /**
33
- * Gets a readable location.
34
- *
35
- * - FunctionExpression -> the function name or `function` keyword.
36
- * - ArrowFunctionExpression -> `=>` token.
37
- * @param {ASTNode} node A function node to get.
38
- * @param {SourceCode} sourceCode A source code to get tokens.
39
- * @returns {ASTNode|Token} The node or the token of a location.
40
- */
41
- function getLocation(node, sourceCode) {
42
- if (node.type === "ArrowFunctionExpression") {
43
- return sourceCode.getTokenBefore(node.body);
44
- }
45
- return node.id || node;
46
- }
47
-
48
32
  /**
49
33
  * Checks a given node is a MemberExpression node which has the specified name's
50
34
  * property.
@@ -179,6 +163,7 @@ module.exports = {
179
163
  create(context) {
180
164
 
181
165
  const options = context.options[0] || { allowImplicit: false, checkForEach: false };
166
+ const sourceCode = context.getSourceCode();
182
167
 
183
168
  let funcInfo = {
184
169
  arrayMethodName: null,
@@ -217,12 +202,12 @@ module.exports = {
217
202
  }
218
203
 
219
204
  if (messageId) {
220
- let name = astUtils.getFunctionNameWithKind(funcInfo.node);
205
+ let name = astUtils.getFunctionNameWithKind(node);
221
206
 
222
207
  name = messageId === "expectedNoReturnValue" ? lodash.upperFirst(name) : name;
223
208
  context.report({
224
209
  node,
225
- loc: getLocation(node, context.getSourceCode()).loc.start,
210
+ loc: astUtils.getFunctionHeadLoc(node, sourceCode),
226
211
  messageId,
227
212
  data: { name }
228
213
  });
@@ -105,10 +105,27 @@ module.exports = {
105
105
  ], `${shouldAddSpaceForAsync ? " " : ""}${paramToken.value}`);
106
106
  }
107
107
 
108
+ /**
109
+ * Checks whether there are comments inside the params or not.
110
+ * @returns {boolean} `true` if there are comments inside of parens, else `false`
111
+ */
112
+ function hasCommentsInParens() {
113
+ if (astUtils.isOpeningParenToken(firstTokenOfParam)) {
114
+ const closingParenToken = sourceCode.getTokenAfter(node.params[0], astUtils.isClosingParenToken);
115
+
116
+ return closingParenToken && sourceCode.commentsExistBetween(firstTokenOfParam, closingParenToken);
117
+ }
118
+ return false;
119
+
120
+ }
121
+
122
+ if (hasCommentsInParens()) {
123
+ return;
124
+ }
125
+
108
126
  // "as-needed", { "requireForBlockBody": true }: x => x
109
127
  if (
110
128
  requireForBlockBody &&
111
- node.params.length === 1 &&
112
129
  node.params[0].type === "Identifier" &&
113
130
  !node.params[0].typeAnnotation &&
114
131
  node.body.type !== "BlockStatement" &&
@@ -144,7 +161,6 @@ module.exports = {
144
161
 
145
162
  // "as-needed": x => x
146
163
  if (asNeeded &&
147
- node.params.length === 1 &&
148
164
  node.params[0].type === "Identifier" &&
149
165
  !node.params[0].typeAnnotation &&
150
166
  !node.returnType
@@ -178,7 +194,7 @@ module.exports = {
178
194
  }
179
195
 
180
196
  return {
181
- ArrowFunctionExpression: parens
197
+ "ArrowFunctionExpression[params.length=1]": parens
182
198
  };
183
199
  }
184
200
  };
@@ -102,9 +102,18 @@ module.exports = {
102
102
 
103
103
  // Check.
104
104
  if (!isValid(openBrace, firstToken)) {
105
+ let loc = openBrace.loc;
106
+
107
+ if (messageId === "extra") {
108
+ loc = {
109
+ start: openBrace.loc.end,
110
+ end: firstToken.loc.start
111
+ };
112
+ }
113
+
105
114
  context.report({
106
115
  node,
107
- loc: openBrace.loc.start,
116
+ loc,
108
117
  messageId,
109
118
  data: {
110
119
  location: "after",
@@ -120,9 +129,17 @@ module.exports = {
120
129
  });
121
130
  }
122
131
  if (!isValid(lastToken, closeBrace)) {
132
+ let loc = closeBrace.loc;
133
+
134
+ if (messageId === "extra") {
135
+ loc = {
136
+ start: lastToken.loc.end,
137
+ end: closeBrace.loc.start
138
+ };
139
+ }
123
140
  context.report({
124
141
  node,
125
- loc: closeBrace.loc.start,
142
+ loc,
126
143
  messageId,
127
144
  data: {
128
145
  location: "before",
@@ -10,6 +10,10 @@
10
10
 
11
11
  module.exports = {
12
12
  meta: {
13
+ deprecated: true,
14
+
15
+ replacedBy: [],
16
+
13
17
  type: "suggestion",
14
18
 
15
19
  docs: {
@@ -146,10 +146,7 @@ module.exports = {
146
146
  // lone comma
147
147
  context.report({
148
148
  node: reportItem,
149
- loc: {
150
- line: commaToken.loc.end.line,
151
- column: commaToken.loc.start.column
152
- },
149
+ loc: commaToken.loc,
153
150
  messageId: "unexpectedLineBeforeAndAfterComma",
154
151
  fix: getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken)
155
152
  });
@@ -158,6 +155,7 @@ module.exports = {
158
155
 
159
156
  context.report({
160
157
  node: reportItem,
158
+ loc: commaToken.loc,
161
159
  messageId: "expectedCommaFirst",
162
160
  fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken)
163
161
  });
@@ -166,10 +164,7 @@ module.exports = {
166
164
 
167
165
  context.report({
168
166
  node: reportItem,
169
- loc: {
170
- line: commaToken.loc.end.line,
171
- column: commaToken.loc.end.column
172
- },
167
+ loc: commaToken.loc,
173
168
  messageId: "expectedCommaLast",
174
169
  fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken)
175
170
  });
@@ -63,7 +63,8 @@ module.exports = {
63
63
  },
64
64
 
65
65
  messages: {
66
- unexpected: "Unexpected newline between function name and paren.",
66
+ unexpectedWhitespace: "Unexpected whitespace between function name and paren.",
67
+ unexpectedNewline: "Unexpected newline between function name and paren.",
67
68
  missing: "Missing space between function name and paren."
68
69
  }
69
70
  },
@@ -115,8 +116,14 @@ module.exports = {
115
116
  if (never && hasWhitespace) {
116
117
  context.report({
117
118
  node,
118
- loc: leftToken.loc.start,
119
- messageId: "unexpected",
119
+ loc: {
120
+ start: leftToken.loc.end,
121
+ end: {
122
+ line: rightToken.loc.start.line,
123
+ column: rightToken.loc.start.column - 1
124
+ }
125
+ },
126
+ messageId: "unexpectedWhitespace",
120
127
  fix(fixer) {
121
128
 
122
129
  /*
@@ -133,7 +140,13 @@ module.exports = {
133
140
  } else if (!never && !hasWhitespace) {
134
141
  context.report({
135
142
  node,
136
- loc: leftToken.loc.start,
143
+ loc: {
144
+ start: {
145
+ line: leftToken.loc.end.line,
146
+ column: leftToken.loc.end.column - 1
147
+ },
148
+ end: rightToken.loc.start
149
+ },
137
150
  messageId: "missing",
138
151
  fix(fixer) {
139
152
  return fixer.insertTextBefore(rightToken, " ");
@@ -142,8 +155,11 @@ module.exports = {
142
155
  } else if (!never && !allowNewlines && hasNewline) {
143
156
  context.report({
144
157
  node,
145
- loc: leftToken.loc.start,
146
- messageId: "unexpected",
158
+ loc: {
159
+ start: leftToken.loc.end,
160
+ end: rightToken.loc.start
161
+ },
162
+ messageId: "unexpectedNewline",
147
163
  fix(fixer) {
148
164
  return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], " ");
149
165
  }
@@ -25,17 +25,6 @@ function isReachable(segment) {
25
25
  return segment.reachable;
26
26
  }
27
27
 
28
- /**
29
- * Gets a readable location.
30
- *
31
- * - FunctionExpression -> the function name or `function` keyword.
32
- * @param {ASTNode} node A function node to get.
33
- * @returns {ASTNode|Token} The node or the token of a location.
34
- */
35
- function getId(node) {
36
- return node.id || node;
37
- }
38
-
39
28
  //------------------------------------------------------------------------------
40
29
  // Rule Definition
41
30
  //------------------------------------------------------------------------------
@@ -75,6 +64,7 @@ module.exports = {
75
64
  create(context) {
76
65
 
77
66
  const options = context.options[0] || { allowImplicit: false };
67
+ const sourceCode = context.getSourceCode();
78
68
 
79
69
  let funcInfo = {
80
70
  upper: null,
@@ -99,7 +89,7 @@ module.exports = {
99
89
  ) {
100
90
  context.report({
101
91
  node,
102
- loc: getId(node).loc.start,
92
+ loc: astUtils.getFunctionHeadLoc(node, sourceCode),
103
93
  messageId: funcInfo.hasReturn ? "expectedAlways" : "expected",
104
94
  data: {
105
95
  name: astUtils.getFunctionNameWithKind(funcInfo.node)
@@ -48,6 +48,10 @@ function isShadowed(scope, node) {
48
48
 
49
49
  module.exports = {
50
50
  meta: {
51
+ deprecated: true,
52
+
53
+ replacedBy: [],
54
+
51
55
  type: "suggestion",
52
56
 
53
57
  docs: {
@@ -11,6 +11,10 @@
11
11
 
12
12
  module.exports = {
13
13
  meta: {
14
+ deprecated: true,
15
+
16
+ replacedBy: [],
17
+
14
18
  type: "suggestion",
15
19
 
16
20
  docs: {
@@ -148,6 +148,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
148
148
  "no-lone-blocks": () => require("./no-lone-blocks"),
149
149
  "no-lonely-if": () => require("./no-lonely-if"),
150
150
  "no-loop-func": () => require("./no-loop-func"),
151
+ "no-loss-of-precision": () => require("./no-loss-of-precision"),
151
152
  "no-magic-numbers": () => require("./no-magic-numbers"),
152
153
  "no-misleading-character-class": () => require("./no-misleading-character-class"),
153
154
  "no-mixed-operators": () => require("./no-mixed-operators"),
@@ -45,7 +45,7 @@ function isSingleLine(node) {
45
45
  /**
46
46
  * Checks whether the properties on a single line.
47
47
  * @param {ASTNode[]} properties List of Property AST nodes.
48
- * @returns {boolean} True if all properies is on a single line.
48
+ * @returns {boolean} True if all properties is on a single line.
49
49
  */
50
50
  function isSingleLineProperties(properties) {
51
51
  const [firstProp] = properties,
@@ -152,7 +152,7 @@ module.exports = {
152
152
  sourceCode.isSpaceBetweenTokens(prevToken, token)
153
153
  ) {
154
154
  context.report({
155
- loc: token.loc.start,
155
+ loc: { start: prevToken.loc.end, end: token.loc.start },
156
156
  messageId: "unexpectedBefore",
157
157
  data: token,
158
158
  fix(fixer) {
@@ -203,8 +203,9 @@ module.exports = {
203
203
  astUtils.isTokenOnSameLine(token, nextToken) &&
204
204
  sourceCode.isSpaceBetweenTokens(token, nextToken)
205
205
  ) {
206
+
206
207
  context.report({
207
- loc: token.loc.start,
208
+ loc: { start: token.loc.end, end: nextToken.loc.start },
208
209
  messageId: "unexpectedAfter",
209
210
  data: token,
210
211
  fix(fixer) {
@@ -442,6 +443,12 @@ module.exports = {
442
443
  checkSpacingAround(sourceCode.getTokenAfter(firstToken));
443
444
  }
444
445
 
446
+ if (node.type === "ExportAllDeclaration" && node.exported) {
447
+ const asToken = sourceCode.getTokenBefore(node.exported);
448
+
449
+ checkSpacingBefore(asToken, PREV_TOKEN_M);
450
+ }
451
+
445
452
  if (node.source) {
446
453
  const fromToken = sourceCode.getTokenBefore(node.source);
447
454
 
@@ -86,8 +86,14 @@ module.exports = {
86
86
  context.report({
87
87
  node,
88
88
  loc: {
89
- line: i,
90
- column: sourceCode.lines[i - 1].length
89
+ start: {
90
+ line: i,
91
+ column: sourceCode.lines[i - 1].length
92
+ },
93
+ end: {
94
+ line: i + 1,
95
+ column: 0
96
+ }
91
97
  },
92
98
  messageId: expectedLF ? "expectedLF" : "expectedCRLF",
93
99
  fix: createFix(range, expectedLFChars)
@@ -134,7 +134,7 @@ module.exports = {
134
134
  * @returns {boolean} True if it's an IIFE
135
135
  */
136
136
  function isIIFE(node) {
137
- return node.type === "FunctionExpression" && node.parent && node.parent.type === "CallExpression" && node.parent.callee === node;
137
+ return (node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") && node.parent && node.parent.type === "CallExpression" && node.parent.callee === node;
138
138
  }
139
139
 
140
140
  /**