Browse Source

tools: update ESLint to 2.9.0

ESLint 2.9.0 fixes some minor bugs that we have been experiencing and
introduces some new rules that we may wish to consider.

PR-URL: https://github.com/nodejs/node/pull/6498
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Roman Reiss <me@silverwind.io>
v6.x
Rich Trott 9 years ago
committed by Evan Lucas
parent
commit
d629f265fe
  1. 92
      tools/eslint/CHANGELOG.md
  2. 2
      tools/eslint/LICENSE
  3. 30
      tools/eslint/README.md
  4. 2
      tools/eslint/bin/eslint.js
  5. 2
      tools/eslint/conf/cli-options.js
  6. 1
      tools/eslint/conf/environments.js
  7. 2
      tools/eslint/conf/eslint.json
  8. 2
      tools/eslint/lib/ast-utils.js
  9. 87
      tools/eslint/lib/cli-engine.js
  10. 2
      tools/eslint/lib/code-path-analysis/code-path-analyzer.js
  11. 17
      tools/eslint/lib/code-path-analysis/code-path-segment.js
  12. 2
      tools/eslint/lib/code-path-analysis/code-path-state.js
  13. 2
      tools/eslint/lib/code-path-analysis/code-path.js
  14. 2
      tools/eslint/lib/code-path-analysis/debug-helpers.js
  15. 2
      tools/eslint/lib/code-path-analysis/fork-context.js
  16. 2
      tools/eslint/lib/code-path-analysis/id-generator.js
  17. 5
      tools/eslint/lib/config.js
  18. 8
      tools/eslint/lib/config/autoconfig.js
  19. 2
      tools/eslint/lib/config/config-file.js
  20. 21
      tools/eslint/lib/config/config-initializer.js
  21. 2
      tools/eslint/lib/config/config-ops.js
  22. 2
      tools/eslint/lib/config/config-rule.js
  23. 16
      tools/eslint/lib/config/config-validator.js
  24. 2
      tools/eslint/lib/config/environments.js
  25. 2
      tools/eslint/lib/config/plugins.js
  26. 9
      tools/eslint/lib/eslint.js
  27. 4
      tools/eslint/lib/file-finder.js
  28. 1
      tools/eslint/lib/formatters/html.js
  29. 1
      tools/eslint/lib/formatters/json.js
  30. 1
      tools/eslint/lib/formatters/table.js
  31. 1
      tools/eslint/lib/formatters/unix.js
  32. 2
      tools/eslint/lib/formatters/visualstudio.js
  33. 1
      tools/eslint/lib/ignored-paths.js
  34. 4
      tools/eslint/lib/logging.js
  35. 8
      tools/eslint/lib/options.js
  36. 2
      tools/eslint/lib/rule-context.js
  37. 17
      tools/eslint/lib/rules/accessor-pairs.js
  38. 28
      tools/eslint/lib/rules/array-bracket-spacing.js
  39. 24
      tools/eslint/lib/rules/array-callback-return.js
  40. 28
      tools/eslint/lib/rules/arrow-body-style.js
  41. 27
      tools/eslint/lib/rules/arrow-parens.js
  42. 47
      tools/eslint/lib/rules/arrow-spacing.js
  43. 34
      tools/eslint/lib/rules/block-scoped-var.js
  44. 23
      tools/eslint/lib/rules/block-spacing.js
  45. 68
      tools/eslint/lib/rules/brace-style.js
  46. 25
      tools/eslint/lib/rules/callback-return.js
  47. 39
      tools/eslint/lib/rules/camelcase.js
  48. 87
      tools/eslint/lib/rules/comma-dangle.js
  49. 49
      tools/eslint/lib/rules/comma-spacing.js
  50. 50
      tools/eslint/lib/rules/comma-style.js
  51. 88
      tools/eslint/lib/rules/complexity.js
  52. 27
      tools/eslint/lib/rules/computed-property-spacing.js
  53. 22
      tools/eslint/lib/rules/consistent-return.js
  54. 36
      tools/eslint/lib/rules/consistent-this.js
  55. 184
      tools/eslint/lib/rules/constructor-super.js
  56. 79
      tools/eslint/lib/rules/curly.js
  57. 34
      tools/eslint/lib/rules/default-case.js
  58. 27
      tools/eslint/lib/rules/dot-location.js
  59. 44
      tools/eslint/lib/rules/dot-notation.js
  60. 28
      tools/eslint/lib/rules/eol-last.js
  61. 28
      tools/eslint/lib/rules/eqeqeq.js
  62. 20
      tools/eslint/lib/rules/func-names.js
  63. 51
      tools/eslint/lib/rules/func-style.js
  64. 56
      tools/eslint/lib/rules/generator-star-spacing.js
  65. 19
      tools/eslint/lib/rules/global-require.js
  66. 18
      tools/eslint/lib/rules/guard-for-in.js
  67. 32
      tools/eslint/lib/rules/handle-callback-err.js
  68. 35
      tools/eslint/lib/rules/id-blacklist.js
  69. 95
      tools/eslint/lib/rules/id-length.js
  70. 81
      tools/eslint/lib/rules/id-match.js
  71. 163
      tools/eslint/lib/rules/indent.js
  72. 79
      tools/eslint/lib/rules/init-declarations.js
  73. 29
      tools/eslint/lib/rules/jsx-quotes.js
  74. 146
      tools/eslint/lib/rules/key-spacing.js
  75. 68
      tools/eslint/lib/rules/keyword-spacing.js
  76. 31
      tools/eslint/lib/rules/linebreak-style.js
  77. 97
      tools/eslint/lib/rules/lines-around-comment.js
  78. 89
      tools/eslint/lib/rules/max-depth.js
  79. 111
      tools/eslint/lib/rules/max-len.js
  80. 67
      tools/eslint/lib/rules/max-nested-callbacks.js
  81. 70
      tools/eslint/lib/rules/max-params.js
  82. 45
      tools/eslint/lib/rules/max-statements-per-line.js
  83. 89
      tools/eslint/lib/rules/max-statements.js
  84. 74
      tools/eslint/lib/rules/new-cap.js
  85. 18
      tools/eslint/lib/rules/new-parens.js
  86. 29
      tools/eslint/lib/rules/newline-after-var.js
  87. 53
      tools/eslint/lib/rules/newline-before-return.js
  88. 38
      tools/eslint/lib/rules/newline-per-chained-call.js
  89. 22
      tools/eslint/lib/rules/no-alert.js
  90. 20
      tools/eslint/lib/rules/no-array-constructor.js
  91. 56
      tools/eslint/lib/rules/no-bitwise.js
  92. 18
      tools/eslint/lib/rules/no-caller.js
  93. 19
      tools/eslint/lib/rules/no-case-declarations.js
  94. 18
      tools/eslint/lib/rules/no-catch-shadow.js
  95. 21
      tools/eslint/lib/rules/no-class-assign.js
  96. 42
      tools/eslint/lib/rules/no-cond-assign.js
  97. 52
      tools/eslint/lib/rules/no-confusing-arrow.js
  98. 49
      tools/eslint/lib/rules/no-console.js
  99. 19
      tools/eslint/lib/rules/no-const-assign.js
  100. 70
      tools/eslint/lib/rules/no-constant-condition.js

92
tools/eslint/CHANGELOG.md

