eslint 5.13.0 → 5.15.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.
Files changed (148) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/README.md +68 -156
  3. package/lib/built-in-rules-index.js +1 -0
  4. package/lib/cli-engine.js +5 -2
  5. package/lib/config/config-file.js +27 -4
  6. package/lib/config/config-initializer.js +151 -144
  7. package/lib/config/config-ops.js +2 -0
  8. package/lib/config/config-validator.js +1 -1
  9. package/lib/config/plugins.js +1 -1
  10. package/lib/formatters/codeframe.js +1 -1
  11. package/lib/formatters/stylish.js +2 -2
  12. package/lib/linter.js +7 -4
  13. package/lib/rules/accessor-pairs.js +4 -2
  14. package/lib/rules/array-callback-return.js +4 -3
  15. package/lib/rules/arrow-body-style.js +1 -1
  16. package/lib/rules/arrow-parens.js +2 -1
  17. package/lib/rules/arrow-spacing.js +7 -6
  18. package/lib/rules/brace-style.js +2 -1
  19. package/lib/rules/camelcase.js +5 -4
  20. package/lib/rules/capitalized-comments.js +10 -14
  21. package/lib/rules/class-methods-use-this.js +1 -1
  22. package/lib/rules/comma-spacing.js +10 -4
  23. package/lib/rules/complexity.js +6 -7
  24. package/lib/rules/consistent-return.js +2 -1
  25. package/lib/rules/curly.js +1 -1
  26. package/lib/rules/default-case.js +2 -2
  27. package/lib/rules/dot-notation.js +7 -5
  28. package/lib/rules/eol-last.js +1 -1
  29. package/lib/rules/func-call-spacing.js +2 -2
  30. package/lib/rules/func-style.js +3 -2
  31. package/lib/rules/getter-return.js +3 -2
  32. package/lib/rules/handle-callback-err.js +1 -1
  33. package/lib/rules/id-length.js +3 -2
  34. package/lib/rules/id-match.js +7 -4
  35. package/lib/rules/indent-legacy.js +1 -1
  36. package/lib/rules/indent.js +9 -6
  37. package/lib/rules/jsx-quotes.js +2 -2
  38. package/lib/rules/key-spacing.js +1 -1
  39. package/lib/rules/keyword-spacing.js +14 -14
  40. package/lib/rules/line-comment-position.js +5 -4
  41. package/lib/rules/lines-around-comment.js +14 -14
  42. package/lib/rules/lines-between-class-members.js +2 -1
  43. package/lib/rules/max-depth.js +5 -5
  44. package/lib/rules/max-len.js +21 -14
  45. package/lib/rules/max-lines-per-function.js +13 -17
  46. package/lib/rules/max-lines.js +3 -5
  47. package/lib/rules/max-nested-callbacks.js +6 -7
  48. package/lib/rules/max-params.js +5 -5
  49. package/lib/rules/max-statements-per-line.js +3 -2
  50. package/lib/rules/max-statements.js +6 -7
  51. package/lib/rules/multiline-comment-style.js +9 -9
  52. package/lib/rules/new-cap.js +9 -6
  53. package/lib/rules/newline-per-chained-call.js +2 -1
  54. package/lib/rules/no-alert.js +1 -1
  55. package/lib/rules/no-bitwise.js +2 -1
  56. package/lib/rules/no-caller.js +1 -1
  57. package/lib/rules/no-confusing-arrow.js +1 -1
  58. package/lib/rules/no-constant-condition.js +2 -1
  59. package/lib/rules/no-dupe-keys.js +2 -2
  60. package/lib/rules/no-duplicate-imports.js +2 -1
  61. package/lib/rules/no-else-return.js +4 -3
  62. package/lib/rules/no-empty-character-class.js +1 -1
  63. package/lib/rules/no-empty.js +2 -1
  64. package/lib/rules/no-eval.js +1 -1
  65. package/lib/rules/no-extra-parens.js +7 -1
  66. package/lib/rules/no-fallthrough.js +4 -3
  67. package/lib/rules/no-implicit-coercion.js +10 -7
  68. package/lib/rules/no-implied-eval.js +1 -1
  69. package/lib/rules/no-invalid-regexp.js +2 -2
  70. package/lib/rules/no-irregular-whitespace.js +11 -7
  71. package/lib/rules/no-labels.js +6 -4
  72. package/lib/rules/no-lonely-if.js +1 -1
  73. package/lib/rules/no-magic-numbers.js +6 -3
  74. package/lib/rules/no-mixed-operators.js +6 -5
  75. package/lib/rules/no-mixed-requires.js +1 -1
  76. package/lib/rules/no-mixed-spaces-and-tabs.js +2 -2
  77. package/lib/rules/no-multi-spaces.js +2 -1
  78. package/lib/rules/no-octal-escape.js +1 -1
  79. package/lib/rules/no-octal.js +1 -1
  80. package/lib/rules/no-param-reassign.js +2 -2
  81. package/lib/rules/no-path-concat.js +1 -1
  82. package/lib/rules/no-plusplus.js +2 -1
  83. package/lib/rules/no-redeclare.js +2 -2
  84. package/lib/rules/no-regex-spaces.js +1 -1
  85. package/lib/rules/no-return-assign.js +1 -1
  86. package/lib/rules/no-self-assign.js +3 -2
  87. package/lib/rules/no-shadow-restricted-names.js +16 -2
  88. package/lib/rules/no-shadow.js +3 -3
  89. package/lib/rules/no-sync.js +2 -1
  90. package/lib/rules/no-tabs.js +4 -3
  91. package/lib/rules/no-template-curly-in-string.js +1 -1
  92. package/lib/rules/no-trailing-spaces.js +7 -5
  93. package/lib/rules/no-undef.js +2 -1
  94. package/lib/rules/no-underscore-dangle.js +6 -3
  95. package/lib/rules/no-unexpected-multiline.js +1 -1
  96. package/lib/rules/no-unmodified-loop-condition.js +5 -5
  97. package/lib/rules/no-unneeded-ternary.js +2 -1
  98. package/lib/rules/no-unsafe-finally.js +3 -3
  99. package/lib/rules/no-unused-expressions.js +8 -5
  100. package/lib/rules/no-unused-vars.js +6 -6
  101. package/lib/rules/no-use-before-define.js +2 -2
  102. package/lib/rules/no-useless-escape.js +1 -1
  103. package/lib/rules/no-useless-rename.js +3 -3
  104. package/lib/rules/no-var.js +1 -1
  105. package/lib/rules/no-warning-comments.js +6 -6
  106. package/lib/rules/object-property-newline.js +5 -3
  107. package/lib/rules/one-var.js +18 -35
  108. package/lib/rules/padded-blocks.js +32 -9
  109. package/lib/rules/padding-line-between-statements.js +4 -3
  110. package/lib/rules/prefer-arrow-callback.js +4 -2
  111. package/lib/rules/prefer-const.js +5 -5
  112. package/lib/rules/prefer-destructuring.js +56 -5
  113. package/lib/rules/prefer-named-capture-group.js +123 -0
  114. package/lib/rules/prefer-object-spread.js +1 -1
  115. package/lib/rules/prefer-promise-reject-errors.js +1 -1
  116. package/lib/rules/prefer-spread.js +2 -13
  117. package/lib/rules/prefer-template.js +3 -3
  118. package/lib/rules/quotes.js +2 -2
  119. package/lib/rules/require-jsdoc.js +13 -7
  120. package/lib/rules/semi-spacing.js +6 -8
  121. package/lib/rules/semi.js +4 -4
  122. package/lib/rules/sort-imports.js +6 -3
  123. package/lib/rules/sort-keys.js +13 -5
  124. package/lib/rules/sort-vars.js +2 -1
  125. package/lib/rules/space-infix-ops.js +2 -1
  126. package/lib/rules/space-unary-ops.js +5 -3
  127. package/lib/rules/spaced-comment.js +6 -5
  128. package/lib/rules/switch-colon-spacing.js +2 -2
  129. package/lib/rules/template-curly-spacing.js +2 -2
  130. package/lib/rules/use-isnan.js +1 -1
  131. package/lib/rules/valid-jsdoc.js +12 -7
  132. package/lib/rules/valid-typeof.js +2 -1
  133. package/lib/rules/vars-on-top.js +1 -1
  134. package/lib/rules/wrap-iife.js +3 -2
  135. package/lib/rules/yoda.js +6 -4
  136. package/lib/util/ajv.js +1 -0
  137. package/lib/util/ast-utils.js +12 -12
  138. package/lib/util/config-comment-parser.js +4 -4
  139. package/lib/util/glob-utils.js +3 -3
  140. package/lib/util/ignored-paths.js +4 -4
  141. package/lib/util/interpolate.js +1 -1
  142. package/lib/util/naming.js +6 -6
  143. package/lib/util/node-event-generator.js +1 -1
  144. package/lib/util/path-utils.js +2 -2
  145. package/lib/util/patterns/letters.js +1 -1
  146. package/lib/util/source-code.js +2 -2
  147. package/lib/util/xml-escape.js +1 -1
  148. package/package.json +25 -23
