eslint 7.8.1 → 7.12.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.
@@ -39,33 +39,25 @@ function getTopConcatBinaryExpression(node) {
39
39
  }
40
40
 
41
41
  /**
42
- * Determines whether a given node is a octal escape sequence
42
+ * Checks whether or not a node contains a string literal with an octal or non-octal decimal escape sequence
43
43
  * @param {ASTNode} node A node to check
44
- * @returns {boolean} `true` if the node is an octal escape sequence
44
+ * @returns {boolean} `true` if at least one string literal within the node contains
45
+ * an octal or non-octal decimal escape sequence
45
46
  */
46
- function isOctalEscapeSequence(node) {
47
-
48
- // No need to check TemplateLiterals – would throw error with octal escape
49
- const isStringLiteral = node.type === "Literal" && typeof node.value === "string";
50
-
51
- if (!isStringLiteral) {
52
- return false;
47
+ function hasOctalOrNonOctalDecimalEscapeSequence(node) {
48
+ if (isConcatenation(node)) {
49
+ return (
50
+ hasOctalOrNonOctalDecimalEscapeSequence(node.left) ||
51
+ hasOctalOrNonOctalDecimalEscapeSequence(node.right)
52
+ );
53
53
  }
54
54
 
55
- return astUtils.hasOctalEscapeSequence(node.raw);
56
- }
57
-
58
- /**
59
- * Checks whether or not a node contains a octal escape sequence
60
- * @param {ASTNode} node A node to check
61
- * @returns {boolean} `true` if the node contains an octal escape sequence
62
- */
63
- function hasOctalEscapeSequence(node) {
64
- if (isConcatenation(node)) {
65
- return hasOctalEscapeSequence(node.left) || hasOctalEscapeSequence(node.right);
55
+ // No need to check TemplateLiterals – would throw parsing error
56
+ if (node.type === "Literal" && typeof node.value === "string") {
57
+ return astUtils.hasOctalOrNonOctalDecimalEscapeSequence(node.raw);
66
58
  }
67
59
 
68
- return isOctalEscapeSequence(node);
60
+ return false;
69
61
  }
70
62
 
71
63
  /**
@@ -237,7 +229,7 @@ module.exports = {
237
229
  function fixNonStringBinaryExpression(fixer, node) {
238
230
  const topBinaryExpr = getTopConcatBinaryExpression(node.parent);
239
231
 
240
- if (hasOctalEscapeSequence(topBinaryExpr)) {
232
+ if (hasOctalOrNonOctalDecimalEscapeSequence(topBinaryExpr)) {
241
233
  return null;
242
234
  }
243
235
 
@@ -282,9 +282,12 @@ module.exports = {
282
282
  description: settings.description
283
283
  },
284
284
  fix(fixer) {
285
- if (quoteOption === "backtick" && astUtils.hasOctalEscapeSequence(rawVal)) {
285
+ if (quoteOption === "backtick" && astUtils.hasOctalOrNonOctalDecimalEscapeSequence(rawVal)) {
286
286
 
287
- // An octal escape sequence in a template literal would produce syntax error, even in non-strict mode.
287
+ /*
288
+ * An octal or non-octal decimal escape sequence in a template literal would
289
+ * produce syntax error, even in non-strict mode.
290
+ */
288
291
  return null;
289
292
  }
290
293
 
@@ -5,8 +5,31 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ //------------------------------------------------------------------------------
9
+ // Requirements
10
+ //------------------------------------------------------------------------------
11
+
8
12
  const astUtils = require("./utils/ast-utils");
9
13
 
14
+ //------------------------------------------------------------------------------
15
+ // Helpers
16
+ //------------------------------------------------------------------------------
17
+
18
+ /**
19
+ * Checks whether the given node represents the body of a function.
20
+ * @param {ASTNode} node the node to check.
21
+ * @returns {boolean} `true` if the node is function body.
22
+ */
23
+ function isFunctionBody(node) {
24
+ const parent = node.parent;
25
+
26
+ return (
27
+ node.type === "BlockStatement" &&
28
+ astUtils.isFunction(parent) &&
29
+ parent.body === node
30
+ );
31
+ }
32
+
10
33
  //------------------------------------------------------------------------------
11
34
  // Rule Definition
12
35
  //------------------------------------------------------------------------------
@@ -82,13 +105,16 @@ module.exports = {
82
105
  }
83
106
 
84
107
  /**
85
- * Checks whether or not a given token is an arrow operator (=>) or a keyword
86
- * in order to avoid to conflict with `arrow-spacing` and `keyword-spacing`.
87
- * @param {Token} token A token to check.
88
- * @returns {boolean} `true` if the token is an arrow operator.
108
+ * Checks whether the spacing before the given block is already controlled by another rule:
109
+ * - `arrow-spacing` checks spaces after `=>`.
110
+ * - `keyword-spacing` checks spaces after keywords in certain contexts.
111
+ * @param {Token} precedingToken first token before the block.
112
+ * @param {ASTNode|Token} node `BlockStatement` node or `{` token of a `SwitchStatement` node.
113
+ * @returns {boolean} `true` if requiring or disallowing spaces before the given block could produce conflicts with other rules.
89
114
  */
90
- function isConflicted(token) {
91
- return (token.type === "Punctuator" && token.value === "=>") || token.type === "Keyword";
115
+ function isConflicted(precedingToken, node) {
116
+ return astUtils.isArrowToken(precedingToken) ||
117
+ astUtils.isKeywordToken(precedingToken) && !isFunctionBody(node);
92
118
  }
93
119
 
94
120
  /**
@@ -99,13 +125,12 @@ module.exports = {
99
125
  function checkPrecedingSpace(node) {
100
126
  const precedingToken = sourceCode.getTokenBefore(node);
101
127
 
102
- if (precedingToken && !isConflicted(precedingToken) && astUtils.isTokenOnSameLine(precedingToken, node)) {
128
+ if (precedingToken && !isConflicted(precedingToken, node) && astUtils.isTokenOnSameLine(precedingToken, node)) {
103
129
  const hasSpace = sourceCode.isSpaceBetweenTokens(precedingToken, node);
104
- const parent = context.getAncestors().pop();
105
130
  let requireSpace;
106
131
  let requireNoSpace;
107
132
 
108
- if (parent.type === "FunctionExpression" || parent.type === "FunctionDeclaration") {
133
+ if (isFunctionBody(node)) {
109
134
  requireSpace = alwaysFunctions;
110
135
  requireNoSpace = neverFunctions;
111
136
  } else if (node.type === "ClassBody") {
@@ -37,8 +37,10 @@ const LINEBREAKS = new Set(["\r\n", "\r", "\n", "\u2028", "\u2029"]);
37
37
  // A set of node types that can contain a list of statements
38
38
  const STATEMENT_LIST_PARENTS = new Set(["Program", "BlockStatement", "SwitchCase"]);
39
39
 
40
- const DECIMAL_INTEGER_PATTERN = /^(0|[1-9](?:_?\d)*)$/u;
41
- const OCTAL_ESCAPE_PATTERN = /^(?:[^\\]|\\[^0-7]|\\0(?![0-9]))*\\(?:[1-7]|0[0-9])/u;
40
+ const DECIMAL_INTEGER_PATTERN = /^(?:0|0[0-7]*[89]\d*|[1-9](?:_?\d)*)$/u;
41
+
42
+ // Tests the presence of at least one LegacyOctalEscapeSequence or NonOctalDecimalEscapeSequence in a raw string
43
+ const OCTAL_OR_NON_OCTAL_DECIMAL_ESCAPE_PATTERN = /^(?:[^\\]|\\.)*\\(?:[1-9]|0[0-9])/su;
42
44
 
43
45
  const LOGICAL_ASSIGNMENT_OPERATORS = new Set(["&&=", "||=", "??="]);
44
46
 
@@ -1244,6 +1246,8 @@ module.exports = {
1244
1246
  * 50 // true
1245
1247
  * 5_000 // true
1246
1248
  * 1_234_56 // true
1249
+ * 08 // true
1250
+ * 0192 // true
1247
1251
  * 5. // false
1248
1252
  * .5 // false
1249
1253
  * 5.0 // false
@@ -1609,6 +1613,17 @@ module.exports = {
1609
1613
  }
1610
1614
 
1611
1615
  case "LogicalExpression":
1616
+
1617
+ /*
1618
+ * If the && operator short-circuits, the left side was falsy and therefore not an error, and if it
1619
+ * doesn't short-circuit, it takes the value from the right side, so the right side must always be
1620
+ * a plausible error. A future improvement could verify that the left side could be truthy by
1621
+ * excluding falsy literals.
1622
+ */
1623
+ if (node.operator === "&&") {
1624
+ return module.exports.couldBeError(node.right);
1625
+ }
1626
+
1612
1627
  return module.exports.couldBeError(node.left) || module.exports.couldBeError(node.right);
1613
1628
 
1614
1629
  case "ConditionalExpression":
@@ -1764,17 +1779,19 @@ module.exports = {
1764
1779
  },
1765
1780
 
1766
1781
  /**
1767
- * Determines whether the given raw string contains an octal escape sequence.
1782
+ * Determines whether the given raw string contains an octal escape sequence
1783
+ * or a non-octal decimal escape sequence ("\8", "\9").
1768
1784
  *
1769
- * "\1", "\2" ... "\7"
1770
- * "\00", "\01" ... "\09"
1785
+ * "\1", "\2" ... "\7", "\8", "\9"
1786
+ * "\00", "\01" ... "\07", "\08", "\09"
1771
1787
  *
1772
1788
  * "\0", when not followed by a digit, is not an octal escape sequence.
1773
1789
  * @param {string} rawString A string in its raw representation.
1774
- * @returns {boolean} `true` if the string contains at least one octal escape sequence.
1790
+ * @returns {boolean} `true` if the string contains at least one octal escape sequence
1791
+ * or at least one non-octal decimal escape sequence.
1775
1792
  */
1776
- hasOctalEscapeSequence(rawString) {
1777
- return OCTAL_ESCAPE_PATTERN.test(rawString);
1793
+ hasOctalOrNonOctalDecimalEscapeSequence(rawString) {
1794
+ return OCTAL_OR_NON_OCTAL_DECIMAL_ESCAPE_PATTERN.test(rawString);
1778
1795
  },
1779
1796
 
1780
1797
  isLogicalExpression,
package/lib/rules/yoda.js CHANGED
@@ -265,36 +265,37 @@ module.exports = {
265
265
  * @returns {string} A string representation of the node with the sides and operator flipped
266
266
  */
267
267
  function getFlippedString(node) {
268
- const tokenBefore = sourceCode.getTokenBefore(node);
269
268
  const operatorToken = sourceCode.getFirstTokenBetween(
270
269
  node.left,
271
270
  node.right,
272
271
  token => token.value === node.operator
273
272
  );
274
- const textBeforeOperator = sourceCode
275
- .getText()
276
- .slice(
277
- sourceCode.getTokenBefore(operatorToken).range[1],
278
- operatorToken.range[0]
279
- );
280
- const textAfterOperator = sourceCode
281
- .getText()
282
- .slice(
283
- operatorToken.range[1],
284
- sourceCode.getTokenAfter(operatorToken).range[0]
285
- );
286
- const leftText = sourceCode
287
- .getText()
288
- .slice(
289
- node.range[0],
290
- sourceCode.getTokenBefore(operatorToken).range[1]
291
- );
273
+ const lastLeftToken = sourceCode.getTokenBefore(operatorToken);
292
274
  const firstRightToken = sourceCode.getTokenAfter(operatorToken);
293
- const rightText = sourceCode
294
- .getText()
295
- .slice(firstRightToken.range[0], node.range[1]);
296
275
 
276
+ const source = sourceCode.getText();
277
+
278
+ const leftText = source.slice(
279
+ node.range[0],
280
+ lastLeftToken.range[1]
281
+ );
282
+ const textBeforeOperator = source.slice(
283
+ lastLeftToken.range[1],
284
+ operatorToken.range[0]
285
+ );
286
+ const textAfterOperator = source.slice(
287
+ operatorToken.range[1],
288
+ firstRightToken.range[0]
289
+ );
290
+ const rightText = source.slice(
291
+ firstRightToken.range[0],
292
+ node.range[1]
293
+ );
294
+
295
+ const tokenBefore = sourceCode.getTokenBefore(node);
296
+ const tokenAfter = sourceCode.getTokenAfter(node);
297
297
  let prefix = "";
298
+ let suffix = "";
298
299
 
299
300
  if (
300
301
  tokenBefore &&
@@ -304,13 +305,22 @@ module.exports = {
304
305
  prefix = " ";
305
306
  }
306
307
 
308
+ if (
309
+ tokenAfter &&
310
+ node.range[1] === tokenAfter.range[0] &&
311
+ !astUtils.canTokensBeAdjacent(lastLeftToken, tokenAfter)
312
+ ) {
313
+ suffix = " ";
314
+ }
315
+
307
316
  return (
308
317
  prefix +
309
318
  rightText +
310
319
  textBeforeOperator +
311
320
  OPERATOR_FLIP_MAP[operatorToken.value] +
312
321
  textAfterOperator +
313
- leftText
322
+ leftText +
323
+ suffix
314
324
  );
315
325
  }
316
326
 
@@ -0,0 +1,8 @@
1
+ "<%- configName %>" is invalid syntax for a config specifier.
2
+
3
+ * If your intention is to extend from a configuration exported from the plugin, add the configuration name after a slash: e.g. "<%- configName %>/myConfig".
4
+ * If this is the name of a shareable config instead of a plugin, remove the "plugin:" prefix: i.e. "<%- configName.slice("plugin:".length) %>".
5
+
6
+ "<%- configName %>" was referenced from the config file in "<%- importerName %>".
7
+
8
+ If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint",
3
- "version": "7.8.1",
3
+ "version": "7.12.0",
4
4
  "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
5
5
  "description": "An AST-based pattern checker for JavaScript.",
6
6
  "bin": {
@@ -47,16 +47,16 @@
47
47
  "bugs": "https://github.com/eslint/eslint/issues/",
48
48
  "dependencies": {
49
49
  "@babel/code-frame": "^7.0.0",
50
- "@eslint/eslintrc": "^0.1.3",
50
+ "@eslint/eslintrc": "^0.2.0",
51
51
  "ajv": "^6.10.0",
52
52
  "chalk": "^4.0.0",
53
53
  "cross-spawn": "^7.0.2",
54
54
  "debug": "^4.0.1",
55
55
  "doctrine": "^3.0.0",
56
56
  "enquirer": "^2.3.5",
57
- "eslint-scope": "^5.1.0",
57
+ "eslint-scope": "^5.1.1",
58
58
  "eslint-utils": "^2.1.0",
59
- "eslint-visitor-keys": "^1.3.0",
59
+ "eslint-visitor-keys": "^2.0.0",
60
60
  "espree": "^7.3.0",
61
61
  "esquery": "^1.2.0",
62
62
  "esutils": "^2.0.2",
@@ -105,6 +105,7 @@
105
105
  "eslint-release": "^2.0.0",
106
106
  "eslump": "^2.0.0",
107
107
  "esprima": "^4.0.1",
108
+ "fs-teardown": "^0.1.0",
108
109
  "glob": "^7.1.6",
109
110
  "jsdoc": "^3.5.5",
110
111
  "karma": "^4.0.1",