@ -1,3 +1,95 @@
v2.9.0 - April 29, 2016
* a8a2cd8 Fix: Avoid autoconfig crashes from inline comments (fixes #5992) (#5999) (Ian VanSchooten)
* 23b00e0 Upgrade: npm-license to 0.3.2 (fixes #5996) (#5998) (alberto)
* 377167d Upgrade: ignore to 3.1.2 (fixes #5979) (#5988) (alberto)
* 141b778 Fix: no-control-regex literal handling fixed. (fixes #5737) (#5943) (Efe Gürkan YALAMAN)
* 577757d Fix: Clarify color option (fixes #5928) (#5974) (Grant Snodgrass)
* e7e6581 Docs: Update CLA link (#5980) (Gustav Nikolaj)
* 0be26bc Build: Add nodejs 6 to travis (fixes #5971) (#5973) (Gyandeep Singh)
* e606523 New: Rule `no-unsafe-finally` (fixes #5808) (#5932) (Onur Temizkan)
* 42d1ecc Chore: Add metadata to existing rules - Batch 7 (refs #5417) (#5969) (Vitor Balocco)
* e2ad1ec Update: object-shorthand lints computed methods (fixes #5871) (#5963) (Chris Sauvé)
* d24516a Chore: Add metadata to existing rules - Batch 6 (refs #5417) (#5966) (Vitor Balocco)
* 1e7a3ef Fix: `id-match` false positive in property values (fixes #5885) (#5960) (Mike Sherov)
* 51ddd4b Update: Use process @abstract when processing @return (fixes #5941) (#5945) (Simon Schick)
* 52a4bea Update: Add autofix for `no-whitespace-before-property` (fixes #5927) (#5951) (alberto)
* 46e058d Docs: Correct typo in configuring.md (#5957) (Nick S. Plekhanov)
* 5f8abab Chore: Add metadata to existing rules - Batch 5 (refs #5417) (#5944) (Vitor Balocco)
* 0562f77 Chore: Add missing newlines to test cases (fixes #5947) (Rich Trott)
* fc78e78 Chore: Enable quote-props rule in eslint-config-eslint (refs #5188) (#5938) (Gyandeep Singh)
* 43f6d05 Docs: Update docs to refer to column (#5937) (Sashko Stubailo)
* 586478e Update: Add autofix for `comma-dangle` (fixes #3805) (#5925) (alberto)
* a4f9c5a Docs: Distinguish examples in rules under Stylistic Issues part 3 (Kenneth Williams)
* e7c0737 Chore: Enable no-console rule in eslint-config-eslint (refs #5188) (Kevin Partington)
* 0023fe6 Build: Add “chore” to commit tags (fixes #5880) (#5929) (Mike Sherov)
* 25d626a Upgrade: espree 3.1.4 (fixes #5923, fixes #5756) (Kai Cataldo)
* a01b412 New: Add `no-useless-computed-key` rule (fixes #5402) (Burak Yigit Kaya)
* 9afb9cb Chore: Remove workaround for espree and escope bugs (fixes #5852) (alberto)
* 3ffc582 Chore: Update copyright and license info (alberto)
* 249eb40 Docs: Clarify init sets up local installation (fixes #5874) (Kai Cataldo)
* 6cd8c86 Docs: Describe options in rules under Possible Errors part 1 (Mark Pedrotti)
* f842d18 Fix: `no-this-before-super` crash on unreachable paths (fixes #5894) (Toru Nagashima)
* a02960b Docs: Fix missing delimiter in README links (Kevin Partington)
* 3a9e72c Docs: Update developer guide with new standards (Nicholas C. Zakas)
* cb78585 Update: Add `allowUnboundThis` to `prefer-arrow-callback` (fixes #4668) (Burak Yigit Kaya)
* 02be29f Chore: Remove CLA check from bot (Nicholas C. Zakas)
* 220713e Chore: Add metadata to existing rules - Batch 4 (refs #5417) (Vitor Balocco)
* df53414 Chore: Include jQuery Foundation info (Nicholas C. Zakas)
* f1b2992 Fix: `no-useless-escape` false positive in JSXAttribute (fixes #5882) (Toru Nagashima)
* 74674ad Docs: Move `sort-imports` to 'ECMAScript 6' (Kenneth Williams)
* ae69ddb Docs: Fix severity type in example (Kenneth Williams)
* 19f6fff Update: Autofixing does multiple passes (refs #5329) (Nicholas C. Zakas)
* 1e4b0ca Docs: Reduce length of paragraphs in rules index (Mark Pedrotti)
* 8cfe1eb Docs: Fix a wrong option (Zach Orlovsky)
* 8f6739f Docs: Add alberto as reviewer (alberto)
* 2ae4938 Docs: Fix message for `inline-config` option (alberto)
* 089900b Docs: Fix a wrong rule name in an example (Toru Nagashima)
* c032b41 Docs: Fix emphasis (Toru Nagashima)
* ae606f0 Docs: Update JSCS info in README (alberto)
* a9c5323 Fix: Install ESLint on init if not installed (fixes #5833) (Kai Cataldo)
* ed38358 Docs: Removed incorrect example (James M. Greene)
* af3113c Docs: Fix config comments in indent docs (Brandon Mills)
* 2b39461 Update: `commentPattern` option for `default-case` rule (fixes #5803) (Artyom Lvov)
v2.8.0 - April 15, 2016
* a8821a5 Docs: Distinguish examples in rules under Stylistic Issues part 2 (Kenneth Williams)
* 76913b6 Update: Add metadata to existing rules - Batch 3 (refs #5417) (Vitor Balocco)
* 34ad8d2 Fix: Check that module.paths exists (fixes #5791) (Nicholas C. Zakas)
* 37239b1 Docs: Add new members of the team (Ilya Volodin)
* fb3c2eb Update: allow template literals (fixes #5234) (Jonathan Haines)
* 5a4a935 Update: Add metadata to existing rules - Batch 2 (refs #5417) (Vitor Balocco)
* ea2e625 Fix: newline-before-return handles return as first token (fixes #5816) (Kevin Partington)
* f8db9c9 Update: add nestedBinaryExpressions to no-extra-parens (fixes #3065) (Ilya Volodin)
* 0045d57 Update: `allowNamedFunctions` in `prefer-arrow-callback` (fixes #5675) (alberto)
* 19da72a Update: Add metadata to existing rules - Batch 1 (refs #5417) (Vitor Balocco)
* cc14e43 Fix: `no-fallthrough` empty case with comment (fixes #5799) (alberto)
* 13c8b14 Fix: LogicalExpression checks for short circuit (fixes #5693) (Vamshi krishna)
* 73b225e Fix: Document and fix metadata (refs #5417) (Ilya Volodin)
* 882d199 Docs: Improve options description in `no-redeclare` (alberto)
* 6a71ceb Docs: Improve options description in `no-params-reassign` (alberto)
* 24b6215 Update: Include 'typeof' in rule 'no-constant-condition' (fixes #5228) (Vamshi krishna)
* a959063 Docs: Remove link to deprecated ESLintTester project (refs #3110) (Trey Thomas)
* 6fd7d82 Update: Change order in `eslint --init` env options (fixes #5742) (alberto)
* c59d909 Fix: Extra paren check around object arrow bodies (fixes #5789) (Brandon Mills)
* 6f88546 Docs: Use double quotes for better Win compatibility (fixes #5796) (alberto)
* 02743d5 Fix: catch self-assignment operators in `no-magic-number` (fixes #4400) (alberto)
* c94e74e Docs: Make rule descriptions more consistent (Kenneth Williams)
* 6028252 Docs: Distinguish examples in rules under Stylistic Issues part 1 (Mark Pedrotti)
* ccd8ca9 Fix: Added property onlyDeclaration to id-match rule (fixes #3488) (Gajus Kuizinas)
* 6703c02 Update: no-useless-escape / exact locations of errors (fixes #5751) (Onur Temizkan)
* 3d84b91 Fix: ignore trailing whitespace in template literal (fixes #5786) (Kai Cataldo)
* b0e6bc4 Update: add allowEmptyCatch option to no-empty (fixes #5800) (Kai Cataldo)
* f1f1dd7 Docs: Add @pedrottimark as a committer (Brandon Mills)
* 228f201 Update: `commentPattern` option for `no-fallthrough` rule (fixes #5757) (Artyom Lvov)
* 41db670 Docs: Clarify disable inline comments (Kai Cataldo)
* 9c9a295 Docs: Add note about shell vs node glob parameters in cli (alberto)
* 5308ff9 Docs: Add code backticks to sentence in fixable rules (Mark Pedrotti)
* 965ec06 Docs: fix the examples for space-before-function-paren. (Craig Silverstein)
* 2b202fc Update: Add ignore option to space-before-function-parens (fixes #4127) (Craig Silverstein)
* 24c12ba Fix: improve `constructor-super` errors for literals (fixes #5449) (Toru Nagashima)
v2.7.0 - April 4, 2016 v2.7.0 - April 4, 2016
* 134cb1f Revert "Update: adds nestedBinaryExpressions for no-extra-parens rule (fixes #3065)" (Ilya Volodin) * 134cb1f Revert "Update: adds nestedBinaryExpressions for no-extra-parens rule (fixes #3065)" (Ilya Volodin)

2
tools/eslint/LICENSE

@ -1,5 +1,5 @@
ESLint ESLint
Copyright (c) 2013 Nicholas C. Zakas. All rights reserved. Copyright jQuery Foundation and other contributors, https://jquery.org/
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

30
tools/eslint/README.md

@ -8,7 +8,15 @@
# ESLint # ESLint
[Website](http://eslint.org) | [Configuring](http://eslint.org/docs/user-guide/configuring) | [Rules](http://eslint.org/docs/rules/) | [Contributing](http://eslint.org/docs/developer-guide/contributing) | [Reporting Bugs](http://eslint.org/docs/developer-guide/contributing/reporting-bugs) | [Twitter](https://twitter.com/geteslint) | [Mailing List](https://groups.google.com/group/eslint) | [Chat Room](https://gitter.im/eslint/eslint) [Website](http://eslint.org) |
[Configuring](http://eslint.org/docs/user-guide/configuring) |
[Rules](http://eslint.org/docs/rules/) |
[Contributing](http://eslint.org/docs/developer-guide/contributing) |
[Reporting Bugs](http://eslint.org/docs/developer-guide/contributing/reporting-bugs) |
[Code of Conduct](https://jquery.org/conduct/) |
[Twitter](https://twitter.com/geteslint) |
[Mailing List](https://groups.google.com/group/eslint) |
[Chat Room](https://gitter.im/eslint/eslint)
ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code. In many ways, it is similar to JSLint and JSHint with a few exceptions: ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code. In many ways, it is similar to JSLint and JSHint with a few exceptions:
@ -32,6 +40,8 @@ After that, you can run ESLint on any JavaScript file:
eslint test.js test2.js eslint test.js test2.js
**Note:** `eslint --init` is intended for setting up and configuring ESLint on a per-project basis and will perform a local installation of ESLint and its plugins in the directory in which it is run. If you prefer using a global installation of ESLint, any plugins used in your configuration must also be installed globally.
## Configuration ## Configuration
After running `eslint --init`, you'll have a `.eslintrc` file in your directory. In it, you'll see some rules configured like this: After running `eslint --init`, you'll have a `.eslintrc` file in your directory. In it, you'll see some rules configured like this:
@ -67,13 +77,19 @@ These folks keep the project moving and are resources for help:
* Brandon Mills ([@btmills](https://github.com/btmills)) - reviewer * Brandon Mills ([@btmills](https://github.com/btmills)) - reviewer
* Gyandeep Singh ([@gyandeeps](https://github.com/gyandeeps)) - reviewer * Gyandeep Singh ([@gyandeeps](https://github.com/gyandeeps)) - reviewer
* Toru Nagashima ([@mysticatea](https://github.com/mysticatea)) - reviewer * Toru Nagashima ([@mysticatea](https://github.com/mysticatea)) - reviewer
* Alberto Rodríguez ([@alberto](https://github.com/alberto)) - reviewer
* Mathias Schreck ([@lo1tuma](https://github.com/lo1tuma)) - committer * Mathias Schreck ([@lo1tuma](https://github.com/lo1tuma)) - committer
* Jamund Ferguson ([@xjamundx](https://github.com/xjamundx)) - committer * Jamund Ferguson ([@xjamundx](https://github.com/xjamundx)) - committer
* Ian VanSchooten ([@ianvs](https://github.com/ianvs)) - committer * Ian VanSchooten ([@ianvs](https://github.com/ianvs)) - committer
* Burak Yiğit Kaya ([@byk](https://github.com/byk)) - committer * Burak Yiğit Kaya ([@byk](https://github.com/byk)) - committer
* Alberto Rodríguez ([@alberto](https://github.com/alberto)) - committer
* Kai Cataldo ([@kaicataldo](https://github.com/kaicataldo)) - committer * Kai Cataldo ([@kaicataldo](https://github.com/kaicataldo)) - committer
* Michael Ficarra ([@michaelficarra](https://github.com/michaelficarra)) - committer * Michael Ficarra ([@michaelficarra](https://github.com/michaelficarra)) - committer
* Mark Pedrotti ([@pedrottimark](https://github.com/pedrottimark)) - committer
* Oleg Gaidarenko ([@markelog](https://github.com/markelog)) - committer
* Mike Sherov [@mikesherov](https://github.com/mikesherov)) - committer
* Henry Zhu ([@hzoo](https://github.com/hzoo)) - committer
* Marat Dulin ([@mdevils](https://github.com/mdevils)) - committer
* Alexej Yaroshevich ([@zxqfox](https://github.com/zxqfox)) - committer
## Releases ## Releases
@ -98,15 +114,19 @@ I do like JSHint. And I like Anton and Rick. Neither of those were deciding fact
That's not really a question, but I got it. I'm not trying to convince you that ESLint is better than JSHint. The only thing I know is that ESLint is better than JSHint for what I'm doing. In the off chance you're doing something similar, it might be better for you. Otherwise, keep using JSHint, I'm certainly not going to tell you to stop using it. That's not really a question, but I got it. I'm not trying to convince you that ESLint is better than JSHint. The only thing I know is that ESLint is better than JSHint for what I'm doing. In the off chance you're doing something similar, it might be better for you. Otherwise, keep using JSHint, I'm certainly not going to tell you to stop using it.
### How does ESLint performance compare to JSHint and JSCS? ### How does ESLint performance compare to JSHint?
ESLint is slower than JSHint, usually 2-3x slower on a single file. This is because ESLint uses Espree to construct an AST before it can evaluate your code whereas JSHint evaluates your code as it's being parsed. The speed is also based on the number of rules you enable; the more rules you enable, the slower the process. ESLint is slower than JSHint, usually 2-3x slower on a single file. This is because ESLint uses Espree to construct an AST before it can evaluate your code whereas JSHint evaluates your code as it's being parsed. The speed is also based on the number of rules you enable; the more rules you enable, the slower the process.
Despite being slower, we believe that ESLint is fast enough to replace JSHint without causing significant pain. Despite being slower, we believe that ESLint is fast enough to replace JSHint without causing significant pain.
ESLint is faster than JSCS, as ESLint uses a single-pass traversal for analysis whereas JSCS using a querying model. ### I heard ESLint is going to replace JSCS?
Yes. Since we are solving the same problems, ESLint and JSCS teams have decided to join forces and work together in the development of ESLint instead of competing with each other. You can read more about this in both [ESLint](http://eslint.org/blog/2016/04/welcoming-jscs-to-eslint) and [JSCS](https://medium.com/@markelog/jscs-end-of-the-line-bc9bf0b3fdb2#.u76sx334n) announcements.
### So, should I stop using JSCS and start using ESLint?
If you are using both JSHint and JSCS on your files, then using just ESLint will be faster. Not yet. We are still working to smooth the transition. You can see our progress [here](https://github.com/eslint/eslint/milestones/JSCS%20Compatibility). We’ll announce when all of the changes necessary to support JSCS users in ESLint are complete and will start encouraging JSCS users to switch to ESLint at that time. Meanwhile, we recommend you to upgrade to JSCS 3.0 and provide feedback to the team.
### Is ESLint just linting or does it also check style? ### Is ESLint just linting or does it also check style?

2
tools/eslint/bin/eslint.js

@ -3,8 +3,6 @@
/** /**
* @fileoverview Main CLI that is run via the eslint command. * @fileoverview Main CLI that is run via the eslint command.
* @author Nicholas C. Zakas * @author Nicholas C. Zakas
* @copyright 2013 Nicholas C. Zakas. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";

2
tools/eslint/conf/cli-options.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Default CLIEngineOptions. * @fileoverview Default CLIEngineOptions.
* @author Ian VanSchooten * @author Ian VanSchooten
* @copyright 2016 Ian VanSchooten. All rights reserved.
* See LICENSE in root directory for full license.
*/ */
"use strict"; "use strict";

1
tools/eslint/conf/environments.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview Defines environment settings and globals. * @fileoverview Defines environment settings and globals.
* @author Elan Shanker * @author Elan Shanker
* @copyright 2014 Elan Shanker. All rights reserved.
*/ */
"use strict"; "use strict";

2
tools/eslint/conf/eslint.json

@ -109,11 +109,13 @@
"no-unmodified-loop-condition": "off", "no-unmodified-loop-condition": "off",
"no-unneeded-ternary": "off", "no-unneeded-ternary": "off",
"no-unreachable": "error", "no-unreachable": "error",
"no-unsafe-finally": "off",
"no-unused-expressions": "off", "no-unused-expressions": "off",
"no-unused-labels": "error", "no-unused-labels": "error",
"no-unused-vars": "error", "no-unused-vars": "error",
"no-use-before-define": "off", "no-use-before-define": "off",
"no-useless-call": "off", "no-useless-call": "off",
"no-useless-computed-key": "off",
"no-useless-concat": "off", "no-useless-concat": "off",
"no-useless-constructor": "off", "no-useless-constructor": "off",
"no-useless-escape": "off", "no-useless-escape": "off",

2
tools/eslint/lib/ast-utils.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Common utils for AST. * @fileoverview Common utils for AST.
* @author Gyandeep Singh * @author Gyandeep Singh
* @copyright 2015 Gyandeep Singh. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";

87
tools/eslint/lib/cli-engine.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Main CLI object. * @fileoverview Main CLI object.
* @author Nicholas C. Zakas * @author Nicholas C. Zakas
* @copyright 2014 Nicholas C. Zakas. All rights reserved.
* See LICENSE in root directory for full license.
*/ */
"use strict"; "use strict";
@ -115,6 +113,79 @@ function calculateStatsPerRun(results) {
}); });
} }
/**
* Performs multiple autofix passes over the text until as many fixes as possible
* have been applied.
* @param {string} text The source text to apply fixes to.
* @param {Object} config The ESLint config object to use.
* @param {Object} options The ESLint options object to use.
* @param {string} options.filename The filename from which the text was read.
* @param {boolean} options.allowInlineConfig Flag indicating if inline comments
* should be allowed.
* @returns {Object} The result of the fix operation as returned from the
* SourceCodeFixer.
* @private
*/
function multipassFix(text, config, options) {
var messages = [],
fixedResult,
fixed = false,
passNumber = 0,
lastMessageCount,
MAX_PASSES = 10;
/**
* This loop continues until one of the following is true:
*
* 1. No more fixes have been applied.
* 2. There are no more linting errors reported.
* 3. The number of linting errors is no different between two passes.
* 4. Ten passes have been made.
*
* That means anytime a fix is successfully applied, there will be another pass.
* Essentially, guaranteeing a minimum of two passes.
*/
do {
passNumber++;
lastMessageCount = messages.length;
debug("Linting code for " + options.filename + " (pass " + passNumber + ")");
messages = eslint.verify(text, config, options);
debug("Generating fixed text for " + options.filename + " (pass " + passNumber + ")");
fixedResult = SourceCodeFixer.applyFixes(eslint.getSourceCode(), messages);
// keep track if any fixes were ever applied - important for return value
fixed = fixed || fixedResult.fixed;
// update to use the fixed output instead of the original text
text = fixedResult.output;
} while (
fixedResult.fixed && fixedResult.messages.length > 0 &&
fixedResult.messages.length !== lastMessageCount &&
passNumber < MAX_PASSES
);
/*
* If the last result had fixes, we need to lint again to me sure we have
* the most up-to-date information.
*/
if (fixedResult.fixed) {
fixedResult.messages = eslint.verify(text, config, options);
}
// ensure the last result properly reflects if fixes were done
fixedResult.fixed = fixed;
fixedResult.output = text;
return fixedResult;
}
/** /**
* Processes an source code using ESLint. * Processes an source code using ESLint.
* @param {string} text The source code to check. * @param {string} text The source code to check.
@ -179,15 +250,17 @@ function processText(text, configHelper, filename, fix, allowInlineConfig) {
} else { } else {
messages = eslint.verify(text, config, { if (fix) {
fixedResult = multipassFix(text, config, {
filename: filename, filename: filename,
allowInlineConfig: allowInlineConfig allowInlineConfig: allowInlineConfig
}); });
if (fix) {
debug("Generating fixed text for " + filename);
fixedResult = SourceCodeFixer.applyFixes(eslint.getSourceCode(), messages);
messages = fixedResult.messages; messages = fixedResult.messages;
} else {
messages = eslint.verify(text, config, {
filename: filename,
allowInlineConfig: allowInlineConfig
});
} }
} }

2
tools/eslint/lib/code-path-analysis/code-path-analyzer.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview A class of the code path analyzer. * @fileoverview A class of the code path analyzer.
* @author Toru Nagashima * @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";

17
tools/eslint/lib/code-path-analysis/code-path-segment.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview A class of the code path segment. * @fileoverview A class of the code path segment.
* @author Toru Nagashima * @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";
@ -11,8 +9,7 @@
// Requirements // Requirements
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
var assert = require("assert"), var debug = require("./debug-helpers");
debug = require("./debug-helpers");
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Helpers // Helpers
@ -178,7 +175,13 @@ CodePathSegment.newNext = function(id, allPrevSegments) {
* @returns {CodePathSegment} The created segment. * @returns {CodePathSegment} The created segment.
*/ */
CodePathSegment.newUnreachable = function(id, allPrevSegments) { CodePathSegment.newUnreachable = function(id, allPrevSegments) {
return new CodePathSegment(id, flattenUnusedSegments(allPrevSegments), false); var segment = new CodePathSegment(id, flattenUnusedSegments(allPrevSegments), false);
// In `if (a) return a; foo();` case, the unreachable segment preceded by
// the return statement is not used but must not be remove.
CodePathSegment.markUsed(segment);
return segment;
}; };
/** /**
@ -203,7 +206,9 @@ CodePathSegment.newDisconnected = function(id, allPrevSegments) {
* @returns {void} * @returns {void}
*/ */
CodePathSegment.markUsed = function(segment) { CodePathSegment.markUsed = function(segment) {
assert(!segment.internal.used, segment.id + " is marked twice."); if (segment.internal.used) {
return;
}
segment.internal.used = true; segment.internal.used = true;
var i; var i;

2
tools/eslint/lib/code-path-analysis/code-path-state.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview A class to manage state of generating a code path. * @fileoverview A class to manage state of generating a code path.
* @author Toru Nagashima * @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";

2
tools/eslint/lib/code-path-analysis/code-path.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview A class of the code path. * @fileoverview A class of the code path.
* @author Toru Nagashima * @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";

2
tools/eslint/lib/code-path-analysis/debug-helpers.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Helpers to debug for code path analysis. * @fileoverview Helpers to debug for code path analysis.
* @author Toru Nagashima * @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";

2
tools/eslint/lib/code-path-analysis/fork-context.js

@ -5,8 +5,6 @@
* This has a fork list and manages it. * This has a fork list and manages it.
* *
* @author Toru Nagashima * @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";

2
tools/eslint/lib/code-path-analysis/id-generator.js

@ -5,8 +5,6 @@
* information of the code path. * information of the code path.
* *
* @author Toru Nagashima * @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";

5
tools/eslint/lib/config.js

@ -1,11 +1,8 @@
/** /**
* @fileoverview Responsible for loading config files * @fileoverview Responsible for loading config files
* @author Seth McLaughlin * @author Seth McLaughlin
* @copyright 2014-2016 Nicholas C. Zakas. All rights reserved.
* @copyright 2014 Michael McLaughlin. All rights reserved.
* @copyright 2013 Seth McLaughlin. All rights reserved.
* See LICENSE in root directory for full license.
*/ */
"use strict"; "use strict";
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

8
tools/eslint/lib/config/autoconfig.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Used for creating a suggested configuration based on project code. * @fileoverview Used for creating a suggested configuration based on project code.
* @author Ian VanSchooten * @author Ian VanSchooten
* @copyright 2015 Ian VanSchooten. All rights reserved.
* See LICENSE in root directory for full license.
*/ */
"use strict"; "use strict";
@ -312,7 +310,13 @@ Registry.prototype = {
var lintResults = eslint.verify(sourceCodes[filename], lintConfig); var lintResults = eslint.verify(sourceCodes[filename], lintConfig);
lintResults.forEach(function(result) { lintResults.forEach(function(result) {
// It is possible that the error is from a configuration comment
// in a linted file, in which case there may not be a config
// set in this ruleSetIdx. (https://github.com/eslint/eslint/issues/5992)
if (lintedRegistry.rules[result.ruleId][ruleSetIdx]) {
lintedRegistry.rules[result.ruleId][ruleSetIdx].errorCount += 1; lintedRegistry.rules[result.ruleId][ruleSetIdx].errorCount += 1;
}
}); });
ruleSetIdx += 1; ruleSetIdx += 1;

2
tools/eslint/lib/config/config-file.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Helper to locate and load configuration files. * @fileoverview Helper to locate and load configuration files.
* @author Nicholas C. Zakas * @author Nicholas C. Zakas
* @copyright 2015 Nicholas C. Zakas. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
/* eslint no-use-before-define: 0 */ /* eslint no-use-before-define: 0 */

21
tools/eslint/lib/config/config-initializer.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview Config initialization wizard. * @fileoverview Config initialization wizard.
* @author Ilya Volodin * @author Ilya Volodin
* @copyright 2015 Ilya Volodin. All rights reserved.
*/ */
"use strict"; "use strict";
@ -50,6 +49,10 @@ function writeFile(config, format) {
ConfigFile.write(config, "./.eslintrc" + extname); ConfigFile.write(config, "./.eslintrc" + extname);
log.info("Successfully created .eslintrc" + extname + " file in " + process.cwd()); log.info("Successfully created .eslintrc" + extname + " file in " + process.cwd());
if (config.installedESLint) {
log.info("ESLint was installed locally. We recommend using this local copy instead of your globally-installed copy.");
}
} }
/** /**
@ -76,12 +79,24 @@ function installModules(config) {
if (modules.length === 0) { if (modules.length === 0) {
return; return;
} }
// Add eslint to list in case user does not have it installed locally
modules.unshift("eslint");
installStatus = npmUtil.checkDevDeps(modules); installStatus = npmUtil.checkDevDeps(modules);
// Install packages which aren't already installed // Install packages which aren't already installed
modulesToInstall = Object.keys(installStatus).filter(function(module) { modulesToInstall = Object.keys(installStatus).filter(function(module) {
return installStatus[module] === false; var notInstalled = installStatus[module] === false;
if (module === "eslint" && notInstalled) {
log.info("Local ESLint installation not found.");
config.installedESLint = true;
}
return notInstalled;
}); });
if (modulesToInstall.length > 0) { if (modulesToInstall.length > 0) {
log.info("Installing " + modulesToInstall.join(", ")); log.info("Installing " + modulesToInstall.join(", "));
npmUtil.installSyncSaveDev(modulesToInstall); npmUtil.installSyncSaveDev(modulesToInstall);
@ -366,7 +381,7 @@ function promptUser(callback) {
name: "env", name: "env",
message: "Where will your code run?", message: "Where will your code run?",
default: ["browser"], default: ["browser"],
choices: [{name: "Node", value: "node"}, {name: "Browser", value: "browser"}] choices: [{name: "Browser", value: "browser"}, {name: "Node", value: "node"}]
}, },
{ {
type: "confirm", type: "confirm",

2
tools/eslint/lib/config/config-ops.js

@ -2,8 +2,6 @@
* @fileoverview Config file operations. This file must be usable in the browser, * @fileoverview Config file operations. This file must be usable in the browser,
* so no Node-specific code can be here. * so no Node-specific code can be here.
* @author Nicholas C. Zakas * @author Nicholas C. Zakas
* @copyright 2015 Nicholas C. Zakas. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";

2
tools/eslint/lib/config/config-rule.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Create configurations for a rule * @fileoverview Create configurations for a rule
* @author Ian VanSchooten * @author Ian VanSchooten
* @copyright 2016 Ian VanSchooten. All rights reserved.
* See LICENSE in root directory for full license.
*/ */
"use strict"; "use strict";

16
tools/eslint/lib/config/config-validator.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Validates configs. * @fileoverview Validates configs.
* @author Brandon Mills * @author Brandon Mills
* @copyright 2015 Brandon Mills
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";
@ -37,16 +35,16 @@ function getRuleOptionsSchema(id) {
if (Array.isArray(schema)) { if (Array.isArray(schema)) {
if (schema.length) { if (schema.length) {
return { return {
"type": "array", type: "array",
"items": schema, items: schema,
"minItems": 0, minItems: 0,
"maxItems": schema.length maxItems: schema.length
}; };
} else { } else {
return { return {
"type": "array", type: "array",
"minItems": 0, minItems: 0,
"maxItems": 0 maxItems: 0
}; };
} }
} }

2
tools/eslint/lib/config/environments.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Environments manager * @fileoverview Environments manager
* @author Nicholas C. Zakas * @author Nicholas C. Zakas
* @copyright 2016 Nicholas C. Zakas. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";

2
tools/eslint/lib/config/plugins.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Plugins manager * @fileoverview Plugins manager
* @author Nicholas C. Zakas * @author Nicholas C. Zakas
* @copyright 2016 Nicholas C. Zakas. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";

9
tools/eslint/lib/eslint.js

@ -1,9 +1,8 @@
/** /**
* @fileoverview Main ESLint object. * @fileoverview Main ESLint object.
* @author Nicholas C. Zakas * @author Nicholas C. Zakas
* @copyright 2013 Nicholas C. Zakas. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -345,11 +344,11 @@ function modifyConfigsFromComments(filename, ast, config, reportingConfig, messa
} }
} else { // comment.type === "Line" } else { // comment.type === "Line"
if (match[1] === "eslint-disable-line") { if (match[1] === "eslint-disable-line") {
disableReporting(reportingConfig, { "line": comment.loc.start.line, "column": 0 }, Object.keys(parseListConfig(value))); disableReporting(reportingConfig, { line: comment.loc.start.line, column: 0 }, Object.keys(parseListConfig(value)));
enableReporting(reportingConfig, comment.loc.end, Object.keys(parseListConfig(value))); enableReporting(reportingConfig, comment.loc.end, Object.keys(parseListConfig(value)));
} else if (match[1] === "eslint-disable-next-line") { } else if (match[1] === "eslint-disable-next-line") {
disableReporting(reportingConfig, comment.loc.start, Object.keys(parseListConfig(value))); disableReporting(reportingConfig, comment.loc.start, Object.keys(parseListConfig(value)));
enableReporting(reportingConfig, { "line": comment.loc.start.line + 2 }, Object.keys(parseListConfig(value))); enableReporting(reportingConfig, { line: comment.loc.start.line + 2 }, Object.keys(parseListConfig(value)));
} }
} }
} }
@ -964,7 +963,7 @@ module.exports = (function() {
}; };
// ensure there's range and text properties as well as metadata switch, otherwise it's not a valid fix // ensure there's range and text properties as well as metadata switch, otherwise it's not a valid fix
if (fix && Array.isArray(fix.range) && (typeof fix.text === "string") && (!meta || !meta.docs || meta.docs.fixable)) { if (fix && Array.isArray(fix.range) && (typeof fix.text === "string") && (!meta || meta.fixable)) {
problem.fix = fix; problem.fix = fix;
} }

4
tools/eslint/lib/file-finder.js

@ -1,10 +1,8 @@
/** /**
* @fileoverview Util class to find config files. * @fileoverview Util class to find config files.
* @author Aliaksei Shytkin * @author Aliaksei Shytkin
* @copyright 2014 Michael McLaughlin. All rights reserved.
* @copyright 2014 Aliaksei Shytkin. All rights reserved.
* See LICENSE in root directory for full license.
*/ */
"use strict"; "use strict";
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

1
tools/eslint/lib/formatters/html.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview HTML reporter * @fileoverview HTML reporter
* @author Julian Laval * @author Julian Laval
* @copyright 2015 Julian Laval. All rights reserved.
*/ */
"use strict"; "use strict";

1
tools/eslint/lib/formatters/json.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview JSON reporter * @fileoverview JSON reporter
* @author Burak Yigit Kaya aka BYK * @author Burak Yigit Kaya aka BYK
* @copyright 2015 Burak Yigit Kaya. All rights reserved.
*/ */
"use strict"; "use strict";

1
tools/eslint/lib/formatters/table.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview "table reporter. * @fileoverview "table reporter.
* @author Gajus Kuizinas <gajus@gajus.com> * @author Gajus Kuizinas <gajus@gajus.com>
* @copyright 2016 Gajus Kuizinas <gajus@gajus.com>. All rights reserved.
*/ */
"use strict"; "use strict";

1
tools/eslint/lib/formatters/unix.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview unix-style formatter. * @fileoverview unix-style formatter.
* @author oshi-shinobu * @author oshi-shinobu
* @copyright 2015 oshi-shinobu. All rights reserved.
*/ */
"use strict"; "use strict";

2
tools/eslint/lib/formatters/visualstudio.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Visual Studio compatible formatter * @fileoverview Visual Studio compatible formatter
* @author Ronald Pijnacker * @author Ronald Pijnacker
* @copyright 2015 Ronald Pijnacker. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";

1
tools/eslint/lib/ignored-paths.js

@ -2,6 +2,7 @@
* @fileoverview Responsible for loading ignore config files and managing ignore patterns * @fileoverview Responsible for loading ignore config files and managing ignore patterns
* @author Jonathan Rajavuori * @author Jonathan Rajavuori
*/ */
"use strict"; "use strict";
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

4
tools/eslint/lib/logging.js

@ -1,10 +1,12 @@
/** /**
* @fileoverview Handle logging for ESLint * @fileoverview Handle logging for ESLint
* @author Gyandeep Singh * @author Gyandeep Singh
* @copyright 2015 Gyandeep Singh. All rights reserved.
*/ */
"use strict"; "use strict";
/* eslint no-console: "off" */
/* istanbul ignore next */ /* istanbul ignore next */
module.exports = { module.exports = {

8
tools/eslint/lib/options.js

@ -1,8 +1,8 @@
/** /**
* @fileoverview Options configuration for optionator. * @fileoverview Options configuration for optionator.
* @author George Zahariev * @author George Zahariev
* See LICENSE in root directory for full license.
*/ */
"use strict"; "use strict";
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -173,8 +173,8 @@ module.exports = optionator({
{ {
option: "color", option: "color",
type: "Boolean", type: "Boolean",
default: "true", alias: "no-color",
description: "Disable color in piped output" description: "Force enabling/disabling of color"
}, },
{ {
heading: "Miscellaneous" heading: "Miscellaneous"
@ -213,7 +213,7 @@ module.exports = optionator({
option: "inline-config", option: "inline-config",
type: "Boolean", type: "Boolean",
default: "true", default: "true",
description: "Allow comments to change eslint config/rules" description: "Prevent comments from changing config or rules"
}, },
{ {
option: "print-config", option: "print-config",

2
tools/eslint/lib/rule-context.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview RuleContext utility for rules * @fileoverview RuleContext utility for rules
* @author Nicholas C. Zakas * @author Nicholas C. Zakas
* @copyright 2013 Nicholas C. Zakas. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";

17
tools/eslint/lib/rules/accessor-pairs.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview Rule to flag wrapping non-iife in parens * @fileoverview Rule to flag wrapping non-iife in parens
* @author Gyandeep Singh * @author Gyandeep Singh
* @copyright 2015 Gyandeep Singh. All rights reserved.
*/ */
"use strict"; "use strict";
@ -79,16 +78,16 @@ module.exports = {
recommended: false recommended: false
}, },
schema: [{ schema: [{
"type": "object", type: "object",
"properties": { properties: {
"getWithoutSet": { getWithoutSet: {
"type": "boolean" type: "boolean"
}, },
"setWithoutGet": { setWithoutGet: {
"type": "boolean" type: "boolean"
} }
}, },
"additionalProperties": false additionalProperties: false
}] }]
}, },
create: function(context) { create: function(context) {
@ -147,7 +146,7 @@ module.exports = {
} }
return { return {
"ObjectExpression": function(node) { ObjectExpression: function(node) {
if (checkSetWithoutGet || checkGetWithoutSet) { if (checkSetWithoutGet || checkGetWithoutSet) {
checkLonelySetGet(node); checkLonelySetGet(node);
} }

28
tools/eslint/lib/rules/array-bracket-spacing.js

@ -1,10 +1,6 @@
/** /**
* @fileoverview Disallows or enforces spaces inside of array brackets. * @fileoverview Disallows or enforces spaces inside of array brackets.
* @author Jamund Ferguson * @author Jamund Ferguson
* @copyright 2015 Jamund Ferguson. All rights reserved.
* @copyright 2014 Brandyn Bennett. All rights reserved.
* @copyright 2014 Michael Ficarra. No rights reserved.
* @copyright 2014 Vignesh Anand. All rights reserved.
*/ */
"use strict"; "use strict";
@ -19,27 +15,27 @@ module.exports = {
docs: { docs: {
description: "Enforce spacing inside array brackets", description: "Enforce spacing inside array brackets",
category: "Stylistic Issues", category: "Stylistic Issues",
recommended: false, recommended: false
fixable: "whitespace"
}, },
fixable: "whitespace",
schema: [ schema: [
{ {
"enum": ["always", "never"] enum: ["always", "never"]
}, },
{ {
"type": "object", type: "object",
"properties": { properties: {
"singleValue": { singleValue: {
"type": "boolean" type: "boolean"
}, },
"objectsInArrays": { objectsInArrays: {
"type": "boolean" type: "boolean"
}, },
"arraysInArrays": { arraysInArrays: {
"type": "boolean" type: "boolean"
} }
}, },
"additionalProperties": false additionalProperties: false
} }
] ]
}, },

24
tools/eslint/lib/rules/array-callback-return.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Rule to enforce return statements in callbacks of array's methods * @fileoverview Rule to enforce return statements in callbacks of array's methods
* @author Toru Nagashima * @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";
@ -166,7 +164,18 @@ function isCallbackOfArrayMethod(node) {
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce `return` statements in callbacks of array methods",
category: "Best Practices",
recommended: false
},
schema: []
},
create: function(context) {
var funcInfo = { var funcInfo = {
upper: null, upper: null,
codePath: null, codePath: null,
@ -201,7 +210,7 @@ module.exports = function(context) {
return { return {
// Stacks this function's information. // Stacks this function's information.
"onCodePathStart": function(codePath, node) { onCodePathStart: function(codePath, node) {
funcInfo = { funcInfo = {
upper: funcInfo, upper: funcInfo,
codePath: codePath, codePath: codePath,
@ -214,12 +223,12 @@ module.exports = function(context) {
}, },
// Pops this function's information. // Pops this function's information.
"onCodePathEnd": function() { onCodePathEnd: function() {
funcInfo = funcInfo.upper; funcInfo = funcInfo.upper;
}, },
// Checks the return statement is valid. // Checks the return statement is valid.
"ReturnStatement": function(node) { ReturnStatement: function(node) {
if (funcInfo.shouldCheck) { if (funcInfo.shouldCheck) {
funcInfo.hasReturn = true; funcInfo.hasReturn = true;
@ -236,6 +245,5 @@ module.exports = function(context) {
"FunctionExpression:exit": checkLastSegment, "FunctionExpression:exit": checkLastSegment,
"ArrowFunctionExpression:exit": checkLastSegment "ArrowFunctionExpression:exit": checkLastSegment
}; };
}
}; };
module.exports.schema = [];

28
tools/eslint/lib/rules/arrow-body-style.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Rule to require braces in arrow function body. * @fileoverview Rule to require braces in arrow function body.
* @author Alberto Rodríguez * @author Alberto Rodríguez
* @copyright 2015 Alberto Rodríguez. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";
@ -10,7 +8,22 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require braces around arrow function bodies",
category: "ECMAScript 6",
recommended: false
},
schema: [
{
enum: ["always", "as-needed"]
}
]
},
create: function(context) {
var always = context.options[0] === "always"; var always = context.options[0] === "always";
var asNeeded = !context.options[0] || context.options[0] === "as-needed"; var asNeeded = !context.options[0] || context.options[0] === "as-needed";
@ -48,12 +61,7 @@ module.exports = function(context) {
} }
return { return {
"ArrowFunctionExpression": validate ArrowFunctionExpression: validate
}; };
};
module.exports.schema = [
{
"enum": ["always", "as-needed"]
} }
]; };

27
tools/eslint/lib/rules/arrow-parens.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview Rule to require parens in arrow function arguments. * @fileoverview Rule to require parens in arrow function arguments.
* @author Jxck * @author Jxck
* @copyright 2015 Jxck. All rights reserved.
*/ */
"use strict"; "use strict";
@ -9,7 +8,22 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require parentheses around arrow function arguments",
category: "ECMAScript 6",
recommended: false
},
schema: [
{
enum: ["always", "as-needed"]
}
]
},
create: function(context) {
var message = "Expected parentheses around arrow function argument."; var message = "Expected parentheses around arrow function argument.";
var asNeededMessage = "Unexpected parentheses around single function argument"; var asNeededMessage = "Unexpected parentheses around single function argument";
var asNeeded = context.options[0] === "as-needed"; var asNeeded = context.options[0] === "as-needed";
@ -41,12 +55,7 @@ module.exports = function(context) {
} }
return { return {
"ArrowFunctionExpression": parens ArrowFunctionExpression: parens
}; };
};
module.exports.schema = [
{
"enum": ["always", "as-needed"]
} }
]; };

47
tools/eslint/lib/rules/arrow-spacing.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview Rule to define spacing before/after arrow function's arrow. * @fileoverview Rule to define spacing before/after arrow function's arrow.
* @author Jxck * @author Jxck
* @copyright 2015 Jxck. All rights reserved.
*/ */
"use strict"; "use strict";
@ -9,7 +8,33 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce consistent spacing before and after the arrow in arrow functions",
category: "ECMAScript 6",
recommended: false
},
fixable: "whitespace",
schema: [
{
type: "object",
properties: {
before: {
type: "boolean"
},
after: {
type: "boolean"
}
},
additionalProperties: false
}
]
},
create: function(context) {
// merge rules with default // merge rules with default
var rule = { before: true, after: true }, var rule = { before: true, after: true },
@ -113,21 +138,7 @@ module.exports = function(context) {
} }
return { return {
"ArrowFunctionExpression": spaces ArrowFunctionExpression: spaces
};
}; };
module.exports.schema = [
{
"type": "object",
"properties": {
"before": {
"type": "boolean"
},
"after": {
"type": "boolean"
}
},
"additionalProperties": false
} }
]; };

34
tools/eslint/lib/rules/block-scoped-var.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Rule to check for "block scoped" variables by binding context * @fileoverview Rule to check for "block scoped" variables by binding context
* @author Matt DuVall <http://www.mattduvall.com> * @author Matt DuVall <http://www.mattduvall.com>
* @copyright 2015 Toru Nagashima. All rights reserved.
* @copyright 2015 Mathieu M-Gosselin. All rights reserved.
*/ */
"use strict"; "use strict";
@ -10,7 +8,18 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce the use of variables within the scope they are defined",
category: "Best Practices",
recommended: false
},
schema: []
},
create: function(context) {
var stack = []; var stack = [];
/** /**
@ -83,28 +92,27 @@ module.exports = function(context) {
} }
return { return {
"Program": function(node) { Program: function(node) {
stack = [node.range]; stack = [node.range];
}, },
// Manages scopes. // Manages scopes.
"BlockStatement": enterScope, BlockStatement: enterScope,
"BlockStatement:exit": exitScope, "BlockStatement:exit": exitScope,
"ForStatement": enterScope, ForStatement: enterScope,
"ForStatement:exit": exitScope, "ForStatement:exit": exitScope,
"ForInStatement": enterScope, ForInStatement: enterScope,
"ForInStatement:exit": exitScope, "ForInStatement:exit": exitScope,
"ForOfStatement": enterScope, ForOfStatement: enterScope,
"ForOfStatement:exit": exitScope, "ForOfStatement:exit": exitScope,
"SwitchStatement": enterScope, SwitchStatement: enterScope,
"SwitchStatement:exit": exitScope, "SwitchStatement:exit": exitScope,
"CatchClause": enterScope, CatchClause: enterScope,
"CatchClause:exit": exitScope, "CatchClause:exit": exitScope,
// Finds and reports references which are outside of valid scope. // Finds and reports references which are outside of valid scope.
"VariableDeclaration": checkForVariables VariableDeclaration: checkForVariables
}; };
}
}; };
module.exports.schema = [];

23
tools/eslint/lib/rules/block-spacing.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview A rule to disallow or enforce spaces inside of single line blocks. * @fileoverview A rule to disallow or enforce spaces inside of single line blocks.
* @author Toru Nagashima * @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
*/ */
"use strict"; "use strict";
@ -12,7 +11,22 @@ var util = require("../ast-utils");
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce consistent spacing inside single-line blocks",
category: "Stylistic Issues",
recommended: false
},
fixable: "whitespace",
schema: [
{enum: ["always", "never"]}
]
},
create: function(context) {
var always = (context.options[0] !== "never"), var always = (context.options[0] !== "never"),
message = always ? "Requires a space" : "Unexpected space(s)", message = always ? "Requires a space" : "Unexpected space(s)",
sourceCode = context.getSourceCode(); sourceCode = context.getSourceCode();
@ -113,8 +127,5 @@ module.exports = function(context) {
BlockStatement: checkSpacingInsideBraces, BlockStatement: checkSpacingInsideBraces,
SwitchStatement: checkSpacingInsideBraces SwitchStatement: checkSpacingInsideBraces
}; };
}
}; };
module.exports.schema = [
{enum: ["always", "never"]}
];

68
tools/eslint/lib/rules/brace-style.js

@ -9,7 +9,31 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce consistent brace style for blocks",
category: "Stylistic Issues",
recommended: false
},
schema: [
{
enum: ["1tbs", "stroustrup", "allman"]
},
{
type: "object",
properties: {
allowSingleLine: {
type: "boolean"
}
},
additionalProperties: false
}
]
},
create: function(context) {
var style = context.options[0] || "1tbs", var style = context.options[0] || "1tbs",
params = context.options[1] || {}, params = context.options[1] || {},
sourceCode = context.getSourceCode(); sourceCode = context.getSourceCode();
@ -201,34 +225,20 @@ module.exports = function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
return { return {
"FunctionDeclaration": checkBlock("body"), FunctionDeclaration: checkBlock("body"),
"FunctionExpression": checkBlock("body"), FunctionExpression: checkBlock("body"),
"ArrowFunctionExpression": checkBlock("body"), ArrowFunctionExpression: checkBlock("body"),
"IfStatement": checkIfStatement, IfStatement: checkIfStatement,
"TryStatement": checkTryStatement, TryStatement: checkTryStatement,
"CatchClause": checkCatchClause, CatchClause: checkCatchClause,
"DoWhileStatement": checkBlock("body"), DoWhileStatement: checkBlock("body"),
"WhileStatement": checkBlock("body"), WhileStatement: checkBlock("body"),
"WithStatement": checkBlock("body"), WithStatement: checkBlock("body"),
"ForStatement": checkBlock("body"), ForStatement: checkBlock("body"),
"ForInStatement": checkBlock("body"), ForInStatement: checkBlock("body"),
"ForOfStatement": checkBlock("body"), ForOfStatement: checkBlock("body"),
"SwitchStatement": checkSwitchStatement SwitchStatement: checkSwitchStatement
};
}; };
module.exports.schema = [
{
"enum": ["1tbs", "stroustrup", "allman"]
},
{
"type": "object",
"properties": {
"allowSingleLine": {
"type": "boolean"
}
},
"additionalProperties": false
} }
]; };

25
tools/eslint/lib/rules/callback-return.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview Enforce return after a callback. * @fileoverview Enforce return after a callback.
* @author Jamund Ferguson * @author Jamund Ferguson
* @copyright 2015 Jamund Ferguson. All rights reserved.
*/ */
"use strict"; "use strict";
@ -9,7 +8,21 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require `return` statements after callbacks",
category: "Node.js and CommonJS",
recommended: false
},
schema: [{
type: "array",
items: { type: "string" }
}]
},
create: function(context) {
var callbacks = context.options[0] || ["callback", "cb", "next"]; var callbacks = context.options[0] || ["callback", "cb", "next"];
@ -75,7 +88,7 @@ module.exports = function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
return { return {
"CallExpression": function(node) { CallExpression: function(node) {
// if we"re not a callback we can return // if we"re not a callback we can return
if (!isCallback(node)) { if (!isCallback(node)) {
@ -136,9 +149,5 @@ module.exports = function(context) {
} }
}; };
}
}; };
module.exports.schema = [{
type: "array",
items: { type: "string" }
}];

39
tools/eslint/lib/rules/camelcase.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview Rule to flag non-camelcased identifiers * @fileoverview Rule to flag non-camelcased identifiers
* @author Nicholas C. Zakas * @author Nicholas C. Zakas
* @copyright 2015 Dieter Oberkofler. All rights reserved.
*/ */
"use strict"; "use strict";
@ -10,7 +9,28 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce camelcase naming convention",
category: "Stylistic Issues",
recommended: false
},
schema: [
{
type: "object",
properties: {
properties: {
enum: ["always", "never"]
}
},
additionalProperties: false
}
]
},
create: function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Helpers // Helpers
@ -53,7 +73,7 @@ module.exports = function(context) {
return { return {
"Identifier": function(node) { Identifier: function(node) {
/* /*
* Leading and trailing underscores are commonly used to flag * Leading and trailing underscores are commonly used to flag
@ -110,16 +130,5 @@ module.exports = function(context) {
}; };
};
module.exports.schema = [
{
"type": "object",
"properties": {
"properties": {
"enum": ["always", "never"]
} }
}, };
"additionalProperties": false
}
];

87
tools/eslint/lib/rules/comma-dangle.js

@ -1,10 +1,6 @@
/** /**
* @fileoverview Rule to forbid or enforce dangling commas. * @fileoverview Rule to forbid or enforce dangling commas.
* @author Ian Christian Myers * @author Ian Christian Myers
* @copyright 2015 Toru Nagashima
* @copyright 2015 Mathias Schreck
* @copyright 2013 Ian Christian Myers
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";
@ -24,33 +20,31 @@ var lodash = require("lodash");
* @returns {boolean} `true` if a trailing comma is allowed. * @returns {boolean} `true` if a trailing comma is allowed.
*/ */
function isTrailingCommaAllowed(node, lastItem) { function isTrailingCommaAllowed(node, lastItem) {
switch (node.type) { return node.type !== "ArrayPattern" || lastItem.type !== "RestElement";
case "ArrayPattern":
// TODO(t-nagashima): Remove SpreadElement after https://github.com/eslint/espree/issues/194 was fixed.
return (
lastItem.type !== "RestElement" &&
lastItem.type !== "SpreadElement"
);
// TODO(t-nagashima): Remove this case after https://github.com/eslint/espree/issues/195 was fixed.
case "ArrayExpression":
return (
node.parent.type !== "ForOfStatement" ||
node.parent.left !== node ||
lastItem.type !== "SpreadElement"
);
default:
return true;
}
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require or disallow trailing commas",
category: "Possible Errors",
recommended: true
},
fixable: "code",
schema: [
{
enum: ["always", "always-multiline", "only-multiline", "never"]
}
]
},
create: function(context) {
var mode = context.options[0]; var mode = context.options[0];
var UNEXPECTED_MESSAGE = "Unexpected trailing comma."; var UNEXPECTED_MESSAGE = "Unexpected trailing comma.";
var MISSING_MESSAGE = "Missing trailing comma."; var MISSING_MESSAGE = "Missing trailing comma.";
@ -114,10 +108,14 @@ module.exports = function(context) {
} }
if (trailingToken.value === ",") { if (trailingToken.value === ",") {
context.report( context.report({
lastItem, node: lastItem,
trailingToken.loc.start, loc: trailingToken.loc.start,
UNEXPECTED_MESSAGE); message: UNEXPECTED_MESSAGE,
fix: function(fixer) {
return fixer.remove(trailingToken);
}
});
} }
} }
@ -155,10 +153,14 @@ module.exports = function(context) {
} }
if (trailingToken.value !== ",") { if (trailingToken.value !== ",") {
context.report( context.report({
lastItem, node: lastItem,
lastItem.loc.end, loc: lastItem.loc.end,
MISSING_MESSAGE); message: MISSING_MESSAGE,
fix: function(fixer) {
return fixer.insertTextAfter(lastItem, ",");
}
});
} }
} }
@ -210,17 +212,12 @@ module.exports = function(context) {
} }
return { return {
"ObjectExpression": checkForTrailingComma, ObjectExpression: checkForTrailingComma,
"ObjectPattern": checkForTrailingComma, ObjectPattern: checkForTrailingComma,
"ArrayExpression": checkForTrailingComma, ArrayExpression: checkForTrailingComma,
"ArrayPattern": checkForTrailingComma, ArrayPattern: checkForTrailingComma,
"ImportDeclaration": checkForTrailingComma, ImportDeclaration: checkForTrailingComma,
"ExportNamedDeclaration": checkForTrailingComma ExportNamedDeclaration: checkForTrailingComma
};
}; };
module.exports.schema = [
{
"enum": ["always", "always-multiline", "only-multiline", "never"]
} }
]; };

49
tools/eslint/lib/rules/comma-spacing.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview Comma spacing - validates spacing before and after comma * @fileoverview Comma spacing - validates spacing before and after comma
* @author Vignesh Anand aka vegetableman. * @author Vignesh Anand aka vegetableman.
* @copyright 2014 Vignesh Anand. All rights reserved.
*/ */
"use strict"; "use strict";
@ -11,7 +10,33 @@ var astUtils = require("../ast-utils");
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce consistent spacing before and after commas",
category: "Stylistic Issues",
recommended: false
},
fixable: "whitespace",
schema: [
{
type: "object",
properties: {
before: {
type: "boolean"
},
after: {
type: "boolean"
}
},
additionalProperties: false
}
]
},
create: function(context) {
var sourceCode = context.getSourceCode(); var sourceCode = context.getSourceCode();
var tokensAndComments = sourceCode.tokensAndComments; var tokensAndComments = sourceCode.tokensAndComments;
@ -160,24 +185,10 @@ module.exports = function(context) {
}, token); }, token);
}); });
}, },
"ArrayExpression": addNullElementsToIgnoreList, ArrayExpression: addNullElementsToIgnoreList,
"ArrayPattern": addNullElementsToIgnoreList ArrayPattern: addNullElementsToIgnoreList
};
}; };
module.exports.schema = [
{
"type": "object",
"properties": {
"before": {
"type": "boolean"
},
"after": {
"type": "boolean"
}
},
"additionalProperties": false
} }
]; };

50
tools/eslint/lib/rules/comma-style.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Comma style - enforces comma styles of two types: last and first * @fileoverview Comma style - enforces comma styles of two types: last and first
* @author Vignesh Anand aka vegetableman * @author Vignesh Anand aka vegetableman
* @copyright 2014 Vignesh Anand. All rights reserved.
* @copyright 2015 Evan Simmons. All rights reserved.
*/ */
"use strict"; "use strict";
@ -13,7 +11,34 @@ var astUtils = require("../ast-utils");
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce consistent comma style",
category: "Stylistic Issues",
recommended: false
},
schema: [
{
enum: ["first", "last"]
},
{
type: "object",
properties: {
exceptions: {
type: "object",
additionalProperties: {
type: "boolean"
}
}
},
additionalProperties: false
}
]
},
create: function(context) {
var style = context.options[0] || "last", var style = context.options[0] || "last",
exceptions = {}; exceptions = {};
@ -165,22 +190,5 @@ module.exports = function(context) {
} }
return nodes; return nodes;
};
module.exports.schema = [
{
"enum": ["first", "last"]
},
{
"type": "object",
"properties": {
"exceptions": {
"type": "object",
"additionalProperties": {
"type": "boolean"
}
} }
}, };
"additionalProperties": false
}
];

88
tools/eslint/lib/rules/complexity.js

@ -10,7 +10,41 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce a maximum cyclomatic complexity allowed in a program",
category: "Best Practices",
recommended: false
},
schema: [
{
oneOf: [
{
type: "integer",
minimum: 0
},
{
type: "object",
properties: {
maximum: {
type: "integer",
minimum: 0
},
max: {
type: "integer",
minimum: 0
}
},
additionalProperties: false
}
]
}
]
},
create: function(context) {
var option = context.options[0], var option = context.options[0],
THRESHOLD = 20; THRESHOLD = 20;
@ -105,48 +139,24 @@ module.exports = function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
return { return {
"FunctionDeclaration": startFunction, FunctionDeclaration: startFunction,
"FunctionExpression": startFunction, FunctionExpression: startFunction,
"ArrowFunctionExpression": startFunction, ArrowFunctionExpression: startFunction,
"FunctionDeclaration:exit": endFunction, "FunctionDeclaration:exit": endFunction,
"FunctionExpression:exit": endFunction, "FunctionExpression:exit": endFunction,
"ArrowFunctionExpression:exit": endFunction, "ArrowFunctionExpression:exit": endFunction,
"CatchClause": increaseComplexity, CatchClause: increaseComplexity,
"ConditionalExpression": increaseComplexity, ConditionalExpression: increaseComplexity,
"LogicalExpression": increaseLogicalComplexity, LogicalExpression: increaseLogicalComplexity,
"ForStatement": increaseComplexity, ForStatement: increaseComplexity,
"ForInStatement": increaseComplexity, ForInStatement: increaseComplexity,
"ForOfStatement": increaseComplexity, ForOfStatement: increaseComplexity,
"IfStatement": increaseComplexity, IfStatement: increaseComplexity,
"SwitchCase": increaseSwitchComplexity, SwitchCase: increaseSwitchComplexity,
"WhileStatement": increaseComplexity, WhileStatement: increaseComplexity,
"DoWhileStatement": increaseComplexity DoWhileStatement: increaseComplexity
};
}; };
module.exports.schema = [
{
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"type": "object",
"properties": {
"maximum": {
"type": "integer",
"minimum": 0
},
"max": {
"type": "integer",
"minimum": 0
}
},
"additionalProperties": false
} }
] };
}
];

27
tools/eslint/lib/rules/computed-property-spacing.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview Disallows or enforces spaces inside computed properties. * @fileoverview Disallows or enforces spaces inside computed properties.
* @author Jamund Ferguson * @author Jamund Ferguson
* @copyright 2015 Jamund Ferguson. All rights reserved.
*/ */
"use strict"; "use strict";
@ -11,7 +10,24 @@ var astUtils = require("../ast-utils");
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce consistent spacing inside computed property brackets",
category: "Stylistic Issues",
recommended: false
},
fixable: "whitespace",
schema: [
{
enum: ["always", "never"]
}
]
},
create: function(context) {
var sourceCode = context.getSourceCode(); var sourceCode = context.getSourceCode();
var propertyNameMustBeSpaced = context.options[0] === "always"; // default is "never" var propertyNameMustBeSpaced = context.options[0] === "always"; // default is "never"
@ -144,10 +160,5 @@ module.exports = function(context) {
MemberExpression: checkSpacing("property") MemberExpression: checkSpacing("property")
}; };
};
module.exports.schema = [
{
"enum": ["always", "never"]
} }
]; };

22
tools/eslint/lib/rules/consistent-return.js

@ -27,7 +27,18 @@ function isUnreachable(segment) {
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require `return` statements to either always or never specify values",
category: "Best Practices",
recommended: false
},
schema: []
},
create: function(context) {
var funcInfo = null; var funcInfo = null;
/** /**
@ -89,7 +100,7 @@ module.exports = function(context) {
return { return {
// Initializes/Disposes state of each code path. // Initializes/Disposes state of each code path.
"onCodePathStart": function(codePath) { onCodePathStart: function(codePath) {
funcInfo = { funcInfo = {
upper: funcInfo, upper: funcInfo,
codePath: codePath, codePath: codePath,
@ -98,12 +109,12 @@ module.exports = function(context) {
message: "" message: ""
}; };
}, },
"onCodePathEnd": function() { onCodePathEnd: function() {
funcInfo = funcInfo.upper; funcInfo = funcInfo.upper;
}, },
// Reports a given return statement if it's inconsistent. // Reports a given return statement if it's inconsistent.
"ReturnStatement": function(node) { ReturnStatement: function(node) {
var hasReturnValue = Boolean(node.argument); var hasReturnValue = Boolean(node.argument);
if (!funcInfo.hasReturn) { if (!funcInfo.hasReturn) {
@ -121,6 +132,5 @@ module.exports = function(context) {
"FunctionExpression:exit": checkLastSegment, "FunctionExpression:exit": checkLastSegment,
"ArrowFunctionExpression:exit": checkLastSegment "ArrowFunctionExpression:exit": checkLastSegment
}; };
}
}; };
module.exports.schema = [];

36
tools/eslint/lib/rules/consistent-this.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Rule to enforce consistent naming of "this" context variables * @fileoverview Rule to enforce consistent naming of "this" context variables
* @author Raphael Pigulla * @author Raphael Pigulla
* @copyright 2015 Timothy Jones. All rights reserved.
* @copyright 2015 David Aurelio. All rights reserved.
*/ */
"use strict"; "use strict";
@ -10,7 +8,25 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce consistent naming when capturing the current execution context",
category: "Stylistic Issues",
recommended: false
},
schema: {
type: "array",
items: {
type: "string",
minLength: 1
},
uniqueItems: true
}
},
create: function(context) {
var aliases = []; var aliases = [];
if (context.options.length === 0) { if (context.options.length === 0) {
@ -111,7 +127,7 @@ module.exports = function(context) {
"FunctionExpression:exit": ensureWasAssigned, "FunctionExpression:exit": ensureWasAssigned,
"FunctionDeclaration:exit": ensureWasAssigned, "FunctionDeclaration:exit": ensureWasAssigned,
"VariableDeclarator": function(node) { VariableDeclarator: function(node) {
var id = node.id; var id = node.id;
var isDestructuring = var isDestructuring =
id.type === "ArrayPattern" || id.type === "ObjectPattern"; id.type === "ArrayPattern" || id.type === "ObjectPattern";
@ -121,20 +137,12 @@ module.exports = function(context) {
} }
}, },
"AssignmentExpression": function(node) { AssignmentExpression: function(node) {
if (node.left.type === "Identifier") { if (node.left.type === "Identifier") {
checkAssignment(node, node.left.name, node.right); checkAssignment(node, node.left.name, node.right);
} }
} }
}; };
}; }
module.exports.schema = {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
}; };

184
tools/eslint/lib/rules/constructor-super.js

@ -1,21 +1,24 @@
/** /**
* @fileoverview A rule to verify `super()` callings in constructor. * @fileoverview A rule to verify `super()` callings in constructor.
* @author Toru Nagashima * @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
*/ */
"use strict"; "use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var astUtils = require("../ast-utils");
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Helpers // Helpers
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/**
* Checks whether a given code path segment is reachable or not.
*
* @param {CodePathSegment} segment - A code path segment to check.
* @returns {boolean} `true` if the segment is reachable.
*/
function isReachable(segment) {
return segment.reachable;
}
/** /**
* Checks whether or not a given node is a constructor. * Checks whether or not a given node is a constructor.
* @param {ASTNode} node - A node to check. This node type is one of * @param {ASTNode} node - A node to check. This node type is one of
@ -31,11 +34,73 @@ function isConstructorFunction(node) {
); );
} }
/**
* Checks whether a given node can be a constructor or not.
*
* @param {ASTNode} node - A node to check.
* @returns {boolean} `true` if the node can be a constructor.
*/
function isPossibleConstructor(node) {
if (!node) {
return false;
}
switch (node.type) {
case "ClassExpression":
case "FunctionExpression":
case "ThisExpression":
case "MemberExpression":
case "CallExpression":
case "NewExpression":
case "YieldExpression":
case "TaggedTemplateExpression":
case "MetaProperty":
return true;
case "Identifier":
return node.name !== "undefined";
case "AssignmentExpression":
return isPossibleConstructor(node.right);
case "LogicalExpression":
return (
isPossibleConstructor(node.left) ||
isPossibleConstructor(node.right)
);
case "ConditionalExpression":
return (
isPossibleConstructor(node.alternate) ||
isPossibleConstructor(node.consequent)
);
case "SequenceExpression":
var lastExpression = node.expressions[node.expressions.length - 1];
return isPossibleConstructor(lastExpression);
default:
return false;
}
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require `super()` calls in constructors",
category: "ECMAScript 6",
recommended: true
},
schema: []
},
create: function(context) {
/* /*
* {{hasExtends: boolean, scope: Scope, codePath: CodePath}[]} * {{hasExtends: boolean, scope: Scope, codePath: CodePath}[]}
@ -63,7 +128,7 @@ module.exports = function(context) {
* @returns {boolean} The flag which shows `super()` is called in some paths * @returns {boolean} The flag which shows `super()` is called in some paths
*/ */
function isCalledInSomePath(segment) { function isCalledInSomePath(segment) {
return segInfoMap[segment.id].calledInSomePaths; return segment.reachable && segInfoMap[segment.id].calledInSomePaths;
} }
/** /**
@ -83,7 +148,7 @@ module.exports = function(context) {
) { ) {
return true; return true;
} }
return segInfoMap[segment.id].calledInEveryPaths; return segment.reachable && segInfoMap[segment.id].calledInEveryPaths;
} }
return { return {
@ -94,19 +159,18 @@ module.exports = function(context) {
* @param {ASTNode} node - The current node. * @param {ASTNode} node - The current node.
* @returns {void} * @returns {void}
*/ */
"onCodePathStart": function(codePath, node) { onCodePathStart: function(codePath, node) {
if (isConstructorFunction(node)) { if (isConstructorFunction(node)) {
// Class > ClassBody > MethodDefinition > FunctionExpression // Class > ClassBody > MethodDefinition > FunctionExpression
var classNode = node.parent.parent.parent; var classNode = node.parent.parent.parent;
var superClass = classNode.superClass;
funcInfo = { funcInfo = {
upper: funcInfo, upper: funcInfo,
isConstructor: true, isConstructor: true,
hasExtends: Boolean( hasExtends: Boolean(superClass),
classNode.superClass && superIsConstructor: isPossibleConstructor(superClass),
!astUtils.isNullOrUndefined(classNode.superClass)
),
codePath: codePath codePath: codePath
}; };
} else { } else {
@ -114,6 +178,7 @@ module.exports = function(context) {
upper: funcInfo, upper: funcInfo,
isConstructor: false, isConstructor: false,
hasExtends: false, hasExtends: false,
superIsConstructor: false,
codePath: codePath codePath: codePath
}; };
} }
@ -126,11 +191,10 @@ module.exports = function(context) {
* @param {ASTNode} node - The current node. * @param {ASTNode} node - The current node.
* @returns {void} * @returns {void}
*/ */
"onCodePathEnd": function(codePath, node) { onCodePathEnd: function(codePath, node) {
// Skip if own class which has a valid `extends` part.
var hasExtends = funcInfo.hasExtends; var hasExtends = funcInfo.hasExtends;
// Pop.
funcInfo = funcInfo.upper; funcInfo = funcInfo.upper;
if (!hasExtends) { if (!hasExtends) {
@ -157,12 +221,7 @@ module.exports = function(context) {
* @param {CodePathSegment} segment - A code path segment to initialize. * @param {CodePathSegment} segment - A code path segment to initialize.
* @returns {void} * @returns {void}
*/ */
"onCodePathSegmentStart": function(segment) { onCodePathSegmentStart: function(segment) {
/*
* Skip if this is not in a constructor of a class which has a
* valid `extends` part.
*/
if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) {
return; return;
} }
@ -192,12 +251,7 @@ module.exports = function(context) {
* of a loop. * of a loop.
* @returns {void} * @returns {void}
*/ */
"onCodePathSegmentLoop": function(fromSegment, toSegment) { onCodePathSegmentLoop: function(fromSegment, toSegment) {
/*
* Skip if this is not in a constructor of a class which has a
* valid `extends` part.
*/
if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) {
return; return;
} }
@ -209,10 +263,9 @@ module.exports = function(context) {
{first: toSegment, last: fromSegment}, {first: toSegment, last: fromSegment},
function(segment) { function(segment) {
var info = segInfoMap[segment.id]; var info = segInfoMap[segment.id];
// Updates flags.
var prevSegments = segment.prevSegments; var prevSegments = segment.prevSegments;
// Updates flags.
info.calledInSomePaths = prevSegments.some(isCalledInSomePath); info.calledInSomePaths = prevSegments.some(isCalledInSomePath);
info.calledInEveryPaths = prevSegments.every(isCalledInEveryPath); info.calledInEveryPaths = prevSegments.every(isCalledInEveryPath);
@ -241,48 +294,49 @@ module.exports = function(context) {
* @returns {void} * @returns {void}
*/ */
"CallExpression:exit": function(node) { "CallExpression:exit": function(node) {
if (!(funcInfo && funcInfo.isConstructor)) {
// Skip if the node is not `super()`.
if (node.callee.type !== "Super") {
return; return;
} }
// Skip if this is not in a constructor. // Skips except `super()`.
if (!(funcInfo && funcInfo.isConstructor)) { if (node.callee.type !== "Super") {
return; return;
} }
// Reports if needed. // Reports if needed.
if (funcInfo.hasExtends) { if (funcInfo.hasExtends) {
/*
* This class has a valid `extends` part.
* Checks duplicate `super()`;
*/
var segments = funcInfo.codePath.currentSegments; var segments = funcInfo.codePath.currentSegments;
var reachable = false;
var duplicate = false; var duplicate = false;
for (var i = 0; i < segments.length; ++i) { for (var i = 0; i < segments.length; ++i) {
var info = segInfoMap[segments[i].id]; var segment = segments[i];
if (segment.reachable) {
var info = segInfoMap[segment.id];
reachable = true;
duplicate = duplicate || info.calledInSomePaths; duplicate = duplicate || info.calledInSomePaths;
info.calledInSomePaths = info.calledInEveryPaths = true; info.calledInSomePaths = info.calledInEveryPaths = true;
} }
}
if (reachable) {
if (duplicate) { if (duplicate) {
context.report({ context.report({
message: "Unexpected duplicate 'super()'.", message: "Unexpected duplicate 'super()'.",
node: node node: node
}); });
} else if (!funcInfo.superIsConstructor) {
context.report({
message: "Unexpected 'super()' because 'super' is not a constructor.",
node: node
});
} else { } else {
info.validNodes.push(node); info.validNodes.push(node);
} }
} else { }
} else if (funcInfo.codePath.currentSegments.some(isReachable)) {
/*
* This class does not have a valid `extends` part.
* Disallow `super()`.
*/
context.report({ context.report({
message: "Unexpected 'super()'.", message: "Unexpected 'super()'.",
node: node node: node
@ -290,6 +344,35 @@ module.exports = function(context) {
} }
}, },
/**
* Set the mark to the returned path as `super()` was called.
* @param {ASTNode} node - A ReturnStatement node to check.
* @returns {void}
*/
ReturnStatement: function(node) {
if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) {
return;
}
// Skips if no argument.
if (!node.argument) {
return;
}
// Returning argument is a substitute of 'super()'.
var segments = funcInfo.codePath.currentSegments;
for (var i = 0; i < segments.length; ++i) {
var segment = segments[i];
if (segment.reachable) {
var info = segInfoMap[segment.id];
info.calledInSomePaths = info.calledInEveryPaths = true;
}
}
},
/** /**
* Resets state. * Resets state.
* @returns {void} * @returns {void}
@ -298,6 +381,5 @@ module.exports = function(context) {
segInfoMap = Object.create(null); segInfoMap = Object.create(null);
} }
}; };
}
}; };
module.exports.schema = [];

79
tools/eslint/lib/rules/curly.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview Rule to flag statements without curly braces * @fileoverview Rule to flag statements without curly braces
* @author Nicholas C. Zakas * @author Nicholas C. Zakas
* @copyright 2015 Ivan Nikulin. All rights reserved.
*/ */
"use strict"; "use strict";
@ -15,7 +14,44 @@ var astUtils = require("../ast-utils");
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce consistent brace style for all control statements",
category: "Best Practices",
recommended: false
},
schema: {
anyOf: [
{
type: "array",
items: [
{
enum: ["all"]
}
],
minItems: 0,
maxItems: 1
},
{
type: "array",
items: [
{
enum: ["multi", "multi-line", "multi-or-nest"]
},
{
enum: ["consistent"]
}
],
minItems: 0,
maxItems: 2
}
]
}
},
create: function(context) {
var multiOnly = (context.options[0] === "multi"); var multiOnly = (context.options[0] === "multi");
var multiLine = (context.options[0] === "multi-line"); var multiLine = (context.options[0] === "multi-line");
@ -235,7 +271,7 @@ module.exports = function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
return { return {
"IfStatement": function(node) { IfStatement: function(node) {
if (node.parent.type !== "IfStatement") { if (node.parent.type !== "IfStatement") {
prepareIfChecks(node).forEach(function(preparedCheck) { prepareIfChecks(node).forEach(function(preparedCheck) {
preparedCheck.check(); preparedCheck.check();
@ -243,52 +279,25 @@ module.exports = function(context) {
} }
}, },
"WhileStatement": function(node) { WhileStatement: function(node) {
prepareCheck(node, node.body, "while", "condition").check(); prepareCheck(node, node.body, "while", "condition").check();
}, },
"DoWhileStatement": function(node) { DoWhileStatement: function(node) {
prepareCheck(node, node.body, "do").check(); prepareCheck(node, node.body, "do").check();
}, },
"ForStatement": function(node) { ForStatement: function(node) {
prepareCheck(node, node.body, "for", "condition").check(); prepareCheck(node, node.body, "for", "condition").check();
}, },
"ForInStatement": function(node) { ForInStatement: function(node) {
prepareCheck(node, node.body, "for-in").check(); prepareCheck(node, node.body, "for-in").check();
}, },
"ForOfStatement": function(node) { ForOfStatement: function(node) {
prepareCheck(node, node.body, "for-of").check(); prepareCheck(node, node.body, "for-of").check();
} }
}; };
};
module.exports.schema = {
"anyOf": [
{
"type": "array",
"items": [
{
"enum": ["all"]
}
],
"minItems": 0,
"maxItems": 1
},
{
"type": "array",
"items": [
{
"enum": ["multi", "multi-line", "multi-or-nest"]
},
{
"enum": ["consistent"]
}
],
"minItems": 0,
"maxItems": 2
} }
]
}; };

34
tools/eslint/lib/rules/default-case.js

@ -4,13 +4,36 @@
*/ */
"use strict"; "use strict";
var COMMENT_VALUE = "no default"; var DEFAULT_COMMENT_PATTERN = /^no default$/;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require `default` cases in <code>switch</code> statements",
category: "Best Practices",
recommended: false
},
schema: [{
type: "object",
properties: {
commentPattern: {
type: "string"
}
},
additionalProperties: false
}]
},
create: function(context) {
var options = context.options[0] || {};
var commentPattern = options.commentPattern ?
new RegExp(options.commentPattern) :
DEFAULT_COMMENT_PATTERN;
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Helpers // Helpers
@ -31,7 +54,7 @@ module.exports = function(context) {
return { return {
"SwitchStatement": function(node) { SwitchStatement: function(node) {
if (!node.cases.length) { if (!node.cases.length) {
@ -59,12 +82,11 @@ module.exports = function(context) {
comment = last(comments); comment = last(comments);
} }
if (!comment || comment.value.trim() !== COMMENT_VALUE) { if (!comment || !commentPattern.test(comment.value.trim())) {
context.report(node, "Expected a default case."); context.report(node, "Expected a default case.");
} }
} }
} }
}; };
}
}; };
module.exports.schema = [];

27
tools/eslint/lib/rules/dot-location.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview Validates newlines before and after dots * @fileoverview Validates newlines before and after dots
* @author Greg Cochard * @author Greg Cochard
* @copyright 2015 Greg Cochard
*/ */
"use strict"; "use strict";
@ -12,7 +11,22 @@ var astUtils = require("../ast-utils");
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce consistent newlines before and after dots",
category: "Best Practices",
recommended: false
},
schema: [
{
enum: ["object", "property"]
}
]
},
create: function(context) {
var config = context.options[0], var config = context.options[0],
onObject; onObject;
@ -51,12 +65,7 @@ module.exports = function(context) {
} }
return { return {
"MemberExpression": checkNode MemberExpression: checkNode
}; };
};
module.exports.schema = [
{
"enum": ["object", "property"]
} }
]; };

44
tools/eslint/lib/rules/dot-notation.js

@ -11,7 +11,31 @@
var validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/; var validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
var keywords = require("../util/keywords"); var keywords = require("../util/keywords");
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce dot notation whenever possible",
category: "Best Practices",
recommended: false
},
schema: [
{
type: "object",
properties: {
allowKeywords: {
type: "boolean"
},
allowPattern: {
type: "string"
}
},
additionalProperties: false
}
]
},
create: function(context) {
var options = context.options[0] || {}; var options = context.options[0] || {};
var allowKeywords = options.allowKeywords === void 0 || !!options.allowKeywords; var allowKeywords = options.allowKeywords === void 0 || !!options.allowKeywords;
@ -22,7 +46,7 @@ module.exports = function(context) {
} }
return { return {
"MemberExpression": function(node) { MemberExpression: function(node) {
if ( if (
node.computed && node.computed &&
node.property.type === "Literal" && node.property.type === "Literal" &&
@ -42,19 +66,5 @@ module.exports = function(context) {
} }
} }
}; };
};
module.exports.schema = [
{
"type": "object",
"properties": {
"allowKeywords": {
"type": "boolean"
},
"allowPattern": {
"type": "string"
}
},
"additionalProperties": false
} }
]; };

28
tools/eslint/lib/rules/eol-last.js

@ -8,7 +8,24 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce at least one newline at the end of files",
category: "Stylistic Issues",
recommended: false
},
fixable: "whitespace",
schema: [
{
enum: ["unix", "windows"]
}
]
},
create: function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Public // Public
@ -16,7 +33,7 @@ module.exports = function(context) {
return { return {
"Program": function checkBadEOF(node) { Program: function checkBadEOF(node) {
// Get the whole source code, not for node only. // Get the whole source code, not for node only.
var src = context.getSource(), var src = context.getSource(),
@ -41,10 +58,5 @@ module.exports = function(context) {
}; };
};
module.exports.schema = [
{
"enum": ["unix", "windows"]
} }
]; };

28
tools/eslint/lib/rules/eqeqeq.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Rule to flag statements that use != and == instead of !== and === * @fileoverview Rule to flag statements that use != and == instead of !== and ===
* @author Nicholas C. Zakas * @author Nicholas C. Zakas
* @copyright 2013 Nicholas C. Zakas. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";
@ -11,7 +9,22 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require the use of `===` and `!==`",
category: "Best Practices",
recommended: false
},
schema: [
{
enum: ["smart", "allow-null"]
}
]
},
create: function(context) {
/** /**
* Checks if an expression is a typeof expression * Checks if an expression is a typeof expression
@ -68,7 +81,7 @@ module.exports = function(context) {
} }
return { return {
"BinaryExpression": function(node) { BinaryExpression: function(node) {
if (node.operator !== "==" && node.operator !== "!=") { if (node.operator !== "==" && node.operator !== "!=") {
return; return;
} }
@ -92,10 +105,5 @@ module.exports = function(context) {
} }
}; };
};
module.exports.schema = [
{
"enum": ["smart", "allow-null"]
} }
]; };

20
tools/eslint/lib/rules/func-names.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Rule to warn when a function expression does not have a name. * @fileoverview Rule to warn when a function expression does not have a name.
* @author Kyle T. Nunery * @author Kyle T. Nunery
* @copyright 2015 Brandon Mills. All rights reserved.
* @copyright 2014 Kyle T. Nunery. All rights reserved.
*/ */
"use strict"; "use strict";
@ -11,7 +9,18 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce named `function` expressions",
category: "Stylistic Issues",
recommended: false
},
schema: []
},
create: function(context) {
/** /**
* Determines whether the current FunctionExpression node is a get, set, or * Determines whether the current FunctionExpression node is a get, set, or
@ -31,7 +40,7 @@ module.exports = function(context) {
} }
return { return {
"FunctionExpression": function(node) { FunctionExpression: function(node) {
var name = node.id && node.id.name; var name = node.id && node.id.name;
@ -40,6 +49,5 @@ module.exports = function(context) {
} }
} }
}; };
}
}; };
module.exports.schema = [];

51
tools/eslint/lib/rules/func-style.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview Rule to enforce a particular function style * @fileoverview Rule to enforce a particular function style
* @author Nicholas C. Zakas * @author Nicholas C. Zakas
* @copyright 2013 Nicholas C. Zakas. All rights reserved.
*/ */
"use strict"; "use strict";
@ -9,7 +8,31 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce the consistent use of either `function` declarations or expressions",
category: "Stylistic Issues",
recommended: false
},
schema: [
{
enum: ["declaration", "expression"]
},
{
type: "object",
properties: {
allowArrowFunctions: {
type: "boolean"
}
},
additionalProperties: false
}
]
},
create: function(context) {
var style = context.options[0], var style = context.options[0],
allowArrowFunctions = context.options[1] && context.options[1].allowArrowFunctions === true, allowArrowFunctions = context.options[1] && context.options[1].allowArrowFunctions === true,
@ -17,11 +40,11 @@ module.exports = function(context) {
stack = []; stack = [];
var nodesToCheck = { var nodesToCheck = {
"Program": function() { Program: function() {
stack = []; stack = [];
}, },
"FunctionDeclaration": function(node) { FunctionDeclaration: function(node) {
stack.push(false); stack.push(false);
if (!enforceDeclarations && node.parent.type !== "ExportDefaultDeclaration") { if (!enforceDeclarations && node.parent.type !== "ExportDefaultDeclaration") {
@ -32,7 +55,7 @@ module.exports = function(context) {
stack.pop(); stack.pop();
}, },
"FunctionExpression": function(node) { FunctionExpression: function(node) {
stack.push(false); stack.push(false);
if (enforceDeclarations && node.parent.type === "VariableDeclarator") { if (enforceDeclarations && node.parent.type === "VariableDeclarator") {
@ -43,7 +66,7 @@ module.exports = function(context) {
stack.pop(); stack.pop();
}, },
"ThisExpression": function() { ThisExpression: function() {
if (stack.length > 0) { if (stack.length > 0) {
stack[stack.length - 1] = true; stack[stack.length - 1] = true;
} }
@ -66,19 +89,5 @@ module.exports = function(context) {
return nodesToCheck; return nodesToCheck;
};
module.exports.schema = [
{
"enum": ["declaration", "expression"]
},
{
"type": "object",
"properties": {
"allowArrowFunctions": {
"type": "boolean"
}
},
"additionalProperties": false
} }
]; };

56
tools/eslint/lib/rules/generator-star-spacing.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Rule to check the spacing around the * in generator functions. * @fileoverview Rule to check the spacing around the * in generator functions.
* @author Jamund Ferguson * @author Jamund Ferguson
* @copyright 2015 Brandon Mills. All rights reserved.
* @copyright 2014 Jamund Ferguson. All rights reserved.
*/ */
"use strict"; "use strict";
@ -11,7 +9,36 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce consistent spacing around `*` operators in generator functions",
category: "ECMAScript 6",
recommended: false
},
fixable: "whitespace",
schema: [
{
oneOf: [
{
enum: ["before", "after", "both", "neither"]
},
{
type: "object",
properties: {
before: {type: "boolean"},
after: {type: "boolean"}
},
additionalProperties: false
}
]
}
]
},
create: function(context) {
var mode = (function(option) { var mode = (function(option) {
if (!option || typeof option === "string") { if (!option || typeof option === "string") {
@ -87,26 +114,9 @@ module.exports = function(context) {
} }
return { return {
"FunctionDeclaration": checkFunction, FunctionDeclaration: checkFunction,
"FunctionExpression": checkFunction FunctionExpression: checkFunction
};
}; };
module.exports.schema = [
{
"oneOf": [
{
"enum": ["before", "after", "both", "neither"]
},
{
"type": "object",
"properties": {
"before": {"type": "boolean"},
"after": {"type": "boolean"}
},
"additionalProperties": false
} }
] };
}
];

19
tools/eslint/lib/rules/global-require.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview Rule for disallowing require() outside of the top-level module context * @fileoverview Rule for disallowing require() outside of the top-level module context
* @author Jamund Ferguson * @author Jamund Ferguson
* @copyright 2015 Jamund Ferguson. All rights reserved.
*/ */
"use strict"; "use strict";
@ -49,9 +48,20 @@ function isShadowed(scope, node) {
return reference && reference.resolved && reference.resolved.defs.length > 0; return reference && reference.resolved && reference.resolved.defs.length > 0;
} }
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require `require()` calls to be placed at top-level module scope",
category: "Node.js and CommonJS",
recommended: false
},
schema: []
},
create: function(context) {
return { return {
"CallExpression": function(node) { CallExpression: function(node) {
var currentScope = context.getScope(), var currentScope = context.getScope(),
isGoodRequire; isGoodRequire;
@ -65,6 +75,5 @@ module.exports = function(context) {
} }
} }
}; };
}
}; };
module.exports.schema = [];

18
tools/eslint/lib/rules/guard-for-in.js

@ -9,11 +9,22 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require `for-in` loops to include an `if` statement",
category: "Best Practices",
recommended: false
},
schema: []
},
create: function(context) {
return { return {
"ForInStatement": function(node) { ForInStatement: function(node) {
/* /*
* If the for-in statement has {}, then the real body is the body * If the for-in statement has {}, then the real body is the body
@ -27,6 +38,5 @@ module.exports = function(context) {
} }
}; };
}
}; };
module.exports.schema = [];

32
tools/eslint/lib/rules/handle-callback-err.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Ensure handling of errors when we know they exist. * @fileoverview Ensure handling of errors when we know they exist.
* @author Jamund Ferguson * @author Jamund Ferguson
* @copyright 2015 Mathias Schreck.
* @copyright 2014 Jamund Ferguson. All rights reserved.
*/ */
"use strict"; "use strict";
@ -11,7 +9,22 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require error handling in callbacks",
category: "Node.js and CommonJS",
recommended: false
},
schema: [
{
type: "string"
}
]
},
create: function(context) {
var errorArgument = context.options[0] || "err"; var errorArgument = context.options[0] || "err";
@ -69,15 +82,10 @@ module.exports = function(context) {
} }
return { return {
"FunctionDeclaration": checkForError, FunctionDeclaration: checkForError,
"FunctionExpression": checkForError, FunctionExpression: checkForError,
"ArrowFunctionExpression": checkForError ArrowFunctionExpression: checkForError
}; };
};
module.exports.schema = [
{
"type": "string"
} }
]; };

35
tools/eslint/lib/rules/id-blacklist.js

@ -1,11 +1,7 @@
/** /**
* @fileoverview Rule that warns when identifier names that are * @fileoverview Rule that warns when identifier names that are
blacklisted in the configuration are used. * blacklisted in the configuration are used.
* @author Keith Cirkel (http://keithcirkel.co.uk) * @author Keith Cirkel (http://keithcirkel.co.uk)
* Based on id-match rule:
* @author Matthieu Larcher
* @copyright 2015 Matthieu Larcher. All rights reserved.
* See LICENSE in root directory for full license.
*/ */
"use strict"; "use strict";
@ -14,7 +10,24 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "disallow specified identifiers",
category: "Stylistic Issues",
recommended: false
},
schema: {
type: "array",
items: {
type: "string"
},
uniqueItems: true
}
},
create: function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@ -61,7 +74,7 @@ module.exports = function(context) {
return { return {
"Identifier": function(node) { Identifier: function(node) {
var name = node.name, var name = node.name,
effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent; effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent;
@ -100,11 +113,5 @@ module.exports = function(context) {
}; };
}; }
module.exports.schema = {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
}; };

95
tools/eslint/lib/rules/id-length.js

@ -2,8 +2,6 @@
* @fileoverview Rule that warns when identifier names are shorter or longer * @fileoverview Rule that warns when identifier names are shorter or longer
* than the values provided in configuration. * than the values provided in configuration.
* @author Burak Yigit Kaya aka BYK * @author Burak Yigit Kaya aka BYK
* @copyright 2015 Burak Yigit Kaya. All rights reserved.
* @copyright 2015 Mathieu M-Gosselin. All rights reserved.
*/ */
"use strict"; "use strict";
@ -12,7 +10,41 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce minimum and maximum identifier lengths",
category: "Stylistic Issues",
recommended: false
},
schema: [
{
type: "object",
properties: {
min: {
type: "number"
},
max: {
type: "number"
},
exceptions: {
type: "array",
uniqueItems: true,
items: {
type: "string"
}
},
properties: {
enum: ["always", "never"]
}
},
additionalProperties: false
}
]
},
create: function(context) {
var options = context.options[0] || {}; var options = context.options[0] || {};
var minLength = typeof options.min !== "undefined" ? options.min : 2; var minLength = typeof options.min !== "undefined" ? options.min : 2;
var maxLength = typeof options.max !== "undefined" ? options.max : Infinity; var maxLength = typeof options.max !== "undefined" ? options.max : Infinity;
@ -25,35 +57,32 @@ module.exports = function(context) {
}, {}); }, {});
var SUPPORTED_EXPRESSIONS = { var SUPPORTED_EXPRESSIONS = {
"MemberExpression": properties && function(parent) { MemberExpression: properties && function(parent) {
return !parent.computed && ( return !parent.computed && (
// regular property assignment // regular property assignment
parent.parent.left === parent || ( (parent.parent.left === parent || // or the last identifier in an ObjectPattern destructuring
// or the last identifier in an ObjectPattern destructuring
parent.parent.type === "Property" && parent.parent.value === parent && parent.parent.type === "Property" && parent.parent.value === parent &&
parent.parent.parent.type === "ObjectPattern" && parent.parent.parent.parent.left === parent.parent.parent parent.parent.parent.type === "ObjectPattern" && parent.parent.parent.parent.left === parent.parent.parent)
)
); );
}, },
"AssignmentPattern": function(parent, node) { AssignmentPattern: function(parent, node) {
return parent.left === node; return parent.left === node;
}, },
"VariableDeclarator": function(parent, node) { VariableDeclarator: function(parent, node) {
return parent.id === node; return parent.id === node;
}, },
"Property": properties && function(parent, node) { Property: properties && function(parent, node) {
return parent.key === node; return parent.key === node;
}, },
"ImportDefaultSpecifier": true, ImportDefaultSpecifier: true,
"RestElement": true, RestElement: true,
"FunctionExpression": true, FunctionExpression: true,
"ArrowFunctionExpression": true, ArrowFunctionExpression: true,
"ClassDeclaration": true, ClassDeclaration: true,
"FunctionDeclaration": true, FunctionDeclaration: true,
"MethodDefinition": true, MethodDefinition: true,
"CatchClause": true CatchClause: true
}; };
return { return {
@ -81,29 +110,5 @@ module.exports = function(context) {
} }
} }
}; };
};
module.exports.schema = [
{
"type": "object",
"properties": {
"min": {
"type": "number"
},
"max": {
"type": "number"
},
"exceptions": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "string"
} }
}, };
"properties": {
"enum": ["always", "never"]
}
},
"additionalProperties": false
}
];

81
tools/eslint/lib/rules/id-match.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Rule to flag non-matching identifiers * @fileoverview Rule to flag non-matching identifiers
* @author Matthieu Larcher * @author Matthieu Larcher
* @copyright 2015 Matthieu Larcher. All rights reserved.
* See LICENSE in root directory for full license.
*/ */
"use strict"; "use strict";
@ -11,7 +9,30 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require identifiers to match a specified regular expression",
category: "Stylistic Issues",
recommended: false
},
schema: [
{
type: "string"
},
{
type: "object",
properties: {
properties: {
type: "boolean"
}
}
}
]
},
create: function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Helpers // Helpers
@ -21,11 +42,8 @@ module.exports = function(context) {
regexp = new RegExp(pattern); regexp = new RegExp(pattern);
var options = context.options[1] || {}, var options = context.options[1] || {},
properties = options.properties; properties = !!options.properties,
onlyDeclarations = !!options.onlyDeclarations;
// cast to boolean and default to false
properties = !!properties;
/** /**
* Checks if a string matches the provided pattern * Checks if a string matches the provided pattern
@ -65,21 +83,20 @@ module.exports = function(context) {
return { return {
"Identifier": function(node) { Identifier: function(node) {
var name = node.name, var name = node.name,
effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent; parent = node.parent,
effectiveParent = (parent.type === "MemberExpression") ? parent.parent : parent;
// MemberExpressions get special rules if (parent.type === "MemberExpression") {
if (node.parent.type === "MemberExpression") {
// return early if properties is false
if (!properties) { if (!properties) {
return; return;
} }
// Always check object names // Always check object names
if (node.parent.object.type === "Identifier" && if (parent.object.type === "Identifier" &&
node.parent.object.name === node.name) { parent.object.name === name) {
if (isInvalid(name)) { if (isInvalid(name)) {
report(node); report(node);
} }
@ -88,17 +105,15 @@ module.exports = function(context) {
} else if (effectiveParent.type === "AssignmentExpression" && } else if (effectiveParent.type === "AssignmentExpression" &&
(effectiveParent.right.type !== "MemberExpression" || (effectiveParent.right.type !== "MemberExpression" ||
effectiveParent.left.type === "MemberExpression" && effectiveParent.left.type === "MemberExpression" &&
effectiveParent.left.property.name === node.name)) { effectiveParent.left.property.name === name)) {
if (isInvalid(name)) { if (isInvalid(name)) {
report(node); report(node);
} }
} }
// Properties have their own rules } else if (parent.type === "Property") {
} else if (node.parent.type === "Property") {
// return early if properties is false if (!properties || parent.key.name !== name) {
if (!properties) {
return; return;
} }
@ -106,26 +121,20 @@ module.exports = function(context) {
report(node); report(node);
} }
// Report anything that is a match and not a CallExpression } else {
} else if (shouldReport(effectiveParent, name)) { var isDeclaration = effectiveParent.type === "FunctionDeclaration" || effectiveParent.type === "VariableDeclarator";
if (onlyDeclarations && !isDeclaration) {
return;
}
if (shouldReport(effectiveParent, name)) {
report(node); report(node);
} }
} }
}
}; };
};
module.exports.schema = [
{
"type": "string"
},
{
"type": "object",
"properties": {
"properties": {
"type": "boolean"
} }
} };
}
];

163
tools/eslint/lib/rules/indent.js

@ -1,30 +1,9 @@
/** /**
* @fileoverview This option sets a specific tab width for your code * @fileoverview This option sets a specific tab width for your code
*
* This rule has been ported and modified from nodeca. * This rule has been ported and modified from nodeca.
* @author Vitaly Puzrin * @author Vitaly Puzrin
* @author Gyandeep Singh * @author Gyandeep Singh
* @copyright 2015 Vitaly Puzrin. All rights reserved.
* @copyright 2015 Gyandeep Singh. All rights reserved.
Copyright (C) 2014 by Vitaly Puzrin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/ */
"use strict"; "use strict";
@ -35,7 +14,67 @@
var util = require("util"); var util = require("util");
var lodash = require("lodash"); var lodash = require("lodash");
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce consistent indentation",
category: "Stylistic Issues",
recommended: false
},
fixable: "whitespace",
schema: [
{
oneOf: [
{
enum: ["tab"]
},
{
type: "integer",
minimum: 0
}
]
},
{
type: "object",
properties: {
SwitchCase: {
type: "integer",
minimum: 0
},
VariableDeclarator: {
oneOf: [
{
type: "integer",
minimum: 0
},
{
type: "object",
properties: {
var: {
type: "integer",
minimum: 0
},
let: {
type: "integer",
minimum: 0
},
const: {
type: "integer",
minimum: 0
}
}
}
]
}
},
additionalProperties: false
}
]
},
create: function(context) {
var MESSAGE = "Expected indentation of {{needed}} {{type}} {{characters}} but found {{gotten}}."; var MESSAGE = "Expected indentation of {{needed}} {{type}} {{characters}} but found {{gotten}}.";
var DEFAULT_VARIABLE_INDENT = 1; var DEFAULT_VARIABLE_INDENT = 1;
@ -658,7 +697,7 @@ module.exports = function(context) {
} }
return { return {
"Program": function(node) { Program: function(node) {
if (node.body.length > 0) { if (node.body.length > 0) {
// Root nodes should have no indent // Root nodes should have no indent
@ -666,41 +705,41 @@ module.exports = function(context) {
} }
}, },
"ClassBody": blockIndentationCheck, ClassBody: blockIndentationCheck,
"BlockStatement": blockIndentationCheck, BlockStatement: blockIndentationCheck,
"WhileStatement": blockLessNodes, WhileStatement: blockLessNodes,
"ForStatement": blockLessNodes, ForStatement: blockLessNodes,
"ForInStatement": blockLessNodes, ForInStatement: blockLessNodes,
"ForOfStatement": blockLessNodes, ForOfStatement: blockLessNodes,
"DoWhileStatement": blockLessNodes, DoWhileStatement: blockLessNodes,
"IfStatement": function(node) { IfStatement: function(node) {
if (node.consequent.type !== "BlockStatement" && node.consequent.loc.start.line > node.loc.start.line) { if (node.consequent.type !== "BlockStatement" && node.consequent.loc.start.line > node.loc.start.line) {
blockIndentationCheck(node); blockIndentationCheck(node);
} }
}, },
"VariableDeclaration": function(node) { VariableDeclaration: function(node) {
if (node.declarations[node.declarations.length - 1].loc.start.line > node.declarations[0].loc.start.line) { if (node.declarations[node.declarations.length - 1].loc.start.line > node.declarations[0].loc.start.line) {
checkIndentInVariableDeclarations(node); checkIndentInVariableDeclarations(node);
} }
}, },
"ObjectExpression": function(node) { ObjectExpression: function(node) {
checkIndentInArrayOrObjectBlock(node); checkIndentInArrayOrObjectBlock(node);
}, },
"ArrayExpression": function(node) { ArrayExpression: function(node) {
checkIndentInArrayOrObjectBlock(node); checkIndentInArrayOrObjectBlock(node);
}, },
"SwitchStatement": function(node) { SwitchStatement: function(node) {
// Switch is not a 'BlockStatement' // Switch is not a 'BlockStatement'
var switchIndent = getNodeIndent(node); var switchIndent = getNodeIndent(node);
@ -712,7 +751,7 @@ module.exports = function(context) {
checkLastNodeLineIndent(node, switchIndent); checkLastNodeLineIndent(node, switchIndent);
}, },
"SwitchCase": function(node) { SwitchCase: function(node) {
// Skip inline cases // Skip inline cases
if (isSingleLineNode(node)) { if (isSingleLineNode(node)) {
@ -724,53 +763,5 @@ module.exports = function(context) {
} }
}; };
};
module.exports.schema = [
{
"oneOf": [
{
"enum": ["tab"]
},
{
"type": "integer",
"minimum": 0
} }
] };
},
{
"type": "object",
"properties": {
"SwitchCase": {
"type": "integer",
"minimum": 0
},
"VariableDeclarator": {
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"type": "object",
"properties": {
"var": {
"type": "integer",
"minimum": 0
},
"let": {
"type": "integer",
"minimum": 0
},
"const": {
"type": "integer",
"minimum": 0
}
}
}
]
}
},
"additionalProperties": false
}
];

79
tools/eslint/lib/rules/init-declarations.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview A rule to control the style of variable initializations. * @fileoverview A rule to control the style of variable initializations.
* @author Colin Ihrig * @author Colin Ihrig
* @copyright 2015 Colin Ihrig. All rights reserved.
*/ */
"use strict"; "use strict";
@ -43,7 +42,50 @@ function isInitialized(node) {
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require or disallow initialization in `var` declarations",
category: "Variables",
recommended: false
},
schema: {
anyOf: [
{
type: "array",
items: [
{
enum: ["always"]
}
],
minItems: 0,
maxItems: 1
},
{
type: "array",
items: [
{
enum: ["never"]
},
{
type: "object",
properties: {
ignoreForLoopInit: {
type: "boolean"
}
},
additionalProperties: false
}
],
minItems: 0,
maxItems: 2
}
]
}
},
create: function(context) {
var MODE_ALWAYS = "always", var MODE_ALWAYS = "always",
MODE_NEVER = "never"; MODE_NEVER = "never";
@ -79,38 +121,5 @@ module.exports = function(context) {
} }
} }
}; };
};
module.exports.schema = {
"anyOf": [
{
"type": "array",
"items": [
{
"enum": ["always"]
}
],
"minItems": 0,
"maxItems": 1
},
{
"type": "array",
"items": [
{
"enum": ["never"]
},
{
"type": "object",
"properties": {
"ignoreForLoopInit": {
"type": "boolean"
} }
},
"additionalProperties": false
}
],
"minItems": 0,
"maxItems": 2
}
]
}; };

29
tools/eslint/lib/rules/jsx-quotes.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview A rule to ensure consistent quotes used in jsx syntax. * @fileoverview A rule to ensure consistent quotes used in jsx syntax.
* @author Mathias Schreck <https://github.com/lo1tuma> * @author Mathias Schreck <https://github.com/lo1tuma>
* @copyright 2015 Mathias Schreck
*/ */
"use strict"; "use strict";
@ -37,7 +36,24 @@ var QUOTE_SETTINGS = {
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce the consistent use of either double or single quotes in JSX attributes",
category: "Stylistic Issues",
recommended: false
},
fixable: "whitespace",
schema: [
{
enum: [ "prefer-single", "prefer-double" ]
}
]
},
create: function(context) {
var quoteOption = context.options[0] || "prefer-double", var quoteOption = context.options[0] || "prefer-double",
setting = QUOTE_SETTINGS[quoteOption]; setting = QUOTE_SETTINGS[quoteOption];
@ -52,7 +68,7 @@ module.exports = function(context) {
} }
return { return {
"JSXAttribute": function(node) { JSXAttribute: function(node) {
var attributeValue = node.value; var attributeValue = node.value;
if (attributeValue && astUtils.isStringLiteral(attributeValue) && !usesExpectedQuotes(attributeValue)) { if (attributeValue && astUtils.isStringLiteral(attributeValue) && !usesExpectedQuotes(attributeValue)) {
@ -66,10 +82,5 @@ module.exports = function(context) {
} }
} }
}; };
};
module.exports.schema = [
{
"enum": [ "prefer-single", "prefer-double" ]
} }
]; };

146
tools/eslint/lib/rules/key-spacing.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview Rule to specify spacing of object literal keys and values * @fileoverview Rule to specify spacing of object literal keys and values
* @author Brandon Mills * @author Brandon Mills
* @copyright 2014 Brandon Mills. All rights reserved.
*/ */
"use strict"; "use strict";
@ -111,7 +110,78 @@ var messages = {
value: "{{error}} space before value for {{computed}}key '{{key}}'." value: "{{error}} space before value for {{computed}}key '{{key}}'."
}; };
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce consistent spacing between keys and values in object literal properties",
category: "Stylistic Issues",
recommended: false
},
schema: [{
anyOf: [
{
type: "object",
properties: {
align: {
enum: ["colon", "value"]
},
mode: {
enum: ["strict", "minimum"]
},
beforeColon: {
type: "boolean"
},
afterColon: {
type: "boolean"
}
},
additionalProperties: false
},
{
type: "object",
properties: {
singleLine: {
type: "object",
properties: {
mode: {
enum: ["strict", "minimum"]
},
beforeColon: {
type: "boolean"
},
afterColon: {
type: "boolean"
}
},
additionalProperties: false
},
multiLine: {
type: "object",
properties: {
align: {
enum: ["colon", "value"]
},
mode: {
enum: ["strict", "minimum"]
},
beforeColon: {
type: "boolean"
},
afterColon: {
type: "boolean"
}
},
additionalProperties: false
}
},
additionalProperties: false
}
]
}]
},
create: function(context) {
/** /**
* OPTIONS * OPTIONS
@ -133,10 +203,9 @@ module.exports = function(context) {
*/ */
function isKeyValueProperty(property) { function isKeyValueProperty(property) {
return !( return !(
property.method || (property.method ||
property.shorthand || property.shorthand ||
property.kind !== "init" || property.kind !== "init" || property.type !== "Property") // Could be "ExperimentalSpreadProperty" or "SpreadProperty"
property.type !== "Property" // Could be "ExperimentalSpreadProperty" or "SpreadProperty"
); );
} }
@ -358,7 +427,7 @@ module.exports = function(context) {
if (multiLineOptions.align) { // Verify vertical alignment if (multiLineOptions.align) { // Verify vertical alignment
return { return {
"ObjectExpression": function(node) { ObjectExpression: function(node) {
if (isSingleLine(node)) { if (isSingleLine(node)) {
verifyListSpacing(node.properties.filter(isKeyValueProperty)); verifyListSpacing(node.properties.filter(isKeyValueProperty));
} else { } else {
@ -370,73 +439,12 @@ module.exports = function(context) {
} else { // Obey beforeColon and afterColon in each property as configured } else { // Obey beforeColon and afterColon in each property as configured
return { return {
"Property": function(node) { Property: function(node) {
verifySpacing(node, isSingleLine(node.parent) ? singleLineOptions : multiLineOptions); verifySpacing(node, isSingleLine(node.parent) ? singleLineOptions : multiLineOptions);
} }
}; };
} }
};
module.exports.schema = [{
"anyOf": [
{
"type": "object",
"properties": {
"align": {
"enum": ["colon", "value"]
},
"mode": {
"enum": ["strict", "minimum"]
},
"beforeColon": {
"type": "boolean"
},
"afterColon": {
"type": "boolean"
}
},
"additionalProperties": false
},
{
"type": "object",
"properties": {
"singleLine": {
"type": "object",
"properties": {
"mode": {
"enum": ["strict", "minimum"]
},
"beforeColon": {
"type": "boolean"
},
"afterColon": {
"type": "boolean"
} }
}, };
"additionalProperties": false
},
"multiLine": {
"type": "object",
"properties": {
"align": {
"enum": ["colon", "value"]
},
"mode": {
"enum": ["strict", "minimum"]
},
"beforeColon": {
"type": "boolean"
},
"afterColon": {
"type": "boolean"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
]
}];

68
tools/eslint/lib/rules/keyword-spacing.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Rule to enforce spacing before and after keywords. * @fileoverview Rule to enforce spacing before and after keywords.
* @author Toru Nagashima * @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";
@ -65,7 +63,44 @@ function isCloseParenOfTemplate(token) {
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce consistent spacing before and after keywords",
category: "Stylistic Issues",
recommended: false
},
fixable: "whitespace",
schema: [
{
type: "object",
properties: {
before: {type: "boolean"},
after: {type: "boolean"},
overrides: {
type: "object",
properties: KEYS.reduce(function(retv, key) {
retv[key] = {
type: "object",
properties: {
before: {type: "boolean"},
after: {type: "boolean"}
},
additionalProperties: false
};
return retv;
}, {}),
additionalProperties: false
}
},
additionalProperties: false
}
]
},
create: function(context) {
var sourceCode = context.getSourceCode(); var sourceCode = context.getSourceCode();
/** /**
@ -505,30 +540,5 @@ module.exports = function(context) {
MethodDefinition: checkSpacingForProperty, MethodDefinition: checkSpacingForProperty,
Property: checkSpacingForProperty Property: checkSpacingForProperty
}; };
};
module.exports.schema = [
{
"type": "object",
"properties": {
"before": {"type": "boolean"},
"after": {"type": "boolean"},
"overrides": {
"type": "object",
"properties": KEYS.reduce(function(retv, key) {
retv[key] = {
"type": "object",
"properties": {
"before": {"type": "boolean"},
"after": {"type": "boolean"}
},
"additionalProperties": false
};
return retv;
}, {}),
"additionalProperties": false
} }
}, };
"additionalProperties": false
}
];

31
tools/eslint/lib/rules/linebreak-style.js

@ -1,9 +1,6 @@
/** /**
* @fileoverview Rule to enforce a single linebreak style. * @fileoverview Rule to enforce a single linebreak style.
* @author Erik Mueller * @author Erik Mueller
* @copyright 2015 Varun Verma. All rights reserverd.
* @copyright 2015 James Whitney. All rights reserved.
* @copyright 2015 Erik Mueller. All rights reserved.
*/ */
"use strict"; "use strict";
@ -12,7 +9,24 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce consistent linebreak style",
category: "Stylistic Issues",
recommended: false
},
fixable: "whitespace",
schema: [
{
enum: ["unix", "windows"]
}
]
},
create: function(context) {
var EXPECTED_LF_MSG = "Expected linebreaks to be 'LF' but found 'CRLF'.", var EXPECTED_LF_MSG = "Expected linebreaks to be 'LF' but found 'CRLF'.",
EXPECTED_CRLF_MSG = "Expected linebreaks to be 'CRLF' but found 'LF'."; EXPECTED_CRLF_MSG = "Expected linebreaks to be 'CRLF' but found 'LF'.";
@ -39,7 +53,7 @@ module.exports = function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
return { return {
"Program": function checkForlinebreakStyle(node) { Program: function checkForlinebreakStyle(node) {
var linebreakStyle = context.options[0] || "unix", var linebreakStyle = context.options[0] || "unix",
expectedLF = linebreakStyle === "unix", expectedLF = linebreakStyle === "unix",
expectedLFChars = expectedLF ? "\n" : "\r\n", expectedLFChars = expectedLF ? "\n" : "\r\n",
@ -71,10 +85,5 @@ module.exports = function(context) {
} }
} }
}; };
};
module.exports.schema = [
{
"enum": ["unix", "windows"]
} }
]; };

97
tools/eslint/lib/rules/lines-around-comment.js

@ -1,9 +1,6 @@
/** /**
* @fileoverview Enforces empty lines around comments. * @fileoverview Enforces empty lines around comments.
* @author Jamund Ferguson * @author Jamund Ferguson
* @copyright 2015 Mathieu M-Gosselin. All rights reserved.
* @copyright 2015 Jamund Ferguson. All rights reserved.
* @copyright 2015 Gyandeep Singh. All rights reserved.
*/ */
"use strict"; "use strict";
@ -68,7 +65,55 @@ function contains(val, array) {
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require empty lines around comments",
category: "Stylistic Issues",
recommended: false
},
schema: [
{
type: "object",
properties: {
beforeBlockComment: {
type: "boolean"
},
afterBlockComment: {
type: "boolean"
},
beforeLineComment: {
type: "boolean"
},
afterLineComment: {
type: "boolean"
},
allowBlockStart: {
type: "boolean"
},
allowBlockEnd: {
type: "boolean"
},
allowObjectStart: {
type: "boolean"
},
allowObjectEnd: {
type: "boolean"
},
allowArrayStart: {
type: "boolean"
},
allowArrayEnd: {
type: "boolean"
}
},
additionalProperties: false
}
]
},
create: function(context) {
var options = context.options[0] ? lodash.assign({}, context.options[0]) : {}; var options = context.options[0] ? lodash.assign({}, context.options[0]) : {};
@ -278,7 +323,7 @@ module.exports = function(context) {
return { return {
"LineComment": function(node) { LineComment: function(node) {
if (options.beforeLineComment || options.afterLineComment) { if (options.beforeLineComment || options.afterLineComment) {
checkForEmptyLine(node, { checkForEmptyLine(node, {
after: options.afterLineComment, after: options.afterLineComment,
@ -287,7 +332,7 @@ module.exports = function(context) {
} }
}, },
"BlockComment": function(node) { BlockComment: function(node) {
if (options.beforeBlockComment || options.afterBlockComment) { if (options.beforeBlockComment || options.afterBlockComment) {
checkForEmptyLine(node, { checkForEmptyLine(node, {
after: options.afterBlockComment, after: options.afterBlockComment,
@ -297,43 +342,5 @@ module.exports = function(context) {
} }
}; };
};
module.exports.schema = [
{
"type": "object",
"properties": {
"beforeBlockComment": {
"type": "boolean"
},
"afterBlockComment": {
"type": "boolean"
},
"beforeLineComment": {
"type": "boolean"
},
"afterLineComment": {
"type": "boolean"
},
"allowBlockStart": {
"type": "boolean"
},
"allowBlockEnd": {
"type": "boolean"
},
"allowObjectStart": {
"type": "boolean"
},
"allowObjectEnd": {
"type": "boolean"
},
"allowArrayStart": {
"type": "boolean"
},
"allowArrayEnd": {
"type": "boolean"
}
},
"additionalProperties": false
} }
]; };

89
tools/eslint/lib/rules/max-depth.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview A rule to set the maximum depth block can be nested in a function. * @fileoverview A rule to set the maximum depth block can be nested in a function.
* @author Ian Christian Myers * @author Ian Christian Myers
* @copyright 2013 Ian Christian Myers. All rights reserved.
*/ */
"use strict"; "use strict";
@ -10,7 +9,41 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce a maximum depth that blocks can be nested",
category: "Stylistic Issues",
recommended: false
},
schema: [
{
oneOf: [
{
type: "integer",
minimum: 0
},
{
type: "object",
properties: {
maximum: {
type: "integer",
minimum: 0
},
max: {
type: "integer",
minimum: 0
}
},
additionalProperties: false
}
]
}
]
},
create: function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Helpers // Helpers
@ -77,24 +110,24 @@ module.exports = function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
return { return {
"Program": startFunction, Program: startFunction,
"FunctionDeclaration": startFunction, FunctionDeclaration: startFunction,
"FunctionExpression": startFunction, FunctionExpression: startFunction,
"ArrowFunctionExpression": startFunction, ArrowFunctionExpression: startFunction,
"IfStatement": function(node) { IfStatement: function(node) {
if (node.parent.type !== "IfStatement") { if (node.parent.type !== "IfStatement") {
pushBlock(node); pushBlock(node);
} }
}, },
"SwitchStatement": pushBlock, SwitchStatement: pushBlock,
"TryStatement": pushBlock, TryStatement: pushBlock,
"DoWhileStatement": pushBlock, DoWhileStatement: pushBlock,
"WhileStatement": pushBlock, WhileStatement: pushBlock,
"WithStatement": pushBlock, WithStatement: pushBlock,
"ForStatement": pushBlock, ForStatement: pushBlock,
"ForInStatement": pushBlock, ForInStatement: pushBlock,
"ForOfStatement": pushBlock, ForOfStatement: pushBlock,
"IfStatement:exit": popBlock, "IfStatement:exit": popBlock,
"SwitchStatement:exit": popBlock, "SwitchStatement:exit": popBlock,
@ -112,29 +145,5 @@ module.exports = function(context) {
"Program:exit": endFunction "Program:exit": endFunction
}; };
};
module.exports.schema = [
{
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"type": "object",
"properties": {
"maximum": {
"type": "integer",
"minimum": 0
},
"max": {
"type": "integer",
"minimum": 0
}
},
"additionalProperties": false
} }
] };
}
];

111
tools/eslint/lib/rules/max-len.js

@ -1,16 +1,75 @@
/** /**
* @fileoverview Rule to check for max length on a line. * @fileoverview Rule to check for max length on a line.
* @author Matt DuVall <http://www.mattduvall.com> * @author Matt DuVall <http://www.mattduvall.com>
* @copyright 2013 Matt DuVall. All rights reserved.
*/ */
"use strict"; "use strict";
//------------------------------------------------------------------------------
// Constants
//------------------------------------------------------------------------------
var OPTIONS_SCHEMA = {
type: "object",
properties: {
code: {
type: "integer",
minimum: 0
},
comments: {
type: "integer",
minimum: 0
},
tabWidth: {
type: "integer",
minimum: 0
},
ignorePattern: {
type: "string"
},
ignoreComments: {
type: "boolean"
},
ignoreUrls: {
type: "boolean"
},
ignoreTrailingComments: {
type: "boolean"
}
},
additionalProperties: false
};
var OPTIONS_OR_INTEGER_SCHEMA = {
anyOf: [
OPTIONS_SCHEMA,
{
type: "integer",
minimum: 0
}
]
};
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce a maximum line length",
category: "Stylistic Issues",
recommended: false
},
schema: [
OPTIONS_OR_INTEGER_SCHEMA,
OPTIONS_OR_INTEGER_SCHEMA,
OPTIONS_SCHEMA
]
},
create: function(context) {
/* /*
* Inspired by http://tools.ietf.org/html/rfc3986#appendix-B, however: * Inspired by http://tools.ietf.org/html/rfc3986#appendix-B, however:
@ -192,54 +251,8 @@ module.exports = function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
return { return {
"Program": checkProgramForMaxLength Program: checkProgramForMaxLength
}; };
};
var OPTIONS_SCHEMA = {
"type": "object",
"properties": {
"code": {
"type": "integer",
"minimum": 0
},
"comments": {
"type": "integer",
"minimum": 0
},
"tabWidth": {
"type": "integer",
"minimum": 0
},
"ignorePattern": {
"type": "string"
},
"ignoreComments": {
"type": "boolean"
},
"ignoreUrls": {
"type": "boolean"
},
"ignoreTrailingComments": {
"type": "boolean"
} }
},
"additionalProperties": false
};
var OPTIONS_OR_INTEGER_SCHEMA = {
"anyOf": [
OPTIONS_SCHEMA,
{
"type": "integer",
"minimum": 0
}
]
}; };
module.exports.schema = [
OPTIONS_OR_INTEGER_SCHEMA,
OPTIONS_OR_INTEGER_SCHEMA,
OPTIONS_SCHEMA
];

67
tools/eslint/lib/rules/max-nested-callbacks.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview Rule to enforce a maximum number of nested callbacks. * @fileoverview Rule to enforce a maximum number of nested callbacks.
* @author Ian Christian Myers * @author Ian Christian Myers
* @copyright 2013 Ian Christian Myers. All rights reserved.
*/ */
"use strict"; "use strict";
@ -10,7 +9,41 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce a maximum depth that callbacks can be nested",
category: "Stylistic Issues",
recommended: false
},
schema: [
{
oneOf: [
{
type: "integer",
minimum: 0
},
{
type: "object",
properties: {
maximum: {
type: "integer",
minimum: 0
},
max: {
type: "integer",
minimum: 0
}
},
additionalProperties: false
}
]
}
]
},
create: function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Constants // Constants
@ -68,36 +101,12 @@ module.exports = function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
return { return {
"ArrowFunctionExpression": checkFunction, ArrowFunctionExpression: checkFunction,
"ArrowFunctionExpression:exit": popStack, "ArrowFunctionExpression:exit": popStack,
"FunctionExpression": checkFunction, FunctionExpression: checkFunction,
"FunctionExpression:exit": popStack "FunctionExpression:exit": popStack
}; };
};
module.exports.schema = [
{
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"type": "object",
"properties": {
"maximum": {
"type": "integer",
"minimum": 0
},
"max": {
"type": "integer",
"minimum": 0
}
},
"additionalProperties": false
} }
] };
}
];

70
tools/eslint/lib/rules/max-params.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Rule to flag when a function has too many parameters * @fileoverview Rule to flag when a function has too many parameters
* @author Ilya Volodin * @author Ilya Volodin
* @copyright 2014 Nicholas C. Zakas. All rights reserved.
* @copyright 2013 Ilya Volodin. All rights reserved.
*/ */
"use strict"; "use strict";
@ -11,7 +9,41 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce a maximum number of parameters in `function` definitions",
category: "Stylistic Issues",
recommended: false
},
schema: [
{
oneOf: [
{
type: "integer",
minimum: 0
},
{
type: "object",
properties: {
maximum: {
type: "integer",
minimum: 0
},
max: {
type: "integer",
minimum: 0
}
},
additionalProperties: false
}
]
}
]
},
create: function(context) {
var option = context.options[0], var option = context.options[0],
numParams = 3; numParams = 3;
@ -42,34 +74,10 @@ module.exports = function(context) {
} }
return { return {
"FunctionDeclaration": checkFunction, FunctionDeclaration: checkFunction,
"ArrowFunctionExpression": checkFunction, ArrowFunctionExpression: checkFunction,
"FunctionExpression": checkFunction FunctionExpression: checkFunction
};
}; };
module.exports.schema = [
{
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"type": "object",
"properties": {
"maximum": {
"type": "integer",
"minimum": 0
},
"max": {
"type": "integer",
"minimum": 0
}
},
"additionalProperties": false
} }
] };
}
];

45
tools/eslint/lib/rules/max-statements-per-line.js

@ -1,9 +1,6 @@
/** /**
* @fileoverview Specify the maximum number of statements allowed per line. * @fileoverview Specify the maximum number of statements allowed per line.
* @author Kenneth Williams * @author Kenneth Williams
* @copyright 2016 Kenneth Williams. All rights reserved.
* @copyright 2016 Michael Ficarra. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";
@ -11,7 +8,28 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce a maximum number of statements allowed per line",
category: "Stylistic Issues",
recommended: false
},
schema: [
{
type: "object",
properties: {
max: {
type: "integer"
}
},
additionalProperties: false
}
]
},
create: function(context) {
var options = context.options[0] || {}, var options = context.options[0] || {},
lastStatementLine = 0, lastStatementLine = 0,
@ -86,21 +104,10 @@ module.exports = function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
return { return {
"Program": checkLinesInBody, Program: checkLinesInBody,
"BlockStatement": checkLinesInBody, BlockStatement: checkLinesInBody,
"SwitchCase": checkLinesInConsequent SwitchCase: checkLinesInConsequent
};
}; };
module.exports.schema = [
{
"type": "object",
"properties": {
"max": {
"type": "integer"
} }
}, };
"additionalProperties": false
}
];

89
tools/eslint/lib/rules/max-statements.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview A rule to set the maximum number of statements in a function. * @fileoverview A rule to set the maximum number of statements in a function.
* @author Ian Christian Myers * @author Ian Christian Myers
* @copyright 2013 Ian Christian Myers. All rights reserved.
*/ */
"use strict"; "use strict";
@ -10,7 +9,50 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "enforce a maximum number of statements allowed in `function` blocks",
category: "Stylistic Issues",
recommended: false
},
schema: [
{
oneOf: [
{
type: "integer",
minimum: 0
},
{
type: "object",
properties: {
maximum: {
type: "integer",
minimum: 0
},
max: {
type: "integer",
minimum: 0
}
},
additionalProperties: false
}
]
},
{
type: "object",
properties: {
ignoreTopLevelFunctions: {
type: "boolean"
}
},
additionalProperties: false
}
]
},
create: function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Helpers // Helpers
@ -89,11 +131,11 @@ module.exports = function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
return { return {
"FunctionDeclaration": startFunction, FunctionDeclaration: startFunction,
"FunctionExpression": startFunction, FunctionExpression: startFunction,
"ArrowFunctionExpression": startFunction, ArrowFunctionExpression: startFunction,
"BlockStatement": countStatements, BlockStatement: countStatements,
"FunctionDeclaration:exit": endFunction, "FunctionDeclaration:exit": endFunction,
"FunctionExpression:exit": endFunction, "FunctionExpression:exit": endFunction,
@ -113,38 +155,5 @@ module.exports = function(context) {
} }
}; };
};
module.exports.schema = [
{
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"type": "object",
"properties": {
"maximum": {
"type": "integer",
"minimum": 0
},
"max": {
"type": "integer",
"minimum": 0
} }
}, };
"additionalProperties": false
}
]
},
{
"type": "object",
"properties": {
"ignoreTopLevelFunctions": {
"type": "boolean"
}
},
"additionalProperties": false
}
];

74
tools/eslint/lib/rules/new-cap.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Rule to flag use of constructors without capital letters * @fileoverview Rule to flag use of constructors without capital letters
* @author Nicholas C. Zakas * @author Nicholas C. Zakas
* @copyright 2014 Jordan Harband. All rights reserved.
* @copyright 2013-2014 Nicholas C. Zakas. All rights reserved.
*/ */
"use strict"; "use strict";
@ -76,7 +74,46 @@ function calculateCapIsNewExceptions(config) {
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require constructor `function` names to begin with a capital letter",
category: "Stylistic Issues",
recommended: false
},
schema: [
{
type: "object",
properties: {
newIsCap: {
type: "boolean"
},
capIsNew: {
type: "boolean"
},
newIsCapExceptions: {
type: "array",
items: {
type: "string"
}
},
capIsNewExceptions: {
type: "array",
items: {
type: "string"
}
},
properties: {
type: "boolean"
}
},
additionalProperties: false
}
]
},
create: function(context) {
var config = context.options[0] ? lodash.assign({}, context.options[0]) : {}; var config = context.options[0] ? lodash.assign({}, context.options[0]) : {};
@ -216,34 +253,5 @@ module.exports = function(context) {
} }
return listeners; return listeners;
};
module.exports.schema = [
{
"type": "object",
"properties": {
"newIsCap": {
"type": "boolean"
},
"capIsNew": {
"type": "boolean"
},
"newIsCapExceptions": {
"type": "array",
"items": {
"type": "string"
}
},
"capIsNewExceptions": {
"type": "array",
"items": {
"type": "string"
} }
}, };
"properties": {
"type": "boolean"
}
},
"additionalProperties": false
}
];

18
tools/eslint/lib/rules/new-parens.js

@ -9,11 +9,22 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require parentheses when invoking a constructor with no arguments",
category: "Stylistic Issues",
recommended: false
},
schema: []
},
create: function(context) {
return { return {
"NewExpression": function(node) { NewExpression: function(node) {
var tokens = context.getTokens(node); var tokens = context.getTokens(node);
var prenticesTokens = tokens.filter(function(token) { var prenticesTokens = tokens.filter(function(token) {
return token.value === "(" || token.value === ")"; return token.value === "(" || token.value === ")";
@ -25,6 +36,5 @@ module.exports = function(context) {
} }
}; };
}
}; };
module.exports.schema = [];

29
tools/eslint/lib/rules/newline-after-var.js

@ -1,9 +1,6 @@
/** /**
* @fileoverview Rule to check empty newline after "var" statement * @fileoverview Rule to check empty newline after "var" statement
* @author Gopal Venkatesan * @author Gopal Venkatesan
* @copyright 2015 Gopal Venkatesan. All rights reserved.
* @copyright 2015 Casey Visco. All rights reserved.
* @copyright 2015 Ian VanSchooten. All rights reserved.
*/ */
"use strict"; "use strict";
@ -12,7 +9,22 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require or disallow an empty line after `var` declarations",
category: "Stylistic Issues",
recommended: false
},
schema: [
{
enum: ["never", "always"]
}
]
},
create: function(context) {
var ALWAYS_MESSAGE = "Expected blank line after variable declarations.", var ALWAYS_MESSAGE = "Expected blank line after variable declarations.",
NEVER_MESSAGE = "Unexpected blank line after variable declarations."; NEVER_MESSAGE = "Unexpected blank line after variable declarations.";
@ -158,13 +170,8 @@ module.exports = function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
return { return {
"VariableDeclaration": checkForBlankLine VariableDeclaration: checkForBlankLine
}; };
};
module.exports.schema = [
{
"enum": ["never", "always"]
} }
]; };

