tools: update ESLint to 4.19.1
A few bug fixes result in more stringent linting rules. PR-URL: https://github.com/nodejs/node/pull/19528 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
5e00a013eb
commit
0863a0e528
4
tools/node_modules/eslint/README.md
generated
vendored
4
tools/node_modules/eslint/README.md
generated
vendored
@ -227,9 +227,9 @@ In all cases, make sure your plugins' peerDependencies have been installed as we
|
||||
|
||||
Yes, ESLint natively supports parsing JSX syntax (this must be enabled in [configuration](https://eslint.org/docs/user-guide/configuring)). Please note that supporting JSX syntax *is not* the same as supporting React. React applies specific semantics to JSX syntax that ESLint doesn't recognize. We recommend using [eslint-plugin-react](https://www.npmjs.com/package/eslint-plugin-react) if you are using React and want React semantics.
|
||||
|
||||
### What about ECMAScript 6 support?
|
||||
### What ECMAScript versions does ESLint support?
|
||||
|
||||
ESLint has full support for ECMAScript 6. By default, this support is off. You can enable ECMAScript 6 syntax and global variables through [configuration](https://eslint.org/docs/user-guide/configuring).
|
||||
ESLint has full support for ECMAScript 3, 5 (default), 2015, 2016, 2017, and 2018. You can set your desired ECMAScript syntax (and other settings, like global variables or your target environments) through [configuration](https://eslint.org/docs/user-guide/configuring).
|
||||
|
||||
### What about experimental features?
|
||||
|
||||
|
29
tools/node_modules/eslint/conf/default-config-options.js
generated
vendored
29
tools/node_modules/eslint/conf/default-config-options.js
generated
vendored
@ -1,29 +0,0 @@
|
||||
/**
|
||||
* @fileoverview Default config options
|
||||
* @author Teddy Katz
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Freezes an object and all its nested properties
|
||||
* @param {Object} obj The object to deeply freeze
|
||||
* @returns {Object} `obj` after freezing it
|
||||
*/
|
||||
function deepFreeze(obj) {
|
||||
if (obj === null || typeof obj !== "object") {
|
||||
return obj;
|
||||
}
|
||||
|
||||
Object.keys(obj).map(key => obj[key]).forEach(deepFreeze);
|
||||
return Object.freeze(obj);
|
||||
}
|
||||
|
||||
module.exports = deepFreeze({
|
||||
env: {},
|
||||
globals: {},
|
||||
rules: {},
|
||||
settings: {},
|
||||
parser: "espree",
|
||||
parserOptions: {}
|
||||
});
|
4
tools/node_modules/eslint/conf/environments.js
generated
vendored
4
tools/node_modules/eslint/conf/environments.js
generated
vendored
@ -15,7 +15,9 @@ const globals = require("globals");
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
module.exports = {
|
||||
builtin: globals.es5,
|
||||
builtin: {
|
||||
globals: globals.es5
|
||||
},
|
||||
browser: {
|
||||
|
||||
/*
|
||||
|
0
tools/node_modules/eslint/conf/eslint-recommended.js
generated
vendored
Executable file → Normal file
0
tools/node_modules/eslint/conf/eslint-recommended.js
generated
vendored
Executable file → Normal file
54
tools/node_modules/eslint/lib/ast-utils.js
generated
vendored
54
tools/node_modules/eslint/lib/ast-utils.js
generated
vendored
@ -84,11 +84,10 @@ function isES5Constructor(node) {
|
||||
* @returns {Node|null} A found function node.
|
||||
*/
|
||||
function getUpperFunction(node) {
|
||||
while (node) {
|
||||
if (anyFunctionPattern.test(node.type)) {
|
||||
return node;
|
||||
for (let currentNode = node; currentNode; currentNode = currentNode.parent) {
|
||||
if (anyFunctionPattern.test(currentNode.type)) {
|
||||
return currentNode;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -132,12 +131,10 @@ function isLoop(node) {
|
||||
* @returns {boolean} `true` if the node is in a loop.
|
||||
*/
|
||||
function isInLoop(node) {
|
||||
while (node && !isFunction(node)) {
|
||||
if (isLoop(node)) {
|
||||
for (let currentNode = node; currentNode && !isFunction(currentNode); currentNode = currentNode.parent) {
|
||||
if (isLoop(currentNode)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -204,16 +201,14 @@ function isArrayFromMethod(node) {
|
||||
* @returns {boolean} Whether or not the node is a method which has `thisArg`.
|
||||
*/
|
||||
function isMethodWhichHasThisArg(node) {
|
||||
while (node) {
|
||||
if (node.type === "Identifier") {
|
||||
return arrayMethodPattern.test(node.name);
|
||||
for (
|
||||
let currentNode = node;
|
||||
currentNode.type === "MemberExpression" && !currentNode.computed;
|
||||
currentNode = currentNode.property
|
||||
) {
|
||||
if (currentNode.property.type === "Identifier") {
|
||||
return arrayMethodPattern.test(currentNode.property.name);
|
||||
}
|
||||
if (node.type === "MemberExpression" && !node.computed) {
|
||||
node = node.property;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -631,9 +626,10 @@ module.exports = {
|
||||
return false;
|
||||
}
|
||||
const isAnonymous = node.id === null;
|
||||
let currentNode = node;
|
||||
|
||||
while (node) {
|
||||
const parent = node.parent;
|
||||
while (currentNode) {
|
||||
const parent = currentNode.parent;
|
||||
|
||||
switch (parent.type) {
|
||||
|
||||
@ -643,7 +639,7 @@ module.exports = {
|
||||
*/
|
||||
case "LogicalExpression":
|
||||
case "ConditionalExpression":
|
||||
node = parent;
|
||||
currentNode = parent;
|
||||
break;
|
||||
|
||||
/*
|
||||
@ -663,14 +659,14 @@ module.exports = {
|
||||
if (func === null || !isCallee(func)) {
|
||||
return true;
|
||||
}
|
||||
node = func.parent;
|
||||
currentNode = func.parent;
|
||||
break;
|
||||
}
|
||||
case "ArrowFunctionExpression":
|
||||
if (node !== parent.body || !isCallee(parent)) {
|
||||
if (currentNode !== parent.body || !isCallee(parent)) {
|
||||
return true;
|
||||
}
|
||||
node = parent.parent;
|
||||
currentNode = parent.parent;
|
||||
break;
|
||||
|
||||
/*
|
||||
@ -685,7 +681,7 @@ module.exports = {
|
||||
*/
|
||||
case "Property":
|
||||
case "MethodDefinition":
|
||||
return parent.value !== node;
|
||||
return parent.value !== currentNode;
|
||||
|
||||
/*
|
||||
* e.g.
|
||||
@ -715,7 +711,7 @@ module.exports = {
|
||||
case "VariableDeclarator":
|
||||
return !(
|
||||
isAnonymous &&
|
||||
parent.init === node &&
|
||||
parent.init === currentNode &&
|
||||
parent.id.type === "Identifier" &&
|
||||
startsWithUpperCase(parent.id.name)
|
||||
);
|
||||
@ -728,7 +724,7 @@ module.exports = {
|
||||
*/
|
||||
case "MemberExpression":
|
||||
return (
|
||||
parent.object !== node ||
|
||||
parent.object !== currentNode ||
|
||||
parent.property.type !== "Identifier" ||
|
||||
!bindOrCallOrApplyPattern.test(parent.property.name) ||
|
||||
!isCallee(parent) ||
|
||||
@ -746,21 +742,21 @@ module.exports = {
|
||||
if (isReflectApply(parent.callee)) {
|
||||
return (
|
||||
parent.arguments.length !== 3 ||
|
||||
parent.arguments[0] !== node ||
|
||||
parent.arguments[0] !== currentNode ||
|
||||
isNullOrUndefined(parent.arguments[1])
|
||||
);
|
||||
}
|
||||
if (isArrayFromMethod(parent.callee)) {
|
||||
return (
|
||||
parent.arguments.length !== 3 ||
|
||||
parent.arguments[1] !== node ||
|
||||
parent.arguments[1] !== currentNode ||
|
||||
isNullOrUndefined(parent.arguments[2])
|
||||
);
|
||||
}
|
||||
if (isMethodWhichHasThisArg(parent.callee)) {
|
||||
return (
|
||||
parent.arguments.length !== 2 ||
|
||||
parent.arguments[0] !== node ||
|
||||
parent.arguments[0] !== currentNode ||
|
||||
isNullOrUndefined(parent.arguments[1])
|
||||
);
|
||||
}
|
||||
|
57
tools/node_modules/eslint/lib/cli-engine.js
generated
vendored
57
tools/node_modules/eslint/lib/cli-engine.js
generated
vendored
@ -157,8 +157,9 @@ function processText(text, configHelper, filename, fix, allowInlineConfig, repor
|
||||
fileExtension = path.extname(filename);
|
||||
}
|
||||
|
||||
filename = filename || "<text>";
|
||||
debug(`Linting ${filename}`);
|
||||
const effectiveFilename = filename || "<text>";
|
||||
|
||||
debug(`Linting ${effectiveFilename}`);
|
||||
const config = configHelper.getConfig(filePath);
|
||||
|
||||
if (config.plugins) {
|
||||
@ -177,18 +178,18 @@ function processText(text, configHelper, filename, fix, allowInlineConfig, repor
|
||||
const autofixingEnabled = typeof fix !== "undefined" && (!processor || processor.supportsAutofix);
|
||||
|
||||
const fixedResult = linter.verifyAndFix(text, config, {
|
||||
filename,
|
||||
filename: effectiveFilename,
|
||||
allowInlineConfig,
|
||||
reportUnusedDisableDirectives,
|
||||
fix: !!autofixingEnabled && fix,
|
||||
preprocess: processor && (rawText => processor.preprocess(rawText, filename)),
|
||||
postprocess: processor && (problemLists => processor.postprocess(problemLists, filename))
|
||||
preprocess: processor && (rawText => processor.preprocess(rawText, effectiveFilename)),
|
||||
postprocess: processor && (problemLists => processor.postprocess(problemLists, effectiveFilename))
|
||||
});
|
||||
|
||||
const stats = calculateStatsPerFile(fixedResult.messages);
|
||||
|
||||
const result = {
|
||||
filePath: filename,
|
||||
filePath: effectiveFilename,
|
||||
messages: fixedResult.messages,
|
||||
errorCount: stats.errorCount,
|
||||
warningCount: stats.warningCount,
|
||||
@ -302,10 +303,10 @@ function getCacheFile(cacheFile, cwd) {
|
||||
* make sure the path separators are normalized for the environment/os
|
||||
* keeping the trailing path separator if present
|
||||
*/
|
||||
cacheFile = path.normalize(cacheFile);
|
||||
const normalizedCacheFile = path.normalize(cacheFile);
|
||||
|
||||
const resolvedCacheFile = path.resolve(cwd, cacheFile);
|
||||
const looksLikeADirectory = cacheFile[cacheFile.length - 1] === path.sep;
|
||||
const resolvedCacheFile = path.resolve(cwd, normalizedCacheFile);
|
||||
const looksLikeADirectory = normalizedCacheFile.slice(-1) === path.sep;
|
||||
|
||||
/**
|
||||
* return the name for the cache file in case the provided parameter is a directory
|
||||
@ -368,16 +369,16 @@ class CLIEngine {
|
||||
|
||||
/**
|
||||
* Creates a new instance of the core CLI engine.
|
||||
* @param {CLIEngineOptions} options The options for this instance.
|
||||
* @param {CLIEngineOptions} providedOptions The options for this instance.
|
||||
* @constructor
|
||||
*/
|
||||
constructor(options) {
|
||||
constructor(providedOptions) {
|
||||
|
||||
options = Object.assign(
|
||||
const options = Object.assign(
|
||||
Object.create(null),
|
||||
defaultOptions,
|
||||
{ cwd: process.cwd() },
|
||||
options
|
||||
providedOptions
|
||||
);
|
||||
|
||||
/**
|
||||
@ -605,20 +606,21 @@ class CLIEngine {
|
||||
ignoredPaths = new IgnoredPaths(options);
|
||||
|
||||
// resolve filename based on options.cwd (for reporting, ignoredPaths also resolves)
|
||||
if (filename && !path.isAbsolute(filename)) {
|
||||
filename = path.resolve(options.cwd, filename);
|
||||
}
|
||||
|
||||
if (filename && ignoredPaths.contains(filename)) {
|
||||
const resolvedFilename = filename && !path.isAbsolute(filename)
|
||||
? path.resolve(options.cwd, filename)
|
||||
: filename;
|
||||
|
||||
if (resolvedFilename && ignoredPaths.contains(resolvedFilename)) {
|
||||
if (warnIgnored) {
|
||||
results.push(createIgnoreResult(filename, options.cwd));
|
||||
results.push(createIgnoreResult(resolvedFilename, options.cwd));
|
||||
}
|
||||
} else {
|
||||
results.push(
|
||||
processText(
|
||||
text,
|
||||
configHelper,
|
||||
filename,
|
||||
resolvedFilename,
|
||||
options.fix,
|
||||
options.allowInlineConfig,
|
||||
options.reportUnusedDisableDirectives,
|
||||
@ -672,31 +674,30 @@ class CLIEngine {
|
||||
*/
|
||||
getFormatter(format) {
|
||||
|
||||
|
||||
// default is stylish
|
||||
format = format || "stylish";
|
||||
const resolvedFormatName = format || "stylish";
|
||||
|
||||
// only strings are valid formatters
|
||||
if (typeof format === "string") {
|
||||
if (typeof resolvedFormatName === "string") {
|
||||
|
||||
// replace \ with / for Windows compatibility
|
||||
format = format.replace(/\\/g, "/");
|
||||
const normalizedFormatName = resolvedFormatName.replace(/\\/g, "/");
|
||||
|
||||
const cwd = this.options ? this.options.cwd : process.cwd();
|
||||
const namespace = naming.getNamespaceFromTerm(format);
|
||||
const namespace = naming.getNamespaceFromTerm(normalizedFormatName);
|
||||
|
||||
let formatterPath;
|
||||
|
||||
// if there's a slash, then it's a file
|
||||
if (!namespace && format.indexOf("/") > -1) {
|
||||
formatterPath = path.resolve(cwd, format);
|
||||
if (!namespace && normalizedFormatName.indexOf("/") > -1) {
|
||||
formatterPath = path.resolve(cwd, normalizedFormatName);
|
||||
} else {
|
||||
try {
|
||||
const npmFormat = naming.normalizePackageName(format, "eslint-formatter");
|
||||
const npmFormat = naming.normalizePackageName(normalizedFormatName, "eslint-formatter");
|
||||
|
||||
formatterPath = resolver.resolve(npmFormat, `${cwd}/node_modules`);
|
||||
} catch (e) {
|
||||
formatterPath = `./formatters/${format}`;
|
||||
formatterPath = `./formatters/${normalizedFormatName}`;
|
||||
}
|
||||
}
|
||||
|
||||
|
10
tools/node_modules/eslint/lib/code-path-analysis/code-path-state.js
generated
vendored
10
tools/node_modules/eslint/lib/code-path-analysis/code-path-state.js
generated
vendored
@ -164,13 +164,13 @@ function removeConnection(prevSegments, nextSegments) {
|
||||
* Creates looping path.
|
||||
*
|
||||
* @param {CodePathState} state - The instance.
|
||||
* @param {CodePathSegment[]} fromSegments - Segments which are source.
|
||||
* @param {CodePathSegment[]} toSegments - Segments which are destination.
|
||||
* @param {CodePathSegment[]} unflattenedFromSegments - Segments which are source.
|
||||
* @param {CodePathSegment[]} unflattenedToSegments - Segments which are destination.
|
||||
* @returns {void}
|
||||
*/
|
||||
function makeLooped(state, fromSegments, toSegments) {
|
||||
fromSegments = CodePathSegment.flattenUnusedSegments(fromSegments);
|
||||
toSegments = CodePathSegment.flattenUnusedSegments(toSegments);
|
||||
function makeLooped(state, unflattenedFromSegments, unflattenedToSegments) {
|
||||
const fromSegments = CodePathSegment.flattenUnusedSegments(unflattenedFromSegments);
|
||||
const toSegments = CodePathSegment.flattenUnusedSegments(unflattenedToSegments);
|
||||
|
||||
const end = Math.min(fromSegments.length, toSegments.length);
|
||||
|
||||
|
17
tools/node_modules/eslint/lib/code-path-analysis/code-path.js
generated
vendored
17
tools/node_modules/eslint/lib/code-path-analysis/code-path.js
generated
vendored
@ -134,14 +134,19 @@ class CodePath {
|
||||
* @returns {void}
|
||||
*/
|
||||
traverseSegments(options, callback) {
|
||||
let resolvedOptions;
|
||||
let resolvedCallback;
|
||||
|
||||
if (typeof options === "function") {
|
||||
callback = options;
|
||||
options = null;
|
||||
resolvedCallback = options;
|
||||
resolvedOptions = {};
|
||||
} else {
|
||||
resolvedOptions = options || {};
|
||||
resolvedCallback = callback;
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
const startSegment = options.first || this.internal.initialSegment;
|
||||
const lastSegment = options.last;
|
||||
const startSegment = resolvedOptions.first || this.internal.initialSegment;
|
||||
const lastSegment = resolvedOptions.last;
|
||||
|
||||
let item = null;
|
||||
let index = 0;
|
||||
@ -206,7 +211,7 @@ class CodePath {
|
||||
|
||||
// Call the callback when the first time.
|
||||
if (!skippedSegment) {
|
||||
callback.call(this, segment, controller);
|
||||
resolvedCallback.call(this, segment, controller);
|
||||
if (segment === lastSegment) {
|
||||
controller.skip();
|
||||
}
|
||||
|
22
tools/node_modules/eslint/lib/code-path-analysis/fork-context.js
generated
vendored
22
tools/node_modules/eslint/lib/code-path-analysis/fork-context.js
generated
vendored
@ -46,19 +46,15 @@ function isReachable(segment) {
|
||||
function makeSegments(context, begin, end, create) {
|
||||
const list = context.segmentsList;
|
||||
|
||||
if (begin < 0) {
|
||||
begin = list.length + begin;
|
||||
}
|
||||
if (end < 0) {
|
||||
end = list.length + end;
|
||||
}
|
||||
const normalizedBegin = begin >= 0 ? begin : list.length + begin;
|
||||
const normalizedEnd = end >= 0 ? end : list.length + end;
|
||||
|
||||
const segments = [];
|
||||
|
||||
for (let i = 0; i < context.count; ++i) {
|
||||
const allPrevSegments = [];
|
||||
|
||||
for (let j = begin; j <= end; ++j) {
|
||||
for (let j = normalizedBegin; j <= normalizedEnd; ++j) {
|
||||
allPrevSegments.push(list[j][i]);
|
||||
}
|
||||
|
||||
@ -79,18 +75,20 @@ function makeSegments(context, begin, end, create) {
|
||||
* @returns {CodePathSegment[]} The merged segments.
|
||||
*/
|
||||
function mergeExtraSegments(context, segments) {
|
||||
while (segments.length > context.count) {
|
||||
let currentSegments = segments;
|
||||
|
||||
while (currentSegments.length > context.count) {
|
||||
const merged = [];
|
||||
|
||||
for (let i = 0, length = segments.length / 2 | 0; i < length; ++i) {
|
||||
for (let i = 0, length = currentSegments.length / 2 | 0; i < length; ++i) {
|
||||
merged.push(CodePathSegment.newNext(
|
||||
context.idGenerator.next(),
|
||||
[segments[i], segments[i + length]]
|
||||
[currentSegments[i], currentSegments[i + length]]
|
||||
));
|
||||
}
|
||||
segments = merged;
|
||||
currentSegments = merged;
|
||||
}
|
||||
return segments;
|
||||
return currentSegments;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
15
tools/node_modules/eslint/lib/config.js
generated
vendored
15
tools/node_modules/eslint/lib/config.js
generated
vendored
@ -51,11 +51,11 @@ function hasRules(options) {
|
||||
class Config {
|
||||
|
||||
/**
|
||||
* @param {Object} options Options to be passed in
|
||||
* @param {Object} providedOptions Options to be passed in
|
||||
* @param {Linter} linterContext Linter instance object
|
||||
*/
|
||||
constructor(options, linterContext) {
|
||||
options = options || {};
|
||||
constructor(providedOptions, linterContext) {
|
||||
const options = providedOptions || {};
|
||||
|
||||
this.linterContext = linterContext;
|
||||
this.plugins = new Plugins(linterContext.environments, linterContext.rules);
|
||||
@ -132,11 +132,10 @@ class Config {
|
||||
isResolvable(`eslint-config-${config}`) ||
|
||||
config.charAt(0) === "@";
|
||||
|
||||
if (!isNamedConfig) {
|
||||
config = path.resolve(this.options.cwd, config);
|
||||
}
|
||||
|
||||
this.specificConfig = ConfigFile.load(config, this);
|
||||
this.specificConfig = ConfigFile.load(
|
||||
isNamedConfig ? config : path.resolve(this.options.cwd, config),
|
||||
this
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
31
tools/node_modules/eslint/lib/config/config-file.js
generated
vendored
31
tools/node_modules/eslint/lib/config/config-file.js
generated
vendored
@ -400,25 +400,29 @@ function applyExtends(config, configContext, filePath, relativeTo) {
|
||||
}
|
||||
|
||||
// Make the last element in an array take the highest precedence
|
||||
config = configExtends.reduceRight((previousValue, parentPath) => {
|
||||
return configExtends.reduceRight((previousValue, parentPath) => {
|
||||
try {
|
||||
let extensionPath;
|
||||
|
||||
if (parentPath.startsWith("eslint:")) {
|
||||
parentPath = getEslintCoreConfigPath(parentPath);
|
||||
extensionPath = getEslintCoreConfigPath(parentPath);
|
||||
} else if (isFilePath(parentPath)) {
|
||||
|
||||
/*
|
||||
* If the `extends` path is relative, use the directory of the current configuration
|
||||
* file as the reference point. Otherwise, use as-is.
|
||||
*/
|
||||
parentPath = (path.isAbsolute(parentPath)
|
||||
extensionPath = (path.isAbsolute(parentPath)
|
||||
? parentPath
|
||||
: path.join(relativeTo || path.dirname(filePath), parentPath)
|
||||
);
|
||||
} else {
|
||||
extensionPath = parentPath;
|
||||
}
|
||||
debug(`Loading ${parentPath}`);
|
||||
debug(`Loading ${extensionPath}`);
|
||||
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
return ConfigOps.merge(load(parentPath, configContext, relativeTo), previousValue);
|
||||
return ConfigOps.merge(load(extensionPath, configContext, relativeTo), previousValue);
|
||||
} catch (e) {
|
||||
|
||||
/*
|
||||
@ -432,8 +436,6 @@ function applyExtends(config, configContext, filePath, relativeTo) {
|
||||
}
|
||||
|
||||
}, config);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -463,13 +465,20 @@ function resolve(filePath, relativeTo) {
|
||||
|
||||
normalizedPackageName = naming.normalizePackageName(pluginName, "eslint-plugin");
|
||||
debug(`Attempting to resolve ${normalizedPackageName}`);
|
||||
filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo));
|
||||
return { filePath, configName, configFullName };
|
||||
|
||||
return {
|
||||
filePath: resolver.resolve(normalizedPackageName, getLookupPath(relativeTo)),
|
||||
configName,
|
||||
configFullName
|
||||
};
|
||||
}
|
||||
normalizedPackageName = naming.normalizePackageName(filePath, "eslint-config");
|
||||
debug(`Attempting to resolve ${normalizedPackageName}`);
|
||||
filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo));
|
||||
return { filePath, configFullName: filePath };
|
||||
|
||||
return {
|
||||
filePath: resolver.resolve(normalizedPackageName, getLookupPath(relativeTo)),
|
||||
configFullName: filePath
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
18
tools/node_modules/eslint/lib/config/config-ops.js
generated
vendored
18
tools/node_modules/eslint/lib/config/config-ops.js
generated
vendored
@ -136,29 +136,27 @@ module.exports = {
|
||||
const array = Array.isArray(src) || Array.isArray(target);
|
||||
let dst = array && [] || {};
|
||||
|
||||
combine = !!combine;
|
||||
isRule = !!isRule;
|
||||
if (array) {
|
||||
target = target || [];
|
||||
const resolvedTarget = target || [];
|
||||
|
||||
// src could be a string, so check for array
|
||||
if (isRule && Array.isArray(src) && src.length > 1) {
|
||||
dst = dst.concat(src);
|
||||
} else {
|
||||
dst = dst.concat(target);
|
||||
dst = dst.concat(resolvedTarget);
|
||||
}
|
||||
if (typeof src !== "object" && !Array.isArray(src)) {
|
||||
src = [src];
|
||||
}
|
||||
Object.keys(src).forEach((e, i) => {
|
||||
e = src[i];
|
||||
const resolvedSrc = typeof src === "object" ? src : [src];
|
||||
|
||||
Object.keys(resolvedSrc).forEach((_, i) => {
|
||||
const e = resolvedSrc[i];
|
||||
|
||||
if (typeof dst[i] === "undefined") {
|
||||
dst[i] = e;
|
||||
} else if (typeof e === "object") {
|
||||
if (isRule) {
|
||||
dst[i] = e;
|
||||
} else {
|
||||
dst[i] = deepmerge(target[i], e, combine, isRule);
|
||||
dst[i] = deepmerge(resolvedTarget[i], e, combine, isRule);
|
||||
}
|
||||
} else {
|
||||
if (!combine) {
|
||||
|
5
tools/node_modules/eslint/lib/config/config-rule.js
generated
vendored
5
tools/node_modules/eslint/lib/config/config-rule.js
generated
vendored
@ -197,11 +197,10 @@ class RuleConfigSet {
|
||||
* Add a severity level to the front of all configs in the instance.
|
||||
* This should only be called after all configs have been added to the instance.
|
||||
*
|
||||
* @param {number} [severity=2] The level of severity for the rule (0, 1, 2)
|
||||
* @returns {void}
|
||||
*/
|
||||
addErrorSeverity(severity) {
|
||||
severity = severity || 2;
|
||||
addErrorSeverity() {
|
||||
const severity = 2;
|
||||
|
||||
this.ruleConfigs = this.ruleConfigs.map(config => {
|
||||
config.unshift(severity);
|
||||
|
11
tools/node_modules/eslint/lib/config/config-validator.js
generated
vendored
11
tools/node_modules/eslint/lib/config/config-validator.js
generated
vendored
@ -98,7 +98,8 @@ function validateRuleSchema(rule, localOptions) {
|
||||
* @param {{create: Function}|null} rule The rule that the config is being validated for
|
||||
* @param {string} ruleId The rule's unique name.
|
||||
* @param {array|number} options The given options for the rule.
|
||||
* @param {string} source The name of the configuration source to report in any errors.
|
||||
* @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.
|
||||
* @returns {void}
|
||||
*/
|
||||
function validateRuleOptions(rule, ruleId, options, source) {
|
||||
@ -112,7 +113,13 @@ function validateRuleOptions(rule, ruleId, options, source) {
|
||||
validateRuleSchema(rule, Array.isArray(options) ? options.slice(1) : []);
|
||||
}
|
||||
} catch (err) {
|
||||
throw new Error(`${source}:\n\tConfiguration for rule "${ruleId}" is invalid:\n${err.message}`);
|
||||
const enhancedMessage = `Configuration for rule "${ruleId}" is invalid:\n${err.message}`;
|
||||
|
||||
if (typeof source === "string") {
|
||||
throw new Error(`${source}:\n\t${enhancedMessage}`);
|
||||
} else {
|
||||
throw new Error(enhancedMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
20
tools/node_modules/eslint/lib/config/plugins.js
generated
vendored
20
tools/node_modules/eslint/lib/config/plugins.js
generated
vendored
@ -120,6 +120,26 @@ class Plugins {
|
||||
throw pluginLoadErr;
|
||||
}
|
||||
|
||||
// This step is costly, so skip if debug is disabled
|
||||
if (debug.enabled) {
|
||||
const resolvedPath = require.resolve(longName);
|
||||
|
||||
let version = null;
|
||||
|
||||
try {
|
||||
version = require(`${longName}/package.json`).version;
|
||||
} catch (e) {
|
||||
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
const loadedPluginAndVersion = version
|
||||
? `${longName}@${version}`
|
||||
: `${longName}, version unknown`;
|
||||
|
||||
debug(`Loaded plugin ${pluginName} (${loadedPluginAndVersion}) (from ${resolvedPath})`);
|
||||
}
|
||||
|
||||
this.define(pluginName, plugin);
|
||||
}
|
||||
}
|
||||
|
19
tools/node_modules/eslint/lib/file-finder.js
generated
vendored
19
tools/node_modules/eslint/lib/file-finder.js
generated
vendored
@ -79,26 +79,25 @@ class FileFinder {
|
||||
* Does not check if a matching directory entry is a file.
|
||||
* Searches for all the file names in this.fileNames.
|
||||
* Is currently used by lib/config.js to find .eslintrc and package.json files.
|
||||
* @param {string} directory The directory to start the search from.
|
||||
* @param {string} relativeDirectory The directory to start the search from.
|
||||
* @returns {GeneratorFunction} to iterate the file paths found
|
||||
*/
|
||||
*findAllInDirectoryAndParents(directory) {
|
||||
*findAllInDirectoryAndParents(relativeDirectory) {
|
||||
const cache = this.cache;
|
||||
|
||||
if (directory) {
|
||||
directory = path.resolve(this.cwd, directory);
|
||||
} else {
|
||||
directory = this.cwd;
|
||||
}
|
||||
const initialDirectory = relativeDirectory
|
||||
? path.resolve(this.cwd, relativeDirectory)
|
||||
: this.cwd;
|
||||
|
||||
if (cache.hasOwnProperty(directory)) {
|
||||
yield* cache[directory];
|
||||
if (cache.hasOwnProperty(initialDirectory)) {
|
||||
yield* cache[initialDirectory];
|
||||
return; // to avoid doing the normal loop afterwards
|
||||
}
|
||||
|
||||
const dirs = [];
|
||||
const fileNames = this.fileNames;
|
||||
let searched = 0;
|
||||
let directory = initialDirectory;
|
||||
|
||||
do {
|
||||
dirs[searched++] = directory;
|
||||
@ -135,7 +134,7 @@ class FileFinder {
|
||||
|
||||
// Add what has been cached previously to the cache of each directory searched.
|
||||
for (let i = 0; i < searched; i++) {
|
||||
dirs.push.apply(cache[dirs[i]], cache[directory]);
|
||||
[].push.apply(cache[dirs[i]], cache[directory]);
|
||||
}
|
||||
|
||||
yield* cache[dirs[0]];
|
||||
|
8
tools/node_modules/eslint/lib/ignored-paths.js
generated
vendored
8
tools/node_modules/eslint/lib/ignored-paths.js
generated
vendored
@ -76,7 +76,6 @@ function findPackageJSONFile(cwd) {
|
||||
* @returns {Object} Merged options
|
||||
*/
|
||||
function mergeDefaultOptions(options) {
|
||||
options = (options || {});
|
||||
return Object.assign({}, DEFAULT_OPTIONS, options);
|
||||
}
|
||||
|
||||
@ -90,10 +89,11 @@ function mergeDefaultOptions(options) {
|
||||
class IgnoredPaths {
|
||||
|
||||
/**
|
||||
* @param {Object} options object containing 'ignore', 'ignorePath' and 'patterns' properties
|
||||
* @param {Object} providedOptions object containing 'ignore', 'ignorePath' and 'patterns' properties
|
||||
*/
|
||||
constructor(options) {
|
||||
options = mergeDefaultOptions(options);
|
||||
constructor(providedOptions) {
|
||||
const options = mergeDefaultOptions(providedOptions);
|
||||
|
||||
this.cache = {};
|
||||
|
||||
/**
|
||||
|
704
tools/node_modules/eslint/lib/linter.js
generated
vendored
Executable file → Normal file
704
tools/node_modules/eslint/lib/linter.js
generated
vendored
Executable file → Normal file
@ -14,7 +14,6 @@ const eslintScope = require("eslint-scope"),
|
||||
levn = require("levn"),
|
||||
lodash = require("lodash"),
|
||||
blankScriptAST = require("../conf/blank-script.json"),
|
||||
defaultConfig = require("../conf/default-config-options.js"),
|
||||
CodePathAnalyzer = require("./code-path-analysis/code-path-analyzer"),
|
||||
ConfigOps = require("./config/config-ops"),
|
||||
validator = require("./config/config-validator"),
|
||||
@ -33,6 +32,7 @@ const eslintScope = require("eslint-scope"),
|
||||
|
||||
const debug = require("debug")("eslint:linter");
|
||||
const MAX_AUTOFIX_PASSES = 10;
|
||||
const DEFAULT_PARSER_NAME = "espree";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Typedefs
|
||||
@ -48,6 +48,14 @@ const MAX_AUTOFIX_PASSES = 10;
|
||||
* @property {Object|null} visitorKeys The visitor keys to traverse this AST.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} DisableDirective
|
||||
* @property {("disable"|"enable"|"disable-line"|"disable-next-line")} type
|
||||
* @property {number} line
|
||||
* @property {number} column
|
||||
* @property {(string|null)} ruleId
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
@ -63,25 +71,25 @@ function parseBooleanConfig(string, comment) {
|
||||
const items = {};
|
||||
|
||||
// Collapse whitespace around `:` and `,` to make parsing easier
|
||||
string = string.replace(/\s*([:,])\s*/g, "$1");
|
||||
const trimmedString = string.replace(/\s*([:,])\s*/g, "$1");
|
||||
|
||||
string.split(/\s|,+/).forEach(name => {
|
||||
trimmedString.split(/\s|,+/).forEach(name => {
|
||||
if (!name) {
|
||||
return;
|
||||
}
|
||||
const pos = name.indexOf(":");
|
||||
let value;
|
||||
|
||||
if (pos !== -1) {
|
||||
value = name.slice(pos + 1);
|
||||
name = name.slice(0, pos);
|
||||
}
|
||||
|
||||
if (pos === -1) {
|
||||
items[name] = {
|
||||
value: (value === "true"),
|
||||
value: false,
|
||||
comment
|
||||
};
|
||||
|
||||
} else {
|
||||
items[name.slice(0, pos)] = {
|
||||
value: name.slice(pos + 1) === "true",
|
||||
comment
|
||||
};
|
||||
}
|
||||
});
|
||||
return items;
|
||||
}
|
||||
@ -119,9 +127,10 @@ function parseJsonConfig(string, location) {
|
||||
* But we are supporting that. So this is a fallback for that.
|
||||
*/
|
||||
items = {};
|
||||
string = string.replace(/([a-zA-Z0-9\-/]+):/g, "\"$1\":").replace(/(]|[0-9])\s+(?=")/, "$1,");
|
||||
const normalizedString = string.replace(/([a-zA-Z0-9\-/]+):/g, "\"$1\":").replace(/(]|[0-9])\s+(?=")/, "$1,");
|
||||
|
||||
try {
|
||||
items = JSON.parse(`{${string}}`);
|
||||
items = JSON.parse(`{${normalizedString}}`);
|
||||
} catch (ex) {
|
||||
return {
|
||||
success: false,
|
||||
@ -130,7 +139,7 @@ function parseJsonConfig(string, location) {
|
||||
fatal: true,
|
||||
severity: 2,
|
||||
source: null,
|
||||
message: `Failed to parse JSON from '${string}': ${ex.message}`,
|
||||
message: `Failed to parse JSON from '${normalizedString}': ${ex.message}`,
|
||||
line: location.start.line,
|
||||
column: location.start.column + 1
|
||||
}
|
||||
@ -153,14 +162,12 @@ function parseListConfig(string) {
|
||||
const items = {};
|
||||
|
||||
// Collapse whitespace around ,
|
||||
string = string.replace(/\s*,\s*/g, ",");
|
||||
string.replace(/\s*,\s*/g, ",").split(/,+/).forEach(name => {
|
||||
const trimmedName = name.trim();
|
||||
|
||||
string.split(/,+/).forEach(name => {
|
||||
name = name.trim();
|
||||
if (!name) {
|
||||
return;
|
||||
if (trimmedName) {
|
||||
items[trimmedName] = true;
|
||||
}
|
||||
items[name] = true;
|
||||
});
|
||||
return items;
|
||||
}
|
||||
@ -170,32 +177,12 @@ function parseListConfig(string) {
|
||||
* and any globals declared by special block comments, are present in the global
|
||||
* scope.
|
||||
* @param {Scope} globalScope The global scope.
|
||||
* @param {Object} config The existing configuration data.
|
||||
* @param {Environments} envContext Env context
|
||||
* @param {Object} configGlobals The globals declared in configuration
|
||||
* @param {{exportedVariables: Object, enabledGlobals: Object}} commentDirectives Directives from comment configuration
|
||||
* @returns {void}
|
||||
*/
|
||||
function addDeclaredGlobals(globalScope, config, envContext) {
|
||||
const declaredGlobals = {},
|
||||
exportedGlobals = {},
|
||||
explicitGlobals = {},
|
||||
builtin = envContext.get("builtin");
|
||||
|
||||
Object.assign(declaredGlobals, builtin);
|
||||
|
||||
Object.keys(config.env).filter(name => config.env[name]).forEach(name => {
|
||||
const env = envContext.get(name),
|
||||
environmentGlobals = env && env.globals;
|
||||
|
||||
if (environmentGlobals) {
|
||||
Object.assign(declaredGlobals, environmentGlobals);
|
||||
}
|
||||
});
|
||||
|
||||
Object.assign(exportedGlobals, config.exported);
|
||||
Object.assign(declaredGlobals, config.globals);
|
||||
Object.assign(explicitGlobals, config.astGlobals);
|
||||
|
||||
Object.keys(declaredGlobals).forEach(name => {
|
||||
function addDeclaredGlobals(globalScope, configGlobals, commentDirectives) {
|
||||
Object.keys(configGlobals).forEach(name => {
|
||||
let variable = globalScope.set.get(name);
|
||||
|
||||
if (!variable) {
|
||||
@ -204,24 +191,24 @@ function addDeclaredGlobals(globalScope, config, envContext) {
|
||||
globalScope.variables.push(variable);
|
||||
globalScope.set.set(name, variable);
|
||||
}
|
||||
variable.writeable = declaredGlobals[name];
|
||||
variable.writeable = configGlobals[name];
|
||||
});
|
||||
|
||||
Object.keys(explicitGlobals).forEach(name => {
|
||||
Object.keys(commentDirectives.enabledGlobals).forEach(name => {
|
||||
let variable = globalScope.set.get(name);
|
||||
|
||||
if (!variable) {
|
||||
variable = new eslintScope.Variable(name, globalScope);
|
||||
variable.eslintExplicitGlobal = true;
|
||||
variable.eslintExplicitGlobalComment = explicitGlobals[name].comment;
|
||||
variable.eslintExplicitGlobalComment = commentDirectives.enabledGlobals[name].comment;
|
||||
globalScope.variables.push(variable);
|
||||
globalScope.set.set(name, variable);
|
||||
}
|
||||
variable.writeable = explicitGlobals[name].value;
|
||||
variable.writeable = commentDirectives.enabledGlobals[name].value;
|
||||
});
|
||||
|
||||
// mark all exported variables as such
|
||||
Object.keys(exportedGlobals).forEach(name => {
|
||||
Object.keys(commentDirectives.exportedVariables).forEach(name => {
|
||||
const variable = globalScope.set.get(name);
|
||||
|
||||
if (variable) {
|
||||
@ -260,12 +247,7 @@ function addDeclaredGlobals(globalScope, config, envContext) {
|
||||
* @param {{line: number, column: number}} loc The 0-based location of the comment token
|
||||
* @param {string} value The value after the directive in the comment
|
||||
* comment specified no specific rules, so it applies to all rules (e.g. `eslint-disable`)
|
||||
* @returns {{
|
||||
* type: ("disable"|"enable"|"disable-line"|"disable-next-line"),
|
||||
* line: number,
|
||||
* column: number,
|
||||
* ruleId: (string|null)
|
||||
* }[]} Directives from the comment
|
||||
* @returns {DisableDirective[]} Directives from the comment
|
||||
*/
|
||||
function createDisableDirectives(type, loc, value) {
|
||||
const ruleIds = Object.keys(parseListConfig(value));
|
||||
@ -280,68 +262,73 @@ function createDisableDirectives(type, loc, value) {
|
||||
* where reporting is disabled or enabled and merges them with reporting config.
|
||||
* @param {string} filename The file being checked.
|
||||
* @param {ASTNode} ast The top node of the AST.
|
||||
* @param {Object} config The existing configuration data.
|
||||
* @param {function(string): {create: Function}} ruleMapper A map from rule IDs to defined rules
|
||||
* @returns {{
|
||||
* config: Object,
|
||||
* problems: Problem[],
|
||||
* disableDirectives: {
|
||||
* type: ("disable"|"enable"|"disable-line"|"disable-next-line"),
|
||||
* line: number,
|
||||
* column: number,
|
||||
* ruleId: (string|null)
|
||||
* }[]
|
||||
* }} Modified config object, along with any problems encountered
|
||||
* while parsing config comments
|
||||
* @returns {{configuredRules: Object, enabledGlobals: Object, exportedVariables: Object, problems: Problem[], disableDirectives: DisableDirective[]}}
|
||||
* A collection of the directive comments that were found, along with any problems that occurred when parsing
|
||||
*/
|
||||
function modifyConfigsFromComments(filename, ast, config, ruleMapper) {
|
||||
|
||||
const commentConfig = {
|
||||
exported: {},
|
||||
astGlobals: {},
|
||||
rules: {},
|
||||
env: {}
|
||||
};
|
||||
const commentRules = {};
|
||||
function getDirectiveComments(filename, ast, ruleMapper) {
|
||||
const configuredRules = {};
|
||||
const enabledGlobals = {};
|
||||
const exportedVariables = {};
|
||||
const problems = [];
|
||||
const disableDirectives = [];
|
||||
|
||||
ast.comments.filter(token => token.type !== "Shebang").forEach(comment => {
|
||||
const trimmedCommentText = comment.value.trim();
|
||||
const match = /^(eslint(-\w+){0,3}|exported|globals?)(\s|$)/.exec(trimmedCommentText);
|
||||
|
||||
let value = comment.value.trim();
|
||||
const match = /^(eslint(-\w+){0,3}|exported|globals?)(\s|$)/.exec(value);
|
||||
if (!match) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (match) {
|
||||
value = value.slice(match.index + match[1].length);
|
||||
const directiveValue = trimmedCommentText.slice(match.index + match[1].length);
|
||||
|
||||
if (comment.type === "Block") {
|
||||
if (/^eslint-disable-(next-)?line$/.test(match[1]) && comment.loc.start.line === comment.loc.end.line) {
|
||||
const directiveType = match[1].slice("eslint-".length);
|
||||
|
||||
[].push.apply(disableDirectives, createDisableDirectives(directiveType, comment.loc.start, directiveValue));
|
||||
} else if (comment.type === "Block") {
|
||||
switch (match[1]) {
|
||||
case "exported":
|
||||
Object.assign(commentConfig.exported, parseBooleanConfig(value, comment));
|
||||
Object.assign(exportedVariables, parseBooleanConfig(directiveValue, comment));
|
||||
break;
|
||||
|
||||
case "globals":
|
||||
case "global":
|
||||
Object.assign(commentConfig.astGlobals, parseBooleanConfig(value, comment));
|
||||
Object.assign(enabledGlobals, parseBooleanConfig(directiveValue, comment));
|
||||
break;
|
||||
|
||||
case "eslint-disable":
|
||||
[].push.apply(disableDirectives, createDisableDirectives("disable", comment.loc.start, value));
|
||||
[].push.apply(disableDirectives, createDisableDirectives("disable", comment.loc.start, directiveValue));
|
||||
break;
|
||||
|
||||
case "eslint-enable":
|
||||
[].push.apply(disableDirectives, createDisableDirectives("enable", comment.loc.start, value));
|
||||
[].push.apply(disableDirectives, createDisableDirectives("enable", comment.loc.start, directiveValue));
|
||||
break;
|
||||
|
||||
case "eslint": {
|
||||
const parseResult = parseJsonConfig(value, comment.loc);
|
||||
const parseResult = parseJsonConfig(directiveValue, comment.loc);
|
||||
|
||||
if (parseResult.success) {
|
||||
Object.keys(parseResult.config).forEach(name => {
|
||||
const ruleValue = parseResult.config[name];
|
||||
|
||||
validator.validateRuleOptions(ruleMapper(name), name, ruleValue, `${filename} line ${comment.loc.start.line}`);
|
||||
commentRules[name] = ruleValue;
|
||||
try {
|
||||
validator.validateRuleOptions(ruleMapper(name), name, ruleValue);
|
||||
} catch (err) {
|
||||
problems.push({
|
||||
ruleId: name,
|
||||
severity: 2,
|
||||
source: null,
|
||||
message: err.message,
|
||||
line: comment.loc.start.line,
|
||||
column: comment.loc.start.column + 1,
|
||||
endLine: comment.loc.end.line,
|
||||
endColumn: comment.loc.end.column + 1,
|
||||
nodeType: null
|
||||
});
|
||||
}
|
||||
configuredRules[name] = ruleValue;
|
||||
});
|
||||
} else {
|
||||
problems.push(parseResult.error);
|
||||
@ -352,20 +339,13 @@ function modifyConfigsFromComments(filename, ast, config, ruleMapper) {
|
||||
|
||||
// no default
|
||||
}
|
||||
} else { // comment.type === "Line"
|
||||
if (match[1] === "eslint-disable-line") {
|
||||
[].push.apply(disableDirectives, createDisableDirectives("disable-line", comment.loc.start, value));
|
||||
} else if (match[1] === "eslint-disable-next-line") {
|
||||
[].push.apply(disableDirectives, createDisableDirectives("disable-next-line", comment.loc.start, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Object.assign(commentConfig.rules, commentRules);
|
||||
|
||||
return {
|
||||
config: ConfigOps.merge(config, commentConfig),
|
||||
configuredRules,
|
||||
enabledGlobals,
|
||||
exportedVariables,
|
||||
problems,
|
||||
disableDirectives
|
||||
};
|
||||
@ -381,7 +361,7 @@ function normalizeEcmaVersion(ecmaVersion, isModule) {
|
||||
|
||||
// Need at least ES6 for modules
|
||||
if (isModule && (!ecmaVersion || ecmaVersion < 6)) {
|
||||
ecmaVersion = 6;
|
||||
return 6;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -389,70 +369,12 @@ function normalizeEcmaVersion(ecmaVersion, isModule) {
|
||||
* ES2015, which corresponds with ES6 (or a difference of 2009).
|
||||
*/
|
||||
if (ecmaVersion >= 2015) {
|
||||
ecmaVersion -= 2009;
|
||||
return ecmaVersion - 2009;
|
||||
}
|
||||
|
||||
return ecmaVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process initial config to make it safe to extend by file comment config
|
||||
* @param {Object} config Initial config
|
||||
* @param {Environments} envContext Env context
|
||||
* @returns {Object} Processed config
|
||||
*/
|
||||
function prepareConfig(config, envContext) {
|
||||
config.globals = config.globals || {};
|
||||
const copiedRules = {};
|
||||
let parserOptions = {};
|
||||
|
||||
if (typeof config.rules === "object") {
|
||||
Object.keys(config.rules).forEach(k => {
|
||||
const rule = config.rules[k];
|
||||
|
||||
if (rule === null) {
|
||||
throw new Error(`Invalid config for rule '${k}'.`);
|
||||
}
|
||||
if (Array.isArray(rule)) {
|
||||
copiedRules[k] = rule.slice();
|
||||
} else {
|
||||
copiedRules[k] = rule;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// merge in environment parserOptions
|
||||
if (typeof config.env === "object") {
|
||||
Object.keys(config.env).forEach(envName => {
|
||||
const env = envContext.get(envName);
|
||||
|
||||
if (config.env[envName] && env && env.parserOptions) {
|
||||
parserOptions = ConfigOps.merge(parserOptions, env.parserOptions);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const preparedConfig = {
|
||||
rules: copiedRules,
|
||||
parser: config.parser || defaultConfig.parser,
|
||||
globals: ConfigOps.merge(defaultConfig.globals, config.globals),
|
||||
env: ConfigOps.merge(defaultConfig.env, config.env || {}),
|
||||
settings: ConfigOps.merge(defaultConfig.settings, config.settings || {}),
|
||||
parserOptions: ConfigOps.merge(parserOptions, config.parserOptions || {})
|
||||
};
|
||||
const isModule = preparedConfig.parserOptions.sourceType === "module";
|
||||
|
||||
if (isModule) {
|
||||
|
||||
// can't have global return inside of modules
|
||||
preparedConfig.parserOptions.ecmaFeatures = Object.assign({}, preparedConfig.parserOptions.ecmaFeatures, { globalReturn: false });
|
||||
}
|
||||
|
||||
preparedConfig.parserOptions.ecmaVersion = normalizeEcmaVersion(preparedConfig.parserOptions.ecmaVersion, isModule);
|
||||
|
||||
return preparedConfig;
|
||||
}
|
||||
|
||||
const eslintEnvPattern = /\/\*\s*eslint-env\s(.+?)\*\//g;
|
||||
|
||||
/**
|
||||
@ -472,6 +394,64 @@ function findEslintEnv(text) {
|
||||
return retv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the possible options for `linter.verify` and `linter.verifyAndFix` to a
|
||||
* consistent shape.
|
||||
* @param {(string|{reportUnusedDisableDirectives: boolean, filename: string, allowInlineConfig: boolean})} providedOptions Options
|
||||
* @returns {{reportUnusedDisableDirectives: boolean, filename: string, allowInlineConfig: boolean}} Normalized options
|
||||
*/
|
||||
function normalizeVerifyOptions(providedOptions) {
|
||||
const isObjectOptions = typeof providedOptions === "object";
|
||||
const providedFilename = isObjectOptions ? providedOptions.filename : providedOptions;
|
||||
|
||||
return {
|
||||
filename: typeof providedFilename === "string" ? providedFilename : "<input>",
|
||||
allowInlineConfig: !isObjectOptions || providedOptions.allowInlineConfig !== false,
|
||||
reportUnusedDisableDirectives: isObjectOptions && !!providedOptions.reportUnusedDisableDirectives
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines the provided parserOptions with the options from environments
|
||||
* @param {Object} providedOptions The provided 'parserOptions' key in a config
|
||||
* @param {Environment[]} enabledEnvironments The environments enabled in configuration and with inline comments
|
||||
* @returns {Object} Resulting parser options after merge
|
||||
*/
|
||||
function resolveParserOptions(providedOptions, enabledEnvironments) {
|
||||
const parserOptionsFromEnv = enabledEnvironments
|
||||
.filter(env => env.parserOptions)
|
||||
.reduce((parserOptions, env) => ConfigOps.merge(parserOptions, env.parserOptions), {});
|
||||
|
||||
const mergedParserOptions = ConfigOps.merge(parserOptionsFromEnv, providedOptions || {});
|
||||
|
||||
const isModule = mergedParserOptions.sourceType === "module";
|
||||
|
||||
if (isModule) {
|
||||
|
||||
// can't have global return inside of modules
|
||||
mergedParserOptions.ecmaFeatures = Object.assign({}, mergedParserOptions.ecmaFeatures, { globalReturn: false });
|
||||
}
|
||||
|
||||
mergedParserOptions.ecmaVersion = normalizeEcmaVersion(mergedParserOptions.ecmaVersion, isModule);
|
||||
|
||||
return mergedParserOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines the provided globals object with the globals from environments
|
||||
* @param {Object} providedGlobals The 'globals' key in a config
|
||||
* @param {Environments[]} enabledEnvironments The environments enabled in configuration and with inline comments
|
||||
* @returns {Object} The resolved globals object
|
||||
*/
|
||||
function resolveGlobals(providedGlobals, enabledEnvironments) {
|
||||
return Object.assign.apply(
|
||||
null,
|
||||
[{}]
|
||||
.concat(enabledEnvironments.filter(env => env.globals).map(env => env.globals))
|
||||
.concat(providedGlobals)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips Unicode BOM from a given text.
|
||||
*
|
||||
@ -532,13 +512,16 @@ function analyzeScope(ast, parserOptions, visitorKeys) {
|
||||
* as possible
|
||||
* @param {string} text The text to parse.
|
||||
* @param {Object} providedParserOptions Options to pass to the parser
|
||||
* @param {Object} parser The parser module
|
||||
* @param {string} parserName The name of the parser
|
||||
* @param {Map<string, Object>} parserMap A map from names to loaded parsers
|
||||
* @param {string} filePath The path to the file being parsed.
|
||||
* @returns {{success: false, error: Problem}|{success: true, sourceCode: SourceCode}}
|
||||
* An object containing the AST and parser services if parsing was successful, or the error if parsing failed
|
||||
* @private
|
||||
*/
|
||||
function parse(text, providedParserOptions, parser, filePath) {
|
||||
function parse(text, providedParserOptions, parserName, parserMap, filePath) {
|
||||
|
||||
|
||||
const textToParse = stripUnicodeBOM(text).replace(astUtils.SHEBANG_MATCHER, (match, captured) => `//${captured}`);
|
||||
const parserOptions = Object.assign({}, providedParserOptions, {
|
||||
loc: true,
|
||||
@ -551,6 +534,25 @@ function parse(text, providedParserOptions, parser, filePath) {
|
||||
filePath
|
||||
});
|
||||
|
||||
let parser;
|
||||
|
||||
try {
|
||||
parser = parserMap.get(parserName) || require(parserName);
|
||||
} catch (ex) {
|
||||
return {
|
||||
success: false,
|
||||
error: {
|
||||
ruleId: null,
|
||||
fatal: true,
|
||||
severity: 2,
|
||||
source: null,
|
||||
message: ex.message,
|
||||
line: 0,
|
||||
column: 0
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for parsing errors first. If there's a parsing error, nothing
|
||||
* else can happen. However, a parsing error does not throw an error
|
||||
@ -669,6 +671,21 @@ function markVariableAsUsed(scopeManager, currentNode, parserOptions, name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @returns {Object} A map of selector listeners provided by the rule
|
||||
*/
|
||||
function createRuleListeners(rule, ruleContext) {
|
||||
try {
|
||||
return rule.create(ruleContext);
|
||||
} catch (ex) {
|
||||
ex.message = `Error while loading rule '${ruleContext.id}': ${ex.message}`;
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
// methods that exist on SourceCode object
|
||||
const DEPRECATED_SOURCECODE_PASSTHROUGHS = {
|
||||
getSource: "getText",
|
||||
@ -707,164 +724,20 @@ const BASE_TRAVERSAL_CONTEXT = Object.freeze(
|
||||
)
|
||||
);
|
||||
|
||||
const lastSourceCodes = new WeakMap();
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Object that is responsible for verifying JavaScript text
|
||||
* @name eslint
|
||||
* Runs the given rules on the given SourceCode object
|
||||
* @param {SourceCode} sourceCode A SourceCode object for the given text
|
||||
* @param {Object} configuredRules The rules configuration
|
||||
* @param {function(string): Rule} ruleMapper A mapper function from rule names to rules
|
||||
* @param {Object} parserOptions The options that were passed to the parser
|
||||
* @param {string} parserName The name of the parser in the config
|
||||
* @param {Object} settings The settings that were enabled in the config
|
||||
* @param {string} filename The reported filename of the code
|
||||
* @returns {Problem[]} An array of reported problems
|
||||
*/
|
||||
module.exports = class Linter {
|
||||
|
||||
constructor() {
|
||||
lastSourceCodes.set(this, null);
|
||||
this.version = pkg.version;
|
||||
|
||||
this.rules = new Rules();
|
||||
this._parsers = new Map();
|
||||
this.environments = new Environments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration object for the `verify` API. A JS representation of the eslintrc files.
|
||||
* @typedef {Object} ESLintConfig
|
||||
* @property {Object} rules The rule configuration to verify against.
|
||||
* @property {string} [parser] Parser to use when generatig the AST.
|
||||
* @property {Object} [parserOptions] Options for the parsed used.
|
||||
* @property {Object} [settings] Global settings passed to each rule.
|
||||
* @property {Object} [env] The environment to verify in.
|
||||
* @property {Object} [globals] Available globals to the code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Same as linter.verify, except without support for processors.
|
||||
* @param {string|SourceCode} textOrSourceCode The text to parse or a SourceCode object.
|
||||
* @param {ESLintConfig} config An ESLintConfig instance to configure everything.
|
||||
* @param {(string|Object)} [filenameOrOptions] The optional filename of the file being checked.
|
||||
* If this is not set, the filename will default to '<input>' in the rule context. If
|
||||
* an object, then it has "filename", "saveState", and "allowInlineConfig" properties.
|
||||
* @param {boolean} [filenameOrOptions.allowInlineConfig=true] Allow/disallow inline comments' ability to change config once it is set. Defaults to true if not supplied.
|
||||
* Useful if you want to validate JS without comments overriding rules.
|
||||
* @param {boolean} [filenameOrOptions.reportUnusedDisableDirectives=false] Adds reported errors for unused
|
||||
* eslint-disable directives
|
||||
* @returns {Object[]} The results as an array of messages or null if no messages.
|
||||
*/
|
||||
_verifyWithoutProcessors(textOrSourceCode, config, filenameOrOptions) {
|
||||
let text,
|
||||
allowInlineConfig,
|
||||
providedFilename,
|
||||
reportUnusedDisableDirectives;
|
||||
|
||||
// evaluate arguments
|
||||
if (typeof filenameOrOptions === "object") {
|
||||
providedFilename = filenameOrOptions.filename;
|
||||
allowInlineConfig = filenameOrOptions.allowInlineConfig;
|
||||
reportUnusedDisableDirectives = filenameOrOptions.reportUnusedDisableDirectives;
|
||||
} else {
|
||||
providedFilename = filenameOrOptions;
|
||||
}
|
||||
|
||||
if (typeof textOrSourceCode === "string") {
|
||||
lastSourceCodes.set(this, null);
|
||||
text = textOrSourceCode;
|
||||
} else {
|
||||
lastSourceCodes.set(this, textOrSourceCode);
|
||||
text = textOrSourceCode.text;
|
||||
}
|
||||
|
||||
const filename = typeof providedFilename === "string" ? providedFilename : "<input>";
|
||||
|
||||
// search and apply "eslint-env *".
|
||||
const envInFile = findEslintEnv(text);
|
||||
|
||||
config = Object.assign({}, config);
|
||||
|
||||
if (envInFile) {
|
||||
if (config.env) {
|
||||
config.env = Object.assign({}, config.env, envInFile);
|
||||
} else {
|
||||
config.env = envInFile;
|
||||
}
|
||||
}
|
||||
|
||||
// process initial config to make it safe to extend
|
||||
config = prepareConfig(config, this.environments);
|
||||
|
||||
if (!lastSourceCodes.get(this)) {
|
||||
|
||||
// there's no input, just exit here
|
||||
if (text.trim().length === 0) {
|
||||
lastSourceCodes.set(this, new SourceCode(text, blankScriptAST));
|
||||
return [];
|
||||
}
|
||||
|
||||
let parser;
|
||||
|
||||
try {
|
||||
parser = this._parsers.get(config.parser) || require(config.parser);
|
||||
} catch (ex) {
|
||||
return [{
|
||||
ruleId: null,
|
||||
fatal: true,
|
||||
severity: 2,
|
||||
source: null,
|
||||
message: ex.message,
|
||||
line: 0,
|
||||
column: 0
|
||||
}];
|
||||
}
|
||||
const parseResult = parse(
|
||||
text,
|
||||
config.parserOptions,
|
||||
parser,
|
||||
filename
|
||||
);
|
||||
|
||||
if (!parseResult.success) {
|
||||
return [parseResult.error];
|
||||
}
|
||||
|
||||
lastSourceCodes.set(this, parseResult.sourceCode);
|
||||
} else {
|
||||
|
||||
/*
|
||||
* If the given source code object as the first argument does not have scopeManager, analyze the scope.
|
||||
* This is for backward compatibility (SourceCode is frozen so it cannot rebind).
|
||||
*/
|
||||
const lastSourceCode = lastSourceCodes.get(this);
|
||||
|
||||
if (!lastSourceCode.scopeManager) {
|
||||
lastSourceCodes.set(this, new SourceCode({
|
||||
text: lastSourceCode.text,
|
||||
ast: lastSourceCode.ast,
|
||||
parserServices: lastSourceCode.parserServices,
|
||||
visitorKeys: lastSourceCode.visitorKeys,
|
||||
scopeManager: analyzeScope(lastSourceCode.ast, config.parserOptions)
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
const problems = [];
|
||||
const sourceCode = lastSourceCodes.get(this);
|
||||
let disableDirectives;
|
||||
|
||||
// parse global comments and modify config
|
||||
if (allowInlineConfig !== false) {
|
||||
const modifyConfigResult = modifyConfigsFromComments(filename, sourceCode.ast, config, ruleId => this.rules.get(ruleId));
|
||||
|
||||
config = modifyConfigResult.config;
|
||||
modifyConfigResult.problems.forEach(problem => problems.push(problem));
|
||||
disableDirectives = modifyConfigResult.disableDirectives;
|
||||
} else {
|
||||
disableDirectives = [];
|
||||
}
|
||||
|
||||
function runRules(sourceCode, configuredRules, ruleMapper, parserOptions, parserName, settings, filename) {
|
||||
const emitter = createEmitter();
|
||||
const traverser = new Traverser();
|
||||
const scopeManager = sourceCode.scopeManager;
|
||||
|
||||
/*
|
||||
* Create a frozen object with the ruleContext properties and methods that are shared by all rules.
|
||||
@ -876,15 +749,15 @@ module.exports = class Linter {
|
||||
Object.create(BASE_TRAVERSAL_CONTEXT),
|
||||
{
|
||||
getAncestors: () => traverser.parents(),
|
||||
getDeclaredVariables: scopeManager.getDeclaredVariables.bind(scopeManager),
|
||||
getDeclaredVariables: sourceCode.scopeManager.getDeclaredVariables.bind(sourceCode.scopeManager),
|
||||
getFilename: () => filename,
|
||||
getScope: () => getScope(scopeManager, traverser.current(), config.parserOptions.ecmaVersion),
|
||||
getScope: () => getScope(sourceCode.scopeManager, traverser.current(), parserOptions.ecmaVersion),
|
||||
getSourceCode: () => sourceCode,
|
||||
markVariableAsUsed: name => markVariableAsUsed(scopeManager, traverser.current(), config.parserOptions, name),
|
||||
parserOptions: config.parserOptions,
|
||||
parserPath: config.parser,
|
||||
markVariableAsUsed: name => markVariableAsUsed(sourceCode.scopeManager, traverser.current(), parserOptions, name),
|
||||
parserOptions,
|
||||
parserPath: parserName,
|
||||
parserServices: sourceCode.parserServices,
|
||||
settings: config.settings,
|
||||
settings,
|
||||
|
||||
/**
|
||||
* This is used to avoid breaking rules that used to monkeypatch the `Linter#report` method
|
||||
@ -902,23 +775,25 @@ module.exports = class Linter {
|
||||
)
|
||||
);
|
||||
|
||||
// enable appropriate rules
|
||||
Object.keys(config.rules).forEach(ruleId => {
|
||||
const severity = ConfigOps.getRuleSeverity(config.rules[ruleId]);
|
||||
|
||||
const lintingProblems = [];
|
||||
|
||||
Object.keys(configuredRules).forEach(ruleId => {
|
||||
const severity = ConfigOps.getRuleSeverity(configuredRules[ruleId]);
|
||||
|
||||
if (severity === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rule = this.rules.get(ruleId);
|
||||
const messageIds = rule && rule.meta && rule.meta.messages;
|
||||
const rule = ruleMapper(ruleId);
|
||||
const messageIds = rule.meta && rule.meta.messages;
|
||||
let reportTranslator = null;
|
||||
const ruleContext = Object.freeze(
|
||||
Object.assign(
|
||||
Object.create(sharedTraversalContext),
|
||||
{
|
||||
id: ruleId,
|
||||
options: getRuleOptions(config.rules[ruleId]),
|
||||
options: getRuleOptions(configuredRules[ruleId]),
|
||||
report() {
|
||||
|
||||
/*
|
||||
@ -939,7 +814,7 @@ module.exports = class Linter {
|
||||
if (problem.fix && rule.meta && !rule.meta.fixable) {
|
||||
throw new Error("Fixable rules should export a `meta.fixable` property.");
|
||||
}
|
||||
problems.push(problem);
|
||||
lintingProblems.push(problem);
|
||||
|
||||
/*
|
||||
* This is used to avoid breaking rules that used monkeypatch Linter, and relied on
|
||||
@ -963,8 +838,7 @@ module.exports = class Linter {
|
||||
)
|
||||
);
|
||||
|
||||
try {
|
||||
const ruleListeners = rule.create(ruleContext);
|
||||
const ruleListeners = createRuleListeners(rule, ruleContext);
|
||||
|
||||
// add all the selectors from the rule as listeners
|
||||
Object.keys(ruleListeners).forEach(selector => {
|
||||
@ -975,15 +849,8 @@ module.exports = class Linter {
|
||||
: ruleListeners[selector]
|
||||
);
|
||||
});
|
||||
} catch (ex) {
|
||||
ex.message = `Error while loading rule '${ruleId}': ${ex.message}`;
|
||||
throw ex;
|
||||
}
|
||||
});
|
||||
|
||||
// augment global scope with declared global variables
|
||||
addDeclaredGlobals(scopeManager.scopes[0], config, this.environments);
|
||||
|
||||
const eventGenerator = new CodePathAnalyzer(new NodeEventGenerator(emitter));
|
||||
|
||||
/*
|
||||
@ -1003,10 +870,152 @@ module.exports = class Linter {
|
||||
visitorKeys: sourceCode.visitorKeys
|
||||
});
|
||||
|
||||
return lintingProblems;
|
||||
}
|
||||
|
||||
const lastSourceCodes = new WeakMap();
|
||||
const loadedParserMaps = new WeakMap();
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Object that is responsible for verifying JavaScript text
|
||||
* @name eslint
|
||||
*/
|
||||
module.exports = class Linter {
|
||||
|
||||
constructor() {
|
||||
lastSourceCodes.set(this, null);
|
||||
loadedParserMaps.set(this, new Map());
|
||||
this.version = pkg.version;
|
||||
|
||||
this.rules = new Rules();
|
||||
this.environments = new Environments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration object for the `verify` API. A JS representation of the eslintrc files.
|
||||
* @typedef {Object} ESLintConfig
|
||||
* @property {Object} rules The rule configuration to verify against.
|
||||
* @property {string} [parser] Parser to use when generatig the AST.
|
||||
* @property {Object} [parserOptions] Options for the parsed used.
|
||||
* @property {Object} [settings] Global settings passed to each rule.
|
||||
* @property {Object} [env] The environment to verify in.
|
||||
* @property {Object} [globals] Available globals to the code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Same as linter.verify, except without support for processors.
|
||||
* @param {string|SourceCode} textOrSourceCode The text to parse or a SourceCode object.
|
||||
* @param {ESLintConfig} providedConfig An ESLintConfig instance to configure everything.
|
||||
* @param {(string|Object)} [filenameOrOptions] The optional filename of the file being checked.
|
||||
* If this is not set, the filename will default to '<input>' in the rule context. If
|
||||
* an object, then it has "filename", "saveState", and "allowInlineConfig" properties.
|
||||
* @param {boolean} [filenameOrOptions.allowInlineConfig=true] Allow/disallow inline comments' ability to change config once it is set. Defaults to true if not supplied.
|
||||
* Useful if you want to validate JS without comments overriding rules.
|
||||
* @param {boolean} [filenameOrOptions.reportUnusedDisableDirectives=false] Adds reported errors for unused
|
||||
* eslint-disable directives
|
||||
* @returns {Object[]} The results as an array of messages or an empty array if no messages.
|
||||
*/
|
||||
_verifyWithoutProcessors(textOrSourceCode, providedConfig, filenameOrOptions) {
|
||||
const config = providedConfig || {};
|
||||
const options = normalizeVerifyOptions(filenameOrOptions);
|
||||
let text;
|
||||
|
||||
// evaluate arguments
|
||||
if (typeof textOrSourceCode === "string") {
|
||||
lastSourceCodes.set(this, null);
|
||||
text = textOrSourceCode;
|
||||
} else {
|
||||
lastSourceCodes.set(this, textOrSourceCode);
|
||||
text = textOrSourceCode.text;
|
||||
}
|
||||
|
||||
// search and apply "eslint-env *".
|
||||
const envInFile = findEslintEnv(text);
|
||||
const resolvedEnvConfig = Object.assign({ builtin: true }, config.env, envInFile);
|
||||
const enabledEnvs = Object.keys(resolvedEnvConfig)
|
||||
.filter(envName => resolvedEnvConfig[envName])
|
||||
.map(envName => this.environments.get(envName))
|
||||
.filter(env => env);
|
||||
|
||||
const parserOptions = resolveParserOptions(config.parserOptions || {}, enabledEnvs);
|
||||
const configuredGlobals = resolveGlobals(config.globals || {}, enabledEnvs);
|
||||
const parserName = config.parser || DEFAULT_PARSER_NAME;
|
||||
const settings = config.settings || {};
|
||||
|
||||
if (!lastSourceCodes.get(this)) {
|
||||
|
||||
// there's no input, just exit here
|
||||
if (text.trim().length === 0) {
|
||||
lastSourceCodes.set(this, new SourceCode(text, blankScriptAST));
|
||||
return [];
|
||||
}
|
||||
|
||||
const parseResult = parse(
|
||||
text,
|
||||
parserOptions,
|
||||
parserName,
|
||||
loadedParserMaps.get(this),
|
||||
options.filename
|
||||
);
|
||||
|
||||
if (!parseResult.success) {
|
||||
return [parseResult.error];
|
||||
}
|
||||
|
||||
lastSourceCodes.set(this, parseResult.sourceCode);
|
||||
} else {
|
||||
|
||||
/*
|
||||
* If the given source code object as the first argument does not have scopeManager, analyze the scope.
|
||||
* This is for backward compatibility (SourceCode is frozen so it cannot rebind).
|
||||
*/
|
||||
const lastSourceCode = lastSourceCodes.get(this);
|
||||
|
||||
if (!lastSourceCode.scopeManager) {
|
||||
lastSourceCodes.set(this, new SourceCode({
|
||||
text: lastSourceCode.text,
|
||||
ast: lastSourceCode.ast,
|
||||
parserServices: lastSourceCode.parserServices,
|
||||
visitorKeys: lastSourceCode.visitorKeys,
|
||||
scopeManager: analyzeScope(lastSourceCode.ast, parserOptions)
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
const sourceCode = lastSourceCodes.get(this);
|
||||
const commentDirectives = options.allowInlineConfig
|
||||
? getDirectiveComments(options.filename, sourceCode.ast, ruleId => this.rules.get(ruleId))
|
||||
: { configuredRules: {}, enabledGlobals: {}, exportedVariables: {}, problems: [], disableDirectives: [] };
|
||||
|
||||
// augment global scope with declared global variables
|
||||
addDeclaredGlobals(
|
||||
sourceCode.scopeManager.scopes[0],
|
||||
configuredGlobals,
|
||||
{ exportedVariables: commentDirectives.exportedVariables, enabledGlobals: commentDirectives.enabledGlobals }
|
||||
);
|
||||
|
||||
const configuredRules = Object.assign({}, config.rules, commentDirectives.configuredRules);
|
||||
|
||||
const lintingProblems = runRules(
|
||||
sourceCode,
|
||||
configuredRules,
|
||||
ruleId => this.rules.get(ruleId),
|
||||
parserOptions,
|
||||
parserName,
|
||||
settings,
|
||||
options.filename
|
||||
);
|
||||
|
||||
return applyDisableDirectives({
|
||||
directives: disableDirectives,
|
||||
problems: problems.sort((problemA, problemB) => problemA.line - problemB.line || problemA.column - problemB.column),
|
||||
reportUnusedDisableDirectives
|
||||
directives: commentDirectives.disableDirectives,
|
||||
problems: lintingProblems
|
||||
.concat(commentDirectives.problems)
|
||||
.sort((problemA, problemB) => problemA.line - problemB.line || problemA.column - problemB.column),
|
||||
reportUnusedDisableDirectives: options.reportUnusedDisableDirectives
|
||||
});
|
||||
}
|
||||
|
||||
@ -1026,7 +1035,7 @@ module.exports = class Linter {
|
||||
* @param {function(Array<Object[]>): Object[]} [filenameOrOptions.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
|
||||
* @returns {Object[]} The results as an array of messages or null if no messages.
|
||||
* @returns {Object[]} The results as an array of messages or an empty array if no messages.
|
||||
*/
|
||||
verify(textOrSourceCode, config, filenameOrOptions) {
|
||||
const preprocess = filenameOrOptions && filenameOrOptions.preprocess || (rawText => [rawText]);
|
||||
@ -1083,7 +1092,7 @@ module.exports = class Linter {
|
||||
* @returns {void}
|
||||
*/
|
||||
defineParser(parserId, parserModule) {
|
||||
this._parsers.set(parserId, parserModule);
|
||||
loadedParserMaps.get(this).set(parserId, parserModule);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1108,7 +1117,8 @@ module.exports = class Linter {
|
||||
let messages = [],
|
||||
fixedResult,
|
||||
fixed = false,
|
||||
passNumber = 0;
|
||||
passNumber = 0,
|
||||
currentText = text;
|
||||
const debugTextDescription = options && options.filename || `${text.slice(0, 10)}...`;
|
||||
const shouldFix = options && typeof options.fix !== "undefined" ? options.fix : true;
|
||||
|
||||
@ -1125,10 +1135,10 @@ module.exports = class Linter {
|
||||
passNumber++;
|
||||
|
||||
debug(`Linting code for ${debugTextDescription} (pass ${passNumber})`);
|
||||
messages = this.verify(text, config, options);
|
||||
messages = this.verify(currentText, config, options);
|
||||
|
||||
debug(`Generating fixed text for ${debugTextDescription} (pass ${passNumber})`);
|
||||
fixedResult = SourceCodeFixer.applyFixes(text, messages, shouldFix);
|
||||
fixedResult = SourceCodeFixer.applyFixes(currentText, messages, shouldFix);
|
||||
|
||||
/*
|
||||
* stop if there are any syntax errors.
|
||||
@ -1142,7 +1152,7 @@ module.exports = class Linter {
|
||||
fixed = fixed || fixedResult.fixed;
|
||||
|
||||
// update to use the fixed output instead of the original text
|
||||
text = fixedResult.output;
|
||||
currentText = fixedResult.output;
|
||||
|
||||
} while (
|
||||
fixedResult.fixed &&
|
||||
@ -1154,12 +1164,12 @@ module.exports = class Linter {
|
||||
* the most up-to-date information.
|
||||
*/
|
||||
if (fixedResult.fixed) {
|
||||
fixedResult.messages = this.verify(text, config, options);
|
||||
fixedResult.messages = this.verify(currentText, config, options);
|
||||
}
|
||||
|
||||
// ensure the last result properly reflects if fixes were done
|
||||
fixedResult.fixed = fixed;
|
||||
fixedResult.output = text;
|
||||
fixedResult.output = currentText;
|
||||
|
||||
return fixedResult;
|
||||
}
|
||||
|
13
tools/node_modules/eslint/lib/load-rules.js
generated
vendored
13
tools/node_modules/eslint/lib/load-rules.js
generated
vendored
@ -20,16 +20,15 @@ const rulesDirCache = {};
|
||||
|
||||
/**
|
||||
* Load all rule modules from specified directory.
|
||||
* @param {string} [rulesDir] Path to rules directory, may be relative. Defaults to `lib/rules`.
|
||||
* @param {string} [relativeRulesDir] Path to rules directory, may be relative. Defaults to `lib/rules`.
|
||||
* @param {string} cwd Current working directory
|
||||
* @returns {Object} Loaded rule modules by rule ids (file names).
|
||||
*/
|
||||
module.exports = function(rulesDir, cwd) {
|
||||
if (!rulesDir) {
|
||||
rulesDir = path.join(__dirname, "rules");
|
||||
} else {
|
||||
rulesDir = path.resolve(cwd, rulesDir);
|
||||
}
|
||||
module.exports = function(relativeRulesDir, cwd) {
|
||||
|
||||
const rulesDir = relativeRulesDir
|
||||
? path.resolve(cwd, relativeRulesDir)
|
||||
: path.join(__dirname, "rules");
|
||||
|
||||
// cache will help performance as IO operation are expensive
|
||||
if (rulesDirCache[rulesDir]) {
|
||||
|
14
tools/node_modules/eslint/lib/options.js
generated
vendored
14
tools/node_modules/eslint/lib/options.js
generated
vendored
@ -26,17 +26,17 @@ module.exports = optionator({
|
||||
{
|
||||
heading: "Basic configuration"
|
||||
},
|
||||
{
|
||||
option: "config",
|
||||
alias: "c",
|
||||
type: "path::String",
|
||||
description: "Use configuration from this file or shareable config"
|
||||
},
|
||||
{
|
||||
option: "eslintrc",
|
||||
type: "Boolean",
|
||||
default: "true",
|
||||
description: "Disable use of configuration from .eslintrc"
|
||||
description: "Disable use of configuration from .eslintrc.*"
|
||||
},
|
||||
{
|
||||
option: "config",
|
||||
alias: "c",
|
||||
type: "path::String",
|
||||
description: "Use this configuration, overriding .eslintrc.* config options if present"
|
||||
},
|
||||
{
|
||||
option: "env",
|
||||
|
65
tools/node_modules/eslint/lib/report-translator.js
generated
vendored
65
tools/node_modules/eslint/lib/report-translator.js
generated
vendored
@ -28,6 +28,22 @@ const interpolate = require("./util/interpolate");
|
||||
* @property {Function} [fix] The function to call that creates a fix command.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Module Definition
|
||||
//------------------------------------------------------------------------------
|
||||
@ -121,7 +137,7 @@ function compareFixesByRange(a, b) {
|
||||
* Merges the given fixes array into one.
|
||||
* @param {Fix[]} fixes The fixes to merge.
|
||||
* @param {SourceCode} sourceCode The source code object to get the text between fixes.
|
||||
* @returns {{text: string, range: [number, number]}} The merged fixes
|
||||
* @returns {{text: string, range: number[]}} The merged fixes
|
||||
*/
|
||||
function mergeFixes(fixes, sourceCode) {
|
||||
if (fixes.length === 0) {
|
||||
@ -158,7 +174,7 @@ function mergeFixes(fixes, sourceCode) {
|
||||
* If the descriptor retrieves multiple fixes, this merges those to one.
|
||||
* @param {MessageDescriptor} descriptor The report descriptor.
|
||||
* @param {SourceCode} sourceCode The source code object to get text between fixes.
|
||||
* @returns {({text: string, range: [number, number]}|null)} The fix for the descriptor
|
||||
* @returns {({text: string, range: number[]}|null)} The fix for the descriptor
|
||||
*/
|
||||
function normalizeFixes(descriptor, sourceCode) {
|
||||
if (typeof descriptor.fix !== "function") {
|
||||
@ -177,27 +193,15 @@ function normalizeFixes(descriptor, sourceCode) {
|
||||
|
||||
/**
|
||||
* Creates information about the report from a descriptor
|
||||
* @param {{
|
||||
* ruleId: string,
|
||||
* severity: (0|1|2),
|
||||
* node: (ASTNode|null),
|
||||
* message: string,
|
||||
* loc: {start: SourceLocation, end: (SourceLocation|null)},
|
||||
* fix: ({text: string, range: [number, number]}|null),
|
||||
* sourceLines: string[]
|
||||
* }} options Information about the problem
|
||||
* @returns {function(...args): {
|
||||
* ruleId: string,
|
||||
* severity: (0|1|2),
|
||||
* message: string,
|
||||
* line: number,
|
||||
* column: number,
|
||||
* endLine: (number|undefined),
|
||||
* endColumn: (number|undefined),
|
||||
* nodeType: (string|null),
|
||||
* source: string,
|
||||
* fix: ({text: string, range: [number, number]}|null)
|
||||
* }} Information about the report
|
||||
* @param {Object} options Information about the problem
|
||||
* @param {string} options.ruleId Rule ID
|
||||
* @param {(0|1|2)} options.severity Rule severity
|
||||
* @param {(ASTNode|null)} options.node Node
|
||||
* @param {string} options.message Error message
|
||||
* @param {{start: SourceLocation, end: (SourceLocation|null)}} options.loc Start and end location
|
||||
* @param {{text: string, range: (number[]|null)}} options.fix The fix object
|
||||
* @param {string[]} options.sourceLines Source lines
|
||||
* @returns {function(...args): ReportInfo} Function that returns information about the report
|
||||
*/
|
||||
function createProblem(options) {
|
||||
const problem = {
|
||||
@ -235,20 +239,7 @@ function createProblem(options) {
|
||||
* problem for the Node.js API.
|
||||
* @param {{ruleId: string, severity: number, sourceCode: SourceCode, messageIds: Object}} metadata Metadata for the reported problem
|
||||
* @param {SourceCode} sourceCode The `SourceCode` instance for the text being linted
|
||||
* @returns {function(...args): {
|
||||
* ruleId: string,
|
||||
* severity: (0|1|2),
|
||||
* message: (string|undefined),
|
||||
* messageId: (string|undefined),
|
||||
* line: number,
|
||||
* column: number,
|
||||
* endLine: (number|undefined),
|
||||
* endColumn: (number|undefined),
|
||||
* nodeType: (string|null),
|
||||
* source: string,
|
||||
* fix: ({text: string, range: [number, number]}|null)
|
||||
* }}
|
||||
* Information about the report
|
||||
* @returns {function(...args): ReportInfo} Function that returns information about the report
|
||||
*/
|
||||
|
||||
module.exports = function createReportTranslator(metadata) {
|
||||
|
18
tools/node_modules/eslint/lib/rules/accessor-pairs.js
generated
vendored
18
tools/node_modules/eslint/lib/rules/accessor-pairs.js
generated
vendored
@ -58,11 +58,11 @@ function isPropertyDescriptor(node) {
|
||||
* Object.defineProperties(obj, {foo: {set: ...}})
|
||||
* Object.create(proto, {foo: {set: ...}})
|
||||
*/
|
||||
node = node.parent.parent;
|
||||
const grandparent = node.parent.parent;
|
||||
|
||||
return node.type === "ObjectExpression" && (
|
||||
isArgumentOfMethodCall(node, 1, "Object", "create") ||
|
||||
isArgumentOfMethodCall(node, 1, "Object", "defineProperties")
|
||||
return grandparent.type === "ObjectExpression" && (
|
||||
isArgumentOfMethodCall(grandparent, 1, "Object", "create") ||
|
||||
isArgumentOfMethodCall(grandparent, 1, "Object", "defineProperties")
|
||||
);
|
||||
}
|
||||
|
||||
@ -89,7 +89,11 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}]
|
||||
}],
|
||||
messages: {
|
||||
getter: "Getter is not present.",
|
||||
setter: "Setter is not present."
|
||||
}
|
||||
},
|
||||
create(context) {
|
||||
const config = context.options[0] || {};
|
||||
@ -140,9 +144,9 @@ module.exports = {
|
||||
}
|
||||
|
||||
if (checkSetWithoutGet && isSetPresent && !isGetPresent) {
|
||||
context.report({ node, message: "Getter is not present." });
|
||||
context.report({ node, messageId: "getter" });
|
||||
} else if (checkGetWithoutSet && isGetPresent && !isSetPresent) {
|
||||
context.report({ node, message: "Setter is not present." });
|
||||
context.report({ node, messageId: "setter" });
|
||||
}
|
||||
}
|
||||
|
||||
|
16
tools/node_modules/eslint/lib/rules/array-bracket-newline.js
generated
vendored
16
tools/node_modules/eslint/lib/rules/array-bracket-newline.js
generated
vendored
@ -41,7 +41,13 @@ module.exports = {
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
messages: {
|
||||
unexpectedOpeningLinebreak: "There should be no linebreak after '['.",
|
||||
unexpectedClosingLinebreak: "There should be no linebreak before ']'.",
|
||||
missingOpeningLinebreak: "A linebreak is required after '['.",
|
||||
missingClosingLinebreak: "A linebreak is required before ']'."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -106,7 +112,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: token.loc,
|
||||
message: "There should be no linebreak after '['.",
|
||||
messageId: "unexpectedOpeningLinebreak",
|
||||
fix(fixer) {
|
||||
const nextToken = sourceCode.getTokenAfter(token, { includeComments: true });
|
||||
|
||||
@ -129,7 +135,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: token.loc,
|
||||
message: "There should be no linebreak before ']'.",
|
||||
messageId: "unexpectedClosingLinebreak",
|
||||
fix(fixer) {
|
||||
const previousToken = sourceCode.getTokenBefore(token, { includeComments: true });
|
||||
|
||||
@ -152,7 +158,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: token.loc,
|
||||
message: "A linebreak is required after '['.",
|
||||
messageId: "missingOpeningLinebreak",
|
||||
fix(fixer) {
|
||||
return fixer.insertTextAfter(token, "\n");
|
||||
}
|
||||
@ -169,7 +175,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: token.loc,
|
||||
message: "A linebreak is required before ']'.",
|
||||
messageId: "missingClosingLinebreak",
|
||||
fix(fixer) {
|
||||
return fixer.insertTextBefore(token, "\n");
|
||||
}
|
||||
|
16
tools/node_modules/eslint/lib/rules/array-bracket-spacing.js
generated
vendored
16
tools/node_modules/eslint/lib/rules/array-bracket-spacing.js
generated
vendored
@ -38,7 +38,13 @@ module.exports = {
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
],
|
||||
messages: {
|
||||
unexpectedSpaceAfter: "There should be no space after '{{tokenValue}}'.",
|
||||
unexpectedSpaceBefore: "There should be no space before '{{tokenValue}}'.",
|
||||
missingSpaceAfter: "A space is required after '{{tokenValue}}'.",
|
||||
missingSpaceBefore: "A space is required before '{{tokenValue}}'."
|
||||
}
|
||||
},
|
||||
create(context) {
|
||||
const spaced = context.options[0] === "always",
|
||||
@ -76,7 +82,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: token.loc.start,
|
||||
message: "There should be no space after '{{tokenValue}}'.",
|
||||
messageId: "unexpectedSpaceAfter",
|
||||
data: {
|
||||
tokenValue: token.value
|
||||
},
|
||||
@ -98,7 +104,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: token.loc.start,
|
||||
message: "There should be no space before '{{tokenValue}}'.",
|
||||
messageId: "unexpectedSpaceBefore",
|
||||
data: {
|
||||
tokenValue: token.value
|
||||
},
|
||||
@ -120,7 +126,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: token.loc.start,
|
||||
message: "A space is required after '{{tokenValue}}'.",
|
||||
messageId: "missingSpaceAfter",
|
||||
data: {
|
||||
tokenValue: token.value
|
||||
},
|
||||
@ -140,7 +146,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: token.loc.start,
|
||||
message: "A space is required before '{{tokenValue}}'.",
|
||||
messageId: "missingSpaceBefore",
|
||||
data: {
|
||||
tokenValue: token.value
|
||||
},
|
||||
|
30
tools/node_modules/eslint/lib/rules/array-callback-return.js
generated
vendored
30
tools/node_modules/eslint/lib/rules/array-callback-return.js
generated
vendored
@ -71,8 +71,10 @@ function isTargetMethod(node) {
|
||||
* @returns {boolean} `true` if the node is the callback of an array method.
|
||||
*/
|
||||
function isCallbackOfArrayMethod(node) {
|
||||
while (node) {
|
||||
const parent = node.parent;
|
||||
let currentNode = node;
|
||||
|
||||
while (currentNode) {
|
||||
const parent = currentNode.parent;
|
||||
|
||||
switch (parent.type) {
|
||||
|
||||
@ -82,7 +84,7 @@ function isCallbackOfArrayMethod(node) {
|
||||
*/
|
||||
case "LogicalExpression":
|
||||
case "ConditionalExpression":
|
||||
node = parent;
|
||||
currentNode = parent;
|
||||
break;
|
||||
|
||||
/*
|
||||
@ -99,7 +101,7 @@ function isCallbackOfArrayMethod(node) {
|
||||
if (func === null || !astUtils.isCallee(func)) {
|
||||
return false;
|
||||
}
|
||||
node = func.parent;
|
||||
currentNode = func.parent;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -112,13 +114,13 @@ function isCallbackOfArrayMethod(node) {
|
||||
if (astUtils.isArrayFromMethod(parent.callee)) {
|
||||
return (
|
||||
parent.arguments.length >= 2 &&
|
||||
parent.arguments[1] === node
|
||||
parent.arguments[1] === currentNode
|
||||
);
|
||||
}
|
||||
if (isTargetMethod(parent.callee)) {
|
||||
return (
|
||||
parent.arguments.length >= 1 &&
|
||||
parent.arguments[0] === node
|
||||
parent.arguments[0] === currentNode
|
||||
);
|
||||
}
|
||||
return false;
|
||||
@ -156,7 +158,13 @@ module.exports = {
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
messages: {
|
||||
expectedAtEnd: "Expected to return a value at the end of {{name}}.",
|
||||
expectedInside: "Expected to return a value in {{name}}.",
|
||||
expectedReturnValue: "{{name}} expected a return value."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -188,9 +196,9 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: getLocation(node, context.getSourceCode()).loc.start,
|
||||
message: funcInfo.hasReturn
|
||||
? "Expected to return a value at the end of {{name}}."
|
||||
: "Expected to return a value in {{name}}.",
|
||||
messageId: funcInfo.hasReturn
|
||||
? "expectedAtEnd"
|
||||
: "expectedInside",
|
||||
data: {
|
||||
name: astUtils.getFunctionNameWithKind(funcInfo.node)
|
||||
}
|
||||
@ -230,7 +238,7 @@ module.exports = {
|
||||
if (!options.allowImplicit && !node.argument) {
|
||||
context.report({
|
||||
node,
|
||||
message: "{{name}} expected a return value.",
|
||||
messageId: "expectedReturnValue",
|
||||
data: {
|
||||
name: lodash.upperFirst(astUtils.getFunctionNameWithKind(funcInfo.node))
|
||||
}
|
||||
|
19
tools/node_modules/eslint/lib/rules/array-element-newline.js
generated
vendored
19
tools/node_modules/eslint/lib/rules/array-element-newline.js
generated
vendored
@ -41,7 +41,12 @@ module.exports = {
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
messages: {
|
||||
unexpectedLineBreak: "There should be no linebreak here.",
|
||||
missingLineBreak: "There should be a linebreak after this element."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -54,16 +59,16 @@ module.exports = {
|
||||
/**
|
||||
* Normalizes a given option value.
|
||||
*
|
||||
* @param {string|Object|undefined} option - An option value to parse.
|
||||
* @param {string|Object|undefined} providedOption - An option value to parse.
|
||||
* @returns {{multiline: boolean, minItems: number}} Normalized option object.
|
||||
*/
|
||||
function normalizeOptionValue(option) {
|
||||
function normalizeOptionValue(providedOption) {
|
||||
let multiline = false;
|
||||
let minItems;
|
||||
|
||||
option = option || "always";
|
||||
const option = providedOption || "always";
|
||||
|
||||
if (option === "always" || option.minItems === 0) {
|
||||
if (!option || option === "always" || option.minItems === 0) {
|
||||
minItems = 0;
|
||||
} else if (option === "never") {
|
||||
minItems = Number.POSITIVE_INFINITY;
|
||||
@ -100,7 +105,7 @@ module.exports = {
|
||||
start: tokenBefore.loc.end,
|
||||
end: token.loc.start
|
||||
},
|
||||
message: "There should be no linebreak here.",
|
||||
messageId: "unexpectedLineBreak",
|
||||
fix(fixer) {
|
||||
if (astUtils.isCommentToken(tokenBefore)) {
|
||||
return null;
|
||||
@ -149,7 +154,7 @@ module.exports = {
|
||||
start: tokenBefore.loc.end,
|
||||
end: token.loc.start
|
||||
},
|
||||
message: "There should be a linebreak after this element.",
|
||||
messageId: "missingLineBreak",
|
||||
fix(fixer) {
|
||||
return fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], "\n");
|
||||
}
|
||||
|
24
tools/node_modules/eslint/lib/rules/arrow-body-style.js
generated
vendored
24
tools/node_modules/eslint/lib/rules/arrow-body-style.js
generated
vendored
@ -55,7 +55,15 @@ module.exports = {
|
||||
]
|
||||
},
|
||||
|
||||
fixable: "code"
|
||||
fixable: "code",
|
||||
|
||||
messages: {
|
||||
unexpectedOtherBlock: "Unexpected block statement surrounding arrow body.",
|
||||
unexpectedEmptyBlock: "Unexpected block statement surrounding arrow body; put a value of `undefined` immediately after the `=>`.",
|
||||
unexpectedObjectBlock: "Unexpected block statement surrounding arrow body; parenthesize the returned value and move it immediately after the `=>`.",
|
||||
unexpectedSingleBlock: "Unexpected block statement surrounding arrow body; move the returned value immediately after the `=>`.",
|
||||
expectedBlock: "Expected block statement surrounding arrow body."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -110,22 +118,22 @@ module.exports = {
|
||||
}
|
||||
|
||||
if (never || asNeeded && blockBody[0].type === "ReturnStatement") {
|
||||
let message;
|
||||
let messageId;
|
||||
|
||||
if (blockBody.length === 0) {
|
||||
message = "Unexpected block statement surrounding arrow body; put a value of `undefined` immediately after the `=>`.";
|
||||
messageId = "unexpectedEmptyBlock";
|
||||
} else if (blockBody.length > 1) {
|
||||
message = "Unexpected block statement surrounding arrow body.";
|
||||
messageId = "unexpectedOtherBlock";
|
||||
} else if (astUtils.isOpeningBraceToken(sourceCode.getFirstToken(blockBody[0], { skip: 1 }))) {
|
||||
message = "Unexpected block statement surrounding arrow body; parenthesize the returned value and move it immediately after the `=>`.";
|
||||
messageId = "unexpectedObjectBlock";
|
||||
} else {
|
||||
message = "Unexpected block statement surrounding arrow body; move the returned value immediately after the `=>`.";
|
||||
messageId = "unexpectedSingleBlock";
|
||||
}
|
||||
|
||||
context.report({
|
||||
node,
|
||||
loc: arrowBody.loc.start,
|
||||
message,
|
||||
messageId,
|
||||
fix(fixer) {
|
||||
const fixes = [];
|
||||
|
||||
@ -190,7 +198,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: arrowBody.loc.start,
|
||||
message: "Expected block statement surrounding arrow body.",
|
||||
messageId: "expectedBlock",
|
||||
fix(fixer) {
|
||||
const fixes = [];
|
||||
const arrowToken = sourceCode.getTokenBefore(arrowBody, astUtils.isArrowToken);
|
||||
|
22
tools/node_modules/eslint/lib/rules/arrow-parens.js
generated
vendored
22
tools/node_modules/eslint/lib/rules/arrow-parens.js
generated
vendored
@ -38,15 +38,19 @@ module.exports = {
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
messages: {
|
||||
unexpectedParens: "Unexpected parentheses around single function argument.",
|
||||
expectedParens: "Expected parentheses around arrow function argument.",
|
||||
|
||||
unexpectedParensInline: "Unexpected parentheses around single function argument having a body with no curly braces.",
|
||||
expectedParensBlock: "Expected parentheses around arrow function argument having a body with curly braces."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const message = "Expected parentheses around arrow function argument.";
|
||||
const asNeededMessage = "Unexpected parentheses around single function argument.";
|
||||
const asNeeded = context.options[0] === "as-needed";
|
||||
const requireForBlockBodyMessage = "Unexpected parentheses around single function argument having a body with no curly braces";
|
||||
const requireForBlockBodyNoParensMessage = "Expected parentheses around arrow function argument having a body with curly braces.";
|
||||
const requireForBlockBody = asNeeded && context.options[1] && context.options[1].requireForBlockBody === true;
|
||||
|
||||
const sourceCode = context.getSourceCode();
|
||||
@ -94,7 +98,7 @@ module.exports = {
|
||||
if (astUtils.isOpeningParenToken(firstTokenOfParam)) {
|
||||
context.report({
|
||||
node,
|
||||
message: requireForBlockBodyMessage,
|
||||
messageId: "unexpectedParensInline",
|
||||
fix: fixParamsWithParenthesis
|
||||
});
|
||||
}
|
||||
@ -108,7 +112,7 @@ module.exports = {
|
||||
if (!astUtils.isOpeningParenToken(firstTokenOfParam)) {
|
||||
context.report({
|
||||
node,
|
||||
message: requireForBlockBodyNoParensMessage,
|
||||
messageId: "expectedParensBlock",
|
||||
fix(fixer) {
|
||||
return fixer.replaceText(firstTokenOfParam, `(${firstTokenOfParam.value})`);
|
||||
}
|
||||
@ -127,7 +131,7 @@ module.exports = {
|
||||
if (astUtils.isOpeningParenToken(firstTokenOfParam)) {
|
||||
context.report({
|
||||
node,
|
||||
message: asNeededMessage,
|
||||
messageId: "unexpectedParens",
|
||||
fix: fixParamsWithParenthesis
|
||||
});
|
||||
}
|
||||
@ -141,7 +145,7 @@ module.exports = {
|
||||
if (after.value !== ")") {
|
||||
context.report({
|
||||
node,
|
||||
message,
|
||||
messageId: "expectedParens",
|
||||
fix(fixer) {
|
||||
return fixer.replaceText(firstTokenOfParam, `(${firstTokenOfParam.value})`);
|
||||
}
|
||||
|
18
tools/node_modules/eslint/lib/rules/arrow-spacing.js
generated
vendored
18
tools/node_modules/eslint/lib/rules/arrow-spacing.js
generated
vendored
@ -38,7 +38,15 @@ module.exports = {
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
messages: {
|
||||
expectedBefore: "Missing space before =>.",
|
||||
unexpectedBefore: "Unexpected space before =>.",
|
||||
|
||||
expectedAfter: "Missing space after =>.",
|
||||
unexpectedAfter: "Unexpected space after =>."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -96,7 +104,7 @@ module.exports = {
|
||||
if (countSpace.before === 0) {
|
||||
context.report({
|
||||
node: tokens.before,
|
||||
message: "Missing space before =>.",
|
||||
messageId: "expectedBefore",
|
||||
fix(fixer) {
|
||||
return fixer.insertTextBefore(tokens.arrow, " ");
|
||||
}
|
||||
@ -108,7 +116,7 @@ module.exports = {
|
||||
if (countSpace.before > 0) {
|
||||
context.report({
|
||||
node: tokens.before,
|
||||
message: "Unexpected space before =>.",
|
||||
messageId: "unexpectedBefore",
|
||||
fix(fixer) {
|
||||
return fixer.removeRange([tokens.before.range[1], tokens.arrow.range[0]]);
|
||||
}
|
||||
@ -122,7 +130,7 @@ module.exports = {
|
||||
if (countSpace.after === 0) {
|
||||
context.report({
|
||||
node: tokens.after,
|
||||
message: "Missing space after =>.",
|
||||
messageId: "expectedAfter",
|
||||
fix(fixer) {
|
||||
return fixer.insertTextAfter(tokens.arrow, " ");
|
||||
}
|
||||
@ -134,7 +142,7 @@ module.exports = {
|
||||
if (countSpace.after > 0) {
|
||||
context.report({
|
||||
node: tokens.after,
|
||||
message: "Unexpected space after =>.",
|
||||
messageId: "unexpectedAfter",
|
||||
fix(fixer) {
|
||||
return fixer.removeRange([tokens.arrow.range[1], tokens.after.range[0]]);
|
||||
}
|
||||
|
8
tools/node_modules/eslint/lib/rules/block-scoped-var.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/block-scoped-var.js
generated
vendored
@ -17,7 +17,11 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/block-scoped-var"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
outOfScope: "'{{name}}' used outside of binding context."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -48,7 +52,7 @@ module.exports = {
|
||||
function report(reference) {
|
||||
const identifier = reference.identifier;
|
||||
|
||||
context.report({ node: identifier, message: "'{{name}}' used outside of binding context.", data: { name: identifier.name } });
|
||||
context.report({ node: identifier, messageId: "outOfScope", data: { name: identifier.name } });
|
||||
}
|
||||
|
||||
/**
|
||||
|
19
tools/node_modules/eslint/lib/rules/block-spacing.js
generated
vendored
19
tools/node_modules/eslint/lib/rules/block-spacing.js
generated
vendored
@ -24,12 +24,17 @@ module.exports = {
|
||||
|
||||
schema: [
|
||||
{ enum: ["always", "never"] }
|
||||
]
|
||||
],
|
||||
|
||||
messages: {
|
||||
missing: "Requires a space {{location}} '{{token}}'",
|
||||
extra: "Unexpected space(s) {{location}} '{{token}}'"
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const always = (context.options[0] !== "never"),
|
||||
message = always ? "Requires a space" : "Unexpected space(s)",
|
||||
messageId = always ? "missing" : "extra",
|
||||
sourceCode = context.getSourceCode();
|
||||
|
||||
/**
|
||||
@ -98,9 +103,10 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: openBrace.loc.start,
|
||||
message: "{{message}} after '{'.",
|
||||
messageId,
|
||||
data: {
|
||||
message
|
||||
location: "after",
|
||||
token: openBrace.value
|
||||
},
|
||||
fix(fixer) {
|
||||
if (always) {
|
||||
@ -115,9 +121,10 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: closeBrace.loc.start,
|
||||
message: "{{message}} before '}'.",
|
||||
messageId,
|
||||
data: {
|
||||
message
|
||||
location: "before",
|
||||
token: closeBrace.value
|
||||
},
|
||||
fix(fixer) {
|
||||
if (always) {
|
||||
|
30
tools/node_modules/eslint/lib/rules/brace-style.js
generated
vendored
30
tools/node_modules/eslint/lib/rules/brace-style.js
generated
vendored
@ -35,7 +35,16 @@ module.exports = {
|
||||
}
|
||||
],
|
||||
|
||||
fixable: "whitespace"
|
||||
fixable: "whitespace",
|
||||
|
||||
messages: {
|
||||
nextLineOpen: "Opening curly brace does not appear on the same line as controlling statement.",
|
||||
sameLineOpen: "Opening curly brace appears on the same line as controlling statement.",
|
||||
blockSameLine: "Statement inside of curly braces should be on next line.",
|
||||
nextLineClose: "Closing curly brace does not appear on the same line as the subsequent block.",
|
||||
singleLineClose: "Closing curly brace should be on the same line as opening curly brace or on the line after the previous block.",
|
||||
sameLineClose: "Closing curly brace appears on the same line as the subsequent block."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -43,13 +52,6 @@ module.exports = {
|
||||
params = context.options[1] || {},
|
||||
sourceCode = context.getSourceCode();
|
||||
|
||||
const OPEN_MESSAGE = "Opening curly brace does not appear on the same line as controlling statement.",
|
||||
OPEN_MESSAGE_ALLMAN = "Opening curly brace appears on the same line as controlling statement.",
|
||||
BODY_MESSAGE = "Statement inside of curly braces should be on next line.",
|
||||
CLOSE_MESSAGE = "Closing curly brace does not appear on the same line as the subsequent block.",
|
||||
CLOSE_MESSAGE_SINGLE = "Closing curly brace should be on the same line as opening curly brace or on the line after the previous block.",
|
||||
CLOSE_MESSAGE_STROUSTRUP_ALLMAN = "Closing curly brace appears on the same line as the subsequent block.";
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//--------------------------------------------------------------------------
|
||||
@ -86,7 +88,7 @@ module.exports = {
|
||||
if (style !== "allman" && !astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly)) {
|
||||
context.report({
|
||||
node: openingCurly,
|
||||
message: OPEN_MESSAGE,
|
||||
messageId: "nextLineOpen",
|
||||
fix: removeNewlineBetween(tokenBeforeOpeningCurly, openingCurly)
|
||||
});
|
||||
}
|
||||
@ -94,7 +96,7 @@ module.exports = {
|
||||
if (style === "allman" && astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly) && !singleLineException) {
|
||||
context.report({
|
||||
node: openingCurly,
|
||||
message: OPEN_MESSAGE_ALLMAN,
|
||||
messageId: "sameLineOpen",
|
||||
fix: fixer => fixer.insertTextBefore(openingCurly, "\n")
|
||||
});
|
||||
}
|
||||
@ -102,7 +104,7 @@ module.exports = {
|
||||
if (astUtils.isTokenOnSameLine(openingCurly, tokenAfterOpeningCurly) && tokenAfterOpeningCurly !== closingCurly && !singleLineException) {
|
||||
context.report({
|
||||
node: openingCurly,
|
||||
message: BODY_MESSAGE,
|
||||
messageId: "blockSameLine",
|
||||
fix: fixer => fixer.insertTextAfter(openingCurly, "\n")
|
||||
});
|
||||
}
|
||||
@ -110,7 +112,7 @@ module.exports = {
|
||||
if (tokenBeforeClosingCurly !== openingCurly && !singleLineException && astUtils.isTokenOnSameLine(tokenBeforeClosingCurly, closingCurly)) {
|
||||
context.report({
|
||||
node: closingCurly,
|
||||
message: CLOSE_MESSAGE_SINGLE,
|
||||
messageId: "singleLineClose",
|
||||
fix: fixer => fixer.insertTextBefore(closingCurly, "\n")
|
||||
});
|
||||
}
|
||||
@ -127,7 +129,7 @@ module.exports = {
|
||||
if (style === "1tbs" && !astUtils.isTokenOnSameLine(curlyToken, keywordToken)) {
|
||||
context.report({
|
||||
node: curlyToken,
|
||||
message: CLOSE_MESSAGE,
|
||||
messageId: "nextLineClose",
|
||||
fix: removeNewlineBetween(curlyToken, keywordToken)
|
||||
});
|
||||
}
|
||||
@ -135,7 +137,7 @@ module.exports = {
|
||||
if (style !== "1tbs" && astUtils.isTokenOnSameLine(curlyToken, keywordToken)) {
|
||||
context.report({
|
||||
node: curlyToken,
|
||||
message: CLOSE_MESSAGE_STROUSTRUP_ALLMAN,
|
||||
messageId: "sameLineClose",
|
||||
fix: fixer => fixer.insertTextAfter(curlyToken, "\n")
|
||||
});
|
||||
}
|
||||
|
8
tools/node_modules/eslint/lib/rules/callback-return.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/callback-return.js
generated
vendored
@ -20,7 +20,11 @@ module.exports = {
|
||||
schema: [{
|
||||
type: "array",
|
||||
items: { type: "string" }
|
||||
}]
|
||||
}],
|
||||
|
||||
messages: {
|
||||
missingReturn: "Expected return with your callback function."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -166,7 +170,7 @@ module.exports = {
|
||||
|
||||
// as long as you're the child of a function at this point you should be asked to return
|
||||
if (findClosestParentOfType(node, ["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"])) {
|
||||
context.report({ node, message: "Expected return with your callback function." });
|
||||
context.report({ node, messageId: "missingReturn" });
|
||||
}
|
||||
|
||||
}
|
||||
|
8
tools/node_modules/eslint/lib/rules/camelcase.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/camelcase.js
generated
vendored
@ -28,7 +28,11 @@ module.exports = {
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
messages: {
|
||||
notCamelCase: "Identifier '{{name}}' is not in camel case."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -62,7 +66,7 @@ module.exports = {
|
||||
function report(node) {
|
||||
if (reported.indexOf(node) < 0) {
|
||||
reported.push(node);
|
||||
context.report({ node, message: "Identifier '{{name}}' is not in camel case.", data: { name: node.name } });
|
||||
context.report({ node, messageId: "notCamelCase", data: { name: node.name } });
|
||||
}
|
||||
}
|
||||
|
||||
|
19
tools/node_modules/eslint/lib/rules/capitalized-comments.js
generated
vendored
19
tools/node_modules/eslint/lib/rules/capitalized-comments.js
generated
vendored
@ -15,9 +15,7 @@ const astUtils = require("../ast-utils");
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const ALWAYS_MESSAGE = "Comments should not begin with a lowercase character",
|
||||
NEVER_MESSAGE = "Comments should not begin with an uppercase character",
|
||||
DEFAULT_IGNORE_PATTERN = astUtils.COMMENTS_IGNORE_PATTERN,
|
||||
const DEFAULT_IGNORE_PATTERN = astUtils.COMMENTS_IGNORE_PATTERN,
|
||||
WHITESPACE = /\s/g,
|
||||
MAYBE_URL = /^\s*[^:/?#\s]+:\/\/[^?#]/, // TODO: Combine w/ max-len pattern?
|
||||
DEFAULTS = {
|
||||
@ -132,7 +130,12 @@ module.exports = {
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
messages: {
|
||||
unexpectedLowercaseComment: "Comments should not begin with a lowercase character",
|
||||
unexpectedUppercaseComment: "Comments should not begin with an uppercase character"
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -267,14 +270,14 @@ module.exports = {
|
||||
commentValid = isCommentValid(comment, options);
|
||||
|
||||
if (!commentValid) {
|
||||
const message = capitalize === "always"
|
||||
? ALWAYS_MESSAGE
|
||||
: NEVER_MESSAGE;
|
||||
const messageId = capitalize === "always"
|
||||
? "unexpectedLowercaseComment"
|
||||
: "unexpectedUppercaseComment";
|
||||
|
||||
context.report({
|
||||
node: null, // Intentionally using loc instead
|
||||
loc: comment.loc,
|
||||
message,
|
||||
messageId,
|
||||
fix(fixer) {
|
||||
const match = comment.value.match(LETTER_PATTERN);
|
||||
|
||||
|
10
tools/node_modules/eslint/lib/rules/class-methods-use-this.js
generated
vendored
10
tools/node_modules/eslint/lib/rules/class-methods-use-this.js
generated
vendored
@ -28,7 +28,11 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}]
|
||||
}],
|
||||
|
||||
messages: {
|
||||
missingThis: "Expected 'this' to be used by class method '{{name}}'."
|
||||
}
|
||||
},
|
||||
create(context) {
|
||||
const config = context.options[0] ? Object.assign({}, context.options[0]) : {};
|
||||
@ -80,9 +84,9 @@ module.exports = {
|
||||
if (isIncludedInstanceMethod(node.parent) && !methodUsesThis) {
|
||||
context.report({
|
||||
node,
|
||||
message: "Expected 'this' to be used by class method '{{classMethod}}'.",
|
||||
messageId: "missingThis",
|
||||
data: {
|
||||
classMethod: node.parent.key.name
|
||||
name: node.parent.key.name
|
||||
}
|
||||
});
|
||||
}
|
||||
|
11
tools/node_modules/eslint/lib/rules/comma-dangle.js
generated
vendored
11
tools/node_modules/eslint/lib/rules/comma-dangle.js
generated
vendored
@ -124,14 +124,17 @@ module.exports = {
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
messages: {
|
||||
unexpected: "Unexpected trailing comma.",
|
||||
missing: "Missing trailing comma."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const options = normalizeOptions(context.options[0]);
|
||||
const sourceCode = context.getSourceCode();
|
||||
const UNEXPECTED_MESSAGE = "Unexpected trailing comma.";
|
||||
const MISSING_MESSAGE = "Missing trailing comma.";
|
||||
|
||||
/**
|
||||
* Gets the last item of the given node.
|
||||
@ -230,7 +233,7 @@ module.exports = {
|
||||
context.report({
|
||||
node: lastItem,
|
||||
loc: trailingToken.loc.start,
|
||||
message: UNEXPECTED_MESSAGE,
|
||||
messageId: "unexpected",
|
||||
fix(fixer) {
|
||||
return fixer.remove(trailingToken);
|
||||
}
|
||||
@ -267,7 +270,7 @@ module.exports = {
|
||||
context.report({
|
||||
node: lastItem,
|
||||
loc: trailingToken.loc.end,
|
||||
message: MISSING_MESSAGE,
|
||||
messageId: "missing",
|
||||
fix(fixer) {
|
||||
return fixer.insertTextAfter(trailingToken, ",");
|
||||
}
|
||||
|
23
tools/node_modules/eslint/lib/rules/comma-spacing.js
generated
vendored
23
tools/node_modules/eslint/lib/rules/comma-spacing.js
generated
vendored
@ -34,7 +34,12 @@ module.exports = {
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
messages: {
|
||||
missing: "A space is required {{loc}} ','.",
|
||||
unexpected: "There should be no space {{loc}} ','."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -57,17 +62,17 @@ module.exports = {
|
||||
/**
|
||||
* Reports a spacing error with an appropriate message.
|
||||
* @param {ASTNode} node The binary expression node to report.
|
||||
* @param {string} dir Is the error "before" or "after" the comma?
|
||||
* @param {string} loc Is the error "before" or "after" the comma?
|
||||
* @param {ASTNode} otherNode The node at the left or right of `node`
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function report(node, dir, otherNode) {
|
||||
function report(node, loc, otherNode) {
|
||||
context.report({
|
||||
node,
|
||||
fix(fixer) {
|
||||
if (options[dir]) {
|
||||
if (dir === "before") {
|
||||
if (options[loc]) {
|
||||
if (loc === "before") {
|
||||
return fixer.insertTextBefore(node, " ");
|
||||
}
|
||||
return fixer.insertTextAfter(node, " ");
|
||||
@ -76,7 +81,7 @@ module.exports = {
|
||||
let start, end;
|
||||
const newText = "";
|
||||
|
||||
if (dir === "before") {
|
||||
if (loc === "before") {
|
||||
start = otherNode.range[1];
|
||||
end = node.range[0];
|
||||
} else {
|
||||
@ -87,11 +92,9 @@ module.exports = {
|
||||
return fixer.replaceTextRange([start, end], newText);
|
||||
|
||||
},
|
||||
message: options[dir]
|
||||
? "A space is required {{dir}} ','."
|
||||
: "There should be no space {{dir}} ','.",
|
||||
messageId: options[loc] ? "missing" : "unexpected",
|
||||
data: {
|
||||
dir
|
||||
loc
|
||||
}
|
||||
});
|
||||
}
|
||||
|
21
tools/node_modules/eslint/lib/rules/comma-style.js
generated
vendored
21
tools/node_modules/eslint/lib/rules/comma-style.js
generated
vendored
@ -36,7 +36,12 @@ module.exports = {
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
],
|
||||
messages: {
|
||||
unexpectedLineBeforeAndAfterComma: "Bad line breaking before and after ','.",
|
||||
expectedCommaFirst: "',' should be placed first.",
|
||||
expectedCommaLast: "',' should be placed last."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -49,7 +54,8 @@ module.exports = {
|
||||
FunctionDeclaration: true,
|
||||
FunctionExpression: true,
|
||||
ImportDeclaration: true,
|
||||
ObjectPattern: true
|
||||
ObjectPattern: true,
|
||||
NewExpression: true
|
||||
};
|
||||
|
||||
if (context.options.length === 2 && context.options[1].hasOwnProperty("exceptions")) {
|
||||
@ -134,7 +140,7 @@ module.exports = {
|
||||
line: commaToken.loc.end.line,
|
||||
column: commaToken.loc.start.column
|
||||
},
|
||||
message: "Bad line breaking before and after ','.",
|
||||
messageId: "unexpectedLineBeforeAndAfterComma",
|
||||
fix: getFixerFunction("between", previousItemToken, commaToken, currentItemToken)
|
||||
});
|
||||
|
||||
@ -142,7 +148,7 @@ module.exports = {
|
||||
|
||||
context.report({
|
||||
node: reportItem,
|
||||
message: "',' should be placed first.",
|
||||
messageId: "expectedCommaFirst",
|
||||
fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken)
|
||||
});
|
||||
|
||||
@ -154,7 +160,7 @@ module.exports = {
|
||||
line: commaToken.loc.end.line,
|
||||
column: commaToken.loc.end.column
|
||||
},
|
||||
message: "',' should be placed last.",
|
||||
messageId: "expectedCommaLast",
|
||||
fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken)
|
||||
});
|
||||
}
|
||||
@ -294,6 +300,11 @@ module.exports = {
|
||||
validateComma(node, "specifiers");
|
||||
};
|
||||
}
|
||||
if (!exceptions.NewExpression) {
|
||||
nodes.NewExpression = function(node) {
|
||||
validateComma(node, "arguments");
|
||||
};
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
8
tools/node_modules/eslint/lib/rules/complexity.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/complexity.js
generated
vendored
@ -50,7 +50,11 @@ module.exports = {
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
messages: {
|
||||
complex: "{{name}} has a complexity of {{complexity}}."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -96,7 +100,7 @@ module.exports = {
|
||||
if (complexity > THRESHOLD) {
|
||||
context.report({
|
||||
node,
|
||||
message: "{{name}} has a complexity of {{complexity}}.",
|
||||
messageId: "complex",
|
||||
data: { name, complexity }
|
||||
});
|
||||
}
|
||||
|
18
tools/node_modules/eslint/lib/rules/computed-property-spacing.js
generated
vendored
18
tools/node_modules/eslint/lib/rules/computed-property-spacing.js
generated
vendored
@ -25,7 +25,15 @@ module.exports = {
|
||||
{
|
||||
enum: ["always", "never"]
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
messages: {
|
||||
unexpectedSpaceBefore: "There should be no space before '{{tokenValue}}'.",
|
||||
unexpectedSpaceAfter: "There should be no space after '{{tokenValue}}'.",
|
||||
|
||||
missingSpaceBefore: "A space is required before '{{tokenValue}}'.",
|
||||
missingSpaceAfter: "A space is required after '{{tokenValue}}'."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -47,7 +55,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: token.loc.start,
|
||||
message: "There should be no space after '{{tokenValue}}'.",
|
||||
messageId: "unexpectedSpaceAfter",
|
||||
data: {
|
||||
tokenValue: token.value
|
||||
},
|
||||
@ -68,7 +76,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: token.loc.start,
|
||||
message: "There should be no space before '{{tokenValue}}'.",
|
||||
messageId: "unexpectedSpaceBefore",
|
||||
data: {
|
||||
tokenValue: token.value
|
||||
},
|
||||
@ -88,7 +96,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: token.loc.start,
|
||||
message: "A space is required after '{{tokenValue}}'.",
|
||||
messageId: "missingSpaceAfter",
|
||||
data: {
|
||||
tokenValue: token.value
|
||||
},
|
||||
@ -108,7 +116,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: token.loc.start,
|
||||
message: "A space is required before '{{tokenValue}}'.",
|
||||
messageId: "missingSpaceBefore",
|
||||
data: {
|
||||
tokenValue: token.value
|
||||
},
|
||||
|
19
tools/node_modules/eslint/lib/rules/consistent-return.js
generated
vendored
19
tools/node_modules/eslint/lib/rules/consistent-return.js
generated
vendored
@ -68,7 +68,13 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}]
|
||||
}],
|
||||
|
||||
messages: {
|
||||
missingReturn: "Expected to return a value at the end of {{name}}.",
|
||||
missingReturnValue: "{{name}} expected a return value.",
|
||||
unexpectedReturnValue: "{{name}} expected no return value."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -129,7 +135,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc,
|
||||
message: "Expected to return a value at the end of {{name}}.",
|
||||
messageId: "missingReturn",
|
||||
data: { name }
|
||||
});
|
||||
}
|
||||
@ -143,7 +149,7 @@ module.exports = {
|
||||
codePath,
|
||||
hasReturn: false,
|
||||
hasReturnValue: false,
|
||||
message: "",
|
||||
messageId: "",
|
||||
node
|
||||
};
|
||||
},
|
||||
@ -163,17 +169,16 @@ module.exports = {
|
||||
if (!funcInfo.hasReturn) {
|
||||
funcInfo.hasReturn = true;
|
||||
funcInfo.hasReturnValue = hasReturnValue;
|
||||
funcInfo.message = "{{name}} expected {{which}} return value.";
|
||||
funcInfo.messageId = hasReturnValue ? "missingReturnValue" : "unexpectedReturnValue";
|
||||
funcInfo.data = {
|
||||
name: funcInfo.node.type === "Program"
|
||||
? "Program"
|
||||
: lodash.upperFirst(astUtils.getFunctionNameWithKind(funcInfo.node)),
|
||||
which: hasReturnValue ? "a" : "no"
|
||||
: lodash.upperFirst(astUtils.getFunctionNameWithKind(funcInfo.node))
|
||||
};
|
||||
} else if (funcInfo.hasReturnValue !== hasReturnValue) {
|
||||
context.report({
|
||||
node,
|
||||
message: funcInfo.message,
|
||||
messageId: funcInfo.messageId,
|
||||
data: funcInfo.data
|
||||
});
|
||||
}
|
||||
|
13
tools/node_modules/eslint/lib/rules/consistent-this.js
generated
vendored
13
tools/node_modules/eslint/lib/rules/consistent-this.js
generated
vendored
@ -24,6 +24,11 @@ module.exports = {
|
||||
minLength: 1
|
||||
},
|
||||
uniqueItems: true
|
||||
},
|
||||
|
||||
messages: {
|
||||
aliasNotAssignedToThis: "Designated alias '{{name}}' is not assigned to 'this'.",
|
||||
unexpectedAlias: "Unexpected alias '{{name}}' for 'this'."
|
||||
}
|
||||
},
|
||||
|
||||
@ -40,11 +45,11 @@ module.exports = {
|
||||
* Reports that a variable declarator or assignment expression is assigning
|
||||
* a non-'this' value to the specified alias.
|
||||
* @param {ASTNode} node - The assigning node.
|
||||
* @param {string} alias - the name of the alias that was incorrectly used.
|
||||
* @param {string} name - the name of the alias that was incorrectly used.
|
||||
* @returns {void}
|
||||
*/
|
||||
function reportBadAssignment(node, alias) {
|
||||
context.report({ node, message: "Designated alias '{{alias}}' is not assigned to 'this'.", data: { alias } });
|
||||
function reportBadAssignment(node, name) {
|
||||
context.report({ node, messageId: "aliasNotAssignedToThis", data: { name } });
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,7 +68,7 @@ module.exports = {
|
||||
reportBadAssignment(node, name);
|
||||
}
|
||||
} else if (isThis) {
|
||||
context.report({ node, message: "Unexpected alias '{{name}}' for 'this'.", data: { name } });
|
||||
context.report({ node, messageId: "unexpectedAlias", data: { name } });
|
||||
}
|
||||
}
|
||||
|
||||
|
25
tools/node_modules/eslint/lib/rules/constructor-super.js
generated
vendored
25
tools/node_modules/eslint/lib/rules/constructor-super.js
generated
vendored
@ -99,7 +99,16 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/constructor-super"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
missingSome: "Lacked a call of 'super()' in some code paths.",
|
||||
missingAll: "Expected to call 'super()'.",
|
||||
|
||||
duplicate: "Unexpected duplicate 'super()'.",
|
||||
badSuper: "Unexpected 'super()' because 'super' is not a constructor.",
|
||||
unexpected: "Unexpected 'super()'."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -210,9 +219,9 @@ module.exports = {
|
||||
|
||||
if (!calledInEveryPaths) {
|
||||
context.report({
|
||||
message: calledInSomePaths
|
||||
? "Lacked a call of 'super()' in some code paths."
|
||||
: "Expected to call 'super()'.",
|
||||
messageId: calledInSomePaths
|
||||
? "missingSome"
|
||||
: "missingAll",
|
||||
node: node.parent
|
||||
});
|
||||
}
|
||||
@ -281,7 +290,7 @@ module.exports = {
|
||||
const node = nodes[i];
|
||||
|
||||
context.report({
|
||||
message: "Unexpected duplicate 'super()'.",
|
||||
messageId: "duplicate",
|
||||
node
|
||||
});
|
||||
}
|
||||
@ -325,12 +334,12 @@ module.exports = {
|
||||
if (info) {
|
||||
if (duplicate) {
|
||||
context.report({
|
||||
message: "Unexpected duplicate 'super()'.",
|
||||
messageId: "duplicate",
|
||||
node
|
||||
});
|
||||
} else if (!funcInfo.superIsConstructor) {
|
||||
context.report({
|
||||
message: "Unexpected 'super()' because 'super' is not a constructor.",
|
||||
messageId: "badSuper",
|
||||
node
|
||||
});
|
||||
} else {
|
||||
@ -339,7 +348,7 @@ module.exports = {
|
||||
}
|
||||
} else if (funcInfo.codePath.currentSegments.some(isReachable)) {
|
||||
context.report({
|
||||
message: "Unexpected 'super()'.",
|
||||
messageId: "unexpected",
|
||||
node
|
||||
});
|
||||
}
|
||||
|
158
tools/node_modules/eslint/lib/rules/curly.js
generated
vendored
158
tools/node_modules/eslint/lib/rules/curly.js
generated
vendored
@ -51,7 +51,14 @@ module.exports = {
|
||||
]
|
||||
},
|
||||
|
||||
fixable: "code"
|
||||
fixable: "code",
|
||||
|
||||
messages: {
|
||||
missingCurlyAfter: "Expected { after '{{name}}'.",
|
||||
missingCurlyAfterCondition: "Expected { after '{{name}}' condition.",
|
||||
unexpectedCurlyAfter: "Unnecessary { after '{{name}}'.",
|
||||
unexpectedCurlyAfterCondition: "Unnecessary { after '{{name}}' condition."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -130,40 +137,20 @@ module.exports = {
|
||||
return true;
|
||||
}
|
||||
|
||||
node = node.consequent.body[0];
|
||||
while (node) {
|
||||
if (node.type === "IfStatement" && !node.alternate) {
|
||||
for (
|
||||
let currentNode = node.consequent.body[0];
|
||||
currentNode;
|
||||
currentNode = astUtils.getTrailingStatement(currentNode)
|
||||
) {
|
||||
if (currentNode.type === "IfStatement" && !currentNode.alternate) {
|
||||
return true;
|
||||
}
|
||||
node = astUtils.getTrailingStatement(node);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports "Expected { after ..." error
|
||||
* @param {ASTNode} node The node to report.
|
||||
* @param {ASTNode} bodyNode The body node that is incorrectly missing curly brackets
|
||||
* @param {string} name The name to report.
|
||||
* @param {string} suffix Additional string to add to the end of a report.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function reportExpectedBraceError(node, bodyNode, name, suffix) {
|
||||
context.report({
|
||||
node,
|
||||
loc: (name !== "else" ? node : getElseKeyword(node)).loc.start,
|
||||
message: "Expected { after '{{name}}'{{suffix}}.",
|
||||
data: {
|
||||
name,
|
||||
suffix: (suffix ? ` ${suffix}` : "")
|
||||
},
|
||||
fix: fixer => fixer.replaceText(bodyNode, `{${sourceCode.getText(bodyNode)}}`)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a semicolon needs to be inserted after removing a set of curly brackets, in order to avoid a SyntaxError.
|
||||
* @param {Token} closingBracket The } token
|
||||
@ -218,62 +205,12 @@ module.exports = {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports "Unnecessary { after ..." error
|
||||
* @param {ASTNode} node The node to report.
|
||||
* @param {ASTNode} bodyNode The block statement that is incorrectly surrounded by parens
|
||||
* @param {string} name The name to report.
|
||||
* @param {string} suffix Additional string to add to the end of a report.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function reportUnnecessaryBraceError(node, bodyNode, name, suffix) {
|
||||
context.report({
|
||||
node,
|
||||
loc: (name !== "else" ? node : getElseKeyword(node)).loc.start,
|
||||
message: "Unnecessary { after '{{name}}'{{suffix}}.",
|
||||
data: {
|
||||
name,
|
||||
suffix: (suffix ? ` ${suffix}` : "")
|
||||
},
|
||||
fix(fixer) {
|
||||
|
||||
/*
|
||||
* `do while` expressions sometimes need a space to be inserted after `do`.
|
||||
* e.g. `do{foo()} while (bar)` should be corrected to `do foo() while (bar)`
|
||||
*/
|
||||
const needsPrecedingSpace = node.type === "DoWhileStatement" &&
|
||||
sourceCode.getTokenBefore(bodyNode).range[1] === bodyNode.range[0] &&
|
||||
!astUtils.canTokensBeAdjacent("do", sourceCode.getFirstToken(bodyNode, { skip: 1 }));
|
||||
|
||||
const openingBracket = sourceCode.getFirstToken(bodyNode);
|
||||
const closingBracket = sourceCode.getLastToken(bodyNode);
|
||||
const lastTokenInBlock = sourceCode.getTokenBefore(closingBracket);
|
||||
|
||||
if (needsSemicolon(closingBracket)) {
|
||||
|
||||
/*
|
||||
* If removing braces would cause a SyntaxError due to multiple statements on the same line (or
|
||||
* change the semantics of the code due to ASI), don't perform a fix.
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
|
||||
const resultingBodyText = sourceCode.getText().slice(openingBracket.range[1], lastTokenInBlock.range[0]) +
|
||||
sourceCode.getText(lastTokenInBlock) +
|
||||
sourceCode.getText().slice(lastTokenInBlock.range[1], closingBracket.range[0]);
|
||||
|
||||
return fixer.replaceText(bodyNode, (needsPrecedingSpace ? " " : "") + resultingBodyText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares to check the body of a node to see if it's a block statement.
|
||||
* @param {ASTNode} node The node to report if there's a problem.
|
||||
* @param {ASTNode} body The body node to check for blocks.
|
||||
* @param {string} name The name to report if there's a problem.
|
||||
* @param {string} suffix Additional string to add to the end of a report.
|
||||
* @param {{ condition: boolean }} opts Options to pass to the report functions
|
||||
* @returns {Object} a prepared check object, with "actual", "expected", "check" properties.
|
||||
* "actual" will be `true` or `false` whether the body is already a block statement.
|
||||
* "expected" will be `true` or `false` if the body should be a block statement or not, or
|
||||
@ -282,7 +219,7 @@ module.exports = {
|
||||
* "check" will be a function reporting appropriate problems depending on the other
|
||||
* properties.
|
||||
*/
|
||||
function prepareCheck(node, body, name, suffix) {
|
||||
function prepareCheck(node, body, name, opts) {
|
||||
const hasBlock = (body.type === "BlockStatement");
|
||||
let expected = null;
|
||||
|
||||
@ -314,9 +251,53 @@ module.exports = {
|
||||
check() {
|
||||
if (this.expected !== null && this.expected !== this.actual) {
|
||||
if (this.expected) {
|
||||
reportExpectedBraceError(node, body, name, suffix);
|
||||
context.report({
|
||||
node,
|
||||
loc: (name !== "else" ? node : getElseKeyword(node)).loc.start,
|
||||
messageId: opts && opts.condition ? "missingCurlyAfterCondition" : "missingCurlyAfter",
|
||||
data: {
|
||||
name
|
||||
},
|
||||
fix: fixer => fixer.replaceText(body, `{${sourceCode.getText(body)}}`)
|
||||
});
|
||||
} else {
|
||||
reportUnnecessaryBraceError(node, body, name, suffix);
|
||||
context.report({
|
||||
node,
|
||||
loc: (name !== "else" ? node : getElseKeyword(node)).loc.start,
|
||||
messageId: opts && opts.condition ? "unexpectedCurlyAfterCondition" : "unexpectedCurlyAfter",
|
||||
data: {
|
||||
name
|
||||
},
|
||||
fix(fixer) {
|
||||
|
||||
/*
|
||||
* `do while` expressions sometimes need a space to be inserted after `do`.
|
||||
* e.g. `do{foo()} while (bar)` should be corrected to `do foo() while (bar)`
|
||||
*/
|
||||
const needsPrecedingSpace = node.type === "DoWhileStatement" &&
|
||||
sourceCode.getTokenBefore(body).range[1] === body.range[0] &&
|
||||
!astUtils.canTokensBeAdjacent("do", sourceCode.getFirstToken(body, { skip: 1 }));
|
||||
|
||||
const openingBracket = sourceCode.getFirstToken(body);
|
||||
const closingBracket = sourceCode.getLastToken(body);
|
||||
const lastTokenInBlock = sourceCode.getTokenBefore(closingBracket);
|
||||
|
||||
if (needsSemicolon(closingBracket)) {
|
||||
|
||||
/*
|
||||
* If removing braces would cause a SyntaxError due to multiple statements on the same line (or
|
||||
* change the semantics of the code due to ASI), don't perform a fix.
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
|
||||
const resultingBodyText = sourceCode.getText().slice(openingBracket.range[1], lastTokenInBlock.range[0]) +
|
||||
sourceCode.getText(lastTokenInBlock) +
|
||||
sourceCode.getText().slice(lastTokenInBlock.range[1], closingBracket.range[0]);
|
||||
|
||||
return fixer.replaceText(body, (needsPrecedingSpace ? " " : "") + resultingBodyText);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -332,14 +313,13 @@ module.exports = {
|
||||
function prepareIfChecks(node) {
|
||||
const preparedChecks = [];
|
||||
|
||||
do {
|
||||
preparedChecks.push(prepareCheck(node, node.consequent, "if", "condition"));
|
||||
if (node.alternate && node.alternate.type !== "IfStatement") {
|
||||
preparedChecks.push(prepareCheck(node, node.alternate, "else"));
|
||||
for (let currentNode = node; currentNode; currentNode = currentNode.alternate) {
|
||||
preparedChecks.push(prepareCheck(currentNode, currentNode.consequent, "if", { condition: true }));
|
||||
if (currentNode.alternate && currentNode.alternate.type !== "IfStatement") {
|
||||
preparedChecks.push(prepareCheck(currentNode, currentNode.alternate, "else"));
|
||||
break;
|
||||
}
|
||||
node = node.alternate;
|
||||
} while (node);
|
||||
}
|
||||
|
||||
if (consistent) {
|
||||
|
||||
@ -377,7 +357,7 @@ module.exports = {
|
||||
},
|
||||
|
||||
WhileStatement(node) {
|
||||
prepareCheck(node, node.body, "while", "condition").check();
|
||||
prepareCheck(node, node.body, "while", { condition: true }).check();
|
||||
},
|
||||
|
||||
DoWhileStatement(node) {
|
||||
@ -385,7 +365,7 @@ module.exports = {
|
||||
},
|
||||
|
||||
ForStatement(node) {
|
||||
prepareCheck(node, node.body, "for", "condition").check();
|
||||
prepareCheck(node, node.body, "for", { condition: true }).check();
|
||||
},
|
||||
|
||||
ForInStatement(node) {
|
||||
|
8
tools/node_modules/eslint/lib/rules/default-case.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/default-case.js
generated
vendored
@ -27,7 +27,11 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}]
|
||||
}],
|
||||
|
||||
messages: {
|
||||
missingDefaultCase: "Expected a default case."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -82,7 +86,7 @@ module.exports = {
|
||||
}
|
||||
|
||||
if (!comment || !commentPattern.test(comment.value.trim())) {
|
||||
context.report({ node, message: "Expected a default case." });
|
||||
context.report({ node, messageId: "missingDefaultCase" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
tools/node_modules/eslint/lib/rules/dot-location.js
generated
vendored
11
tools/node_modules/eslint/lib/rules/dot-location.js
generated
vendored
@ -26,7 +26,12 @@ module.exports = {
|
||||
}
|
||||
],
|
||||
|
||||
fixable: "code"
|
||||
fixable: "code",
|
||||
|
||||
messages: {
|
||||
expectedDotAfterObject: "Expected dot to be on same line as object.",
|
||||
expectedDotBeforeProperty: "Expected dot to be on same line as property."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -58,7 +63,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: dot.loc.start,
|
||||
message: "Expected dot to be on same line as object.",
|
||||
messageId: "expectedDotAfterObject",
|
||||
fix: fixer => fixer.replaceTextRange([obj.range[1], prop.range[0]], `${neededTextAfterObj}.${textBeforeDot}${textAfterDot}`)
|
||||
});
|
||||
}
|
||||
@ -66,7 +71,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: dot.loc.start,
|
||||
message: "Expected dot to be on same line as property.",
|
||||
messageId: "expectedDotBeforeProperty",
|
||||
fix: fixer => fixer.replaceTextRange([obj.range[1], prop.range[0]], `${textBeforeDot}${textAfterDot}.`)
|
||||
});
|
||||
}
|
||||
|
15
tools/node_modules/eslint/lib/rules/dot-notation.js
generated
vendored
15
tools/node_modules/eslint/lib/rules/dot-notation.js
generated
vendored
@ -41,7 +41,12 @@ module.exports = {
|
||||
}
|
||||
],
|
||||
|
||||
fixable: "code"
|
||||
fixable: "code",
|
||||
|
||||
messages: {
|
||||
useDot: "[{{key}}] is better written in dot notation.",
|
||||
useBrackets: ".{{key}} is a syntax error."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -71,9 +76,9 @@ module.exports = {
|
||||
|
||||
context.report({
|
||||
node: node.property,
|
||||
message: "[{{propertyValue}}] is better written in dot notation.",
|
||||
messageId: "useDot",
|
||||
data: {
|
||||
propertyValue: formattedValue
|
||||
key: formattedValue
|
||||
},
|
||||
fix(fixer) {
|
||||
const leftBracket = sourceCode.getTokenAfter(node.object, astUtils.isOpeningBracketToken);
|
||||
@ -124,9 +129,9 @@ module.exports = {
|
||||
) {
|
||||
context.report({
|
||||
node: node.property,
|
||||
message: ".{{propertyName}} is a syntax error.",
|
||||
messageId: "useBrackets",
|
||||
data: {
|
||||
propertyName: node.property.name
|
||||
key: node.property.name
|
||||
},
|
||||
fix(fixer) {
|
||||
const dot = sourceCode.getTokenBefore(node.property);
|
||||
|
10
tools/node_modules/eslint/lib/rules/eol-last.js
generated
vendored
10
tools/node_modules/eslint/lib/rules/eol-last.js
generated
vendored
@ -27,7 +27,11 @@ module.exports = {
|
||||
{
|
||||
enum: ["always", "never", "unix", "windows"]
|
||||
}
|
||||
]
|
||||
],
|
||||
messages: {
|
||||
missing: "Newline required at end of file but not found.",
|
||||
unexpected: "Newline not allowed at end of file."
|
||||
}
|
||||
},
|
||||
create(context) {
|
||||
|
||||
@ -75,7 +79,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: location,
|
||||
message: "Newline required at end of file but not found.",
|
||||
messageId: "missing",
|
||||
fix(fixer) {
|
||||
return fixer.insertTextAfterRange([0, src.length], appendCRLF ? CRLF : LF);
|
||||
}
|
||||
@ -86,7 +90,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: location,
|
||||
message: "Newline not allowed at end of file.",
|
||||
messageId: "unexpected",
|
||||
fix(fixer) {
|
||||
const finalEOLs = /(?:\r?\n)+$/,
|
||||
match = finalEOLs.exec(sourceCode.text),
|
||||
|
8
tools/node_modules/eslint/lib/rules/eqeqeq.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/eqeqeq.js
generated
vendored
@ -56,7 +56,11 @@ module.exports = {
|
||||
]
|
||||
},
|
||||
|
||||
fixable: "code"
|
||||
fixable: "code",
|
||||
|
||||
messages: {
|
||||
unexpected: "Expected '{{expectedOperator}}' and instead saw '{{actualOperator}}'."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -134,7 +138,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: getOperatorLocation(node),
|
||||
message: "Expected '{{expectedOperator}}' and instead saw '{{actualOperator}}'.",
|
||||
messageId: "unexpected",
|
||||
data: { expectedOperator, actualOperator: node.operator },
|
||||
fix(fixer) {
|
||||
|
||||
|
3
tools/node_modules/eslint/lib/rules/generator-star-spacing.js
generated
vendored
3
tools/node_modules/eslint/lib/rules/generator-star-spacing.js
generated
vendored
@ -85,7 +85,6 @@ module.exports = {
|
||||
}
|
||||
|
||||
const modes = (function(option) {
|
||||
option = option || {};
|
||||
const defaults = optionToDefinition(option, optionDefinitions.before);
|
||||
|
||||
return {
|
||||
@ -93,7 +92,7 @@ module.exports = {
|
||||
anonymous: optionToDefinition(option.anonymous, defaults),
|
||||
method: optionToDefinition(option.method, defaults)
|
||||
};
|
||||
}(context.options[0]));
|
||||
}(context.options[0] || {}));
|
||||
|
||||
const sourceCode = context.getSourceCode();
|
||||
|
||||
|
42
tools/node_modules/eslint/lib/rules/guard-for-in.js
generated
vendored
42
tools/node_modules/eslint/lib/rules/guard-for-in.js
generated
vendored
@ -26,17 +26,45 @@ module.exports = {
|
||||
return {
|
||||
|
||||
ForInStatement(node) {
|
||||
const body = node.body;
|
||||
|
||||
/*
|
||||
* If the for-in statement has {}, then the real body is the body
|
||||
* of the BlockStatement. Otherwise, just use body as provided.
|
||||
*/
|
||||
const body = node.body.type === "BlockStatement" ? node.body.body[0] : node.body;
|
||||
// empty statement
|
||||
if (body.type === "EmptyStatement") {
|
||||
return;
|
||||
}
|
||||
|
||||
// if statement
|
||||
if (body.type === "IfStatement") {
|
||||
return;
|
||||
}
|
||||
|
||||
// empty block
|
||||
if (body.type === "BlockStatement" && body.body.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// block with just if statement
|
||||
if (body.type === "BlockStatement" && body.body.length === 1 && body.body[0].type === "IfStatement") {
|
||||
return;
|
||||
}
|
||||
|
||||
// block that starts with if statement
|
||||
if (body.type === "BlockStatement" && body.body.length >= 1 && body.body[0].type === "IfStatement") {
|
||||
const i = body.body[0];
|
||||
|
||||
// ... whose consequent is a continue
|
||||
if (i.consequent.type === "ContinueStatement") {
|
||||
return;
|
||||
}
|
||||
|
||||
// ... whose consequent is a block that contains only a continue
|
||||
if (i.consequent.type === "BlockStatement" && i.consequent.body.length === 1 && i.consequent.body[0].type === "ContinueStatement") {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (body && body.type !== "IfStatement") {
|
||||
context.report({ node, message: "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype." });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
17
tools/node_modules/eslint/lib/rules/indent-legacy.js
generated
vendored
17
tools/node_modules/eslint/lib/rules/indent-legacy.js
generated
vendored
@ -505,12 +505,9 @@ module.exports = {
|
||||
*/
|
||||
function getParentNodeByType(node, type, stopAtList) {
|
||||
let parent = node.parent;
|
||||
const stopAtSet = new Set(stopAtList || ["Program"]);
|
||||
|
||||
if (!stopAtList) {
|
||||
stopAtList = ["Program"];
|
||||
}
|
||||
|
||||
while (parent.type !== type && stopAtList.indexOf(parent.type) === -1 && parent.type !== "Program") {
|
||||
while (parent.type !== type && !stopAtSet.has(parent.type) && parent.type !== "Program") {
|
||||
parent = parent.parent;
|
||||
}
|
||||
|
||||
@ -941,19 +938,19 @@ module.exports = {
|
||||
/**
|
||||
* Returns the expected indentation for the case statement
|
||||
* @param {ASTNode} node node to examine
|
||||
* @param {int} [switchIndent] indent for switch statement
|
||||
* @param {int} [providedSwitchIndent] indent for switch statement
|
||||
* @returns {int} indent size
|
||||
*/
|
||||
function expectedCaseIndent(node, switchIndent) {
|
||||
function expectedCaseIndent(node, providedSwitchIndent) {
|
||||
const switchNode = (node.type === "SwitchStatement") ? node : node.parent;
|
||||
const switchIndent = typeof providedSwitchIndent === "undefined"
|
||||
? getNodeIndent(switchNode).goodChar
|
||||
: providedSwitchIndent;
|
||||
let caseIndent;
|
||||
|
||||
if (caseIndentStore[switchNode.loc.start.line]) {
|
||||
return caseIndentStore[switchNode.loc.start.line];
|
||||
}
|
||||
if (typeof switchIndent === "undefined") {
|
||||
switchIndent = getNodeIndent(switchNode).goodChar;
|
||||
}
|
||||
|
||||
if (switchNode.cases.length > 0 && options.SwitchCase === 0) {
|
||||
caseIndent = switchIndent;
|
||||
|
86
tools/node_modules/eslint/lib/rules/indent.js
generated
vendored
86
tools/node_modules/eslint/lib/rules/indent.js
generated
vendored
@ -442,6 +442,7 @@ class OffsetStorage {
|
||||
const offset = (
|
||||
offsetInfo.from &&
|
||||
offsetInfo.from.loc.start.line === token.loc.start.line &&
|
||||
!/^\s*?\n/.test(token.value) &&
|
||||
!offsetInfo.force
|
||||
) ? 0 : offsetInfo.offset * this._indentSize;
|
||||
|
||||
@ -778,6 +779,19 @@ module.exports = {
|
||||
return (statement.type === "ExpressionStatement" || statement.type === "VariableDeclaration") && statement.parent.type === "Program";
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of linebreaks that follow the last non-whitespace character in a string
|
||||
* @param {string} string The string to check
|
||||
* @returns {number} The number of JavaScript linebreaks that follow the last non-whitespace character,
|
||||
* or the total number of linebreaks if the string is all whitespace.
|
||||
*/
|
||||
function countTrailingLinebreaks(string) {
|
||||
const trailingWhitespace = string.match(/\s*$/)[0];
|
||||
const linebreakMatches = trailingWhitespace.match(astUtils.createGlobalLinebreakMatcher());
|
||||
|
||||
return linebreakMatches === null ? 0 : linebreakMatches.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check indentation for lists of elements (arrays, objects, function params)
|
||||
* @param {ASTNode[]} elements List of elements that should be offset
|
||||
@ -835,8 +849,12 @@ module.exports = {
|
||||
} else {
|
||||
const previousElement = elements[index - 1];
|
||||
const firstTokenOfPreviousElement = previousElement && getFirstToken(previousElement);
|
||||
const previousElementLastToken = previousElement && sourceCode.getLastToken(previousElement);
|
||||
|
||||
if (previousElement && sourceCode.getLastToken(previousElement).loc.start.line > startToken.loc.end.line) {
|
||||
if (
|
||||
previousElement &&
|
||||
previousElementLastToken.loc.end.line - countTrailingLinebreaks(previousElementLastToken.value) > startToken.loc.end.line
|
||||
) {
|
||||
offsets.setDesiredOffsets(element.range, firstTokenOfPreviousElement, 0);
|
||||
}
|
||||
}
|
||||
@ -979,6 +997,8 @@ module.exports = {
|
||||
return !node || node.loc.start.line === token.loc.start.line;
|
||||
}
|
||||
|
||||
const ignoredNodeFirstTokens = new Set();
|
||||
|
||||
const baseOffsetListeners = {
|
||||
"ArrayExpression, ArrayPattern"(node) {
|
||||
const openingBracket = sourceCode.getFirstToken(node);
|
||||
@ -1009,15 +1029,6 @@ module.exports = {
|
||||
addElementListIndent(node.params, openingParen, closingParen, options.FunctionExpression.parameters);
|
||||
}
|
||||
addBlocklessNodeIndent(node.body);
|
||||
|
||||
let arrowToken;
|
||||
|
||||
if (node.params.length) {
|
||||
arrowToken = sourceCode.getTokenAfter(node.params[node.params.length - 1], astUtils.isArrowToken);
|
||||
} else {
|
||||
arrowToken = sourceCode.getFirstToken(node, astUtils.isArrowToken);
|
||||
}
|
||||
offsets.setDesiredOffset(arrowToken, sourceCode.getFirstToken(node), 0);
|
||||
},
|
||||
|
||||
AssignmentExpression(node) {
|
||||
@ -1042,7 +1053,6 @@ module.exports = {
|
||||
offsets.ignoreToken(operator);
|
||||
offsets.ignoreToken(tokenAfterOperator);
|
||||
offsets.setDesiredOffset(tokenAfterOperator, operator, 0);
|
||||
offsets.setDesiredOffsets([tokenAfterOperator.range[1], node.range[1]], tokenAfterOperator, 1);
|
||||
},
|
||||
|
||||
"BlockStatement, ClassBody"(node) {
|
||||
@ -1094,8 +1104,8 @@ module.exports = {
|
||||
const questionMarkToken = sourceCode.getFirstTokenBetween(node.test, node.consequent, token => token.type === "Punctuator" && token.value === "?");
|
||||
const colonToken = sourceCode.getFirstTokenBetween(node.consequent, node.alternate, token => token.type === "Punctuator" && token.value === ":");
|
||||
|
||||
const firstConsequentToken = sourceCode.getTokenAfter(questionMarkToken, { includeComments: true });
|
||||
const lastConsequentToken = sourceCode.getTokenBefore(colonToken, { includeComments: true });
|
||||
const firstConsequentToken = sourceCode.getTokenAfter(questionMarkToken);
|
||||
const lastConsequentToken = sourceCode.getTokenBefore(colonToken);
|
||||
const firstAlternateToken = sourceCode.getTokenAfter(colonToken);
|
||||
|
||||
offsets.setDesiredOffset(questionMarkToken, firstToken, 1);
|
||||
@ -1128,9 +1138,6 @@ module.exports = {
|
||||
*/
|
||||
offsets.setDesiredOffset(firstAlternateToken, firstToken, 1);
|
||||
}
|
||||
|
||||
offsets.setDesiredOffsets([questionMarkToken.range[1], colonToken.range[0]], firstConsequentToken, 0);
|
||||
offsets.setDesiredOffsets([colonToken.range[1], node.range[1]], firstAlternateToken, 0);
|
||||
}
|
||||
},
|
||||
|
||||
@ -1272,20 +1279,9 @@ module.exports = {
|
||||
SwitchStatement(node) {
|
||||
const openingCurly = sourceCode.getTokenAfter(node.discriminant, astUtils.isOpeningBraceToken);
|
||||
const closingCurly = sourceCode.getLastToken(node);
|
||||
const caseKeywords = node.cases.map(switchCase => sourceCode.getFirstToken(switchCase));
|
||||
|
||||
offsets.setDesiredOffsets([openingCurly.range[1], closingCurly.range[0]], openingCurly, options.SwitchCase);
|
||||
|
||||
node.cases.forEach((switchCase, index) => {
|
||||
const caseKeyword = caseKeywords[index];
|
||||
|
||||
if (!(switchCase.consequent.length === 1 && switchCase.consequent[0].type === "BlockStatement")) {
|
||||
const tokenAfterCurrentCase = index === node.cases.length - 1 ? closingCurly : caseKeywords[index + 1];
|
||||
|
||||
offsets.setDesiredOffsets([caseKeyword.range[1], tokenAfterCurrentCase.range[0]], caseKeyword, 1);
|
||||
}
|
||||
});
|
||||
|
||||
if (node.cases.length) {
|
||||
sourceCode.getTokensBetween(
|
||||
node.cases[node.cases.length - 1],
|
||||
@ -1295,6 +1291,15 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
|
||||
SwitchCase(node) {
|
||||
if (!(node.consequent.length === 1 && node.consequent[0].type === "BlockStatement")) {
|
||||
const caseKeyword = sourceCode.getFirstToken(node);
|
||||
const tokenAfterCurrentCase = sourceCode.getTokenAfter(node);
|
||||
|
||||
offsets.setDesiredOffsets([caseKeyword.range[1], tokenAfterCurrentCase.range[0]], caseKeyword, 1);
|
||||
}
|
||||
},
|
||||
|
||||
TemplateLiteral(node) {
|
||||
node.expressions.forEach((expression, index) => {
|
||||
const previousQuasi = node.quasis[index];
|
||||
@ -1385,7 +1390,6 @@ module.exports = {
|
||||
const firstToken = sourceCode.getFirstToken(node);
|
||||
|
||||
offsets.setDesiredOffsets(node.name.range, firstToken, 1);
|
||||
offsets.setDesiredOffset(sourceCode.getLastToken(node), firstToken, 0);
|
||||
},
|
||||
|
||||
JSXExpressionContainer(node) {
|
||||
@ -1397,7 +1401,15 @@ module.exports = {
|
||||
openingCurly,
|
||||
1
|
||||
);
|
||||
offsets.setDesiredOffset(closingCurly, openingCurly, 0);
|
||||
},
|
||||
|
||||
"*"(node) {
|
||||
const firstToken = sourceCode.getFirstToken(node);
|
||||
|
||||
// Ensure that the children of every node are indented at least as much as the first token.
|
||||
if (firstToken && !ignoredNodeFirstTokens.has(firstToken)) {
|
||||
offsets.setDesiredOffsets(node.range, firstToken, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -1406,7 +1418,8 @@ module.exports = {
|
||||
/*
|
||||
* To ignore the indentation of a node:
|
||||
* 1. Don't call the node's listener when entering it (if it has a listener)
|
||||
* 2. Call `ignoreNode` on the node sometime after exiting it and before validating offsets.
|
||||
* 2. Don't set any offsets against the first token of the node.
|
||||
* 3. Call `ignoreNode` on the node sometime after exiting it and before validating offsets.
|
||||
*/
|
||||
const offsetListeners = lodash.mapValues(
|
||||
baseOffsetListeners,
|
||||
@ -1434,7 +1447,16 @@ module.exports = {
|
||||
|
||||
// For each ignored node selector, set up a listener to collect it into the `ignoredNodes` set.
|
||||
const ignoredNodes = new Set();
|
||||
const addToIgnoredNodes = ignoredNodes.add.bind(ignoredNodes);
|
||||
|
||||
/**
|
||||
* Ignores a node
|
||||
* @param {ASTNode} node The node to ignore
|
||||
* @returns {void}
|
||||
*/
|
||||
function addToIgnoredNodes(node) {
|
||||
ignoredNodes.add(node);
|
||||
ignoredNodeFirstTokens.add(sourceCode.getFirstToken(node));
|
||||
}
|
||||
|
||||
const ignoredNodeListeners = options.ignoredNodes.reduce(
|
||||
(listeners, ignoredSelector) => Object.assign(listeners, { [ignoredSelector]: addToIgnoredNodes }),
|
||||
@ -1457,7 +1479,7 @@ module.exports = {
|
||||
|
||||
// If a node's type is nonstandard, we can't tell how its children should be offset, so ignore it.
|
||||
if (!KNOWN_NODES.has(node.type)) {
|
||||
ignoredNodes.add(node);
|
||||
addToIgnoredNodes(node);
|
||||
}
|
||||
},
|
||||
"Program:exit"() {
|
||||
|
5
tools/node_modules/eslint/lib/rules/key-spacing.js
generated
vendored
5
tools/node_modules/eslint/lib/rules/key-spacing.js
generated
vendored
@ -360,9 +360,10 @@ module.exports = {
|
||||
*/
|
||||
function isKeyValueProperty(property) {
|
||||
return !(
|
||||
(property.method ||
|
||||
property.method ||
|
||||
property.shorthand ||
|
||||
property.kind !== "init" || property.type !== "Property") // Could be "ExperimentalSpreadProperty" or "SpreadProperty"
|
||||
property.kind !== "init" ||
|
||||
property.type !== "Property" // Could be "ExperimentalSpreadProperty" or "SpreadElement"
|
||||
);
|
||||
}
|
||||
|
||||
|
29
tools/node_modules/eslint/lib/rules/keyword-spacing.js
generated
vendored
29
tools/node_modules/eslint/lib/rules/keyword-spacing.js
generated
vendored
@ -108,13 +108,10 @@ module.exports = {
|
||||
* Reports a given token if there are not space(s) before the token.
|
||||
*
|
||||
* @param {Token} token - A token to report.
|
||||
* @param {RegExp|undefined} pattern - Optional. A pattern of the previous
|
||||
* token to check.
|
||||
* @param {RegExp} pattern - A pattern of the previous token to check.
|
||||
* @returns {void}
|
||||
*/
|
||||
function expectSpaceBefore(token, pattern) {
|
||||
pattern = pattern || PREV_TOKEN;
|
||||
|
||||
const prevToken = sourceCode.getTokenBefore(token);
|
||||
|
||||
if (prevToken &&
|
||||
@ -138,13 +135,10 @@ module.exports = {
|
||||
* Reports a given token if there are space(s) before the token.
|
||||
*
|
||||
* @param {Token} token - A token to report.
|
||||
* @param {RegExp|undefined} pattern - Optional. A pattern of the previous
|
||||
* token to check.
|
||||
* @param {RegExp} pattern - A pattern of the previous token to check.
|
||||
* @returns {void}
|
||||
*/
|
||||
function unexpectSpaceBefore(token, pattern) {
|
||||
pattern = pattern || PREV_TOKEN;
|
||||
|
||||
const prevToken = sourceCode.getTokenBefore(token);
|
||||
|
||||
if (prevToken &&
|
||||
@ -168,13 +162,10 @@ module.exports = {
|
||||
* Reports a given token if there are not space(s) after the token.
|
||||
*
|
||||
* @param {Token} token - A token to report.
|
||||
* @param {RegExp|undefined} pattern - Optional. A pattern of the next
|
||||
* token to check.
|
||||
* @param {RegExp} pattern - A pattern of the next token to check.
|
||||
* @returns {void}
|
||||
*/
|
||||
function expectSpaceAfter(token, pattern) {
|
||||
pattern = pattern || NEXT_TOKEN;
|
||||
|
||||
const nextToken = sourceCode.getTokenAfter(token);
|
||||
|
||||
if (nextToken &&
|
||||
@ -198,13 +189,10 @@ module.exports = {
|
||||
* Reports a given token if there are space(s) after the token.
|
||||
*
|
||||
* @param {Token} token - A token to report.
|
||||
* @param {RegExp|undefined} pattern - Optional. A pattern of the next
|
||||
* token to check.
|
||||
* @param {RegExp} pattern - A pattern of the next token to check.
|
||||
* @returns {void}
|
||||
*/
|
||||
function unexpectSpaceAfter(token, pattern) {
|
||||
pattern = pattern || NEXT_TOKEN;
|
||||
|
||||
const nextToken = sourceCode.getTokenAfter(token);
|
||||
|
||||
if (nextToken &&
|
||||
@ -274,7 +262,7 @@ module.exports = {
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkSpacingBefore(token, pattern) {
|
||||
checkMethodMap[token.value].before(token, pattern);
|
||||
checkMethodMap[token.value].before(token, pattern || PREV_TOKEN);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -287,7 +275,7 @@ module.exports = {
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkSpacingAfter(token, pattern) {
|
||||
checkMethodMap[token.value].after(token, pattern);
|
||||
checkMethodMap[token.value].after(token, pattern || NEXT_TOKEN);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -436,7 +424,12 @@ module.exports = {
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkSpacingForForOfStatement(node) {
|
||||
if (node.await) {
|
||||
checkSpacingBefore(sourceCode.getFirstToken(node, 0));
|
||||
checkSpacingAfter(sourceCode.getFirstToken(node, 1));
|
||||
} else {
|
||||
checkSpacingAroundFirstToken(node);
|
||||
}
|
||||
checkSpacingAround(sourceCode.getTokenBefore(node.right, astUtils.isNotOpeningParenToken));
|
||||
}
|
||||
|
||||
|
17
tools/node_modules/eslint/lib/rules/max-len.js
generated
vendored
17
tools/node_modules/eslint/lib/rules/max-len.js
generated
vendored
@ -213,7 +213,8 @@ module.exports = {
|
||||
* @returns {ASTNode[]} An array of string nodes.
|
||||
*/
|
||||
function getAllStrings() {
|
||||
return sourceCode.ast.tokens.filter(token => token.type === "String");
|
||||
return sourceCode.ast.tokens.filter(token => (token.type === "String" ||
|
||||
(token.type === "JSXText" && sourceCode.getNodeByRangeIndex(token.range[0] - 1).type === "JSXAttribute")));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -287,6 +288,7 @@ module.exports = {
|
||||
* line is a comment
|
||||
*/
|
||||
let lineIsComment = false;
|
||||
let textToMeasure;
|
||||
|
||||
/*
|
||||
* We can short-circuit the comment checks if we're already out of
|
||||
@ -305,12 +307,17 @@ module.exports = {
|
||||
|
||||
if (isFullLineComment(line, lineNumber, comment)) {
|
||||
lineIsComment = true;
|
||||
textToMeasure = line;
|
||||
} else if (ignoreTrailingComments && isTrailingComment(line, lineNumber, comment)) {
|
||||
line = stripTrailingComment(line, comment);
|
||||
textToMeasure = stripTrailingComment(line, comment);
|
||||
} else {
|
||||
textToMeasure = line;
|
||||
}
|
||||
} else {
|
||||
textToMeasure = line;
|
||||
}
|
||||
if (ignorePattern && ignorePattern.test(line) ||
|
||||
ignoreUrls && URL_REGEXP.test(line) ||
|
||||
if (ignorePattern && ignorePattern.test(textToMeasure) ||
|
||||
ignoreUrls && URL_REGEXP.test(textToMeasure) ||
|
||||
ignoreStrings && stringsByLine[lineNumber] ||
|
||||
ignoreTemplateLiterals && templateLiteralsByLine[lineNumber] ||
|
||||
ignoreRegExpLiterals && regExpLiteralsByLine[lineNumber]
|
||||
@ -320,7 +327,7 @@ module.exports = {
|
||||
return;
|
||||
}
|
||||
|
||||
const lineLength = computeLineLength(line, tabWidth);
|
||||
const lineLength = computeLineLength(textToMeasure, tabWidth);
|
||||
const commentLengthApplies = lineIsComment && maxCommentLength;
|
||||
|
||||
if (lineIsComment && ignoreComments) {
|
||||
|
35
tools/node_modules/eslint/lib/rules/no-alert.js
generated
vendored
35
tools/node_modules/eslint/lib/rules/no-alert.js
generated
vendored
@ -23,17 +23,6 @@ function isProhibitedIdentifier(name) {
|
||||
return /^(alert|confirm|prompt)$/.test(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports the given node and identifier name.
|
||||
* @param {RuleContext} context The ESLint rule context.
|
||||
* @param {ASTNode} node The node to report on.
|
||||
* @param {string} identifierName The name of the identifier.
|
||||
* @returns {void}
|
||||
*/
|
||||
function report(context, node, identifierName) {
|
||||
context.report(node, "Unexpected {{name}}.", { name: identifierName });
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the eslint-scope reference in the given scope.
|
||||
* @param {Object} scope The scope to search.
|
||||
@ -92,7 +81,11 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-alert"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unexpected: "Unexpected {{name}}."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -103,17 +96,25 @@ module.exports = {
|
||||
|
||||
// without window.
|
||||
if (callee.type === "Identifier") {
|
||||
const identifierName = callee.name;
|
||||
const name = callee.name;
|
||||
|
||||
if (!isShadowed(currentScope, callee) && isProhibitedIdentifier(callee.name)) {
|
||||
report(context, node, identifierName);
|
||||
context.report({
|
||||
node,
|
||||
messageId: "unexpected",
|
||||
data: { name }
|
||||
});
|
||||
}
|
||||
|
||||
} else if (callee.type === "MemberExpression" && isGlobalThisReferenceOrGlobalWindow(currentScope, callee.object)) {
|
||||
const identifierName = getPropertyName(callee);
|
||||
const name = getPropertyName(callee);
|
||||
|
||||
if (isProhibitedIdentifier(identifierName)) {
|
||||
report(context, node, identifierName);
|
||||
if (isProhibitedIdentifier(name)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "unexpected",
|
||||
data: { name }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-array-constructor.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-array-constructor.js
generated
vendored
@ -18,7 +18,11 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-array-constructor"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
preferLiteral: "The array literal notation [] is preferable."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -35,7 +39,7 @@ module.exports = {
|
||||
node.callee.type === "Identifier" &&
|
||||
node.callee.name === "Array"
|
||||
) {
|
||||
context.report({ node, message: "The array literal notation [] is preferrable." });
|
||||
context.report({ node, messageId: "preferLiteral" });
|
||||
}
|
||||
}
|
||||
|
||||
|
118
tools/node_modules/eslint/lib/rules/no-await-in-loop.js
generated
vendored
118
tools/node_modules/eslint/lib/rules/no-await-in-loop.js
generated
vendored
@ -4,24 +4,54 @@
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
// Node types which are considered loops.
|
||||
const loopTypes = new Set([
|
||||
"ForStatement",
|
||||
"ForOfStatement",
|
||||
"ForInStatement",
|
||||
"WhileStatement",
|
||||
"DoWhileStatement"
|
||||
]);
|
||||
/**
|
||||
* Check whether it should stop traversing ancestors at the given node.
|
||||
* @param {ASTNode} node A node to check.
|
||||
* @returns {boolean} `true` if it should stop traversing.
|
||||
*/
|
||||
function isBoundary(node) {
|
||||
const t = node.type;
|
||||
|
||||
return (
|
||||
t === "FunctionDeclaration" ||
|
||||
t === "FunctionExpression" ||
|
||||
t === "ArrowFunctionExpression" ||
|
||||
|
||||
/*
|
||||
* Node types at which we should stop looking for loops. For example, it is fine to declare an async
|
||||
* function within a loop, and use await inside of that.
|
||||
* Don't report the await expressions on for-await-of loop since it's
|
||||
* asynchronous iteration intentionally.
|
||||
*/
|
||||
const boundaryTypes = new Set([
|
||||
"FunctionDeclaration",
|
||||
"FunctionExpression",
|
||||
"ArrowFunctionExpression"
|
||||
]);
|
||||
(t === "ForOfStatement" && node.await === true)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given node is in loop.
|
||||
* @param {ASTNode} node A node to check.
|
||||
* @param {ASTNode} parent A parent node to check.
|
||||
* @returns {boolean} `true` if the node is in loop.
|
||||
*/
|
||||
function isLooped(node, parent) {
|
||||
switch (parent.type) {
|
||||
case "ForStatement":
|
||||
return (
|
||||
node === parent.test ||
|
||||
node === parent.update ||
|
||||
node === parent.body
|
||||
);
|
||||
|
||||
case "ForOfStatement":
|
||||
case "ForInStatement":
|
||||
return node === parent.body;
|
||||
|
||||
case "WhileStatement":
|
||||
case "DoWhileStatement":
|
||||
return node === parent.test || node === parent.body;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
@ -31,54 +61,42 @@ module.exports = {
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/rules/no-await-in-loop"
|
||||
},
|
||||
schema: []
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpectedAwait: "Unexpected `await` inside a loop."
|
||||
}
|
||||
},
|
||||
create(context) {
|
||||
return {
|
||||
AwaitExpression(node) {
|
||||
const ancestors = context.getAncestors();
|
||||
|
||||
// Reverse so that we can traverse from the deepest node upwards.
|
||||
ancestors.reverse();
|
||||
|
||||
/*
|
||||
* Create a set of all the ancestors plus this node so that we can check
|
||||
* if this use of await appears in the body of the loop as opposed to
|
||||
* the right-hand side of a for...of, for example.
|
||||
*/
|
||||
const ancestorSet = new Set(ancestors).add(node);
|
||||
|
||||
for (let i = 0; i < ancestors.length; i++) {
|
||||
const ancestor = ancestors[i];
|
||||
|
||||
if (boundaryTypes.has(ancestor.type)) {
|
||||
|
||||
/*
|
||||
* Short-circuit out if we encounter a boundary type. Loops above
|
||||
* this do not matter.
|
||||
/**
|
||||
* Validate an await expression.
|
||||
* @param {ASTNode} awaitNode An AwaitExpression or ForOfStatement node to validate.
|
||||
* @returns {void}
|
||||
*/
|
||||
function validate(awaitNode) {
|
||||
if (awaitNode.type === "ForOfStatement" && !awaitNode.await) {
|
||||
return;
|
||||
}
|
||||
if (loopTypes.has(ancestor.type)) {
|
||||
|
||||
/*
|
||||
* Only report if we are actually in the body or another part that gets executed on
|
||||
* every iteration.
|
||||
*/
|
||||
if (
|
||||
ancestorSet.has(ancestor.body) ||
|
||||
ancestorSet.has(ancestor.test) ||
|
||||
ancestorSet.has(ancestor.update)
|
||||
) {
|
||||
let node = awaitNode;
|
||||
let parent = node.parent;
|
||||
|
||||
while (parent && !isBoundary(parent)) {
|
||||
if (isLooped(node, parent)) {
|
||||
context.report({
|
||||
node,
|
||||
message: "Unexpected `await` inside a loop."
|
||||
node: awaitNode,
|
||||
messageId: "unexpectedAwait"
|
||||
});
|
||||
return;
|
||||
}
|
||||
node = parent;
|
||||
parent = parent.parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
AwaitExpression: validate,
|
||||
ForOfStatement: validate
|
||||
};
|
||||
}
|
||||
};
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-bitwise.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-bitwise.js
generated
vendored
@ -46,7 +46,11 @@ module.exports = {
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
messages: {
|
||||
unexpected: "Unexpected use of '{{operator}}'."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -60,7 +64,7 @@ module.exports = {
|
||||
* @returns {void}
|
||||
*/
|
||||
function report(node) {
|
||||
context.report({ node, message: "Unexpected use of '{{operator}}'.", data: { operator: node.operator } });
|
||||
context.report({ node, messageId: "unexpected", data: { operator: node.operator } });
|
||||
}
|
||||
|
||||
/**
|
||||
|
11
tools/node_modules/eslint/lib/rules/no-buffer-constructor.js
generated
vendored
11
tools/node_modules/eslint/lib/rules/no-buffer-constructor.js
generated
vendored
@ -11,12 +11,15 @@
|
||||
module.exports = {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow use of the Buffer() constructor",
|
||||
description: "disallow use of the `Buffer()` constructor",
|
||||
category: "Node.js and CommonJS",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/rules/no-buffer-constructor"
|
||||
},
|
||||
schema: []
|
||||
schema: [],
|
||||
messages: {
|
||||
deprecated: "{{expr}} is deprecated. Use Buffer.from(), Buffer.alloc(), or Buffer.allocUnsafe() instead."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -29,8 +32,8 @@ module.exports = {
|
||||
"CallExpression[callee.name='Buffer'], NewExpression[callee.name='Buffer']"(node) {
|
||||
context.report({
|
||||
node,
|
||||
message: "{{example}} is deprecated. Use Buffer.from(), Buffer.alloc(), or Buffer.allocUnsafe() instead.",
|
||||
data: { example: node.type === "CallExpression" ? "Buffer()" : "new Buffer()" }
|
||||
messageId: "deprecated",
|
||||
data: { expr: node.type === "CallExpression" ? "Buffer()" : "new Buffer()" }
|
||||
});
|
||||
}
|
||||
};
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-caller.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-caller.js
generated
vendored
@ -18,7 +18,11 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-caller"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unexpected: "Avoid arguments.{{prop}}."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -30,7 +34,7 @@ module.exports = {
|
||||
propertyName = node.property.name;
|
||||
|
||||
if (objectName === "arguments" && !node.computed && propertyName && propertyName.match(/^calle[er]$/)) {
|
||||
context.report({ node, message: "Avoid arguments.{{property}}.", data: { property: propertyName } });
|
||||
context.report({ node, messageId: "unexpected", data: { prop: propertyName } });
|
||||
}
|
||||
|
||||
}
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-case-declarations.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-case-declarations.js
generated
vendored
@ -17,7 +17,11 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-case-declarations"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unexpected: "Unexpected lexical declaration in case block."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -47,7 +51,7 @@ module.exports = {
|
||||
if (isLexicalDeclaration(statement)) {
|
||||
context.report({
|
||||
node,
|
||||
message: "Unexpected lexical declaration in case block."
|
||||
messageId: "unexpected"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-catch-shadow.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-catch-shadow.js
generated
vendored
@ -24,7 +24,11 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-catch-shadow"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
mutable: "Value of '{{name}}' may be overwritten in IE 8 and earlier."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -61,7 +65,7 @@ module.exports = {
|
||||
}
|
||||
|
||||
if (paramIsShadowing(scope, node.param.name)) {
|
||||
context.report({ node, message: "Value of '{{name}}' may be overwritten in IE 8 and earlier.", data: { name: node.param.name } });
|
||||
context.report({ node, messageId: "mutable", data: { name: node.param.name } });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-class-assign.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-class-assign.js
generated
vendored
@ -20,7 +20,11 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-class-assign"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
class: "'{{name}}' is a class."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -32,7 +36,7 @@ module.exports = {
|
||||
*/
|
||||
function checkVariable(variable) {
|
||||
astUtils.getModifyingReferences(variable.references).forEach(reference => {
|
||||
context.report({ node: reference.identifier, message: "'{{name}}' is a class.", data: { name: reference.identifier.name } });
|
||||
context.report({ node: reference.identifier, messageId: "class", data: { name: reference.identifier.name } });
|
||||
|
||||
});
|
||||
}
|
||||
|
7
tools/node_modules/eslint/lib/rules/no-compare-neg-zero.js
generated
vendored
7
tools/node_modules/eslint/lib/rules/no-compare-neg-zero.js
generated
vendored
@ -17,7 +17,10 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-compare-neg-zero"
|
||||
},
|
||||
fixable: null,
|
||||
schema: []
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: "Do not use the '{{operator}}' operator to compare against -0."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -43,7 +46,7 @@ module.exports = {
|
||||
if (isNegZero(node.left) || isNegZero(node.right)) {
|
||||
context.report({
|
||||
node,
|
||||
message: "Do not use the '{{operator}}' operator to compare against -0.",
|
||||
messageId: "unexpected",
|
||||
data: { operator: node.operator }
|
||||
});
|
||||
}
|
||||
|
14
tools/node_modules/eslint/lib/rules/no-cond-assign.js
generated
vendored
14
tools/node_modules/eslint/lib/rules/no-cond-assign.js
generated
vendored
@ -30,7 +30,14 @@ module.exports = {
|
||||
{
|
||||
enum: ["except-parens", "always"]
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
messages: {
|
||||
unexpected: "Unexpected assignment within {{type}}.",
|
||||
|
||||
// must match JSHint's error message
|
||||
missing: "Expected a conditional expression and instead saw an assignment."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -95,11 +102,10 @@ module.exports = {
|
||||
)
|
||||
) {
|
||||
|
||||
// must match JSHint's error message
|
||||
context.report({
|
||||
node,
|
||||
loc: node.test.loc.start,
|
||||
message: "Expected a conditional expression and instead saw an assignment."
|
||||
messageId: "missing"
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -115,7 +121,7 @@ module.exports = {
|
||||
if (ancestor) {
|
||||
context.report({
|
||||
node: ancestor,
|
||||
message: "Unexpected assignment within {{type}}.",
|
||||
messageId: "unexpected",
|
||||
data: {
|
||||
type: NODE_DESCRIPTIONS[ancestor.type] || ancestor.type
|
||||
}
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-confusing-arrow.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-confusing-arrow.js
generated
vendored
@ -42,7 +42,11 @@ module.exports = {
|
||||
allowParens: { type: "boolean" }
|
||||
},
|
||||
additionalProperties: false
|
||||
}]
|
||||
}],
|
||||
|
||||
messages: {
|
||||
confusing: "Arrow function used ambiguously with a conditional expression."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -60,7 +64,7 @@ module.exports = {
|
||||
if (isConditional(body) && !(config.allowParens && astUtils.isParenthesised(sourceCode, body))) {
|
||||
context.report({
|
||||
node,
|
||||
message: "Arrow function used ambiguously with a conditional expression.",
|
||||
messageId: "confusing",
|
||||
fix(fixer) {
|
||||
|
||||
// if `allowParens` is not set to true dont bother wrapping in parens
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-console.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-console.js
generated
vendored
@ -39,7 +39,11 @@ module.exports = {
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
messages: {
|
||||
unexpected: "Unexpected console statement."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -102,7 +106,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: node.loc,
|
||||
message: "Unexpected console statement."
|
||||
messageId: "unexpected"
|
||||
});
|
||||
}
|
||||
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-const-assign.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-const-assign.js
generated
vendored
@ -20,7 +20,11 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-const-assign"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
const: "'{{name}}' is constant."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -32,7 +36,7 @@ module.exports = {
|
||||
*/
|
||||
function checkVariable(variable) {
|
||||
astUtils.getModifyingReferences(variable.references).forEach(reference => {
|
||||
context.report({ node: reference.identifier, message: "'{{name}}' is constant.", data: { name: reference.identifier.name } });
|
||||
context.report({ node: reference.identifier, messageId: "const", data: { name: reference.identifier.name } });
|
||||
});
|
||||
}
|
||||
|
||||
|
9
tools/node_modules/eslint/lib/rules/no-constant-condition.js
generated
vendored
9
tools/node_modules/eslint/lib/rules/no-constant-condition.js
generated
vendored
@ -28,8 +28,11 @@ module.exports = {
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
|
||||
]
|
||||
messages: {
|
||||
unexpected: "Unexpected constant condition."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -139,7 +142,7 @@ module.exports = {
|
||||
function checkConstantConditionLoopInSet(node) {
|
||||
if (loopsInCurrentScope.has(node)) {
|
||||
loopsInCurrentScope.delete(node);
|
||||
context.report({ node: node.test, message: "Unexpected constant condition." });
|
||||
context.report({ node: node.test, messageId: "unexpected" });
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,7 +154,7 @@ module.exports = {
|
||||
*/
|
||||
function reportIfConstant(node) {
|
||||
if (node.test && isConstant(node.test, true)) {
|
||||
context.report({ node: node.test, message: "Unexpected constant condition." });
|
||||
context.report({ node: node.test, messageId: "unexpected" });
|
||||
}
|
||||
}
|
||||
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-continue.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-continue.js
generated
vendored
@ -18,14 +18,18 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-continue"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unexpected: "Unexpected use of continue statement."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
|
||||
return {
|
||||
ContinueStatement(node) {
|
||||
context.report({ node, message: "Unexpected use of continue statement." });
|
||||
context.report({ node, messageId: "unexpected" });
|
||||
}
|
||||
};
|
||||
|
||||
|
133
tools/node_modules/eslint/lib/rules/no-control-regex.js
generated
vendored
133
tools/node_modules/eslint/lib/rules/no-control-regex.js
generated
vendored
@ -5,6 +5,44 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const RegExpValidator = require("regexpp").RegExpValidator;
|
||||
const collector = new class {
|
||||
constructor() {
|
||||
this.ecmaVersion = 2018;
|
||||
this._source = "";
|
||||
this._controlChars = [];
|
||||
this._validator = new RegExpValidator(this);
|
||||
}
|
||||
|
||||
onPatternEnter() {
|
||||
this._controlChars = [];
|
||||
}
|
||||
|
||||
onCharacter(start, end, cp) {
|
||||
if (cp >= 0x00 &&
|
||||
cp <= 0x1F &&
|
||||
(
|
||||
this._source.codePointAt(start) === cp ||
|
||||
this._source.slice(start, end).startsWith("\\x") ||
|
||||
this._source.slice(start, end).startsWith("\\u")
|
||||
)
|
||||
) {
|
||||
this._controlChars.push(`\\x${`0${cp.toString(16)}`.slice(-2)}`);
|
||||
}
|
||||
}
|
||||
|
||||
collectControlChars(regexpStr) {
|
||||
try {
|
||||
this._source = regexpStr;
|
||||
this._validator.validatePattern(regexpStr); // Call onCharacter hook
|
||||
} catch (err) {
|
||||
|
||||
// Ignore syntax errors in RegExp.
|
||||
}
|
||||
return this._controlChars;
|
||||
}
|
||||
}();
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
@ -18,7 +56,11 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-control-regex"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unexpected: "Unexpected control character(s) in regular expression: {{controlChars}}."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -26,95 +68,36 @@ module.exports = {
|
||||
/**
|
||||
* Get the regex expression
|
||||
* @param {ASTNode} node node to evaluate
|
||||
* @returns {*} Regex if found else null
|
||||
* @returns {RegExp|null} Regex if found else null
|
||||
* @private
|
||||
*/
|
||||
function getRegExp(node) {
|
||||
if (node.value instanceof RegExp) {
|
||||
function getRegExpPattern(node) {
|
||||
if (node.regex) {
|
||||
return node.regex.pattern;
|
||||
}
|
||||
if (typeof node.value === "string" &&
|
||||
(node.parent.type === "NewExpression" || node.parent.type === "CallExpression") &&
|
||||
node.parent.callee.type === "Identifier" &&
|
||||
node.parent.callee.name === "RegExp" &&
|
||||
node.parent.arguments[0] === node
|
||||
) {
|
||||
return node.value;
|
||||
}
|
||||
if (typeof node.value === "string") {
|
||||
|
||||
const parent = context.getAncestors().pop();
|
||||
|
||||
if ((parent.type === "NewExpression" || parent.type === "CallExpression") &&
|
||||
parent.callee.type === "Identifier" && parent.callee.name === "RegExp"
|
||||
) {
|
||||
|
||||
// there could be an invalid regular expression string
|
||||
try {
|
||||
return new RegExp(node.value);
|
||||
} catch (ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
const controlChar = /[\x00-\x1f]/g; // eslint-disable-line no-control-regex
|
||||
const consecutiveSlashes = /\\+/g;
|
||||
const consecutiveSlashesAtEnd = /\\+$/g;
|
||||
const stringControlChar = /\\x[01][0-9a-f]/ig;
|
||||
const stringControlCharWithoutSlash = /x[01][0-9a-f]/ig;
|
||||
|
||||
/**
|
||||
* Return a list of the control characters in the given regex string
|
||||
* @param {string} regexStr regex as string to check
|
||||
* @returns {array} returns a list of found control characters on given string
|
||||
* @private
|
||||
*/
|
||||
function getControlCharacters(regexStr) {
|
||||
|
||||
// check control characters, if RegExp object used
|
||||
const controlChars = regexStr.match(controlChar) || [];
|
||||
|
||||
let stringControlChars = [];
|
||||
|
||||
// check substr, if regex literal used
|
||||
const subStrIndex = regexStr.search(stringControlChar);
|
||||
|
||||
if (subStrIndex > -1) {
|
||||
|
||||
// is it escaped, check backslash count
|
||||
const possibleEscapeCharacters = regexStr.slice(0, subStrIndex).match(consecutiveSlashesAtEnd);
|
||||
|
||||
const hasControlChars = possibleEscapeCharacters === null || !(possibleEscapeCharacters[0].length % 2);
|
||||
|
||||
if (hasControlChars) {
|
||||
stringControlChars = regexStr.slice(subStrIndex, -1)
|
||||
.split(consecutiveSlashes)
|
||||
.filter(Boolean)
|
||||
.map(x => {
|
||||
const match = x.match(stringControlCharWithoutSlash) || [x];
|
||||
|
||||
return `\\${match[0]}`;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return controlChars.map(x => {
|
||||
const hexCode = `0${x.charCodeAt(0).toString(16)}`.slice(-2);
|
||||
|
||||
return `\\x${hexCode}`;
|
||||
}).concat(stringControlChars);
|
||||
}
|
||||
|
||||
return {
|
||||
Literal(node) {
|
||||
const regex = getRegExp(node);
|
||||
const pattern = getRegExpPattern(node);
|
||||
|
||||
if (regex) {
|
||||
const computedValue = regex.toString();
|
||||
|
||||
const controlCharacters = getControlCharacters(computedValue);
|
||||
if (pattern) {
|
||||
const controlCharacters = collector.collectControlChars(pattern);
|
||||
|
||||
if (controlCharacters.length > 0) {
|
||||
context.report({
|
||||
node,
|
||||
message: "Unexpected control character(s) in regular expression: {{controlChars}}.",
|
||||
messageId: "unexpected",
|
||||
data: {
|
||||
controlChars: controlCharacters.join(", ")
|
||||
}
|
||||
|
7
tools/node_modules/eslint/lib/rules/no-debugger.js
generated
vendored
7
tools/node_modules/eslint/lib/rules/no-debugger.js
generated
vendored
@ -20,7 +20,10 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-debugger"
|
||||
},
|
||||
fixable: "code",
|
||||
schema: []
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: "Unexpected 'debugger' statement."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -29,7 +32,7 @@ module.exports = {
|
||||
DebuggerStatement(node) {
|
||||
context.report({
|
||||
node,
|
||||
message: "Unexpected 'debugger' statement.",
|
||||
messageId: "unexpected",
|
||||
fix(fixer) {
|
||||
if (astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)) {
|
||||
return fixer.remove(node);
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-delete-var.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-delete-var.js
generated
vendored
@ -18,7 +18,11 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-delete-var"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unexpected: "Variables should not be deleted."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -27,7 +31,7 @@ module.exports = {
|
||||
|
||||
UnaryExpression(node) {
|
||||
if (node.operator === "delete" && node.argument.type === "Identifier") {
|
||||
context.report({ node, message: "Variables should not be deleted." });
|
||||
context.report({ node, messageId: "unexpected" });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-div-regex.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-div-regex.js
generated
vendored
@ -18,7 +18,11 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-div-regex"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unexpected: "A regular expression literal can be confused with '/='."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -30,7 +34,7 @@ module.exports = {
|
||||
const token = sourceCode.getFirstToken(node);
|
||||
|
||||
if (token.type === "RegularExpression" && token.value[1] === "=") {
|
||||
context.report({ node, message: "A regular expression literal can be confused with '/='." });
|
||||
context.report({ node, messageId: "unexpected" });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-dupe-args.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-dupe-args.js
generated
vendored
@ -18,7 +18,11 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-dupe-args"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unexpected: "Duplicate param '{{name}}'."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -54,7 +58,7 @@ module.exports = {
|
||||
if (defs.length >= 2) {
|
||||
context.report({
|
||||
node,
|
||||
message: "Duplicate param '{{name}}'.",
|
||||
messageId: "unexpected",
|
||||
data: { name: variable.name }
|
||||
});
|
||||
}
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-dupe-class-members.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-dupe-class-members.js
generated
vendored
@ -18,7 +18,11 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-dupe-class-members"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unexpected: "Duplicate name '{{name}}'."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -102,7 +106,7 @@ module.exports = {
|
||||
}
|
||||
|
||||
if (isDuplicate) {
|
||||
context.report({ node, message: "Duplicate name '{{name}}'.", data: { name } });
|
||||
context.report({ node, messageId: "unexpected", data: { name } });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-dupe-keys.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-dupe-keys.js
generated
vendored
@ -91,7 +91,11 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-dupe-keys"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unexpected: "Duplicate key '{{name}}'."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -123,7 +127,7 @@ module.exports = {
|
||||
context.report({
|
||||
node: info.node,
|
||||
loc: node.key.loc,
|
||||
message: "Duplicate key '{{name}}'.",
|
||||
messageId: "unexpected",
|
||||
data: { name }
|
||||
});
|
||||
}
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-duplicate-case.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-duplicate-case.js
generated
vendored
@ -19,7 +19,11 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-duplicate-case"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unexpected: "Duplicate case label."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -33,7 +37,7 @@ module.exports = {
|
||||
const key = sourceCode.getText(switchCase.test);
|
||||
|
||||
if (mapping[key]) {
|
||||
context.report({ node: switchCase, message: "Duplicate case label." });
|
||||
context.report({ node: switchCase, messageId: "unexpected" });
|
||||
} else {
|
||||
mapping[key] = switchCase;
|
||||
}
|
||||
|
22
tools/node_modules/eslint/lib/rules/no-else-return.js
generated
vendored
22
tools/node_modules/eslint/lib/rules/no-else-return.js
generated
vendored
@ -34,7 +34,12 @@ module.exports = {
|
||||
},
|
||||
additionalProperties: false
|
||||
}],
|
||||
fixable: "code"
|
||||
|
||||
fixable: "code",
|
||||
|
||||
messages: {
|
||||
unexpected: "Unnecessary 'else' after 'return'."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -52,7 +57,7 @@ module.exports = {
|
||||
function displayReport(node) {
|
||||
context.report({
|
||||
node,
|
||||
message: "Unnecessary 'else' after 'return'.",
|
||||
messageId: "unexpected",
|
||||
fix: fixer => {
|
||||
const sourceCode = context.getSourceCode();
|
||||
const startToken = sourceCode.getFirstToken(node);
|
||||
@ -212,8 +217,6 @@ module.exports = {
|
||||
*/
|
||||
function checkIfWithoutElse(node) {
|
||||
const parent = node.parent;
|
||||
let consequents,
|
||||
alternate;
|
||||
|
||||
/*
|
||||
* Fixing this would require splitting one statement into two, so no error should
|
||||
@ -223,12 +226,15 @@ module.exports = {
|
||||
return;
|
||||
}
|
||||
|
||||
for (consequents = []; node.type === "IfStatement"; node = node.alternate) {
|
||||
if (!node.alternate) {
|
||||
const consequents = [];
|
||||
let alternate;
|
||||
|
||||
for (let currentNode = node; currentNode.type === "IfStatement"; currentNode = currentNode.alternate) {
|
||||
if (!currentNode.alternate) {
|
||||
return;
|
||||
}
|
||||
consequents.push(node.consequent);
|
||||
alternate = node.alternate;
|
||||
consequents.push(currentNode.consequent);
|
||||
alternate = currentNode.alternate;
|
||||
}
|
||||
|
||||
if (consequents.every(alwaysReturns)) {
|
||||
|
10
tools/node_modules/eslint/lib/rules/no-empty-character-class.js
generated
vendored
10
tools/node_modules/eslint/lib/rules/no-empty-character-class.js
generated
vendored
@ -21,7 +21,7 @@
|
||||
* 4. `[gimuy]*`: optional regexp flags
|
||||
* 5. `$`: fix the match at the end of the string
|
||||
*/
|
||||
const regex = /^\/([^\\[]|\\.|\[([^\\\]]|\\.)+])*\/[gimuy]*$/;
|
||||
const regex = /^\/([^\\[]|\\.|\[([^\\\]]|\\.)+])*\/[gimuys]*$/;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
@ -36,7 +36,11 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-empty-character-class"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unexpected: "Empty class."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -48,7 +52,7 @@ module.exports = {
|
||||
const token = sourceCode.getFirstToken(node);
|
||||
|
||||
if (token.type === "RegularExpression" && !regex.test(token.value)) {
|
||||
context.report({ node, message: "Empty class." });
|
||||
context.report({ node, messageId: "unexpected" });
|
||||
}
|
||||
}
|
||||
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-empty-function.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-empty-function.js
generated
vendored
@ -109,7 +109,11 @@ module.exports = {
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
messages: {
|
||||
unexpected: "Unexpected empty {{name}}."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -146,7 +150,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: node.body.loc.start,
|
||||
message: "Unexpected empty {{name}}.",
|
||||
messageId: "unexpected",
|
||||
data: { name }
|
||||
});
|
||||
}
|
||||
|
10
tools/node_modules/eslint/lib/rules/no-empty-pattern.js
generated
vendored
10
tools/node_modules/eslint/lib/rules/no-empty-pattern.js
generated
vendored
@ -17,19 +17,23 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-empty-pattern"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unexpected: "Unexpected empty {{type}} pattern."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
return {
|
||||
ObjectPattern(node) {
|
||||
if (node.properties.length === 0) {
|
||||
context.report({ node, message: "Unexpected empty object pattern." });
|
||||
context.report({ node, messageId: "unexpected", data: { type: "object" } });
|
||||
}
|
||||
},
|
||||
ArrayPattern(node) {
|
||||
if (node.elements.length === 0) {
|
||||
context.report({ node, message: "Unexpected empty array pattern." });
|
||||
context.report({ node, messageId: "unexpected", data: { type: "array" } });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
10
tools/node_modules/eslint/lib/rules/no-empty.js
generated
vendored
10
tools/node_modules/eslint/lib/rules/no-empty.js
generated
vendored
@ -33,7 +33,11 @@ module.exports = {
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
messages: {
|
||||
unexpected: "Empty {{type}} statement."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -64,13 +68,13 @@ module.exports = {
|
||||
return;
|
||||
}
|
||||
|
||||
context.report({ node, message: "Empty block statement." });
|
||||
context.report({ node, messageId: "unexpected", data: { type: "block" } });
|
||||
},
|
||||
|
||||
SwitchStatement(node) {
|
||||
|
||||
if (typeof node.cases === "undefined" || node.cases.length === 0) {
|
||||
context.report({ node, message: "Empty switch statement." });
|
||||
context.report({ node, messageId: "unexpected", data: { type: "switch" } });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-eq-null.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-eq-null.js
generated
vendored
@ -19,7 +19,11 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-eq-null"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unexpected: "Use '===' to compare with null."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -31,7 +35,7 @@ module.exports = {
|
||||
|
||||
if (node.right.type === "Literal" && node.right.raw === "null" && badOperator ||
|
||||
node.left.type === "Literal" && node.left.raw === "null" && badOperator) {
|
||||
context.report({ node, message: "Use ‘===’ to compare with ‘null’." });
|
||||
context.report({ node, messageId: "unexpected" });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
23
tools/node_modules/eslint/lib/rules/no-eval.js
generated
vendored
23
tools/node_modules/eslint/lib/rules/no-eval.js
generated
vendored
@ -91,7 +91,11 @@ module.exports = {
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
messages: {
|
||||
unexpected: "eval can be harmful."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -147,20 +151,19 @@ module.exports = {
|
||||
* @returns {void}
|
||||
*/
|
||||
function report(node) {
|
||||
let locationNode = node;
|
||||
const parent = node.parent;
|
||||
const locationNode = node.type === "MemberExpression"
|
||||
? node.property
|
||||
: node;
|
||||
|
||||
if (node.type === "MemberExpression") {
|
||||
locationNode = node.property;
|
||||
}
|
||||
if (parent.type === "CallExpression" && parent.callee === node) {
|
||||
node = parent;
|
||||
}
|
||||
const reportNode = parent.type === "CallExpression" && parent.callee === node
|
||||
? parent
|
||||
: node;
|
||||
|
||||
context.report({
|
||||
node,
|
||||
node: reportNode,
|
||||
loc: locationNode.loc.start,
|
||||
message: "eval can be harmful."
|
||||
messageId: "unexpected"
|
||||
});
|
||||
}
|
||||
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-ex-assign.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-ex-assign.js
generated
vendored
@ -20,7 +20,11 @@ module.exports = {
|
||||
url: "https://eslint.org/docs/rules/no-ex-assign"
|
||||
},
|
||||
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unexpected: "Do not assign to the exception parameter."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -32,7 +36,7 @@ module.exports = {
|
||||
*/
|
||||
function checkVariable(variable) {
|
||||
astUtils.getModifyingReferences(variable.references).forEach(reference => {
|
||||
context.report({ node: reference.identifier, message: "Do not assign to the exception parameter." });
|
||||
context.report({ node: reference.identifier, messageId: "unexpected" });
|
||||
});
|
||||
}
|
||||
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-extend-native.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-extend-native.js
generated
vendored
@ -45,7 +45,11 @@ module.exports = {
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
messages: {
|
||||
unexpected: "{{builtin}} prototype is read only, properties should not be added."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -67,7 +71,7 @@ module.exports = {
|
||||
function reportNode(node, builtin) {
|
||||
context.report({
|
||||
node,
|
||||
message: "{{builtin}} prototype is read only, properties should not be added.",
|
||||
messageId: "unexpected",
|
||||
data: {
|
||||
builtin
|
||||
}
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-extra-bind.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-extra-bind.js
generated
vendored
@ -25,7 +25,11 @@ module.exports = {
|
||||
|
||||
schema: [],
|
||||
|
||||
fixable: "code"
|
||||
fixable: "code",
|
||||
|
||||
messages: {
|
||||
unexpected: "The function binding is unnecessary."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -41,7 +45,7 @@ module.exports = {
|
||||
function report(node) {
|
||||
context.report({
|
||||
node: node.parent.parent,
|
||||
message: "The function binding is unnecessary.",
|
||||
messageId: "unexpected",
|
||||
loc: node.parent.property.loc.start,
|
||||
fix(fixer) {
|
||||
const firstTokenToRemove = context.getSourceCode()
|
||||
|
11
tools/node_modules/eslint/lib/rules/no-extra-boolean-cast.js
generated
vendored
11
tools/node_modules/eslint/lib/rules/no-extra-boolean-cast.js
generated
vendored
@ -26,7 +26,12 @@ module.exports = {
|
||||
|
||||
schema: [],
|
||||
|
||||
fixable: "code"
|
||||
fixable: "code",
|
||||
|
||||
messages: {
|
||||
unexpectedCall: "Redundant Boolean call.",
|
||||
unexpectedNegation: "Redundant double negation."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -82,7 +87,7 @@ module.exports = {
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
message: "Redundant double negation.",
|
||||
messageId: "unexpectedNegation",
|
||||
fix: fixer => fixer.replaceText(parent, sourceCode.getText(node.argument))
|
||||
});
|
||||
}
|
||||
@ -97,7 +102,7 @@ module.exports = {
|
||||
if (isInBooleanContext(node, parent)) {
|
||||
context.report({
|
||||
node,
|
||||
message: "Redundant Boolean call.",
|
||||
messageId: "unexpectedCall",
|
||||
fix: fixer => {
|
||||
if (!node.arguments.length) {
|
||||
return fixer.replaceText(parent, "true");
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-extra-label.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-extra-label.js
generated
vendored
@ -26,7 +26,11 @@ module.exports = {
|
||||
|
||||
schema: [],
|
||||
|
||||
fixable: "code"
|
||||
fixable: "code",
|
||||
|
||||
messages: {
|
||||
unexpected: "This label '{{name}}' is unnecessary."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -109,7 +113,7 @@ module.exports = {
|
||||
if (info.breakable && info.label && info.label.name === labelNode.name) {
|
||||
context.report({
|
||||
node: labelNode,
|
||||
message: "This label '{{name}}' is unnecessary.",
|
||||
messageId: "unexpected",
|
||||
data: labelNode,
|
||||
fix: fixer => fixer.removeRange([sourceCode.getFirstToken(node).range[1], labelNode.range[1]])
|
||||
});
|
||||
|
15
tools/node_modules/eslint/lib/rules/no-extra-parens.js
generated
vendored
15
tools/node_modules/eslint/lib/rules/no-extra-parens.js
generated
vendored
@ -55,6 +55,10 @@ module.exports = {
|
||||
maxItems: 2
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
messages: {
|
||||
unexpected: "Gratuitous parentheses around expression."
|
||||
}
|
||||
},
|
||||
|
||||
@ -163,12 +167,13 @@ module.exports = {
|
||||
* @private
|
||||
*/
|
||||
function isInReturnStatement(node) {
|
||||
while (node) {
|
||||
if (node.type === "ReturnStatement" ||
|
||||
(node.type === "ArrowFunctionExpression" && node.body.type !== "BlockStatement")) {
|
||||
for (let currentNode = node; currentNode; currentNode = currentNode.parent) {
|
||||
if (
|
||||
currentNode.type === "ReturnStatement" ||
|
||||
(currentNode.type === "ArrowFunctionExpression" && currentNode.body.type !== "BlockStatement")
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -312,7 +317,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
loc: leftParenToken.loc.start,
|
||||
message: "Gratuitous parentheses around expression.",
|
||||
messageId: "unexpected",
|
||||
fix(fixer) {
|
||||
const parenthesizedSource = sourceCode.text.slice(leftParenToken.range[1], rightParenToken.range[0]);
|
||||
|
||||
|
8
tools/node_modules/eslint/lib/rules/no-extra-semi.js
generated
vendored
8
tools/node_modules/eslint/lib/rules/no-extra-semi.js
generated
vendored
@ -26,7 +26,11 @@ module.exports = {
|
||||
},
|
||||
|
||||
fixable: "code",
|
||||
schema: []
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unexpected: "Unnecessary semicolon."
|
||||
}
|
||||
},
|
||||
|
||||
create(context) {
|
||||
@ -40,7 +44,7 @@ module.exports = {
|
||||
function report(nodeOrToken) {
|
||||
context.report({
|
||||
node: nodeOrToken,
|
||||
message: "Unnecessary semicolon.",
|
||||
messageId: "unexpected",
|
||||
fix(fixer) {
|
||||
|
||||
/*
|
||||
|
15
tools/node_modules/eslint/lib/rules/no-implicit-coercion.js
generated
vendored
15
tools/node_modules/eslint/lib/rules/no-implicit-coercion.js
generated
vendored
@ -20,7 +20,6 @@ const ALLOWABLE_OPERATORS = ["~", "!!", "+", "*"];
|
||||
* @returns {Object} The parsed and normalized option object.
|
||||
*/
|
||||
function parseOptions(options) {
|
||||
options = options || {};
|
||||
return {
|
||||
boolean: "boolean" in options ? Boolean(options.boolean) : true,
|
||||
number: "number" in options ? Boolean(options.number) : true,
|
||||
@ -186,7 +185,7 @@ module.exports = {
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const options = parseOptions(context.options[0]);
|
||||
const options = parseOptions(context.options[0] || {});
|
||||
const sourceCode = context.getSourceCode();
|
||||
|
||||
/**
|
||||
@ -197,8 +196,6 @@ module.exports = {
|
||||
* @returns {void}
|
||||
*/
|
||||
function report(node, recommendation, shouldFix) {
|
||||
shouldFix = typeof shouldFix === "undefined" ? true : shouldFix;
|
||||
|
||||
context.report({
|
||||
node,
|
||||
message: "use `{{recommendation}}` instead.",
|
||||
@ -233,7 +230,7 @@ module.exports = {
|
||||
if (!operatorAllowed && options.boolean && isDoubleLogicalNegating(node)) {
|
||||
const recommendation = `Boolean(${sourceCode.getText(node.argument.argument)})`;
|
||||
|
||||
report(node, recommendation);
|
||||
report(node, recommendation, true);
|
||||
}
|
||||
|
||||
// ~foo.indexOf(bar)
|
||||
@ -249,7 +246,7 @@ module.exports = {
|
||||
if (!operatorAllowed && options.number && node.operator === "+" && !isNumeric(node.argument)) {
|
||||
const recommendation = `Number(${sourceCode.getText(node.argument)})`;
|
||||
|
||||
report(node, recommendation);
|
||||
report(node, recommendation, true);
|
||||
}
|
||||
},
|
||||
|
||||
@ -264,7 +261,7 @@ module.exports = {
|
||||
if (nonNumericOperand) {
|
||||
const recommendation = `Number(${sourceCode.getText(nonNumericOperand)})`;
|
||||
|
||||
report(node, recommendation);
|
||||
report(node, recommendation, true);
|
||||
}
|
||||
|
||||
// "" + foo
|
||||
@ -272,7 +269,7 @@ module.exports = {
|
||||
if (!operatorAllowed && options.string && isConcatWithEmptyString(node)) {
|
||||
const recommendation = `String(${sourceCode.getText(getNonEmptyOperand(node))})`;
|
||||
|
||||
report(node, recommendation);
|
||||
report(node, recommendation, true);
|
||||
}
|
||||
},
|
||||
|
||||
@ -285,7 +282,7 @@ module.exports = {
|
||||
const code = sourceCode.getText(getNonEmptyOperand(node));
|
||||
const recommendation = `${code} = String(${code})`;
|
||||
|
||||
report(node, recommendation);
|
||||
report(node, recommendation, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
95
tools/node_modules/eslint/lib/rules/no-invalid-regexp.js
generated
vendored
95
tools/node_modules/eslint/lib/rules/no-invalid-regexp.js
generated
vendored
@ -8,7 +8,10 @@
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const espree = require("espree");
|
||||
const RegExpValidator = require("regexpp").RegExpValidator;
|
||||
const validator = new RegExpValidator({ ecmaVersion: 2018 });
|
||||
const validFlags = /[gimuys]/g;
|
||||
const undefined1 = void 0;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
@ -40,10 +43,14 @@ module.exports = {
|
||||
create(context) {
|
||||
|
||||
const options = context.options[0];
|
||||
let allowedFlags = "";
|
||||
let allowedFlags = null;
|
||||
|
||||
if (options && options.allowConstructorFlags) {
|
||||
allowedFlags = options.allowConstructorFlags.join("");
|
||||
const temp = options.allowConstructorFlags.join("").replace(validFlags, "");
|
||||
|
||||
if (temp) {
|
||||
allowedFlags = new RegExp(`[${temp}]`, "gi");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,51 +64,61 @@ module.exports = {
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate strings passed to the RegExp constructor
|
||||
* @param {ASTNode} node node to evaluate
|
||||
* @returns {void}
|
||||
* @private
|
||||
* Check syntax error in a given pattern.
|
||||
* @param {string} pattern The RegExp pattern to validate.
|
||||
* @param {boolean} uFlag The Unicode flag.
|
||||
* @returns {string|null} The syntax error.
|
||||
*/
|
||||
function check(node) {
|
||||
if (node.callee.type === "Identifier" && node.callee.name === "RegExp" && isString(node.arguments[0])) {
|
||||
let flags = isString(node.arguments[1]) ? node.arguments[1].value : "";
|
||||
|
||||
if (allowedFlags) {
|
||||
flags = flags.replace(new RegExp(`[${allowedFlags}]`, "gi"), "");
|
||||
}
|
||||
|
||||
function validateRegExpPattern(pattern, uFlag) {
|
||||
try {
|
||||
void new RegExp(node.arguments[0].value);
|
||||
} catch (e) {
|
||||
context.report({
|
||||
node,
|
||||
message: "{{message}}.",
|
||||
data: e
|
||||
});
|
||||
validator.validatePattern(pattern, undefined1, undefined1, uFlag);
|
||||
return null;
|
||||
} catch (err) {
|
||||
return err.message;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags) {
|
||||
|
||||
/**
|
||||
* Check syntax error in a given flags.
|
||||
* @param {string} flags The RegExp flags to validate.
|
||||
* @returns {string|null} The syntax error.
|
||||
*/
|
||||
function validateRegExpFlags(flags) {
|
||||
try {
|
||||
espree.parse(`/./${flags}`, context.parserOptions);
|
||||
} catch (ex) {
|
||||
context.report({
|
||||
node,
|
||||
message: "Invalid flags supplied to RegExp constructor '{{flags}}'.",
|
||||
data: {
|
||||
flags
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
validator.validateFlags(flags);
|
||||
return null;
|
||||
} catch (err) {
|
||||
return `Invalid flags supplied to RegExp constructor '${flags}'`;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
CallExpression: check,
|
||||
NewExpression: check
|
||||
};
|
||||
"CallExpression, NewExpression"(node) {
|
||||
if (node.callee.type !== "Identifier" || node.callee.name !== "RegExp" || !isString(node.arguments[0])) {
|
||||
return;
|
||||
}
|
||||
const pattern = node.arguments[0].value;
|
||||
let flags = isString(node.arguments[1]) ? node.arguments[1].value : "";
|
||||
|
||||
if (allowedFlags) {
|
||||
flags = flags.replace(allowedFlags, "");
|
||||
}
|
||||
|
||||
// If flags are unknown, check both are errored or not.
|
||||
const message = validateRegExpFlags(flags) || (
|
||||
flags
|
||||
? validateRegExpPattern(pattern, flags.indexOf("u") !== -1)
|
||||
: validateRegExpPattern(pattern, true) && validateRegExpPattern(pattern, false)
|
||||
);
|
||||
|
||||
if (message) {
|
||||
context.report({
|
||||
node,
|
||||
message: "{{message}}.",
|
||||
data: { message }
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
2
tools/node_modules/eslint/lib/rules/no-irregular-whitespace.js
generated
vendored
2
tools/node_modules/eslint/lib/rules/no-irregular-whitespace.js
generated
vendored
@ -101,7 +101,7 @@ module.exports = {
|
||||
*/
|
||||
function removeInvalidNodeErrorsInIdentifierOrLiteral(node) {
|
||||
const shouldCheckStrings = skipStrings && (typeof node.value === "string");
|
||||
const shouldCheckRegExps = skipRegExps && (node.value instanceof RegExp);
|
||||
const shouldCheckRegExps = skipRegExps && Boolean(node.regex);
|
||||
|
||||
if (shouldCheckStrings || shouldCheckRegExps) {
|
||||
|
||||
|
20
tools/node_modules/eslint/lib/rules/no-loop-func.js
generated
vendored
20
tools/node_modules/eslint/lib/rules/no-loop-func.js
generated
vendored
@ -20,9 +20,9 @@
|
||||
* `null`.
|
||||
*/
|
||||
function getContainingLoopNode(node) {
|
||||
let parent = node.parent;
|
||||
for (let currentNode = node; currentNode.parent; currentNode = currentNode.parent) {
|
||||
const parent = currentNode.parent;
|
||||
|
||||
while (parent) {
|
||||
switch (parent.type) {
|
||||
case "WhileStatement":
|
||||
case "DoWhileStatement":
|
||||
@ -31,7 +31,7 @@ function getContainingLoopNode(node) {
|
||||
case "ForStatement":
|
||||
|
||||
// `init` is outside of the loop.
|
||||
if (parent.init !== node) {
|
||||
if (parent.init !== currentNode) {
|
||||
return parent;
|
||||
}
|
||||
break;
|
||||
@ -40,7 +40,7 @@ function getContainingLoopNode(node) {
|
||||
case "ForOfStatement":
|
||||
|
||||
// `right` is outside of the loop.
|
||||
if (parent.right !== node) {
|
||||
if (parent.right !== currentNode) {
|
||||
return parent;
|
||||
}
|
||||
break;
|
||||
@ -55,9 +55,6 @@ function getContainingLoopNode(node) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
node = parent;
|
||||
parent = node.parent;
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -73,12 +70,13 @@ function getContainingLoopNode(node) {
|
||||
* @returns {ASTNode} The most outer loop node.
|
||||
*/
|
||||
function getTopLoopNode(node, excludedNode) {
|
||||
let retv = node;
|
||||
const border = excludedNode ? excludedNode.range[1] : 0;
|
||||
let retv = node;
|
||||
let containingLoopNode = node;
|
||||
|
||||
while (node && node.range[0] >= border) {
|
||||
retv = node;
|
||||
node = getContainingLoopNode(node);
|
||||
while (containingLoopNode && containingLoopNode.range[0] >= border) {
|
||||
retv = containingLoopNode;
|
||||
containingLoopNode = getContainingLoopNode(containingLoopNode);
|
||||
}
|
||||
|
||||
return retv;
|
||||
|
27
tools/node_modules/eslint/lib/rules/no-magic-numbers.js
generated
vendored
27
tools/node_modules/eslint/lib/rules/no-magic-numbers.js
generated
vendored
@ -101,25 +101,32 @@ module.exports = {
|
||||
|
||||
return {
|
||||
Literal(node) {
|
||||
let parent = node.parent,
|
||||
value = node.value,
|
||||
raw = node.raw;
|
||||
const okTypes = detectObjects ? [] : ["ObjectExpression", "Property", "AssignmentExpression"];
|
||||
|
||||
if (!isNumber(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let fullNumberNode;
|
||||
let parent;
|
||||
let value;
|
||||
let raw;
|
||||
|
||||
// For negative magic numbers: update the value and parent node
|
||||
if (parent.type === "UnaryExpression" && parent.operator === "-") {
|
||||
node = parent;
|
||||
if (node.parent.type === "UnaryExpression" && node.parent.operator === "-") {
|
||||
fullNumberNode = node.parent;
|
||||
parent = fullNumberNode.parent;
|
||||
value = -node.value;
|
||||
raw = `-${node.raw}`;
|
||||
} else {
|
||||
fullNumberNode = node;
|
||||
parent = node.parent;
|
||||
value = -value;
|
||||
raw = `-${raw}`;
|
||||
value = node.value;
|
||||
raw = node.raw;
|
||||
}
|
||||
|
||||
if (shouldIgnoreNumber(value) ||
|
||||
shouldIgnoreParseInt(parent, node) ||
|
||||
shouldIgnoreParseInt(parent, fullNumberNode) ||
|
||||
shouldIgnoreArrayIndexes(parent) ||
|
||||
shouldIgnoreJSXNumbers(parent)) {
|
||||
return;
|
||||
@ -128,7 +135,7 @@ module.exports = {
|
||||
if (parent.type === "VariableDeclarator") {
|
||||
if (enforceConst && parent.parent.kind !== "const") {
|
||||
context.report({
|
||||
node,
|
||||
node: fullNumberNode,
|
||||
message: "Number constants declarations must use 'const'."
|
||||
});
|
||||
}
|
||||
@ -137,7 +144,7 @@ module.exports = {
|
||||
(parent.type === "AssignmentExpression" && parent.left.type === "Identifier")
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
node: fullNumberNode,
|
||||
message: "No magic number: {{raw}}.",
|
||||
data: {
|
||||
raw
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user