eslint 4.7.2 → 4.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +123 -0
- package/README.md +34 -19
- package/conf/default-cli-options.js +7 -4
- package/conf/eslint-recommended.js +2 -0
- package/lib/ast-utils.js +83 -42
- package/lib/cli-engine.js +53 -17
- package/lib/cli.js +17 -9
- package/lib/code-path-analysis/code-path-analyzer.js +8 -4
- package/lib/code-path-analysis/code-path-segment.js +43 -41
- package/lib/code-path-analysis/code-path-state.js +7 -2
- package/lib/config/autoconfig.js +14 -12
- package/lib/config/config-file.js +8 -51
- package/lib/config/config-initializer.js +10 -6
- package/lib/config/config-ops.js +21 -21
- package/lib/config/config-rule.js +24 -24
- package/lib/config/config-validator.js +38 -36
- package/lib/config/plugins.js +8 -35
- package/lib/config.js +12 -8
- package/lib/formatters/html-template-message.html +1 -1
- package/lib/formatters/html-template-page.html +3 -1
- package/lib/formatters/html.js +2 -1
- package/lib/formatters/junit.js +21 -15
- package/lib/formatters/tap.js +5 -3
- package/lib/ignored-paths.js +5 -3
- package/lib/linter.js +42 -42
- package/lib/logging.js +2 -2
- package/lib/options.js +12 -0
- package/lib/rules/.eslintrc.yml +2 -2
- package/lib/rules/array-bracket-newline.js +39 -25
- package/lib/rules/array-bracket-spacing.js +28 -28
- package/lib/rules/array-callback-return.js +13 -9
- package/lib/rules/array-element-newline.js +8 -8
- package/lib/rules/arrow-body-style.js +12 -6
- package/lib/rules/arrow-parens.js +4 -2
- package/lib/rules/block-spacing.js +1 -1
- package/lib/rules/brace-style.js +14 -14
- package/lib/rules/callback-return.js +2 -1
- package/lib/rules/capitalized-comments.js +2 -1
- package/lib/rules/comma-style.js +3 -1
- package/lib/rules/computed-property-spacing.js +22 -22
- package/lib/rules/consistent-return.js +4 -4
- package/lib/rules/consistent-this.js +4 -2
- package/lib/rules/curly.js +13 -9
- package/lib/rules/dot-notation.js +56 -35
- package/lib/rules/func-call-spacing.js +4 -2
- package/lib/rules/generator-star-spacing.js +3 -3
- package/lib/rules/getter-return.js +2 -1
- package/lib/rules/indent-legacy.js +25 -14
- package/lib/rules/indent.js +101 -91
- package/lib/rules/key-spacing.js +5 -3
- package/lib/rules/lines-around-comment.js +33 -4
- package/lib/rules/lines-around-directive.js +16 -12
- package/lib/rules/lines-between-class-members.js +91 -0
- package/lib/rules/max-len.js +2 -3
- package/lib/rules/max-statements-per-line.js +5 -3
- package/lib/rules/multiline-comment-style.js +294 -0
- package/lib/rules/new-cap.js +2 -1
- package/lib/rules/newline-after-var.js +8 -6
- package/lib/rules/newline-before-return.js +13 -9
- package/lib/rules/no-alert.js +7 -15
- package/lib/rules/no-await-in-loop.js +17 -9
- package/lib/rules/no-bitwise.js +5 -3
- package/lib/rules/no-catch-shadow.js +4 -2
- package/lib/rules/no-console.js +2 -1
- package/lib/rules/no-constant-condition.js +2 -2
- package/lib/rules/no-control-regex.js +2 -1
- package/lib/rules/no-else-return.js +60 -19
- package/lib/rules/no-empty-character-class.js +11 -11
- package/lib/rules/no-extra-parens.js +22 -11
- package/lib/rules/no-extra-semi.js +5 -3
- package/lib/rules/no-global-assign.js +4 -2
- package/lib/rules/no-implicit-coercion.js +6 -6
- package/lib/rules/no-implied-eval.js +2 -1
- package/lib/rules/no-label-var.js +4 -2
- package/lib/rules/no-lone-blocks.js +3 -3
- package/lib/rules/no-lonely-if.js +2 -1
- package/lib/rules/no-loop-func.js +10 -7
- package/lib/rules/no-mixed-requires.js +8 -4
- package/lib/rules/no-native-reassign.js +4 -2
- package/lib/rules/no-param-reassign.js +4 -2
- package/lib/rules/no-regex-spaces.js +1 -1
- package/lib/rules/no-restricted-imports.js +86 -17
- package/lib/rules/no-restricted-modules.js +84 -15
- package/lib/rules/no-restricted-properties.js +10 -10
- package/lib/rules/no-return-await.js +6 -6
- package/lib/rules/no-self-assign.js +4 -2
- package/lib/rules/no-sequences.js +6 -4
- package/lib/rules/no-trailing-spaces.js +14 -8
- package/lib/rules/no-unneeded-ternary.js +3 -1
- package/lib/rules/no-unreachable.js +4 -2
- package/lib/rules/no-unused-labels.js +2 -1
- package/lib/rules/no-use-before-define.js +13 -11
- package/lib/rules/no-useless-call.js +1 -25
- package/lib/rules/no-useless-computed-key.js +2 -1
- package/lib/rules/no-useless-escape.js +31 -23
- package/lib/rules/no-useless-return.js +14 -8
- package/lib/rules/no-var.js +11 -0
- package/lib/rules/no-whitespace-before-property.js +4 -2
- package/lib/rules/object-curly-newline.js +9 -2
- package/lib/rules/object-curly-spacing.js +20 -20
- package/lib/rules/object-shorthand.js +47 -35
- package/lib/rules/operator-assignment.js +9 -9
- package/lib/rules/operator-linebreak.js +15 -11
- package/lib/rules/padding-line-between-statements.js +6 -4
- package/lib/rules/prefer-arrow-callback.js +12 -10
- package/lib/rules/prefer-const.js +18 -10
- package/lib/rules/prefer-destructuring.js +4 -2
- package/lib/rules/prefer-numeric-literals.js +4 -2
- package/lib/rules/prefer-promise-reject-errors.js +16 -16
- package/lib/rules/prefer-rest-params.js +4 -2
- package/lib/rules/prefer-spread.js +1 -25
- package/lib/rules/prefer-template.js +33 -29
- package/lib/rules/quote-props.js +8 -8
- package/lib/rules/require-jsdoc.js +11 -18
- package/lib/rules/semi-style.js +44 -19
- package/lib/rules/semi.js +5 -3
- package/lib/rules/sort-imports.js +11 -6
- package/lib/rules/space-unary-ops.js +67 -69
- package/lib/rules/strict.js +8 -8
- package/lib/rules/valid-jsdoc.js +39 -33
- package/lib/rules/valid-typeof.js +4 -4
- package/lib/rules/wrap-iife.js +4 -4
- package/lib/rules/yoda.js +9 -7
- package/lib/testers/rule-tester.js +63 -40
- package/lib/token-store/backward-token-cursor.js +5 -3
- package/lib/token-store/forward-token-cursor.js +5 -3
- package/lib/token-store/utils.js +8 -4
- package/lib/util/apply-disable-directives.js +56 -27
- package/lib/util/glob.js +1 -1
- package/lib/util/naming.js +112 -0
- package/lib/util/node-event-generator.js +13 -27
- package/lib/util/safe-emitter.js +54 -0
- package/lib/util/source-code-fixer.js +4 -2
- package/lib/util/source-code.js +70 -65
- package/messages/no-config-found.txt +1 -1
- package/package.json +8 -8
- package/lib/internal-rules/.eslintrc.yml +0 -3
- package/lib/internal-rules/internal-consistent-docs-description.js +0 -130
- package/lib/internal-rules/internal-no-invalid-meta.js +0 -188
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,126 @@
|
|
1
|
+
v4.11.0 - November 10, 2017
|
2
|
+
|
3
|
+
* d4557a6 Docs: disallow use of the comma operator using no-restricted-syntax (#9585) (薛定谔的猫)
|
4
|
+
* d602f9e Upgrade: espree v3.5.2 (#9611) (Kai Cataldo)
|
5
|
+
* 4def876 Chore: avoid handling rules instances in config-validator (#9364) (Teddy Katz)
|
6
|
+
* fe5ac7e Chore: fix incorrect comment in safe-emitter.js (#9605) (Teddy Katz)
|
7
|
+
* 6672fae Docs: Fixed a typo on lines-between-class-members doc (#9603) (Moinul Hossain)
|
8
|
+
* 980ecd3 Chore: Update copyright and license info (#9599) (薛定谔的猫)
|
9
|
+
* cc2c7c9 Build: use Node 8 in appveyor (#9595) (薛定谔的猫)
|
10
|
+
* 2542f04 Docs: Add missing options for `lines-around-comment` (#9589) (Clément Fiorio)
|
11
|
+
* b6a7490 Build: ensure fuzzer tests get run with `npm test` (#9590) (Teddy Katz)
|
12
|
+
* 1073bc5 Build: remove shelljs-nodecli (refs #9533) (#9588) (Teddy Katz)
|
13
|
+
* 7e3bf6a Fix: edge-cases of semi-style (#9560) (Toru Nagashima)
|
14
|
+
* e5a37ce Fix: object-curly-newline for flow code (#9458) (Tiddo Langerak)
|
15
|
+
* 9064b9c Chore: add equalTokens in ast-utils. (#9500) (薛定谔的猫)
|
16
|
+
* b7c5b19 Fix: Correct [object Object] output of error.data. (#9561) (Jonathan Pool)
|
17
|
+
* 51c8cf0 Docs: Disambiguate definition of Update tag (#9584) (Jonathan Pool)
|
18
|
+
* afc3c75 Docs: clarify what eslint-config-eslint is (#9582) (Teddy Katz)
|
19
|
+
* aedae9d Docs: fix spelling in valid-typeof example (#9574) (Maksim Degtyarev)
|
20
|
+
* 4c5aaf3 Docs: Fix typo in no-underscore-dangle rule (#9567) (Fabien Lucas)
|
21
|
+
* 3623600 Chore: upgrade ajv@5.3.0 (#9557) (薛定谔的猫)
|
22
|
+
* 1b606cd Chore: Remove an indirect dependency on jsonify (#9444) (Rouven Weßling)
|
23
|
+
* 4d7d7ab Update: Resolve npm installed formatters (#5900) (#9464) (Tom Erik Støwer)
|
24
|
+
* accc490 Fix: Files with no failures get "passing" testcase (#9547) (Samuel Levy)
|
25
|
+
* ab0f66d Docs: Add examples to better show rule coverage. (#9548) (Jonathan Pool)
|
26
|
+
* 88d2303 Chore: Add object-property-newline tests to increase coverage. (#9553) (Jonathan Pool)
|
27
|
+
* 7f37b1c Build: test Node 9 on Travis (#9556) (Teddy Katz)
|
28
|
+
* acccfbd Docs: Minor rephrase in `no-invalid-this`. (#9542) (Francisc)
|
29
|
+
* 8f9c0fe Docs: improve id-match usage advice (#9544) (Teddy Katz)
|
30
|
+
* a9606a3 Fix: invalid tests with super (fixes #9539) (#9545) (Teddy Katz)
|
31
|
+
* 8e1a095 Chore: enable a modified version of multiline-comment-style on codebase (#9452) (Teddy Katz)
|
32
|
+
* cb60285 Chore: remove commented test for HTML formatter (#9532) (Teddy Katz)
|
33
|
+
* 06b491e Docs: fix duplicate entries in changelog (#9530) (Teddy Katz)
|
34
|
+
* 2224733 Chore: use eslint-plugin-rulesdir instead of --rulesdir for self-linting (#9164) (Teddy Katz)
|
35
|
+
* 9cf4ebe Docs: add .md to link(for github users) (#9529) (薛定谔的猫)
|
36
|
+
|
37
|
+
v4.10.0 - October 27, 2017
|
38
|
+
|
39
|
+
* bb6e60a Fix: Improve the doc for no-restricted-modules rule (fixes #9437) (#9495) (vibss2397)
|
40
|
+
* c529de9 Docs: Amend rule document to correct and complete it (refs #6251). (#9498) (Jonathan Pool)
|
41
|
+
* f9c6673 Chore: Add tests to cover array and object values and leading commas. (#9502) (Jonathan Pool)
|
42
|
+
* 9169258 Chore: remove `npm run check-commit` script (#9513) (Teddy Katz)
|
43
|
+
* 7d390b2 Docs: Revise contributor documentation on issue labels. (#9469) (Jonathan Pool)
|
44
|
+
* d80b9d0 Fix: no-var don't fix globals (fixes #9520) (#9525) (Toru Nagashima)
|
45
|
+
* b8aa071 Fix: allow linting the empty string from stdin (fixes #9515) (#9517) (Teddy Katz)
|
46
|
+
* 350a72c Chore: regex.test => string.startsWith (#9518) (薛定谔的猫)
|
47
|
+
* de0bef4 Chore: remove obsolete eslintbot templates (#9512) (Teddy Katz)
|
48
|
+
* 720b6d5 Docs: Update ISSUE_TEMPLATE.md (#9504) (薛定谔的猫)
|
49
|
+
* 2fa64b7 Fix: should not convert non-consecutive line comments to a single blo… (#9475) (薛定谔的猫)
|
50
|
+
* 9725146 Fix: multiline-comment-style fix produces invalid code (fixes #9461). (#9463) (薛定谔的猫)
|
51
|
+
* b12cff8 Fix: Expected order of jsdoc tags (fixes #9412) (#9451) (Orlando Wenzinger)
|
52
|
+
* f054ab5 Docs: add `.md` to link (for github users) (#9501) (薛定谔的猫)
|
53
|
+
* 5ed9cfc Docs: Correct violations of “Variable Declarations” in Code Conventions (#9447) (Jonathan Pool)
|
54
|
+
* 3171097 Docs: Clears confusion on usage of global and local plugins.(#9492) (Vasili Sviridov)
|
55
|
+
* 3204773 Chore: enable max-len. (#9414) (薛定谔的猫)
|
56
|
+
* 0f71fef Docs: Unquote booleans in lines-between-class-members docs (#9497) (Brandon Mills)
|
57
|
+
* b3d7532 Docs: use consistent terminology & fix link etc. (#9490) (薛定谔的猫)
|
58
|
+
* 87db8ae Docs: Fix broken links (#9488) (gpiress)
|
59
|
+
* 51bdb2f Docs: Incorrect link to related rule (#9477) (Gavin King)
|
60
|
+
* 1a962e8 Docs: Add FAQ for when ESLint cannot find plugin (#9467) (Kevin Partington)
|
61
|
+
* 8768b2d Fix: multiline-comment-style autofixer added trailing space (#9454) (Teddy Katz)
|
62
|
+
* e830aa1 Fix: multiline-comment-style reports block comments followed by code (#9450) (Teddy Katz)
|
63
|
+
* b12e5fe Docs: Repair broken links and add migration links. (#9473) (Jonathan Pool)
|
64
|
+
* eca01ed Docs: Add missing info about special status of home-dir config files. (#9472) (Jonathan Pool)
|
65
|
+
* eb8cfb1 Fix: change err report in constant condition (fixes #9398) (#9436) (Victor Hom)
|
66
|
+
* da77eb4 Chore: Revise no-config-file test to prevent false failure. (#9443) (Jonathan Pool)
|
67
|
+
* 47e5f6f Docs: ensure "good commit message" examples actually follow guidelines (#9466) (Teddy Katz)
|
68
|
+
* ebb530d Update: Don't ignore comments (no-trailing-spaces) (#9416) (Chris van Marle)
|
69
|
+
* 5012661 Build: fix `npm run profile` script (fixes #9397) (#9455) (Teddy Katz)
|
70
|
+
* ecac0fd Docs: Remove blockBindings references (#9446) (Jan Pilzer)
|
71
|
+
* 0b89865 Chore: ensure tests for internal rules get run (#9453) (Teddy Katz)
|
72
|
+
* 052c504 Docs: suggest deleting branches after merging PRs (#9449) (Teddy Katz)
|
73
|
+
* b31e55a Chore: move internal rules out of lib/ (#9448) (Teddy Katz)
|
74
|
+
* a7521e3 Docs: improve examples for multiline-comment-style (#9440) (Teddy Katz)
|
75
|
+
|
76
|
+
v4.9.0 - October 14, 2017
|
77
|
+
|
78
|
+
* 85388fb Fix: Correct error and test messages to fit config search path (#9428) (Jonathan Pool)
|
79
|
+
* 62a323c Fix: Add class options for `lines-around-comment` (fixes #8564) (#8565) (Ed Lee)
|
80
|
+
* 8eb4aae New: multiline-comment-style rule (fixes #8320) (#9389) (薛定谔的猫)
|
81
|
+
* db41408 Chore: avoid applying eslint-env comments twice (#9278) (Teddy Katz)
|
82
|
+
* febb897 Chore: avoid loose equality assertions (#9415) (Teddy Katz)
|
83
|
+
* 2247efa Update: Add FunctionExpression to require-jsdoc (fixes #5867) (#9395) (Kai Cataldo)
|
84
|
+
* 6791d18 Docs: Corrected noun to verb. (#9438) (Jonathan Pool)
|
85
|
+
* b02fbb6 Update: custom messages for no-restricted-* (refs #8400) (Maja Wichrowska)
|
86
|
+
* 02732bd Docs: Reorganized to avoid misunderstandings. (#9434) (Jonathan Pool)
|
87
|
+
* d9466b8 Docs: Correct time forecast for tests. (#9432) (Jonathan Pool)
|
88
|
+
* f7ed84f Docs: Add instruction re home-directory config files (refs #7729) (#9426) (Jonathan Pool)
|
89
|
+
* 30d018b Chore: Add Aladdin-ADD & VictorHom to README (#9424) (Kai Cataldo)
|
90
|
+
* 2d8a303 Docs: fix examples for prefer-numeric-literals (#9155) (Lutz Lengemann)
|
91
|
+
* d7610f5 Docs: Add jquery warning to prefer-destructuring (#9409) (Thomas Grainger)
|
92
|
+
* e835dd1 Docs: clarify no-mixed-operators (fixes #8051) (Ruxandra Fediuc)
|
93
|
+
* 51360c8 Docs: update block-spacing details (fixes #8743) (#9375) (Victor Hom)
|
94
|
+
* 6767857 Update: fix ignored nodes in indent rule when using tabs (fixes #9392) (#9393) (Robin Houston)
|
95
|
+
* 37dde77 Chore: Refactor SourceCode#getJSDocComment (#9403) (Kai Cataldo)
|
96
|
+
* 9fedd51 Chore: Add missing space in blog post template (#9407) (Kevin Partington)
|
97
|
+
* 7654c99 Docs: add installing prerequisites in readme. (#9401) (薛定谔的猫)
|
98
|
+
* 786cc73 Update: Add "consistent" option to array-bracket-newline (fixes #9136) (#9206) (Ethan Rutherford)
|
99
|
+
* e171f6b Docs: add installing prerequisites. (#9394) (薛定谔的猫)
|
100
|
+
* 74dfc87 Docs: update doc for class-methods-use-this (fixes #8910) (#9374) (Victor Hom)
|
101
|
+
* b4a9dbf Docs: show console call with no-restricted-syntax (fixes #7806) (#9376) (Victor Hom)
|
102
|
+
* 8da525f Fix: recognise multiline comments as multiline arrays (fixes #9211) (#9369) (Phil Quinn)
|
103
|
+
* c581b77 Chore: Error => TypeError (#9390) (薛定谔的猫)
|
104
|
+
* ee99876 New: lines-between-class-members rule (fixes #5949) (#9141) (薛定谔的猫)
|
105
|
+
* 9d3f5ad Chore: report unused eslint-disable directives in ESLint codebase (#9371) (Teddy Katz)
|
106
|
+
* 1167638 Update: add allowElseIf option to no-else-return (fixes #9228) (#9229) (Thomas Grainger)
|
107
|
+
* 4567ab1 New: Add the fix-dry-run flag (fixes #9076) (#9073) (Rafał Ruciński)
|
108
|
+
|
109
|
+
v4.8.0 - September 29, 2017
|
110
|
+
|
111
|
+
* 3f2b908 New: add option to report unused eslint-disable directives (fixes #9249) (#9250) (Teddy Katz)
|
112
|
+
* ff2be59 Fix: dot notation rule failing to catch string template (fixes #9350) (#9357) (Phil Quinn)
|
113
|
+
* b1372da Chore: remove sourceCode property from Linter (refs #9161) (#9363) (Teddy Katz)
|
114
|
+
* cef6f8c Docs: remove line about removing rules from semver policy (#9367) (Teddy Katz)
|
115
|
+
* 06efe87 Fix: Add meta element with charset attribute. (#9365) (H1Gdev)
|
116
|
+
* 458ca67 Docs: update architecture page (fixes #9337) (#9345) (Victor Hom)
|
117
|
+
* 1c6bc67 Fix: special EventEmitter keys leak information about other rules (#9328) (Teddy Katz)
|
118
|
+
* d593e61 Docs: update eslint.org links to use https (#9358) (Teddy Katz)
|
119
|
+
* 38d0cb2 Fix: fix wrong code-path about try-for-in (fixes #8848) (#9348) (Toru Nagashima)
|
120
|
+
* 434d9e2 Fix: Invalid font-size property value issue. (#9341) (H1Gdev)
|
121
|
+
* a7668c2 Chore: Remove unnecessary slice from logging utility (#9343) (Gyandeep Singh)
|
122
|
+
* 2ff6fb6 Chore: remove unused arguments in codebase (#9340) (Teddy Katz)
|
123
|
+
|
1
124
|
v4.7.2 - September 21, 2017
|
2
125
|
|
3
126
|
* 4f87732 Fix: Revert setting node.parent early (fixes #9331) (#9336) (Teddy Katz)
|
package/README.md
CHANGED
@@ -9,11 +9,11 @@
|
|
9
9
|
|
10
10
|
# ESLint
|
11
11
|
|
12
|
-
[Website](
|
13
|
-
[Configuring](
|
14
|
-
[Rules](
|
15
|
-
[Contributing](
|
16
|
-
[Reporting Bugs](
|
12
|
+
[Website](https://eslint.org) |
|
13
|
+
[Configuring](https://eslint.org/docs/user-guide/configuring) |
|
14
|
+
[Rules](https://eslint.org/docs/rules/) |
|
15
|
+
[Contributing](https://eslint.org/docs/developer-guide/contributing) |
|
16
|
+
[Reporting Bugs](https://eslint.org/docs/developer-guide/contributing/reporting-bugs) |
|
17
17
|
[Code of Conduct](https://js.foundation/community/code-of-conduct) |
|
18
18
|
[Twitter](https://twitter.com/geteslint) |
|
19
19
|
[Mailing List](https://groups.google.com/group/eslint) |
|
@@ -27,6 +27,8 @@ ESLint is a tool for identifying and reporting on patterns found in ECMAScript/J
|
|
27
27
|
|
28
28
|
## Installation and Usage
|
29
29
|
|
30
|
+
Prerequisites: [Node.js](https://nodejs.org/en/) (>=4.x), npm version 2+.
|
31
|
+
|
30
32
|
There are two ways to install ESLint: globally and locally.
|
31
33
|
|
32
34
|
### Local Installation and Usage
|
@@ -88,17 +90,17 @@ After running `eslint --init`, you'll have a `.eslintrc` file in your directory.
|
|
88
90
|
}
|
89
91
|
```
|
90
92
|
|
91
|
-
The names `"semi"` and `"quotes"` are the names of [rules](
|
93
|
+
The names `"semi"` and `"quotes"` are the names of [rules](https://eslint.org/docs/rules) in ESLint. The first value is the error level of the rule and can be one of these values:
|
92
94
|
|
93
95
|
* `"off"` or `0` - turn the rule off
|
94
96
|
* `"warn"` or `1` - turn the rule on as a warning (doesn't affect exit code)
|
95
97
|
* `"error"` or `2` - turn the rule on as an error (exit code will be 1)
|
96
98
|
|
97
|
-
The three error levels allow you fine-grained control over how ESLint applies rules (for more configuration options and details, see the [configuration docs](
|
99
|
+
The three error levels allow you fine-grained control over how ESLint applies rules (for more configuration options and details, see the [configuration docs](https://eslint.org/docs/user-guide/configuring)).
|
98
100
|
|
99
101
|
## Sponsors
|
100
102
|
|
101
|
-
* Site search ([eslint.org](
|
103
|
+
* Site search ([eslint.org](https://eslint.org)) is sponsored by [Algolia](https://www.algolia.com)
|
102
104
|
|
103
105
|
## Team
|
104
106
|
|
@@ -132,6 +134,8 @@ These folks keep the project moving and are resources for help.
|
|
132
134
|
* Vitor Balocco ([@vitorbal](https://github.com/vitorbal))
|
133
135
|
* James Henry ([@JamesHenry](https://github.com/JamesHenry))
|
134
136
|
* Reyad Attiyat ([@soda0289](https://github.com/soda0289))
|
137
|
+
* 薛定谔的猫 ([@Aladdin-ADD](https://github.com/Aladdin-ADD))
|
138
|
+
* Victor Hom ([@VictorHom](https://github.com/VictorHom))
|
135
139
|
|
136
140
|
## Releases
|
137
141
|
|
@@ -145,10 +149,10 @@ ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/comm
|
|
145
149
|
|
146
150
|
Before filing an issue, please be sure to read the guidelines for what you're reporting:
|
147
151
|
|
148
|
-
* [Bug Report](
|
149
|
-
* [Propose a New Rule](
|
150
|
-
* [Proposing a Rule Change](
|
151
|
-
* [Request a Change](
|
152
|
+
* [Bug Report](https://eslint.org/docs/developer-guide/contributing/reporting-bugs)
|
153
|
+
* [Propose a New Rule](https://eslint.org/docs/developer-guide/contributing/new-rules)
|
154
|
+
* [Proposing a Rule Change](https://eslint.org/docs/developer-guide/contributing/rule-changes)
|
155
|
+
* [Request a Change](https://eslint.org/docs/developer-guide/contributing/changes)
|
152
156
|
|
153
157
|
## Semantic Versioning Policy
|
154
158
|
|
@@ -171,7 +175,6 @@ ESLint follows [semantic versioning](http://semver.org). However, due to the nat
|
|
171
175
|
* Major release (likely to break your lint build)
|
172
176
|
* `eslint:recommended` is updated.
|
173
177
|
* A new option to an existing rule that results in ESLint reporting more errors by default.
|
174
|
-
* An existing rule is removed.
|
175
178
|
* An existing formatter is removed.
|
176
179
|
* Part of the public API is removed or changed in an incompatible way.
|
177
180
|
|
@@ -195,32 +198,44 @@ Despite being slower, we believe that ESLint is fast enough to replace JSHint wi
|
|
195
198
|
|
196
199
|
### I heard ESLint is going to replace JSCS?
|
197
200
|
|
198
|
-
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](
|
201
|
+
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](https://eslint.org/blog/2016/04/welcoming-jscs-to-eslint) and [JSCS](https://medium.com/@markelog/jscs-end-of-the-line-bc9bf0b3fdb2#.u76sx334n) announcements.
|
199
202
|
|
200
203
|
### So, should I stop using JSCS and start using ESLint?
|
201
204
|
|
202
|
-
Maybe, depending on how much you need it. [JSCS has reached end of life](
|
205
|
+
Maybe, depending on how much you need it. [JSCS has reached end of life](https://eslint.org/blog/2016/07/jscs-end-of-life), but if it is working for you then there is no reason to move 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.
|
203
206
|
|
204
207
|
If you are having issues with JSCS, you can try to move to ESLint. We are focusing our time and energy on JSCS compatibility issues.
|
205
208
|
|
206
|
-
|
207
209
|
### Is ESLint just linting or does it also check style?
|
208
210
|
|
209
211
|
ESLint does both traditional linting (looking for problematic patterns) and style checking (enforcement of conventions). You can use it for both.
|
210
212
|
|
213
|
+
### Why can't ESLint find my plugins?
|
214
|
+
|
215
|
+
ESLint can be [globally or locally installed](#installation-and-usage). If you install ESLint globally, your plugins must also be installed globally; if you install ESLint locally, your plugins must also be installed locally.
|
216
|
+
|
217
|
+
If you are trying to run globally, make sure your plugins are installed globally (use `npm ls -g`).
|
218
|
+
|
219
|
+
If you are trying to run locally:
|
220
|
+
|
221
|
+
* Make sure your plugins (and ESLint) are both in your project's `package.json` as devDependencies (or dependencies, if your project uses ESLint at runtime).
|
222
|
+
* Make sure you have run `npm install` and all your dependencies are installed.
|
223
|
+
|
224
|
+
In all cases, make sure your plugins' peerDependencies have been installed as well. You can use `npm view eslint-plugin-myplugin peerDepencies` to see what peer dependencies `eslint-plugin-myplugin` has.
|
225
|
+
|
211
226
|
### Does ESLint support JSX?
|
212
227
|
|
213
|
-
Yes, ESLint natively supports parsing JSX syntax (this must be enabled in [configuration](
|
228
|
+
Yes, ESLint natively supports parsing JSX syntax (this must be enabled in [configuration](https://eslint.org/docs/user-guide/configuring).). Please note that supporting JSX syntax *is not* the same as supporting React. React applies specific semantics to JSX syntax that ESLint doesn't recognize. We recommend using [eslint-plugin-react](https://www.npmjs.com/package/eslint-plugin-react) if you are using React and want React semantics.
|
214
229
|
|
215
230
|
### What about ECMAScript 6 support?
|
216
231
|
|
217
|
-
ESLint has full support for ECMAScript 6. By default, this support is off. You can enable ECMAScript 6 syntax and global variables through [configuration](
|
232
|
+
ESLint has full support for ECMAScript 6. By default, this support is off. You can enable ECMAScript 6 syntax and global variables through [configuration](https://eslint.org/docs/user-guide/configuring).
|
218
233
|
|
219
234
|
### What about experimental features?
|
220
235
|
|
221
236
|
ESLint doesn't natively support experimental ECMAScript language features. You can use [babel-eslint](https://github.com/babel/babel-eslint) to use any option available in Babel.
|
222
237
|
|
223
|
-
Once a language feature has been adopted into the ECMAScript standard (stage 4 according to the [TC39 process](https://tc39.github.io/process-document/)), we will accept issues and pull requests related to the new feature, subject to our [contributing guidelines](
|
238
|
+
Once a language feature has been adopted into the ECMAScript standard (stage 4 according to the [TC39 process](https://tc39.github.io/process-document/)), we will accept issues and pull requests related to the new feature, subject to our [contributing guidelines](https://eslint.org/docs/developer-guide/contributing). Until then, please use the appropriate parser and plugin(s) for your experimental feature.
|
224
239
|
|
225
240
|
### Where to ask for help?
|
226
241
|
|
@@ -17,11 +17,14 @@ module.exports = {
|
|
17
17
|
ignorePath: null,
|
18
18
|
cache: false,
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
/*
|
21
|
+
* in order to honor the cacheFile option if specified
|
22
|
+
* this option should not have a default value otherwise
|
23
|
+
* it will always be used
|
24
|
+
*/
|
23
25
|
cacheLocation: "",
|
24
26
|
cacheFile: ".eslintcache",
|
25
27
|
fix: false,
|
26
|
-
allowInlineConfig: true
|
28
|
+
allowInlineConfig: true,
|
29
|
+
reportUnusedDisableDirectives: false
|
27
30
|
};
|
@@ -63,6 +63,7 @@ module.exports = {
|
|
63
63
|
"linebreak-style": "off",
|
64
64
|
"lines-around-comment": "off",
|
65
65
|
"lines-around-directive": "off",
|
66
|
+
"lines-between-class-members": "off",
|
66
67
|
"max-depth": "off",
|
67
68
|
"max-len": "off",
|
68
69
|
"max-lines": "off",
|
@@ -70,6 +71,7 @@ module.exports = {
|
|
70
71
|
"max-params": "off",
|
71
72
|
"max-statements": "off",
|
72
73
|
"max-statements-per-line": "off",
|
74
|
+
"multiline-comment-style": "off",
|
73
75
|
"multiline-ternary": "off",
|
74
76
|
"new-cap": "off",
|
75
77
|
"new-parens": "off",
|
package/lib/ast-utils.js
CHANGED
@@ -406,6 +406,31 @@ function createGlobalLinebreakMatcher() {
|
|
406
406
|
return new RegExp(LINEBREAK_MATCHER.source, "g");
|
407
407
|
}
|
408
408
|
|
409
|
+
/**
|
410
|
+
* Checks whether or not the tokens of two given nodes are same.
|
411
|
+
* @param {ASTNode} left - A node 1 to compare.
|
412
|
+
* @param {ASTNode} right - A node 2 to compare.
|
413
|
+
* @param {SourceCode} sourceCode - The ESLint source code object.
|
414
|
+
* @returns {boolean} the source code for the given node.
|
415
|
+
*/
|
416
|
+
function equalTokens(left, right, sourceCode) {
|
417
|
+
const tokensL = sourceCode.getTokens(left);
|
418
|
+
const tokensR = sourceCode.getTokens(right);
|
419
|
+
|
420
|
+
if (tokensL.length !== tokensR.length) {
|
421
|
+
return false;
|
422
|
+
}
|
423
|
+
for (let i = 0; i < tokensL.length; ++i) {
|
424
|
+
if (tokensL[i].type !== tokensR[i].type ||
|
425
|
+
tokensL[i].value !== tokensR[i].value
|
426
|
+
) {
|
427
|
+
return false;
|
428
|
+
}
|
429
|
+
}
|
430
|
+
|
431
|
+
return true;
|
432
|
+
}
|
433
|
+
|
409
434
|
//------------------------------------------------------------------------------
|
410
435
|
// Public Interface
|
411
436
|
//------------------------------------------------------------------------------
|
@@ -438,6 +463,7 @@ module.exports = {
|
|
438
463
|
isArrayFromMethod,
|
439
464
|
isParenthesised,
|
440
465
|
createGlobalLinebreakMatcher,
|
466
|
+
equalTokens,
|
441
467
|
|
442
468
|
isArrowToken,
|
443
469
|
isClosingBraceToken,
|
@@ -620,15 +646,17 @@ module.exports = {
|
|
620
646
|
node = parent;
|
621
647
|
break;
|
622
648
|
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
649
|
+
/*
|
650
|
+
* If the upper function is IIFE, checks the destination of the return value.
|
651
|
+
* e.g.
|
652
|
+
* obj.foo = (function() {
|
653
|
+
* // setup...
|
654
|
+
* return function foo() { ... };
|
655
|
+
* })();
|
656
|
+
* obj.foo = (() =>
|
657
|
+
* function foo() { ... }
|
658
|
+
* )();
|
659
|
+
*/
|
632
660
|
case "ReturnStatement": {
|
633
661
|
const func = getUpperFunction(parent);
|
634
662
|
|
@@ -645,23 +673,27 @@ module.exports = {
|
|
645
673
|
node = parent.parent;
|
646
674
|
break;
|
647
675
|
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
676
|
+
/*
|
677
|
+
* e.g.
|
678
|
+
* var obj = { foo() { ... } };
|
679
|
+
* var obj = { foo: function() { ... } };
|
680
|
+
* class A { constructor() { ... } }
|
681
|
+
* class A { foo() { ... } }
|
682
|
+
* class A { get foo() { ... } }
|
683
|
+
* class A { set foo() { ... } }
|
684
|
+
* class A { static foo() { ... } }
|
685
|
+
*/
|
656
686
|
case "Property":
|
657
687
|
case "MethodDefinition":
|
658
688
|
return parent.value !== node;
|
659
689
|
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
690
|
+
/*
|
691
|
+
* e.g.
|
692
|
+
* obj.foo = function foo() { ... };
|
693
|
+
* Foo = function() { ... };
|
694
|
+
* [obj.foo = function foo() { ... }] = a;
|
695
|
+
* [Foo = function() { ... }] = a;
|
696
|
+
*/
|
665
697
|
case "AssignmentExpression":
|
666
698
|
case "AssignmentPattern":
|
667
699
|
if (parent.left.type === "MemberExpression") {
|
@@ -676,8 +708,10 @@ module.exports = {
|
|
676
708
|
}
|
677
709
|
return true;
|
678
710
|
|
679
|
-
|
680
|
-
|
711
|
+
/*
|
712
|
+
* e.g.
|
713
|
+
* var Foo = function() { ... };
|
714
|
+
*/
|
681
715
|
case "VariableDeclarator":
|
682
716
|
return !(
|
683
717
|
isAnonymous &&
|
@@ -686,10 +720,12 @@ module.exports = {
|
|
686
720
|
startsWithUpperCase(parent.id.name)
|
687
721
|
);
|
688
722
|
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
723
|
+
/*
|
724
|
+
* e.g.
|
725
|
+
* var foo = function foo() { ... }.bind(obj);
|
726
|
+
* (function foo() { ... }).call(obj);
|
727
|
+
* (function foo() { ... }).apply(obj, []);
|
728
|
+
*/
|
693
729
|
case "MemberExpression":
|
694
730
|
return (
|
695
731
|
parent.object !== node ||
|
@@ -700,10 +736,12 @@ module.exports = {
|
|
700
736
|
isNullOrUndefined(parent.parent.arguments[0])
|
701
737
|
);
|
702
738
|
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
739
|
+
/*
|
740
|
+
* e.g.
|
741
|
+
* Reflect.apply(function() {}, obj, []);
|
742
|
+
* Array.from([], function() {}, obj);
|
743
|
+
* list.forEach(function() {}, obj);
|
744
|
+
*/
|
707
745
|
case "CallExpression":
|
708
746
|
if (isReflectApply(parent.callee)) {
|
709
747
|
return (
|
@@ -930,8 +968,10 @@ module.exports = {
|
|
930
968
|
node.type === "FunctionDeclaration" ||
|
931
969
|
node.type === "FunctionExpression" ||
|
932
970
|
|
933
|
-
|
934
|
-
|
971
|
+
/*
|
972
|
+
* Do not check arrow functions with implicit return.
|
973
|
+
* `() => "use strict";` returns the string `"use strict"`.
|
974
|
+
*/
|
935
975
|
(node.type === "ArrowFunctionExpression" && node.body.type === "BlockStatement")
|
936
976
|
) {
|
937
977
|
const statements = node.type === "Program" ? node.body : node.body.body;
|
@@ -954,7 +994,7 @@ module.exports = {
|
|
954
994
|
|
955
995
|
/**
|
956
996
|
* Determines whether this node is a decimal integer literal. If a node is a decimal integer literal, a dot added
|
957
|
-
after the node will be parsed as a decimal point, rather than a property-access dot.
|
997
|
+
* after the node will be parsed as a decimal point, rather than a property-access dot.
|
958
998
|
* @param {ASTNode} node - The node to check.
|
959
999
|
* @returns {boolean} `true` if this node is a decimal integer.
|
960
1000
|
* @example
|
@@ -1041,7 +1081,8 @@ module.exports = {
|
|
1041
1081
|
} else if (parent.type === "Property" || parent.type === "MethodDefinition") {
|
1042
1082
|
if (parent.kind === "constructor") {
|
1043
1083
|
return "constructor";
|
1044
|
-
}
|
1084
|
+
}
|
1085
|
+
if (parent.kind === "get") {
|
1045
1086
|
tokens.push("getter");
|
1046
1087
|
} else if (parent.kind === "set") {
|
1047
1088
|
tokens.push("setter");
|
@@ -1182,12 +1223,12 @@ module.exports = {
|
|
1182
1223
|
},
|
1183
1224
|
|
1184
1225
|
/**
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1226
|
+
* Gets the parenthesized text of a node. This is similar to sourceCode.getText(node), but it also includes any parentheses
|
1227
|
+
* surrounding the node.
|
1228
|
+
* @param {SourceCode} sourceCode The source code object
|
1229
|
+
* @param {ASTNode} node An expression node
|
1230
|
+
* @returns {string} The text representing the node, with all surrounding parentheses included
|
1231
|
+
*/
|
1191
1232
|
getParenthesisedText(sourceCode, node) {
|
1192
1233
|
let leftToken = sourceCode.getFirstToken(node);
|
1193
1234
|
let rightToken = sourceCode.getLastToken(node);
|
package/lib/cli-engine.js
CHANGED
@@ -24,12 +24,16 @@ const fs = require("fs"),
|
|
24
24
|
fileEntryCache = require("file-entry-cache"),
|
25
25
|
globUtil = require("./util/glob-util"),
|
26
26
|
validator = require("./config/config-validator"),
|
27
|
-
stringify = require("json-stable-stringify"),
|
27
|
+
stringify = require("json-stable-stringify-without-jsonify"),
|
28
28
|
hash = require("./util/hash"),
|
29
|
+
ModuleResolver = require("./util/module-resolver"),
|
30
|
+
naming = require("./util/naming"),
|
29
31
|
pkg = require("../package.json");
|
30
32
|
|
31
33
|
const debug = require("debug")("eslint:cli-engine");
|
32
34
|
|
35
|
+
const resolver = new ModuleResolver();
|
36
|
+
|
33
37
|
//------------------------------------------------------------------------------
|
34
38
|
// Typedefs
|
35
39
|
//------------------------------------------------------------------------------
|
@@ -56,6 +60,7 @@ const debug = require("debug")("eslint:cli-engine");
|
|
56
60
|
* @property {string[]} plugins An array of plugins to load.
|
57
61
|
* @property {Object<string,*>} rules An object of rules to use.
|
58
62
|
* @property {string[]} rulePaths An array of directories to load custom rules from.
|
63
|
+
* @property {boolean} reportUnusedDisableDirectives `true` adds reports for unused eslint-disable directives
|
59
64
|
*/
|
60
65
|
|
61
66
|
/**
|
@@ -137,11 +142,12 @@ function calculateStatsPerRun(results) {
|
|
137
142
|
* @param {string} filename An optional string representing the texts filename.
|
138
143
|
* @param {boolean|Function} fix Indicates if fixes should be processed.
|
139
144
|
* @param {boolean} allowInlineConfig Allow/ignore comments that change config.
|
145
|
+
* @param {boolean} reportUnusedDisableDirectives Allow/ignore comments that change config.
|
140
146
|
* @param {Linter} linter Linter context
|
141
147
|
* @returns {LintResult} The results for linting on this text.
|
142
148
|
* @private
|
143
149
|
*/
|
144
|
-
function processText(text, configHelper, filename, fix, allowInlineConfig, linter) {
|
150
|
+
function processText(text, configHelper, filename, fix, allowInlineConfig, reportUnusedDisableDirectives, linter) {
|
145
151
|
let filePath,
|
146
152
|
fileExtension,
|
147
153
|
processor;
|
@@ -173,6 +179,7 @@ function processText(text, configHelper, filename, fix, allowInlineConfig, linte
|
|
173
179
|
const fixedResult = linter.verifyAndFix(text, config, {
|
174
180
|
filename,
|
175
181
|
allowInlineConfig,
|
182
|
+
reportUnusedDisableDirectives,
|
176
183
|
fix: !!autofixingEnabled && fix,
|
177
184
|
preprocess: processor && (rawText => processor.preprocess(rawText, filename)),
|
178
185
|
postprocess: processor && (problemLists => processor.postprocess(problemLists, filename))
|
@@ -213,7 +220,15 @@ function processText(text, configHelper, filename, fix, allowInlineConfig, linte
|
|
213
220
|
function processFile(filename, configHelper, options, linter) {
|
214
221
|
|
215
222
|
const text = fs.readFileSync(path.resolve(filename), "utf8"),
|
216
|
-
result = processText(
|
223
|
+
result = processText(
|
224
|
+
text,
|
225
|
+
configHelper,
|
226
|
+
filename,
|
227
|
+
options.fix,
|
228
|
+
options.allowInlineConfig,
|
229
|
+
options.reportUnusedDisableDirectives,
|
230
|
+
linter
|
231
|
+
);
|
217
232
|
|
218
233
|
return result;
|
219
234
|
|
@@ -229,8 +244,8 @@ function processFile(filename, configHelper, options, linter) {
|
|
229
244
|
function createIgnoreResult(filePath, baseDir) {
|
230
245
|
let message;
|
231
246
|
const isHidden = /^\./.test(path.basename(filePath));
|
232
|
-
const isInNodeModules = baseDir &&
|
233
|
-
const isInBowerComponents = baseDir &&
|
247
|
+
const isInNodeModules = baseDir && path.relative(baseDir, filePath).startsWith("node_modules");
|
248
|
+
const isInBowerComponents = baseDir && path.relative(baseDir, filePath).startsWith("bower_components");
|
234
249
|
|
235
250
|
if (isHidden) {
|
236
251
|
message = "File ignored by default. Use a negated ignore pattern (like \"--ignore-pattern '!<relative/path/to/filename>'\") to override.";
|
@@ -394,9 +409,13 @@ class CLIEngine {
|
|
394
409
|
});
|
395
410
|
}
|
396
411
|
|
397
|
-
Object.keys(this.options.rules
|
398
|
-
|
399
|
-
|
412
|
+
if (this.options.rules && Object.keys(this.options.rules).length) {
|
413
|
+
const loadedRules = this.linter.getRules();
|
414
|
+
|
415
|
+
Object.keys(this.options.rules).forEach(name => {
|
416
|
+
validator.validateRuleOptions(loadedRules.get(name), name, this.options.rules[name], "CLI");
|
417
|
+
});
|
418
|
+
}
|
400
419
|
|
401
420
|
this.config = new Config(this.options, this.linter);
|
402
421
|
}
|
@@ -531,10 +550,10 @@ class CLIEngine {
|
|
531
550
|
if (result.messages.length) {
|
532
551
|
|
533
552
|
/*
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
553
|
+
* if a file contains errors or warnings we don't want to
|
554
|
+
* store the file in the cache so we can guarantee that
|
555
|
+
* next execution will also operate on this file
|
556
|
+
*/
|
538
557
|
fileCache.removeEntry(result.filePath);
|
539
558
|
} else {
|
540
559
|
|
@@ -591,7 +610,17 @@ class CLIEngine {
|
|
591
610
|
results.push(createIgnoreResult(filename, options.cwd));
|
592
611
|
}
|
593
612
|
} else {
|
594
|
-
results.push(
|
613
|
+
results.push(
|
614
|
+
processText(
|
615
|
+
text,
|
616
|
+
configHelper,
|
617
|
+
filename,
|
618
|
+
options.fix,
|
619
|
+
options.allowInlineConfig,
|
620
|
+
options.reportUnusedDisableDirectives,
|
621
|
+
this.linter
|
622
|
+
)
|
623
|
+
);
|
595
624
|
}
|
596
625
|
|
597
626
|
const stats = calculateStatsPerRun(results);
|
@@ -649,15 +678,22 @@ class CLIEngine {
|
|
649
678
|
// replace \ with / for Windows compatibility
|
650
679
|
format = format.replace(/\\/g, "/");
|
651
680
|
|
681
|
+
const cwd = this.options ? this.options.cwd : process.cwd();
|
682
|
+
const namespace = naming.getNamespaceFromTerm(format);
|
683
|
+
|
652
684
|
let formatterPath;
|
653
685
|
|
654
686
|
// if there's a slash, then it's a file
|
655
|
-
if (format.indexOf("/") > -1) {
|
656
|
-
const cwd = this.options ? this.options.cwd : process.cwd();
|
657
|
-
|
687
|
+
if (!namespace && format.indexOf("/") > -1) {
|
658
688
|
formatterPath = path.resolve(cwd, format);
|
659
689
|
} else {
|
660
|
-
|
690
|
+
try {
|
691
|
+
const npmFormat = naming.normalizePackageName(format, "eslint-formatter");
|
692
|
+
|
693
|
+
formatterPath = resolver.resolve(npmFormat, `${cwd}/node_modules`);
|
694
|
+
} catch (e) {
|
695
|
+
formatterPath = `./formatters/${format}`;
|
696
|
+
}
|
661
697
|
}
|
662
698
|
|
663
699
|
try {
|