53
tools/eslint/lib/rules/newline-before-return.js

@ -1,9 +1,6 @@
/** /**
* @fileoverview Rule to require newlines before `return` statement * @fileoverview Rule to require newlines before `return` statement
* @author Kai Cataldo * @author Kai Cataldo
* @copyright 2016 Kai Cataldo. All rights reserved.
* See LICENSE file in root directory for full license.
*/ */
"use strict"; "use strict";
@ -11,7 +8,18 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require an empty line before `return` statements",
category: "Stylistic Issues",
recommended: false
},
schema: []
},
create: function(context) {
var sourceCode = context.getSourceCode(); var sourceCode = context.getSourceCode();
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@ -62,13 +70,13 @@ module.exports = function(context) {
/** /**
* Returns the number of lines of comments that precede the node * Returns the number of lines of comments that precede the node
* @param {ASTNode} node - node to check for overlapping comments * @param {ASTNode} node - node to check for overlapping comments
* @param {token} tokenBefore - previous token to check for overlapping comments * @param {number} lineNumTokenBefore - line number of previous token, to check for overlapping comments
* @returns {number} Number of lines of comments that precede the node * @returns {number} Number of lines of comments that precede the node
* @private * @private
*/ */
function calcCommentLines(node, tokenBefore) { function calcCommentLines(node, lineNumTokenBefore) {
var comments = sourceCode.getComments(node).leading; var comments = sourceCode.getComments(node).leading,
var numLinesComments = 0; numLinesComments = 0;
if (!comments.length) { if (!comments.length) {
return numLinesComments; return numLinesComments;
@ -82,7 +90,7 @@ module.exports = function(context) {
} }
// avoid counting lines with inline comments twice // avoid counting lines with inline comments twice
if (comment.loc.start.line === tokenBefore.loc.end.line) { if (comment.loc.start.line === lineNumTokenBefore) {
numLinesComments--; numLinesComments--;
} }
@ -101,10 +109,26 @@ module.exports = function(context) {
* @private * @private
*/ */
function hasNewlineBefore(node) { function hasNewlineBefore(node) {
var tokenBefore = sourceCode.getTokenBefore(node); var tokenBefore = sourceCode.getTokenBefore(node),
var lineNumTokenBefore = tokenBefore.loc.end.line; lineNumNode = node.loc.start.line,
var lineNumNode = node.loc.start.line; lineNumTokenBefore,
var commentLines = calcCommentLines(node, tokenBefore); commentLines;
/**
* Global return (at the beginning of a script) is a special case.
* If there is no token before `return`, then we expect no line
* break before the return. Comments are allowed to occupy lines
* before the global return, just no blank lines.
* Setting lineNumTokenBefore to zero in that case results in the
* desired behavior.
*/
if (tokenBefore) {
lineNumTokenBefore = tokenBefore.loc.end.line;
} else {
lineNumTokenBefore = 0; // global return at beginning of script
}
commentLines = calcCommentLines(node, lineNumTokenBefore);
return (lineNumNode - lineNumTokenBefore - commentLines) > 1; return (lineNumNode - lineNumTokenBefore - commentLines) > 1;
} }
@ -138,6 +162,5 @@ module.exports = function(context) {
} }
} }
}; };
}
}; };
module.exports.schema = [];

