diff options
Diffstat (limited to 'tools/node_modules/eslint/lib/linter/linter.js')
-rw-r--r-- | tools/node_modules/eslint/lib/linter/linter.js | 216 |
1 files changed, 121 insertions, 95 deletions
diff --git a/tools/node_modules/eslint/lib/linter/linter.js b/tools/node_modules/eslint/lib/linter/linter.js index 534181da9e..6d88cb5aa1 100644 --- a/tools/node_modules/eslint/lib/linter/linter.js +++ b/tools/node_modules/eslint/lib/linter/linter.js @@ -292,10 +292,15 @@ function getDirectiveComments(filename, ast, ruleMapper, warnInlineConfig) { if (!match) { return; } - const lineCommentSupported = /^eslint-disable-(next-)?line$/u.test(match[1]); + const directiveText = match[1]; + const lineCommentSupported = /^eslint-disable-(next-)?line$/u.test(directiveText); - if (warnInlineConfig && (lineCommentSupported || comment.type === "Block")) { - const kind = comment.type === "Block" ? `/*${match[1]}*/` : `//${match[1]}`; + if (comment.type === "Line" && !lineCommentSupported) { + return; + } + + if (warnInlineConfig) { + const kind = comment.type === "Block" ? `/*${directiveText}*/` : `//${directiveText}`; problems.push(createLintingProblem({ ruleId: null, @@ -306,108 +311,101 @@ function getDirectiveComments(filename, ast, ruleMapper, warnInlineConfig) { return; } - const directiveValue = trimmedCommentText.slice(match.index + match[1].length); - let directiveType = ""; + if (lineCommentSupported && comment.loc.start.line !== comment.loc.end.line) { + const message = `${directiveText} comment should not span multiple lines.`; - if (lineCommentSupported) { - if (comment.loc.start.line === comment.loc.end.line) { - directiveType = match[1].slice("eslint-".length); - } else { - const message = `${match[1]} comment should not span multiple lines.`; + problems.push(createLintingProblem({ + ruleId: null, + message, + loc: comment.loc + })); + return; + } - problems.push(createLintingProblem({ - ruleId: null, - message, - loc: comment.loc - })); + const directiveValue = trimmedCommentText.slice(match.index + directiveText.length); + + switch (directiveText) { + case "eslint-disable": + case "eslint-enable": + case "eslint-disable-next-line": + case "eslint-disable-line": { + const directiveType = directiveText.slice("eslint-".length); + const options = { type: directiveType, loc: comment.loc, value: directiveValue, ruleMapper }; + const { directives, directiveProblems } = createDisableDirectives(options); + + disableDirectives.push(...directives); + problems.push(...directiveProblems); + break; } - } else if (comment.type === "Block") { - switch (match[1]) { - case "exported": - Object.assign(exportedVariables, commentParser.parseStringConfig(directiveValue, comment)); - break; - case "globals": - case "global": - for (const [id, { value }] of Object.entries(commentParser.parseStringConfig(directiveValue, comment))) { - let normalizedValue; + case "exported": + Object.assign(exportedVariables, commentParser.parseStringConfig(directiveValue, comment)); + break; + + case "globals": + case "global": + for (const [id, { value }] of Object.entries(commentParser.parseStringConfig(directiveValue, comment))) { + let normalizedValue; + + try { + normalizedValue = ConfigOps.normalizeConfigGlobal(value); + } catch (err) { + problems.push(createLintingProblem({ + ruleId: null, + loc: comment.loc, + message: err.message + })); + continue; + } + + if (enabledGlobals[id]) { + enabledGlobals[id].comments.push(comment); + enabledGlobals[id].value = normalizedValue; + } else { + enabledGlobals[id] = { + comments: [comment], + value: normalizedValue + }; + } + } + break; + + case "eslint": { + const parseResult = commentParser.parseJsonConfig(directiveValue, comment.loc); + + if (parseResult.success) { + Object.keys(parseResult.config).forEach(name => { + const rule = ruleMapper(name); + const ruleValue = parseResult.config[name]; + + if (rule === null) { + problems.push(createLintingProblem({ ruleId: name, loc: comment.loc })); + return; + } try { - normalizedValue = ConfigOps.normalizeConfigGlobal(value); + validator.validateRuleOptions(rule, name, ruleValue); } catch (err) { problems.push(createLintingProblem({ - ruleId: null, - loc: comment.loc, - message: err.message + ruleId: name, + message: err.message, + loc: comment.loc })); - continue; - } - if (enabledGlobals[id]) { - enabledGlobals[id].comments.push(comment); - enabledGlobals[id].value = normalizedValue; - } else { - enabledGlobals[id] = { - comments: [comment], - value: normalizedValue - }; + // do not apply the config, if found invalid options. + return; } - } - break; - - case "eslint-disable": - directiveType = "disable"; - break; - - case "eslint-enable": - directiveType = "enable"; - break; - - case "eslint": { - const parseResult = commentParser.parseJsonConfig(directiveValue, comment.loc); - - if (parseResult.success) { - Object.keys(parseResult.config).forEach(name => { - const rule = ruleMapper(name); - const ruleValue = parseResult.config[name]; - - if (rule === null) { - problems.push(createLintingProblem({ ruleId: name, loc: comment.loc })); - return; - } - - try { - validator.validateRuleOptions(rule, name, ruleValue); - } catch (err) { - problems.push(createLintingProblem({ - ruleId: name, - message: err.message, - loc: comment.loc - })); - - // do not apply the config, if found invalid options. - return; - } - - configuredRules[name] = ruleValue; - }); - } else { - problems.push(parseResult.error); - } - break; + configuredRules[name] = ruleValue; + }); + } else { + problems.push(parseResult.error); } - // no default + break; } - } - - if (directiveType !== "") { - const options = { type: directiveType, loc: comment.loc, value: directiveValue, ruleMapper }; - const { directives, directiveProblems } = createDisableDirectives(options); - disableDirectives.push(...directives); - problems.push(...directiveProblems); + // no default } }); @@ -438,7 +436,7 @@ const eslintEnvPattern = /\/\*\s*eslint-env\s(.+?)\*\//gu; /** * Checks whether or not there is a comment which has "eslint-env *" in a given text. - * @param {string} text - A source code text to check. + * @param {string} text A source code text to check. * @returns {Object|null} A result of parseListConfig() with "eslint-env *" comment. */ function findEslintEnv(text) { @@ -555,8 +553,7 @@ function resolveGlobals(providedGlobals, enabledEnvironments) { /** * Strips Unicode BOM from a given text. - * - * @param {string} text - A text to strip. + * @param {string} text A text to strip. * @returns {string} The stripped text. */ function stripUnicodeBOM(text) { @@ -669,6 +666,8 @@ function parse(text, parser, providedParserOptions, filePath) { // If the message includes a leading line number, strip it: const message = `Parsing error: ${ex.message.replace(/^line \d+:/iu, "").trim()}`; + debug("%s\n%s", message, ex.stack); + return { success: false, error: { @@ -813,9 +812,10 @@ const BASE_TRAVERSAL_CONTEXT = Object.freeze( * @param {Object} settings The settings that were enabled in the config * @param {string} filename The reported filename of the code * @param {boolean} disableFixes If true, it doesn't make `fix` properties. + * @param {string | undefined} cwd cwd of the cli * @returns {Problem[]} An array of reported problems */ -function runRules(sourceCode, configuredRules, ruleMapper, parserOptions, parserName, settings, filename, disableFixes) { +function runRules(sourceCode, configuredRules, ruleMapper, parserOptions, parserName, settings, filename, disableFixes, cwd) { const emitter = createEmitter(); const nodeQueue = []; let currentNode = sourceCode.ast; @@ -842,6 +842,7 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserOptions, parser { getAncestors: () => getAncestors(currentNode), getDeclaredVariables: sourceCode.scopeManager.getDeclaredVariables.bind(sourceCode.scopeManager), + getCwd: () => cwd, getFilename: () => filename, getScope: () => getScope(sourceCode.scopeManager, currentNode), getSourceCode: () => sourceCode, @@ -989,6 +990,24 @@ function getRule(slots, ruleId) { } /** + * Normalize the value of the cwd + * @param {string | undefined} cwd raw value of the cwd, path to a directory that should be considered as the current working directory, can be undefined. + * @returns {string | undefined} normalized cwd + */ +function normalizeCwd(cwd) { + if (cwd) { + return cwd; + } + if (typeof process === "object") { + return process.cwd(); + } + + // It's more explicit to assign the undefined + // eslint-disable-next-line no-undefined + return undefined; +} + +/** * The map to store private data. * @type {WeakMap<Linter, LinterInternalSlots>} */ @@ -1004,8 +1023,14 @@ const internalSlotsMap = new WeakMap(); */ class Linter { - constructor() { + /** + * Initialize the Linter. + * @param {Object} [config] the config object + * @param {string} [config.cwd] path to a directory that should be considered as the current working directory, can be undefined. + */ + constructor({ cwd } = {}) { internalSlotsMap.set(this, { + cwd: normalizeCwd(cwd), lastConfigArray: null, lastSourceCode: null, parserMap: new Map([["espree", espree]]), @@ -1137,7 +1162,8 @@ class Linter { parserName, settings, options.filename, - options.disableFixes + options.disableFixes, + slots.cwd ); } catch (err) { err.message += `\nOccurred while linting ${options.filename}`; |