WIP: bootstrap and partial real Solana watcher implementation
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -0,0 +1,59 @@
|
||||
let parts = [process.platform, process.arch];
|
||||
if (process.platform === 'linux') {
|
||||
const { MUSL, familySync } = require('detect-libc');
|
||||
const family = familySync();
|
||||
if (family === MUSL) {
|
||||
parts.push('musl');
|
||||
} else if (process.arch === 'arm') {
|
||||
parts.push('gnueabihf');
|
||||
} else {
|
||||
parts.push('gnu');
|
||||
}
|
||||
} else if (process.platform === 'win32') {
|
||||
parts.push('msvc');
|
||||
}
|
||||
|
||||
let native;
|
||||
try {
|
||||
native = require(`lightningcss-${parts.join('-')}`);
|
||||
} catch (err) {
|
||||
native = require(`../lightningcss.${parts.join('-')}.node`);
|
||||
}
|
||||
|
||||
module.exports.transform = wrap(native.transform);
|
||||
module.exports.transformStyleAttribute = wrap(native.transformStyleAttribute);
|
||||
module.exports.bundle = wrap(native.bundle);
|
||||
module.exports.bundleAsync = wrap(native.bundleAsync);
|
||||
module.exports.browserslistToTargets = require('./browserslistToTargets');
|
||||
module.exports.composeVisitors = require('./composeVisitors');
|
||||
module.exports.Features = require('./flags').Features;
|
||||
|
||||
function wrap(call) {
|
||||
return (options) => {
|
||||
if (typeof options.visitor === 'function') {
|
||||
let deps = [];
|
||||
options.visitor = options.visitor({
|
||||
addDependency(dep) {
|
||||
deps.push(dep);
|
||||
}
|
||||
});
|
||||
|
||||
let result = call(options);
|
||||
if (result instanceof Promise) {
|
||||
result = result.then(res => {
|
||||
if (deps.length) {
|
||||
res.dependencies ??= [];
|
||||
res.dependencies.push(...deps);
|
||||
}
|
||||
return res;
|
||||
});
|
||||
} else if (deps.length) {
|
||||
result.dependencies ??= [];
|
||||
result.dependencies.push(...deps);
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
return call(options);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Unique ID creation requires a high quality random # generator. In the browser we therefore
|
||||
// require the crypto API and do not support built-in fallback to lower quality random number
|
||||
// generators (like Math.random()).
|
||||
var getRandomValues;
|
||||
var rnds8 = new Uint8Array(16);
|
||||
export default function rng() {
|
||||
// lazy load so that environments that need to polyfill have a chance to do so
|
||||
if (!getRandomValues) {
|
||||
// getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
|
||||
// find the complete implementation of crypto (msCrypto) on IE11.
|
||||
getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);
|
||||
|
||||
if (!getRandomValues) {
|
||||
throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
|
||||
}
|
||||
}
|
||||
|
||||
return getRandomValues(rnds8);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
process.env.NODE_ENV = 'test'
|
||||
|
||||
var path = require('path')
|
||||
var test = null
|
||||
|
||||
try {
|
||||
var pkg = require(path.join(process.cwd(), 'package.json'))
|
||||
if (pkg.name && process.env[pkg.name.toUpperCase().replace(/-/g, '_')]) {
|
||||
process.exit(0)
|
||||
}
|
||||
test = pkg.prebuild.test
|
||||
} catch (err) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
if (test) require(path.join(process.cwd(), test))
|
||||
else require('./')()
|
||||
@@ -0,0 +1,77 @@
|
||||
import OverloadYield from "./OverloadYield.js";
|
||||
import regenerator from "./regenerator.js";
|
||||
import regeneratorAsync from "./regeneratorAsync.js";
|
||||
import regeneratorAsyncGen from "./regeneratorAsyncGen.js";
|
||||
import regeneratorAsyncIterator from "./regeneratorAsyncIterator.js";
|
||||
import regeneratorKeys from "./regeneratorKeys.js";
|
||||
import regeneratorValues from "./regeneratorValues.js";
|
||||
function _regeneratorRuntime() {
|
||||
"use strict";
|
||||
|
||||
var r = regenerator(),
|
||||
e = r.m(_regeneratorRuntime),
|
||||
t = (Object.getPrototypeOf ? Object.getPrototypeOf(e) : e.__proto__).constructor;
|
||||
function n(r) {
|
||||
var e = "function" == typeof r && r.constructor;
|
||||
return !!e && (e === t || "GeneratorFunction" === (e.displayName || e.name));
|
||||
}
|
||||
var o = {
|
||||
"throw": 1,
|
||||
"return": 2,
|
||||
"break": 3,
|
||||
"continue": 3
|
||||
};
|
||||
function a(r) {
|
||||
var e, t;
|
||||
return function (n) {
|
||||
e || (e = {
|
||||
stop: function stop() {
|
||||
return t(n.a, 2);
|
||||
},
|
||||
"catch": function _catch() {
|
||||
return n.v;
|
||||
},
|
||||
abrupt: function abrupt(r, e) {
|
||||
return t(n.a, o[r], e);
|
||||
},
|
||||
delegateYield: function delegateYield(r, o, a) {
|
||||
return e.resultName = o, t(n.d, regeneratorValues(r), a);
|
||||
},
|
||||
finish: function finish(r) {
|
||||
return t(n.f, r);
|
||||
}
|
||||
}, t = function t(r, _t, o) {
|
||||
n.p = e.prev, n.n = e.next;
|
||||
try {
|
||||
return r(_t, o);
|
||||
} finally {
|
||||
e.next = n.n;
|
||||
}
|
||||
}), e.resultName && (e[e.resultName] = n.v, e.resultName = void 0), e.sent = n.v, e.next = n.n;
|
||||
try {
|
||||
return r.call(this, e);
|
||||
} finally {
|
||||
n.p = e.prev, n.n = e.next;
|
||||
}
|
||||
};
|
||||
}
|
||||
return (_regeneratorRuntime = function _regeneratorRuntime() {
|
||||
return {
|
||||
wrap: function wrap(e, t, n, o) {
|
||||
return r.w(a(e), t, n, o && o.reverse());
|
||||
},
|
||||
isGeneratorFunction: n,
|
||||
mark: r.m,
|
||||
awrap: function awrap(r, e) {
|
||||
return new OverloadYield(r, e);
|
||||
},
|
||||
AsyncIterator: regeneratorAsyncIterator,
|
||||
async: function async(r, e, t, o, u) {
|
||||
return (n(e) ? regeneratorAsyncGen : regeneratorAsync)(a(r), e, t, o, u);
|
||||
},
|
||||
keys: regeneratorKeys,
|
||||
values: regeneratorValues
|
||||
};
|
||||
})();
|
||||
}
|
||||
export { _regeneratorRuntime as default };
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @fileoverview A rule to disallow unnecessary `.call()` and `.apply()`.
|
||||
* @author Toru Nagashima
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Checks whether or not a node is a `.call()`/`.apply()`.
|
||||
* @param {ASTNode} node A CallExpression node to check.
|
||||
* @returns {boolean} Whether or not the node is a `.call()`/`.apply()`.
|
||||
*/
|
||||
function isCallOrNonVariadicApply(node) {
|
||||
const callee = astUtils.skipChainExpression(node.callee);
|
||||
|
||||
return (
|
||||
callee.type === "MemberExpression" &&
|
||||
callee.property.type === "Identifier" &&
|
||||
callee.computed === false &&
|
||||
((callee.property.name === "call" && node.arguments.length >= 1) ||
|
||||
(callee.property.name === "apply" &&
|
||||
node.arguments.length === 2 &&
|
||||
node.arguments[1].type === "ArrayExpression"))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether or not `thisArg` is not changed by `.call()`/`.apply()`.
|
||||
* @param {ASTNode|null} expectedThis The node that is the owner of the applied function.
|
||||
* @param {ASTNode} thisArg The node that is given to the first argument of the `.call()`/`.apply()`.
|
||||
* @param {SourceCode} sourceCode The ESLint source code object.
|
||||
* @returns {boolean} Whether or not `thisArg` is not changed by `.call()`/`.apply()`.
|
||||
*/
|
||||
function isValidThisArg(expectedThis, thisArg, sourceCode) {
|
||||
if (!expectedThis) {
|
||||
return astUtils.isNullOrUndefined(thisArg);
|
||||
}
|
||||
return astUtils.equalTokens(expectedThis, thisArg, sourceCode);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Disallow unnecessary calls to `.call()` and `.apply()`",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/no-useless-call",
|
||||
},
|
||||
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unnecessaryCall: "Unnecessary '.{{name}}()'.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
return {
|
||||
CallExpression(node) {
|
||||
if (!isCallOrNonVariadicApply(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const callee = astUtils.skipChainExpression(node.callee);
|
||||
const applied = astUtils.skipChainExpression(callee.object);
|
||||
const expectedThis =
|
||||
applied.type === "MemberExpression" ? applied.object : null;
|
||||
const thisArg = node.arguments[0];
|
||||
|
||||
if (isValidThisArg(expectedThis, thisArg, sourceCode)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "unnecessaryCall",
|
||||
data: { name: callee.property.name },
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "postgres-date",
|
||||
"main": "index.js",
|
||||
"version": "1.0.7",
|
||||
"description": "Postgres date column parser",
|
||||
"license": "MIT",
|
||||
"repository": "bendrucker/postgres-date",
|
||||
"author": {
|
||||
"name": "Ben Drucker",
|
||||
"email": "bvdrucker@gmail.com",
|
||||
"url": "bendrucker.me"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "standard && tape test.js"
|
||||
},
|
||||
"keywords": [
|
||||
"postgres",
|
||||
"date",
|
||||
"parser"
|
||||
],
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"standard": "^14.0.0",
|
||||
"tape": "^5.0.0"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"readme.md"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env node
|
||||
require('../uuid-bin');
|
||||
@@ -0,0 +1,34 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Masks a buffer using the given mask.
|
||||
*
|
||||
* @param {Buffer} source The buffer to mask
|
||||
* @param {Buffer} mask The mask to use
|
||||
* @param {Buffer} output The buffer where to store the result
|
||||
* @param {Number} offset The offset at which to start writing
|
||||
* @param {Number} length The number of bytes to mask.
|
||||
* @public
|
||||
*/
|
||||
const mask = (source, mask, output, offset, length) => {
|
||||
for (var i = 0; i < length; i++) {
|
||||
output[offset + i] = source[i] ^ mask[i & 3];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Unmasks a buffer using the given mask.
|
||||
*
|
||||
* @param {Buffer} buffer The buffer to unmask
|
||||
* @param {Buffer} mask The mask to use
|
||||
* @public
|
||||
*/
|
||||
const unmask = (buffer, mask) => {
|
||||
// Required until https://github.com/nodejs/node/issues/9006 is resolved.
|
||||
const length = buffer.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
buffer[i] ^= mask[i & 3];
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = { mask, unmask };
|
||||
@@ -0,0 +1,332 @@
|
||||
/**
|
||||
* @fileoverview Collects the built-in rules into a map structure so that they can be imported all at once and without
|
||||
* using the file-system directly.
|
||||
* @author Peter (Somogyvari) Metz
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/* eslint sort-keys: ["error", "asc"] -- More readable for long list */
|
||||
|
||||
const { LazyLoadingRuleMap } = require("./utils/lazy-loading-rule-map");
|
||||
|
||||
/** @type {Map<string, import("../types").Rule.RuleModule>} */
|
||||
module.exports = new LazyLoadingRuleMap(
|
||||
Object.entries({
|
||||
"accessor-pairs": () => require("./accessor-pairs"),
|
||||
"array-bracket-newline": () => require("./array-bracket-newline"),
|
||||
"array-bracket-spacing": () => require("./array-bracket-spacing"),
|
||||
"array-callback-return": () => require("./array-callback-return"),
|
||||
"array-element-newline": () => require("./array-element-newline"),
|
||||
"arrow-body-style": () => require("./arrow-body-style"),
|
||||
"arrow-parens": () => require("./arrow-parens"),
|
||||
"arrow-spacing": () => require("./arrow-spacing"),
|
||||
"block-scoped-var": () => require("./block-scoped-var"),
|
||||
"block-spacing": () => require("./block-spacing"),
|
||||
"brace-style": () => require("./brace-style"),
|
||||
"callback-return": () => require("./callback-return"),
|
||||
camelcase: () => require("./camelcase"),
|
||||
"capitalized-comments": () => require("./capitalized-comments"),
|
||||
"class-methods-use-this": () => require("./class-methods-use-this"),
|
||||
"comma-dangle": () => require("./comma-dangle"),
|
||||
"comma-spacing": () => require("./comma-spacing"),
|
||||
"comma-style": () => require("./comma-style"),
|
||||
complexity: () => require("./complexity"),
|
||||
"computed-property-spacing": () =>
|
||||
require("./computed-property-spacing"),
|
||||
"consistent-return": () => require("./consistent-return"),
|
||||
"consistent-this": () => require("./consistent-this"),
|
||||
"constructor-super": () => require("./constructor-super"),
|
||||
curly: () => require("./curly"),
|
||||
"default-case": () => require("./default-case"),
|
||||
"default-case-last": () => require("./default-case-last"),
|
||||
"default-param-last": () => require("./default-param-last"),
|
||||
"dot-location": () => require("./dot-location"),
|
||||
"dot-notation": () => require("./dot-notation"),
|
||||
"eol-last": () => require("./eol-last"),
|
||||
eqeqeq: () => require("./eqeqeq"),
|
||||
"for-direction": () => require("./for-direction"),
|
||||
"func-call-spacing": () => require("./func-call-spacing"),
|
||||
"func-name-matching": () => require("./func-name-matching"),
|
||||
"func-names": () => require("./func-names"),
|
||||
"func-style": () => require("./func-style"),
|
||||
"function-call-argument-newline": () =>
|
||||
require("./function-call-argument-newline"),
|
||||
"function-paren-newline": () => require("./function-paren-newline"),
|
||||
"generator-star-spacing": () => require("./generator-star-spacing"),
|
||||
"getter-return": () => require("./getter-return"),
|
||||
"global-require": () => require("./global-require"),
|
||||
"grouped-accessor-pairs": () => require("./grouped-accessor-pairs"),
|
||||
"guard-for-in": () => require("./guard-for-in"),
|
||||
"handle-callback-err": () => require("./handle-callback-err"),
|
||||
"id-blacklist": () => require("./id-blacklist"),
|
||||
"id-denylist": () => require("./id-denylist"),
|
||||
"id-length": () => require("./id-length"),
|
||||
"id-match": () => require("./id-match"),
|
||||
"implicit-arrow-linebreak": () => require("./implicit-arrow-linebreak"),
|
||||
indent: () => require("./indent"),
|
||||
"indent-legacy": () => require("./indent-legacy"),
|
||||
"init-declarations": () => require("./init-declarations"),
|
||||
"jsx-quotes": () => require("./jsx-quotes"),
|
||||
"key-spacing": () => require("./key-spacing"),
|
||||
"keyword-spacing": () => require("./keyword-spacing"),
|
||||
"line-comment-position": () => require("./line-comment-position"),
|
||||
"linebreak-style": () => require("./linebreak-style"),
|
||||
"lines-around-comment": () => require("./lines-around-comment"),
|
||||
"lines-around-directive": () => require("./lines-around-directive"),
|
||||
"lines-between-class-members": () =>
|
||||
require("./lines-between-class-members"),
|
||||
"logical-assignment-operators": () =>
|
||||
require("./logical-assignment-operators"),
|
||||
"max-classes-per-file": () => require("./max-classes-per-file"),
|
||||
"max-depth": () => require("./max-depth"),
|
||||
"max-len": () => require("./max-len"),
|
||||
"max-lines": () => require("./max-lines"),
|
||||
"max-lines-per-function": () => require("./max-lines-per-function"),
|
||||
"max-nested-callbacks": () => require("./max-nested-callbacks"),
|
||||
"max-params": () => require("./max-params"),
|
||||
"max-statements": () => require("./max-statements"),
|
||||
"max-statements-per-line": () => require("./max-statements-per-line"),
|
||||
"multiline-comment-style": () => require("./multiline-comment-style"),
|
||||
"multiline-ternary": () => require("./multiline-ternary"),
|
||||
"new-cap": () => require("./new-cap"),
|
||||
"new-parens": () => require("./new-parens"),
|
||||
"newline-after-var": () => require("./newline-after-var"),
|
||||
"newline-before-return": () => require("./newline-before-return"),
|
||||
"newline-per-chained-call": () => require("./newline-per-chained-call"),
|
||||
"no-alert": () => require("./no-alert"),
|
||||
"no-array-constructor": () => require("./no-array-constructor"),
|
||||
"no-async-promise-executor": () =>
|
||||
require("./no-async-promise-executor"),
|
||||
"no-await-in-loop": () => require("./no-await-in-loop"),
|
||||
"no-bitwise": () => require("./no-bitwise"),
|
||||
"no-buffer-constructor": () => require("./no-buffer-constructor"),
|
||||
"no-caller": () => require("./no-caller"),
|
||||
"no-case-declarations": () => require("./no-case-declarations"),
|
||||
"no-catch-shadow": () => require("./no-catch-shadow"),
|
||||
"no-class-assign": () => require("./no-class-assign"),
|
||||
"no-compare-neg-zero": () => require("./no-compare-neg-zero"),
|
||||
"no-cond-assign": () => require("./no-cond-assign"),
|
||||
"no-confusing-arrow": () => require("./no-confusing-arrow"),
|
||||
"no-console": () => require("./no-console"),
|
||||
"no-const-assign": () => require("./no-const-assign"),
|
||||
"no-constant-binary-expression": () =>
|
||||
require("./no-constant-binary-expression"),
|
||||
"no-constant-condition": () => require("./no-constant-condition"),
|
||||
"no-constructor-return": () => require("./no-constructor-return"),
|
||||
"no-continue": () => require("./no-continue"),
|
||||
"no-control-regex": () => require("./no-control-regex"),
|
||||
"no-debugger": () => require("./no-debugger"),
|
||||
"no-delete-var": () => require("./no-delete-var"),
|
||||
"no-div-regex": () => require("./no-div-regex"),
|
||||
"no-dupe-args": () => require("./no-dupe-args"),
|
||||
"no-dupe-class-members": () => require("./no-dupe-class-members"),
|
||||
"no-dupe-else-if": () => require("./no-dupe-else-if"),
|
||||
"no-dupe-keys": () => require("./no-dupe-keys"),
|
||||
"no-duplicate-case": () => require("./no-duplicate-case"),
|
||||
"no-duplicate-imports": () => require("./no-duplicate-imports"),
|
||||
"no-else-return": () => require("./no-else-return"),
|
||||
"no-empty": () => require("./no-empty"),
|
||||
"no-empty-character-class": () => require("./no-empty-character-class"),
|
||||
"no-empty-function": () => require("./no-empty-function"),
|
||||
"no-empty-pattern": () => require("./no-empty-pattern"),
|
||||
"no-empty-static-block": () => require("./no-empty-static-block"),
|
||||
"no-eq-null": () => require("./no-eq-null"),
|
||||
"no-eval": () => require("./no-eval"),
|
||||
"no-ex-assign": () => require("./no-ex-assign"),
|
||||
"no-extend-native": () => require("./no-extend-native"),
|
||||
"no-extra-bind": () => require("./no-extra-bind"),
|
||||
"no-extra-boolean-cast": () => require("./no-extra-boolean-cast"),
|
||||
"no-extra-label": () => require("./no-extra-label"),
|
||||
"no-extra-parens": () => require("./no-extra-parens"),
|
||||
"no-extra-semi": () => require("./no-extra-semi"),
|
||||
"no-fallthrough": () => require("./no-fallthrough"),
|
||||
"no-floating-decimal": () => require("./no-floating-decimal"),
|
||||
"no-func-assign": () => require("./no-func-assign"),
|
||||
"no-global-assign": () => require("./no-global-assign"),
|
||||
"no-implicit-coercion": () => require("./no-implicit-coercion"),
|
||||
"no-implicit-globals": () => require("./no-implicit-globals"),
|
||||
"no-implied-eval": () => require("./no-implied-eval"),
|
||||
"no-import-assign": () => require("./no-import-assign"),
|
||||
"no-inline-comments": () => require("./no-inline-comments"),
|
||||
"no-inner-declarations": () => require("./no-inner-declarations"),
|
||||
"no-invalid-regexp": () => require("./no-invalid-regexp"),
|
||||
"no-invalid-this": () => require("./no-invalid-this"),
|
||||
"no-irregular-whitespace": () => require("./no-irregular-whitespace"),
|
||||
"no-iterator": () => require("./no-iterator"),
|
||||
"no-label-var": () => require("./no-label-var"),
|
||||
"no-labels": () => require("./no-labels"),
|
||||
"no-lone-blocks": () => require("./no-lone-blocks"),
|
||||
"no-lonely-if": () => require("./no-lonely-if"),
|
||||
"no-loop-func": () => require("./no-loop-func"),
|
||||
"no-loss-of-precision": () => require("./no-loss-of-precision"),
|
||||
"no-magic-numbers": () => require("./no-magic-numbers"),
|
||||
"no-misleading-character-class": () =>
|
||||
require("./no-misleading-character-class"),
|
||||
"no-mixed-operators": () => require("./no-mixed-operators"),
|
||||
"no-mixed-requires": () => require("./no-mixed-requires"),
|
||||
"no-mixed-spaces-and-tabs": () => require("./no-mixed-spaces-and-tabs"),
|
||||
"no-multi-assign": () => require("./no-multi-assign"),
|
||||
"no-multi-spaces": () => require("./no-multi-spaces"),
|
||||
"no-multi-str": () => require("./no-multi-str"),
|
||||
"no-multiple-empty-lines": () => require("./no-multiple-empty-lines"),
|
||||
"no-native-reassign": () => require("./no-native-reassign"),
|
||||
"no-negated-condition": () => require("./no-negated-condition"),
|
||||
"no-negated-in-lhs": () => require("./no-negated-in-lhs"),
|
||||
"no-nested-ternary": () => require("./no-nested-ternary"),
|
||||
"no-new": () => require("./no-new"),
|
||||
"no-new-func": () => require("./no-new-func"),
|
||||
"no-new-native-nonconstructor": () =>
|
||||
require("./no-new-native-nonconstructor"),
|
||||
"no-new-object": () => require("./no-new-object"),
|
||||
"no-new-require": () => require("./no-new-require"),
|
||||
"no-new-symbol": () => require("./no-new-symbol"),
|
||||
"no-new-wrappers": () => require("./no-new-wrappers"),
|
||||
"no-nonoctal-decimal-escape": () =>
|
||||
require("./no-nonoctal-decimal-escape"),
|
||||
"no-obj-calls": () => require("./no-obj-calls"),
|
||||
"no-object-constructor": () => require("./no-object-constructor"),
|
||||
"no-octal": () => require("./no-octal"),
|
||||
"no-octal-escape": () => require("./no-octal-escape"),
|
||||
"no-param-reassign": () => require("./no-param-reassign"),
|
||||
"no-path-concat": () => require("./no-path-concat"),
|
||||
"no-plusplus": () => require("./no-plusplus"),
|
||||
"no-process-env": () => require("./no-process-env"),
|
||||
"no-process-exit": () => require("./no-process-exit"),
|
||||
"no-promise-executor-return": () =>
|
||||
require("./no-promise-executor-return"),
|
||||
"no-proto": () => require("./no-proto"),
|
||||
"no-prototype-builtins": () => require("./no-prototype-builtins"),
|
||||
"no-redeclare": () => require("./no-redeclare"),
|
||||
"no-regex-spaces": () => require("./no-regex-spaces"),
|
||||
"no-restricted-exports": () => require("./no-restricted-exports"),
|
||||
"no-restricted-globals": () => require("./no-restricted-globals"),
|
||||
"no-restricted-imports": () => require("./no-restricted-imports"),
|
||||
"no-restricted-modules": () => require("./no-restricted-modules"),
|
||||
"no-restricted-properties": () => require("./no-restricted-properties"),
|
||||
"no-restricted-syntax": () => require("./no-restricted-syntax"),
|
||||
"no-return-assign": () => require("./no-return-assign"),
|
||||
"no-return-await": () => require("./no-return-await"),
|
||||
"no-script-url": () => require("./no-script-url"),
|
||||
"no-self-assign": () => require("./no-self-assign"),
|
||||
"no-self-compare": () => require("./no-self-compare"),
|
||||
"no-sequences": () => require("./no-sequences"),
|
||||
"no-setter-return": () => require("./no-setter-return"),
|
||||
"no-shadow": () => require("./no-shadow"),
|
||||
"no-shadow-restricted-names": () =>
|
||||
require("./no-shadow-restricted-names"),
|
||||
"no-spaced-func": () => require("./no-spaced-func"),
|
||||
"no-sparse-arrays": () => require("./no-sparse-arrays"),
|
||||
"no-sync": () => require("./no-sync"),
|
||||
"no-tabs": () => require("./no-tabs"),
|
||||
"no-template-curly-in-string": () =>
|
||||
require("./no-template-curly-in-string"),
|
||||
"no-ternary": () => require("./no-ternary"),
|
||||
"no-this-before-super": () => require("./no-this-before-super"),
|
||||
"no-throw-literal": () => require("./no-throw-literal"),
|
||||
"no-trailing-spaces": () => require("./no-trailing-spaces"),
|
||||
"no-unassigned-vars": () => require("./no-unassigned-vars"),
|
||||
"no-undef": () => require("./no-undef"),
|
||||
"no-undef-init": () => require("./no-undef-init"),
|
||||
"no-undefined": () => require("./no-undefined"),
|
||||
"no-underscore-dangle": () => require("./no-underscore-dangle"),
|
||||
"no-unexpected-multiline": () => require("./no-unexpected-multiline"),
|
||||
"no-unmodified-loop-condition": () =>
|
||||
require("./no-unmodified-loop-condition"),
|
||||
"no-unneeded-ternary": () => require("./no-unneeded-ternary"),
|
||||
"no-unreachable": () => require("./no-unreachable"),
|
||||
"no-unreachable-loop": () => require("./no-unreachable-loop"),
|
||||
"no-unsafe-finally": () => require("./no-unsafe-finally"),
|
||||
"no-unsafe-negation": () => require("./no-unsafe-negation"),
|
||||
"no-unsafe-optional-chaining": () =>
|
||||
require("./no-unsafe-optional-chaining"),
|
||||
"no-unused-expressions": () => require("./no-unused-expressions"),
|
||||
"no-unused-labels": () => require("./no-unused-labels"),
|
||||
"no-unused-private-class-members": () =>
|
||||
require("./no-unused-private-class-members"),
|
||||
"no-unused-vars": () => require("./no-unused-vars"),
|
||||
"no-use-before-define": () => require("./no-use-before-define"),
|
||||
"no-useless-assignment": () => require("./no-useless-assignment"),
|
||||
"no-useless-backreference": () => require("./no-useless-backreference"),
|
||||
"no-useless-call": () => require("./no-useless-call"),
|
||||
"no-useless-catch": () => require("./no-useless-catch"),
|
||||
"no-useless-computed-key": () => require("./no-useless-computed-key"),
|
||||
"no-useless-concat": () => require("./no-useless-concat"),
|
||||
"no-useless-constructor": () => require("./no-useless-constructor"),
|
||||
"no-useless-escape": () => require("./no-useless-escape"),
|
||||
"no-useless-rename": () => require("./no-useless-rename"),
|
||||
"no-useless-return": () => require("./no-useless-return"),
|
||||
"no-var": () => require("./no-var"),
|
||||
"no-void": () => require("./no-void"),
|
||||
"no-warning-comments": () => require("./no-warning-comments"),
|
||||
"no-whitespace-before-property": () =>
|
||||
require("./no-whitespace-before-property"),
|
||||
"no-with": () => require("./no-with"),
|
||||
"nonblock-statement-body-position": () =>
|
||||
require("./nonblock-statement-body-position"),
|
||||
"object-curly-newline": () => require("./object-curly-newline"),
|
||||
"object-curly-spacing": () => require("./object-curly-spacing"),
|
||||
"object-property-newline": () => require("./object-property-newline"),
|
||||
"object-shorthand": () => require("./object-shorthand"),
|
||||
"one-var": () => require("./one-var"),
|
||||
"one-var-declaration-per-line": () =>
|
||||
require("./one-var-declaration-per-line"),
|
||||
"operator-assignment": () => require("./operator-assignment"),
|
||||
"operator-linebreak": () => require("./operator-linebreak"),
|
||||
"padded-blocks": () => require("./padded-blocks"),
|
||||
"padding-line-between-statements": () =>
|
||||
require("./padding-line-between-statements"),
|
||||
"prefer-arrow-callback": () => require("./prefer-arrow-callback"),
|
||||
"prefer-const": () => require("./prefer-const"),
|
||||
"prefer-destructuring": () => require("./prefer-destructuring"),
|
||||
"prefer-exponentiation-operator": () =>
|
||||
require("./prefer-exponentiation-operator"),
|
||||
"prefer-named-capture-group": () =>
|
||||
require("./prefer-named-capture-group"),
|
||||
"prefer-numeric-literals": () => require("./prefer-numeric-literals"),
|
||||
"prefer-object-has-own": () => require("./prefer-object-has-own"),
|
||||
"prefer-object-spread": () => require("./prefer-object-spread"),
|
||||
"prefer-promise-reject-errors": () =>
|
||||
require("./prefer-promise-reject-errors"),
|
||||
"prefer-reflect": () => require("./prefer-reflect"),
|
||||
"prefer-regex-literals": () => require("./prefer-regex-literals"),
|
||||
"prefer-rest-params": () => require("./prefer-rest-params"),
|
||||
"prefer-spread": () => require("./prefer-spread"),
|
||||
"prefer-template": () => require("./prefer-template"),
|
||||
"preserve-caught-error": () => require("./preserve-caught-error"),
|
||||
"quote-props": () => require("./quote-props"),
|
||||
quotes: () => require("./quotes"),
|
||||
radix: () => require("./radix"),
|
||||
"require-atomic-updates": () => require("./require-atomic-updates"),
|
||||
"require-await": () => require("./require-await"),
|
||||
"require-unicode-regexp": () => require("./require-unicode-regexp"),
|
||||
"require-yield": () => require("./require-yield"),
|
||||
"rest-spread-spacing": () => require("./rest-spread-spacing"),
|
||||
semi: () => require("./semi"),
|
||||
"semi-spacing": () => require("./semi-spacing"),
|
||||
"semi-style": () => require("./semi-style"),
|
||||
"sort-imports": () => require("./sort-imports"),
|
||||
"sort-keys": () => require("./sort-keys"),
|
||||
"sort-vars": () => require("./sort-vars"),
|
||||
"space-before-blocks": () => require("./space-before-blocks"),
|
||||
"space-before-function-paren": () =>
|
||||
require("./space-before-function-paren"),
|
||||
"space-in-parens": () => require("./space-in-parens"),
|
||||
"space-infix-ops": () => require("./space-infix-ops"),
|
||||
"space-unary-ops": () => require("./space-unary-ops"),
|
||||
"spaced-comment": () => require("./spaced-comment"),
|
||||
strict: () => require("./strict"),
|
||||
"switch-colon-spacing": () => require("./switch-colon-spacing"),
|
||||
"symbol-description": () => require("./symbol-description"),
|
||||
"template-curly-spacing": () => require("./template-curly-spacing"),
|
||||
"template-tag-spacing": () => require("./template-tag-spacing"),
|
||||
"unicode-bom": () => require("./unicode-bom"),
|
||||
"use-isnan": () => require("./use-isnan"),
|
||||
"valid-typeof": () => require("./valid-typeof"),
|
||||
"vars-on-top": () => require("./vars-on-top"),
|
||||
"wrap-iife": () => require("./wrap-iife"),
|
||||
"wrap-regex": () => require("./wrap-regex"),
|
||||
"yield-star-spacing": () => require("./yield-star-spacing"),
|
||||
yoda: () => require("./yoda"),
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,2 @@
|
||||
function _temporalUndefined() {}
|
||||
module.exports = _temporalUndefined, module.exports.__esModule = true, module.exports["default"] = module.exports;
|
||||
@@ -0,0 +1,400 @@
|
||||
/**
|
||||
* @fileoverview This rule should require or disallow spaces before or after unary operations.
|
||||
* @author Marcin Kumorek
|
||||
* @deprecated in ESLint v8.53.0
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
deprecated: {
|
||||
message: "Formatting rules are being moved out of ESLint core.",
|
||||
url: "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
|
||||
deprecatedSince: "8.53.0",
|
||||
availableUntil: "11.0.0",
|
||||
replacedBy: [
|
||||
{
|
||||
message:
|
||||
"ESLint Stylistic now maintains deprecated stylistic core rules.",
|
||||
url: "https://eslint.style/guide/migration",
|
||||
plugin: {
|
||||
name: "@stylistic/eslint-plugin",
|
||||
url: "https://eslint.style",
|
||||
},
|
||||
rule: {
|
||||
name: "space-unary-ops",
|
||||
url: "https://eslint.style/rules/space-unary-ops",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
type: "layout",
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Enforce consistent spacing before or after unary operators",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/space-unary-ops",
|
||||
},
|
||||
|
||||
fixable: "whitespace",
|
||||
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
words: {
|
||||
type: "boolean",
|
||||
default: true,
|
||||
},
|
||||
nonwords: {
|
||||
type: "boolean",
|
||||
default: false,
|
||||
},
|
||||
overrides: {
|
||||
type: "object",
|
||||
additionalProperties: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
unexpectedBefore:
|
||||
"Unexpected space before unary operator '{{operator}}'.",
|
||||
unexpectedAfter:
|
||||
"Unexpected space after unary operator '{{operator}}'.",
|
||||
unexpectedAfterWord:
|
||||
"Unexpected space after unary word operator '{{word}}'.",
|
||||
wordOperator:
|
||||
"Unary word operator '{{word}}' must be followed by whitespace.",
|
||||
operator:
|
||||
"Unary operator '{{operator}}' must be followed by whitespace.",
|
||||
beforeUnaryExpressions:
|
||||
"Space is required before unary expressions '{{token}}'.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const options = context.options[0] || { words: true, nonwords: false };
|
||||
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Check if the node is the first "!" in a "!!" convert to Boolean expression
|
||||
* @param {ASTnode} node AST node
|
||||
* @returns {boolean} Whether or not the node is first "!" in "!!"
|
||||
*/
|
||||
function isFirstBangInBangBangExpression(node) {
|
||||
return (
|
||||
node &&
|
||||
node.type === "UnaryExpression" &&
|
||||
node.argument.operator === "!" &&
|
||||
node.argument &&
|
||||
node.argument.type === "UnaryExpression" &&
|
||||
node.argument.operator === "!"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an override exists for a given operator.
|
||||
* @param {string} operator Operator
|
||||
* @returns {boolean} Whether or not an override has been provided for the operator
|
||||
*/
|
||||
function overrideExistsForOperator(operator) {
|
||||
return (
|
||||
options.overrides && Object.hasOwn(options.overrides, operator)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value that the override was set to for this operator
|
||||
* @param {string} operator Operator
|
||||
* @returns {boolean} Whether or not an override enforces a space with this operator
|
||||
*/
|
||||
function overrideEnforcesSpaces(operator) {
|
||||
return options.overrides[operator];
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify Unary Word Operator has spaces after the word operator
|
||||
* @param {ASTnode} node AST node
|
||||
* @param {Object} firstToken first token from the AST node
|
||||
* @param {Object} secondToken second token from the AST node
|
||||
* @param {string} word The word to be used for reporting
|
||||
* @returns {void}
|
||||
*/
|
||||
function verifyWordHasSpaces(node, firstToken, secondToken, word) {
|
||||
if (secondToken.range[0] === firstToken.range[1]) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "wordOperator",
|
||||
data: {
|
||||
word,
|
||||
},
|
||||
fix(fixer) {
|
||||
return fixer.insertTextAfter(firstToken, " ");
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify Unary Word Operator doesn't have spaces after the word operator
|
||||
* @param {ASTnode} node AST node
|
||||
* @param {Object} firstToken first token from the AST node
|
||||
* @param {Object} secondToken second token from the AST node
|
||||
* @param {string} word The word to be used for reporting
|
||||
* @returns {void}
|
||||
*/
|
||||
function verifyWordDoesntHaveSpaces(
|
||||
node,
|
||||
firstToken,
|
||||
secondToken,
|
||||
word,
|
||||
) {
|
||||
if (astUtils.canTokensBeAdjacent(firstToken, secondToken)) {
|
||||
if (secondToken.range[0] > firstToken.range[1]) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "unexpectedAfterWord",
|
||||
data: {
|
||||
word,
|
||||
},
|
||||
fix(fixer) {
|
||||
return fixer.removeRange([
|
||||
firstToken.range[1],
|
||||
secondToken.range[0],
|
||||
]);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Unary Word Operators for spaces after the word operator
|
||||
* @param {ASTnode} node AST node
|
||||
* @param {Object} firstToken first token from the AST node
|
||||
* @param {Object} secondToken second token from the AST node
|
||||
* @param {string} word The word to be used for reporting
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkUnaryWordOperatorForSpaces(
|
||||
node,
|
||||
firstToken,
|
||||
secondToken,
|
||||
word,
|
||||
) {
|
||||
if (overrideExistsForOperator(word)) {
|
||||
if (overrideEnforcesSpaces(word)) {
|
||||
verifyWordHasSpaces(node, firstToken, secondToken, word);
|
||||
} else {
|
||||
verifyWordDoesntHaveSpaces(
|
||||
node,
|
||||
firstToken,
|
||||
secondToken,
|
||||
word,
|
||||
);
|
||||
}
|
||||
} else if (options.words) {
|
||||
verifyWordHasSpaces(node, firstToken, secondToken, word);
|
||||
} else {
|
||||
verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies YieldExpressions satisfy spacing requirements
|
||||
* @param {ASTnode} node AST node
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkForSpacesAfterYield(node) {
|
||||
const tokens = sourceCode.getFirstTokens(node, 3),
|
||||
word = "yield";
|
||||
|
||||
if (!node.argument || node.delegate) {
|
||||
return;
|
||||
}
|
||||
|
||||
checkUnaryWordOperatorForSpaces(node, tokens[0], tokens[1], word);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies AwaitExpressions satisfy spacing requirements
|
||||
* @param {ASTNode} node AwaitExpression AST node
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkForSpacesAfterAwait(node) {
|
||||
const tokens = sourceCode.getFirstTokens(node, 3);
|
||||
|
||||
checkUnaryWordOperatorForSpaces(
|
||||
node,
|
||||
tokens[0],
|
||||
tokens[1],
|
||||
"await",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies UnaryExpression, UpdateExpression and NewExpression have spaces before or after the operator
|
||||
* @param {ASTnode} node AST node
|
||||
* @param {Object} firstToken First token in the expression
|
||||
* @param {Object} secondToken Second token in the expression
|
||||
* @returns {void}
|
||||
*/
|
||||
function verifyNonWordsHaveSpaces(node, firstToken, secondToken) {
|
||||
if (node.prefix) {
|
||||
if (isFirstBangInBangBangExpression(node)) {
|
||||
return;
|
||||
}
|
||||
if (firstToken.range[1] === secondToken.range[0]) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "operator",
|
||||
data: {
|
||||
operator: firstToken.value,
|
||||
},
|
||||
fix(fixer) {
|
||||
return fixer.insertTextAfter(firstToken, " ");
|
||||
},
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (firstToken.range[1] === secondToken.range[0]) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "beforeUnaryExpressions",
|
||||
data: {
|
||||
token: secondToken.value,
|
||||
},
|
||||
fix(fixer) {
|
||||
return fixer.insertTextBefore(secondToken, " ");
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies UnaryExpression, UpdateExpression and NewExpression don't have spaces before or after the operator
|
||||
* @param {ASTnode} node AST node
|
||||
* @param {Object} firstToken First token in the expression
|
||||
* @param {Object} secondToken Second token in the expression
|
||||
* @returns {void}
|
||||
*/
|
||||
function verifyNonWordsDontHaveSpaces(node, firstToken, secondToken) {
|
||||
if (node.prefix) {
|
||||
if (secondToken.range[0] > firstToken.range[1]) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "unexpectedAfter",
|
||||
data: {
|
||||
operator: firstToken.value,
|
||||
},
|
||||
fix(fixer) {
|
||||
if (
|
||||
astUtils.canTokensBeAdjacent(
|
||||
firstToken,
|
||||
secondToken,
|
||||
)
|
||||
) {
|
||||
return fixer.removeRange([
|
||||
firstToken.range[1],
|
||||
secondToken.range[0],
|
||||
]);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (secondToken.range[0] > firstToken.range[1]) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "unexpectedBefore",
|
||||
data: {
|
||||
operator: secondToken.value,
|
||||
},
|
||||
fix(fixer) {
|
||||
return fixer.removeRange([
|
||||
firstToken.range[1],
|
||||
secondToken.range[0],
|
||||
]);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies UnaryExpression, UpdateExpression and NewExpression satisfy spacing requirements
|
||||
* @param {ASTnode} node AST node
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkForSpaces(node) {
|
||||
const tokens =
|
||||
node.type === "UpdateExpression" && !node.prefix
|
||||
? sourceCode.getLastTokens(node, 2)
|
||||
: sourceCode.getFirstTokens(node, 2);
|
||||
const firstToken = tokens[0];
|
||||
const secondToken = tokens[1];
|
||||
|
||||
if (
|
||||
(node.type === "NewExpression" || node.prefix) &&
|
||||
firstToken.type === "Keyword"
|
||||
) {
|
||||
checkUnaryWordOperatorForSpaces(
|
||||
node,
|
||||
firstToken,
|
||||
secondToken,
|
||||
firstToken.value,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const operator = node.prefix ? tokens[0].value : tokens[1].value;
|
||||
|
||||
if (overrideExistsForOperator(operator)) {
|
||||
if (overrideEnforcesSpaces(operator)) {
|
||||
verifyNonWordsHaveSpaces(node, firstToken, secondToken);
|
||||
} else {
|
||||
verifyNonWordsDontHaveSpaces(node, firstToken, secondToken);
|
||||
}
|
||||
} else if (options.nonwords) {
|
||||
verifyNonWordsHaveSpaces(node, firstToken, secondToken);
|
||||
} else {
|
||||
verifyNonWordsDontHaveSpaces(node, firstToken, secondToken);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
UnaryExpression: checkForSpaces,
|
||||
UpdateExpression: checkForSpaces,
|
||||
NewExpression: checkForSpaces,
|
||||
YieldExpression: checkForSpacesAfterYield,
|
||||
AwaitExpression: checkForSpacesAfterAwait,
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,688 @@
|
||||
/**
|
||||
* @fileoverview Rule to flag on declaring variables already declared in the outer scope
|
||||
* @author Ilya Volodin
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Types
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @typedef {import("eslint-scope").Variable} Variable */
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const FUNC_EXPR_NODE_TYPES = new Set([
|
||||
"ArrowFunctionExpression",
|
||||
"FunctionExpression",
|
||||
]);
|
||||
const CALL_EXPR_NODE_TYPE = new Set(["CallExpression"]);
|
||||
const FOR_IN_OF_TYPE = /^For(?:In|Of)Statement$/u;
|
||||
const SENTINEL_TYPE =
|
||||
/^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/u;
|
||||
|
||||
// TS-specific node types
|
||||
const TYPES_HOISTED_NODES = new Set([
|
||||
"TSInterfaceDeclaration",
|
||||
"TSTypeAliasDeclaration",
|
||||
]);
|
||||
|
||||
// TS-specific function variable def types
|
||||
const ALLOWED_FUNCTION_VARIABLE_DEF_TYPES = new Set([
|
||||
"TSCallSignatureDeclaration",
|
||||
"TSFunctionType",
|
||||
"TSMethodSignature",
|
||||
"TSEmptyBodyFunctionExpression",
|
||||
"TSDeclareFunction",
|
||||
"TSConstructSignatureDeclaration",
|
||||
"TSConstructorType",
|
||||
]);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
|
||||
defaultOptions: [
|
||||
{
|
||||
allow: [],
|
||||
builtinGlobals: false,
|
||||
hoist: "functions",
|
||||
ignoreOnInitialization: false,
|
||||
ignoreTypeValueShadow: true,
|
||||
ignoreFunctionTypeParameterNameValueShadow: true,
|
||||
},
|
||||
],
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Disallow variable declarations from shadowing variables declared in the outer scope",
|
||||
dialects: ["JavaScript", "TypeScript"],
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/no-shadow",
|
||||
},
|
||||
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
builtinGlobals: { type: "boolean" },
|
||||
hoist: {
|
||||
enum: [
|
||||
"all",
|
||||
"functions",
|
||||
"never",
|
||||
"types",
|
||||
"functions-and-types",
|
||||
],
|
||||
},
|
||||
allow: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
ignoreOnInitialization: { type: "boolean" },
|
||||
ignoreTypeValueShadow: { type: "boolean" },
|
||||
ignoreFunctionTypeParameterNameValueShadow: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
|
||||
messages: {
|
||||
noShadow:
|
||||
"'{{name}}' is already declared in the upper scope on line {{shadowedLine}} column {{shadowedColumn}}.",
|
||||
noShadowGlobal: "'{{name}}' is already a global variable.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const [
|
||||
{
|
||||
builtinGlobals,
|
||||
hoist,
|
||||
allow,
|
||||
ignoreOnInitialization,
|
||||
ignoreTypeValueShadow,
|
||||
ignoreFunctionTypeParameterNameValueShadow,
|
||||
},
|
||||
] = context.options;
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
/**
|
||||
* Check if a scope is a TypeScript module augmenting the global namespace.
|
||||
* @param {Scope} scope The scope to check
|
||||
* @returns {boolean} Whether the scope is a global augmentation
|
||||
*/
|
||||
function isGlobalAugmentation(scope) {
|
||||
return (
|
||||
scope.block.kind === "global" ||
|
||||
(!!scope.upper && isGlobalAugmentation(scope.upper))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if variable is a `this` parameter.
|
||||
* @param {Object} variable The variable to check
|
||||
* @returns {boolean} Whether the variable is a this parameter
|
||||
*/
|
||||
function isThisParam(variable) {
|
||||
return variable.name === "this";
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if type and value shadows each other
|
||||
* @param {Object} variable The variable to check
|
||||
* @param {Object} shadowedVariable The shadowed variable
|
||||
* @returns {boolean} Whether it's a type/value shadow case to ignore
|
||||
*/
|
||||
function isTypeValueShadow(variable, shadowedVariable) {
|
||||
if (ignoreTypeValueShadow !== true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!("isValueVariable" in variable)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const firstDefinition = shadowedVariable.defs[0];
|
||||
|
||||
// Check if shadowedVariable is a type import
|
||||
const isTypeImport =
|
||||
firstDefinition &&
|
||||
firstDefinition.parent?.type === "ImportDeclaration" &&
|
||||
(firstDefinition.parent.importKind === "type" ||
|
||||
firstDefinition.parent.specifiers.some(
|
||||
s => s.importKind === "type",
|
||||
));
|
||||
|
||||
const isShadowedValue =
|
||||
!firstDefinition ||
|
||||
(isTypeImport ? false : shadowedVariable.isValueVariable);
|
||||
|
||||
return variable.isValueVariable !== isShadowedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if it's a function type parameter shadow
|
||||
* @param {Object} variable The variable to check
|
||||
* @returns {boolean} Whether it's a function type parameter shadow case to ignore
|
||||
*/
|
||||
function isFunctionTypeParameterNameValueShadow(variable) {
|
||||
if (ignoreFunctionTypeParameterNameValueShadow !== true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return variable.defs.some(def =>
|
||||
ALLOWED_FUNCTION_VARIABLE_DEF_TYPES.has(def.node.type),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the variable is a generic of a static method
|
||||
* @param {Object} variable The variable to check
|
||||
* @returns {boolean} Whether the variable is a generic of a static method
|
||||
*/
|
||||
function isTypeParameterOfStaticMethod(variable) {
|
||||
const typeParameter = variable.identifiers[0].parent;
|
||||
const typeParameterDecl = typeParameter.parent;
|
||||
if (typeParameterDecl.type !== "TSTypeParameterDeclaration") {
|
||||
return false;
|
||||
}
|
||||
const functionExpr = typeParameterDecl.parent;
|
||||
const methodDefinition = functionExpr.parent;
|
||||
return methodDefinition.static;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for static method generic shadowing class generic
|
||||
* @param {Object} variable The variable to check
|
||||
* @returns {boolean} Whether it's a static method generic shadowing class generic
|
||||
*/
|
||||
function isGenericOfAStaticMethodShadow(variable) {
|
||||
return isTypeParameterOfStaticMethod(variable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether or not a given location is inside of the range of a given node.
|
||||
* @param {ASTNode} node An node to check.
|
||||
* @param {number} location A location to check.
|
||||
* @returns {boolean} `true` if the location is inside of the range of the node.
|
||||
*/
|
||||
function isInRange(node, location) {
|
||||
return (
|
||||
node && node.range[0] <= location && location <= node.range[1]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches from the current node through its ancestry to find a matching node.
|
||||
* @param {ASTNode} node a node to get.
|
||||
* @param {(node: ASTNode) => boolean} match a callback that checks whether or not the node verifies its condition or not.
|
||||
* @returns {ASTNode|null} the matching node.
|
||||
*/
|
||||
function findSelfOrAncestor(node, match) {
|
||||
let currentNode = node;
|
||||
|
||||
while (currentNode && !match(currentNode)) {
|
||||
currentNode = currentNode.parent;
|
||||
}
|
||||
return currentNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds function's outer scope.
|
||||
* @param {Scope} scope Function's own scope.
|
||||
* @returns {Scope} Function's outer scope.
|
||||
*/
|
||||
function getOuterScope(scope) {
|
||||
const upper = scope.upper;
|
||||
|
||||
if (upper && upper.type === "function-expression-name") {
|
||||
return upper.upper;
|
||||
}
|
||||
return upper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a variable and a shadowedVariable have the same init pattern ancestor.
|
||||
* @param {Object} variable a variable to check.
|
||||
* @param {Object} shadowedVariable a shadowedVariable to check.
|
||||
* @returns {boolean} Whether or not the variable and the shadowedVariable have the same init pattern ancestor.
|
||||
*/
|
||||
function isInitPatternNode(variable, shadowedVariable) {
|
||||
const outerDef = shadowedVariable.defs[0];
|
||||
|
||||
if (!outerDef) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { variableScope } = variable.scope;
|
||||
|
||||
if (!(
|
||||
FUNC_EXPR_NODE_TYPES.has(variableScope.block.type) &&
|
||||
getOuterScope(variableScope) === shadowedVariable.scope
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const fun = variableScope.block;
|
||||
const { parent } = fun;
|
||||
|
||||
const callExpression = findSelfOrAncestor(parent, node =>
|
||||
CALL_EXPR_NODE_TYPE.has(node.type),
|
||||
);
|
||||
|
||||
if (!callExpression) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let node = outerDef.name;
|
||||
const location = callExpression.range[1];
|
||||
|
||||
while (node) {
|
||||
if (node.type === "VariableDeclarator") {
|
||||
if (isInRange(node.init, location)) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
FOR_IN_OF_TYPE.test(node.parent.parent.type) &&
|
||||
isInRange(node.parent.parent.right, location)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
} else if (node.type === "AssignmentPattern") {
|
||||
if (isInRange(node.right, location)) {
|
||||
return true;
|
||||
}
|
||||
} else if (SENTINEL_TYPE.test(node.type)) {
|
||||
break;
|
||||
}
|
||||
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if variable name is allowed.
|
||||
* @param {ASTNode} variable The variable to check.
|
||||
* @returns {boolean} Whether or not the variable name is allowed.
|
||||
*/
|
||||
function isAllowed(variable) {
|
||||
return allow.includes(variable.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a variable of the class name in the class scope of ClassDeclaration.
|
||||
*
|
||||
* ClassDeclaration creates two variables of its name into its outer scope and its class scope.
|
||||
* So we should ignore the variable in the class scope.
|
||||
* @param {Object} variable The variable to check.
|
||||
* @returns {boolean} Whether or not the variable of the class name in the class scope of ClassDeclaration.
|
||||
*/
|
||||
function isDuplicatedClassNameVariable(variable) {
|
||||
const block = variable.scope.block;
|
||||
|
||||
return (
|
||||
block.type === "ClassDeclaration" &&
|
||||
block.id === variable.identifiers[0]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the uppermost expression node that can evaluate to the given one.
|
||||
*
|
||||
* Examples:
|
||||
* If given `a` in `a || foo`, it returns the `a || foo` node.
|
||||
* If given `a` in `foo ? a : bar`, it returns the `foo ? a : bar` node.
|
||||
* If given `a` in `foo ? bar : (baz && a)`, it returns the `foo ? bar : (baz && a)` node.
|
||||
* If given `a` in `a ? foo : bar`, it returns the `a` node.
|
||||
* If given `a` in `foo(a)`, it returns the `a` node.
|
||||
* @param {ASTNode} expression The expression node to unwrap.
|
||||
* @returns {ASTNode} The uppermost ancestor that can evaluate to the given node
|
||||
* or the given node if there is no such ancestor.
|
||||
*/
|
||||
function unwrapExpression(expression) {
|
||||
const { parent } = expression;
|
||||
|
||||
const shouldUnwrap =
|
||||
parent.type === "LogicalExpression" ||
|
||||
(parent.type === "ConditionalExpression" &&
|
||||
parent.test !== expression);
|
||||
|
||||
return shouldUnwrap ? unwrapExpression(parent) : expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if inner variable is the name of a function or class
|
||||
* that is assigned to outer variable as its initializer.
|
||||
*
|
||||
* To avoid reporting at declarations such as:
|
||||
* var a = function a() {};
|
||||
* var A = class A {};
|
||||
* var a = foo || function a() {};
|
||||
* var a = foo ? function a() {} : bar;
|
||||
* var { a = function a() {} } = foo;
|
||||
*
|
||||
* But it should report at declarations such as:
|
||||
* var a = function(a) {};
|
||||
* var a = function() { function a() {} };
|
||||
* var a = wrap(function a() {});
|
||||
* @param {Object} innerVariable The inner variable to check.
|
||||
* @param {Object} outerVariable The outer variable.
|
||||
* @returns {boolean} Whether or not inner variable is the name of a
|
||||
* function or class that is assigned to outer variable as its initializer.
|
||||
*/
|
||||
function isFunctionNameInitializerException(
|
||||
innerVariable,
|
||||
outerVariable,
|
||||
) {
|
||||
const outerDef = outerVariable.defs[0];
|
||||
const innerDef = innerVariable.defs[0];
|
||||
|
||||
if (!outerDef || !innerDef) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(
|
||||
(innerDef.type === "FunctionName" &&
|
||||
innerDef.node.type === "FunctionExpression") ||
|
||||
(innerDef.type === "ClassName" &&
|
||||
innerDef.node.type === "ClassExpression")
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const outerIdentifier = outerDef.name;
|
||||
let initializerNode;
|
||||
|
||||
if (outerIdentifier.parent.type === "VariableDeclarator") {
|
||||
initializerNode = outerIdentifier.parent.init;
|
||||
} else if (outerIdentifier.parent.type === "AssignmentPattern") {
|
||||
initializerNode = outerIdentifier.parent.right;
|
||||
}
|
||||
|
||||
if (!initializerNode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const nodeToCheck = innerDef.node; // FunctionExpression or ClassExpression node
|
||||
|
||||
// Exit early if the node to check isn't inside the initializer
|
||||
if (!(
|
||||
initializerNode.range[0] <= nodeToCheck.range[0] &&
|
||||
nodeToCheck.range[1] <= initializerNode.range[1]
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return initializerNode === unwrapExpression(nodeToCheck);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a range of a variable's identifier node.
|
||||
* @param {Object} variable The variable to get.
|
||||
* @returns {Array|undefined} The range of the variable's identifier node.
|
||||
*/
|
||||
function getNameRange(variable) {
|
||||
const def = variable.defs[0];
|
||||
|
||||
return def && def.name.range;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get declared line and column of a variable.
|
||||
* @param {Variable} variable The variable to get.
|
||||
* @returns {Object} The declared line and column of the variable.
|
||||
*/
|
||||
function getDeclaredLocation(variable) {
|
||||
const identifier = variable.identifiers[0];
|
||||
let obj;
|
||||
|
||||
if (identifier) {
|
||||
obj = {
|
||||
global: false,
|
||||
line: identifier.loc.start.line,
|
||||
column: identifier.loc.start.column + 1,
|
||||
};
|
||||
} else {
|
||||
obj = {
|
||||
global: true,
|
||||
};
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a variable is in TDZ of scopeVar.
|
||||
* @param {Object} variable The variable to check.
|
||||
* @param {Object} scopeVar The variable of TDZ.
|
||||
* @returns {boolean} Whether or not the variable is in TDZ of scopeVar.
|
||||
*/
|
||||
function isInTdz(variable, scopeVar) {
|
||||
const outerDef = scopeVar.defs[0];
|
||||
const inner = getNameRange(variable);
|
||||
const outer = getNameRange(scopeVar);
|
||||
|
||||
if (!outer || inner[1] >= outer[0]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hoist === "types") {
|
||||
return !TYPES_HOISTED_NODES.has(outerDef.node.type);
|
||||
}
|
||||
|
||||
if (hoist === "functions-and-types") {
|
||||
return (
|
||||
outerDef.node.type !== "FunctionDeclaration" &&
|
||||
!TYPES_HOISTED_NODES.has(outerDef.node.type)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
inner &&
|
||||
outer &&
|
||||
inner[1] < outer[0] &&
|
||||
// Excepts FunctionDeclaration if is {"hoist":"function"}.
|
||||
(hoist !== "functions" ||
|
||||
!outerDef ||
|
||||
outerDef.node.type !== "FunctionDeclaration")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the initialization of a variable has the declare modifier in a
|
||||
* definition file.
|
||||
* @param {Object} variable The variable to check
|
||||
* @returns {boolean} Whether the variable is declared in a definition file
|
||||
*/
|
||||
function isDeclareInDTSFile(variable) {
|
||||
const fileName = context.filename;
|
||||
if (
|
||||
!fileName.endsWith(".d.ts") &&
|
||||
!fileName.endsWith(".d.cts") &&
|
||||
!fileName.endsWith(".d.mts")
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return variable.defs.some(
|
||||
def =>
|
||||
(def.type === "Variable" && def.parent.declare) ||
|
||||
(def.type === "ClassName" && def.node.declare) ||
|
||||
(def.type === "TSEnumName" && def.node.declare) ||
|
||||
(def.type === "TSModuleName" && def.node.declare),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a variable is a duplicate of an enum name in the enum scope
|
||||
* @param {Object} variable The variable to check
|
||||
* @returns {boolean} Whether it's a duplicate enum name variable
|
||||
*/
|
||||
function isDuplicatedEnumNameVariable(variable) {
|
||||
const block = variable.scope.block;
|
||||
|
||||
return (
|
||||
block.type === "TSEnumDeclaration" &&
|
||||
block.id === variable.identifiers[0]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this is an external module declaration merging with a type import
|
||||
* @param {Scope} scope Current scope
|
||||
* @param {Object} variable Current variable
|
||||
* @param {Object} shadowedVariable Shadowed variable
|
||||
* @returns {boolean} Whether it's an external declaration merging
|
||||
*/
|
||||
function isExternalDeclarationMerging(
|
||||
scope,
|
||||
variable,
|
||||
shadowedVariable,
|
||||
) {
|
||||
const firstDefinition = shadowedVariable.defs[0];
|
||||
|
||||
if (!firstDefinition || !firstDefinition.parent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the shadowed variable is a type import
|
||||
const isTypeImport =
|
||||
firstDefinition.parent.type === "ImportDeclaration" &&
|
||||
(firstDefinition.parent.importKind === "type" ||
|
||||
firstDefinition.parent.specifiers?.some(
|
||||
s =>
|
||||
s.type === "ImportSpecifier" &&
|
||||
s.importKind === "type" &&
|
||||
s.local.name === shadowedVariable.name,
|
||||
));
|
||||
|
||||
if (!isTypeImport) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the current variable is within a module declaration
|
||||
const moduleDecl = findSelfOrAncestor(
|
||||
variable.identifiers[0]?.parent,
|
||||
node => node.type === "TSModuleDeclaration",
|
||||
);
|
||||
|
||||
if (!moduleDecl) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module declaration merging should only happen within the same module
|
||||
* Check if the module name matches the import source
|
||||
*/
|
||||
const importSource = firstDefinition.parent.source.value;
|
||||
const moduleName =
|
||||
moduleDecl.id.type === "Literal"
|
||||
? moduleDecl.id.value
|
||||
: moduleDecl.id.name;
|
||||
|
||||
return importSource === moduleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the current context for shadowed variables.
|
||||
* @param {Scope} scope The scope to check for shadowed variables.
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkForShadows(scope) {
|
||||
// ignore global augmentation
|
||||
if (isGlobalAugmentation(scope)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const variables = scope.variables;
|
||||
|
||||
for (let i = 0; i < variables.length; ++i) {
|
||||
const variable = variables[i];
|
||||
|
||||
// Skips "arguments" or variables of a class name in the class scope of ClassDeclaration.
|
||||
if (
|
||||
variable.identifiers.length === 0 ||
|
||||
isDuplicatedClassNameVariable(variable) ||
|
||||
isDuplicatedEnumNameVariable(variable) ||
|
||||
isAllowed(variable) ||
|
||||
isDeclareInDTSFile(variable) ||
|
||||
isThisParam(variable)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Gets shadowed variable.
|
||||
const shadowed = astUtils.getVariableByName(
|
||||
scope.upper,
|
||||
variable.name,
|
||||
);
|
||||
|
||||
if (
|
||||
shadowed &&
|
||||
(shadowed.identifiers.length > 0 ||
|
||||
(builtinGlobals && "writeable" in shadowed)) &&
|
||||
!isFunctionNameInitializerException(variable, shadowed) &&
|
||||
!(
|
||||
ignoreOnInitialization &&
|
||||
isInitPatternNode(variable, shadowed)
|
||||
) &&
|
||||
!(hoist !== "all" && isInTdz(variable, shadowed)) &&
|
||||
!isTypeValueShadow(variable, shadowed) &&
|
||||
!isFunctionTypeParameterNameValueShadow(variable) &&
|
||||
!isGenericOfAStaticMethodShadow(variable, shadowed) &&
|
||||
!isExternalDeclarationMerging(scope, variable, shadowed)
|
||||
) {
|
||||
const location = getDeclaredLocation(shadowed);
|
||||
const messageId = location.global
|
||||
? "noShadowGlobal"
|
||||
: "noShadow";
|
||||
const data = { name: variable.name };
|
||||
|
||||
if (!location.global) {
|
||||
data.shadowedLine = location.line;
|
||||
data.shadowedColumn = location.column;
|
||||
}
|
||||
context.report({
|
||||
node: variable.identifiers[0],
|
||||
messageId,
|
||||
data,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
"Program:exit"(node) {
|
||||
const globalScope = sourceCode.getScope(node);
|
||||
const stack = globalScope.childScopes.slice();
|
||||
|
||||
while (stack.length) {
|
||||
const scope = stack.pop();
|
||||
|
||||
stack.push(...scope.childScopes);
|
||||
checkForShadows(scope);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
function _writeOnlyError(r) {
|
||||
throw new TypeError('"' + r + '" is write-only');
|
||||
}
|
||||
export { _writeOnlyError as default };
|
||||
@@ -0,0 +1,11 @@
|
||||
"use strict";
|
||||
// THIS CODE WAS AUTOMATICALLY GENERATED
|
||||
// DO NOT EDIT THIS CODE BY HAND
|
||||
// RUN THE FOLLOWING COMMAND FROM THE WORKSPACE ROOT TO REGENERATE:
|
||||
// npx nx generate-lib repo
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.webworker_iterable = void 0;
|
||||
exports.webworker_iterable = {
|
||||
libs: [],
|
||||
variables: [],
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* @fileoverview Rule to restrict what can be thrown as an exception.
|
||||
* @author Dieter Oberkofler
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
|
||||
docs: {
|
||||
description: "Disallow throwing literals as exceptions",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/no-throw-literal",
|
||||
},
|
||||
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
object: "Expected an error object to be thrown.",
|
||||
undef: "Do not throw undefined.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
return {
|
||||
ThrowStatement(node) {
|
||||
if (!astUtils.couldBeError(node.argument)) {
|
||||
context.report({ node, messageId: "object" });
|
||||
} else if (node.argument.type === "Identifier") {
|
||||
if (
|
||||
node.argument.name === "undefined" &&
|
||||
sourceCode.isGlobalReference(node.argument)
|
||||
) {
|
||||
context.report({ node, messageId: "undef" });
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user