38
tools/eslint/lib/rules/newline-per-chained-call.js

@ -2,8 +2,6 @@
* @fileoverview Rule to ensure newline per method call when chaining calls * @fileoverview Rule to ensure newline per method call when chaining calls
* @author Rajendra Patil * @author Rajendra Patil
* @author Burak Yigit Kaya * @author Burak Yigit Kaya
* @copyright 2016 Rajendra Patil. All rights reserved.
* @copyright 2016 Burak Yigit Kaya. All rights reserved.
*/ */
"use strict"; "use strict";
@ -12,7 +10,28 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "require a newline after each call in a method chain",
category: "Stylistic Issues",
recommended: false
},
schema: [{
type: "object",
properties: {
ignoreChainWithDepth: {
type: "integer",
minimum: 1,
maximum: 10
}
},
additionalProperties: false
}]
},
create: function(context) {
var options = context.options[0] || {}, var options = context.options[0] || {},
ignoreChainWithDepth = options.ignoreChainWithDepth || 2; ignoreChainWithDepth = options.ignoreChainWithDepth || 2;
@ -41,16 +60,5 @@ module.exports = function(context) {
} }
} }
}; };
};
module.exports.schema = [{
"type": "object",
"properties": {
"ignoreChainWithDepth": {
"type": "integer",
"minimum": 1,
"maximum": 10
} }
}, };
"additionalProperties": false
}];

