eslint 6.0.0-alpha.1 → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +71 -0
- package/README.md +28 -21
- package/bin/eslint.js +2 -2
- package/conf/config-schema.js +38 -31
- package/conf/environments.js +1 -1
- package/conf/eslint-all.js +2 -2
- package/conf/eslint-recommended.js +1 -1
- package/lib/api.js +7 -3
- package/lib/cli-engine/cascading-config-array-factory.js +20 -8
- package/lib/{cli-engine.js → cli-engine/cli-engine.js} +44 -21
- package/lib/cli-engine/config-array/config-array.js +7 -8
- package/lib/cli-engine/config-array/config-dependency.js +2 -2
- package/lib/cli-engine/config-array/extracted-config.js +3 -3
- package/lib/cli-engine/config-array/override-tester.js +11 -1
- package/lib/cli-engine/config-array-factory.js +75 -65
- package/lib/cli-engine/file-enumerator.js +14 -6
- package/lib/{formatters → cli-engine/formatters}/checkstyle.js +1 -1
- package/lib/{formatters → cli-engine/formatters}/codeframe.js +0 -0
- package/lib/{formatters → cli-engine/formatters}/compact.js +0 -0
- package/lib/{formatters → cli-engine/formatters}/html-template-message.html +0 -0
- package/lib/{formatters → cli-engine/formatters}/html-template-page.html +0 -0
- package/lib/{formatters → cli-engine/formatters}/html-template-result.html +0 -0
- package/lib/{formatters → cli-engine/formatters}/html.js +0 -0
- package/lib/{formatters → cli-engine/formatters}/jslint-xml.js +1 -1
- package/lib/{formatters → cli-engine/formatters}/json-with-metadata.js +0 -0
- package/lib/{formatters → cli-engine/formatters}/json.js +0 -0
- package/lib/{formatters → cli-engine/formatters}/junit.js +15 -3
- package/lib/{formatters → cli-engine/formatters}/stylish.js +0 -0
- package/lib/{formatters → cli-engine/formatters}/table.js +0 -0
- package/lib/{formatters → cli-engine/formatters}/tap.js +0 -0
- package/lib/{formatters → cli-engine/formatters}/unix.js +0 -0
- package/lib/{formatters → cli-engine/formatters}/visualstudio.js +0 -0
- package/lib/{util → cli-engine}/hash.js +0 -0
- package/lib/{util → cli-engine}/ignored-paths.js +6 -1
- package/lib/cli-engine/index.js +7 -0
- package/lib/{util → cli-engine}/lint-result-cache.js +0 -0
- package/lib/{load-rules.js → cli-engine/load-rules.js} +0 -0
- package/lib/{util → cli-engine}/naming.js +0 -0
- package/lib/{util → cli-engine}/xml-escape.js +0 -0
- package/lib/cli.js +3 -3
- package/lib/{config → init}/autoconfig.js +3 -3
- package/lib/{config → init}/config-file.js +0 -0
- package/lib/{config → init}/config-initializer.js +6 -6
- package/lib/{config → init}/config-rule.js +8 -2
- package/lib/{util → init}/npm-utils.js +1 -1
- package/lib/{util → init}/source-code-utils.js +16 -1
- package/lib/{util → linter}/apply-disable-directives.js +0 -0
- package/lib/{code-path-analysis → linter/code-path-analysis}/code-path-analyzer.js +19 -6
- package/lib/{code-path-analysis → linter/code-path-analysis}/code-path-segment.js +0 -0
- package/lib/{code-path-analysis → linter/code-path-analysis}/code-path-state.js +0 -0
- package/lib/{code-path-analysis → linter/code-path-analysis}/code-path.js +0 -0
- package/lib/{code-path-analysis → linter/code-path-analysis}/debug-helpers.js +0 -0
- package/lib/{code-path-analysis → linter/code-path-analysis}/fork-context.js +0 -0
- package/lib/{code-path-analysis → linter/code-path-analysis}/id-generator.js +0 -0
- package/lib/{util → linter}/config-comment-parser.js +1 -1
- package/lib/linter/index.js +13 -0
- package/lib/{util → linter}/interpolate.js +0 -0
- package/lib/{linter.js → linter/linter.js} +298 -152
- package/lib/{util → linter}/node-event-generator.js +7 -5
- package/lib/{util → linter}/report-translator.js +0 -0
- package/lib/{util → linter}/rule-fixer.js +0 -0
- package/lib/{rules.js → linter/rules.js} +3 -29
- package/lib/{util → linter}/safe-emitter.js +0 -0
- package/lib/{util → linter}/source-code-fixer.js +0 -0
- package/lib/{util → linter}/timing.js +1 -1
- package/lib/rule-tester/index.js +5 -0
- package/lib/{testers → rule-tester}/rule-tester.js +43 -15
- package/lib/rules/array-bracket-newline.js +1 -1
- package/lib/rules/array-bracket-spacing.js +1 -1
- package/lib/rules/array-callback-return.js +1 -1
- package/lib/rules/array-element-newline.js +1 -1
- package/lib/rules/arrow-body-style.js +1 -1
- package/lib/rules/arrow-parens.js +22 -1
- package/lib/rules/arrow-spacing.js +1 -1
- package/lib/rules/block-spacing.js +1 -1
- package/lib/rules/brace-style.js +1 -1
- package/lib/rules/capitalized-comments.js +2 -2
- package/lib/rules/comma-dangle.js +1 -1
- package/lib/rules/comma-spacing.js +1 -1
- package/lib/rules/comma-style.js +1 -1
- package/lib/rules/complexity.js +3 -3
- package/lib/rules/computed-property-spacing.js +1 -1
- package/lib/rules/consistent-return.js +1 -1
- package/lib/rules/curly.js +1 -1
- package/lib/rules/dot-location.js +1 -1
- package/lib/rules/dot-notation.js +2 -2
- package/lib/rules/eqeqeq.js +1 -1
- package/lib/rules/func-call-spacing.js +1 -1
- package/lib/rules/func-name-matching.js +1 -1
- package/lib/rules/func-names.js +1 -1
- package/lib/rules/function-paren-newline.js +1 -1
- package/lib/rules/getter-return.js +1 -1
- package/lib/rules/implicit-arrow-linebreak.js +1 -1
- package/lib/rules/indent-legacy.js +1 -1
- package/lib/rules/indent.js +1 -1
- package/lib/rules/index.js +281 -0
- package/lib/rules/jsx-quotes.js +1 -1
- package/lib/rules/key-spacing.js +1 -1
- package/lib/rules/keyword-spacing.js +2 -2
- package/lib/rules/line-comment-position.js +1 -1
- package/lib/rules/linebreak-style.js +1 -1
- package/lib/rules/lines-around-comment.js +1 -1
- package/lib/rules/lines-around-directive.js +1 -1
- package/lib/rules/lines-between-class-members.js +1 -1
- package/lib/rules/max-classes-per-file.js +2 -1
- package/lib/rules/max-depth.js +2 -2
- package/lib/rules/max-len.js +11 -4
- package/lib/rules/max-lines-per-function.js +4 -2
- package/lib/rules/max-lines.js +2 -2
- package/lib/rules/max-params.js +1 -1
- package/lib/rules/max-statements-per-line.js +1 -1
- package/lib/rules/max-statements.js +1 -1
- package/lib/rules/multiline-comment-style.js +3 -2
- package/lib/rules/multiline-ternary.js +1 -1
- package/lib/rules/new-parens.js +43 -11
- package/lib/rules/newline-after-var.js +1 -1
- package/lib/rules/newline-per-chained-call.js +1 -1
- package/lib/rules/no-alert.js +1 -1
- package/lib/rules/no-catch-shadow.js +1 -1
- package/lib/rules/no-class-assign.js +1 -1
- package/lib/rules/no-cond-assign.js +1 -1
- package/lib/rules/no-confusing-arrow.js +1 -1
- package/lib/rules/no-console.js +1 -1
- package/lib/rules/no-const-assign.js +1 -1
- package/lib/rules/no-div-regex.js +9 -1
- package/lib/rules/no-dupe-keys.js +1 -1
- package/lib/rules/no-else-return.js +129 -2
- package/lib/rules/no-empty-function.js +1 -1
- package/lib/rules/no-empty.js +1 -1
- package/lib/rules/no-eval.js +1 -1
- package/lib/rules/no-ex-assign.js +1 -1
- package/lib/rules/no-extend-native.js +1 -1
- package/lib/rules/no-extra-bind.js +1 -1
- package/lib/rules/no-extra-boolean-cast.js +1 -1
- package/lib/rules/no-extra-label.js +1 -1
- package/lib/rules/no-extra-parens.js +1 -1
- package/lib/rules/no-extra-semi.js +2 -2
- package/lib/rules/no-floating-decimal.js +1 -1
- package/lib/rules/no-func-assign.js +1 -1
- package/lib/rules/no-implicit-coercion.js +1 -1
- package/lib/rules/no-inline-comments.js +1 -1
- package/lib/rules/no-invalid-this.js +1 -1
- package/lib/rules/no-irregular-whitespace.js +1 -1
- package/lib/rules/no-label-var.js +1 -1
- package/lib/rules/no-labels.js +1 -1
- package/lib/rules/no-misleading-character-class.js +1 -1
- package/lib/rules/no-mixed-operators.js +1 -1
- package/lib/rules/no-multi-spaces.js +1 -1
- package/lib/rules/no-multi-str.js +1 -1
- package/lib/rules/no-octal.js +1 -1
- package/lib/rules/no-redeclare.js +1 -1
- package/lib/rules/no-regex-spaces.js +1 -1
- package/lib/rules/no-restricted-imports.js +18 -14
- package/lib/rules/no-restricted-properties.js +1 -1
- package/lib/rules/no-return-assign.js +1 -1
- package/lib/rules/no-return-await.js +1 -1
- package/lib/rules/no-self-assign.js +1 -1
- package/lib/rules/no-sequences.js +1 -1
- package/lib/rules/no-shadow.js +1 -1
- package/lib/rules/no-this-before-super.js +1 -1
- package/lib/rules/no-throw-literal.js +1 -1
- package/lib/rules/no-trailing-spaces.js +1 -1
- package/lib/rules/no-undef-init.js +1 -1
- package/lib/rules/no-unexpected-multiline.js +1 -1
- package/lib/rules/no-unmodified-loop-condition.js +2 -2
- package/lib/rules/no-unneeded-ternary.js +1 -1
- package/lib/rules/no-unsafe-negation.js +1 -1
- package/lib/rules/no-unused-vars.js +1 -1
- package/lib/rules/no-useless-call.js +1 -1
- package/lib/rules/no-useless-computed-key.js +1 -1
- package/lib/rules/no-useless-concat.js +1 -1
- package/lib/rules/no-useless-escape.js +7 -2
- package/lib/rules/no-useless-return.js +2 -2
- package/lib/rules/no-var.js +15 -2
- package/lib/rules/no-warning-comments.js +1 -1
- package/lib/rules/no-whitespace-before-property.js +1 -1
- package/lib/rules/object-curly-newline.js +1 -1
- package/lib/rules/object-curly-spacing.js +1 -1
- package/lib/rules/object-shorthand.js +1 -1
- package/lib/rules/operator-assignment.js +1 -1
- package/lib/rules/operator-linebreak.js +1 -1
- package/lib/rules/padded-blocks.js +1 -1
- package/lib/rules/padding-line-between-statements.js +1 -1
- package/lib/rules/prefer-const.js +1 -1
- package/lib/rules/prefer-object-spread.js +1 -1
- package/lib/rules/prefer-promise-reject-errors.js +1 -1
- package/lib/rules/prefer-spread.js +1 -1
- package/lib/rules/prefer-template.js +1 -1
- package/lib/rules/quote-props.js +1 -1
- package/lib/rules/quotes.js +1 -1
- package/lib/rules/radix.js +1 -1
- package/lib/rules/require-atomic-updates.js +63 -84
- package/lib/rules/require-await.js +1 -1
- package/lib/rules/semi-spacing.js +1 -1
- package/lib/rules/semi-style.js +1 -1
- package/lib/rules/semi.js +2 -2
- package/lib/rules/sort-keys.js +12 -4
- package/lib/rules/space-before-blocks.js +1 -1
- package/lib/rules/space-before-function-paren.js +1 -1
- package/lib/rules/space-in-parens.js +1 -1
- package/lib/rules/space-unary-ops.js +1 -1
- package/lib/rules/spaced-comment.js +1 -1
- package/lib/rules/strict.js +1 -1
- package/lib/rules/switch-colon-spacing.js +1 -1
- package/lib/rules/symbol-description.js +1 -1
- package/lib/rules/template-curly-spacing.js +1 -1
- package/lib/{util → rules/utils}/ast-utils.js +8 -27
- package/lib/{util → rules/utils}/fix-tracker.js +1 -1
- package/lib/{util → rules/utils}/keywords.js +0 -0
- package/lib/{util → rules/utils}/lazy-loading-rule-map.js +0 -0
- package/lib/{util → rules/utils}/patterns/letters.js +0 -0
- package/lib/{util → rules/utils}/unicode/index.js +0 -0
- package/lib/{util → rules/utils}/unicode/is-combining-character.js +0 -0
- package/lib/{util → rules/utils}/unicode/is-emoji-modifier.js +0 -0
- package/lib/{util → rules/utils}/unicode/is-regional-indicator-symbol.js +0 -0
- package/lib/{util → rules/utils}/unicode/is-surrogate-pair.js +0 -0
- package/lib/rules/valid-typeof.js +1 -1
- package/lib/rules/wrap-iife.js +1 -1
- package/lib/rules/yoda.js +1 -1
- package/lib/{util → shared}/ajv.js +0 -0
- package/lib/shared/ast-utils.js +29 -0
- package/lib/{config → shared}/config-ops.js +0 -0
- package/lib/{config → shared}/config-validator.js +22 -7
- package/lib/{util → shared}/logging.js +0 -0
- package/lib/{util → shared}/relative-module-resolver.js +10 -3
- package/lib/{util → shared}/traverser.js +0 -0
- package/lib/{util → shared}/types.js +4 -0
- package/lib/source-code/index.js +5 -0
- package/lib/{util → source-code}/source-code.js +10 -8
- package/lib/{token-store → source-code/token-store}/backward-token-comment-cursor.js +0 -0
- package/lib/{token-store → source-code/token-store}/backward-token-cursor.js +0 -0
- package/lib/{token-store → source-code/token-store}/cursor.js +0 -0
- package/lib/{token-store → source-code/token-store}/cursors.js +0 -0
- package/lib/{token-store → source-code/token-store}/decorative-cursor.js +0 -0
- package/lib/{token-store → source-code/token-store}/filter-cursor.js +0 -0
- package/lib/{token-store → source-code/token-store}/forward-token-comment-cursor.js +0 -0
- package/lib/{token-store → source-code/token-store}/forward-token-cursor.js +0 -0
- package/lib/{token-store → source-code/token-store}/index.js +3 -3
- package/lib/{token-store → source-code/token-store}/limit-cursor.js +0 -0
- package/lib/{token-store → source-code/token-store}/padded-token-cursor.js +0 -0
- package/lib/{token-store → source-code/token-store}/skip-cursor.js +0 -0
- package/lib/{token-store → source-code/token-store}/utils.js +0 -0
- package/messages/extend-config-missing.txt +2 -0
- package/messages/print-config-with-directory-path.txt +2 -0
- package/package.json +8 -11
- package/lib/built-in-rules-index.js +0 -281
@@ -1,6 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @fileoverview Main Linter Class
|
3
3
|
* @author Gyandeep Singh
|
4
|
+
* @author aladdin-add
|
4
5
|
*/
|
5
6
|
|
6
7
|
"use strict";
|
@@ -9,44 +10,49 @@
|
|
9
10
|
// Requirements
|
10
11
|
//------------------------------------------------------------------------------
|
11
12
|
|
12
|
-
const
|
13
|
+
const
|
14
|
+
path = require("path"),
|
13
15
|
eslintScope = require("eslint-scope"),
|
14
16
|
evk = require("eslint-visitor-keys"),
|
15
17
|
espree = require("espree"),
|
16
18
|
lodash = require("lodash"),
|
19
|
+
BuiltInEnvironments = require("../../conf/environments"),
|
20
|
+
pkg = require("../../package.json"),
|
21
|
+
astUtils = require("../shared/ast-utils"),
|
22
|
+
ConfigOps = require("../shared/config-ops"),
|
23
|
+
validator = require("../shared/config-validator"),
|
24
|
+
Traverser = require("../shared/traverser"),
|
25
|
+
{ SourceCode } = require("../source-code"),
|
17
26
|
CodePathAnalyzer = require("./code-path-analysis/code-path-analyzer"),
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
createEmitter = require("./util/safe-emitter"),
|
23
|
-
NodeEventGenerator = require("./util/node-event-generator"),
|
24
|
-
SourceCode = require("./util/source-code"),
|
25
|
-
Traverser = require("./util/traverser"),
|
26
|
-
createReportTranslator = require("./util/report-translator"),
|
27
|
+
applyDisableDirectives = require("./apply-disable-directives"),
|
28
|
+
ConfigCommentParser = require("./config-comment-parser"),
|
29
|
+
NodeEventGenerator = require("./node-event-generator"),
|
30
|
+
createReportTranslator = require("./report-translator"),
|
27
31
|
Rules = require("./rules"),
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
SourceCodeFixer = require("./util/source-code-fixer");
|
32
|
+
createEmitter = require("./safe-emitter"),
|
33
|
+
SourceCodeFixer = require("./source-code-fixer"),
|
34
|
+
timing = require("./timing"),
|
35
|
+
ruleReplacements = require("../../conf/replacements.json");
|
33
36
|
|
34
37
|
const debug = require("debug")("eslint:linter");
|
35
38
|
const MAX_AUTOFIX_PASSES = 10;
|
36
39
|
const DEFAULT_PARSER_NAME = "espree";
|
37
40
|
const commentParser = new ConfigCommentParser();
|
41
|
+
const DEFAULT_ERROR_LOC = { start: { line: 1, column: 0 }, end: { line: 1, column: 1 } };
|
38
42
|
|
39
43
|
//------------------------------------------------------------------------------
|
40
44
|
// Typedefs
|
41
45
|
//------------------------------------------------------------------------------
|
42
46
|
|
43
|
-
/** @typedef {InstanceType<import("
|
44
|
-
/** @typedef {import("
|
45
|
-
/** @typedef {import("
|
46
|
-
/** @typedef {import("
|
47
|
-
/** @typedef {import("
|
48
|
-
/** @typedef {import("
|
49
|
-
/** @typedef {import("
|
47
|
+
/** @typedef {InstanceType<import("../cli-engine/config-array")["ConfigArray"]>} ConfigArray */
|
48
|
+
/** @typedef {InstanceType<import("../cli-engine/config-array")["ExtractedConfig"]>} ExtractedConfig */
|
49
|
+
/** @typedef {import("../shared/types").ConfigData} ConfigData */
|
50
|
+
/** @typedef {import("../shared/types").Environment} Environment */
|
51
|
+
/** @typedef {import("../shared/types").GlobalConf} GlobalConf */
|
52
|
+
/** @typedef {import("../shared/types").LintMessage} LintMessage */
|
53
|
+
/** @typedef {import("../shared/types").ParserOptions} ParserOptions */
|
54
|
+
/** @typedef {import("../shared/types").Processor} Processor */
|
55
|
+
/** @typedef {import("../shared/types").Rule} Rule */
|
50
56
|
|
51
57
|
/**
|
52
58
|
* @typedef {Object} DisableDirective
|
@@ -65,6 +71,38 @@ const commentParser = new ConfigCommentParser();
|
|
65
71
|
* @property {Rules} ruleMap The loaded rules.
|
66
72
|
*/
|
67
73
|
|
74
|
+
/**
|
75
|
+
* @typedef {Object} VerifyOptions
|
76
|
+
* @property {boolean} [allowInlineConfig] Allow/disallow inline comments' ability
|
77
|
+
* to change config once it is set. Defaults to true if not supplied.
|
78
|
+
* Useful if you want to validate JS without comments overriding rules.
|
79
|
+
* @property {boolean} [disableFixes] if `true` then the linter doesn't make `fix`
|
80
|
+
* properties into the lint result.
|
81
|
+
* @property {string} [filename] the filename of the source code.
|
82
|
+
* @property {boolean} [reportUnusedDisableDirectives] Adds reported errors for
|
83
|
+
* unused `eslint-disable` directives.
|
84
|
+
*/
|
85
|
+
|
86
|
+
/**
|
87
|
+
* @typedef {Object} ProcessorOptions
|
88
|
+
* @property {(filename:string, text:string) => boolean} [filterCodeBlock] the
|
89
|
+
* predicate function that selects adopt code blocks.
|
90
|
+
* @property {Processor["postprocess"]} [postprocess] postprocessor for report
|
91
|
+
* messages. If provided, this should accept an array of the message lists
|
92
|
+
* for each code block returned from the preprocessor, apply a mapping to
|
93
|
+
* the messages as appropriate, and return a one-dimensional array of
|
94
|
+
* messages.
|
95
|
+
* @property {Processor["preprocess"]} [preprocess] preprocessor for source text.
|
96
|
+
* If provided, this should accept a string of source text, and return an
|
97
|
+
* array of code blocks to lint.
|
98
|
+
*/
|
99
|
+
|
100
|
+
/**
|
101
|
+
* @typedef {Object} FixOptions
|
102
|
+
* @property {boolean | ((message: LintMessage) => boolean)} [fix] Determines
|
103
|
+
* whether fixes should be applied.
|
104
|
+
*/
|
105
|
+
|
68
106
|
//------------------------------------------------------------------------------
|
69
107
|
// Helpers
|
70
108
|
//------------------------------------------------------------------------------
|
@@ -145,19 +183,71 @@ function addDeclaredGlobals(globalScope, configGlobals, { exportedVariables, ena
|
|
145
183
|
});
|
146
184
|
}
|
147
185
|
|
186
|
+
/**
|
187
|
+
* creates a missing-rule message.
|
188
|
+
* @param {string} ruleId the ruleId to create
|
189
|
+
* @returns {string} created error message
|
190
|
+
* @private
|
191
|
+
*/
|
192
|
+
function createMissingRuleMessage(ruleId) {
|
193
|
+
return Object.prototype.hasOwnProperty.call(ruleReplacements.rules, ruleId)
|
194
|
+
? `Rule '${ruleId}' was removed and replaced by: ${ruleReplacements.rules[ruleId].join(", ")}`
|
195
|
+
: `Definition for rule '${ruleId}' was not found.`;
|
196
|
+
}
|
197
|
+
|
198
|
+
/**
|
199
|
+
* creates a linting problem
|
200
|
+
* @param {Object} options to create linting error
|
201
|
+
* @param {string} options.ruleId the ruleId to report
|
202
|
+
* @param {Object} options.loc the loc to report
|
203
|
+
* @param {string} options.message the error message to report
|
204
|
+
* @returns {Problem} created problem, returns a missing-rule problem if only provided ruleId.
|
205
|
+
* @private
|
206
|
+
*/
|
207
|
+
function createLintingProblem(options) {
|
208
|
+
const { ruleId, loc = DEFAULT_ERROR_LOC, message = createMissingRuleMessage(options.ruleId) } = options;
|
209
|
+
|
210
|
+
return {
|
211
|
+
ruleId,
|
212
|
+
message,
|
213
|
+
line: loc.start.line,
|
214
|
+
column: loc.start.column + 1,
|
215
|
+
endLine: loc.end.line,
|
216
|
+
endColumn: loc.end.column + 1,
|
217
|
+
severity: 2,
|
218
|
+
nodeType: null
|
219
|
+
};
|
220
|
+
}
|
221
|
+
|
148
222
|
/**
|
149
223
|
* Creates a collection of disable directives from a comment
|
150
|
-
* @param {
|
151
|
-
* @param {
|
152
|
-
* @param {
|
224
|
+
* @param {Object} options to create disable directives
|
225
|
+
* @param {("disable"|"enable"|"disable-line"|"disable-next-line")} options.type The type of directive comment
|
226
|
+
* @param {{line: number, column: number}} options.loc The 0-based location of the comment token
|
227
|
+
* @param {string} options.value The value after the directive in the comment
|
153
228
|
* comment specified no specific rules, so it applies to all rules (e.g. `eslint-disable`)
|
154
|
-
* @
|
229
|
+
* @param {function(string): {create: Function}} options.ruleMapper A map from rule IDs to defined rules
|
230
|
+
* @returns {Object} Directives and problems from the comment
|
155
231
|
*/
|
156
|
-
function createDisableDirectives(
|
232
|
+
function createDisableDirectives(options) {
|
233
|
+
const { type, loc, value, ruleMapper } = options;
|
157
234
|
const ruleIds = Object.keys(commentParser.parseListConfig(value));
|
158
235
|
const directiveRules = ruleIds.length ? ruleIds : [null];
|
236
|
+
const result = {
|
237
|
+
directives: [], // valid disable directives
|
238
|
+
directiveProblems: [] // problems in directives
|
239
|
+
};
|
240
|
+
|
241
|
+
for (const ruleId of directiveRules) {
|
159
242
|
|
160
|
-
|
243
|
+
// push to directives, if the rule is defined(including null, e.g. /*eslint enable*/)
|
244
|
+
if (ruleId === null || ruleMapper(ruleId) !== null) {
|
245
|
+
result.directives.push({ type, line: loc.start.line, column: loc.start.column + 1, ruleId });
|
246
|
+
} else {
|
247
|
+
result.directiveProblems.push(createLintingProblem({ ruleId, loc }));
|
248
|
+
}
|
249
|
+
}
|
250
|
+
return result;
|
161
251
|
}
|
162
252
|
|
163
253
|
/**
|
@@ -186,23 +276,19 @@ function getDirectiveComments(filename, ast, ruleMapper) {
|
|
186
276
|
}
|
187
277
|
|
188
278
|
const directiveValue = trimmedCommentText.slice(match.index + match[1].length);
|
279
|
+
let directiveType = "";
|
189
280
|
|
190
281
|
if (/^eslint-disable-(next-)?line$/u.test(match[1])) {
|
191
282
|
if (comment.loc.start.line === comment.loc.end.line) {
|
192
|
-
|
193
|
-
|
194
|
-
disableDirectives.push(...createDisableDirectives(directiveType, comment.loc.start, directiveValue));
|
283
|
+
directiveType = match[1].slice("eslint-".length);
|
195
284
|
} else {
|
196
|
-
|
285
|
+
const message = `${match[1]} comment should not span multiple lines.`;
|
286
|
+
|
287
|
+
problems.push(createLintingProblem({
|
197
288
|
ruleId: null,
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
column: comment.loc.start.column + 1,
|
202
|
-
endLine: comment.loc.end.line,
|
203
|
-
endColumn: comment.loc.end.column + 1,
|
204
|
-
nodeType: null
|
205
|
-
});
|
289
|
+
message,
|
290
|
+
loc: comment.loc
|
291
|
+
}));
|
206
292
|
}
|
207
293
|
} else if (comment.type === "Block") {
|
208
294
|
switch (match[1]) {
|
@@ -218,16 +304,11 @@ function getDirectiveComments(filename, ast, ruleMapper) {
|
|
218
304
|
try {
|
219
305
|
normalizedValue = ConfigOps.normalizeConfigGlobal(value);
|
220
306
|
} catch (err) {
|
221
|
-
problems.push({
|
307
|
+
problems.push(createLintingProblem({
|
222
308
|
ruleId: null,
|
223
|
-
|
224
|
-
message: err.message
|
225
|
-
|
226
|
-
column: comment.loc.start.column + 1,
|
227
|
-
endLine: comment.loc.end.line,
|
228
|
-
endColumn: comment.loc.end.column + 1,
|
229
|
-
nodeType: null
|
230
|
-
});
|
309
|
+
loc: comment.loc,
|
310
|
+
message: err.message
|
311
|
+
}));
|
231
312
|
continue;
|
232
313
|
}
|
233
314
|
|
@@ -244,11 +325,11 @@ function getDirectiveComments(filename, ast, ruleMapper) {
|
|
244
325
|
break;
|
245
326
|
|
246
327
|
case "eslint-disable":
|
247
|
-
|
328
|
+
directiveType = "disable";
|
248
329
|
break;
|
249
330
|
|
250
331
|
case "eslint-enable":
|
251
|
-
|
332
|
+
directiveType = "enable";
|
252
333
|
break;
|
253
334
|
|
254
335
|
case "eslint": {
|
@@ -256,22 +337,27 @@ function getDirectiveComments(filename, ast, ruleMapper) {
|
|
256
337
|
|
257
338
|
if (parseResult.success) {
|
258
339
|
Object.keys(parseResult.config).forEach(name => {
|
340
|
+
const rule = ruleMapper(name);
|
259
341
|
const ruleValue = parseResult.config[name];
|
260
342
|
|
343
|
+
if (rule === null) {
|
344
|
+
problems.push(createLintingProblem({ ruleId: name, loc: comment.loc }));
|
345
|
+
return;
|
346
|
+
}
|
347
|
+
|
261
348
|
try {
|
262
|
-
validator.validateRuleOptions(
|
349
|
+
validator.validateRuleOptions(rule, name, ruleValue);
|
263
350
|
} catch (err) {
|
264
|
-
problems.push({
|
351
|
+
problems.push(createLintingProblem({
|
265
352
|
ruleId: name,
|
266
|
-
severity: 2,
|
267
353
|
message: err.message,
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
});
|
354
|
+
loc: comment.loc
|
355
|
+
}));
|
356
|
+
|
357
|
+
// do not apply the config, if found invalid options.
|
358
|
+
return;
|
274
359
|
}
|
360
|
+
|
275
361
|
configuredRules[name] = ruleValue;
|
276
362
|
});
|
277
363
|
} else {
|
@@ -284,6 +370,14 @@ function getDirectiveComments(filename, ast, ruleMapper) {
|
|
284
370
|
// no default
|
285
371
|
}
|
286
372
|
}
|
373
|
+
|
374
|
+
if (directiveType !== "") {
|
375
|
+
const options = { type: directiveType, loc: comment.loc, value: directiveValue, ruleMapper };
|
376
|
+
const { directives, directiveProblems } = createDisableDirectives(options);
|
377
|
+
|
378
|
+
disableDirectives.push(...directives);
|
379
|
+
problems.push(...directiveProblems);
|
380
|
+
}
|
287
381
|
});
|
288
382
|
|
289
383
|
return {
|
@@ -328,21 +422,37 @@ function findEslintEnv(text) {
|
|
328
422
|
return retv;
|
329
423
|
}
|
330
424
|
|
425
|
+
/**
|
426
|
+
* Convert "/path/to/<text>" to "<text>".
|
427
|
+
* `CLIEngine#executeOnText()` method gives "/path/to/<text>" if the filename
|
428
|
+
* was omitted because `configArray.extractConfig()` requires an absolute path.
|
429
|
+
* But the linter should pass `<text>` to `RuleContext#getFilename()` in that
|
430
|
+
* case.
|
431
|
+
* Also, code blocks can have their virtual filename. If the parent filename was
|
432
|
+
* `<text>`, the virtual filename is `<text>/0_foo.js` or something like (i.e.,
|
433
|
+
* it's not an absolute path).
|
434
|
+
* @param {string} filename The filename to normalize.
|
435
|
+
* @returns {string} The normalized filename.
|
436
|
+
*/
|
437
|
+
function normalizeFilename(filename) {
|
438
|
+
const parts = filename.split(path.sep);
|
439
|
+
const index = parts.lastIndexOf("<text>");
|
440
|
+
|
441
|
+
return index === -1 ? filename : parts.slice(index).join(path.sep);
|
442
|
+
}
|
443
|
+
|
331
444
|
/**
|
332
445
|
* Normalizes the possible options for `linter.verify` and `linter.verifyAndFix` to a
|
333
446
|
* consistent shape.
|
334
|
-
* @param {
|
335
|
-
* @returns {
|
447
|
+
* @param {VerifyOptions} providedOptions Options
|
448
|
+
* @returns {Required<VerifyOptions>} Normalized options
|
336
449
|
*/
|
337
450
|
function normalizeVerifyOptions(providedOptions) {
|
338
|
-
const isObjectOptions = typeof providedOptions === "object";
|
339
|
-
const providedFilename = isObjectOptions ? providedOptions.filename : providedOptions;
|
340
|
-
|
341
451
|
return {
|
342
|
-
filename:
|
343
|
-
allowInlineConfig:
|
344
|
-
reportUnusedDisableDirectives:
|
345
|
-
disableFixes: Boolean(providedOptions
|
452
|
+
filename: normalizeFilename(providedOptions.filename || "<input>"),
|
453
|
+
allowInlineConfig: providedOptions.allowInlineConfig !== false,
|
454
|
+
reportUnusedDisableDirectives: Boolean(providedOptions.reportUnusedDisableDirectives),
|
455
|
+
disableFixes: Boolean(providedOptions.disableFixes)
|
346
456
|
};
|
347
457
|
}
|
348
458
|
|
@@ -460,7 +570,7 @@ function analyzeScope(ast, parserOptions, visitorKeys) {
|
|
460
570
|
* @private
|
461
571
|
*/
|
462
572
|
function parse(text, parser, providedParserOptions, filePath) {
|
463
|
-
const textToParse = stripUnicodeBOM(text).replace(astUtils.
|
573
|
+
const textToParse = stripUnicodeBOM(text).replace(astUtils.shebangPattern, (match, captured) => `//${captured}`);
|
464
574
|
const parserOptions = Object.assign({}, providedParserOptions, {
|
465
575
|
loc: true,
|
466
576
|
range: true,
|
@@ -700,11 +810,18 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserOptions, parser
|
|
700
810
|
Object.keys(configuredRules).forEach(ruleId => {
|
701
811
|
const severity = ConfigOps.getRuleSeverity(configuredRules[ruleId]);
|
702
812
|
|
813
|
+
// not load disabled rules
|
703
814
|
if (severity === 0) {
|
704
815
|
return;
|
705
816
|
}
|
706
817
|
|
707
818
|
const rule = ruleMapper(ruleId);
|
819
|
+
|
820
|
+
if (rule === null) {
|
821
|
+
lintingProblems.push(createLintingProblem({ ruleId }));
|
822
|
+
return;
|
823
|
+
}
|
824
|
+
|
708
825
|
const messageIds = rule.meta && rule.meta.messages;
|
709
826
|
let reportTranslator = null;
|
710
827
|
const ruleContext = Object.freeze(
|
@@ -778,6 +895,22 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserOptions, parser
|
|
778
895
|
return lintingProblems;
|
779
896
|
}
|
780
897
|
|
898
|
+
/**
|
899
|
+
* Ensure the source code to be a string.
|
900
|
+
* @param {string|SourceCode} textOrSourceCode The text or source code object.
|
901
|
+
* @returns {string} The source code text.
|
902
|
+
*/
|
903
|
+
function ensureText(textOrSourceCode) {
|
904
|
+
if (typeof textOrSourceCode === "object") {
|
905
|
+
const { hasBOM, text } = textOrSourceCode;
|
906
|
+
const bom = hasBOM ? "\uFEFF" : "";
|
907
|
+
|
908
|
+
return bom + text;
|
909
|
+
}
|
910
|
+
|
911
|
+
return String(textOrSourceCode);
|
912
|
+
}
|
913
|
+
|
781
914
|
/**
|
782
915
|
* Get an environment.
|
783
916
|
* @param {LinterInternalSlots} slots The internal slots of Linter.
|
@@ -796,13 +929,11 @@ function getEnv(slots, envId) {
|
|
796
929
|
* Get a rule.
|
797
930
|
* @param {LinterInternalSlots} slots The internal slots of Linter.
|
798
931
|
* @param {string} ruleId The rule ID to get.
|
799
|
-
* @returns {Rule} The rule.
|
932
|
+
* @returns {Rule|null} The rule.
|
800
933
|
*/
|
801
934
|
function getRule(slots, ruleId) {
|
802
935
|
return (
|
803
936
|
(slots.lastConfigArray && slots.lastConfigArray.pluginRules.get(ruleId)) ||
|
804
|
-
|
805
|
-
// This returns the stub for missing rules if the rule does not exist.
|
806
937
|
slots.ruleMap.get(ruleId)
|
807
938
|
);
|
808
939
|
}
|
@@ -847,19 +978,13 @@ class Linter {
|
|
847
978
|
* Same as linter.verify, except without support for processors.
|
848
979
|
* @param {string|SourceCode} textOrSourceCode The text to parse or a SourceCode object.
|
849
980
|
* @param {ConfigData} providedConfig An ESLintConfig instance to configure everything.
|
850
|
-
* @param {
|
851
|
-
* If this is not set, the filename will default to '<input>' in the rule context. If
|
852
|
-
* an object, then it has "filename", "saveState", and "allowInlineConfig" properties.
|
853
|
-
* @param {boolean} [filenameOrOptions.allowInlineConfig=true] Allow/disallow inline comments' ability to change config once it is set. Defaults to true if not supplied.
|
854
|
-
* Useful if you want to validate JS without comments overriding rules.
|
855
|
-
* @param {boolean} [filenameOrOptions.reportUnusedDisableDirectives=false] Adds reported errors for unused
|
856
|
-
* eslint-disable directives
|
981
|
+
* @param {VerifyOptions} [providedOptions] The optional filename of the file being checked.
|
857
982
|
* @returns {LintMessage[]} The results as an array of messages or an empty array if no messages.
|
858
983
|
*/
|
859
|
-
_verifyWithoutProcessors(textOrSourceCode, providedConfig,
|
984
|
+
_verifyWithoutProcessors(textOrSourceCode, providedConfig, providedOptions) {
|
860
985
|
const slots = internalSlotsMap.get(this);
|
861
986
|
const config = providedConfig || {};
|
862
|
-
const options = normalizeVerifyOptions(
|
987
|
+
const options = normalizeVerifyOptions(providedOptions);
|
863
988
|
let text;
|
864
989
|
|
865
990
|
// evaluate arguments
|
@@ -991,91 +1116,121 @@ class Linter {
|
|
991
1116
|
* Verifies the text against the rules specified by the second argument.
|
992
1117
|
* @param {string|SourceCode} textOrSourceCode The text to parse or a SourceCode object.
|
993
1118
|
* @param {ConfigData|ConfigArray} config An ESLintConfig instance to configure everything.
|
994
|
-
* @param {(string|
|
1119
|
+
* @param {(string|(VerifyOptions&ProcessorOptions))} [filenameOrOptions] The optional filename of the file being checked.
|
995
1120
|
* If this is not set, the filename will default to '<input>' in the rule context. If
|
996
|
-
* an object, then it has "filename", "
|
997
|
-
* @param {boolean} [filenameOrOptions.allowInlineConfig] Allow/disallow inline comments' ability to change config once it is set. Defaults to true if not supplied.
|
998
|
-
* Useful if you want to validate JS without comments overriding rules.
|
999
|
-
* @param {function(string): string[]} [filenameOrOptions.preprocess] preprocessor for source text. If provided,
|
1000
|
-
* this should accept a string of source text, and return an array of code blocks to lint.
|
1001
|
-
* @param {function(Array<LintMessage[]>): LintMessage[]} [filenameOrOptions.postprocess] postprocessor for report messages. If provided,
|
1002
|
-
* this should accept an array of the message lists for each code block returned from the preprocessor,
|
1003
|
-
* apply a mapping to the messages as appropriate, and return a one-dimensional array of messages
|
1121
|
+
* an object, then it has "filename", "allowInlineConfig", and some properties.
|
1004
1122
|
* @returns {LintMessage[]} The results as an array of messages or an empty array if no messages.
|
1005
1123
|
*/
|
1006
1124
|
verify(textOrSourceCode, config, filenameOrOptions) {
|
1125
|
+
debug("Verify");
|
1126
|
+
const options = typeof filenameOrOptions === "string"
|
1127
|
+
? { filename: filenameOrOptions }
|
1128
|
+
: filenameOrOptions || {};
|
1129
|
+
|
1130
|
+
// CLIEngine passes a `ConfigArray` object.
|
1007
1131
|
if (config && typeof config.extractConfig === "function") {
|
1008
|
-
return this._verifyWithConfigArray(
|
1009
|
-
textOrSourceCode,
|
1010
|
-
config,
|
1011
|
-
typeof filenameOrOptions === "string"
|
1012
|
-
? { filename: filenameOrOptions }
|
1013
|
-
: filenameOrOptions || {}
|
1014
|
-
);
|
1132
|
+
return this._verifyWithConfigArray(textOrSourceCode, config, options);
|
1015
1133
|
}
|
1016
1134
|
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
);
|
1135
|
+
/*
|
1136
|
+
* `Linter` doesn't support `overrides` property in configuration.
|
1137
|
+
* So we cannot apply multiple processors.
|
1138
|
+
*/
|
1139
|
+
if (options.preprocess || options.postprocess) {
|
1140
|
+
return this._verifyWithProcessor(textOrSourceCode, config, options);
|
1141
|
+
}
|
1142
|
+
return this._verifyWithoutProcessors(textOrSourceCode, config, options);
|
1025
1143
|
}
|
1026
1144
|
|
1027
1145
|
/**
|
1028
1146
|
* Verify a given code with `ConfigArray`.
|
1029
|
-
* @param {string}
|
1147
|
+
* @param {string|SourceCode} textOrSourceCode The source code.
|
1030
1148
|
* @param {ConfigArray} configArray The config array.
|
1031
|
-
* @param {
|
1149
|
+
* @param {VerifyOptions&ProcessorOptions} options The options.
|
1032
1150
|
* @returns {LintMessage[]} The found problems.
|
1033
1151
|
*/
|
1034
|
-
_verifyWithConfigArray(
|
1035
|
-
debug("
|
1152
|
+
_verifyWithConfigArray(textOrSourceCode, configArray, options) {
|
1153
|
+
debug("With ConfigArray: %s", options.filename);
|
1036
1154
|
|
1037
1155
|
// Store the config array in order to get plugin envs and rules later.
|
1038
1156
|
internalSlotsMap.get(this).lastConfigArray = configArray;
|
1039
1157
|
|
1040
|
-
/*
|
1041
|
-
* TODO: implement https://github.com/eslint/rfcs/tree/master/designs/2018-processors-improvements here.
|
1042
|
-
*/
|
1043
|
-
|
1044
1158
|
// Extract the final config for this file.
|
1045
|
-
const config = configArray.extractConfig(
|
1159
|
+
const config = configArray.extractConfig(options.filename);
|
1160
|
+
const processor =
|
1161
|
+
config.processor &&
|
1162
|
+
configArray.pluginProcessors.get(config.processor);
|
1046
1163
|
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
* `RuleContext#getFilename()` in that case.
|
1053
|
-
*/
|
1054
|
-
const filename = path.basename(providedOptions.filename) === "<text>"
|
1055
|
-
? "<text>"
|
1056
|
-
: providedOptions.filename;
|
1057
|
-
|
1058
|
-
// Make options.
|
1059
|
-
const options = {
|
1060
|
-
...providedOptions,
|
1061
|
-
filename
|
1062
|
-
};
|
1164
|
+
// Verify.
|
1165
|
+
if (processor) {
|
1166
|
+
debug("Apply the processor: %o", config.processor);
|
1167
|
+
const { preprocess, postprocess, supportsAutofix } = processor;
|
1168
|
+
const disableFixes = options.disableFixes || !supportsAutofix;
|
1063
1169
|
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1170
|
+
return this._verifyWithProcessor(
|
1171
|
+
textOrSourceCode,
|
1172
|
+
config,
|
1173
|
+
{ ...options, disableFixes, postprocess, preprocess },
|
1174
|
+
configArray
|
1175
|
+
);
|
1176
|
+
}
|
1177
|
+
return this._verifyWithoutProcessors(textOrSourceCode, config, options);
|
1178
|
+
}
|
1067
1179
|
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1180
|
+
/**
|
1181
|
+
* Verify with a processor.
|
1182
|
+
* @param {string|SourceCode} textOrSourceCode The source code.
|
1183
|
+
* @param {ConfigData|ExtractedConfig} config The config array.
|
1184
|
+
* @param {VerifyOptions&ProcessorOptions} options The options.
|
1185
|
+
* @param {ConfigArray} [configForRecursive] The `CofnigArray` object to apply multiple processors recursively.
|
1186
|
+
* @returns {LintMessage[]} The found problems.
|
1187
|
+
*/
|
1188
|
+
_verifyWithProcessor(textOrSourceCode, config, options, configForRecursive) {
|
1189
|
+
const filename = options.filename || "<input>";
|
1190
|
+
const filenameToExpose = normalizeFilename(filename);
|
1191
|
+
const text = ensureText(textOrSourceCode);
|
1192
|
+
const preprocess = options.preprocess || (rawText => [rawText]);
|
1193
|
+
const postprocess = options.postprocess || lodash.flatten;
|
1194
|
+
const filterCodeBlock =
|
1195
|
+
options.filterCodeBlock ||
|
1196
|
+
(blockFilename => blockFilename.endsWith(".js"));
|
1197
|
+
const originalExtname = path.extname(filename);
|
1198
|
+
const messageLists = preprocess(text, filenameToExpose).map((block, i) => {
|
1199
|
+
debug("A code block was found: %o", block.filename || "(unnamed)");
|
1200
|
+
|
1201
|
+
// Keep the legacy behavior.
|
1202
|
+
if (typeof block === "string") {
|
1203
|
+
return this._verifyWithoutProcessors(block, config, options);
|
1204
|
+
}
|
1205
|
+
|
1206
|
+
const blockText = block.text;
|
1207
|
+
const blockName = path.join(filename, `${i}_${block.filename}`);
|
1071
1208
|
|
1072
|
-
|
1073
|
-
|
1209
|
+
// Skip this block if filtered.
|
1210
|
+
if (!filterCodeBlock(blockName, blockText)) {
|
1211
|
+
debug("This code block was skipped.");
|
1212
|
+
return [];
|
1074
1213
|
}
|
1075
|
-
}
|
1076
1214
|
|
1077
|
-
|
1078
|
-
|
1215
|
+
// Resolve configuration again if the file extension was changed.
|
1216
|
+
if (configForRecursive && path.extname(blockName) !== originalExtname) {
|
1217
|
+
debug("Resolving configuration again because the file extension was changed.");
|
1218
|
+
return this._verifyWithConfigArray(
|
1219
|
+
blockText,
|
1220
|
+
configForRecursive,
|
1221
|
+
{ ...options, filename: blockName }
|
1222
|
+
);
|
1223
|
+
}
|
1224
|
+
|
1225
|
+
// Does lint.
|
1226
|
+
return this._verifyWithoutProcessors(
|
1227
|
+
blockText,
|
1228
|
+
config,
|
1229
|
+
{ ...options, filename: blockName }
|
1230
|
+
);
|
1231
|
+
});
|
1232
|
+
|
1233
|
+
return postprocess(messageLists, filenameToExpose);
|
1079
1234
|
}
|
1080
1235
|
|
1081
1236
|
/**
|
@@ -1138,16 +1293,7 @@ class Linter {
|
|
1138
1293
|
* have been applied.
|
1139
1294
|
* @param {string} text The source text to apply fixes to.
|
1140
1295
|
* @param {ConfigData|ConfigArray} config The ESLint config object to use.
|
1141
|
-
* @param {
|
1142
|
-
* @param {string} options.filename The filename from which the text was read.
|
1143
|
-
* @param {boolean} options.allowInlineConfig Flag indicating if inline comments
|
1144
|
-
* should be allowed.
|
1145
|
-
* @param {boolean|Function} options.fix Determines whether fixes should be applied
|
1146
|
-
* @param {Function} options.preprocess preprocessor for source text. If provided, this should
|
1147
|
-
* accept a string of source text, and return an array of code blocks to lint.
|
1148
|
-
* @param {Function} options.postprocess postprocessor for report messages. If provided,
|
1149
|
-
* this should accept an array of the message lists for each code block returned from the preprocessor,
|
1150
|
-
* apply a mapping to the messages as appropriate, and return a one-dimensional array of messages
|
1296
|
+
* @param {VerifyOptions&ProcessorOptions&FixOptions} options The ESLint options object to use.
|
1151
1297
|
* @returns {{fixed:boolean,messages:LintMessage[],output:string}} The result of the fix operation as returned from the
|
1152
1298
|
* SourceCodeFixer.
|
1153
1299
|
*/
|