@@ -3,6 +3,7 @@
3
3
  * @author Ilya Volodin
4
4
  */
5
5
 
6
+
6
7
  "use strict";
7
8
 
8
9
  //------------------------------------------------------------------------------
@@ -28,6 +29,8 @@ const debug = require("debug")("eslint:config-initializer");
28
29
  // Private
29
30
  //------------------------------------------------------------------------------
30
31
 
32
+ const DEFAULT_ECMA_VERSION = 2018;
33
+
31
34
  /* istanbul ignore next: hard to test fs function */
32
35
  /**
33
36
  * Create .eslintrc file in the current working directory
@@ -149,7 +152,7 @@ function configureRules(answers, config) {
149
152
  bar.tick(0); // Shows the progress bar
150
153
 
151
154
  // Get the SourceCode of all chosen files
152
- const patterns = answers.patterns.split(/[\s]+/);
155
+ const patterns = answers.patterns.split(/[\s]+/u);
153
156
 
154
157
  try {
155
158
  sourceCodes = getSourceCodeOfFiles(patterns, { baseConfig: newConfig, useEslintrc: false }, total => {
@@ -239,43 +242,65 @@ function configureRules(answers, config) {
239
242
  * @returns {Object} config object
240
243
  */
241
244
  function processAnswers(answers) {
242
- let config = { rules: {}, env: {}, parserOptions: {} };
245
+ let config = {
246
+ rules: {},
247
+ env: {},
248
+ parserOptions: {},
249
+ extends: []
250
+ };
243
251
 
244
- config.parserOptions.ecmaVersion = answers.ecmaVersion;
245
- if (answers.ecmaVersion >= 2015) {
246
- if (answers.modules) {
247
- config.parserOptions.sourceType = "module";
248
- }
249
- config.env.es6 = true;
250
- }
252
+ // set the latest ECMAScript version
253
+ config.parserOptions.ecmaVersion = DEFAULT_ECMA_VERSION;
254
+ config.env.es6 = true;
255
+ config.globals = {
256
+ Atomics: "readonly",
257
+ SharedArrayBuffer: "readonly"
258
+ };
251
259
 
252
- if (answers.commonjs) {
260
+ // set the module type
261
+ if (answers.moduleType === "esm") {
262
+ config.parserOptions.sourceType = "module";
263
+ } else if (answers.moduleType === "commonjs") {
253
264
  config.env.commonjs = true;
254
265
  }
266
+
267
+ // add in browser and node environments if necessary
255
268
  answers.env.forEach(env => {
256
269
  config.env[env] = true;
257
270
  });
258
- if (answers.jsx) {
259
- config.parserOptions = config.parserOptions || {};
260
- config.parserOptions.ecmaFeatures = config.parserOptions.ecmaFeatures || {};
261
- config.parserOptions.ecmaFeatures.jsx = true;
262
- if (answers.react) {
263
- config.plugins = ["react"];
264
- config.parserOptions.ecmaVersion = 2018;
265
- }
271
+
272
+ // add in library information
273
+ if (answers.framework === "react") {
274
+ config.parserOptions.ecmaFeatures = {
275
+ jsx: true
276
+ };
277
+ config.plugins = ["react"];
278
+ } else if (answers.framework === "vue") {
279
+ config.plugins = ["vue"];
280
+ config.extends.push("plugin:vue/essential");
266
281
  }
267
282
 
268
- if (answers.source === "prompt") {
269
- config.extends = "eslint:recommended";
270
- config.rules.indent = ["error", answers.indent];
271
- config.rules.quotes = ["error", answers.quotes];
272
- config.rules["linebreak-style"] = ["error", answers.linebreak];
273
- config.rules.semi = ["error", answers.semi ? "always" : "never"];
283
+ // setup rules based on problems/style enforcement preferences
284
+ if (answers.purpose === "problems") {
285
+ config.extends.unshift("eslint:recommended");
286
+ } else if (answers.purpose === "style") {
287
+ if (answers.source === "prompt") {
288
+ config.extends.unshift("eslint:recommended");
289
+ config.rules.indent = ["error", answers.indent];
290
+ config.rules.quotes = ["error", answers.quotes];
291
+ config.rules["linebreak-style"] = ["error", answers.linebreak];
292
+ config.rules.semi = ["error", answers.semi ? "always" : "never"];
293
+ } else if (answers.source === "auto") {
294
+ config = configureRules(answers, config);
295
+ config = autoconfig.extendFromRecommended(config);
296
+ }
274
297
  }
275
298
 
276
- if (answers.source === "auto") {
277
- config = configureRules(answers, config);
278
- config = autoconfig.extendFromRecommended(config);
299
+ // normalize extends
300
+ if (config.extends.length === 0) {
301
+ delete config.extends;
302
+ } else if (config.extends.length === 1) {
303
+ config.extends = config.extends[0];
279
304
  }
280
305
 
281
306
  ConfigOps.normalizeToStrings(config);
@@ -324,7 +349,7 @@ function getLocalESLintVersion() {
324
349
  * @returns {string} The shareable config name.
325
350
  */
326
351
  function getStyleGuideName(answers) {
327
- if (answers.styleguide === "airbnb" && !answers.airbnbReact) {
352
+ if (answers.styleguide === "airbnb" && answers.framework !== "react") {
328
353
  return "airbnb-base";
329
354
  }
330
355
  return answers.styleguide;
@@ -417,16 +442,62 @@ function askInstallModules(modules, packageJsonExists) {
417
442
  function promptUser() {
418
443
 
419
444
  return inquirer.prompt([
445
+ {
446
+ type: "list",
447
+ name: "purpose",
448
+ message: "How would you like to use ESLint?",
449
+ default: "problems",
450
+ choices: [
451
+ { name: "To check syntax only", value: "syntax" },
452
+ { name: "To check syntax and find problems", value: "problems" },
453
+ { name: "To check syntax, find problems, and enforce code style", value: "style" }
454
+ ]
455
+ },
456
+ {
457
+ type: "list",
458
+ name: "moduleType",
459
+ message: "What type of modules does your project use?",
460
+ default: "esm",
461
+ choices: [
462
+ { name: "JavaScript modules (import/export)", value: "esm" },
463
+ { name: "CommonJS (require/exports)", value: "commonjs" },
464
+ { name: "None of these", value: "none" }
465
+ ]
466
+ },
467
+ {
468
+ type: "list",
469
+ name: "framework",
470
+ message: "Which framework does your project use?",
471
+ default: "react",
472
+ choices: [
473
+ { name: "React", value: "react" },
474
+ { name: "Vue.js", value: "vue" },
475
+ { name: "None of these", value: "none" }
476
+ ]
477
+ },
478
+ {
479
+ type: "checkbox",
480
+ name: "env",
481
+ message: "Where does your code run?",
482
+ default: ["browser"],
483
+ choices: [
484
+ { name: "Browser", value: "browser" },
485
+ { name: "Node", value: "node" }
486
+ ]
487
+ },
420
488
  {
421
489
  type: "list",
422
490
  name: "source",
423
- message: "How would you like to configure ESLint?",
424
- default: "prompt",
491
+ message: "How would you like to define a style for your project?",
492
+ default: "guide",
425
493
  choices: [
426
494
  { name: "Use a popular style guide", value: "guide" },
427
495
  { name: "Answer questions about your style", value: "prompt" },
428
496
  { name: "Inspect your JavaScript file(s)", value: "auto" }
429
- ]
497
+ ],
498
+ when(answers) {
499
+ return answers.purpose === "style";
500
+ }
430
501
  },
431
502
  {
432
503
  type: "list",
@@ -442,15 +513,6 @@ function promptUser() {
442
513
  return answers.source === "guide" && answers.packageJsonExists;
443
514
  }
444
515
  },
445
- {
446
- type: "confirm",
447
- name: "airbnbReact",
448
- message: "Do you use React?",
449
- default: false,
450
- when(answers) {
451
- return answers.styleguide === "airbnb";
452
- }
453
- },
454
516
  {
455
517
  type: "input",
456
518
  name: "patterns",
@@ -470,10 +532,7 @@ function promptUser() {
470
532
  name: "format",
471
533
  message: "What format do you want your config file to be in?",
472
534
  default: "JavaScript",
473
- choices: ["JavaScript", "YAML", "JSON"],
474
- when(answers) {
475
- return ((answers.source === "guide" && answers.packageJsonExists) || answers.source === "auto");
476
- }
535
+ choices: ["JavaScript", "YAML", "JSON"]
477
536
  },
478
537
  {
479
538
  type: "confirm",
@@ -492,6 +551,15 @@ function promptUser() {
492
551
  }
493
552
  ]).then(earlyAnswers => {
494
553
 
554
+ // early exit if no style guide is necessary
555
+ if (earlyAnswers.purpose !== "style") {
556
+ const config = processAnswers(earlyAnswers);
557
+ const modules = getModulesList(config);
558
+
559
+ return askInstallModules(modules, earlyAnswers.packageJsonExists)
560
+ .then(() => writeFile(config, earlyAnswers.format));
561
+ }
562
+
495
563
  // early exit if you are using a style guide
496
564
  if (earlyAnswers.source === "guide") {
497
565
  if (!earlyAnswers.packageJsonExists) {
@@ -501,130 +569,69 @@ function promptUser() {
501
569
  if (earlyAnswers.installESLint === false && !semver.satisfies(earlyAnswers.localESLintVersion, earlyAnswers.requiredESLintVersionRange)) {
502
570
  log.info(`Note: it might not work since ESLint's version is mismatched with the ${earlyAnswers.styleguide} config.`);
503
571
  }
504
- if (earlyAnswers.styleguide === "airbnb" && !earlyAnswers.airbnbReact) {
572
+ if (earlyAnswers.styleguide === "airbnb" && earlyAnswers.framework !== "react") {
505
573
  earlyAnswers.styleguide = "airbnb-base";
506
574
  }
507
575
 
508
- const config = getConfigForStyleGuide(earlyAnswers.styleguide);
576
+ const config = ConfigOps.merge(processAnswers(earlyAnswers), getConfigForStyleGuide(earlyAnswers.styleguide));
509
577
  const modules = getModulesList(config);
510
578
 
511
579
  return askInstallModules(modules, earlyAnswers.packageJsonExists)
512
580
  .then(() => writeFile(config, earlyAnswers.format));
581
+
513
582
  }
514
583
 
515
- // continue with the questions otherwise...
584
+ if (earlyAnswers.source === "auto") {
585
+ const combinedAnswers = Object.assign({}, earlyAnswers);
586
+ const config = processAnswers(combinedAnswers);
587
+ const modules = getModulesList(config);
588
+
589
+ return askInstallModules(modules).then(() => writeFile(config, earlyAnswers.format));
590
+ }
591
+
592
+ // continue with the style questions otherwise...
516
593
  return inquirer.prompt([
517
594
  {
518
595
  type: "list",
519
- name: "ecmaVersion",
520
- message: "Which version of ECMAScript do you use?",
521
- choices: [
522
- { name: "ES3", value: 3 },
523
- { name: "ES5", value: 5 },
524
- { name: "ES2015", value: 2015 },
525
- { name: "ES2016", value: 2016 },
526
- { name: "ES2017", value: 2017 },
527
- { name: "ES2018", value: 2018 }
528
- ],
529
- default: 1 // This is the index in the choices list
596
+ name: "indent",
597
+ message: "What style of indentation do you use?",
598
+ default: "tab",
599
+ choices: [{ name: "Tabs", value: "tab" }, { name: "Spaces", value: 4 }]
530
600
  },
531
601
  {
532
- type: "confirm",
533
- name: "modules",
534
- message: "Are you using ES6 modules?",
535
- default: false,
536
- when(answers) {
537
- return answers.ecmaVersion >= 2015;
538
- }
539
- },
540
- {
541
- type: "checkbox",
542
- name: "env",
543
- message: "Where will your code run?",
544
- default: ["browser"],
545
- choices: [{ name: "Browser", value: "browser" }, { name: "Node", value: "node" }]
602
+ type: "list",
603
+ name: "quotes",
604
+ message: "What quotes do you use for strings?",
605
+ default: "double",
606
+ choices: [{ name: "Double", value: "double" }, { name: "Single", value: "single" }]
546
607
  },
547
608
  {
548
- type: "confirm",
549
- name: "commonjs",
550
- message: "Do you use CommonJS?",
551
- default: false,
552
- when(answers) {
553
- return answers.env.some(env => env === "browser");
554
- }
609
+ type: "list",
610
+ name: "linebreak",
611
+ message: "What line endings do you use?",
612
+ default: "unix",
613
+ choices: [{ name: "Unix", value: "unix" }, { name: "Windows", value: "windows" }]
555
614
  },
556
615
  {
557
616
  type: "confirm",
558
- name: "jsx",
559
- message: "Do you use JSX?",
560
- default: false
617
+ name: "semi",
618
+ message: "Do you require semicolons?",
619
+ default: true
561
620
  },
562
621
  {
563
- type: "confirm",
564
- name: "react",
565
- message: "Do you use React?",
566
- default: false,
567
- when(answers) {
568
- return answers.jsx;
569
- }
570
- }
571
- ]).then(secondAnswers => {
572
-
573
- // early exit if you are using automatic style generation
574
- if (earlyAnswers.source === "auto") {
575
- const combinedAnswers = Object.assign({}, earlyAnswers, secondAnswers);
576
-
577
- const config = processAnswers(combinedAnswers);
578
-
579
- const modules = getModulesList(config);
580
-
581
- return askInstallModules(modules).then(() => writeFile(config, earlyAnswers.format));
622
+ type: "list",
623
+ name: "format",
624
+ message: "What format do you want your config file to be in?",
625
+ default: "JavaScript",
626
+ choices: ["JavaScript", "YAML", "JSON"]
582
627
  }
628
+ ]).then(answers => {
629
+ const totalAnswers = Object.assign({}, earlyAnswers, answers);
583
630
 
584
- // continue with the style questions otherwise...
585
- return inquirer.prompt([
586
- {
587
- type: "list",
588
- name: "indent",
589
- message: "What style of indentation do you use?",
590
- default: "tab",
591
- choices: [{ name: "Tabs", value: "tab" }, { name: "Spaces", value: 4 }]
592
- },
593
- {
594
- type: "list",
595
- name: "quotes",
596
- message: "What quotes do you use for strings?",
597
- default: "double",
598
- choices: [{ name: "Double", value: "double" }, { name: "Single", value: "single" }]
599
- },
600
- {
601
- type: "list",
602
- name: "linebreak",
603
- message: "What line endings do you use?",
604
- default: "unix",
605
- choices: [{ name: "Unix", value: "unix" }, { name: "Windows", value: "windows" }]
606
- },
607
- {
608
- type: "confirm",
609
- name: "semi",
610
- message: "Do you require semicolons?",
611
- default: true
612
- },
613
- {
614
- type: "list",
615
- name: "format",
616
- message: "What format do you want your config file to be in?",
617
- default: "JavaScript",
618
- choices: ["JavaScript", "YAML", "JSON"]
619
- }
620
- ]).then(answers => {
621
- const totalAnswers = Object.assign({}, earlyAnswers, secondAnswers, answers);
622
-
623
- const config = processAnswers(totalAnswers);
624
- const modules = getModulesList(config);
631
+ const config = processAnswers(totalAnswers);
632
+ const modules = getModulesList(config);
625
633
 
626
- return askInstallModules(modules).then(() => writeFile(config, answers.format));
627
- });
634
+ return askInstallModules(modules).then(() => writeFile(config, answers.format));
628
635
  });
629
636
  });
630
637
  }
@@ -386,12 +386,14 @@ module.exports = {
386
386
  case true:
387
387
  case "true":
388
388
  case "writeable":
389
+ case "writable":
389
390
  return "writeable";
390
391
 
391
392
  case null:
392
393
  case false:
393
394
  case "false":
394
395
  case "readable":
396
+ case "readonly":
395
397
  return "readable";
396
398
 
397
399
  // Fallback to minimize compatibility impact
@@ -76,7 +76,7 @@ function validateRuleSeverity(options) {
76
76
  return normSeverity;
77
77
  }
78
78
 
79
- throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${util.inspect(severity).replace(/'/g, "\"").replace(/\n/g, "")}').\n`);
79
+ throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${util.inspect(severity).replace(/'/gu, "\"").replace(/\n/gu, "")}').\n`);
80
80
 
81
81
  }
82
82
 
@@ -84,7 +84,7 @@ class Plugins {
84
84
  const shortName = naming.getShorthandName(longName, "eslint-plugin");
85
85
  let plugin = null;
86
86
 
87
- if (pluginName.match(/\s+/)) {
87
+ if (pluginName.match(/\s+/u)) {
88
88
  const whitespaceError = new Error(`Whitespace found in plugin name '${pluginName}'`);
89
89
 
90
90
  whitespaceError.messageTemplate = "whitespace-found";
@@ -47,7 +47,7 @@ function formatFilePath(filePath, line, column) {
47
47
  */
48
48
  function formatMessage(message, parentResult) {
49
49
  const type = (message.fatal || message.severity === 2) ? chalk.red("error") : chalk.yellow("warning");
50
- const msg = `${chalk.bold(message.message.replace(/([^ ])\.$/, "$1"))}`;
50
+ const msg = `${chalk.bold(message.message.replace(/([^ ])\.$/u, "$1"))}`;
51
51
  const ruleId = message.fatal ? "" : chalk.dim(`(${message.ruleId})`);
52
52
  const filePath = formatFilePath(parentResult.filePath, message.line, message.column);
53
53
  const sourceCode = parentResult.output ? parentResult.output : parentResult.source;
@@ -65,7 +65,7 @@ module.exports = function(results) {
65
65
  message.line || 0,
66
66
  message.column || 0,
67
67
  messageType,
68
- message.message.replace(/([^ ])\.$/, "$1"),
68
+ message.message.replace(/([^ ])\.$/u, "$1"),
69
69
  chalk.dim(message.ruleId || "")
70
70
  ];
71
71
  }),
@@ -75,7 +75,7 @@ module.exports = function(results) {
75
75
  return stripAnsi(str).length;
76
76
  }
77
77
  }
78
- ).split("\n").map(el => el.replace(/(\d+)\s+(\d+)/, (m, p1, p2) => chalk.dim(`${p1}:${p2}`))).join("\n")}\n\n`;
78
+ ).split("\n").map(el => el.replace(/(\d+)\s+(\d+)/u, (m, p1, p2) => chalk.dim(`${p1}:${p2}`))).join("\n")}\n\n`;
79
79
  });
80
80
 
81
81
  const total = errorCount + warningCount;
package/lib/linter.js CHANGED
@@ -11,6 +11,7 @@
11
11
 
12
12
  const eslintScope = require("eslint-scope"),
13
13
  evk = require("eslint-visitor-keys"),
14
+ espree = require("espree"),
14
15
  lodash = require("lodash"),
15
16
  CodePathAnalyzer = require("./code-path-analysis/code-path-analyzer"),
16
17
  ConfigOps = require("./config/config-ops"),
@@ -163,7 +164,7 @@ function getDirectiveComments(filename, ast, ruleMapper) {
163
164
 
164
165
  ast.comments.filter(token => token.type !== "Shebang").forEach(comment => {
165
166
  const trimmedCommentText = comment.value.trim();
166
- const match = /^(eslint(-\w+){0,3}|exported|globals?)(\s|$)/.exec(trimmedCommentText);
167
+ const match = /^(eslint(-\w+){0,3}|exported|globals?)(\s|$)/u.exec(trimmedCommentText);
167
168
 
168
169
  if (!match) {
169
170
  return;
@@ -171,7 +172,7 @@ function getDirectiveComments(filename, ast, ruleMapper) {
171
172
 
172
173
  const directiveValue = trimmedCommentText.slice(match.index + match[1].length);
173
174
 
174
- if (/^eslint-disable-(next-)?line$/.test(match[1])) {
175
+ if (/^eslint-disable-(next-)?line$/u.test(match[1])) {
175
176
  if (comment.loc.start.line === comment.loc.end.line) {
176
177
  const directiveType = match[1].slice("eslint-".length);
177
178
 
@@ -275,7 +276,7 @@ function normalizeEcmaVersion(ecmaVersion, isModule) {
275
276
  return ecmaVersion;
276
277
  }
277
278
 
278
- const eslintEnvPattern = /\/\*\s*eslint-env\s(.+?)\*\//g;
279
+ const eslintEnvPattern = /\/\*\s*eslint-env\s(.+?)\*\//gu;
279
280
 
280
281
  /**
281
282
  * Checks whether or not there is a comment which has "eslint-env *" in a given text.
@@ -497,7 +498,7 @@ function parse(text, providedParserOptions, parserName, parserMap, filePath) {
497
498
  } catch (ex) {
498
499
 
499
500
  // If the message includes a leading line number, strip it:
500
- const message = `Parsing error: ${ex.message.replace(/^line \d+:/i, "").trim()}`;
501
+ const message = `Parsing error: ${ex.message.replace(/^line \d+:/iu, "").trim()}`;
501
502
 
502
503
  return {
503
504
  success: false,
@@ -776,6 +777,8 @@ module.exports = class Linter {
776
777
  ruleMaps.set(this, new Rules());
777
778
  this.version = pkg.version;
778
779
  this.environments = new Environments();
780
+
781
+ this.defineParser("espree", espree);
779
782
  }
780
783
 
781
784
  /**
@@ -85,10 +85,12 @@ module.exports = {
85
85
  type: "object",
86
86
  properties: {
87
87
  getWithoutSet: {
88
- type: "boolean"
88
+ type: "boolean",
89
+ default: false
89
90
  },
90
91
  setWithoutGet: {
91
- type: "boolean"
92
+ type: "boolean",
93
+ default: true
92
94
  }
93
95
  },
94
96
  additionalProperties: false
@@ -17,8 +17,8 @@ const astUtils = require("../util/ast-utils");
17
17
  // Helpers
18
18
  //------------------------------------------------------------------------------
19
19
 
20
- const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/;
21
- const TARGET_METHODS = /^(?:every|filter|find(?:Index)?|map|reduce(?:Right)?|some|sort)$/;
20
+ const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/u;
21
+ const TARGET_METHODS = /^(?:every|filter|find(?:Index)?|map|reduce(?:Right)?|some|sort)$/u;
22
22
 
23
23
  /**
24
24
  * Checks a given code path segment is reachable.
@@ -155,7 +155,8 @@ module.exports = {
155
155
  type: "object",
156
156
  properties: {
157
157
  allowImplicit: {
158
- type: "boolean"
158
+ type: "boolean",
159
+ default: false
159
160
  }
160
161
  },
161
162
  additionalProperties: false
@@ -82,7 +82,7 @@ module.exports = {
82
82
  * @returns {boolean} `true` if it changes semantics if `;` or `}` followed by the token are removed.
83
83
  */
84
84
  function hasASIProblem(token) {
85
- return token && token.type === "Punctuator" && /^[([/`+-]/.test(token.value);
85
+ return token && token.type === "Punctuator" && /^[([/`+-]/u.test(token.value);
86
86
  }
87
87
 
88
88
  /**
@@ -35,7 +35,8 @@ module.exports = {
35
35
  type: "object",
36
36
  properties: {
37
37
  requireForBlockBody: {
38
- type: "boolean"
38
+ type: "boolean",
39
+ default: false
39
40
  }
40
41
  },
41
42
  additionalProperties: false
@@ -32,10 +32,12 @@ module.exports = {
32
32
  type: "object",
33
33
  properties: {
34
34
  before: {
35
- type: "boolean"
35
+ type: "boolean",
36
+ default: true
36
37
  },
37
38
  after: {
38
- type: "boolean"
39
+ type: "boolean",
40
+ default: true
39
41
  }
40
42
  },
41
43
  additionalProperties: false
@@ -54,11 +56,10 @@ module.exports = {
54
56
  create(context) {
55
57
 
56
58
  // merge rules with default
57
- const rule = { before: true, after: true },
58
- option = context.options[0] || {};
59
+ const rule = Object.assign({}, context.options[0]);
59
60
 
60
- rule.before = option.before !== false;
61
- rule.after = option.after !== false;
61
+ rule.before = rule.before !== false;
62
+ rule.after = rule.after !== false;
62
63
 
63
64
  const sourceCode = context.getSourceCode();
64
65
 
@@ -30,7 +30,8 @@ module.exports = {
30
30
  type: "object",
31
31
  properties: {
32
32
  allowSingleLine: {
33
- type: "boolean"
33
+ type: "boolean",
34
+ default: false
34
35
  }
35
36
  },
36
37
  additionalProperties: false
@@ -25,7 +25,8 @@ module.exports = {
25
25
  type: "object",
26
26
  properties: {
27
27
  ignoreDestructuring: {
28
- type: "boolean"
28
+ type: "boolean",
29
+ default: false
29
30
  },
30
31
  properties: {
31
32
  enum: ["always", "never"]
@@ -54,7 +55,7 @@ module.exports = {
54
55
 
55
56
  const options = context.options[0] || {};
56
57
  let properties = options.properties || "";
57
- const ignoreDestructuring = options.ignoreDestructuring || false;
58
+ const ignoreDestructuring = options.ignoreDestructuring;
58
59
  const allow = options.allow || [];
59
60
 
60
61
  if (properties !== "always" && properties !== "never") {
@@ -89,7 +90,7 @@ module.exports = {
89
90
  */
90
91
  function isAllowed(name) {
91
92
  return allow.findIndex(
92
- entry => name === entry || name.match(new RegExp(entry))
93
+ entry => name === entry || name.match(new RegExp(entry)) // eslint-disable-line require-unicode-regexp
93
94
  ) !== -1;
94
95
  }
95
96
 
@@ -141,7 +142,7 @@ module.exports = {
141
142
  * private/protected identifiers, strip them before checking if underscored
142
143
  */
143
144
  const name = node.name,
144
- nameIsUnderscored = isUnderscored(name.replace(/^_+|_+$/g, "")),
145
+ nameIsUnderscored = isUnderscored(name.replace(/^_+|_+$/gu, "")),
145
146
  effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent;
146
147
 
147
148
  // First, we ignore the node if it match the ignore list