22
tools/eslint/lib/rules/no-alert.js

@ -1,8 +1,6 @@
/** /**
* @fileoverview Rule to flag use of alert, confirm, prompt * @fileoverview Rule to flag use of alert, confirm, prompt
* @author Nicholas C. Zakas * @author Nicholas C. Zakas
* @copyright 2015 Mathias Schreck
* @copyright 2013 Nicholas C. Zakas
*/ */
"use strict"; "use strict";
@ -98,16 +96,27 @@ function isGlobalThisReferenceOrGlobalWindow(scope, globalScope, node) {
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "disallow the use of `alert`, `confirm`, and `prompt`",
category: "Best Practices",
recommended: false
},
schema: []
},
create: function(context) {
var globalScope; var globalScope;
return { return {
"Program": function() { Program: function() {
globalScope = context.getScope(); globalScope = context.getScope();
}, },
"CallExpression": function(node) { CallExpression: function(node) {
var callee = node.callee, var callee = node.callee,
identifierName, identifierName,
currentScope = context.getScope(); currentScope = context.getScope();
@ -131,6 +140,5 @@ module.exports = function(context) {
} }
}; };
}
}; };
module.exports.schema = [];

20
tools/eslint/lib/rules/no-array-constructor.js

@ -9,7 +9,18 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "disallow `Array` constructors",
category: "Stylistic Issues",
recommended: false
},
schema: []
},
create: function(context) {
/** /**
* Disallow construction of dense arrays using the Array constructor * Disallow construction of dense arrays using the Array constructor
@ -28,10 +39,9 @@ module.exports = function(context) {
} }
return { return {
"CallExpression": check, CallExpression: check,
"NewExpression": check NewExpression: check
}; };
}
}; };
module.exports.schema = [];

56
tools/eslint/lib/rules/no-bitwise.js

@ -18,7 +18,35 @@ var BITWISE_OPERATORS = [
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "disallow bitwise operators",
category: "Stylistic Issues",
recommended: false
},
schema: [
{
type: "object",
properties: {
allow: {
type: "array",
items: {
enum: BITWISE_OPERATORS
},
uniqueItems: true
},
int32Hint: {
type: "boolean"
}
},
additionalProperties: false
}
]
},
create: function(context) {
var options = context.options[0] || {}; var options = context.options[0] || {};
var allowed = options.allow || []; var allowed = options.allow || [];
var int32Hint = options.int32Hint === true; var int32Hint = options.int32Hint === true;
@ -72,28 +100,10 @@ module.exports = function(context) {
} }
return { return {
"AssignmentExpression": checkNodeForBitwiseOperator, AssignmentExpression: checkNodeForBitwiseOperator,
"BinaryExpression": checkNodeForBitwiseOperator, BinaryExpression: checkNodeForBitwiseOperator,
"UnaryExpression": checkNodeForBitwiseOperator UnaryExpression: checkNodeForBitwiseOperator
}; };
};
module.exports.schema = [
{
"type": "object",
"properties": {
"allow": {
"type": "array",
"items": {
"enum": BITWISE_OPERATORS
},
"uniqueItems": true
},
"int32Hint": {
"type": "boolean"
} }
}, };
"additionalProperties": false
}
];

18
tools/eslint/lib/rules/no-caller.js

@ -9,11 +9,22 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "disallow the use of `arguments.caller` or `arguments.callee`",
category: "Best Practices",
recommended: false
},
schema: []
},
create: function(context) {
return { return {
"MemberExpression": function(node) { MemberExpression: function(node) {
var objectName = node.object.name, var objectName = node.object.name,
propertyName = node.property.name; propertyName = node.property.name;
@ -24,6 +35,5 @@ module.exports = function(context) {
} }
}; };
}
}; };
module.exports.schema = [];

19
tools/eslint/lib/rules/no-case-declarations.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview Rule to flag use of an lexical declarations inside a case clause * @fileoverview Rule to flag use of an lexical declarations inside a case clause
* @author Erik Arvidsson * @author Erik Arvidsson
* @copyright 2015 Erik Arvidsson. All rights reserved.
*/ */
"use strict"; "use strict";
@ -9,7 +8,18 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "disallow lexical declarations in case clauses",
category: "Best Practices",
recommended: true
},
schema: []
},
create: function(context) {
/** /**
* Checks whether or not a node is a lexical declaration. * Checks whether or not a node is a lexical declaration.
@ -29,7 +39,7 @@ module.exports = function(context) {
} }
return { return {
"SwitchCase": function(node) { SwitchCase: function(node) {
for (var i = 0; i < node.consequent.length; i++) { for (var i = 0; i < node.consequent.length; i++) {
var statement = node.consequent[i]; var statement = node.consequent[i];
@ -43,6 +53,5 @@ module.exports = function(context) {
} }
}; };
}
}; };
module.exports.schema = [];

18
tools/eslint/lib/rules/no-catch-shadow.js

@ -15,7 +15,18 @@ var astUtils = require("../ast-utils");
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "disallow `catch` clause parameters from shadowing variables in the outer scope",
category: "Variables",
recommended: false
},
schema: []
},
create: function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Helpers // Helpers
@ -37,7 +48,7 @@ module.exports = function(context) {
return { return {
"CatchClause": function(node) { CatchClause: function(node) {
var scope = context.getScope(); var scope = context.getScope();
// When blockBindings is enabled, CatchClause creates its own scope // When blockBindings is enabled, CatchClause creates its own scope
@ -53,6 +64,5 @@ module.exports = function(context) {
} }
}; };
}
}; };
module.exports.schema = [];

21
tools/eslint/lib/rules/no-class-assign.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview A rule to disallow modifying variables of class declarations * @fileoverview A rule to disallow modifying variables of class declarations
* @author Toru Nagashima * @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
*/ */
"use strict"; "use strict";
@ -12,7 +11,18 @@ var astUtils = require("../ast-utils");
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "disallow reassigning class members",
category: "ECMAScript 6",
recommended: true
},
schema: []
},
create: function(context) {
/** /**
* Finds and reports references that are non initializer and writable. * Finds and reports references that are non initializer and writable.
@ -39,10 +49,9 @@ module.exports = function(context) {
} }
return { return {
"ClassDeclaration": checkForClass, ClassDeclaration: checkForClass,
"ClassExpression": checkForClass ClassExpression: checkForClass
}; };
}
}; };
module.exports.schema = [];

42
tools/eslint/lib/rules/no-cond-assign.js

@ -5,17 +5,32 @@
"use strict"; "use strict";
var NODE_DESCRIPTIONS = { var NODE_DESCRIPTIONS = {
"DoWhileStatement": "a 'do...while' statement", DoWhileStatement: "a 'do...while' statement",
"ForStatement": "a 'for' statement", ForStatement: "a 'for' statement",
"IfStatement": "an 'if' statement", IfStatement: "an 'if' statement",
"WhileStatement": "a 'while' statement" WhileStatement: "a 'while' statement"
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "disallow assignment operators in conditional expressions",
category: "Possible Errors",
recommended: true
},
schema: [
{
enum: ["except-parens", "always"]
}
]
},
create: function(context) {
var prohibitAssign = (context.options[0] || "except-parens"); var prohibitAssign = (context.options[0] || "except-parens");
@ -114,21 +129,16 @@ module.exports = function(context) {
if (prohibitAssign === "always") { if (prohibitAssign === "always") {
return { return {
"AssignmentExpression": testForConditionalAncestor AssignmentExpression: testForConditionalAncestor
}; };
} }
return { return {
"DoWhileStatement": testForAssign, DoWhileStatement: testForAssign,
"ForStatement": testForAssign, ForStatement: testForAssign,
"IfStatement": testForAssign, IfStatement: testForAssign,
"WhileStatement": testForAssign WhileStatement: testForAssign
}; };
};
module.exports.schema = [
{
"enum": ["except-parens", "always"]
} }
]; };

52
tools/eslint/lib/rules/no-confusing-arrow.js

@ -2,28 +2,6 @@
* @fileoverview A rule to warn against using arrow functions when they could be * @fileoverview A rule to warn against using arrow functions when they could be
* confused with comparisions * confused with comparisions
* @author Jxck <https://github.com/Jxck> * @author Jxck <https://github.com/Jxck>
* @copyright 2015 Luke Karrys. All rights reserved.
* The MIT License (MIT)
* Copyright (c) 2015 Jxck
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
"use strict"; "use strict";
@ -47,7 +25,24 @@ function isConditional(node) {
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "disallow arrow functions where they could be confused with comparisons",
category: "ECMAScript 6",
recommended: false
},
schema: [{
type: "object",
properties: {
allowParens: {type: "boolean"}
},
additionalProperties: false
}]
},
create: function(context) {
var config = context.options[0] || {}; var config = context.options[0] || {};
/** /**
@ -64,14 +59,7 @@ module.exports = function(context) {
} }
return { return {
"ArrowFunctionExpression": checkArrowFunc ArrowFunctionExpression: checkArrowFunc
}; };
}
}; };
module.exports.schema = [{
type: "object",
properties: {
allowParens: {type: "boolean"}
},
additionalProperties: false
}];

49
tools/eslint/lib/rules/no-console.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview Rule to flag use of console object * @fileoverview Rule to flag use of console object
* @author Nicholas C. Zakas * @author Nicholas C. Zakas
* @copyright 2016 Eric Correia. All rights reserved.
*/ */
"use strict"; "use strict";
@ -10,11 +9,37 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "disallow the use of `console`",
category: "Possible Errors",
recommended: true
},
schema: [
{
type: "object",
properties: {
allow: {
type: "array",
items: {
type: "string"
},
minItems: 1,
uniqueItems: true
}
},
additionalProperties: false
}
]
},
create: function(context) {
return { return {
"MemberExpression": function(node) { MemberExpression: function(node) {
if (node.object.name === "console") { if (node.object.name === "console") {
var blockConsole = true; var blockConsole = true;
@ -36,21 +61,5 @@ module.exports = function(context) {
} }
}; };
};
module.exports.schema = [
{
"type": "object",
"properties": {
"allow": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}
},
"additionalProperties": false
} }
]; };

