From 58840ac844a61c72eabb603ecfb761812b82a7ed Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Fri, 20 Aug 2021 08:39:17 +0800 Subject: [PATCH] Chore: Update jsdoc plugin and tweak rules in effect (#14814) * Chore: Remove explicit rule declarations that are already inherited * Chore: Add eslint-comments plugin * Chore: Add peerDeps to eslint-config-eslint * Chore: Avoid single-file disable directives in favor of setting to "off" * Chore: Remove rules already included by recommended configs --- .eslintrc.js | 2 +- Makefile.js | 10 +- lib/cli-engine/cli-engine.js | 9 +- lib/cli-engine/file-enumerator.js | 5 +- lib/config/rule-validator.js | 2 +- lib/eslint/eslint.js | 1 + lib/init/autoconfig.js | 6 +- lib/init/config-initializer.js | 5 +- lib/init/npm-utils.js | 1 + lib/init/source-code-utils.js | 1 + .../code-path-analysis/code-path-state.js | 4 + lib/linter/config-comment-parser.js | 2 +- lib/linter/linter.js | 20 ++-- lib/linter/report-translator.js | 24 ++-- lib/linter/safe-emitter.js | 4 +- lib/linter/timing.js | 2 +- lib/rule-tester/rule-tester.js | 7 ++ lib/rules/default-case.js | 2 +- lib/rules/function-paren-newline.js | 1 + lib/rules/indent.js | 14 +-- lib/rules/key-spacing.js | 2 +- lib/rules/keyword-spacing.js | 1 + lib/rules/max-len.js | 2 +- lib/rules/max-lines-per-function.js | 2 +- lib/rules/new-cap.js | 3 +- lib/rules/no-extra-boolean-cast.js | 1 + lib/rules/no-loop-func.js | 2 +- lib/rules/no-mixed-operators.js | 2 +- lib/rules/no-undef-init.js | 3 + lib/rules/no-useless-computed-key.js | 1 + lib/rules/no-useless-escape.js | 17 +-- lib/rules/object-shorthand.js | 4 - lib/rules/padded-blocks.js | 1 + lib/rules/prefer-arrow-callback.js | 1 + lib/rules/utils/ast-utils.js | 5 +- lib/rules/utils/lazy-loading-rule-map.js | 6 +- lib/shared/config-validator.js | 15 ++- lib/shared/relative-module-resolver.js | 1 + lib/shared/runtime-info.js | 3 + lib/source-code/source-code.js | 12 +- package.json | 3 +- packages/eslint-config-eslint/default.yml | 105 ++++++++++++++---- packages/eslint-config-eslint/package.json | 3 +- tests/bin/eslint.js | 2 +- tests/lib/cli-engine/cli-engine.js | 6 +- tests/lib/cli-engine/file-enumerator.js | 6 +- tests/lib/eslint/eslint.js | 4 +- tests/lib/linter/linter.js | 2 +- tests/lib/rule-tester/no-test-runners.js | 2 +- tests/lib/rule-tester/rule-tester.js | 4 +- tests/lib/rules/utils/ast-utils.js | 2 - tools/eslint-fuzzer.js | 2 +- 52 files changed, 234 insertions(+), 113 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 640ac2db742..56f017ffe63 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -51,7 +51,7 @@ module.exports = { "plugin:eslint-plugin/recommended" ], parserOptions: { - ecmaVersion: 2020 + ecmaVersion: 2021 }, /* diff --git a/Makefile.js b/Makefile.js index 59e58b1404d..f19ca020063 100644 --- a/Makefile.js +++ b/Makefile.js @@ -962,14 +962,20 @@ function createConfigForPerformanceTest() { content.join("\n").to(PERF_ESLINTRC); } +/** + * @callback TimeCallback + * @param {?int[]} results + * @returns {void} + */ + /** * Calculates the time for each run for performance * @param {string} cmd cmd * @param {int} runs Total number of runs to do * @param {int} runNumber Current run number * @param {int[]} results Collection results from each run - * @param {Function} cb Function to call when everything is done - * @returns {int[]} calls the cb with all the results + * @param {TimeCallback} cb Function to call when everything is done + * @returns {void} calls the cb with all the results * @private */ function time(cmd, runs, runNumber, results, cb) { diff --git a/lib/cli-engine/cli-engine.js b/lib/cli-engine/cli-engine.js index 3ba0dfe0d9a..9c024e37a28 100644 --- a/lib/cli-engine/cli-engine.js +++ b/lib/cli-engine/cli-engine.js @@ -55,8 +55,8 @@ const validFixTypes = new Set(["directive", "problem", "suggestion", "layout"]); /** @typedef {import("../shared/types").Plugin} Plugin */ /** @typedef {import("../shared/types").RuleConf} RuleConf */ /** @typedef {import("../shared/types").Rule} Rule */ -/** @typedef {ReturnType} ConfigArray */ -/** @typedef {ReturnType} ExtractedConfig */ +/** @typedef {ReturnType} ConfigArray */ +/** @typedef {ReturnType} ExtractedConfig */ /** * The options to configure a CLI engine with. @@ -480,6 +480,7 @@ function getCacheFile(cacheFile, cwd) { * @param {string[]|null} keys The keys to assign true. * @param {boolean} defaultValue The default value for each property. * @param {string} displayName The property name which is used in error message. + * @throws {Error} Requires array. * @returns {Record} The boolean map. */ function toBooleanMap(keys, defaultValue, displayName) { @@ -543,6 +544,7 @@ function createConfigDataFromOptions(options) { /** * Checks whether a directory exists at the given location * @param {string} resolvedPath A path from the CWD + * @throws {Error} As thrown by `fs.statSync` or `fs.isDirectory`. * @returns {boolean} `true` if a directory exists */ function directoryExists(resolvedPath) { @@ -742,6 +744,7 @@ class CLIEngine { /** * Executes the current configuration on an array of file and directory names. * @param {string[]} patterns An array of file and directory names. + * @throws {Error} As may be thrown by `fs.unlinkSync`. * @returns {LintReport} The results for all files that were linted. */ executeOnFiles(patterns) { @@ -948,6 +951,7 @@ class CLIEngine { * This is the same logic used by the ESLint CLI executable to determine * configuration for each file it processes. * @param {string} filePath The path of the file to retrieve a config object for. + * @throws {Error} If filepath a directory path. * @returns {ConfigData} A configuration object for the file. */ getConfigForFile(filePath) { @@ -996,6 +1000,7 @@ class CLIEngine { * Returns the formatter representing the given format or null if the `format` is not a string. * @param {string} [format] The name of the format to load or the path to a * custom formatter. + * @throws {any} As may be thrown by requiring of formatter * @returns {(Function|null)} The formatter function or null if the `format` is not a string. */ getFormatter(format) { diff --git a/lib/cli-engine/file-enumerator.js b/lib/cli-engine/file-enumerator.js index ade28517b42..03a408488f1 100644 --- a/lib/cli-engine/file-enumerator.js +++ b/lib/cli-engine/file-enumerator.js @@ -60,7 +60,7 @@ const IGNORED_SILENTLY = 1; const IGNORED = 2; // For VSCode intellisense -/** @typedef {ReturnType} ConfigArray */ +/** @typedef {ReturnType} ConfigArray */ /** * @typedef {Object} FileEnumeratorOptions @@ -114,6 +114,7 @@ function isGlobPattern(pattern) { /** * Get stats of a given path. * @param {string} filePath The path to target file. + * @throws {Error} As may be thrown by `fs.statSync`. * @returns {fs.Stats|null} The stats. * @private */ @@ -132,6 +133,7 @@ function statSafeSync(filePath) { /** * Get filenames in a given path to a directory. * @param {string} directoryPath The path to target directory. + * @throws {Error} As may be thrown by `fs.readdirSync`. * @returns {import("fs").Dirent[]} The filenames. * @private */ @@ -270,6 +272,7 @@ class FileEnumerator { /** * Iterate files which are matched by given glob patterns. * @param {string|string[]} patternOrPatterns The glob patterns to iterate files. + * @throws {NoFilesFoundError|AllFilesIgnoredError} On an unmatched pattern. * @returns {IterableIterator} The found files. */ *iterateFiles(patternOrPatterns) { diff --git a/lib/config/rule-validator.js b/lib/config/rule-validator.js index f162dd81a05..fe1aa863bfd 100644 --- a/lib/config/rule-validator.js +++ b/lib/config/rule-validator.js @@ -19,6 +19,7 @@ const ajv = require("../shared/ajv")(); * Finds a rule with the given ID in the given config. * @param {string} ruleId The ID of the rule to find. * @param {Object} config The config to search in. + * @throws {TypeError} For missing plugin or rule. * @returns {{create: Function, schema: (Array|null)}} THe rule object. */ function findRuleDefinition(ruleId, config) { @@ -98,7 +99,6 @@ class RuleValidator { * A collection of compiled validators for rules that have already * been validated. * @type {WeakMap} - * @property validators */ this.validators = new WeakMap(); } diff --git a/lib/eslint/eslint.js b/lib/eslint/eslint.js index 62229be8068..e20bcbaf4e3 100644 --- a/lib/eslint/eslint.js +++ b/lib/eslint/eslint.js @@ -151,6 +151,7 @@ class ESLintInvalidOptionsError extends Error { /** * Validates and normalizes options for the wrapped CLIEngine instance. * @param {ESLintOptions} options The options to process. + * @throws {ESLintInvalidOptionsError} If of any of a variety of type errors. * @returns {ESLintOptions} The normalized options. */ function processOptions({ diff --git a/lib/init/autoconfig.js b/lib/init/autoconfig.js index 3233f686539..371b22b1a94 100644 --- a/lib/init/autoconfig.js +++ b/lib/init/autoconfig.js @@ -36,9 +36,9 @@ const MAX_CONFIG_COMBINATIONS = 17, // 16 combinations + 1 for severity only /** * Information about a rule configuration, in the context of a Registry. * @typedef {Object} registryItem - * @param {ruleConfig} config A valid configuration for the rule - * @param {number} specificity The number of elements in the ruleConfig array - * @param {number} errorCount The number of errors encountered when linting with the config + * @property {ruleConfig} config A valid configuration for the rule + * @property {number} specificity The number of elements in the ruleConfig array + * @property {number} errorCount The number of errors encountered when linting with the config */ /** diff --git a/lib/init/config-initializer.js b/lib/init/config-initializer.js index 7ed69dfed5f..b9b35c67c21 100644 --- a/lib/init/config-initializer.js +++ b/lib/init/config-initializer.js @@ -163,6 +163,7 @@ function getModulesList(config, installESLint) { * the original config parameter. * @param {Object} answers answers received from enquirer * @param {Object} config config object + * @throws {Error} If source code retrieval fails or source code file count is 0. * @returns {Object} config object with configured rules */ function configureRules(answers, config) { @@ -428,7 +429,7 @@ function installModules(modules) { * Ask user to install modules. * @param {string[]} modules Array of modules to be installed. * @param {boolean} packageJsonExists Indicates if package.json is existed. - * @returns {Promise} Answer that indicates if user wants to install. + * @returns {Promise} Answer that indicates if user wants to install. */ function askInstallModules(modules, packageJsonExists) { @@ -464,7 +465,7 @@ function askInstallModules(modules, packageJsonExists) { /* istanbul ignore next: no need to test enquirer */ /** * Ask use a few questions on command prompt - * @returns {Promise} The promise with the result of the prompt + * @returns {Promise} The promise with the result of the prompt */ function promptUser() { diff --git a/lib/init/npm-utils.js b/lib/init/npm-utils.js index b91a824b126..76a1618b36f 100644 --- a/lib/init/npm-utils.js +++ b/lib/init/npm-utils.js @@ -91,6 +91,7 @@ function fetchPeerDependencies(packageName) { * @param {boolean} opt.dependencies Set to true to check for direct dependencies * @param {boolean} opt.devDependencies Set to true to check for development dependencies * @param {boolean} opt.startdir Directory to begin searching from + * @throws {Error} If cannot find valid `package.json` file. * @returns {Object} An object whose keys are the module names * and values are booleans indicating installation. */ diff --git a/lib/init/source-code-utils.js b/lib/init/source-code-utils.js index dca6541d1ed..f7b911e4ca2 100644 --- a/lib/init/source-code-utils.js +++ b/lib/init/source-code-utils.js @@ -35,6 +35,7 @@ const debug = require("debug")("eslint:source-code-utils"); * Get the SourceCode object for a single file * @param {string} filename The fully resolved filename to get SourceCode from. * @param {Object} engine A CLIEngine. + * @throws {Error} Upon fatal errors from execution. * @returns {Array} Array of the SourceCode object representing the file * and fatal error message. */ diff --git a/lib/linter/code-path-analysis/code-path-state.js b/lib/linter/code-path-analysis/code-path-state.js index f75e60e28a8..4824632775b 100644 --- a/lib/linter/code-path-analysis/code-path-state.js +++ b/lib/linter/code-path-analysis/code-path-state.js @@ -360,6 +360,7 @@ class CodePathState { /** * Pops the last choice context and finalizes it. + * @throws {Error} (Unreachable.) * @returns {ChoiceContext} The popped context. */ popChoiceContext() { @@ -450,6 +451,7 @@ class CodePathState { /** * Makes a code path segment of the right-hand operand of a logical * expression. + * @throws {Error} (Unreachable.) * @returns {void} */ makeLogicalRight() { @@ -965,6 +967,7 @@ class CodePathState { * `WhileStatement`, `DoWhileStatement`, `ForStatement`, `ForInStatement`, * and `ForStatement`. * @param {string|null} label A label of the node which was triggered. + * @throws {Error} (Unreachable - unknown type.) * @returns {void} */ pushLoopContext(type, label) { @@ -1036,6 +1039,7 @@ class CodePathState { /** * Pops the last context of a loop statement and finalizes it. + * @throws {Error} (Unreachable - unknown type.) * @returns {void} */ popLoopContext() { diff --git a/lib/linter/config-comment-parser.js b/lib/linter/config-comment-parser.js index 64482489535..f5d7b155eb5 100644 --- a/lib/linter/config-comment-parser.js +++ b/lib/linter/config-comment-parser.js @@ -3,7 +3,7 @@ * @author Nicholas C. Zakas */ -/* eslint-disable class-methods-use-this*/ +/* eslint class-methods-use-this: off */ "use strict"; //------------------------------------------------------------------------------ diff --git a/lib/linter/linter.js b/lib/linter/linter.js index a140b4b1bef..1b3121fde4d 100644 --- a/lib/linter/linter.js +++ b/lib/linter/linter.js @@ -50,8 +50,8 @@ const parserSymbol = Symbol.for("eslint.RuleTester.parser"); // Typedefs //------------------------------------------------------------------------------ -/** @typedef {InstanceType} ConfigArray */ -/** @typedef {InstanceType} ExtractedConfig */ +/** @typedef {InstanceType} ConfigArray */ +/** @typedef {InstanceType} ExtractedConfig */ /** @typedef {import("../shared/types").ConfigData} ConfigData */ /** @typedef {import("../shared/types").Environment} Environment */ /** @typedef {import("../shared/types").GlobalConf} GlobalConf */ @@ -60,17 +60,19 @@ const parserSymbol = Symbol.for("eslint.RuleTester.parser"); /** @typedef {import("../shared/types").Processor} Processor */ /** @typedef {import("../shared/types").Rule} Rule */ +/* eslint-disable jsdoc/valid-types -- https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/4#issuecomment-778805577 */ /** * @template T * @typedef {{ [P in keyof T]-?: T[P] }} Required */ +/* eslint-enable jsdoc/valid-types */ /** * @typedef {Object} DisableDirective - * @property {("disable"|"enable"|"disable-line"|"disable-next-line")} type - * @property {number} line - * @property {number} column - * @property {(string|null)} ruleId + * @property {("disable"|"enable"|"disable-line"|"disable-next-line")} type Type of directive + * @property {number} line The line number + * @property {number} column The column number + * @property {(string|null)} ruleId The rule ID */ /** @@ -98,12 +100,12 @@ const parserSymbol = Symbol.for("eslint.RuleTester.parser"); * @typedef {Object} ProcessorOptions * @property {(filename:string, text:string) => boolean} [filterCodeBlock] the * predicate function that selects adopt code blocks. - * @property {Processor["postprocess"]} [postprocess] postprocessor for report + * @property {Processor.postprocess} [postprocess] postprocessor for report * messages. If provided, this should accept an array of the message lists * for each code block returned from the preprocessor, apply a mapping to * the messages as appropriate, and return a one-dimensional array of * messages. - * @property {Processor["preprocess"]} [preprocess] preprocessor for source text. + * @property {Processor.preprocess} [preprocess] preprocessor for source text. * If provided, this should accept a string of source text, and return an * array of code blocks to lint. */ @@ -764,6 +766,7 @@ function markVariableAsUsed(scopeManager, currentNode, parserOptions, name) { * Runs a rule, and gets its listeners * @param {Rule} rule A normalized rule with a `create` method * @param {Context} ruleContext The context that should be passed to the rule + * @throws {any} Any error during the rule's `create` * @returns {Object} A map of selector listeners provided by the rule */ function createRuleListeners(rule, ruleContext) { @@ -1092,6 +1095,7 @@ class Linter { * @param {string|SourceCode} textOrSourceCode The text to parse or a SourceCode object. * @param {ConfigData} providedConfig An ESLintConfig instance to configure everything. * @param {VerifyOptions} [providedOptions] The optional filename of the file being checked. + * @throws {Error} If during rule execution. * @returns {LintMessage[]} The results as an array of messages or an empty array if no messages. */ _verifyWithoutProcessors(textOrSourceCode, providedConfig, providedOptions) { diff --git a/lib/linter/report-translator.js b/lib/linter/report-translator.js index 75005c16e58..781b3136ec5 100644 --- a/lib/linter/report-translator.js +++ b/lib/linter/report-translator.js @@ -32,18 +32,18 @@ const interpolate = require("./interpolate"); /** * Information about the report * @typedef {Object} ReportInfo - * @property {string} ruleId - * @property {(0|1|2)} severity - * @property {(string|undefined)} message - * @property {(string|undefined)} [messageId] - * @property {number} line - * @property {number} column - * @property {(number|undefined)} [endLine] - * @property {(number|undefined)} [endColumn] - * @property {(string|null)} nodeType - * @property {string} source - * @property {({text: string, range: (number[]|null)}|null)} [fix] - * @property {Array<{text: string, range: (number[]|null)}|null>} [suggestions] + * @property {string} ruleId The rule ID + * @property {(0|1|2)} severity Severity of the error + * @property {(string|undefined)} message The message + * @property {(string|undefined)} [messageId] The message ID + * @property {number} line The line number + * @property {number} column The column number + * @property {(number|undefined)} [endLine] The ending line number + * @property {(number|undefined)} [endColumn] The ending column number + * @property {(string|null)} nodeType Type of node + * @property {string} source Source text + * @property {({text: string, range: (number[]|null)}|null)} [fix] The fix object + * @property {Array<{text: string, range: (number[]|null)}|null>} [suggestions] Suggestion info */ //------------------------------------------------------------------------------ diff --git a/lib/linter/safe-emitter.js b/lib/linter/safe-emitter.js index ab212230d39..f4837c1ddcf 100644 --- a/lib/linter/safe-emitter.js +++ b/lib/linter/safe-emitter.js @@ -12,8 +12,8 @@ /** * An event emitter * @typedef {Object} SafeEmitter - * @property {function(eventName: string, listenerFunc: Function): void} on Adds a listener for a given event name - * @property {function(eventName: string, arg1?: any, arg2?: any, arg3?: any)} emit Emits an event with a given name. + * @property {(eventName: string, listenerFunc: Function) => void} on Adds a listener for a given event name + * @property {(eventName: string, arg1?: any, arg2?: any, arg3?: any) => void} emit Emits an event with a given name. * This calls all the listeners that were listening for that name, with `arg1`, `arg2`, and `arg3` as arguments. * @property {function(): string[]} eventNames Gets the list of event names that have registered listeners. */ diff --git a/lib/linter/timing.js b/lib/linter/timing.js index 58230306855..a5613a4a268 100644 --- a/lib/linter/timing.js +++ b/lib/linter/timing.js @@ -126,7 +126,7 @@ module.exports = (function() { /** * Time the run - * @param {*} key key from the data object + * @param {any} key key from the data object * @param {Function} fn function to be called * @returns {Function} function to be executed * @private diff --git a/lib/rule-tester/rule-tester.js b/lib/rule-tester/rule-tester.js index 2d820f5d859..3e2e639882f 100644 --- a/lib/rule-tester/rule-tester.js +++ b/lib/rule-tester/rule-tester.js @@ -63,6 +63,7 @@ const { SourceCode } = require("../source-code"); /** @typedef {import("../shared/types").Parser} Parser */ +/* eslint-disable jsdoc/valid-types -- https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/4#issuecomment-778805577 */ /** * A test case that is expected to pass lint. * @typedef {Object} ValidTestCase @@ -105,6 +106,7 @@ const { SourceCode } = require("../source-code"); * @property {number} [endLine] The 1-based line number of the reported end location. * @property {number} [endColumn] The 1-based column number of the reported end location. */ +/* eslint-enable jsdoc/valid-types */ //------------------------------------------------------------------------------ // Private Members @@ -311,6 +313,7 @@ const IT_ONLY = Symbol("itOnly"); * @this {Mocha} * @param {string} text The description of the test case. * @param {Function} method The logic of the test case. + * @throws {Error} Any error upon execution of `method`. * @returns {any} Returned value of `method`. */ function itDefaultHandler(text, method) { @@ -366,6 +369,7 @@ class RuleTester { /** * Set the configuration to use for all future tests * @param {Object} config the configuration to use. + * @throws {TypeError} If non-object config. * @returns {void} */ static setDefaultConfig(config) { @@ -481,6 +485,8 @@ class RuleTester { * valid: (ValidTestCase | string)[], * invalid: InvalidTestCase[] * }} test The collection of tests to run. + * @throws {TypeError|Error} If non-object `test`, or if a required + * scenario of the given type is missing. * @returns {void} */ run(ruleName, rule, test) { @@ -524,6 +530,7 @@ class RuleTester { /** * Run the rule for the given item * @param {string|Object} item Item to run the rule against + * @throws {Error} If an invalid schema. * @returns {Object} Eslint run result * @private */ diff --git a/lib/rules/default-case.js b/lib/rules/default-case.js index 821e0d72bd1..968aefe9cc8 100644 --- a/lib/rules/default-case.js +++ b/lib/rules/default-case.js @@ -51,7 +51,7 @@ module.exports = { /** * Shortcut to get last element of array * @param {*[]} collection Array - * @returns {*} Last element + * @returns {any} Last element */ function last(collection) { return collection[collection.length - 1]; diff --git a/lib/rules/function-paren-newline.js b/lib/rules/function-paren-newline.js index 9d8d67ba141..8884b9b97fe 100644 --- a/lib/rules/function-paren-newline.js +++ b/lib/rules/function-paren-newline.js @@ -183,6 +183,7 @@ module.exports = { /** * Gets the left paren and right paren tokens of a node. * @param {ASTNode} node The node with parens + * @throws {TypeError} Unexecpted node type. * @returns {Object} An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token. * Can also return `null` if an expression has no parens (e.g. a NewExpression with no arguments, or an ArrowFunctionExpression * with a single parameter) diff --git a/lib/rules/indent.js b/lib/rules/indent.js index 8280d43a654..75d6715ae16 100644 --- a/lib/rules/indent.js +++ b/lib/rules/indent.js @@ -140,7 +140,7 @@ class BinarySearchTree { /** * Inserts an entry into the tree. * @param {number} key The entry's key - * @param {*} value The entry's value + * @param {any} value The entry's value * @returns {void} */ insert(key, value) { @@ -265,7 +265,7 @@ class OffsetStorage { /** * Sets the offset column of token B to match the offset column of token A. - * **WARNING**: This matches a *column*, even if baseToken is not the first token on its line. In + * - **WARNING**: This matches a *column*, even if baseToken is not the first token on its line. In * most cases, `setDesiredOffset` should be used instead. * @param {Token} baseToken The first token * @param {Token} offsetToken The second token, whose offset should be matched to the first token @@ -354,11 +354,11 @@ class OffsetStorage { * Instead, the offset tree is represented as a collection of contiguous offset ranges in a file. For example, the following * list could represent the state of the offset tree at a given point: * - * * Tokens starting in the interval [0, 15) are aligned with the beginning of the file - * * Tokens starting in the interval [15, 30) are offset by 1 indent level from the `bar` token - * * Tokens starting in the interval [30, 43) are offset by 1 indent level from the `foo` token - * * Tokens starting in the interval [43, 820) are offset by 2 indent levels from the `bar` token - * * Tokens starting in the interval [820, ∞) are offset by 1 indent level from the `baz` token + * - Tokens starting in the interval [0, 15) are aligned with the beginning of the file + * - Tokens starting in the interval [15, 30) are offset by 1 indent level from the `bar` token + * - Tokens starting in the interval [30, 43) are offset by 1 indent level from the `foo` token + * - Tokens starting in the interval [43, 820) are offset by 2 indent levels from the `bar` token + * - Tokens starting in the interval [820, ∞) are offset by 1 indent level from the `baz` token * * The `setDesiredOffsets` methods inserts ranges like the ones above. The third line above would be inserted by using: * `setDesiredOffsets([30, 43], fooToken, 1);` diff --git a/lib/rules/key-spacing.js b/lib/rules/key-spacing.js index fc885a117a1..c7230078958 100644 --- a/lib/rules/key-spacing.js +++ b/lib/rules/key-spacing.js @@ -532,7 +532,7 @@ module.exports = { /** * Creates groups of properties. * @param {ASTNode} node ObjectExpression node being evaluated. - * @returns {Array.} Groups of property AST node lists. + * @returns {Array} Groups of property AST node lists. */ function createGroups(node) { if (node.properties.length === 1) { diff --git a/lib/rules/keyword-spacing.js b/lib/rules/keyword-spacing.js index 14a46647458..67054cb8ed0 100644 --- a/lib/rules/keyword-spacing.js +++ b/lib/rules/keyword-spacing.js @@ -473,6 +473,7 @@ module.exports = { * Reports `static`, `get`, and `set` keywords of a given node if usage of * spacing around those keywords is invalid. * @param {ASTNode} node A node to report. + * @throws {Error} If unable to find token get, set, or async beside method name. * @returns {void} */ function checkSpacingForProperty(node) { diff --git a/lib/rules/max-len.js b/lib/rules/max-len.js index dd76760c505..710fb8ede96 100644 --- a/lib/rules/max-len.js +++ b/lib/rules/max-len.js @@ -215,7 +215,7 @@ module.exports = { * Ensure that an array exists at [key] on `object`, and add `value` to it. * @param {Object} object the object to mutate * @param {string} key the object's key - * @param {*} value the value to add + * @param {any} value the value to add * @returns {void} * @private */ diff --git a/lib/rules/max-lines-per-function.js b/lib/rules/max-lines-per-function.js index 60e2e879f54..161a1c5bce7 100644 --- a/lib/rules/max-lines-per-function.js +++ b/lib/rules/max-lines-per-function.js @@ -48,7 +48,7 @@ const OPTIONS_OR_INTEGER_SCHEMA = { /** * Given a list of comment nodes, return a map with numeric keys (source code line numbers) and comment token values. * @param {Array} comments An array of comment nodes. - * @returns {Map.} A map with numeric keys (source code line numbers) and comment token values. + * @returns {Map} A map with numeric keys (source code line numbers) and comment token values. */ function getCommentLineNumbers(comments) { const map = new Map(); diff --git a/lib/rules/new-cap.js b/lib/rules/new-cap.js index 4249a542802..ab3a3674110 100644 --- a/lib/rules/new-cap.js +++ b/lib/rules/new-cap.js @@ -33,7 +33,8 @@ const CAPS_ALLOWED = [ * Ensure that if the key is provided, it must be an array. * @param {Object} obj Object to check with `key`. * @param {string} key Object key to check on `obj`. - * @param {*} fallback If obj[key] is not present, this will be returned. + * @param {any} fallback If obj[key] is not present, this will be returned. + * @throws {TypeError} If key is not an own array type property of `obj`. * @returns {string[]} Returns obj[key] if it's an Array, otherwise `fallback` */ function checkArray(obj, key, fallback) { diff --git a/lib/rules/no-extra-boolean-cast.js b/lib/rules/no-extra-boolean-cast.js index 6ae3ea62ca7..e68f2941eb0 100644 --- a/lib/rules/no-extra-boolean-cast.js +++ b/lib/rules/no-extra-boolean-cast.js @@ -150,6 +150,7 @@ module.exports = { * For example, if the parent is `ConditionalExpression`, `previousNode` must be its `test` child. * @param {ASTNode} previousNode Previous node. * @param {ASTNode} node The node to check. + * @throws {Error} (Unreachable.) * @returns {boolean} `true` if the node needs to be parenthesized. */ function needsParens(previousNode, node) { diff --git a/lib/rules/no-loop-func.js b/lib/rules/no-loop-func.js index 13ebd3ee22b..40d81900f8a 100644 --- a/lib/rules/no-loop-func.js +++ b/lib/rules/no-loop-func.js @@ -174,7 +174,7 @@ module.exports = { * - has a loop node in ancestors. * - has any references which refers to an unsafe variable. * @param {ASTNode} node The AST node to check. - * @returns {boolean} Whether or not the node is within a loop. + * @returns {void} */ function checkForLoops(node) { const loopNode = getContainingLoopNode(node); diff --git a/lib/rules/no-mixed-operators.js b/lib/rules/no-mixed-operators.js index 5a2e139a620..2718e2530c6 100644 --- a/lib/rules/no-mixed-operators.js +++ b/lib/rules/no-mixed-operators.js @@ -58,7 +58,7 @@ function normalizeOptions(options = {}) { /** * Checks whether any group which includes both given operator exists or not. - * @param {Array.} groups A list of groups to check. + * @param {Array} groups A list of groups to check. * @param {string} left An operator. * @param {string} right Another operator. * @returns {boolean} `true` if such group existed. diff --git a/lib/rules/no-undef-init.js b/lib/rules/no-undef-init.js index e23adf34cca..e028fe42832 100644 --- a/lib/rules/no-undef-init.js +++ b/lib/rules/no-undef-init.js @@ -37,6 +37,7 @@ module.exports = { /** * Get the node of init target. * @param {ASTNode} node The node to get. + * @throws {Error} (Unreachable.) * @returns {ASTNode} The node of init target. */ function getIdNode(node) { @@ -53,6 +54,7 @@ module.exports = { /** * Get the node of init value. * @param {ASTNode} node The node to get. + * @throws {Error} (Unreachable.) * @returns {ASTNode} The node of init value. */ function getInitNode(node) { @@ -69,6 +71,7 @@ module.exports = { /** * Get the parent kind of the node. * @param {ASTNode} node The node to get. + * @throws {Error} (Unreachable.) * @returns {string} The parent kind. */ function getParentKind(node) { diff --git a/lib/rules/no-useless-computed-key.js b/lib/rules/no-useless-computed-key.js index a6643061928..cedd2ec242a 100644 --- a/lib/rules/no-useless-computed-key.js +++ b/lib/rules/no-useless-computed-key.js @@ -36,6 +36,7 @@ const astUtils = require("./utils/ast-utils"); * - class C { static ["prototype"]() {} } produces a runtime error (doesn't break the whole script) * class C { static "prototype"() {} } produces a parsing error (breaks the whole script) * @param {ASTNode} node The node to check. It can be `Property`, `PropertyDefinition` or `MethodDefinition`. + * @throws {Error} (Unreachable.) * @returns {void} `true` if the node has useless computed key. */ function hasUselessComputedKey(node) { diff --git a/lib/rules/no-useless-escape.js b/lib/rules/no-useless-escape.js index 436a7531639..4811b40420a 100644 --- a/lib/rules/no-useless-escape.js +++ b/lib/rules/no-useless-escape.js @@ -34,16 +34,17 @@ const REGEX_NON_CHARCLASS_ESCAPES = union(REGEX_GENERAL_ESCAPES, new Set("^/.$*+ * @returns {Object[]} A list of characters, each with info on escaping and whether they're in a character class. * @example * - * parseRegExp('a\\b[cd-]') + * parseRegExp("a\\b[cd-]"); * - * returns: + * // returns: * [ - * {text: 'a', index: 0, escaped: false, inCharClass: false, startsCharClass: false, endsCharClass: false}, - * {text: 'b', index: 2, escaped: true, inCharClass: false, startsCharClass: false, endsCharClass: false}, - * {text: 'c', index: 4, escaped: false, inCharClass: true, startsCharClass: true, endsCharClass: false}, - * {text: 'd', index: 5, escaped: false, inCharClass: true, startsCharClass: false, endsCharClass: false}, - * {text: '-', index: 6, escaped: false, inCharClass: true, startsCharClass: false, endsCharClass: false} - * ] + * { text: "a", index: 0, escaped: false, inCharClass: false, startsCharClass: false, endsCharClass: false }, + * { text: "b", index: 2, escaped: true, inCharClass: false, startsCharClass: false, endsCharClass: false }, + * { text: "c", index: 4, escaped: false, inCharClass: true, startsCharClass: true, endsCharClass: false }, + * { text: "d", index: 5, escaped: false, inCharClass: true, startsCharClass: false, endsCharClass: false }, + * { text: "-", index: 6, escaped: false, inCharClass: true, startsCharClass: false, endsCharClass: false } + * ]; + * */ function parseRegExp(regExpText) { const charList = []; diff --git a/lib/rules/object-shorthand.js b/lib/rules/object-shorthand.js index 3999ff8b99f..020fe49a23f 100644 --- a/lib/rules/object-shorthand.js +++ b/lib/rules/object-shorthand.js @@ -149,7 +149,6 @@ module.exports = { * @param {ASTNode} property Property AST node * @returns {boolean} True if the property can have a shorthand form * @private - * */ function canHaveShorthand(property) { return (property.kind !== "set" && property.kind !== "get" && property.type !== "SpreadElement" && property.type !== "SpreadProperty" && property.type !== "ExperimentalSpreadProperty"); @@ -169,7 +168,6 @@ module.exports = { * @param {ASTNode} property Property AST node * @returns {boolean} True if the property is considered shorthand, false if not. * @private - * */ function isShorthand(property) { @@ -182,7 +180,6 @@ module.exports = { * @param {ASTNode} property Property AST node * @returns {boolean} True if the key and value are named equally, false if not. * @private - * */ function isRedundant(property) { const value = property.value; @@ -202,7 +199,6 @@ module.exports = { * @param {ASTNode} node Property AST node * @param {boolean} checkRedundancy Whether to check longform redundancy * @returns {void} - * */ function checkConsistency(node, checkRedundancy) { diff --git a/lib/rules/padded-blocks.js b/lib/rules/padded-blocks.js index f8b5bd97777..d999704dec4 100644 --- a/lib/rules/padded-blocks.js +++ b/lib/rules/padded-blocks.js @@ -167,6 +167,7 @@ module.exports = { /** * Checks if a node should be padded, according to the rule config. * @param {ASTNode} node The AST node to check. + * @throws {Error} (Unreachable) * @returns {boolean} True if the node should be padded, false otherwise. */ function requirePaddingFor(node) { diff --git a/lib/rules/prefer-arrow-callback.js b/lib/rules/prefer-arrow-callback.js index a01c0340821..599a3266e2d 100644 --- a/lib/rules/prefer-arrow-callback.js +++ b/lib/rules/prefer-arrow-callback.js @@ -60,6 +60,7 @@ function getVariableOfArguments(scope) { /** * Checks whether or not a given node is a callback. * @param {ASTNode} node A node to check. + * @throws {Error} (Unreachable.) * @returns {Object} * {boolean} retv.isCallback - `true` if the node is a callback. * {boolean} retv.isLexicalThis - `true` if the node is with `.bind(this)`. diff --git a/lib/rules/utils/ast-utils.js b/lib/rules/utils/ast-utils.js index abb9c2c7e18..d7f9c9777b7 100644 --- a/lib/rules/utils/ast-utils.js +++ b/lib/rules/utils/ast-utils.js @@ -1288,7 +1288,8 @@ module.exports = { * 5e1_000 // false * 5n // false * 1_000n // false - * '5' // false + * "5" // false + * */ isDecimalInteger(node) { return node.type === "Literal" && typeof node.value === "number" && @@ -1632,7 +1633,7 @@ module.exports = { return sourceCode.getText().slice(leftToken.range[0], rightToken.range[1]); }, - /* + /** * Determine if a node has a possibility to be an Error object * @param {ASTNode} node ASTNode to check * @returns {boolean} True if there is a chance it contains an Error obj diff --git a/lib/rules/utils/lazy-loading-rule-map.js b/lib/rules/utils/lazy-loading-rule-map.js index d426d85c59a..7f116a2684f 100644 --- a/lib/rules/utils/lazy-loading-rule-map.js +++ b/lib/rules/utils/lazy-loading-rule-map.js @@ -14,10 +14,10 @@ const debug = require("debug")("eslint:rules"); * const rules = new LazyLoadingRuleMap([ * ["eqeqeq", () => require("eqeqeq")], * ["semi", () => require("semi")], - * ["no-unused-vars", () => require("no-unused-vars")], - * ]) + * ["no-unused-vars", () => require("no-unused-vars")] + * ]); * - * rules.get("semi") // call `() => require("semi")` here. + * rules.get("semi"); // call `() => require("semi")` here. * * @extends {Map Rule>} */ diff --git a/lib/shared/config-validator.js b/lib/shared/config-validator.js index 928d3ce5650..47353ac4814 100644 --- a/lib/shared/config-validator.js +++ b/lib/shared/config-validator.js @@ -84,6 +84,7 @@ function getRuleOptionsSchema(rule) { /** * Validates a rule's severity and returns the severity value. Throws an error if the severity is invalid. * @param {options} options The given options for the rule. + * @throws {Error} Wrong severity value. * @returns {number|string} The rule's severity value */ function validateRuleSeverity(options) { @@ -102,6 +103,7 @@ function validateRuleSeverity(options) { * Validates the non-severity options passed to a rule, based on its schema. * @param {{create: Function}} rule The rule to validate * @param {Array} localOptions The options for the rule, excluding severity + * @throws {Error} Any rule validation errors. * @returns {void} */ function validateRuleSchema(rule, localOptions) { @@ -132,6 +134,7 @@ function validateRuleSchema(rule, localOptions) { * @param {Array|number} options The given options for the rule. * @param {string|null} source The name of the configuration source to report in any errors. If null or undefined, * no source is prepended to the message. + * @throws {Error} Upon any bad rule configuration. * @returns {void} */ function validateRuleOptions(rule, ruleId, options, source = null) { @@ -156,7 +159,7 @@ function validateRuleOptions(rule, ruleId, options, source = null) { * Validates an environment object * @param {Object} environment The environment config object to validate. * @param {string} source The name of the configuration source to report in any errors. - * @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded environments. + * @param {(envId:string) => Object} [getAdditionalEnv] A map from strings to loaded environments. * @returns {void} */ function validateEnvironment( @@ -185,7 +188,7 @@ function validateEnvironment( * Validates a rules config object * @param {Object} rulesConfig The rules config object to validate. * @param {string} source The name of the configuration source to report in any errors. - * @param {function(ruleId:string): Object} getAdditionalRule A map from strings to loaded rules + * @param {(ruleId:string) => Object} getAdditionalRule A map from strings to loaded rules * @returns {void} */ function validateRules( @@ -229,7 +232,8 @@ function validateGlobals(globalsConfig, source = null) { * Validate `processor` configuration. * @param {string|undefined} processorName The processor name. * @param {string} source The name of config file. - * @param {function(id:string): Processor} getProcessor The getter of defined processors. + * @param {(id:string) => Processor} getProcessor The getter of defined processors. + * @throws {Error} For invalid processor configuration. * @returns {void} */ function validateProcessor(processorName, source, getProcessor) { @@ -268,6 +272,7 @@ function formatErrors(errors) { * Validates the top level properties of the config object. * @param {Object} config The config object to validate. * @param {string} source The name of the configuration source to report in any errors. + * @throws {Error} For any config invalid per the schema. * @returns {void} */ function validateConfigSchema(config, source = null) { @@ -286,8 +291,8 @@ function validateConfigSchema(config, source = null) { * Validates an entire config object. * @param {Object} config The config object to validate. * @param {string} source The name of the configuration source to report in any errors. - * @param {function(ruleId:string): Object} [getAdditionalRule] A map from strings to loaded rules. - * @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded envs. + * @param {(ruleId:string) => Object} [getAdditionalRule] A map from strings to loaded rules. + * @param {(envId:string) => Object} [getAdditionalEnv] A map from strings to loaded envs. * @returns {void} */ function validate(config, source, getAdditionalRule, getAdditionalEnv) { diff --git a/lib/shared/relative-module-resolver.js b/lib/shared/relative-module-resolver.js index fcc2ac41bb3..18a694983c1 100644 --- a/lib/shared/relative-module-resolver.js +++ b/lib/shared/relative-module-resolver.js @@ -26,6 +26,7 @@ module.exports = { * @param {string} moduleName The name of a Node module, or a path to a Node module. * @param {string} relativeToPath An absolute path indicating the module that `moduleName` should be resolved relative to. This must be * a file rather than a directory, but the file need not actually exist. + * @throws {Error} Any error from `module.createRequire` or its `resolve`. * @returns {string} The absolute path that would result from calling `require.resolve(moduleName)` in a file located at `relativeToPath` */ resolve(moduleName, relativeToPath) { diff --git a/lib/shared/runtime-info.js b/lib/shared/runtime-info.js index aa5eff756a8..56c0898be54 100644 --- a/lib/shared/runtime-info.js +++ b/lib/shared/runtime-info.js @@ -40,6 +40,7 @@ function environment() { * Synchronously executes a shell command and formats the result. * @param {string} cmd The command to execute. * @param {Array} args The arguments to be executed with the command. + * @throws {Error} As may be collected by `cross-spawn.sync`. * @returns {string} The version returned by the command. */ function execCommand(cmd, args) { @@ -73,6 +74,7 @@ function environment() { /** * Gets bin version. * @param {string} bin The bin to check. + * @throws {Error} As may be collected by `cross-spawn.sync`. * @returns {string} The normalized version returned by the command. */ function getBinVersion(bin) { @@ -90,6 +92,7 @@ function environment() { * Gets installed npm package version. * @param {string} pkg The package to check. * @param {boolean} global Whether to check globally or not. + * @throws {Error} As may be collected by `cross-spawn.sync`. * @returns {string} The normalized version returned by the command. */ function getNpmPackageVersion(pkg, { global = false } = {}) { diff --git a/lib/source-code/source-code.js b/lib/source-code/source-code.js index cc4524fa74c..82a2b328018 100644 --- a/lib/source-code/source-code.js +++ b/lib/source-code/source-code.js @@ -175,20 +175,20 @@ class SourceCode extends TokenStore { /** * The flag to indicate that the source code has Unicode BOM. - * @type boolean + * @type {boolean} */ this.hasBOM = (text.charCodeAt(0) === 0xFEFF); /** * The original text source code. * BOM was stripped from this text. - * @type string + * @type {string} */ this.text = (this.hasBOM ? text.slice(1) : text); /** * The parsed AST for the source code. - * @type ASTNode + * @type {ASTNode} */ this.ast = ast; @@ -223,7 +223,7 @@ class SourceCode extends TokenStore { /** * The source code split into lines according to ECMA-262 specification. * This is done to avoid each rule needing to do so separately. - * @type string[] + * @type {string[]} */ this.lines = []; this.lineStartIndices = [0]; @@ -506,6 +506,7 @@ class SourceCode extends TokenStore { /** * Converts a source text index into a (line, column) pair. * @param {number} index The index of a character in a file + * @throws {TypeError} If non-numeric index or index out of range. * @returns {Object} A {line, column} location object with a 0-indexed column * @public */ @@ -545,6 +546,9 @@ class SourceCode extends TokenStore { * @param {Object} loc A line/column location * @param {number} loc.line The line number of the location (1-indexed) * @param {number} loc.column The column number of the location (0-indexed) + * @throws {TypeError|RangeError} If `loc` is not an object with a numeric + * `line` and `column`, if the `line` is less than or equal to zero or + * the line or column is out of the expected range. * @returns {number} The range index of the location in the file. * @public */ diff --git a/package.json b/package.json index 16f80b10ab6..bc5bc414594 100644 --- a/package.json +++ b/package.json @@ -99,9 +99,10 @@ "ejs": "^3.0.2", "eslint": "file:.", "eslint-config-eslint": "file:packages/eslint-config-eslint", + "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-eslint-plugin": "^3.5.3", "eslint-plugin-internal-rules": "file:tools/internal-rules", - "eslint-plugin-jsdoc": "^33.3.0", + "eslint-plugin-jsdoc": "^36.0.6", "eslint-plugin-node": "^11.1.0", "eslint-release": "^3.1.2", "eslump": "^3.0.0", diff --git a/packages/eslint-config-eslint/default.yml b/packages/eslint-config-eslint/default.yml index 38061e80155..addce035fe2 100644 --- a/packages/eslint-config-eslint/default.yml +++ b/packages/eslint-config-eslint/default.yml @@ -2,8 +2,8 @@ reportUnusedDisableDirectives: true extends: - "eslint:recommended" - "plugin:node/recommended" -plugins: - - "jsdoc" + - "plugin:jsdoc/recommended" + - "plugin:eslint-comments/recommended" settings: jsdoc: tagNamePreference: @@ -11,7 +11,43 @@ settings: augments: "extends" class: "constructor" preferredTypes: - object: "Object" + "*": + message: "Use a more precise type or if necessary use `any` or `ArbitraryCallbackResult`" + replacement: "any" + Any: + message: "Use a more precise type or if necessary use `any` or `ArbitraryCallbackResult`" + replacement: "any" + # Function: + # message: "Point to a `@callback` namepath or `GenericCallback` if truly arbitrary in form" + # replacement: "GenericCallback" + # function: + # message: "Point to a `@callback` namepath or `GenericCallback` if truly arbitrary in form" + # replacement: "GenericCallback" + function: + message: "Point to a `@callback` namepath or `Function` if truly arbitrary in form" + replacement: "Function" + Promise: + message: "Specify the specific Promise type, including, if necessary, the type `any`" + ".<>": + message: "Prefer type form without dot" + replacement: "<>" + # Object: + # message: "Use the specific object type or `PlainObject` if truly arbitrary" + # replacement: "PlainObject" + # object: + # message: "Use the specific object type or `PlainObject` if truly arbitrary" + # replacement: "PlainObject" + object: + message: "Use the specific object type or `Object` if truly arbitrary" + replacement: "Object" + # Array: + # message: "Use the specific array type or `GenericArray` if it is truly arbitrary." + # replacement: "GenericArray" + # array: + # message: "Use specific array type or `GenericArray` if it is truly arbitrary." + # replacement: "GenericArray" + array: "Array" + rules: array-bracket-spacing: "error" array-callback-return: "error" @@ -36,6 +72,11 @@ rules: dot-notation: ["error", { allowKeywords: true }] eol-last: "error" eqeqeq: "error" + + eslint-comments/disable-enable-pair: ["error"] + eslint-comments/no-unused-disable: "error" + # eslint-comments/require-description: "error" + func-call-spacing: "error" func-style: ["error", "declaration"] function-call-argument-newline: ["error", "consistent"] @@ -43,23 +84,55 @@ rules: generator-star-spacing: "error" grouped-accessor-pairs: "error" guard-for-in: "error" + + # jsdoc: adopt non-recommended rules or change recommended configuration + # jsdoc/check-examples: "error" + # jsdoc/check-indentation: "error" # Revisit if allowing configurable spaces after tag line breaks + # jsdoc/check-line-alignment: ["error", "never"] + jsdoc/check-syntax: "error" + # jsdoc/check-types': ["error', { exemptTagContexts: [ { tag: "typedef", types: ["object", "GenericObject"] } ] } + + jsdoc/check-values: ["error", { allowedLicenses: true }] + jsdoc/newline-after-description: ["error", "never"] + jsdoc/no-bad-blocks: "error" + jsdoc/require-asterisk-prefix: "error" + jsdoc/require-description: "error" + # jsdoc/require-file-overview: "error" + jsdoc/require-hyphen-before-param-description: ["error", "never"] + jsdoc/require-returns: ["error", { forceRequireReturn: true, forceReturnsWithAsync: true }] + jsdoc/require-throws: "error" + jsdoc/tag-lines: ["error", "never", { tags: { example: { lines: "always" }, fileoverview: { lines: "any" } } }] + + # jsdoc: disable recommended rules + jsdoc/no-undefined-types: "off" + jsdoc/require-yields: "off" + + # jsdoc: change recommended rules from warnings into errors + jsdoc/check-access: "error" jsdoc/check-alignment: "error" jsdoc/check-param-names: "error" - jsdoc/check-syntax: "error" + jsdoc/check-property-names: "error" jsdoc/check-tag-names: "error" jsdoc/check-types: "error" + jsdoc/empty-tags: "error" jsdoc/implements-on-classes: "error" - jsdoc/newline-after-description: ["error", "never"] - jsdoc/require-description: "error" - jsdoc/require-hyphen-before-param-description: ["error", "never"] + jsdoc/multiline-blocks: "error" + jsdoc/no-multi-asterisks: "error" jsdoc/require-jsdoc: "error" jsdoc/require-param: "error" jsdoc/require-param-description: "error" jsdoc/require-param-name: "error" jsdoc/require-param-type: "error" - jsdoc/require-returns: ["error", { forceRequireReturn: true, forceReturnsWithAsync: true }] + jsdoc/require-property: "error" + jsdoc/require-property-description: "error" + jsdoc/require-property-name: "error" + jsdoc/require-property-type: "error" + jsdoc/require-returns-check: "error" jsdoc/require-returns-description: "error" jsdoc/require-returns-type: "error" + jsdoc/require-yields-check: "error" + jsdoc/valid-types: "error" + key-spacing: ["error", { beforeColon: false, afterColon: true }] keyword-spacing: "error" lines-around-comment: ["error", { @@ -84,14 +157,11 @@ rules: no-confusing-arrow: "error" no-console: "error" no-constructor-return: "error" - no-delete-var: "error" no-else-return: ["error", { allowElseIf: false }] no-eval: "error" no-extend-native: "error" no-extra-bind: "error" - no-fallthrough: "error" no-floating-decimal: "error" - no-global-assign: "error" no-implied-eval: "error" no-invalid-this: "error" no-iterator: "error" @@ -99,7 +169,7 @@ rules: no-labels: "error" no-lone-blocks: "error" no-loop-func: "error" - no-mixed-spaces-and-tabs: ["error", false] + no-mixed-spaces-and-tabs: ["error", false] # Modified from recommended no-multi-spaces: "error" no-multi-str: "error" no-multiple-empty-lines: ["error", {max: 2, maxBOF: 0, maxEOF: 0}] @@ -108,12 +178,10 @@ rules: no-new-func: "error" no-new-object: "error" no-new-wrappers: "error" - no-octal: "error" no-octal-escape: "error" no-param-reassign: "error" no-proto: "error" no-process-exit: "off" - no-redeclare: "error" no-restricted-properties: [ "error", { property: "substring", message: "Use .slice instead of .substring." }, @@ -125,14 +193,13 @@ rules: ] no-return-assign: "error" no-script-url: "error" - no-self-assign: "error" no-self-compare: "error" no-sequences: "error" no-shadow: "error" no-tabs: "error" no-throw-literal: "error" no-trailing-spaces: "error" - no-undef: ["error", {typeof: true}] + no-undef: ["error", {typeof: true}] # Modified from recommended no-undef-init: "error" no-undefined: "error" no-underscore-dangle: ["error", {allowAfterThis: true}] @@ -140,24 +207,24 @@ rules: no-unneeded-ternary: "error" no-unreachable-loop: "error" no-unused-expressions: "error" - no-unused-vars: ["error", {vars: "all", args: "after-used", caughtErrors: "all"}] + no-unused-vars: ["error", {vars: "all", args: "after-used", caughtErrors: "all"}] # Modified from recommended no-use-before-define: "error" no-useless-call: "error" no-useless-computed-key: "error" no-useless-concat: "error" no-useless-constructor: "error" - no-useless-escape: "error" no-useless-rename: "error" no-useless-return: "error" no-whitespace-before-property: "error" no-var: "error" + node/callback-return: ["error", ["cb", "callback", "next"]] node/handle-callback-err: ["error", "err"] node/no-deprecated-api: "error" node/no-mixed-requires: "error" node/no-new-require: "error" node/no-path-concat: "error" - node/no-process-exit: "error" + object-curly-newline: ["error", { "consistent": true, "multiline": true }] object-curly-spacing: ["error", "always"] object-property-newline: ["error", { "allowAllPropertiesOnSameLine": true }] diff --git a/packages/eslint-config-eslint/package.json b/packages/eslint-config-eslint/package.json index a695451ea87..faa9f4a7188 100644 --- a/packages/eslint-config-eslint/package.json +++ b/packages/eslint-config-eslint/package.json @@ -20,7 +20,8 @@ "homepage": "https://eslint.org", "bugs": "https://github.com/eslint/eslint/issues/", "peerDependencies": { - "eslint-plugin-jsdoc": ">=22.1.0", + "eslint-plugin-eslint-comments": ">=3.2.0", + "eslint-plugin-jsdoc": ">=36.0.6", "eslint-plugin-node": ">=11.1.0" }, "keywords": [ diff --git a/tests/bin/eslint.js b/tests/bin/eslint.js index 4fed66aedd7..c9dbb3fdbe3 100644 --- a/tests/bin/eslint.js +++ b/tests/bin/eslint.js @@ -25,7 +25,7 @@ function awaitExit(exitingProcess) { * Asserts that the exit code of a given child process will equal the given value. * @param {ChildProcess} exitingProcess The child process * @param {number} expectedExitCode The expected exit code of the child process - * @returns {Promise} A Promise that fulfills if the exit code ends up matching, and rejects otherwise. + * @returns {Promise} A Promise that fulfills if the exit code ends up matching, and rejects otherwise. */ function assertExitCode(exitingProcess, expectedExitCode) { return awaitExit(exitingProcess).then(exitCode => { diff --git a/tests/lib/cli-engine/cli-engine.js b/tests/lib/cli-engine/cli-engine.js index 431437e4fd1..ea10362d1a5 100644 --- a/tests/lib/cli-engine/cli-engine.js +++ b/tests/lib/cli-engine/cli-engine.js @@ -44,10 +44,10 @@ describe("CLIEngine", () => { originalDir = process.cwd(), fixtureDir = path.resolve(fs.realpathSync(os.tmpdir()), "eslint/fixtures"); - /** @type {import("../../../lib/cli-engine")["CLIEngine"]} */ + /** @type {import("../../../lib/cli-engine").CLIEngine} */ let CLIEngine; - /** @type {import("../../../lib/cli-engine/cli-engine")["getCLIEngineInternalSlots"]} */ + /** @type {import("../../../lib/cli-engine/cli-engine").getCLIEngineInternalSlots} */ let getCLIEngineInternalSlots; /** @@ -792,7 +792,7 @@ describe("CLIEngine", () => { describe("executeOnFiles()", () => { - /** @type {InstanceType} */ + /** @type {InstanceType} */ let engine; it("should use correct parser when custom parser is specified", () => { diff --git a/tests/lib/cli-engine/file-enumerator.js b/tests/lib/cli-engine/file-enumerator.js index a2ad62e4e27..bea27415f28 100644 --- a/tests/lib/cli-engine/file-enumerator.js +++ b/tests/lib/cli-engine/file-enumerator.js @@ -57,7 +57,7 @@ describe("FileEnumerator", () => { describe("if 'lib/*.js' was given,", () => { - /** @type {Array<{config:(typeof import('../../../lib/cli-engine'))["ConfigArray"], filePath:string, ignored:boolean}>} */ + /** @type {Array<{config:(typeof import('../../../lib/cli-engine')).ConfigArray, filePath:string, ignored:boolean}>} */ let list; beforeEach(() => { @@ -89,7 +89,7 @@ describe("FileEnumerator", () => { describe("if 'lib/**/*.js' was given,", () => { - /** @type {Array<{config:(typeof import('../../../lib/cli-engine'))["ConfigArray"], filePath:string, ignored:boolean}>} */ + /** @type {Array<{config:(typeof import('../../../lib/cli-engine')).ConfigArray, filePath:string, ignored:boolean}>} */ let list; beforeEach(() => { @@ -132,7 +132,7 @@ describe("FileEnumerator", () => { describe("if 'lib/*.js' and 'test/*.js' were given,", () => { - /** @type {Array<{config:(typeof import('../../../lib/cli-engine'))["ConfigArray"], filePath:string, ignored:boolean}>} */ + /** @type {Array<{config:(typeof import('../../../lib/cli-engine')).ConfigArray, filePath:string, ignored:boolean}>} */ let list; beforeEach(() => { diff --git a/tests/lib/eslint/eslint.js b/tests/lib/eslint/eslint.js index a5e342f0dca..3ff9707b173 100644 --- a/tests/lib/eslint/eslint.js +++ b/tests/lib/eslint/eslint.js @@ -45,7 +45,7 @@ describe("ESLint", () => { const originalDir = process.cwd(); const fixtureDir = path.resolve(fs.realpathSync(os.tmpdir()), "eslint/fixtures"); - /** @type {import("../../../lib/eslint")["ESLint"]} */ + /** @type {import("../../../lib/eslint").ESLint} */ let ESLint; /** @@ -872,7 +872,7 @@ describe("ESLint", () => { describe("lintFiles()", () => { - /** @type {InstanceType} */ + /** @type {InstanceType} */ let eslint; it("should use correct parser when custom parser is specified", async () => { diff --git a/tests/lib/linter/linter.js b/tests/lib/linter/linter.js index 0da677d943f..a542cbd86f0 100644 --- a/tests/lib/linter/linter.js +++ b/tests/lib/linter/linter.js @@ -55,7 +55,7 @@ const ESLINT_ENV = "eslint-env"; describe("Linter", () => { const filename = "filename.js"; - /** @type {InstanceType} */ + /** @type {InstanceType} */ let linter; beforeEach(() => { diff --git a/tests/lib/rule-tester/no-test-runners.js b/tests/lib/rule-tester/no-test-runners.js index d6b26d34fad..f40bdfde992 100644 --- a/tests/lib/rule-tester/no-test-runners.js +++ b/tests/lib/rule-tester/no-test-runners.js @@ -1,10 +1,10 @@ +/* eslint no-global-assign: off*/ /** * @fileoverview Tests for RuleTester without any test runner * @author Weijia Wang */ "use strict"; -/* eslint-disable no-global-assign*/ const assert = require("assert"); const { RuleTester } = require("../../../lib/rule-tester"); const tmpIt = it; diff --git a/tests/lib/rule-tester/rule-tester.js b/tests/lib/rule-tester/rule-tester.js index 43f078e90de..5bc4b1f62c3 100644 --- a/tests/lib/rule-tester/rule-tester.js +++ b/tests/lib/rule-tester/rule-tester.js @@ -2298,8 +2298,8 @@ describe("RuleTester", () => { * Asserts that a particular value will be emitted from an EventEmitter. * @param {EventEmitter} emitter The emitter that should emit a value * @param {string} emitType The type of emission to listen for - * @param {*} expectedValue The value that should be emitted - * @returns {Promise} A Promise that fulfills if the value is emitted, and rejects if something else is emitted. + * @param {any} expectedValue The value that should be emitted + * @returns {Promise} A Promise that fulfills if the value is emitted, and rejects if something else is emitted. * The Promise will be indefinitely pending if no value is emitted. */ function assertEmitted(emitter, emitType, expectedValue) { diff --git a/tests/lib/rules/utils/ast-utils.js b/tests/lib/rules/utils/ast-utils.js index 7e1365aa7e5..9ebcace8ec7 100644 --- a/tests/lib/rules/utils/ast-utils.js +++ b/tests/lib/rules/utils/ast-utils.js @@ -185,7 +185,6 @@ describe("ast-utils", () => { * Asserts the node is NOT a directive comment * @param {ASTNode} node node to assert * @returns {void} - * */ function assertFalse(node) { assert.isFalse(astUtils.isDirectiveComment(node)); @@ -195,7 +194,6 @@ describe("ast-utils", () => { * Asserts the node is a directive comment * @param {ASTNode} node node to assert * @returns {void} - * */ function assertTrue(node) { assert.isTrue(astUtils.isDirectiveComment(node)); diff --git a/tools/eslint-fuzzer.js b/tools/eslint-fuzzer.js index c9705200eaf..6c5ed9b1bcb 100644 --- a/tools/eslint-fuzzer.js +++ b/tools/eslint-fuzzer.js @@ -43,7 +43,7 @@ function sample(array) { * might also be passed other keys. * @param {boolean} [options.checkAutofixes=true] `true` if the fuzzer should check for autofix bugs. The fuzzer runs * roughly 4 times slower with autofix checking enabled. - * @param {function(number)} [options.progressCallback] A function that gets called once for each code sample, with the total number of errors found so far + * @param {function(number) : void} [options.progressCallback] A function that gets called once for each code sample, with the total number of errors found so far * @returns {Object[]} A list of problems found. Each problem has the following properties: * type (string): The type of problem. This is either "crash" (a rule crashes) or "autofix" (an autofix produces a syntax error) * text (string): The text that ESLint should be run on to reproduce the problem