19
tools/eslint/lib/rules/no-const-assign.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview A rule to disallow modifying variables that are declared using `const` * @fileoverview A rule to disallow modifying variables that are declared using `const`
* @author Toru Nagashima * @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
*/ */
"use strict"; "use strict";
@ -12,7 +11,18 @@ var astUtils = require("../ast-utils");
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "disallow reassigning `const` variables",
category: "ECMAScript 6",
recommended: true
},
schema: []
},
create: function(context) {
/** /**
* Finds and reports references that are non initializer and writable. * Finds and reports references that are non initializer and writable.
@ -29,13 +39,12 @@ module.exports = function(context) {
} }
return { return {
"VariableDeclaration": function(node) { VariableDeclaration: function(node) {
if (node.kind === "const") { if (node.kind === "const") {
context.getDeclaredVariables(node).forEach(checkVariable); context.getDeclaredVariables(node).forEach(checkVariable);
} }
} }
}; };
}
}; };
module.exports.schema = [];

70
tools/eslint/lib/rules/no-constant-condition.js

@ -1,7 +1,6 @@
/** /**
* @fileoverview Rule to flag use constant conditions * @fileoverview Rule to flag use constant conditions
* @author Christian Schulz <http://rndm.de> * @author Christian Schulz <http://rndm.de>
* @copyright 2014 Christian Schulz. All rights reserved.
*/ */
"use strict"; "use strict";
@ -10,19 +9,53 @@
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = function(context) { module.exports = {
meta: {
docs: {
description: "disallow constant expressions in conditions",
category: "Possible Errors",
recommended: true
},
schema: []
},
create: function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Helpers // Helpers
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
/**
* Checks if a branch node of LogicalExpression short circuits the whole condition
* @param {ASTNode} node The branch of main condition which needs to be checked
* @param {string} operator The operator of the main LogicalExpression.
* @returns {boolean} true when condition short circuits whole condition
*/
function isLogicalIdentity(node, operator) {
switch (node.type) {
case "Literal":
return (operator === "||" && node.value === true) ||
(operator === "&&" && node.value === false);
case "LogicalExpression":
return isLogicalIdentity(node.left, node.operator) ||
isLogicalIdentity(node.right, node.operator);
// no default
}
return false;
}
/** /**
* Checks if a node has a constant truthiness value. * Checks if a node has a constant truthiness value.
* @param {ASTNode} node The AST node to check. * @param {ASTNode} node The AST node to check.
* @param {boolean} inBooleanPosition `false` if checking branch of a condition.
* `true` in all other cases
* @returns {Bool} true when node's truthiness is constant * @returns {Bool} true when node's truthiness is constant
* @private * @private
*/ */
function isConstant(node) { function isConstant(node, inBooleanPosition) {
switch (node.type) { switch (node.type) {
case "Literal": case "Literal":
case "ArrowFunctionExpression": case "ArrowFunctionExpression":
@ -32,17 +65,25 @@ module.exports = function(context) {
return true; return true;
case "UnaryExpression": case "UnaryExpression":
return isConstant(node.argument); return (node.operator === "typeof" && inBooleanPosition) ||
isConstant(node.argument, true);
case "BinaryExpression": case "BinaryExpression":
return isConstant(node.left, false) &&
isConstant(node.right, false) &&
node.operator !== "in";
case "LogicalExpression": case "LogicalExpression":
return isConstant(node.left) && isConstant(node.right) && node.operator !== "in"; var isLeftConstant = isConstant(node.left, inBooleanPosition);
var isRightConstant = isConstant(node.right, inBooleanPosition);
var isLeftShortCircuit = (isLeftConstant && isLogicalIdentity(node.left, node.operator));
var isRightShortCircuit = (isRightConstant && isLogicalIdentity(node.right, node.operator));
return (isLeftConstant && isRightConstant) || isLeftShortCircuit || isRightShortCircuit;
case "AssignmentExpression": case "AssignmentExpression":
return (node.operator === "=") && isConstant(node.right); return (node.operator === "=") && isConstant(node.right, inBooleanPosition);
case "SequenceExpression": case "SequenceExpression":
return isConstant(node.expressions[node.expressions.length - 1]); return isConstant(node.expressions[node.expressions.length - 1], inBooleanPosition);
// no default // no default
} }
@ -56,7 +97,7 @@ module.exports = function(context) {
* @private * @private
*/ */
function checkConstantCondition(node) { function checkConstantCondition(node) {
if (node.test && isConstant(node.test)) { if (node.test && isConstant(node.test, true)) {
context.report(node, "Unexpected constant condition."); context.report(node, "Unexpected constant condition.");
} }
} }
@ -66,13 +107,12 @@ module.exports = function(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
return { return {
"ConditionalExpression": checkConstantCondition, ConditionalExpression: checkConstantCondition,
"IfStatement": checkConstantCondition, IfStatement: checkConstantCondition,
"WhileStatement": checkConstantCondition, WhileStatement: checkConstantCondition,
"DoWhileStatement": checkConstantCondition, DoWhileStatement: checkConstantCondition,
"ForStatement": checkConstantCondition ForStatement: checkConstantCondition
}; };
}
}; };
module.exports.schema = [];

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save