This commit is contained in:
ahaas25
2025-02-23 23:35:15 -05:00
commit 5b64ef9207
1796 changed files with 186622 additions and 0 deletions
@@ -0,0 +1,43 @@
"use strict";
// NOTE: this file is isolated to be shared across legacy and flat configs
// it is exported via `./use-at-your-own-risk/eslint-recommended-raw`
// and it has types manually defined in `./eslint-recommended-raw.d.ts`
/**
* This is a compatibility ruleset that:
* - disables rules from eslint:recommended which are already handled by TypeScript.
* - enables rules that make sense due to TS's typechecking / transpilation.
*/
const config = (style) => ({
files: style === 'glob'
? // classic configs use glob syntax
['*.ts', '*.tsx', '*.mts', '*.cts']
: // flat configs use minimatch syntax
['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'],
rules: {
'constructor-super': 'off', // ts(2335) & ts(2377)
'getter-return': 'off', // ts(2378)
'no-class-assign': 'off', // ts(2629)
'no-const-assign': 'off', // ts(2588)
'no-dupe-args': 'off', // ts(2300)
'no-dupe-class-members': 'off', // ts(2393) & ts(2300)
'no-dupe-keys': 'off', // ts(1117)
'no-func-assign': 'off', // ts(2630)
'no-import-assign': 'off', // ts(2632) & ts(2540)
// TODO - remove this once we no longer support ESLint v8
'no-new-symbol': 'off', // ts(7009)
'no-new-native-nonconstructor': 'off', // ts(7009)
'no-obj-calls': 'off', // ts(2349)
'no-redeclare': 'off', // ts(2451)
'no-setter-return': 'off', // ts(2408)
'no-this-before-super': 'off', // ts(2376) & ts(17009)
'no-undef': 'off', // ts(2304) & ts(2552)
'no-unreachable': 'off', // ts(7027)
'no-unsafe-negation': 'off', // ts(2365) & ts(2322) & ts(2358)
'no-var': 'error', // ts transpiles let/const to var, so no need for vars any more
'prefer-const': 'error', // ts provides better types with const
'prefer-rest-params': 'error', // ts provides better types with rest args over arguments
'prefer-spread': 'error', // ts transpiles spread to apply, so no need for manual apply
},
});
module.exports = config;
//# sourceMappingURL=eslint-recommended-raw.js.map
@@ -0,0 +1 @@
{"version":3,"file":"eslint-recommended-raw.js","sourceRoot":"","sources":["../../src/configs/eslint-recommended-raw.ts"],"names":[],"mappings":";AAAA,0EAA0E;AAC1E,qEAAqE;AACrE,uEAAuE;AAEvE;;;;GAIG;AACH,MAAM,MAAM,GAAG,CACb,KAA2B,EAI3B,EAAE,CAAC,CAAC;IACJ,KAAK,EACH,KAAK,KAAK,MAAM;QACd,CAAC,CAAC,kCAAkC;YAClC,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;QACrC,CAAC,CAAC,oCAAoC;YACpC,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC;IACrD,KAAK,EAAE;QACL,mBAAmB,EAAE,KAAK,EAAE,sBAAsB;QAClD,eAAe,EAAE,KAAK,EAAE,WAAW;QACnC,iBAAiB,EAAE,KAAK,EAAE,WAAW;QACrC,iBAAiB,EAAE,KAAK,EAAE,WAAW;QACrC,cAAc,EAAE,KAAK,EAAE,WAAW;QAClC,uBAAuB,EAAE,KAAK,EAAE,sBAAsB;QACtD,cAAc,EAAE,KAAK,EAAE,WAAW;QAClC,gBAAgB,EAAE,KAAK,EAAE,WAAW;QACpC,kBAAkB,EAAE,KAAK,EAAE,sBAAsB;QACjD,yDAAyD;QACzD,eAAe,EAAE,KAAK,EAAE,WAAW;QACnC,8BAA8B,EAAE,KAAK,EAAE,WAAW;QAClD,cAAc,EAAE,KAAK,EAAE,WAAW;QAClC,cAAc,EAAE,KAAK,EAAE,WAAW;QAClC,kBAAkB,EAAE,KAAK,EAAE,WAAW;QACtC,sBAAsB,EAAE,KAAK,EAAE,uBAAuB;QACtD,UAAU,EAAE,KAAK,EAAE,sBAAsB;QACzC,gBAAgB,EAAE,KAAK,EAAE,WAAW;QACpC,oBAAoB,EAAE,KAAK,EAAE,iCAAiC;QAC9D,QAAQ,EAAE,OAAO,EAAE,+DAA+D;QAClF,cAAc,EAAE,OAAO,EAAE,sCAAsC;QAC/D,oBAAoB,EAAE,OAAO,EAAE,yDAAyD;QACxF,eAAe,EAAE,OAAO,EAAE,6DAA6D;KACxF;CACF,CAAC,CAAC;AAEH,iBAAS,MAAM,CAAC"}
@@ -0,0 +1,138 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const tsutils = __importStar(require("ts-api-utils"));
const util_1 = require("../util");
const getForStatementHeadLoc_1 = require("../util/getForStatementHeadLoc");
exports.default = (0, util_1.createRule)({
name: 'await-thenable',
meta: {
type: 'problem',
docs: {
description: 'Disallow awaiting a value that is not a Thenable',
recommended: 'recommended',
requiresTypeChecking: true,
},
hasSuggestions: true,
messages: {
await: 'Unexpected `await` of a non-Promise (non-"Thenable") value.',
awaitUsingOfNonAsyncDisposable: 'Unexpected `await using` of a value that is not async disposable.',
convertToOrdinaryFor: 'Convert to an ordinary `for...of` loop.',
forAwaitOfNonAsyncIterable: 'Unexpected `for await...of` of a value that is not async iterable.',
removeAwait: 'Remove unnecessary `await`.',
},
schema: [],
},
defaultOptions: [],
create(context) {
const services = (0, util_1.getParserServices)(context);
const checker = services.program.getTypeChecker();
return {
AwaitExpression(node) {
const type = services.getTypeAtLocation(node.argument);
if ((0, util_1.isTypeAnyType)(type) || (0, util_1.isTypeUnknownType)(type)) {
return;
}
const originalNode = services.esTreeNodeToTSNodeMap.get(node);
if (!tsutils.isThenableType(checker, originalNode.expression, type)) {
context.report({
node,
messageId: 'await',
suggest: [
{
messageId: 'removeAwait',
fix(fixer) {
const awaitKeyword = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isAwaitKeyword), util_1.NullThrowsReasons.MissingToken('await', 'await expression'));
return fixer.remove(awaitKeyword);
},
},
],
});
}
},
'ForOfStatement[await=true]'(node) {
const type = services.getTypeAtLocation(node.right);
if ((0, util_1.isTypeAnyType)(type)) {
return;
}
const hasAsyncIteratorSymbol = tsutils
.unionTypeParts(type)
.some(typePart => tsutils.getWellKnownSymbolPropertyOfType(typePart, 'asyncIterator', checker) != null);
if (!hasAsyncIteratorSymbol) {
context.report({
loc: (0, getForStatementHeadLoc_1.getForStatementHeadLoc)(context.sourceCode, node),
messageId: 'forAwaitOfNonAsyncIterable',
suggest: [
// Note that this suggestion causes broken code for sync iterables
// of promises, since the loop variable is not awaited.
{
messageId: 'convertToOrdinaryFor',
fix(fixer) {
const awaitToken = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isAwaitKeyword), util_1.NullThrowsReasons.MissingToken('await', 'for await loop'));
return fixer.remove(awaitToken);
},
},
],
});
}
},
'VariableDeclaration[kind="await using"]'(node) {
for (const declarator of node.declarations) {
const init = declarator.init;
if (init == null) {
continue;
}
const type = services.getTypeAtLocation(init);
if ((0, util_1.isTypeAnyType)(type)) {
continue;
}
const hasAsyncDisposeSymbol = tsutils
.unionTypeParts(type)
.some(typePart => tsutils.getWellKnownSymbolPropertyOfType(typePart, 'asyncDispose', checker) != null);
if (!hasAsyncDisposeSymbol) {
context.report({
node: init,
messageId: 'awaitUsingOfNonAsyncDisposable',
// let the user figure out what to do if there's
// await using a = b, c = d, e = f;
// it's rare and not worth the complexity to handle.
...(0, util_1.getFixOrSuggest)({
fixOrSuggest: node.declarations.length === 1 ? 'suggest' : 'none',
suggestion: {
messageId: 'removeAwait',
fix(fixer) {
const awaitToken = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isAwaitKeyword), util_1.NullThrowsReasons.MissingToken('await', 'await using'));
return fixer.remove(awaitToken);
},
},
}),
});
}
}
},
};
},
});
//# sourceMappingURL=await-thenable.js.map
@@ -0,0 +1 @@
{"version":3,"file":"await-thenable.js","sourceRoot":"","sources":["../../src/rules/await-thenable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const util_1 = require("../util");
exports.default = (0, util_1.createRule)({
name: 'consistent-type-definitions',
meta: {
type: 'suggestion',
docs: {
description: 'Enforce type definitions to consistently use either `interface` or `type`',
recommended: 'stylistic',
},
fixable: 'code',
messages: {
interfaceOverType: 'Use an `interface` instead of a `type`.',
typeOverInterface: 'Use a `type` instead of an `interface`.',
},
schema: [
{
type: 'string',
description: 'Which type definition syntax to prefer.',
enum: ['interface', 'type'],
},
],
},
defaultOptions: ['interface'],
create(context, [option]) {
/**
* Iterates from the highest parent to the currently traversed node
* to determine whether any node in tree is globally declared module declaration
*/
function isCurrentlyTraversedNodeWithinModuleDeclaration(node) {
return context.sourceCode
.getAncestors(node)
.some(node => node.type === utils_1.AST_NODE_TYPES.TSModuleDeclaration &&
node.declare &&
node.kind === 'global');
}
return {
...(option === 'interface' && {
"TSTypeAliasDeclaration[typeAnnotation.type='TSTypeLiteral']"(node) {
context.report({
node: node.id,
messageId: 'interfaceOverType',
fix(fixer) {
const typeToken = (0, util_1.nullThrows)(context.sourceCode.getTokenBefore(node.id, token => token.value === 'type'), util_1.NullThrowsReasons.MissingToken('type keyword', 'type alias'));
const equalsToken = (0, util_1.nullThrows)(context.sourceCode.getTokenBefore(node.typeAnnotation, token => token.value === '='), util_1.NullThrowsReasons.MissingToken('=', 'type alias'));
const beforeEqualsToken = (0, util_1.nullThrows)(context.sourceCode.getTokenBefore(equalsToken, {
includeComments: true,
}), util_1.NullThrowsReasons.MissingToken('before =', 'type alias'));
return [
// replace 'type' with 'interface'.
fixer.replaceText(typeToken, 'interface'),
// delete from the = to the { of the type, and put a space to be pretty.
fixer.replaceTextRange([beforeEqualsToken.range[1], node.typeAnnotation.range[0]], ' '),
// remove from the closing } through the end of the statement.
fixer.removeRange([
node.typeAnnotation.range[1],
node.range[1],
]),
];
},
});
},
}),
...(option === 'type' && {
TSInterfaceDeclaration(node) {
const fix = isCurrentlyTraversedNodeWithinModuleDeclaration(node)
? null
: (fixer) => {
const typeNode = node.typeParameters ?? node.id;
const fixes = [];
const firstToken = context.sourceCode.getTokenBefore(node.id);
if (firstToken) {
fixes.push(fixer.replaceText(firstToken, 'type'));
fixes.push(fixer.replaceTextRange([typeNode.range[1], node.body.range[0]], ' = '));
}
node.extends.forEach(heritage => {
const typeIdentifier = context.sourceCode.getText(heritage);
fixes.push(fixer.insertTextAfter(node.body, ` & ${typeIdentifier}`));
});
if (node.parent.type === utils_1.AST_NODE_TYPES.ExportDefaultDeclaration) {
fixes.push(fixer.removeRange([node.parent.range[0], node.range[0]]), fixer.insertTextAfter(node.body, `\nexport default ${node.id.name}`));
}
return fixes;
};
context.report({
node: node.id,
messageId: 'typeOverInterface',
/**
* remove automatically fix when the interface is within a declare global
* @see {@link https://github.com/typescript-eslint/typescript-eslint/issues/2707}
*/
fix,
});
},
}),
};
},
});
//# sourceMappingURL=consistent-type-definitions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"consistent-type-definitions.js","sourceRoot":"","sources":["../../src/rules/consistent-type-definitions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,344 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const tsutils = __importStar(require("ts-api-utils"));
const ts = __importStar(require("typescript"));
const util_1 = require("../util");
const getParentFunctionNode_1 = require("../util/getParentFunctionNode");
exports.default = (0, util_1.createRule)({
name: 'no-confusing-void-expression',
meta: {
type: 'problem',
docs: {
description: 'Require expressions of type void to appear in statement position',
recommended: 'strict',
requiresTypeChecking: true,
},
fixable: 'code',
hasSuggestions: true,
messages: {
invalidVoidExpr: 'Placing a void expression inside another expression is forbidden. ' +
'Move it to its own statement instead.',
invalidVoidExprArrow: 'Returning a void expression from an arrow function shorthand is forbidden. ' +
'Please add braces to the arrow function.',
invalidVoidExprArrowWrapVoid: 'Void expressions returned from an arrow function shorthand ' +
'must be marked explicitly with the `void` operator.',
invalidVoidExprReturn: 'Returning a void expression from a function is forbidden. ' +
'Please move it before the `return` statement.',
invalidVoidExprReturnLast: 'Returning a void expression from a function is forbidden. ' +
'Please remove the `return` statement.',
invalidVoidExprReturnWrapVoid: 'Void expressions returned from a function ' +
'must be marked explicitly with the `void` operator.',
invalidVoidExprWrapVoid: 'Void expressions used inside another expression ' +
'must be moved to its own statement ' +
'or marked explicitly with the `void` operator.',
voidExprWrapVoid: 'Mark with an explicit `void` operator.',
},
schema: [
{
type: 'object',
additionalProperties: false,
properties: {
ignoreArrowShorthand: {
type: 'boolean',
description: 'Whether to ignore "shorthand" `() =>` arrow functions: those without `{ ... }` braces.',
},
ignoreVoidOperator: {
type: 'boolean',
description: 'Whether to ignore returns that start with the `void` operator.',
},
ignoreVoidReturningFunctions: {
type: 'boolean',
description: 'Whether to ignore returns from functions with explicit `void` return types and functions with contextual `void` return types.',
},
},
},
],
},
defaultOptions: [{ ignoreArrowShorthand: false, ignoreVoidOperator: false }],
create(context, [options]) {
const services = (0, util_1.getParserServices)(context);
const checker = services.program.getTypeChecker();
return {
'AwaitExpression, CallExpression, TaggedTemplateExpression'(node) {
const type = (0, util_1.getConstrainedTypeAtLocation)(services, node);
if (!tsutils.isTypeFlagSet(type, ts.TypeFlags.VoidLike)) {
// not a void expression
return;
}
const invalidAncestor = findInvalidAncestor(node);
if (invalidAncestor == null) {
// void expression is in valid position
return;
}
const wrapVoidFix = (fixer) => {
const nodeText = context.sourceCode.getText(node);
const newNodeText = `void ${nodeText}`;
return fixer.replaceText(node, newNodeText);
};
if (invalidAncestor.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression) {
// handle arrow function shorthand
if (options.ignoreVoidReturningFunctions) {
const returnsVoid = isVoidReturningFunctionNode(invalidAncestor);
if (returnsVoid) {
return;
}
}
if (options.ignoreVoidOperator) {
// handle wrapping with `void`
return context.report({
node,
messageId: 'invalidVoidExprArrowWrapVoid',
fix: wrapVoidFix,
});
}
// handle wrapping with braces
const arrowFunction = invalidAncestor;
return context.report({
node,
messageId: 'invalidVoidExprArrow',
fix(fixer) {
if (!canFix(arrowFunction)) {
return null;
}
const arrowBody = arrowFunction.body;
const arrowBodyText = context.sourceCode.getText(arrowBody);
const newArrowBodyText = `{ ${arrowBodyText}; }`;
if ((0, util_1.isParenthesized)(arrowBody, context.sourceCode)) {
const bodyOpeningParen = (0, util_1.nullThrows)(context.sourceCode.getTokenBefore(arrowBody, util_1.isOpeningParenToken), util_1.NullThrowsReasons.MissingToken('opening parenthesis', 'arrow body'));
const bodyClosingParen = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(arrowBody, util_1.isClosingParenToken), util_1.NullThrowsReasons.MissingToken('closing parenthesis', 'arrow body'));
return fixer.replaceTextRange([bodyOpeningParen.range[0], bodyClosingParen.range[1]], newArrowBodyText);
}
return fixer.replaceText(arrowBody, newArrowBodyText);
},
});
}
if (invalidAncestor.type === utils_1.AST_NODE_TYPES.ReturnStatement) {
// handle return statement
if (options.ignoreVoidReturningFunctions) {
const functionNode = (0, getParentFunctionNode_1.getParentFunctionNode)(invalidAncestor);
if (functionNode) {
const returnsVoid = isVoidReturningFunctionNode(functionNode);
if (returnsVoid) {
return;
}
}
}
if (options.ignoreVoidOperator) {
// handle wrapping with `void`
return context.report({
node,
messageId: 'invalidVoidExprReturnWrapVoid',
fix: wrapVoidFix,
});
}
if (isFinalReturn(invalidAncestor)) {
// remove the `return` keyword
return context.report({
node,
messageId: 'invalidVoidExprReturnLast',
fix(fixer) {
if (!canFix(invalidAncestor)) {
return null;
}
const returnValue = invalidAncestor.argument;
const returnValueText = context.sourceCode.getText(returnValue);
let newReturnStmtText = `${returnValueText};`;
if (isPreventingASI(returnValue)) {
// put a semicolon at the beginning of the line
newReturnStmtText = `;${newReturnStmtText}`;
}
return fixer.replaceText(invalidAncestor, newReturnStmtText);
},
});
}
// move before the `return` keyword
return context.report({
node,
messageId: 'invalidVoidExprReturn',
fix(fixer) {
const returnValue = invalidAncestor.argument;
const returnValueText = context.sourceCode.getText(returnValue);
let newReturnStmtText = `${returnValueText}; return;`;
if (isPreventingASI(returnValue)) {
// put a semicolon at the beginning of the line
newReturnStmtText = `;${newReturnStmtText}`;
}
if (invalidAncestor.parent.type !== utils_1.AST_NODE_TYPES.BlockStatement) {
// e.g. `if (cond) return console.error();`
// add braces if not inside a block
newReturnStmtText = `{ ${newReturnStmtText} }`;
}
return fixer.replaceText(invalidAncestor, newReturnStmtText);
},
});
}
// handle generic case
if (options.ignoreVoidOperator) {
// this would be reported by this rule btw. such irony
return context.report({
node,
messageId: 'invalidVoidExprWrapVoid',
suggest: [{ messageId: 'voidExprWrapVoid', fix: wrapVoidFix }],
});
}
context.report({
node,
messageId: 'invalidVoidExpr',
});
},
};
/**
* Inspects the void expression's ancestors and finds closest invalid one.
* By default anything other than an ExpressionStatement is invalid.
* Parent expressions which can be used for their short-circuiting behavior
* are ignored and their parents are checked instead.
* @param node The void expression node to check.
* @returns Invalid ancestor node if it was found. `null` otherwise.
*/
function findInvalidAncestor(node) {
const parent = (0, util_1.nullThrows)(node.parent, util_1.NullThrowsReasons.MissingParent);
if (parent.type === utils_1.AST_NODE_TYPES.SequenceExpression &&
node !== parent.expressions[parent.expressions.length - 1]) {
return null;
}
if (parent.type === utils_1.AST_NODE_TYPES.ExpressionStatement) {
// e.g. `{ console.log("foo"); }`
// this is always valid
return null;
}
if (parent.type === utils_1.AST_NODE_TYPES.LogicalExpression &&
parent.right === node) {
// e.g. `x && console.log(x)`
// this is valid only if the next ancestor is valid
return findInvalidAncestor(parent);
}
if (parent.type === utils_1.AST_NODE_TYPES.ConditionalExpression &&
(parent.consequent === node || parent.alternate === node)) {
// e.g. `cond ? console.log(true) : console.log(false)`
// this is valid only if the next ancestor is valid
return findInvalidAncestor(parent);
}
if (parent.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression &&
// e.g. `() => console.log("foo")`
// this is valid with an appropriate option
options.ignoreArrowShorthand) {
return null;
}
if (parent.type === utils_1.AST_NODE_TYPES.UnaryExpression &&
parent.operator === 'void' &&
// e.g. `void console.log("foo")`
// this is valid with an appropriate option
options.ignoreVoidOperator) {
return null;
}
if (parent.type === utils_1.AST_NODE_TYPES.ChainExpression) {
// e.g. `console?.log('foo')`
return findInvalidAncestor(parent);
}
// Any other parent is invalid.
// We can assume a return statement will have an argument.
return parent;
}
/** Checks whether the return statement is the last statement in a function body. */
function isFinalReturn(node) {
// the parent must be a block
const block = (0, util_1.nullThrows)(node.parent, util_1.NullThrowsReasons.MissingParent);
if (block.type !== utils_1.AST_NODE_TYPES.BlockStatement) {
// e.g. `if (cond) return;` (not in a block)
return false;
}
// the block's parent must be a function
const blockParent = (0, util_1.nullThrows)(block.parent, util_1.NullThrowsReasons.MissingParent);
if (![
utils_1.AST_NODE_TYPES.ArrowFunctionExpression,
utils_1.AST_NODE_TYPES.FunctionDeclaration,
utils_1.AST_NODE_TYPES.FunctionExpression,
].includes(blockParent.type)) {
// e.g. `if (cond) { return; }`
// not in a top-level function block
return false;
}
// must be the last child of the block
if (block.body.indexOf(node) < block.body.length - 1) {
// not the last statement in the block
return false;
}
return true;
}
/**
* Checks whether the given node, if placed on its own line,
* would prevent automatic semicolon insertion on the line before.
*
* This happens if the line begins with `(`, `[` or `` ` ``
*/
function isPreventingASI(node) {
const startToken = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node), util_1.NullThrowsReasons.MissingToken('first token', node.type));
return ['(', '[', '`'].includes(startToken.value);
}
function canFix(node) {
const targetNode = node.type === utils_1.AST_NODE_TYPES.ReturnStatement
? node.argument
: node.body;
const type = (0, util_1.getConstrainedTypeAtLocation)(services, targetNode);
return tsutils.isTypeFlagSet(type, ts.TypeFlags.VoidLike);
}
function isFunctionReturnTypeIncludesVoid(functionType) {
const callSignatures = tsutils.getCallSignaturesOfType(functionType);
return callSignatures.some(signature => {
const returnType = signature.getReturnType();
return tsutils
.unionTypeParts(returnType)
.some(tsutils.isIntrinsicVoidType);
});
}
function isVoidReturningFunctionNode(functionNode) {
// Game plan:
// - If the function node has a type annotation, check if it includes `void`.
// - If it does then the function is safe to return `void` expressions in.
// - Otherwise, check if the function is a function-expression or an arrow-function.
// - If it is, get its contextual type and bail if we cannot.
// - Return based on whether the contextual type includes `void` or not
const functionTSNode = services.esTreeNodeToTSNodeMap.get(functionNode);
if (functionTSNode.type) {
const returnType = checker.getTypeFromTypeNode(functionTSNode.type);
return tsutils
.unionTypeParts(returnType)
.some(tsutils.isIntrinsicVoidType);
}
if (ts.isExpression(functionTSNode)) {
const functionType = checker.getContextualType(functionTSNode);
if (functionType) {
return tsutils
.unionTypeParts(functionType)
.some(isFunctionReturnTypeIncludesVoid);
}
}
return false;
}
},
});
//# sourceMappingURL=no-confusing-void-expression.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,277 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const tsutils = __importStar(require("ts-api-utils"));
const ts = __importStar(require("typescript"));
const util_1 = require("../util");
exports.default = (0, util_1.createRule)({
name: 'no-deprecated',
meta: {
type: 'problem',
docs: {
description: 'Disallow using code marked as `@deprecated`',
recommended: 'strict',
requiresTypeChecking: true,
},
messages: {
deprecated: `\`{{name}}\` is deprecated.`,
deprecatedWithReason: `\`{{name}}\` is deprecated. {{reason}}`,
},
schema: [],
},
defaultOptions: [],
create(context) {
const { jsDocParsingMode } = context.parserOptions;
if (jsDocParsingMode === 'none' || jsDocParsingMode === 'type-info') {
throw new Error(`Cannot be used with jsDocParsingMode: '${jsDocParsingMode}'.`);
}
const services = (0, util_1.getParserServices)(context);
const checker = services.program.getTypeChecker();
// Deprecated jsdoc tags can be added on some symbol alias, e.g.
//
// export { /** @deprecated */ foo }
//
// When we import foo, its symbol is an alias of the exported foo (the one
// with the deprecated tag), which is itself an alias of the original foo.
// Therefore, we carefully go through the chain of aliases and check each
// immediate alias for deprecated tags
function searchForDeprecationInAliasesChain(symbol, checkDeprecationsOfAliasedSymbol) {
if (!symbol || !tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias)) {
return checkDeprecationsOfAliasedSymbol
? getJsDocDeprecation(symbol)
: undefined;
}
const targetSymbol = checker.getAliasedSymbol(symbol);
while (tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias)) {
const reason = getJsDocDeprecation(symbol);
if (reason !== undefined) {
return reason;
}
const immediateAliasedSymbol = symbol.getDeclarations() && checker.getImmediateAliasedSymbol(symbol);
if (!immediateAliasedSymbol) {
break;
}
symbol = immediateAliasedSymbol;
if (checkDeprecationsOfAliasedSymbol && symbol === targetSymbol) {
return getJsDocDeprecation(symbol);
}
}
return undefined;
}
function isDeclaration(node) {
const { parent } = node;
switch (parent.type) {
case utils_1.AST_NODE_TYPES.ArrayPattern:
return parent.elements.includes(node);
case utils_1.AST_NODE_TYPES.ClassExpression:
case utils_1.AST_NODE_TYPES.ClassDeclaration:
case utils_1.AST_NODE_TYPES.VariableDeclarator:
case utils_1.AST_NODE_TYPES.TSEnumMember:
return parent.id === node;
case utils_1.AST_NODE_TYPES.MethodDefinition:
case utils_1.AST_NODE_TYPES.PropertyDefinition:
return parent.key === node;
case utils_1.AST_NODE_TYPES.Property:
// foo in "const { foo } = bar" will be processed twice, as parent.key
// and parent.value. The second is treated as a declaration.
return ((parent.shorthand && parent.value === node) ||
parent.parent.type === utils_1.AST_NODE_TYPES.ObjectExpression);
case utils_1.AST_NODE_TYPES.AssignmentPattern:
// foo in "const { foo = "" } = bar" will be processed twice, as parent.parent.key
// and parent.left. The second is treated as a declaration.
return parent.left === node;
case utils_1.AST_NODE_TYPES.ArrowFunctionExpression:
case utils_1.AST_NODE_TYPES.FunctionDeclaration:
case utils_1.AST_NODE_TYPES.FunctionExpression:
case utils_1.AST_NODE_TYPES.TSDeclareFunction:
case utils_1.AST_NODE_TYPES.TSEmptyBodyFunctionExpression:
case utils_1.AST_NODE_TYPES.TSEnumDeclaration:
case utils_1.AST_NODE_TYPES.TSInterfaceDeclaration:
case utils_1.AST_NODE_TYPES.TSMethodSignature:
case utils_1.AST_NODE_TYPES.TSModuleDeclaration:
case utils_1.AST_NODE_TYPES.TSParameterProperty:
case utils_1.AST_NODE_TYPES.TSPropertySignature:
case utils_1.AST_NODE_TYPES.TSTypeAliasDeclaration:
case utils_1.AST_NODE_TYPES.TSTypeParameter:
return true;
default:
return false;
}
}
function isInsideExportOrImport(node) {
let current = node;
while (true) {
switch (current.type) {
case utils_1.AST_NODE_TYPES.ExportAllDeclaration:
case utils_1.AST_NODE_TYPES.ExportDefaultDeclaration:
case utils_1.AST_NODE_TYPES.ExportNamedDeclaration:
case utils_1.AST_NODE_TYPES.ImportDeclaration:
return true;
case utils_1.AST_NODE_TYPES.ArrowFunctionExpression:
case utils_1.AST_NODE_TYPES.BlockStatement:
case utils_1.AST_NODE_TYPES.ClassDeclaration:
case utils_1.AST_NODE_TYPES.TSInterfaceDeclaration:
case utils_1.AST_NODE_TYPES.FunctionDeclaration:
case utils_1.AST_NODE_TYPES.FunctionExpression:
case utils_1.AST_NODE_TYPES.Program:
case utils_1.AST_NODE_TYPES.TSUnionType:
case utils_1.AST_NODE_TYPES.VariableDeclarator:
return false;
default:
current = current.parent;
}
}
}
function getJsDocDeprecation(symbol) {
let jsDocTags;
try {
jsDocTags = symbol?.getJsDocTags(checker);
}
catch {
// workaround for https://github.com/microsoft/TypeScript/issues/60024
return;
}
const tag = jsDocTags?.find(tag => tag.name === 'deprecated');
if (!tag) {
return undefined;
}
const displayParts = tag.text;
return displayParts ? ts.displayPartsToString(displayParts) : '';
}
function isNodeCalleeOfParent(node) {
switch (node.parent?.type) {
case utils_1.AST_NODE_TYPES.NewExpression:
case utils_1.AST_NODE_TYPES.CallExpression:
return node.parent.callee === node;
case utils_1.AST_NODE_TYPES.TaggedTemplateExpression:
return node.parent.tag === node;
case utils_1.AST_NODE_TYPES.JSXOpeningElement:
return node.parent.name === node;
default:
return false;
}
}
function getCallLikeNode(node) {
let callee = node;
while (callee.parent?.type === utils_1.AST_NODE_TYPES.MemberExpression &&
callee.parent.property === callee) {
callee = callee.parent;
}
return isNodeCalleeOfParent(callee) ? callee : undefined;
}
function getCallLikeDeprecation(node) {
const tsNode = services.esTreeNodeToTSNodeMap.get(node.parent);
// If the node is a direct function call, we look for its signature.
const signature = (0, util_1.nullThrows)(checker.getResolvedSignature(tsNode), 'Expected call like node to have signature');
const symbol = services.getSymbolAtLocation(node);
const aliasedSymbol = symbol !== undefined &&
tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias)
? checker.getAliasedSymbol(symbol)
: symbol;
const symbolDeclarationKind = aliasedSymbol?.declarations?.[0].kind;
// Properties with function-like types have "deprecated" jsdoc
// on their symbols, not on their signatures:
//
// interface Props {
// /** @deprecated */
// property: () => 'foo'
// ^symbol^ ^signature^
// }
if (symbolDeclarationKind !== ts.SyntaxKind.MethodDeclaration &&
symbolDeclarationKind !== ts.SyntaxKind.FunctionDeclaration &&
symbolDeclarationKind !== ts.SyntaxKind.MethodSignature) {
return (searchForDeprecationInAliasesChain(symbol, true) ??
getJsDocDeprecation(signature) ??
getJsDocDeprecation(aliasedSymbol));
}
return (searchForDeprecationInAliasesChain(symbol,
// Here we're working with a function declaration or method.
// Both can have 1 or more overloads, each overload creates one
// ts.Declaration which is placed in symbol.declarations.
//
// Imagine the following code:
//
// function foo(): void
// /** @deprecated Some Reason */
// function foo(arg: string): void
// function foo(arg?: string): void {}
//
// foo() // <- foo is our symbol
//
// If we call getJsDocDeprecation(checker.getAliasedSymbol(symbol)),
// we get 'Some Reason', but after all, we are calling foo with
// a signature that is not deprecated!
// It works this way because symbol.getJsDocTags returns tags from
// all symbol declarations combined into one array. And AFAIK there is
// no publicly exported TS function that can tell us if a particular
// declaration is deprecated or not.
//
// So, in case of function and method declarations, we don't check original
// aliased symbol, but rely on the getJsDocDeprecation(signature) call below.
false) ?? getJsDocDeprecation(signature));
}
function getDeprecationReason(node) {
const callLikeNode = getCallLikeNode(node);
if (callLikeNode) {
return getCallLikeDeprecation(callLikeNode);
}
if (node.parent.type === utils_1.AST_NODE_TYPES.Property) {
return getJsDocDeprecation(services.getTypeAtLocation(node.parent.parent).getProperty(node.name));
}
return searchForDeprecationInAliasesChain(services.getSymbolAtLocation(node), true);
}
function checkIdentifier(node) {
if (isDeclaration(node) || isInsideExportOrImport(node)) {
return;
}
const reason = getDeprecationReason(node);
if (reason === undefined) {
return;
}
context.report({
...(reason
? {
messageId: 'deprecatedWithReason',
data: { name: node.name, reason },
}
: {
messageId: 'deprecated',
data: { name: node.name },
}),
node,
});
}
return {
Identifier: checkIdentifier,
JSXIdentifier(node) {
if (node.parent.type !== utils_1.AST_NODE_TYPES.JSXClosingElement) {
checkIdentifier(node);
}
},
};
},
});
//# sourceMappingURL=no-deprecated.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,743 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const tsutils = __importStar(require("ts-api-utils"));
const ts = __importStar(require("typescript"));
const util_1 = require("../util");
function parseChecksVoidReturn(checksVoidReturn) {
switch (checksVoidReturn) {
case false:
return false;
case true:
case undefined:
return {
arguments: true,
attributes: true,
inheritedMethods: true,
properties: true,
returns: true,
variables: true,
};
default:
return {
arguments: checksVoidReturn.arguments ?? true,
attributes: checksVoidReturn.attributes ?? true,
inheritedMethods: checksVoidReturn.inheritedMethods ?? true,
properties: checksVoidReturn.properties ?? true,
returns: checksVoidReturn.returns ?? true,
variables: checksVoidReturn.variables ?? true,
};
}
}
exports.default = (0, util_1.createRule)({
name: 'no-misused-promises',
meta: {
type: 'problem',
docs: {
description: 'Disallow Promises in places not designed to handle them',
recommended: 'recommended',
requiresTypeChecking: true,
},
messages: {
conditional: 'Expected non-Promise value in a boolean conditional.',
predicate: 'Expected a non-Promise value to be returned.',
spread: 'Expected a non-Promise value to be spreaded in an object.',
voidReturnArgument: 'Promise returned in function argument where a void return was expected.',
voidReturnAttribute: 'Promise-returning function provided to attribute where a void return was expected.',
voidReturnInheritedMethod: "Promise-returning method provided where a void return was expected by extended/implemented type '{{ heritageTypeName }}'.",
voidReturnProperty: 'Promise-returning function provided to property where a void return was expected.',
voidReturnReturnValue: 'Promise-returning function provided to return value where a void return was expected.',
voidReturnVariable: 'Promise-returning function provided to variable where a void return was expected.',
},
schema: [
{
type: 'object',
additionalProperties: false,
properties: {
checksConditionals: {
type: 'boolean',
description: 'Whether to warn when a Promise is provided to conditional statements.',
},
checksSpreads: {
type: 'boolean',
description: 'Whether to warn when `...` spreading a `Promise`.',
},
checksVoidReturn: {
description: 'Whether to warn when a Promise is returned from a function typed as returning `void`.',
oneOf: [
{
type: 'boolean',
description: 'Whether to disable checking all asynchronous functions.',
},
{
type: 'object',
additionalProperties: false,
description: 'Which forms of functions may have checking disabled.',
properties: {
arguments: {
type: 'boolean',
description: 'Disables checking an asynchronous function passed as argument where the parameter type expects a function that returns `void`.',
},
attributes: {
type: 'boolean',
description: 'Disables checking an asynchronous function passed as a JSX attribute expected to be a function that returns `void`.',
},
inheritedMethods: {
type: 'boolean',
description: 'Disables checking an asynchronous method in a type that extends or implements another type expecting that method to return `void`.',
},
properties: {
type: 'boolean',
description: 'Disables checking an asynchronous function passed as an object property expected to be a function that returns `void`.',
},
returns: {
type: 'boolean',
description: 'Disables checking an asynchronous function returned in a function whose return type is a function that returns `void`.',
},
variables: {
type: 'boolean',
description: 'Disables checking an asynchronous function used as a variable whose return type is a function that returns `void`.',
},
},
},
],
},
},
},
],
},
defaultOptions: [
{
checksConditionals: true,
checksSpreads: true,
checksVoidReturn: true,
},
],
create(context, [{ checksConditionals, checksSpreads, checksVoidReturn }]) {
const services = (0, util_1.getParserServices)(context);
const checker = services.program.getTypeChecker();
const checkedNodes = new Set();
const conditionalChecks = {
'CallExpression > MemberExpression': checkArrayPredicates,
ConditionalExpression: checkTestConditional,
DoWhileStatement: checkTestConditional,
ForStatement: checkTestConditional,
IfStatement: checkTestConditional,
LogicalExpression: checkConditional,
'UnaryExpression[operator="!"]'(node) {
checkConditional(node.argument, true);
},
WhileStatement: checkTestConditional,
};
checksVoidReturn = parseChecksVoidReturn(checksVoidReturn);
const voidReturnChecks = checksVoidReturn
? {
...(checksVoidReturn.arguments && {
CallExpression: checkArguments,
NewExpression: checkArguments,
}),
...(checksVoidReturn.attributes && {
JSXAttribute: checkJSXAttribute,
}),
...(checksVoidReturn.inheritedMethods && {
ClassDeclaration: checkClassLikeOrInterfaceNode,
ClassExpression: checkClassLikeOrInterfaceNode,
TSInterfaceDeclaration: checkClassLikeOrInterfaceNode,
}),
...(checksVoidReturn.properties && {
Property: checkProperty,
}),
...(checksVoidReturn.returns && {
ReturnStatement: checkReturnStatement,
}),
...(checksVoidReturn.variables && {
AssignmentExpression: checkAssignment,
VariableDeclarator: checkVariableDeclaration,
}),
}
: {};
const spreadChecks = {
SpreadElement: checkSpread,
};
/**
* A syntactic check to see if an annotated type is maybe a function type.
* This is a perf optimization to help avoid requesting types where possible
*/
function isPossiblyFunctionType(node) {
switch (node.typeAnnotation.type) {
case utils_1.AST_NODE_TYPES.TSConditionalType:
case utils_1.AST_NODE_TYPES.TSConstructorType:
case utils_1.AST_NODE_TYPES.TSFunctionType:
case utils_1.AST_NODE_TYPES.TSImportType:
case utils_1.AST_NODE_TYPES.TSIndexedAccessType:
case utils_1.AST_NODE_TYPES.TSInferType:
case utils_1.AST_NODE_TYPES.TSIntersectionType:
case utils_1.AST_NODE_TYPES.TSQualifiedName:
case utils_1.AST_NODE_TYPES.TSThisType:
case utils_1.AST_NODE_TYPES.TSTypeOperator:
case utils_1.AST_NODE_TYPES.TSTypeQuery:
case utils_1.AST_NODE_TYPES.TSTypeReference:
case utils_1.AST_NODE_TYPES.TSUnionType:
return true;
case utils_1.AST_NODE_TYPES.TSTypeLiteral:
return node.typeAnnotation.members.some(member => member.type === utils_1.AST_NODE_TYPES.TSCallSignatureDeclaration ||
member.type === utils_1.AST_NODE_TYPES.TSConstructSignatureDeclaration);
case utils_1.AST_NODE_TYPES.TSAbstractKeyword:
case utils_1.AST_NODE_TYPES.TSAnyKeyword:
case utils_1.AST_NODE_TYPES.TSArrayType:
case utils_1.AST_NODE_TYPES.TSAsyncKeyword:
case utils_1.AST_NODE_TYPES.TSBigIntKeyword:
case utils_1.AST_NODE_TYPES.TSBooleanKeyword:
case utils_1.AST_NODE_TYPES.TSDeclareKeyword:
case utils_1.AST_NODE_TYPES.TSExportKeyword:
case utils_1.AST_NODE_TYPES.TSIntrinsicKeyword:
case utils_1.AST_NODE_TYPES.TSLiteralType:
case utils_1.AST_NODE_TYPES.TSMappedType:
case utils_1.AST_NODE_TYPES.TSNamedTupleMember:
case utils_1.AST_NODE_TYPES.TSNeverKeyword:
case utils_1.AST_NODE_TYPES.TSNullKeyword:
case utils_1.AST_NODE_TYPES.TSNumberKeyword:
case utils_1.AST_NODE_TYPES.TSObjectKeyword:
case utils_1.AST_NODE_TYPES.TSOptionalType:
case utils_1.AST_NODE_TYPES.TSPrivateKeyword:
case utils_1.AST_NODE_TYPES.TSProtectedKeyword:
case utils_1.AST_NODE_TYPES.TSPublicKeyword:
case utils_1.AST_NODE_TYPES.TSReadonlyKeyword:
case utils_1.AST_NODE_TYPES.TSRestType:
case utils_1.AST_NODE_TYPES.TSStaticKeyword:
case utils_1.AST_NODE_TYPES.TSStringKeyword:
case utils_1.AST_NODE_TYPES.TSSymbolKeyword:
case utils_1.AST_NODE_TYPES.TSTemplateLiteralType:
case utils_1.AST_NODE_TYPES.TSTupleType:
case utils_1.AST_NODE_TYPES.TSTypePredicate:
case utils_1.AST_NODE_TYPES.TSUndefinedKeyword:
case utils_1.AST_NODE_TYPES.TSUnknownKeyword:
case utils_1.AST_NODE_TYPES.TSVoidKeyword:
return false;
}
}
function checkTestConditional(node) {
if (node.test) {
checkConditional(node.test, true);
}
}
/**
* This function analyzes the type of a node and checks if it is a Promise in a boolean conditional.
* It uses recursion when checking nested logical operators.
* @param node The AST node to check.
* @param isTestExpr Whether the node is a descendant of a test expression.
*/
function checkConditional(node, isTestExpr = false) {
// prevent checking the same node multiple times
if (checkedNodes.has(node)) {
return;
}
checkedNodes.add(node);
if (node.type === utils_1.AST_NODE_TYPES.LogicalExpression) {
// ignore the left operand for nullish coalescing expressions not in a context of a test expression
if (node.operator !== '??' || isTestExpr) {
checkConditional(node.left, isTestExpr);
}
// we ignore the right operand when not in a context of a test expression
if (isTestExpr) {
checkConditional(node.right, isTestExpr);
}
return;
}
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
if (isAlwaysThenable(checker, tsNode)) {
context.report({
node,
messageId: 'conditional',
});
}
}
function checkArrayPredicates(node) {
const parent = node.parent;
if (parent.type === utils_1.AST_NODE_TYPES.CallExpression) {
const callback = parent.arguments.at(0);
if (callback &&
(0, util_1.isArrayMethodCallWithPredicate)(context, services, parent)) {
const type = services.esTreeNodeToTSNodeMap.get(callback);
if (returnsThenable(checker, type)) {
context.report({
node: callback,
messageId: 'predicate',
});
}
}
}
}
function checkArguments(node) {
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
const voidArgs = voidFunctionArguments(checker, tsNode);
if (voidArgs.size === 0) {
return;
}
for (const [index, argument] of node.arguments.entries()) {
if (!voidArgs.has(index)) {
continue;
}
const tsNode = services.esTreeNodeToTSNodeMap.get(argument);
if (returnsThenable(checker, tsNode)) {
context.report({
node: argument,
messageId: 'voidReturnArgument',
});
}
}
}
function checkAssignment(node) {
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
const varType = services.getTypeAtLocation(node.left);
if (!isVoidReturningFunctionType(checker, tsNode.left, varType)) {
return;
}
if (returnsThenable(checker, tsNode.right)) {
context.report({
node: node.right,
messageId: 'voidReturnVariable',
});
}
}
function checkVariableDeclaration(node) {
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
if (tsNode.initializer === undefined ||
node.init == null ||
node.id.typeAnnotation == null) {
return;
}
// syntactically ignore some known-good cases to avoid touching type info
if (!isPossiblyFunctionType(node.id.typeAnnotation)) {
return;
}
const varType = services.getTypeAtLocation(node.id);
if (!isVoidReturningFunctionType(checker, tsNode.initializer, varType)) {
return;
}
if (returnsThenable(checker, tsNode.initializer)) {
context.report({
node: node.init,
messageId: 'voidReturnVariable',
});
}
}
function checkProperty(node) {
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
if (ts.isPropertyAssignment(tsNode)) {
const contextualType = checker.getContextualType(tsNode.initializer);
if (contextualType !== undefined &&
isVoidReturningFunctionType(checker, tsNode.initializer, contextualType) &&
returnsThenable(checker, tsNode.initializer)) {
if ((0, util_1.isFunction)(node.value)) {
const functionNode = node.value;
if (functionNode.returnType) {
context.report({
node: functionNode.returnType.typeAnnotation,
messageId: 'voidReturnProperty',
});
}
else {
context.report({
loc: (0, util_1.getFunctionHeadLoc)(functionNode, context.sourceCode),
messageId: 'voidReturnProperty',
});
}
}
else {
context.report({
node: node.value,
messageId: 'voidReturnProperty',
});
}
}
}
else if (ts.isShorthandPropertyAssignment(tsNode)) {
const contextualType = checker.getContextualType(tsNode.name);
if (contextualType !== undefined &&
isVoidReturningFunctionType(checker, tsNode.name, contextualType) &&
returnsThenable(checker, tsNode.name)) {
context.report({
node: node.value,
messageId: 'voidReturnProperty',
});
}
}
else if (ts.isMethodDeclaration(tsNode)) {
if (ts.isComputedPropertyName(tsNode.name)) {
return;
}
const obj = tsNode.parent;
// Below condition isn't satisfied unless something goes wrong,
// but is needed for type checking.
// 'node' does not include class method declaration so 'obj' is
// always an object literal expression, but after converting 'node'
// to TypeScript AST, its type includes MethodDeclaration which
// does include the case of class method declaration.
if (!ts.isObjectLiteralExpression(obj)) {
return;
}
if (!returnsThenable(checker, tsNode)) {
return;
}
const objType = checker.getContextualType(obj);
if (objType === undefined) {
return;
}
const propertySymbol = checker.getPropertyOfType(objType, tsNode.name.text);
if (propertySymbol === undefined) {
return;
}
const contextualType = checker.getTypeOfSymbolAtLocation(propertySymbol, tsNode.name);
if (isVoidReturningFunctionType(checker, tsNode.name, contextualType)) {
const functionNode = node.value;
if (functionNode.returnType) {
context.report({
node: functionNode.returnType.typeAnnotation,
messageId: 'voidReturnProperty',
});
}
else {
context.report({
loc: (0, util_1.getFunctionHeadLoc)(functionNode, context.sourceCode),
messageId: 'voidReturnProperty',
});
}
}
return;
}
}
function checkReturnStatement(node) {
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
if (tsNode.expression === undefined || node.argument == null) {
return;
}
// syntactically ignore some known-good cases to avoid touching type info
const functionNode = (() => {
let current = node.parent;
while (current && !(0, util_1.isFunction)(current)) {
current = current.parent;
}
return (0, util_1.nullThrows)(current, util_1.NullThrowsReasons.MissingParent);
})();
if (functionNode.returnType &&
!isPossiblyFunctionType(functionNode.returnType)) {
return;
}
const contextualType = checker.getContextualType(tsNode.expression);
if (contextualType !== undefined &&
isVoidReturningFunctionType(checker, tsNode.expression, contextualType) &&
returnsThenable(checker, tsNode.expression)) {
context.report({
node: node.argument,
messageId: 'voidReturnReturnValue',
});
}
}
function checkClassLikeOrInterfaceNode(node) {
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
const heritageTypes = getHeritageTypes(checker, tsNode);
if (!heritageTypes?.length) {
return;
}
for (const nodeMember of tsNode.members) {
const memberName = nodeMember.name?.getText();
if (memberName === undefined) {
// Call/construct/index signatures don't have names. TS allows call signatures to mismatch,
// and construct signatures can't be async.
// TODO - Once we're able to use `checker.isTypeAssignableTo` (v8), we can check an index
// signature here against its compatible index signatures in `heritageTypes`
continue;
}
if (!returnsThenable(checker, nodeMember)) {
continue;
}
const node = services.tsNodeToESTreeNodeMap.get(nodeMember);
if (isStaticMember(node)) {
continue;
}
for (const heritageType of heritageTypes) {
checkHeritageTypeForMemberReturningVoid(nodeMember, heritageType, memberName);
}
}
}
/**
* Checks `heritageType` for a member named `memberName` that returns void; reports the
* 'voidReturnInheritedMethod' message if found.
* @param nodeMember Node member that returns a Promise
* @param heritageType Heritage type to check against
* @param memberName Name of the member to check for
*/
function checkHeritageTypeForMemberReturningVoid(nodeMember, heritageType, memberName) {
const heritageMember = getMemberIfExists(heritageType, memberName);
if (heritageMember === undefined) {
return;
}
const memberType = checker.getTypeOfSymbolAtLocation(heritageMember, nodeMember);
if (!isVoidReturningFunctionType(checker, nodeMember, memberType)) {
return;
}
context.report({
node: services.tsNodeToESTreeNodeMap.get(nodeMember),
messageId: 'voidReturnInheritedMethod',
data: { heritageTypeName: checker.typeToString(heritageType) },
});
}
function checkJSXAttribute(node) {
if (node.value == null ||
node.value.type !== utils_1.AST_NODE_TYPES.JSXExpressionContainer) {
return;
}
const expressionContainer = services.esTreeNodeToTSNodeMap.get(node.value);
const expression = services.esTreeNodeToTSNodeMap.get(node.value.expression);
const contextualType = checker.getContextualType(expressionContainer);
if (contextualType !== undefined &&
isVoidReturningFunctionType(checker, expressionContainer, contextualType) &&
returnsThenable(checker, expression)) {
context.report({
node: node.value,
messageId: 'voidReturnAttribute',
});
}
}
function checkSpread(node) {
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
if (isSometimesThenable(checker, tsNode.expression)) {
context.report({
node: node.argument,
messageId: 'spread',
});
}
}
return {
...(checksConditionals ? conditionalChecks : {}),
...(checksVoidReturn ? voidReturnChecks : {}),
...(checksSpreads ? spreadChecks : {}),
};
},
});
function isSometimesThenable(checker, node) {
const type = checker.getTypeAtLocation(node);
for (const subType of tsutils.unionTypeParts(checker.getApparentType(type))) {
if (tsutils.isThenableType(checker, node, subType)) {
return true;
}
}
return false;
}
// Variation on the thenable check which requires all forms of the type (read:
// alternates in a union) to be thenable. Otherwise, you might be trying to
// check if something is defined or undefined and get caught because one of the
// branches is thenable.
function isAlwaysThenable(checker, node) {
const type = checker.getTypeAtLocation(node);
for (const subType of tsutils.unionTypeParts(checker.getApparentType(type))) {
const thenProp = subType.getProperty('then');
// If one of the alternates has no then property, it is not thenable in all
// cases.
if (thenProp === undefined) {
return false;
}
// We walk through each variation of the then property. Since we know it
// exists at this point, we just need at least one of the alternates to
// be of the right form to consider it thenable.
const thenType = checker.getTypeOfSymbolAtLocation(thenProp, node);
let hasThenableSignature = false;
for (const subType of tsutils.unionTypeParts(thenType)) {
for (const signature of subType.getCallSignatures()) {
if (signature.parameters.length !== 0 &&
isFunctionParam(checker, signature.parameters[0], node)) {
hasThenableSignature = true;
break;
}
}
// We only need to find one variant of the then property that has a
// function signature for it to be thenable.
if (hasThenableSignature) {
break;
}
}
// If no flavors of the then property are thenable, we don't consider the
// overall type to be thenable
if (!hasThenableSignature) {
return false;
}
}
// If all variants are considered thenable (i.e. haven't returned false), we
// consider the overall type thenable
return true;
}
function isFunctionParam(checker, param, node) {
const type = checker.getApparentType(checker.getTypeOfSymbolAtLocation(param, node));
for (const subType of tsutils.unionTypeParts(type)) {
if (subType.getCallSignatures().length !== 0) {
return true;
}
}
return false;
}
function checkThenableOrVoidArgument(checker, node, type, index, thenableReturnIndices, voidReturnIndices) {
if (isThenableReturningFunctionType(checker, node.expression, type)) {
thenableReturnIndices.add(index);
}
else if (isVoidReturningFunctionType(checker, node.expression, type) &&
// If a certain argument accepts both thenable and void returns,
// a promise-returning function is valid
!thenableReturnIndices.has(index)) {
voidReturnIndices.add(index);
}
const contextualType = checker.getContextualTypeForArgumentAtIndex(node, index);
if (contextualType !== type) {
checkThenableOrVoidArgument(checker, node, contextualType, index, thenableReturnIndices, voidReturnIndices);
}
}
// Get the positions of arguments which are void functions (and not also
// thenable functions). These are the candidates for the void-return check at
// the current call site.
// If the function parameters end with a 'rest' parameter, then we consider
// the array type parameter (e.g. '...args:Array<SomeType>') when determining
// if trailing arguments are candidates.
function voidFunctionArguments(checker, node) {
// 'new' can be used without any arguments, as in 'let b = new Object;'
// In this case, there are no argument positions to check, so return early.
if (!node.arguments) {
return new Set();
}
const thenableReturnIndices = new Set();
const voidReturnIndices = new Set();
const type = checker.getTypeAtLocation(node.expression);
// We can't use checker.getResolvedSignature because it prefers an early '() => void' over a later '() => Promise<void>'
// See https://github.com/microsoft/TypeScript/issues/48077
for (const subType of tsutils.unionTypeParts(type)) {
// Standard function calls and `new` have two different types of signatures
const signatures = ts.isCallExpression(node)
? subType.getCallSignatures()
: subType.getConstructSignatures();
for (const signature of signatures) {
for (const [index, parameter] of signature.parameters.entries()) {
const decl = parameter.valueDeclaration;
let type = checker.getTypeOfSymbolAtLocation(parameter, node.expression);
// If this is a array 'rest' parameter, check all of the argument indices
// from the current argument to the end.
if (decl && (0, util_1.isRestParameterDeclaration)(decl)) {
if (checker.isArrayType(type)) {
// Unwrap 'Array<MaybeVoidFunction>' to 'MaybeVoidFunction',
// so that we'll handle it in the same way as a non-rest
// 'param: MaybeVoidFunction'
type = checker.getTypeArguments(type)[0];
for (let i = index; i < node.arguments.length; i++) {
checkThenableOrVoidArgument(checker, node, type, i, thenableReturnIndices, voidReturnIndices);
}
}
else if (checker.isTupleType(type)) {
// Check each type in the tuple - for example, [boolean, () => void] would
// add the index of the second tuple parameter to 'voidReturnIndices'
const typeArgs = checker.getTypeArguments(type);
for (let i = index; i < node.arguments.length && i - index < typeArgs.length; i++) {
checkThenableOrVoidArgument(checker, node, typeArgs[i - index], i, thenableReturnIndices, voidReturnIndices);
}
}
}
else {
checkThenableOrVoidArgument(checker, node, type, index, thenableReturnIndices, voidReturnIndices);
}
}
}
}
for (const index of thenableReturnIndices) {
voidReturnIndices.delete(index);
}
return voidReturnIndices;
}
/**
* @returns Whether any call signature of the type has a thenable return type.
*/
function anySignatureIsThenableType(checker, node, type) {
for (const signature of type.getCallSignatures()) {
const returnType = signature.getReturnType();
if (tsutils.isThenableType(checker, node, returnType)) {
return true;
}
}
return false;
}
/**
* @returns Whether type is a thenable-returning function.
*/
function isThenableReturningFunctionType(checker, node, type) {
for (const subType of tsutils.unionTypeParts(type)) {
if (anySignatureIsThenableType(checker, node, subType)) {
return true;
}
}
return false;
}
/**
* @returns Whether type is a void-returning function.
*/
function isVoidReturningFunctionType(checker, node, type) {
let hadVoidReturn = false;
for (const subType of tsutils.unionTypeParts(type)) {
for (const signature of subType.getCallSignatures()) {
const returnType = signature.getReturnType();
// If a certain positional argument accepts both thenable and void returns,
// a promise-returning function is valid
if (tsutils.isThenableType(checker, node, returnType)) {
return false;
}
hadVoidReturn ||= tsutils.isTypeFlagSet(returnType, ts.TypeFlags.Void);
}
}
return hadVoidReturn;
}
/**
* @returns Whether expression is a function that returns a thenable.
*/
function returnsThenable(checker, node) {
const type = checker.getApparentType(checker.getTypeAtLocation(node));
return tsutils
.unionTypeParts(type)
.some(t => anySignatureIsThenableType(checker, node, t));
}
function getHeritageTypes(checker, tsNode) {
return tsNode.heritageClauses
?.flatMap(clause => clause.types)
.map(typeExpression => checker.getTypeAtLocation(typeExpression));
}
/**
* @returns The member with the given name in `type`, if it exists.
*/
function getMemberIfExists(type, memberName) {
const escapedMemberName = ts.escapeLeadingUnderscores(memberName);
const symbolMemberMatch = type.getSymbol()?.members?.get(escapedMemberName);
return (symbolMemberMatch ?? tsutils.getPropertyOfType(type, escapedMemberName));
}
function isStaticMember(node) {
return ((node.type === utils_1.AST_NODE_TYPES.MethodDefinition ||
node.type === utils_1.AST_NODE_TYPES.PropertyDefinition) &&
node.static);
}
//# sourceMappingURL=no-misused-promises.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,634 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const tsutils = __importStar(require("ts-api-utils"));
const ts = __importStar(require("typescript"));
const util_1 = require("../util");
const assertionFunctionUtils_1 = require("../util/assertionFunctionUtils");
// Truthiness utilities
// #region
const valueIsPseudoBigInt = (value) => {
return typeof value === 'object';
};
const getValueOfLiteralType = (type) => {
if (valueIsPseudoBigInt(type.value)) {
return pseudoBigIntToBigInt(type.value);
}
return type.value;
};
const isFalsyBigInt = (type) => {
return (tsutils.isLiteralType(type) &&
valueIsPseudoBigInt(type.value) &&
!getValueOfLiteralType(type));
};
const isTruthyLiteral = (type) => tsutils.isTrueLiteralType(type) ||
(type.isLiteral() && !!getValueOfLiteralType(type));
const isPossiblyFalsy = (type) => tsutils
.unionTypeParts(type)
// Intersections like `string & {}` can also be possibly falsy,
// requiring us to look into the intersection.
.flatMap(type => tsutils.intersectionTypeParts(type))
// PossiblyFalsy flag includes literal values, so exclude ones that
// are definitely truthy
.filter(t => !isTruthyLiteral(t))
.some(type => (0, util_1.isTypeFlagSet)(type, ts.TypeFlags.PossiblyFalsy));
const isPossiblyTruthy = (type) => tsutils
.unionTypeParts(type)
.map(type => tsutils.intersectionTypeParts(type))
.some(intersectionParts =>
// It is possible to define intersections that are always falsy,
// like `"" & { __brand: string }`.
intersectionParts.every(type => !tsutils.isFalsyType(type) &&
// below is a workaround for ts-api-utils bug
// see https://github.com/JoshuaKGoldberg/ts-api-utils/issues/544
!isFalsyBigInt(type)));
// Nullish utilities
const nullishFlag = ts.TypeFlags.Undefined | ts.TypeFlags.Null;
const isNullishType = (type) => (0, util_1.isTypeFlagSet)(type, nullishFlag);
const isPossiblyNullish = (type) => tsutils.unionTypeParts(type).some(isNullishType);
const isAlwaysNullish = (type) => tsutils.unionTypeParts(type).every(isNullishType);
function toStaticValue(type) {
// type.isLiteral() only covers numbers/bigints and strings, hence the rest of the branches.
if (tsutils.isBooleanLiteralType(type)) {
// Using `type.intrinsicName` instead of `type.value` because `type.value`
// is `undefined`, contrary to what the type guard tells us.
// See https://github.com/JoshuaKGoldberg/ts-api-utils/issues/528
return { value: type.intrinsicName === 'true' };
}
if (type.flags === ts.TypeFlags.Undefined) {
return { value: undefined };
}
if (type.flags === ts.TypeFlags.Null) {
return { value: null };
}
if (type.isLiteral()) {
return { value: getValueOfLiteralType(type) };
}
return undefined;
}
function pseudoBigIntToBigInt(value) {
return BigInt((value.negative ? '-' : '') + value.base10Value);
}
const BOOL_OPERATORS = new Set([
'<',
'>',
'<=',
'>=',
'==',
'===',
'!=',
'!==',
]);
function isBoolOperator(operator) {
return BOOL_OPERATORS.has(operator);
}
function booleanComparison(left, operator, right) {
switch (operator) {
case '!=':
// eslint-disable-next-line eqeqeq -- intentionally comparing with loose equality
return left != right;
case '!==':
return left !== right;
case '<':
// @ts-expect-error: we don't care if the comparison seems unintentional.
return left < right;
case '<=':
// @ts-expect-error: we don't care if the comparison seems unintentional.
return left <= right;
case '==':
// eslint-disable-next-line eqeqeq -- intentionally comparing with loose equality
return left == right;
case '===':
return left === right;
case '>':
// @ts-expect-error: we don't care if the comparison seems unintentional.
return left > right;
case '>=':
// @ts-expect-error: we don't care if the comparison seems unintentional.
return left >= right;
}
}
exports.default = (0, util_1.createRule)({
name: 'no-unnecessary-condition',
meta: {
type: 'suggestion',
docs: {
description: 'Disallow conditionals where the type is always truthy or always falsy',
recommended: 'strict',
requiresTypeChecking: true,
},
fixable: 'code',
messages: {
alwaysFalsy: 'Unnecessary conditional, value is always falsy.',
alwaysFalsyFunc: 'This callback should return a conditional, but return is always falsy.',
alwaysNullish: 'Unnecessary conditional, left-hand side of `??` operator is always `null` or `undefined`.',
alwaysTruthy: 'Unnecessary conditional, value is always truthy.',
alwaysTruthyFunc: 'This callback should return a conditional, but return is always truthy.',
literalBooleanExpression: 'Unnecessary conditional, comparison is always {{trueOrFalse}}. Both sides of the comparison always have a literal type.',
never: 'Unnecessary conditional, value is `never`.',
neverNullish: 'Unnecessary conditional, expected left-hand side of `??` operator to be possibly null or undefined.',
neverOptionalChain: 'Unnecessary optional chain on a non-nullish value.',
noOverlapBooleanExpression: 'Unnecessary conditional, the types have no overlap.',
noStrictNullCheck: 'This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.',
typeGuardAlreadyIsType: 'Unnecessary conditional, expression already has the type being checked by the {{typeGuardOrAssertionFunction}}.',
},
schema: [
{
type: 'object',
additionalProperties: false,
properties: {
allowConstantLoopConditions: {
type: 'boolean',
description: 'Whether to ignore constant loop conditions, such as `while (true)`.',
},
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: {
type: 'boolean',
description: 'Whether to not error when running with a tsconfig that has strictNullChecks turned.',
},
checkTypePredicates: {
type: 'boolean',
description: 'Whether to check the asserted argument of a type predicate function for unnecessary conditions',
},
},
},
],
},
defaultOptions: [
{
allowConstantLoopConditions: false,
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: false,
checkTypePredicates: false,
},
],
create(context, [{ allowConstantLoopConditions, allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing, checkTypePredicates, },]) {
const services = (0, util_1.getParserServices)(context);
const checker = services.program.getTypeChecker();
const compilerOptions = services.program.getCompilerOptions();
const isStrictNullChecks = tsutils.isStrictCompilerOptionEnabled(compilerOptions, 'strictNullChecks');
if (!isStrictNullChecks &&
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing !== true) {
context.report({
loc: {
start: { column: 0, line: 0 },
end: { column: 0, line: 0 },
},
messageId: 'noStrictNullCheck',
});
}
function nodeIsArrayType(node) {
const nodeType = (0, util_1.getConstrainedTypeAtLocation)(services, node);
return tsutils
.unionTypeParts(nodeType)
.some(part => checker.isArrayType(part));
}
function nodeIsTupleType(node) {
const nodeType = (0, util_1.getConstrainedTypeAtLocation)(services, node);
return tsutils
.unionTypeParts(nodeType)
.some(part => checker.isTupleType(part));
}
function isArrayIndexExpression(node) {
return (
// Is an index signature
node.type === utils_1.AST_NODE_TYPES.MemberExpression &&
node.computed &&
// ...into an array type
(nodeIsArrayType(node.object) ||
// ... or a tuple type
(nodeIsTupleType(node.object) &&
// Exception: literal index into a tuple - will have a sound type
node.property.type !== utils_1.AST_NODE_TYPES.Literal)));
}
function isNullableMemberExpression(node) {
const objectType = services.getTypeAtLocation(node.object);
if (node.computed) {
const propertyType = services.getTypeAtLocation(node.property);
return isNullablePropertyType(objectType, propertyType);
}
const property = node.property;
// Get the actual property name, to account for private properties (this.#prop).
const propertyName = context.sourceCode.getText(property);
const propertyType = objectType
.getProperties()
.find(prop => prop.name === propertyName);
if (propertyType &&
tsutils.isSymbolFlagSet(propertyType, ts.SymbolFlags.Optional)) {
return true;
}
return false;
}
/**
* Checks if a conditional node is necessary:
* if the type of the node is always true or always false, it's not necessary.
*/
function checkNode(expression, isUnaryNotArgument = false, node = expression) {
// Check if the node is Unary Negation expression and handle it
if (expression.type === utils_1.AST_NODE_TYPES.UnaryExpression &&
expression.operator === '!') {
return checkNode(expression.argument, !isUnaryNotArgument, node);
}
// Since typescript array index signature types don't represent the
// possibility of out-of-bounds access, if we're indexing into an array
// just skip the check, to avoid false positives
if (isArrayIndexExpression(expression)) {
return;
}
// When checking logical expressions, only check the right side
// as the left side has been checked by checkLogicalExpressionForUnnecessaryConditionals
//
// Unless the node is nullish coalescing, as it's common to use patterns like `nullBool ?? true` to to strict
// boolean checks if we inspect the right here, it'll usually be a constant condition on purpose.
// In this case it's better to inspect the type of the expression as a whole.
if (expression.type === utils_1.AST_NODE_TYPES.LogicalExpression &&
expression.operator !== '??') {
return checkNode(expression.right);
}
const type = (0, util_1.getConstrainedTypeAtLocation)(services, expression);
// Conditional is always necessary if it involves:
// `any` or `unknown` or a naked type variable
if (tsutils
.unionTypeParts(type)
.some(part => (0, util_1.isTypeAnyType)(part) ||
(0, util_1.isTypeUnknownType)(part) ||
(0, util_1.isTypeFlagSet)(part, ts.TypeFlags.TypeVariable))) {
return;
}
let messageId = null;
if ((0, util_1.isTypeFlagSet)(type, ts.TypeFlags.Never)) {
messageId = 'never';
}
else if (!isPossiblyTruthy(type)) {
messageId = !isUnaryNotArgument ? 'alwaysFalsy' : 'alwaysTruthy';
}
else if (!isPossiblyFalsy(type)) {
messageId = !isUnaryNotArgument ? 'alwaysTruthy' : 'alwaysFalsy';
}
if (messageId) {
context.report({ node, messageId });
}
}
function checkNodeForNullish(node) {
const type = (0, util_1.getConstrainedTypeAtLocation)(services, node);
// Conditional is always necessary if it involves `any`, `unknown` or a naked type parameter
if ((0, util_1.isTypeFlagSet)(type, ts.TypeFlags.Any |
ts.TypeFlags.Unknown |
ts.TypeFlags.TypeParameter |
ts.TypeFlags.TypeVariable)) {
return;
}
let messageId = null;
if ((0, util_1.isTypeFlagSet)(type, ts.TypeFlags.Never)) {
messageId = 'never';
}
else if (!isPossiblyNullish(type) &&
!(node.type === utils_1.AST_NODE_TYPES.MemberExpression &&
isNullableMemberExpression(node))) {
// Since typescript array index signature types don't represent the
// possibility of out-of-bounds access, if we're indexing into an array
// just skip the check, to avoid false positives
if (!isArrayIndexExpression(node) &&
!(node.type === utils_1.AST_NODE_TYPES.ChainExpression &&
node.expression.type !== utils_1.AST_NODE_TYPES.TSNonNullExpression &&
optionChainContainsOptionArrayIndex(node.expression))) {
messageId = 'neverNullish';
}
}
else if (isAlwaysNullish(type)) {
messageId = 'alwaysNullish';
}
if (messageId) {
context.report({ node, messageId });
}
}
/**
* Checks that a binary expression is necessarily conditional, reports otherwise.
* If both sides of the binary expression are literal values, it's not a necessary condition.
*
* NOTE: It's also unnecessary if the types that don't overlap at all
* but that case is handled by the Typescript compiler itself.
* Known exceptions:
* - https://github.com/microsoft/TypeScript/issues/32627
* - https://github.com/microsoft/TypeScript/issues/37160 (handled)
*/
function checkIfBoolExpressionIsNecessaryConditional(node, left, right, operator) {
const leftType = (0, util_1.getConstrainedTypeAtLocation)(services, left);
const rightType = (0, util_1.getConstrainedTypeAtLocation)(services, right);
const leftStaticValue = toStaticValue(leftType);
const rightStaticValue = toStaticValue(rightType);
if (leftStaticValue != null && rightStaticValue != null) {
const conditionIsTrue = booleanComparison(leftStaticValue.value, operator, rightStaticValue.value);
context.report({
node,
messageId: 'literalBooleanExpression',
data: {
trueOrFalse: conditionIsTrue ? 'true' : 'false',
},
});
return;
}
// Workaround for https://github.com/microsoft/TypeScript/issues/37160
if (isStrictNullChecks) {
const UNDEFINED = ts.TypeFlags.Undefined;
const NULL = ts.TypeFlags.Null;
const VOID = ts.TypeFlags.Void;
const isComparable = (type, flag) => {
// Allow comparison to `any`, `unknown` or a naked type parameter.
flag |=
ts.TypeFlags.Any |
ts.TypeFlags.Unknown |
ts.TypeFlags.TypeParameter |
ts.TypeFlags.TypeVariable;
// Allow loose comparison to nullish values.
if (operator === '==' || operator === '!=') {
flag |= NULL | UNDEFINED | VOID;
}
return (0, util_1.isTypeFlagSet)(type, flag);
};
if ((leftType.flags === UNDEFINED &&
!isComparable(rightType, UNDEFINED | VOID)) ||
(rightType.flags === UNDEFINED &&
!isComparable(leftType, UNDEFINED | VOID)) ||
(leftType.flags === NULL && !isComparable(rightType, NULL)) ||
(rightType.flags === NULL && !isComparable(leftType, NULL))) {
context.report({ node, messageId: 'noOverlapBooleanExpression' });
return;
}
}
}
/**
* Checks that a logical expression contains a boolean, reports otherwise.
*/
function checkLogicalExpressionForUnnecessaryConditionals(node) {
if (node.operator === '??') {
checkNodeForNullish(node.left);
return;
}
// Only checks the left side, since the right side might not be "conditional" at all.
// The right side will be checked if the LogicalExpression is used in a conditional context
checkNode(node.left);
}
/**
* Checks that a testable expression of a loop is necessarily conditional, reports otherwise.
*/
function checkIfLoopIsNecessaryConditional(node) {
if (node.test == null) {
// e.g. `for(;;)`
return;
}
/**
* Allow:
* while (true) {}
* for (;true;) {}
* do {} while (true)
*/
if (allowConstantLoopConditions &&
tsutils.isTrueLiteralType((0, util_1.getConstrainedTypeAtLocation)(services, node.test))) {
return;
}
checkNode(node.test);
}
function checkCallExpression(node) {
if (checkTypePredicates) {
const truthinessAssertedArgument = (0, assertionFunctionUtils_1.findTruthinessAssertedArgument)(services, node);
if (truthinessAssertedArgument != null) {
checkNode(truthinessAssertedArgument);
}
const typeGuardAssertedArgument = (0, assertionFunctionUtils_1.findTypeGuardAssertedArgument)(services, node);
if (typeGuardAssertedArgument != null) {
const typeOfArgument = (0, util_1.getConstrainedTypeAtLocation)(services, typeGuardAssertedArgument.argument);
if (typeOfArgument === typeGuardAssertedArgument.type) {
context.report({
node: typeGuardAssertedArgument.argument,
messageId: 'typeGuardAlreadyIsType',
data: {
typeGuardOrAssertionFunction: typeGuardAssertedArgument.asserts
? 'assertion function'
: 'type guard',
},
});
}
}
}
// If this is something like arr.filter(x => /*condition*/), check `condition`
if ((0, util_1.isArrayMethodCallWithPredicate)(context, services, node) &&
node.arguments.length) {
const callback = node.arguments[0];
// Inline defined functions
if (callback.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
callback.type === utils_1.AST_NODE_TYPES.FunctionExpression) {
// Two special cases, where we can directly check the node that's returned:
// () => something
if (callback.body.type !== utils_1.AST_NODE_TYPES.BlockStatement) {
return checkNode(callback.body);
}
// () => { return something; }
const callbackBody = callback.body.body;
if (callbackBody.length === 1 &&
callbackBody[0].type === utils_1.AST_NODE_TYPES.ReturnStatement &&
callbackBody[0].argument) {
return checkNode(callbackBody[0].argument);
}
// Potential enhancement: could use code-path analysis to check
// any function with a single return statement
// (Value to complexity ratio is dubious however)
}
// Otherwise just do type analysis on the function as a whole.
const returnTypes = tsutils
.getCallSignaturesOfType((0, util_1.getConstrainedTypeAtLocation)(services, callback))
.map(sig => sig.getReturnType());
/* istanbul ignore if */ if (returnTypes.length === 0) {
// Not a callable function
return;
}
// Predicate is always necessary if it involves `any` or `unknown`
if (returnTypes.some(t => (0, util_1.isTypeAnyType)(t) || (0, util_1.isTypeUnknownType)(t))) {
return;
}
if (!returnTypes.some(isPossiblyFalsy)) {
return context.report({
node: callback,
messageId: 'alwaysTruthyFunc',
});
}
if (!returnTypes.some(isPossiblyTruthy)) {
return context.report({
node: callback,
messageId: 'alwaysFalsyFunc',
});
}
}
}
// Recursively searches an optional chain for an array index expression
// Has to search the entire chain, because an array index will "infect" the rest of the types
// Example:
// ```
// [{x: {y: "z"} }][n] // type is {x: {y: "z"}}
// ?.x // type is {y: "z"}
// ?.y // This access is considered "unnecessary" according to the types
// ```
function optionChainContainsOptionArrayIndex(node) {
const lhsNode = node.type === utils_1.AST_NODE_TYPES.CallExpression ? node.callee : node.object;
if (node.optional && isArrayIndexExpression(lhsNode)) {
return true;
}
if (lhsNode.type === utils_1.AST_NODE_TYPES.MemberExpression ||
lhsNode.type === utils_1.AST_NODE_TYPES.CallExpression) {
return optionChainContainsOptionArrayIndex(lhsNode);
}
return false;
}
function isNullablePropertyType(objType, propertyType) {
if (propertyType.isUnion()) {
return propertyType.types.some(type => isNullablePropertyType(objType, type));
}
if (propertyType.isNumberLiteral() || propertyType.isStringLiteral()) {
const propType = (0, util_1.getTypeOfPropertyOfName)(checker, objType, propertyType.value.toString());
if (propType) {
return (0, util_1.isNullableType)(propType);
}
}
const typeName = (0, util_1.getTypeName)(checker, propertyType);
return checker
.getIndexInfosOfType(objType)
.some(info => (0, util_1.getTypeName)(checker, info.keyType) === typeName);
}
// Checks whether a member expression is nullable or not regardless of it's previous node.
// Example:
// ```
// // 'bar' is nullable if 'foo' is null.
// // but this function checks regardless of 'foo' type, so returns 'true'.
// declare const foo: { bar : { baz: string } } | null
// foo?.bar;
// ```
function isMemberExpressionNullableOriginFromObject(node) {
const prevType = (0, util_1.getConstrainedTypeAtLocation)(services, node.object);
const property = node.property;
if (prevType.isUnion() && (0, util_1.isIdentifier)(property)) {
const isOwnNullable = prevType.types.some(type => {
if (node.computed) {
const propertyType = (0, util_1.getConstrainedTypeAtLocation)(services, node.property);
return isNullablePropertyType(type, propertyType);
}
const propType = (0, util_1.getTypeOfPropertyOfName)(checker, type, property.name);
if (propType) {
return (0, util_1.isNullableType)(propType);
}
return !!checker.getIndexInfoOfType(type, ts.IndexKind.String);
});
return !isOwnNullable && (0, util_1.isNullableType)(prevType);
}
return false;
}
function isCallExpressionNullableOriginFromCallee(node) {
const prevType = (0, util_1.getConstrainedTypeAtLocation)(services, node.callee);
if (prevType.isUnion()) {
const isOwnNullable = prevType.types.some(type => {
const signatures = type.getCallSignatures();
return signatures.some(sig => (0, util_1.isNullableType)(sig.getReturnType()));
});
return !isOwnNullable && (0, util_1.isNullableType)(prevType);
}
return false;
}
function isOptionableExpression(node) {
const type = (0, util_1.getConstrainedTypeAtLocation)(services, node);
const isOwnNullable = node.type === utils_1.AST_NODE_TYPES.MemberExpression
? !isMemberExpressionNullableOriginFromObject(node)
: node.type === utils_1.AST_NODE_TYPES.CallExpression
? !isCallExpressionNullableOriginFromCallee(node)
: true;
return ((0, util_1.isTypeFlagSet)(type, ts.TypeFlags.Any | ts.TypeFlags.Unknown) ||
(isOwnNullable && (0, util_1.isNullableType)(type)));
}
function checkOptionalChain(node, beforeOperator, fix) {
// We only care if this step in the chain is optional. If just descend
// from an optional chain, then that's fine.
if (!node.optional) {
return;
}
// Since typescript array index signature types don't represent the
// possibility of out-of-bounds access, if we're indexing into an array
// just skip the check, to avoid false positives
if (optionChainContainsOptionArrayIndex(node)) {
return;
}
const nodeToCheck = node.type === utils_1.AST_NODE_TYPES.CallExpression ? node.callee : node.object;
if (isOptionableExpression(nodeToCheck)) {
return;
}
const questionDotOperator = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(beforeOperator, token => token.type === utils_1.AST_TOKEN_TYPES.Punctuator && token.value === '?.'), util_1.NullThrowsReasons.MissingToken('operator', node.type));
context.report({
loc: questionDotOperator.loc,
node,
messageId: 'neverOptionalChain',
fix(fixer) {
return fixer.replaceText(questionDotOperator, fix);
},
});
}
function checkOptionalMemberExpression(node) {
checkOptionalChain(node, node.object, node.computed ? '' : '.');
}
function checkOptionalCallExpression(node) {
checkOptionalChain(node, node.callee, '');
}
function checkAssignmentExpression(node) {
// Similar to checkLogicalExpressionForUnnecessaryConditionals, since
// a ||= b is equivalent to a || (a = b)
if (['&&=', '||='].includes(node.operator)) {
checkNode(node.left);
}
else if (node.operator === '??=') {
checkNodeForNullish(node.left);
}
}
return {
AssignmentExpression: checkAssignmentExpression,
BinaryExpression(node) {
const { operator } = node;
if (isBoolOperator(operator)) {
checkIfBoolExpressionIsNecessaryConditional(node, node.left, node.right, operator);
}
},
CallExpression: checkCallExpression,
'CallExpression[optional = true]': checkOptionalCallExpression,
ConditionalExpression: (node) => checkNode(node.test),
DoWhileStatement: checkIfLoopIsNecessaryConditional,
ForStatement: checkIfLoopIsNecessaryConditional,
IfStatement: (node) => checkNode(node.test),
LogicalExpression: checkLogicalExpressionForUnnecessaryConditionals,
'MemberExpression[optional = true]': checkOptionalMemberExpression,
SwitchCase({ parent, test }) {
// only check `case ...:`, not `default:`
if (test) {
checkIfBoolExpressionIsNecessaryConditional(test, parent.discriminant, test, '===');
}
},
WhileStatement: checkIfLoopIsNecessaryConditional,
};
},
});
//# sourceMappingURL=no-unnecessary-condition.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,176 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const tsutils = __importStar(require("ts-api-utils"));
const ts = __importStar(require("typescript"));
const util_1 = require("../util");
const getParentFunctionNode_1 = require("../util/getParentFunctionNode");
exports.default = (0, util_1.createRule)({
name: 'no-unsafe-return',
meta: {
type: 'problem',
docs: {
description: 'Disallow returning a value with type `any` from a function',
recommended: 'recommended',
requiresTypeChecking: true,
},
messages: {
unsafeReturn: 'Unsafe return of a value of type {{type}}.',
unsafeReturnAssignment: 'Unsafe return of type `{{sender}}` from function with return type `{{receiver}}`.',
unsafeReturnThis: [
'Unsafe return of a value of type `{{type}}`. `this` is typed as `any`.',
'You can try to fix this by turning on the `noImplicitThis` compiler option, or adding a `this` parameter to the function.',
].join('\n'),
},
schema: [],
},
defaultOptions: [],
create(context) {
const services = (0, util_1.getParserServices)(context);
const checker = services.program.getTypeChecker();
const compilerOptions = services.program.getCompilerOptions();
const isNoImplicitThis = tsutils.isStrictCompilerOptionEnabled(compilerOptions, 'noImplicitThis');
function checkReturn(returnNode, reportingNode = returnNode) {
const tsNode = services.esTreeNodeToTSNodeMap.get(returnNode);
const type = checker.getTypeAtLocation(tsNode);
const anyType = (0, util_1.discriminateAnyType)(type, checker, services.program, tsNode);
const functionNode = (0, getParentFunctionNode_1.getParentFunctionNode)(returnNode);
/* istanbul ignore if */ if (!functionNode) {
return;
}
// function has an explicit return type, so ensure it's a safe return
const returnNodeType = (0, util_1.getConstrainedTypeAtLocation)(services, returnNode);
const functionTSNode = services.esTreeNodeToTSNodeMap.get(functionNode);
// function expressions will not have their return type modified based on receiver typing
// so we have to use the contextual typing in these cases, i.e.
// const foo1: () => Set<string> = () => new Set<any>();
// the return type of the arrow function is Set<any> even though the variable is typed as Set<string>
let functionType = ts.isFunctionExpression(functionTSNode) ||
ts.isArrowFunction(functionTSNode)
? (0, util_1.getContextualType)(checker, functionTSNode)
: services.getTypeAtLocation(functionNode);
if (!functionType) {
functionType = services.getTypeAtLocation(functionNode);
}
const callSignatures = tsutils.getCallSignaturesOfType(functionType);
// If there is an explicit type annotation *and* that type matches the actual
// function return type, we shouldn't complain (it's intentional, even if unsafe)
if (functionTSNode.type) {
for (const signature of callSignatures) {
const signatureReturnType = signature.getReturnType();
if (returnNodeType === signatureReturnType ||
(0, util_1.isTypeFlagSet)(signatureReturnType, ts.TypeFlags.Any | ts.TypeFlags.Unknown)) {
return;
}
if (functionNode.async) {
const awaitedSignatureReturnType = checker.getAwaitedType(signatureReturnType);
const awaitedReturnNodeType = checker.getAwaitedType(returnNodeType);
if (awaitedReturnNodeType === awaitedSignatureReturnType ||
(awaitedSignatureReturnType &&
(0, util_1.isTypeFlagSet)(awaitedSignatureReturnType, ts.TypeFlags.Any | ts.TypeFlags.Unknown))) {
return;
}
}
}
}
if (anyType !== util_1.AnyType.Safe) {
// Allow cases when the declared return type of the function is either unknown or unknown[]
// and the function is returning any or any[].
for (const signature of callSignatures) {
const functionReturnType = signature.getReturnType();
if (anyType === util_1.AnyType.Any &&
(0, util_1.isTypeUnknownType)(functionReturnType)) {
return;
}
if (anyType === util_1.AnyType.AnyArray &&
(0, util_1.isTypeUnknownArrayType)(functionReturnType, checker)) {
return;
}
const awaitedType = checker.getAwaitedType(functionReturnType);
if (awaitedType &&
anyType === util_1.AnyType.PromiseAny &&
(0, util_1.isTypeUnknownType)(awaitedType)) {
return;
}
}
if (anyType === util_1.AnyType.PromiseAny && !functionNode.async) {
return;
}
let messageId = 'unsafeReturn';
const isErrorType = tsutils.isIntrinsicErrorType(returnNodeType);
if (!isNoImplicitThis) {
// `return this`
const thisExpression = (0, util_1.getThisExpression)(returnNode);
if (thisExpression &&
(0, util_1.isTypeAnyType)((0, util_1.getConstrainedTypeAtLocation)(services, thisExpression))) {
messageId = 'unsafeReturnThis';
}
}
// If the function return type was not unknown/unknown[], mark usage as unsafeReturn.
return context.report({
node: reportingNode,
messageId,
data: {
type: isErrorType
? 'error'
: anyType === util_1.AnyType.Any
? '`any`'
: anyType === util_1.AnyType.PromiseAny
? '`Promise<any>`'
: '`any[]`',
},
});
}
const signature = functionType.getCallSignatures().at(0);
if (signature) {
const functionReturnType = signature.getReturnType();
const result = (0, util_1.isUnsafeAssignment)(returnNodeType, functionReturnType, checker, returnNode);
if (!result) {
return;
}
const { receiver, sender } = result;
return context.report({
node: reportingNode,
messageId: 'unsafeReturnAssignment',
data: {
receiver: checker.typeToString(receiver),
sender: checker.typeToString(sender),
},
});
}
}
return {
'ArrowFunctionExpression > :not(BlockStatement).body': checkReturn,
ReturnStatement(node) {
const argument = node.argument;
if (!argument) {
return;
}
checkReturn(argument, node);
},
};
},
});
//# sourceMappingURL=no-unsafe-return.js.map
@@ -0,0 +1 @@
{"version":3,"file":"no-unsafe-return.js","sourceRoot":"","sources":["../../src/rules/no-unsafe-return.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,105 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const ts = __importStar(require("typescript"));
const util_1 = require("../util");
exports.default = (0, util_1.createRule)({
name: 'only-throw-error',
meta: {
type: 'problem',
docs: {
description: 'Disallow throwing non-`Error` values as exceptions',
extendsBaseRule: 'no-throw-literal',
recommended: 'recommended',
requiresTypeChecking: true,
},
messages: {
object: 'Expected an error object to be thrown.',
undef: 'Do not throw undefined.',
},
schema: [
{
type: 'object',
additionalProperties: false,
properties: {
allow: {
...util_1.typeOrValueSpecifiersSchema,
description: 'Type specifiers that can be thrown.',
},
allowThrowingAny: {
type: 'boolean',
description: 'Whether to always allow throwing values typed as `any`.',
},
allowThrowingUnknown: {
type: 'boolean',
description: 'Whether to always allow throwing values typed as `unknown`.',
},
},
},
],
},
defaultOptions: [
{
allow: [],
allowThrowingAny: true,
allowThrowingUnknown: true,
},
],
create(context, [options]) {
const services = (0, util_1.getParserServices)(context);
const allow = options.allow;
function checkThrowArgument(node) {
if (node.type === utils_1.AST_NODE_TYPES.AwaitExpression ||
node.type === utils_1.AST_NODE_TYPES.YieldExpression) {
return;
}
const type = services.getTypeAtLocation(node);
if ((0, util_1.typeMatchesSomeSpecifier)(type, allow, services.program)) {
return;
}
if (type.flags & ts.TypeFlags.Undefined) {
context.report({ node, messageId: 'undef' });
return;
}
if (options.allowThrowingAny && (0, util_1.isTypeAnyType)(type)) {
return;
}
if (options.allowThrowingUnknown && (0, util_1.isTypeUnknownType)(type)) {
return;
}
if ((0, util_1.isErrorLike)(services.program, type)) {
return;
}
context.report({ node, messageId: 'object' });
}
return {
ThrowStatement(node) {
checkThrowArgument(node.argument);
},
};
},
});
//# sourceMappingURL=only-throw-error.js.map
@@ -0,0 +1 @@
{"version":3,"file":"only-throw-error.js","sourceRoot":"","sources":["../../src/rules/only-throw-error.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAEA,oDAA0D;AAC1D,+CAAiC;AAIjC,kCAQiB;AAYjB,kBAAe,IAAA,iBAAU,EAAsB;IAC7C,IAAI,EAAE,kBAAkB;IACxB,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EAAE,oDAAoD;YACjE,eAAe,EAAE,kBAAkB;YACnC,WAAW,EAAE,aAAa;YAC1B,oBAAoB,EAAE,IAAI;SAC3B;QACD,QAAQ,EAAE;YACR,MAAM,EAAE,wCAAwC;YAChD,KAAK,EAAE,yBAAyB;SACjC;QACD,MAAM,EAAE;YACN;gBACE,IAAI,EAAE,QAAQ;gBACd,oBAAoB,EAAE,KAAK;gBAC3B,UAAU,EAAE;oBACV,KAAK,EAAE;wBACL,GAAG,kCAA2B;wBAC9B,WAAW,EAAE,qCAAqC;qBACnD;oBACD,gBAAgB,EAAE;wBAChB,IAAI,EAAE,SAAS;wBACf,WAAW,EACT,yDAAyD;qBAC5D;oBACD,oBAAoB,EAAE;wBACpB,IAAI,EAAE,SAAS;wBACf,WAAW,EACT,6DAA6D;qBAChE;iBACF;aACF;SACF;KACF;IACD,cAAc,EAAE;QACd;YACE,KAAK,EAAE,EAAE;YACT,gBAAgB,EAAE,IAAI;YACtB,oBAAoB,EAAE,IAAI;SAC3B;KACF;IACD,MAAM,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC;QACvB,MAAM,QAAQ,GAAG,IAAA,wBAAiB,EAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC5B,SAAS,kBAAkB,CAAC,IAAmB;YAC7C,IACE,IAAI,CAAC,IAAI,KAAK,sBAAc,CAAC,eAAe;gBAC5C,IAAI,CAAC,IAAI,KAAK,sBAAc,CAAC,eAAe,EAC5C,CAAC;gBACD,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAE9C,IAAI,IAAA,+BAAwB,EAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5D,OAAO;YACT,CAAC;YAED,IAAI,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;gBACxC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;gBAC7C,OAAO;YACT,CAAC;YAED,IAAI,OAAO,CAAC,gBAAgB,IAAI,IAAA,oBAAa,EAAC,IAAI,CAAC,EAAE,CAAC;gBACpD,OAAO;YACT,CAAC;YAED,IAAI,OAAO,CAAC,oBAAoB,IAAI,IAAA,wBAAiB,EAAC,IAAI,CAAC,EAAE,CAAC;gBAC5D,OAAO;YACT,CAAC;YAED,IAAI,IAAA,kBAAW,EAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;gBACxC,OAAO;YACT,CAAC;YAED,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;QAChD,CAAC;QAED,OAAO;YACL,cAAc,CAAC,IAAI;gBACjB,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACpC,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,419 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const tsutils = __importStar(require("ts-api-utils"));
const ts = __importStar(require("typescript"));
const util_1 = require("../util");
exports.default = (0, util_1.createRule)({
name: 'prefer-nullish-coalescing',
meta: {
type: 'suggestion',
docs: {
description: 'Enforce using the nullish coalescing operator instead of logical assignments or chaining',
recommended: 'stylistic',
requiresTypeChecking: true,
},
hasSuggestions: true,
messages: {
noStrictNullCheck: 'This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.',
preferNullishOverOr: 'Prefer using nullish coalescing operator (`??{{ equals }}`) instead of a logical {{ description }} (`||{{ equals }}`), as it is a safer operator.',
preferNullishOverTernary: 'Prefer using nullish coalescing operator (`??{{ equals }}`) instead of a ternary expression, as it is simpler to read.',
suggestNullish: 'Fix to nullish coalescing operator (`??{{ equals }}`).',
},
schema: [
{
type: 'object',
additionalProperties: false,
properties: {
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: {
type: 'boolean',
description: 'Unless this is set to `true`, the rule will error on every file whose `tsconfig.json` does _not_ have the `strictNullChecks` compiler option (or `strict`) set to `true`.',
},
ignoreBooleanCoercion: {
type: 'boolean',
description: 'Whether to ignore arguments to the `Boolean` constructor',
},
ignoreConditionalTests: {
type: 'boolean',
description: 'Whether to ignore cases that are located within a conditional test.',
},
ignoreMixedLogicalExpressions: {
type: 'boolean',
description: 'Whether to ignore any logical or expressions that are part of a mixed logical expression (with `&&`).',
},
ignorePrimitives: {
description: 'Whether to ignore all (`true`) or some (an object with properties) primitive types.',
oneOf: [
{
type: 'object',
description: 'Which primitives types may be ignored.',
properties: {
bigint: {
type: 'boolean',
description: 'Ignore bigint primitive types.',
},
boolean: {
type: 'boolean',
description: 'Ignore boolean primitive types.',
},
number: {
type: 'boolean',
description: 'Ignore number primitive types.',
},
string: {
type: 'boolean',
description: 'Ignore string primitive types.',
},
},
},
{
type: 'boolean',
description: 'Ignore all primitive types.',
enum: [true],
},
],
},
ignoreTernaryTests: {
type: 'boolean',
description: 'Whether to ignore any ternary expressions that could be simplified by using the nullish coalescing operator.',
},
},
},
],
},
defaultOptions: [
{
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: false,
ignoreBooleanCoercion: false,
ignoreConditionalTests: true,
ignoreMixedLogicalExpressions: false,
ignorePrimitives: {
bigint: false,
boolean: false,
number: false,
string: false,
},
ignoreTernaryTests: false,
},
],
create(context, [{ allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing, ignoreBooleanCoercion, ignoreConditionalTests, ignoreMixedLogicalExpressions, ignorePrimitives, ignoreTernaryTests, },]) {
const parserServices = (0, util_1.getParserServices)(context);
const compilerOptions = parserServices.program.getCompilerOptions();
const checker = parserServices.program.getTypeChecker();
const isStrictNullChecks = tsutils.isStrictCompilerOptionEnabled(compilerOptions, 'strictNullChecks');
if (!isStrictNullChecks &&
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing !== true) {
context.report({
loc: {
start: { column: 0, line: 0 },
end: { column: 0, line: 0 },
},
messageId: 'noStrictNullCheck',
});
}
// todo: rename to something more specific?
function checkAssignmentOrLogicalExpression(node, description, equals) {
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);
const type = checker.getTypeAtLocation(tsNode.left);
if (!(0, util_1.isTypeFlagSet)(type, ts.TypeFlags.Null | ts.TypeFlags.Undefined)) {
return;
}
if (ignoreConditionalTests === true && isConditionalTest(node)) {
return;
}
if (ignoreMixedLogicalExpressions === true &&
isMixedLogicalExpression(node)) {
return;
}
// https://github.com/typescript-eslint/typescript-eslint/issues/5439
/* eslint-disable @typescript-eslint/no-non-null-assertion */
const ignorableFlags = [
(ignorePrimitives === true || ignorePrimitives.bigint) &&
ts.TypeFlags.BigIntLike,
(ignorePrimitives === true || ignorePrimitives.boolean) &&
ts.TypeFlags.BooleanLike,
(ignorePrimitives === true || ignorePrimitives.number) &&
ts.TypeFlags.NumberLike,
(ignorePrimitives === true || ignorePrimitives.string) &&
ts.TypeFlags.StringLike,
]
.filter((flag) => typeof flag === 'number')
.reduce((previous, flag) => previous | flag, 0);
if (type.flags !== ts.TypeFlags.Null &&
type.flags !== ts.TypeFlags.Undefined &&
type.types.some(t => tsutils
.intersectionTypeParts(t)
.some(t => tsutils.isTypeFlagSet(t, ignorableFlags)))) {
return;
}
/* eslint-enable @typescript-eslint/no-non-null-assertion */
const barBarOperator = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(node.left, token => token.type === utils_1.AST_TOKEN_TYPES.Punctuator &&
token.value === node.operator), util_1.NullThrowsReasons.MissingToken('operator', node.type));
function* fix(fixer) {
if ((0, util_1.isLogicalOrOperator)(node.parent)) {
// '&&' and '??' operations cannot be mixed without parentheses (e.g. a && b ?? c)
if (node.left.type === utils_1.AST_NODE_TYPES.LogicalExpression &&
!(0, util_1.isLogicalOrOperator)(node.left.left)) {
yield fixer.insertTextBefore(node.left.right, '(');
}
else {
yield fixer.insertTextBefore(node.left, '(');
}
yield fixer.insertTextAfter(node.right, ')');
}
yield fixer.replaceText(barBarOperator, node.operator.replace('||', '??'));
}
context.report({
node: barBarOperator,
messageId: 'preferNullishOverOr',
data: { description, equals },
suggest: [
{
messageId: 'suggestNullish',
data: { equals },
fix,
},
],
});
}
return {
'AssignmentExpression[operator = "||="]'(node) {
checkAssignmentOrLogicalExpression(node, 'assignment', '=');
},
ConditionalExpression(node) {
if (ignoreTernaryTests) {
return;
}
let operator;
let nodesInsideTestExpression = [];
if (node.test.type === utils_1.AST_NODE_TYPES.BinaryExpression) {
nodesInsideTestExpression = [node.test.left, node.test.right];
if (node.test.operator === '==' ||
node.test.operator === '!=' ||
node.test.operator === '===' ||
node.test.operator === '!==') {
operator = node.test.operator;
}
}
else if (node.test.type === utils_1.AST_NODE_TYPES.LogicalExpression &&
node.test.left.type === utils_1.AST_NODE_TYPES.BinaryExpression &&
node.test.right.type === utils_1.AST_NODE_TYPES.BinaryExpression) {
nodesInsideTestExpression = [
node.test.left.left,
node.test.left.right,
node.test.right.left,
node.test.right.right,
];
if (['||', '||='].includes(node.test.operator)) {
if (node.test.left.operator === '===' &&
node.test.right.operator === '===') {
operator = '===';
}
else if (((node.test.left.operator === '===' ||
node.test.right.operator === '===') &&
(node.test.left.operator === '==' ||
node.test.right.operator === '==')) ||
(node.test.left.operator === '==' &&
node.test.right.operator === '==')) {
operator = '==';
}
}
else if (node.test.operator === '&&') {
if (node.test.left.operator === '!==' &&
node.test.right.operator === '!==') {
operator = '!==';
}
else if (((node.test.left.operator === '!==' ||
node.test.right.operator === '!==') &&
(node.test.left.operator === '!=' ||
node.test.right.operator === '!=')) ||
(node.test.left.operator === '!=' &&
node.test.right.operator === '!=')) {
operator = '!=';
}
}
}
if (!operator) {
return;
}
let identifier;
let hasUndefinedCheck = false;
let hasNullCheck = false;
// we check that the test only contains null, undefined and the identifier
for (const testNode of nodesInsideTestExpression) {
if ((0, util_1.isNullLiteral)(testNode)) {
hasNullCheck = true;
}
else if ((0, util_1.isUndefinedIdentifier)(testNode)) {
hasUndefinedCheck = true;
}
else if ((operator === '!==' || operator === '!=') &&
(0, util_1.isNodeEqual)(testNode, node.consequent)) {
identifier = testNode;
}
else if ((operator === '===' || operator === '==') &&
(0, util_1.isNodeEqual)(testNode, node.alternate)) {
identifier = testNode;
}
else {
return;
}
}
if (!identifier) {
return;
}
const isFixable = (() => {
// it is fixable if we check for both null and undefined, or not if neither
if (hasUndefinedCheck === hasNullCheck) {
return hasUndefinedCheck;
}
// it is fixable if we loosely check for either null or undefined
if (operator === '==' || operator === '!=') {
return true;
}
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(identifier);
const type = checker.getTypeAtLocation(tsNode);
const flags = (0, util_1.getTypeFlags)(type);
if (flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) {
return false;
}
const hasNullType = (flags & ts.TypeFlags.Null) !== 0;
// it is fixable if we check for undefined and the type is not nullable
if (hasUndefinedCheck && !hasNullType) {
return true;
}
const hasUndefinedType = (flags & ts.TypeFlags.Undefined) !== 0;
// it is fixable if we check for null and the type can't be undefined
return hasNullCheck && !hasUndefinedType;
})();
if (isFixable) {
context.report({
node,
messageId: 'preferNullishOverTernary',
// TODO: also account for = in the ternary clause
data: { equals: '' },
suggest: [
{
messageId: 'suggestNullish',
data: { equals: '' },
fix(fixer) {
const [left, right] = operator === '===' || operator === '=='
? [node.alternate, node.consequent]
: [node.consequent, node.alternate];
return fixer.replaceText(node, `${(0, util_1.getTextWithParentheses)(context.sourceCode, left)} ?? ${(0, util_1.getTextWithParentheses)(context.sourceCode, right)}`);
},
},
],
});
}
},
'LogicalExpression[operator = "||"]'(node) {
if (ignoreBooleanCoercion === true &&
isBooleanConstructorContext(node, context)) {
return;
}
checkAssignmentOrLogicalExpression(node, 'or', '');
},
};
},
});
function isConditionalTest(node) {
const parent = node.parent;
if (parent == null) {
return false;
}
if (parent.type === utils_1.AST_NODE_TYPES.LogicalExpression) {
return isConditionalTest(parent);
}
if (parent.type === utils_1.AST_NODE_TYPES.ConditionalExpression &&
(parent.consequent === node || parent.alternate === node)) {
return isConditionalTest(parent);
}
if (parent.type === utils_1.AST_NODE_TYPES.SequenceExpression &&
parent.expressions.at(-1) === node) {
return isConditionalTest(parent);
}
if ((parent.type === utils_1.AST_NODE_TYPES.ConditionalExpression ||
parent.type === utils_1.AST_NODE_TYPES.DoWhileStatement ||
parent.type === utils_1.AST_NODE_TYPES.IfStatement ||
parent.type === utils_1.AST_NODE_TYPES.ForStatement ||
parent.type === utils_1.AST_NODE_TYPES.WhileStatement) &&
parent.test === node) {
return true;
}
return false;
}
function isBooleanConstructorContext(node, context) {
const parent = node.parent;
if (parent == null) {
return false;
}
if (parent.type === utils_1.AST_NODE_TYPES.LogicalExpression) {
return isBooleanConstructorContext(parent, context);
}
if (parent.type === utils_1.AST_NODE_TYPES.ConditionalExpression &&
(parent.consequent === node || parent.alternate === node)) {
return isBooleanConstructorContext(parent, context);
}
if (parent.type === utils_1.AST_NODE_TYPES.SequenceExpression &&
parent.expressions.at(-1) === node) {
return isBooleanConstructorContext(parent, context);
}
return isBuiltInBooleanCall(parent, context);
}
function isBuiltInBooleanCall(node, context) {
if (node.type === utils_1.AST_NODE_TYPES.CallExpression &&
node.callee.type === utils_1.AST_NODE_TYPES.Identifier &&
// eslint-disable-next-line @typescript-eslint/internal/prefer-ast-types-enum
node.callee.name === 'Boolean' &&
node.arguments[0]) {
const scope = context.sourceCode.getScope(node);
const variable = scope.set.get(utils_1.AST_TOKEN_TYPES.Boolean);
return variable == null || variable.defs.length === 0;
}
return false;
}
function isMixedLogicalExpression(node) {
const seen = new Set();
const queue = [node.parent, node.left, node.right];
for (const current of queue) {
if (seen.has(current)) {
continue;
}
seen.add(current);
if (current.type === utils_1.AST_NODE_TYPES.LogicalExpression) {
if (current.operator === '&&') {
return true;
}
else if (['||', '||='].includes(current.operator)) {
// check the pieces of the node to catch cases like `a || b || c && d`
queue.push(current.parent, current.left, current.right);
}
}
}
return false;
}
//# sourceMappingURL=prefer-nullish-coalescing.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,457 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.analyzeChain = analyzeChain;
const utils_1 = require("@typescript-eslint/utils");
const ts_api_utils_1 = require("ts-api-utils");
const ts = __importStar(require("typescript"));
const util_1 = require("../../util");
const checkNullishAndReport_1 = require("./checkNullishAndReport");
const compareNodes_1 = require("./compareNodes");
function includesType(parserServices, node, typeFlagIn) {
const typeFlag = typeFlagIn | ts.TypeFlags.Any | ts.TypeFlags.Unknown;
const types = (0, ts_api_utils_1.unionTypeParts)(parserServices.getTypeAtLocation(node));
for (const type of types) {
if ((0, util_1.isTypeFlagSet)(type, typeFlag)) {
return true;
}
}
return false;
}
const analyzeAndChainOperand = (parserServices, operand, index, chain) => {
switch (operand.comparisonType) {
case "Boolean" /* NullishComparisonType.Boolean */: {
const nextOperand = chain.at(index + 1);
if (nextOperand?.comparisonType ===
"NotStrictEqualNull" /* NullishComparisonType.NotStrictEqualNull */ &&
operand.comparedName.type === utils_1.AST_NODE_TYPES.Identifier) {
return null;
}
return [operand];
}
case "NotEqualNullOrUndefined" /* NullishComparisonType.NotEqualNullOrUndefined */:
return [operand];
case "NotStrictEqualNull" /* NullishComparisonType.NotStrictEqualNull */: {
// handle `x !== null && x !== undefined`
const nextOperand = chain.at(index + 1);
if (nextOperand?.comparisonType ===
"NotStrictEqualUndefined" /* NullishComparisonType.NotStrictEqualUndefined */ &&
(0, compareNodes_1.compareNodes)(operand.comparedName, nextOperand.comparedName) ===
"Equal" /* NodeComparisonResult.Equal */) {
return [operand, nextOperand];
}
if (includesType(parserServices, operand.comparedName, ts.TypeFlags.Undefined)) {
// we know the next operand is not an `undefined` check and that this
// operand includes `undefined` - which means that making this an
// optional chain would change the runtime behavior of the expression
return null;
}
return [operand];
}
case "NotStrictEqualUndefined" /* NullishComparisonType.NotStrictEqualUndefined */: {
// handle `x !== undefined && x !== null`
const nextOperand = chain.at(index + 1);
if (nextOperand?.comparisonType ===
"NotStrictEqualNull" /* NullishComparisonType.NotStrictEqualNull */ &&
(0, compareNodes_1.compareNodes)(operand.comparedName, nextOperand.comparedName) ===
"Equal" /* NodeComparisonResult.Equal */) {
return [operand, nextOperand];
}
if (includesType(parserServices, operand.comparedName, ts.TypeFlags.Null)) {
// we know the next operand is not a `null` check and that this
// operand includes `null` - which means that making this an
// optional chain would change the runtime behavior of the expression
return null;
}
return [operand];
}
default:
return null;
}
};
const analyzeOrChainOperand = (parserServices, operand, index, chain) => {
switch (operand.comparisonType) {
case "NotBoolean" /* NullishComparisonType.NotBoolean */:
case "EqualNullOrUndefined" /* NullishComparisonType.EqualNullOrUndefined */:
return [operand];
case "StrictEqualNull" /* NullishComparisonType.StrictEqualNull */: {
// handle `x === null || x === undefined`
const nextOperand = chain.at(index + 1);
if (nextOperand?.comparisonType ===
"StrictEqualUndefined" /* NullishComparisonType.StrictEqualUndefined */ &&
(0, compareNodes_1.compareNodes)(operand.comparedName, nextOperand.comparedName) ===
"Equal" /* NodeComparisonResult.Equal */) {
return [operand, nextOperand];
}
if (includesType(parserServices, operand.comparedName, ts.TypeFlags.Undefined)) {
// we know the next operand is not an `undefined` check and that this
// operand includes `undefined` - which means that making this an
// optional chain would change the runtime behavior of the expression
return null;
}
return [operand];
}
case "StrictEqualUndefined" /* NullishComparisonType.StrictEqualUndefined */: {
// handle `x === undefined || x === null`
const nextOperand = chain.at(index + 1);
if (nextOperand?.comparisonType === "StrictEqualNull" /* NullishComparisonType.StrictEqualNull */ &&
(0, compareNodes_1.compareNodes)(operand.comparedName, nextOperand.comparedName) ===
"Equal" /* NodeComparisonResult.Equal */) {
return [operand, nextOperand];
}
if (includesType(parserServices, operand.comparedName, ts.TypeFlags.Null)) {
// we know the next operand is not a `null` check and that this
// operand includes `null` - which means that making this an
// optional chain would change the runtime behavior of the expression
return null;
}
return [operand];
}
default:
return null;
}
};
/**
* Returns the range that needs to be reported from the chain.
* @param chain The chain of logical expressions.
* @param boundary The boundary range that the range to report cannot fall outside.
* @param sourceCode The source code to get tokens.
* @returns The range to report.
*/
function getReportRange(chain, boundary, sourceCode) {
const leftNode = chain[0].node;
const rightNode = chain[chain.length - 1].node;
let leftMost = (0, util_1.nullThrows)(sourceCode.getFirstToken(leftNode), util_1.NullThrowsReasons.MissingToken('any token', leftNode.type));
let rightMost = (0, util_1.nullThrows)(sourceCode.getLastToken(rightNode), util_1.NullThrowsReasons.MissingToken('any token', rightNode.type));
while (leftMost.range[0] > boundary[0]) {
const token = sourceCode.getTokenBefore(leftMost);
if (!token || !(0, util_1.isOpeningParenToken)(token) || token.range[0] < boundary[0]) {
break;
}
leftMost = token;
}
while (rightMost.range[1] < boundary[1]) {
const token = sourceCode.getTokenAfter(rightMost);
if (!token || !(0, util_1.isClosingParenToken)(token) || token.range[1] > boundary[1]) {
break;
}
rightMost = token;
}
return [leftMost.range[0], rightMost.range[1]];
}
function getReportDescriptor(sourceCode, parserServices, node, operator, options, chain) {
const lastOperand = chain[chain.length - 1];
let useSuggestionFixer;
if (options.allowPotentiallyUnsafeFixesThatModifyTheReturnTypeIKnowWhatImDoing ===
true) {
// user has opted-in to the unsafe behavior
useSuggestionFixer = false;
}
// optional chain specifically will union `undefined` into the final type
// so we need to make sure that there is at least one operand that includes
// `undefined`, or else we're going to change the final type - which is
// unsafe and might cause downstream type errors.
else if (lastOperand.comparisonType === "EqualNullOrUndefined" /* NullishComparisonType.EqualNullOrUndefined */ ||
lastOperand.comparisonType ===
"NotEqualNullOrUndefined" /* NullishComparisonType.NotEqualNullOrUndefined */ ||
lastOperand.comparisonType === "StrictEqualUndefined" /* NullishComparisonType.StrictEqualUndefined */ ||
lastOperand.comparisonType ===
"NotStrictEqualUndefined" /* NullishComparisonType.NotStrictEqualUndefined */ ||
(operator === '||' &&
lastOperand.comparisonType === "NotBoolean" /* NullishComparisonType.NotBoolean */)) {
// we know the last operand is an equality check - so the change in types
// DOES NOT matter and will not change the runtime result or cause a type
// check error
useSuggestionFixer = false;
}
else {
useSuggestionFixer = true;
for (const operand of chain) {
if (includesType(parserServices, operand.node, ts.TypeFlags.Undefined)) {
useSuggestionFixer = false;
break;
}
}
// TODO - we could further reduce the false-positive rate of this check by
// checking for cases where the change in types don't matter like
// the test location of an if/while/etc statement.
// but it's quite complex to do this without false-negatives, so
// for now we'll just be over-eager with our matching.
//
// it's MUCH better to false-positive here and only provide a
// suggestion fixer, rather than false-negative and autofix to
// broken code.
}
// In its most naive form we could just slap `?.` for every single part of the
// chain. However this would be undesirable because it'd create unnecessary
// conditions in the user's code where there were none before - and it would
// cause errors with rules like our `no-unnecessary-condition`.
//
// Instead we want to include the minimum number of `?.` required to correctly
// unify the code into a single chain. Naively you might think that we can
// just take the final operand add `?.` after the locations from the previous
// operands - however this won't be correct either because earlier operands
// can include a necessary `?.` that's not needed or included in a later
// operand.
//
// So instead what we need to do is to start at the first operand and
// iteratively diff it against the next operand, and add the difference to the
// first operand.
//
// eg
// `foo && foo.bar && foo.bar.baz?.bam && foo.bar.baz.bam()`
// 1) `foo`
// 2) diff(`foo`, `foo.bar`) = `.bar`
// 3) result = `foo?.bar`
// 4) diff(`foo.bar`, `foo.bar.baz?.bam`) = `.baz?.bam`
// 5) result = `foo?.bar?.baz?.bam`
// 6) diff(`foo.bar.baz?.bam`, `foo.bar.baz.bam()`) = `()`
// 7) result = `foo?.bar?.baz?.bam?.()`
const parts = [];
for (const current of chain) {
const nextOperand = flattenChainExpression(sourceCode, current.comparedName);
const diff = nextOperand.slice(parts.length);
if (diff.length > 0) {
if (parts.length > 0) {
// we need to make the first operand of the diff optional so it matches the
// logic before merging
// foo.bar && foo.bar.baz
// diff = .baz
// result = foo.bar?.baz
diff[0].optional = true;
}
parts.push(...diff);
}
}
let newCode = parts
.map(part => {
let str = '';
if (part.optional) {
str += '?.';
}
else {
if (part.nonNull) {
str += '!';
}
if (part.requiresDot) {
str += '.';
}
}
if (part.precedence !== util_1.OperatorPrecedence.Invalid &&
part.precedence < util_1.OperatorPrecedence.Member) {
str += `(${part.text})`;
}
else {
str += part.text;
}
return str;
})
.join('');
if (lastOperand.node.type === utils_1.AST_NODE_TYPES.BinaryExpression) {
// retain the ending comparison for cases like
// x && x.a != null
// x && typeof x.a !== 'undefined'
const operator = lastOperand.node.operator;
const { left, right } = (() => {
if (lastOperand.isYoda) {
const unaryOperator = lastOperand.node.right.type === utils_1.AST_NODE_TYPES.UnaryExpression
? `${lastOperand.node.right.operator} `
: '';
return {
left: sourceCode.getText(lastOperand.node.left),
right: unaryOperator + newCode,
};
}
const unaryOperator = lastOperand.node.left.type === utils_1.AST_NODE_TYPES.UnaryExpression
? `${lastOperand.node.left.operator} `
: '';
return {
left: unaryOperator + newCode,
right: sourceCode.getText(lastOperand.node.right),
};
})();
newCode = `${left} ${operator} ${right}`;
}
else if (lastOperand.comparisonType === "NotBoolean" /* NullishComparisonType.NotBoolean */) {
newCode = `!${newCode}`;
}
const reportRange = getReportRange(chain, node.range, sourceCode);
const fix = fixer => fixer.replaceTextRange(reportRange, newCode);
return {
loc: {
end: sourceCode.getLocFromIndex(reportRange[1]),
start: sourceCode.getLocFromIndex(reportRange[0]),
},
messageId: 'preferOptionalChain',
...(0, util_1.getFixOrSuggest)({
fixOrSuggest: useSuggestionFixer ? 'suggest' : 'fix',
suggestion: {
fix,
messageId: 'optionalChainSuggest',
},
}),
};
function flattenChainExpression(sourceCode, node) {
switch (node.type) {
case utils_1.AST_NODE_TYPES.ChainExpression:
return flattenChainExpression(sourceCode, node.expression);
case utils_1.AST_NODE_TYPES.CallExpression: {
const argumentsText = (() => {
const closingParenToken = (0, util_1.nullThrows)(sourceCode.getLastToken(node), util_1.NullThrowsReasons.MissingToken('closing parenthesis', node.type));
const openingParenToken = (0, util_1.nullThrows)(sourceCode.getFirstTokenBetween(node.typeArguments ?? node.callee, closingParenToken, util_1.isOpeningParenToken), util_1.NullThrowsReasons.MissingToken('opening parenthesis', node.type));
return sourceCode.text.substring(openingParenToken.range[0], closingParenToken.range[1]);
})();
const typeArgumentsText = (() => {
if (node.typeArguments == null) {
return '';
}
return sourceCode.getText(node.typeArguments);
})();
return [
...flattenChainExpression(sourceCode, node.callee),
{
nonNull: false,
optional: node.optional,
// no precedence for this
precedence: util_1.OperatorPrecedence.Invalid,
requiresDot: false,
text: typeArgumentsText + argumentsText,
},
];
}
case utils_1.AST_NODE_TYPES.MemberExpression: {
const propertyText = sourceCode.getText(node.property);
return [
...flattenChainExpression(sourceCode, node.object),
{
nonNull: node.object.type === utils_1.AST_NODE_TYPES.TSNonNullExpression,
optional: node.optional,
precedence: node.computed
? // computed is already wrapped in [] so no need to wrap in () as well
util_1.OperatorPrecedence.Invalid
: (0, util_1.getOperatorPrecedenceForNode)(node.property),
requiresDot: !node.computed,
text: node.computed ? `[${propertyText}]` : propertyText,
},
];
}
case utils_1.AST_NODE_TYPES.TSNonNullExpression:
return flattenChainExpression(sourceCode, node.expression);
default:
return [
{
nonNull: false,
optional: false,
precedence: (0, util_1.getOperatorPrecedenceForNode)(node),
requiresDot: false,
text: sourceCode.getText(node),
},
];
}
}
}
function analyzeChain(context, parserServices, options, node, operator, chain) {
// need at least 2 operands in a chain for it to be a chain
if (chain.length <= 1 ||
/* istanbul ignore next -- previous checks make this unreachable, but keep it for exhaustiveness check */
operator === '??') {
return;
}
const analyzeOperand = (() => {
switch (operator) {
case '&&':
return analyzeAndChainOperand;
case '||':
return analyzeOrChainOperand;
}
})();
// Things like x !== null && x !== undefined have two nodes, but they are
// one logical unit here, so we'll allow them to be grouped.
let subChain = [];
const maybeReportThenReset = (newChainSeed) => {
if (subChain.length > 1) {
const subChainFlat = subChain.flat();
(0, checkNullishAndReport_1.checkNullishAndReport)(context, parserServices, options, subChainFlat.slice(0, -1).map(({ node }) => node), getReportDescriptor(context.sourceCode, parserServices, node, operator, options, subChainFlat));
}
// we've reached the end of a chain of logical expressions
// i.e. the current operand doesn't belong to the previous chain.
//
// we don't want to throw away the current operand otherwise we will skip it
// and that can cause us to miss chains. So instead we seed the new chain
// with the current operand
//
// eg this means we can catch cases like:
// unrelated != null && foo != null && foo.bar != null;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ first "chain"
// ^^^^^^^^^^^ newChainSeed
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ second chain
subChain = newChainSeed ? [newChainSeed] : [];
};
for (let i = 0; i < chain.length; i += 1) {
const lastOperand = subChain.flat().at(-1);
const operand = chain[i];
const validatedOperands = analyzeOperand(parserServices, operand, i, chain);
if (!validatedOperands) {
// TODO - #7170
// check if the name is a superset/equal - if it is, then it likely
// intended to be part of the chain and something we should include in the
// report, eg
// foo == null || foo.bar;
// ^^^^^^^^^^^ valid OR chain
// ^^^^^^^ invalid OR chain logical, but still part of
// the chain for combination purposes
maybeReportThenReset();
continue;
}
// in case multiple operands were consumed - make sure to correctly increment the index
i += validatedOperands.length - 1;
const currentOperand = validatedOperands[0];
if (lastOperand) {
const comparisonResult = (0, compareNodes_1.compareNodes)(lastOperand.comparedName,
// purposely inspect and push the last operand because the prior operands don't matter
// this also means we won't false-positive in cases like
// foo !== null && foo !== undefined
validatedOperands[validatedOperands.length - 1].comparedName);
if (comparisonResult === "Subset" /* NodeComparisonResult.Subset */) {
// the operands are comparable, so we can continue searching
subChain.push(currentOperand);
}
else if (comparisonResult === "Invalid" /* NodeComparisonResult.Invalid */) {
maybeReportThenReset(validatedOperands);
}
else {
// purposely don't push this case because the node is a no-op and if
// we consider it then we might report on things like
// foo && foo
}
}
else {
subChain.push(currentOperand);
}
}
// check the leftovers
maybeReportThenReset();
}
//# sourceMappingURL=analyzeChain.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,366 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const tsutils = __importStar(require("ts-api-utils"));
const ts = __importStar(require("typescript"));
const util_1 = require("../util");
const getOperatorPrecedence_1 = require("../util/getOperatorPrecedence");
exports.default = (0, util_1.createRule)({
name: 'return-await',
meta: {
type: 'problem',
docs: {
description: 'Enforce consistent awaiting of returned promises',
extendsBaseRule: 'no-return-await',
recommended: {
strict: ['error-handling-correctness-only'],
},
requiresTypeChecking: true,
},
fixable: 'code',
// eslint-disable-next-line eslint-plugin/require-meta-has-suggestions -- suggestions are exposed through a helper.
hasSuggestions: true,
messages: {
disallowedPromiseAwait: 'Returning an awaited promise is not allowed in this context.',
disallowedPromiseAwaitSuggestion: 'Remove `await` before the expression. Use caution as this may impact control flow.',
nonPromiseAwait: 'Returning an awaited value that is not a promise is not allowed.',
requiredPromiseAwait: 'Returning an awaited promise is required in this context.',
requiredPromiseAwaitSuggestion: 'Add `await` before the expression. Use caution as this may impact control flow.',
},
schema: [
{
type: 'string',
oneOf: [
{
type: 'string',
description: 'Requires that all returned promises be awaited.',
enum: ['always'],
},
{
type: 'string',
description: 'In error-handling contexts, the rule enforces that returned promises must be awaited. In ordinary contexts, the rule does not enforce any particular behavior around whether returned promises are awaited.',
enum: ['error-handling-correctness-only'],
},
{
type: 'string',
description: 'In error-handling contexts, the rule enforces that returned promises must be awaited. In ordinary contexts, the rule enforces that returned promises _must not_ be awaited.',
enum: ['in-try-catch'],
},
{
type: 'string',
description: 'Disallows awaiting any returned promises.',
enum: ['never'],
},
],
},
],
},
defaultOptions: ['in-try-catch'],
create(context, [option]) {
const services = (0, util_1.getParserServices)(context);
const checker = services.program.getTypeChecker();
const scopeInfoStack = [];
function enterFunction(node) {
scopeInfoStack.push({
hasAsync: node.async,
owningFunc: node,
});
}
function exitFunction() {
scopeInfoStack.pop();
}
function affectsExplicitResourceManagement(node) {
// just need to determine if there is a `using` declaration in scope.
let scope = context.sourceCode.getScope(node);
const functionScope = scope.variableScope;
while (true) {
for (const variable of scope.variables) {
if (variable.defs.length !== 1) {
// This can't be the case for `using` or `await using` since it's
// an error to redeclare those more than once in the same scope,
// unlike, say, `var` declarations.
continue;
}
const declaration = variable.defs[0];
const declaratorNode = declaration.node;
const declarationNode = declaratorNode.parent;
// if it's a using/await using declaration, and it comes _before_ the
// node we're checking, it affects control flow for that node.
if (['await using', 'using'].includes(declarationNode.kind) &&
declaratorNode.range[1] < node.range[0]) {
return true;
}
}
if (scope === functionScope) {
// We've checked all the relevant scopes
break;
}
// This should always exist, since the rule should only be checking
// contexts in which `return` statements are legal, which should always
// be inside a function.
scope = (0, util_1.nullThrows)(scope.upper, 'Expected parent scope to exist. return-await should only operate on return statements within functions');
}
return false;
}
/**
* Tests whether a node is inside of an explicit error handling context
* (try/catch/finally) in a way that throwing an exception will have an
* impact on the program's control flow.
*/
function affectsExplicitErrorHandling(node) {
// If an error-handling block is followed by another error-handling block,
// control flow is affected by whether promises in it are awaited or not.
// Otherwise, we need to check recursively for nested try statements until
// we get to the top level of a function or the program. If by then,
// there's no offending error-handling blocks, it doesn't affect control
// flow.
const tryAncestorResult = findContainingTryStatement(node);
if (tryAncestorResult == null) {
return false;
}
const { block, tryStatement } = tryAncestorResult;
switch (block) {
case 'catch':
// Exceptions thrown in catch blocks followed by a finally block affect
// control flow.
if (tryStatement.finallyBlock != null) {
return true;
}
// Otherwise recurse.
return affectsExplicitErrorHandling(tryStatement);
case 'finally':
return affectsExplicitErrorHandling(tryStatement);
case 'try':
// Try blocks are always followed by either a catch or finally,
// so exceptions thrown here always affect control flow.
return true;
default: {
const __never = block;
throw new Error(`Unexpected block type: ${String(__never)}`);
}
}
}
/**
* A try _statement_ is the whole thing that encompasses try block,
* catch clause, and finally block. This function finds the nearest
* enclosing try statement (if present) for a given node, and reports which
* part of the try statement the node is in.
*/
function findContainingTryStatement(node) {
let child = node;
let ancestor = node.parent;
while (ancestor && !ts.isFunctionLike(ancestor)) {
if (ts.isTryStatement(ancestor)) {
let block;
if (child === ancestor.tryBlock) {
block = 'try';
}
else if (child === ancestor.catchClause) {
block = 'catch';
}
else if (child === ancestor.finallyBlock) {
block = 'finally';
}
return {
block: (0, util_1.nullThrows)(block, 'Child of a try statement must be a try block, catch clause, or finally block'),
tryStatement: ancestor,
};
}
child = ancestor;
ancestor = ancestor.parent;
}
return undefined;
}
function removeAwait(fixer, node) {
// Should always be an await node; but let's be safe.
/* istanbul ignore if */ if (!(0, util_1.isAwaitExpression)(node)) {
return null;
}
const awaitToken = context.sourceCode.getFirstToken(node, util_1.isAwaitKeyword);
// Should always be the case; but let's be safe.
/* istanbul ignore if */ if (!awaitToken) {
return null;
}
const startAt = awaitToken.range[0];
let endAt = awaitToken.range[1];
// Also remove any extraneous whitespace after `await`, if there is any.
const nextToken = context.sourceCode.getTokenAfter(awaitToken, {
includeComments: true,
});
if (nextToken) {
endAt = nextToken.range[0];
}
return fixer.removeRange([startAt, endAt]);
}
function insertAwait(fixer, node, isHighPrecendence) {
if (isHighPrecendence) {
return fixer.insertTextBefore(node, 'await ');
}
return [
fixer.insertTextBefore(node, 'await ('),
fixer.insertTextAfter(node, ')'),
];
}
function isHigherPrecedenceThanAwait(node) {
const operator = ts.isBinaryExpression(node)
? node.operatorToken.kind
: ts.SyntaxKind.Unknown;
const nodePrecedence = (0, getOperatorPrecedence_1.getOperatorPrecedence)(node.kind, operator);
const awaitPrecedence = (0, getOperatorPrecedence_1.getOperatorPrecedence)(ts.SyntaxKind.AwaitExpression, ts.SyntaxKind.Unknown);
return nodePrecedence > awaitPrecedence;
}
function test(node, expression) {
let child;
const isAwait = ts.isAwaitExpression(expression);
if (isAwait) {
child = expression.getChildAt(1);
}
else {
child = expression;
}
const type = checker.getTypeAtLocation(child);
const isThenable = tsutils.isThenableType(checker, expression, type);
// handle awaited _non_thenables
if (!isThenable) {
if (isAwait) {
// any/unknown could be thenable; do not enforce whether they are `await`ed.
if ((0, util_1.isTypeAnyType)(type) || (0, util_1.isTypeUnknownType)(type)) {
return;
}
context.report({
node,
messageId: 'nonPromiseAwait',
fix: fixer => removeAwait(fixer, node),
});
}
return;
}
// At this point it's definitely a thenable.
const affectsErrorHandling = affectsExplicitErrorHandling(expression) ||
affectsExplicitResourceManagement(node);
const useAutoFix = !affectsErrorHandling;
const ruleConfiguration = getConfiguration(option);
const shouldAwaitInCurrentContext = affectsErrorHandling
? ruleConfiguration.errorHandlingContext
: ruleConfiguration.ordinaryContext;
switch (shouldAwaitInCurrentContext) {
case 'await':
if (!isAwait) {
context.report({
node,
messageId: 'requiredPromiseAwait',
...(0, util_1.getFixOrSuggest)({
fixOrSuggest: useAutoFix ? 'fix' : 'suggest',
suggestion: {
messageId: 'requiredPromiseAwaitSuggestion',
fix: fixer => insertAwait(fixer, node, isHigherPrecedenceThanAwait(expression)),
},
}),
});
}
break;
case "don't-care":
break;
case 'no-await':
if (isAwait) {
context.report({
node,
messageId: 'disallowedPromiseAwait',
...(0, util_1.getFixOrSuggest)({
fixOrSuggest: useAutoFix ? 'fix' : 'suggest',
suggestion: {
messageId: 'disallowedPromiseAwaitSuggestion',
fix: fixer => removeAwait(fixer, node),
},
}),
});
}
break;
}
}
function findPossiblyReturnedNodes(node) {
if (node.type === utils_1.AST_NODE_TYPES.ConditionalExpression) {
return [
...findPossiblyReturnedNodes(node.alternate),
...findPossiblyReturnedNodes(node.consequent),
];
}
return [node];
}
return {
ArrowFunctionExpression: enterFunction,
'ArrowFunctionExpression:exit': exitFunction,
FunctionDeclaration: enterFunction,
'FunctionDeclaration:exit': exitFunction,
FunctionExpression: enterFunction,
'FunctionExpression:exit': exitFunction,
// executes after less specific handler, so exitFunction is called
'ArrowFunctionExpression[async = true]:exit'(node) {
if (node.body.type !== utils_1.AST_NODE_TYPES.BlockStatement) {
findPossiblyReturnedNodes(node.body).forEach(node => {
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
test(node, tsNode);
});
}
},
ReturnStatement(node) {
const scopeInfo = scopeInfoStack.at(-1);
if (!scopeInfo?.hasAsync || !node.argument) {
return;
}
findPossiblyReturnedNodes(node.argument).forEach(node => {
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
test(node, tsNode);
});
},
};
},
});
function getConfiguration(option) {
switch (option) {
case 'always':
return {
errorHandlingContext: 'await',
ordinaryContext: 'await',
};
case 'error-handling-correctness-only':
return {
errorHandlingContext: 'await',
ordinaryContext: "don't-care",
};
case 'in-try-catch':
return {
errorHandlingContext: 'await',
ordinaryContext: 'no-await',
};
case 'never':
return {
errorHandlingContext: 'no-await',
ordinaryContext: 'no-await',
};
}
}
//# sourceMappingURL=return-await.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,259 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const tsutils = __importStar(require("ts-api-utils"));
const ts = __importStar(require("typescript"));
const util_1 = require("../util");
exports.default = (0, util_1.createRule)({
name: 'switch-exhaustiveness-check',
meta: {
type: 'suggestion',
docs: {
description: 'Require switch-case statements to be exhaustive',
requiresTypeChecking: true,
},
hasSuggestions: true,
messages: {
addMissingCases: 'Add branches for missing cases.',
dangerousDefaultCase: 'The switch statement is exhaustive, so the default case is unnecessary.',
switchIsNotExhaustive: 'Switch is not exhaustive. Cases not matched: {{missingBranches}}',
},
schema: [
{
type: 'object',
additionalProperties: false,
properties: {
allowDefaultCaseForExhaustiveSwitch: {
type: 'boolean',
description: `If 'true', allow 'default' cases on switch statements with exhaustive cases.`,
},
considerDefaultExhaustiveForUnions: {
type: 'boolean',
description: `If 'true', the 'default' clause is used to determine whether the switch statement is exhaustive for union type`,
},
requireDefaultForNonUnion: {
type: 'boolean',
description: `If 'true', require a 'default' clause for switches on non-union types.`,
},
},
},
],
},
defaultOptions: [
{
allowDefaultCaseForExhaustiveSwitch: true,
considerDefaultExhaustiveForUnions: false,
requireDefaultForNonUnion: false,
},
],
create(context, [{ allowDefaultCaseForExhaustiveSwitch, considerDefaultExhaustiveForUnions, requireDefaultForNonUnion, },]) {
const services = (0, util_1.getParserServices)(context);
const checker = services.program.getTypeChecker();
const compilerOptions = services.program.getCompilerOptions();
function getSwitchMetadata(node) {
const defaultCase = node.cases.find(switchCase => switchCase.test == null);
const discriminantType = (0, util_1.getConstrainedTypeAtLocation)(services, node.discriminant);
const symbolName = discriminantType.getSymbol()?.escapedName;
const containsNonLiteralType = doesTypeContainNonLiteralType(discriminantType);
const caseTypes = new Set();
for (const switchCase of node.cases) {
// If the `test` property of the switch case is `null`, then we are on a
// `default` case.
if (switchCase.test == null) {
continue;
}
const caseType = (0, util_1.getConstrainedTypeAtLocation)(services, switchCase.test);
caseTypes.add(caseType);
}
const missingLiteralBranchTypes = [];
for (const unionPart of tsutils.unionTypeParts(discriminantType)) {
for (const intersectionPart of tsutils.intersectionTypeParts(unionPart)) {
if (caseTypes.has(intersectionPart) ||
!isTypeLiteralLikeType(intersectionPart)) {
continue;
}
// "missing", "optional" and "undefined" types are different runtime objects,
// but all of them have TypeFlags.Undefined type flag
if ([...caseTypes].some(tsutils.isIntrinsicUndefinedType) &&
tsutils.isIntrinsicUndefinedType(intersectionPart)) {
continue;
}
missingLiteralBranchTypes.push(intersectionPart);
}
}
return {
containsNonLiteralType,
defaultCase,
missingLiteralBranchTypes,
symbolName,
};
}
function checkSwitchExhaustive(node, switchMetadata) {
const { defaultCase, missingLiteralBranchTypes, symbolName } = switchMetadata;
// If considerDefaultExhaustiveForUnions is enabled, the presence of a default case
// always makes the switch exhaustive.
if (considerDefaultExhaustiveForUnions && defaultCase != null) {
return;
}
if (missingLiteralBranchTypes.length > 0) {
context.report({
node: node.discriminant,
messageId: 'switchIsNotExhaustive',
data: {
missingBranches: missingLiteralBranchTypes
.map(missingType => tsutils.isTypeFlagSet(missingType, ts.TypeFlags.ESSymbolLike)
? `typeof ${missingType.getSymbol()?.escapedName}`
: checker.typeToString(missingType))
.join(' | '),
},
suggest: [
{
messageId: 'addMissingCases',
fix(fixer) {
return fixSwitch(fixer, node, missingLiteralBranchTypes, symbolName?.toString());
},
},
],
});
}
}
function fixSwitch(fixer, node, missingBranchTypes, // null means default branch
symbolName) {
const lastCase = node.cases.length > 0 ? node.cases[node.cases.length - 1] : null;
const defaultCase = node.cases.find(caseEl => caseEl.test == null);
const caseIndent = lastCase
? ' '.repeat(lastCase.loc.start.column)
: // If there are no cases, use indentation of the switch statement and
// leave it to the user to format it correctly.
' '.repeat(node.loc.start.column);
const missingCases = [];
for (const missingBranchType of missingBranchTypes) {
if (missingBranchType == null) {
missingCases.push(`default: { throw new Error('default case') }`);
continue;
}
const missingBranchName = missingBranchType.getSymbol()?.escapedName;
let caseTest = tsutils.isTypeFlagSet(missingBranchType, ts.TypeFlags.ESSymbolLike)
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
missingBranchName
: checker.typeToString(missingBranchType);
if (symbolName &&
(missingBranchName || missingBranchName === '') &&
(0, util_1.requiresQuoting)(missingBranchName.toString(), compilerOptions.target)) {
const escapedBranchName = missingBranchName
.replaceAll("'", "\\'")
.replaceAll('\n', '\\n')
.replaceAll('\r', '\\r');
caseTest = `${symbolName}['${escapedBranchName}']`;
}
missingCases.push(`case ${caseTest}: { throw new Error('Not implemented yet: ${caseTest
.replaceAll('\\', '\\\\')
.replaceAll("'", "\\'")} case') }`);
}
const fixString = missingCases
.map(code => `${caseIndent}${code}`)
.join('\n');
if (lastCase) {
if (defaultCase) {
const beforeFixString = missingCases
.map(code => `${code}\n${caseIndent}`)
.join('');
return fixer.insertTextBefore(defaultCase, beforeFixString);
}
return fixer.insertTextAfter(lastCase, `\n${fixString}`);
}
// There were no existing cases.
const openingBrace = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(node.discriminant, util_1.isOpeningBraceToken), util_1.NullThrowsReasons.MissingToken('{', 'discriminant'));
const closingBrace = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(node.discriminant, util_1.isClosingBraceToken), util_1.NullThrowsReasons.MissingToken('}', 'discriminant'));
return fixer.replaceTextRange([openingBrace.range[0], closingBrace.range[1]], ['{', fixString, `${caseIndent}}`].join('\n'));
}
function checkSwitchUnnecessaryDefaultCase(switchMetadata) {
if (allowDefaultCaseForExhaustiveSwitch) {
return;
}
const { containsNonLiteralType, defaultCase, missingLiteralBranchTypes } = switchMetadata;
if (missingLiteralBranchTypes.length === 0 &&
defaultCase !== undefined &&
!containsNonLiteralType) {
context.report({
node: defaultCase,
messageId: 'dangerousDefaultCase',
});
}
}
function checkSwitchNoUnionDefaultCase(node, switchMetadata) {
if (!requireDefaultForNonUnion) {
return;
}
const { containsNonLiteralType, defaultCase } = switchMetadata;
if (containsNonLiteralType && defaultCase === undefined) {
context.report({
node: node.discriminant,
messageId: 'switchIsNotExhaustive',
data: { missingBranches: 'default' },
suggest: [
{
messageId: 'addMissingCases',
fix(fixer) {
return fixSwitch(fixer, node, [null]);
},
},
],
});
}
}
return {
SwitchStatement(node) {
const switchMetadata = getSwitchMetadata(node);
checkSwitchExhaustive(node, switchMetadata);
checkSwitchUnnecessaryDefaultCase(switchMetadata);
checkSwitchNoUnionDefaultCase(node, switchMetadata);
},
};
},
});
function isTypeLiteralLikeType(type) {
return tsutils.isTypeFlagSet(type, ts.TypeFlags.Literal |
ts.TypeFlags.Undefined |
ts.TypeFlags.Null |
ts.TypeFlags.UniqueESSymbol);
}
/**
* For example:
*
* - `"foo" | "bar"` is a type with all literal types.
* - `"foo" | number` is a type that contains non-literal types.
* - `"foo" & { bar: 1 }` is a type that contains non-literal types.
*
* Default cases are never superfluous in switches with non-literal types.
*/
function doesTypeContainNonLiteralType(type) {
return tsutils
.unionTypeParts(type)
.some(type => tsutils
.intersectionTypeParts(type)
.every(subType => !isTypeLiteralLikeType(subType)));
}
//# sourceMappingURL=switch-exhaustiveness-check.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getFixOrSuggest = getFixOrSuggest;
function getFixOrSuggest({ fixOrSuggest, suggestion, }) {
switch (fixOrSuggest) {
case 'fix':
return { fix: suggestion.fix };
case 'none':
return undefined;
case 'suggest':
return { suggest: [suggestion] };
}
}
//# sourceMappingURL=getFixOrSuggest.js.map
@@ -0,0 +1 @@
{"version":3,"file":"getFixOrSuggest.js","sourceRoot":"","sources":["../../src/util/getFixOrSuggest.ts"],"names":[],"mappings":";;AAEA,0CAkBC;AAlBD,SAAgB,eAAe,CAA2B,EACxD,YAAY,EACZ,UAAU,GAIX;IAIC,QAAQ,YAAY,EAAE,CAAC;QACrB,KAAK,KAAK;YACR,OAAO,EAAE,GAAG,EAAE,UAAU,CAAC,GAAG,EAAE,CAAC;QACjC,KAAK,MAAM;YACT,OAAO,SAAS,CAAC;QACnB,KAAK,SAAS;YACZ,OAAO,EAAE,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;IACrC,CAAC;AACH,CAAC"}
@@ -0,0 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getParentFunctionNode = getParentFunctionNode;
const utils_1 = require("@typescript-eslint/utils");
function getParentFunctionNode(node) {
let current = node.parent;
while (current) {
if (current.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
current.type === utils_1.AST_NODE_TYPES.FunctionDeclaration ||
current.type === utils_1.AST_NODE_TYPES.FunctionExpression) {
return current;
}
current = current.parent;
}
// this shouldn't happen in correct code, but someone may attempt to parse bad code
// the parser won't error, so we shouldn't throw here
/* istanbul ignore next */ return null;
}
//# sourceMappingURL=getParentFunctionNode.js.map
@@ -0,0 +1 @@
{"version":3,"file":"getParentFunctionNode.js","sourceRoot":"","sources":["../../src/util/getParentFunctionNode.ts"],"names":[],"mappings":";;AAIA,sDAuBC;AAzBD,oDAA0D;AAE1D,SAAgB,qBAAqB,CACnC,IAAmB;IAMnB,IAAI,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;IAC1B,OAAO,OAAO,EAAE,CAAC;QACf,IACE,OAAO,CAAC,IAAI,KAAK,sBAAc,CAAC,uBAAuB;YACvD,OAAO,CAAC,IAAI,KAAK,sBAAc,CAAC,mBAAmB;YACnD,OAAO,CAAC,IAAI,KAAK,sBAAc,CAAC,kBAAkB,EAClD,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED,mFAAmF;IACnF,qDAAqD;IACrD,0BAA0B,CAAC,OAAO,IAAI,CAAC;AACzC,CAAC"}
@@ -0,0 +1,184 @@
---
description: 'Disallow awaiting a value that is not a Thenable.'
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
> 🛑 This file is source code, not the primary documentation location! 🛑
>
> See **https://typescript-eslint.io/rules/await-thenable** for documentation.
A "Thenable" value is an object which has a `then` method, such as a Promise.
The [`await` keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await) is generally used to retrieve the result of calling a Thenable's `then` method.
If the `await` keyword is used on a value that is not a Thenable, the value is directly resolved, but will still pause execution until the next microtask.
While doing so is valid JavaScript, it is often a programmer error, such as forgetting to add parenthesis to call a function that returns a Promise.
## Examples
<Tabs>
<TabItem value="❌ Incorrect">
```ts
await 'value';
const createValue = () => 'value';
await createValue();
```
</TabItem>
<TabItem value="✅ Correct">
```ts
await Promise.resolve('value');
const createValue = async () => 'value';
await createValue();
```
</TabItem>
</Tabs>
## Async Iteration (`for await...of` Loops)
This rule also inspects [`for await...of` statements](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of), and reports if the value being iterated over is not async-iterable.
:::info[Why does the rule report on `for await...of` loops used on an array of Promises?]
While `for await...of` can be used with synchronous iterables, and it will await each promise produced by the iterable, it is inadvisable to do so.
There are some tiny nuances that you may want to consider.
The biggest difference between using `for await...of` and using `for...of` (apart from awaiting each result yourself) is error handling.
When an error occurs within the loop body, `for await...of` does _not_ close the original sync iterable, while `for...of` does.
For detailed examples of this, see the [MDN documentation on using `for await...of` with sync-iterables](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of#iterating_over_sync_iterables_and_generators).
Also consider whether you need sequential awaiting at all. Using `for await...of` may obscure potential opportunities for concurrent processing, such as those reported by [`no-await-in-loop`](https://eslint.org/docs/latest/rules/no-await-in-loop). Consider instead using one of the [promise concurrency methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#promise_concurrency) for better performance.
:::
### Examples
<Tabs>
<TabItem value="❌ Incorrect">
```ts
async function syncIterable() {
const arrayOfValues = [1, 2, 3];
for await (const value of arrayOfValues) {
console.log(value);
}
}
async function syncIterableOfPromises() {
const arrayOfPromises = [
Promise.resolve(1),
Promise.resolve(2),
Promise.resolve(3),
];
for await (const promisedValue of arrayOfPromises) {
console.log(promisedValue);
}
}
```
</TabItem>
<TabItem value="✅ Correct">
```ts
async function syncIterable() {
const arrayOfValues = [1, 2, 3];
for (const value of arrayOfValues) {
console.log(value);
}
}
async function syncIterableOfPromises() {
const arrayOfPromises = [
Promise.resolve(1),
Promise.resolve(2),
Promise.resolve(3),
];
for (const promisedValue of await Promise.all(arrayOfPromises)) {
console.log(promisedValue);
}
}
async function validUseOfForAwaitOnAsyncIterable() {
async function* yieldThingsAsynchronously() {
yield 1;
await new Promise(resolve => setTimeout(resolve, 1000));
yield 2;
}
for await (const promisedValue of yieldThingsAsynchronously()) {
console.log(promisedValue);
}
}
```
</TabItem>
</Tabs>
## Explicit Resource Management (`await using` Statements)
This rule also inspects [`await using` statements](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#using-declarations-and-explicit-resource-management).
If the disposable being used is not async-disposable, an `await using` statement is unnecessary.
### Examples
<Tabs>
<TabItem value="❌ Incorrect">
```ts
function makeSyncDisposable(): Disposable {
return {
[Symbol.dispose](): void {
// Dispose of the resource
},
};
}
async function shouldNotAwait() {
await using resource = makeSyncDisposable();
}
```
</TabItem>
<TabItem value="✅ Correct">
```ts
function makeSyncDisposable(): Disposable {
return {
[Symbol.dispose](): void {
// Dispose of the resource
},
};
}
async function shouldNotAwait() {
using resource = makeSyncDisposable();
}
function makeAsyncDisposable(): AsyncDisposable {
return {
async [Symbol.asyncDispose](): Promise<void> {
// Dispose of the resource asynchronously
},
};
}
async function shouldAwait() {
await using resource = makeAsyncDisposable();
}
```
</TabItem>
</Tabs>
## When Not To Use It
If you want to allow code to `await` non-Promise values.
For example, if your framework is in transition from one style of asynchronous code to another, it may be useful to include `await`s unnecessarily.
This is generally not preferred but can sometimes be useful for visual consistency.
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule.
@@ -0,0 +1,154 @@
---
description: 'Require expressions of type void to appear in statement position.'
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
> 🛑 This file is source code, not the primary documentation location! 🛑
>
> See **https://typescript-eslint.io/rules/no-confusing-void-expression** for documentation.
`void` in TypeScript refers to a function return that is meant to be ignored.
Attempting to use a `void`-typed value, such as storing the result of a called function in a variable, is often a sign of a programmer error.
`void` can also be misleading for other developers even if used correctly.
This rule prevents `void` type expressions from being used in misleading locations such as being assigned to a variable, provided as a function argument, or returned from a function.
## Examples
<Tabs>
<TabItem value="❌ Incorrect">
```ts
// somebody forgot that `alert` doesn't return anything
const response = alert('Are you sure?');
console.log(alert('Are you sure?'));
// it's not obvious whether the chained promise will contain the response (fixable)
promise.then(value => window.postMessage(value));
// it looks like we are returning the result of `console.error` (fixable)
function doSomething() {
if (!somethingToDo) {
return console.error('Nothing to do!');
}
console.log('Doing a thing...');
}
```
</TabItem>
<TabItem value="✅ Correct">
```ts
// just a regular void function in a statement position
alert('Hello, world!');
// this function returns a boolean value so it's ok
const response = confirm('Are you sure?');
console.log(confirm('Are you sure?'));
// now it's obvious that `postMessage` doesn't return any response
promise.then(value => {
window.postMessage(value);
});
// now it's explicit that we want to log the error and return early
function doSomething() {
if (!somethingToDo) {
console.error('Nothing to do!');
return;
}
console.log('Doing a thing...');
}
// using logical expressions for their side effects is fine
cond && console.log('true');
cond || console.error('false');
cond ? console.log('true') : console.error('false');
```
</TabItem>
</Tabs>
## Options
### `ignoreArrowShorthand`
{/* insert option description */}
Whether to ignore "shorthand" `() =>` arrow functions: those without `{ ... }` braces.
It might be undesirable to wrap every arrow function shorthand expression.
Especially when using the Prettier formatter, which spreads such code across 3 lines instead of 1.
Examples of additional **correct** code with this option enabled:
```ts option='{ "ignoreArrowShorthand": true }' showPlaygroundButton
promise.then(value => window.postMessage(value));
```
### `ignoreVoidOperator`
{/* insert option description */}
Whether to ignore returns that start with the `void` operator.
It might be preferable to only use some distinct syntax
to explicitly mark the confusing but valid usage of void expressions.
This option allows void expressions which are explicitly wrapped in the `void` operator.
This can help avoid confusion among other developers as long as they are made aware of this code style.
This option also changes the automatic fixes for common cases to use the `void` operator.
It also enables a suggestion fix to wrap the void expression with `void` operator for every problem reported.
Examples of additional **correct** code with this option enabled:
```ts option='{ "ignoreVoidOperator": true }' showPlaygroundButton
// now it's obvious that we don't expect any response
promise.then(value => void window.postMessage(value));
// now it's explicit that we don't want to return anything
function doSomething() {
if (!somethingToDo) {
return void console.error('Nothing to do!');
}
console.log('Doing a thing...');
}
// we are sure that we want to always log `undefined`
console.log(void alert('Hello, world!'));
```
### `ignoreVoidReturningFunctions`
{/* insert option description */}
Whether to ignore returns from functions with `void` return types when inside a function with a `void` return type.
Some projects prefer allowing functions that explicitly return `void` to return `void` expressions. Doing so allows more writing more succinct functions.
:::note
This is technically risky as the `void`-returning function might actually be returning a value not seen by the type system.
:::
```ts option='{ "ignoreVoidReturningFunctions": true }' showPlaygroundButton
function foo(): void {
return console.log();
}
function onError(callback: () => void): void {
callback();
}
onError(() => console.log('oops'));
```
## When Not To Use It
The return type of a function can be inspected by going to its definition or hovering over it in an IDE.
If you don't care about being explicit about the void type in actual code then don't use this rule.
Also, if you strongly prefer a concise coding style more strongly than any fear of `void`-related bugs then you can avoid this rule.
@@ -0,0 +1,144 @@
---
description: 'Disallow throwing non-`Error` values as exceptions.'
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
> 🛑 This file is source code, not the primary documentation location! 🛑
>
> See **https://typescript-eslint.io/rules/only-throw-error** for documentation.
It is considered good practice to only `throw` the `Error` object itself or an object using the `Error` object as base objects for user-defined exceptions.
The fundamental benefit of `Error` objects is that they automatically keep track of where they were built and originated.
This rule restricts what can be thrown as an exception.
:::info[Migration from `no-throw-literal`]
This rule was formerly known as `no-throw-literal`.
The new name is a drop-in replacement with identical functionality.
:::
## Examples
This rule is aimed at maintaining consistency when throwing exception by disallowing to throw literals and other expressions which cannot possibly be an `Error` object.
<Tabs>
<TabItem value="❌ Incorrect">
```ts
throw 'error';
throw 0;
throw undefined;
throw null;
const err = new Error();
throw 'an ' + err;
const err = new Error();
throw `${err}`;
const err = '';
throw err;
function getError() {
return '';
}
throw getError();
const foo = {
bar: '',
};
throw foo.bar;
```
</TabItem>
<TabItem value="✅ Correct">
```ts
throw new Error();
throw new Error('error');
const e = new Error('error');
throw e;
try {
throw new Error('error');
} catch (e) {
throw e;
}
const err = new Error();
throw err;
function getError() {
return new Error();
}
throw getError();
const foo = {
bar: new Error(),
};
throw foo.bar;
class CustomError extends Error {
// ...
}
throw new CustomError();
```
</TabItem>
</Tabs>
## Options
This rule adds the following options:
```ts
interface Options {
/**
* Type specifiers that can be thrown.
*/
allow?: (
| {
from: 'file';
name: [string, ...string[]] | string;
path?: string;
}
| {
from: 'lib';
name: [string, ...string[]] | string;
}
| {
from: 'package';
name: [string, ...string[]] | string;
package: string;
}
| string
)[];
/**
* Whether to always allow throwing values typed as `any`.
*/
allowThrowingAny?: boolean;
/**
* Whether to always allow throwing values typed as `unknown`.
*/
allowThrowingUnknown?: boolean;
}
const defaultOptions: Options = {
allow: [],
allowThrowingAny: true,
allowThrowingUnknown: true,
};
```
{/* Intentionally Omitted: When Not To Use It */}
@@ -0,0 +1,222 @@
---
description: 'Enforce using the nullish coalescing operator instead of logical assignments or chaining.'
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
> 🛑 This file is source code, not the primary documentation location! 🛑
>
> See **https://typescript-eslint.io/rules/prefer-nullish-coalescing** for documentation.
The `??` nullish coalescing runtime operator allows providing a default value when dealing with `null` or `undefined`.
Because the nullish coalescing operator _only_ coalesces when the original value is `null` or `undefined`, it is much safer than relying upon logical OR operator chaining `||`, which coalesces on any _falsy_ value.
This rule reports when you may consider replacing:
- An `||` operator with `??`
- An `||=` operator with `??=`
:::caution
This rule will not work as expected if [`strictNullChecks`](https://www.typescriptlang.org/tsconfig#strictNullChecks) is not enabled.
:::
## Options
### `ignoreTernaryTests`
{/* insert option description */}
Incorrect code for `ignoreTernaryTests: false`, and correct code for `ignoreTernaryTests: true`:
```ts option='{ "ignoreTernaryTests": false }' showPlaygroundButton
const foo: any = 'bar';
foo !== undefined && foo !== null ? foo : 'a string';
foo === undefined || foo === null ? 'a string' : foo;
foo == undefined ? 'a string' : foo;
foo == null ? 'a string' : foo;
const foo: string | undefined = 'bar';
foo !== undefined ? foo : 'a string';
foo === undefined ? 'a string' : foo;
const foo: string | null = 'bar';
foo !== null ? foo : 'a string';
foo === null ? 'a string' : foo;
```
Correct code for `ignoreTernaryTests: false`:
```ts option='{ "ignoreTernaryTests": false }' showPlaygroundButton
const foo: any = 'bar';
foo ?? 'a string';
foo ?? 'a string';
foo ?? 'a string';
foo ?? 'a string';
const foo: string | undefined = 'bar';
foo ?? 'a string';
foo ?? 'a string';
const foo: string | null = 'bar';
foo ?? 'a string';
foo ?? 'a string';
```
### `ignoreConditionalTests`
{/* insert option description */}
Generally expressions within conditional tests intentionally use the falsy fallthrough behavior of the logical or operator, meaning that fixing the operator to the nullish coalesce operator could cause bugs.
If you're looking to enforce stricter conditional tests, you should consider using the `strict-boolean-expressions` rule.
Incorrect code for `ignoreConditionalTests: false`, and correct code for `ignoreConditionalTests: true`:
```ts option='{ "ignoreConditionalTests": false }' showPlaygroundButton
declare const a: string | null;
declare const b: string | null;
if (a || b) {
}
if ((a ||= b)) {
}
while (a || b) {}
while ((a ||= b)) {}
do {} while (a || b);
for (let i = 0; a || b; i += 1) {}
a || b ? true : false;
```
Correct code for `ignoreConditionalTests: false`:
```ts option='{ "ignoreConditionalTests": false }' showPlaygroundButton
declare const a: string | null;
declare const b: string | null;
if (a ?? b) {
}
if ((a ??= b)) {
}
while (a ?? b) {}
while ((a ??= b)) {}
do {} while (a ?? b);
for (let i = 0; a ?? b; i += 1) {}
a ?? b ? true : false;
```
### `ignoreMixedLogicalExpressions`
{/* insert option description */}
Generally expressions within mixed logical expressions intentionally use the falsy fallthrough behavior of the logical or operator, meaning that fixing the operator to the nullish coalesce operator could cause bugs.
If you're looking to enforce stricter conditional tests, you should consider using the `strict-boolean-expressions` rule.
Incorrect code for `ignoreMixedLogicalExpressions: false`, and correct code for `ignoreMixedLogicalExpressions: true`:
```ts option='{ "ignoreMixedLogicalExpressions": false }' showPlaygroundButton
declare const a: string | null;
declare const b: string | null;
declare const c: string | null;
declare const d: string | null;
a || (b && c);
a ||= b && c;
(a && b) || c || d;
a || (b && c) || d;
a || (b && c && d);
```
Correct code for `ignoreMixedLogicalExpressions: false`:
```ts option='{ "ignoreMixedLogicalExpressions": false }' showPlaygroundButton
declare const a: string | null;
declare const b: string | null;
declare const c: string | null;
declare const d: string | null;
a ?? (b && c);
a ??= b && c;
(a && b) ?? c ?? d;
a ?? (b && c) ?? d;
a ?? (b && c && d);
```
**_NOTE:_** Errors for this specific case will be presented as suggestions (see below), instead of fixes. This is because it is not always safe to automatically convert `||` to `??` within a mixed logical expression, as we cannot tell the intended precedence of the operator. Note that by design, `??` requires parentheses when used with `&&` or `||` in the same expression.
### `ignorePrimitives`
{/* insert option description */}
If you would like to ignore expressions containing operands of certain primitive types that can be falsy then you may pass an object containing a boolean value for each primitive:
- `string: true`, ignores `null` or `undefined` unions with `string` (default: false).
- `number: true`, ignores `null` or `undefined` unions with `number` (default: false).
- `bigint: true`, ignores `null` or `undefined` unions with `bigint` (default: false).
- `boolean: true`, ignores `null` or `undefined` unions with `boolean` (default: false).
Incorrect code for `ignorePrimitives: { string: false }`, and correct code for `ignorePrimitives: { string: true }`:
```ts option='{ "ignorePrimitives": { "string": true } }' showPlaygroundButton
const foo: string | undefined = 'bar';
foo || 'a string';
```
Correct code for both `ignorePrimitives: { string: false }` and `ignorePrimitives: { string: true }`:
```ts option='{ "ignorePrimitives": { "string": true } }' showPlaygroundButton
const foo: string | undefined = 'bar';
foo ?? 'a string';
```
Also, if you would like to ignore all primitives types, you can set `ignorePrimitives: true`. It is equivalent to `ignorePrimitives: { string: true, number: true, bigint: true, boolean: true }`.
### `ignoreBooleanCoercion`
{/* insert option description */}
Whether to ignore expressions that coerce a value into a boolean: `Boolean(...)`.
Incorrect code for `ignoreBooleanCoercion: false`, and correct code for `ignoreBooleanCoercion: true`:
```ts option='{ "ignoreBooleanCoercion": true }' showPlaygroundButton
let a: string | true | undefined;
let b: string | boolean | undefined;
const x = Boolean(a || b);
```
Correct code for `ignoreBooleanCoercion: false`:
```ts option='{ "ignoreBooleanCoercion": false }' showPlaygroundButton
let a: string | true | undefined;
let b: string | boolean | undefined;
const x = Boolean(a ?? b);
```
### `allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing`
{/* insert option description */}
:::danger Deprecated
> This option will be removed in the next major version of typescript-eslint.
> :::
> Unless this is set to `true`, the rule will error on every file whose `tsconfig.json` does _not_ have the `strictNullChecks` compiler option (or `strict`) set to `true`.
Without `strictNullChecks`, TypeScript essentially erases `undefined` and `null` from the types. This means when this rule inspects the types from a variable, **it will not be able to tell that the variable might be `null` or `undefined`**, which essentially makes this rule useless.
You should be using `strictNullChecks` to ensure complete type-safety in your codebase.
If for some reason you cannot turn on `strictNullChecks`, but still want to use this rule - you can use this option to allow it - but know that the behavior of this rule is _undefined_ with the compiler option turned off. We will not accept bug reports if you are using this option.
## When Not To Use It
If you are not using TypeScript 3.7 (or greater), then you will not be able to use this rule, as the operator is not supported.
## Further Reading
- [TypeScript 3.7 Release Notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html)
- [Nullish Coalescing Operator Proposal](https://github.com/tc39/proposal-nullish-coalescing/)
@@ -0,0 +1,5 @@
declare const config: (style: 'glob' | 'minimatch') => {
files: string[];
rules: Record<string, 'error' | 'off' | 'warn'>;
};
export = config;
+112
View File
@@ -0,0 +1,112 @@
{
"name": "@typescript-eslint/eslint-plugin",
"version": "8.14.0",
"description": "TypeScript plugin for ESLint",
"files": [
"dist",
"docs",
"eslint-recommended-raw.d.ts",
"index.d.ts",
"rules.d.ts",
"package.json",
"README.md",
"LICENSE"
],
"type": "commonjs",
"exports": {
".": {
"types": "./index.d.ts",
"default": "./dist/index.js"
},
"./package.json": "./package.json",
"./use-at-your-own-risk/rules": {
"types": "./rules.d.ts",
"default": "./dist/rules/index.js"
},
"./use-at-your-own-risk/eslint-recommended-raw": {
"types": "./eslint-recommended-raw.d.ts",
"default": "./dist/configs/eslint-recommended-raw.js"
}
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"repository": {
"type": "git",
"url": "https://github.com/typescript-eslint/typescript-eslint.git",
"directory": "packages/eslint-plugin"
},
"bugs": {
"url": "https://github.com/typescript-eslint/typescript-eslint/issues"
},
"homepage": "https://typescript-eslint.io/packages/eslint-plugin",
"license": "MIT",
"keywords": [
"eslint",
"eslintplugin",
"eslint-plugin",
"typescript"
],
"scripts": {
"build": "tsc -b tsconfig.build.json",
"clean": "tsc -b tsconfig.build.json --clean",
"postclean": "rimraf dist && rimraf coverage",
"format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore",
"generate:breaking-changes": "tsx tools/generate-breaking-changes.mts",
"generate:configs": "npx nx generate-configs repo",
"lint": "npx nx lint",
"test": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" jest --coverage --logHeapUsage",
"test-single": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" jest --no-coverage",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.14.0",
"@typescript-eslint/type-utils": "8.14.0",
"@typescript-eslint/utils": "8.14.0",
"@typescript-eslint/visitor-keys": "8.14.0",
"graphemer": "^1.4.0",
"ignore": "^5.3.1",
"natural-compare": "^1.4.0",
"ts-api-utils": "^1.3.0"
},
"devDependencies": {
"@jest/types": "29.6.3",
"@types/marked": "^5.0.2",
"@types/mdast": "^4.0.3",
"@types/natural-compare": "*",
"@typescript-eslint/rule-schema-to-typescript-types": "8.14.0",
"@typescript-eslint/rule-tester": "8.14.0",
"ajv": "^6.12.6",
"cross-env": "^7.0.3",
"cross-fetch": "*",
"eslint": "^9.13.0",
"jest": "29.7.0",
"jest-specific-snapshot": "^8.0.0",
"json-schema": "*",
"markdown-table": "^3.0.3",
"marked": "^5.1.2",
"mdast-util-from-markdown": "^2.0.0",
"mdast-util-mdx": "^3.0.0",
"micromark-extension-mdxjs": "^3.0.0",
"prettier": "^3.2.5",
"rimraf": "*",
"title-case": "^3.0.3",
"tsx": "*",
"typescript": "*",
"unist-util-visit": "^5.0.0"
},
"peerDependencies": {
"@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
"eslint": "^8.57.0 || ^9.0.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
}
+87
View File
@@ -0,0 +1,87 @@
{
"name": "@typescript-eslint/parser",
"version": "8.14.0",
"description": "An ESLint custom parser which leverages TypeScript ESTree",
"files": [
"dist",
"_ts4.3",
"README.md",
"LICENSE"
],
"type": "commonjs",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./package.json": "./package.json"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"repository": {
"type": "git",
"url": "https://github.com/typescript-eslint/typescript-eslint.git",
"directory": "packages/parser"
},
"bugs": {
"url": "https://github.com/typescript-eslint/typescript-eslint/issues"
},
"homepage": "https://typescript-eslint.io/packages/parser",
"license": "BSD-2-Clause",
"keywords": [
"ast",
"ecmascript",
"javascript",
"typescript",
"parser",
"syntax",
"eslint"
],
"scripts": {
"build": "tsc -b tsconfig.build.json",
"postbuild": "downlevel-dts dist _ts4.3/dist --to=4.3",
"clean": "tsc -b tsconfig.build.json --clean",
"postclean": "rimraf dist && rimraf _ts4.3 && rimraf coverage",
"format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore",
"lint": "npx nx lint",
"test": "jest --coverage",
"typecheck": "tsc --noEmit"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0"
},
"dependencies": {
"@typescript-eslint/scope-manager": "8.14.0",
"@typescript-eslint/types": "8.14.0",
"@typescript-eslint/typescript-estree": "8.14.0",
"@typescript-eslint/visitor-keys": "8.14.0",
"debug": "^4.3.4"
},
"devDependencies": {
"@jest/types": "29.6.3",
"@types/glob": "*",
"downlevel-dts": "*",
"glob": "*",
"jest": "29.7.0",
"prettier": "^3.2.5",
"rimraf": "*",
"typescript": "*"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"typesVersions": {
"<4.7": {
"*": [
"_ts4.3/*"
]
}
}
}
+32
View File
@@ -0,0 +1,32 @@
"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.es2015_core = void 0;
const base_config_1 = require("./base-config");
exports.es2015_core = {
Array: base_config_1.TYPE,
ArrayConstructor: base_config_1.TYPE,
DateConstructor: base_config_1.TYPE,
Float32Array: base_config_1.TYPE,
Float64Array: base_config_1.TYPE,
Function: base_config_1.TYPE,
Int8Array: base_config_1.TYPE,
Int16Array: base_config_1.TYPE,
Int32Array: base_config_1.TYPE,
Math: base_config_1.TYPE,
NumberConstructor: base_config_1.TYPE,
ObjectConstructor: base_config_1.TYPE,
ReadonlyArray: base_config_1.TYPE,
RegExp: base_config_1.TYPE,
RegExpConstructor: base_config_1.TYPE,
String: base_config_1.TYPE,
StringConstructor: base_config_1.TYPE,
Uint8Array: base_config_1.TYPE,
Uint8ClampedArray: base_config_1.TYPE,
Uint16Array: base_config_1.TYPE,
Uint32Array: base_config_1.TYPE,
};
//# sourceMappingURL=es2015.core.js.map
@@ -0,0 +1 @@
{"version":3,"file":"es2015.core.js","sourceRoot":"","sources":["../../src/lib/es2015.core.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,gCAAgC;AAChC,mEAAmE;AACnE,2BAA2B;;;AAI3B,+CAAqC;AAExB,QAAA,WAAW,GAAG;IACzB,KAAK,EAAE,kBAAI;IACX,gBAAgB,EAAE,kBAAI;IACtB,eAAe,EAAE,kBAAI;IACrB,YAAY,EAAE,kBAAI;IAClB,YAAY,EAAE,kBAAI;IAClB,QAAQ,EAAE,kBAAI;IACd,SAAS,EAAE,kBAAI;IACf,UAAU,EAAE,kBAAI;IAChB,UAAU,EAAE,kBAAI;IAChB,IAAI,EAAE,kBAAI;IACV,iBAAiB,EAAE,kBAAI;IACvB,iBAAiB,EAAE,kBAAI;IACvB,aAAa,EAAE,kBAAI;IACnB,MAAM,EAAE,kBAAI;IACZ,iBAAiB,EAAE,kBAAI;IACvB,MAAM,EAAE,kBAAI;IACZ,iBAAiB,EAAE,kBAAI;IACvB,UAAU,EAAE,kBAAI;IAChB,iBAAiB,EAAE,kBAAI;IACvB,WAAW,EAAE,kBAAI;IACjB,WAAW,EAAE,kBAAI;CAC4B,CAAC"}
@@ -0,0 +1,61 @@
"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.es2015_iterable = void 0;
const base_config_1 = require("./base-config");
const es2015_symbol_1 = require("./es2015.symbol");
exports.es2015_iterable = {
...es2015_symbol_1.es2015_symbol,
Array: base_config_1.TYPE,
ArrayConstructor: base_config_1.TYPE,
ArrayIterator: base_config_1.TYPE,
BuiltinIteratorReturn: base_config_1.TYPE,
Float32Array: base_config_1.TYPE,
Float32ArrayConstructor: base_config_1.TYPE,
Float64Array: base_config_1.TYPE,
Float64ArrayConstructor: base_config_1.TYPE,
IArguments: base_config_1.TYPE,
Int8Array: base_config_1.TYPE,
Int8ArrayConstructor: base_config_1.TYPE,
Int16Array: base_config_1.TYPE,
Int16ArrayConstructor: base_config_1.TYPE,
Int32Array: base_config_1.TYPE,
Int32ArrayConstructor: base_config_1.TYPE,
Iterable: base_config_1.TYPE,
IterableIterator: base_config_1.TYPE,
Iterator: base_config_1.TYPE,
IteratorObject: base_config_1.TYPE,
IteratorResult: base_config_1.TYPE,
IteratorReturnResult: base_config_1.TYPE,
IteratorYieldResult: base_config_1.TYPE,
Map: base_config_1.TYPE,
MapConstructor: base_config_1.TYPE,
MapIterator: base_config_1.TYPE,
Promise: base_config_1.TYPE,
PromiseConstructor: base_config_1.TYPE,
ReadonlyArray: base_config_1.TYPE,
ReadonlyMap: base_config_1.TYPE,
ReadonlySet: base_config_1.TYPE,
Set: base_config_1.TYPE,
SetConstructor: base_config_1.TYPE,
SetIterator: base_config_1.TYPE,
String: base_config_1.TYPE,
StringIterator: base_config_1.TYPE,
SymbolConstructor: base_config_1.TYPE,
Uint8Array: base_config_1.TYPE,
Uint8ArrayConstructor: base_config_1.TYPE,
Uint8ClampedArray: base_config_1.TYPE,
Uint8ClampedArrayConstructor: base_config_1.TYPE,
Uint16Array: base_config_1.TYPE,
Uint16ArrayConstructor: base_config_1.TYPE,
Uint32Array: base_config_1.TYPE,
Uint32ArrayConstructor: base_config_1.TYPE,
WeakMap: base_config_1.TYPE,
WeakMapConstructor: base_config_1.TYPE,
WeakSet: base_config_1.TYPE,
WeakSetConstructor: base_config_1.TYPE,
};
//# sourceMappingURL=es2015.iterable.js.map
@@ -0,0 +1 @@
{"version":3,"file":"es2015.iterable.js","sourceRoot":"","sources":["../../src/lib/es2015.iterable.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,gCAAgC;AAChC,mEAAmE;AACnE,2BAA2B;;;AAI3B,+CAAqC;AACrC,mDAAgD;AAEnC,QAAA,eAAe,GAAG;IAC7B,GAAG,6BAAa;IAChB,KAAK,EAAE,kBAAI;IACX,gBAAgB,EAAE,kBAAI;IACtB,aAAa,EAAE,kBAAI;IACnB,qBAAqB,EAAE,kBAAI;IAC3B,YAAY,EAAE,kBAAI;IAClB,uBAAuB,EAAE,kBAAI;IAC7B,YAAY,EAAE,kBAAI;IAClB,uBAAuB,EAAE,kBAAI;IAC7B,UAAU,EAAE,kBAAI;IAChB,SAAS,EAAE,kBAAI;IACf,oBAAoB,EAAE,kBAAI;IAC1B,UAAU,EAAE,kBAAI;IAChB,qBAAqB,EAAE,kBAAI;IAC3B,UAAU,EAAE,kBAAI;IAChB,qBAAqB,EAAE,kBAAI;IAC3B,QAAQ,EAAE,kBAAI;IACd,gBAAgB,EAAE,kBAAI;IACtB,QAAQ,EAAE,kBAAI;IACd,cAAc,EAAE,kBAAI;IACpB,cAAc,EAAE,kBAAI;IACpB,oBAAoB,EAAE,kBAAI;IAC1B,mBAAmB,EAAE,kBAAI;IACzB,GAAG,EAAE,kBAAI;IACT,cAAc,EAAE,kBAAI;IACpB,WAAW,EAAE,kBAAI;IACjB,OAAO,EAAE,kBAAI;IACb,kBAAkB,EAAE,kBAAI;IACxB,aAAa,EAAE,kBAAI;IACnB,WAAW,EAAE,kBAAI;IACjB,WAAW,EAAE,kBAAI;IACjB,GAAG,EAAE,kBAAI;IACT,cAAc,EAAE,kBAAI;IACpB,WAAW,EAAE,kBAAI;IACjB,MAAM,EAAE,kBAAI;IACZ,cAAc,EAAE,kBAAI;IACpB,iBAAiB,EAAE,kBAAI;IACvB,UAAU,EAAE,kBAAI;IAChB,qBAAqB,EAAE,kBAAI;IAC3B,iBAAiB,EAAE,kBAAI;IACvB,4BAA4B,EAAE,kBAAI;IAClC,WAAW,EAAE,kBAAI;IACjB,sBAAsB,EAAE,kBAAI;IAC5B,WAAW,EAAE,kBAAI;IACjB,sBAAsB,EAAE,kBAAI;IAC5B,OAAO,EAAE,kBAAI;IACb,kBAAkB,EAAE,kBAAI;IACxB,OAAO,EAAE,kBAAI;IACb,kBAAkB,EAAE,kBAAI;CACqB,CAAC"}
+30
View File
@@ -0,0 +1,30 @@
"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.es2015 = void 0;
const es5_1 = require("./es5");
const es2015_collection_1 = require("./es2015.collection");
const es2015_core_1 = require("./es2015.core");
const es2015_generator_1 = require("./es2015.generator");
const es2015_iterable_1 = require("./es2015.iterable");
const es2015_promise_1 = require("./es2015.promise");
const es2015_proxy_1 = require("./es2015.proxy");
const es2015_reflect_1 = require("./es2015.reflect");
const es2015_symbol_1 = require("./es2015.symbol");
const es2015_symbol_wellknown_1 = require("./es2015.symbol.wellknown");
exports.es2015 = {
...es5_1.es5,
...es2015_core_1.es2015_core,
...es2015_collection_1.es2015_collection,
...es2015_iterable_1.es2015_iterable,
...es2015_generator_1.es2015_generator,
...es2015_promise_1.es2015_promise,
...es2015_proxy_1.es2015_proxy,
...es2015_reflect_1.es2015_reflect,
...es2015_symbol_1.es2015_symbol,
...es2015_symbol_wellknown_1.es2015_symbol_wellknown,
};
//# sourceMappingURL=es2015.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"es2015.js","sourceRoot":"","sources":["../../src/lib/es2015.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,gCAAgC;AAChC,mEAAmE;AACnE,2BAA2B;;;AAI3B,+BAA4B;AAC5B,2DAAwD;AACxD,+CAA4C;AAC5C,yDAAsD;AACtD,uDAAoD;AACpD,qDAAkD;AAClD,iDAA8C;AAC9C,qDAAkD;AAClD,mDAAgD;AAChD,uEAAoE;AAEvD,QAAA,MAAM,GAAG;IACpB,GAAG,SAAG;IACN,GAAG,yBAAW;IACd,GAAG,qCAAiB;IACpB,GAAG,iCAAe;IAClB,GAAG,mCAAgB;IACnB,GAAG,+BAAc;IACjB,GAAG,2BAAY;IACf,GAAG,+BAAc;IACjB,GAAG,6BAAa;IAChB,GAAG,iDAAuB;CACmB,CAAC"}
@@ -0,0 +1,46 @@
"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.es2015_symbol_wellknown = void 0;
const base_config_1 = require("./base-config");
const es2015_symbol_1 = require("./es2015.symbol");
exports.es2015_symbol_wellknown = {
...es2015_symbol_1.es2015_symbol,
Array: base_config_1.TYPE,
ArrayBuffer: base_config_1.TYPE,
ArrayBufferConstructor: base_config_1.TYPE,
ArrayConstructor: base_config_1.TYPE,
DataView: base_config_1.TYPE,
Date: base_config_1.TYPE,
Float32Array: base_config_1.TYPE,
Float64Array: base_config_1.TYPE,
Function: base_config_1.TYPE,
GeneratorFunction: base_config_1.TYPE,
Int8Array: base_config_1.TYPE,
Int16Array: base_config_1.TYPE,
Int32Array: base_config_1.TYPE,
JSON: base_config_1.TYPE,
Map: base_config_1.TYPE,
MapConstructor: base_config_1.TYPE,
Math: base_config_1.TYPE,
Promise: base_config_1.TYPE,
PromiseConstructor: base_config_1.TYPE,
ReadonlyArray: base_config_1.TYPE,
RegExp: base_config_1.TYPE,
RegExpConstructor: base_config_1.TYPE,
Set: base_config_1.TYPE,
SetConstructor: base_config_1.TYPE,
String: base_config_1.TYPE,
Symbol: base_config_1.TYPE,
SymbolConstructor: base_config_1.TYPE,
Uint8Array: base_config_1.TYPE,
Uint8ClampedArray: base_config_1.TYPE,
Uint16Array: base_config_1.TYPE,
Uint32Array: base_config_1.TYPE,
WeakMap: base_config_1.TYPE,
WeakSet: base_config_1.TYPE,
};
//# sourceMappingURL=es2015.symbol.wellknown.js.map
@@ -0,0 +1 @@
{"version":3,"file":"es2015.symbol.wellknown.js","sourceRoot":"","sources":["../../src/lib/es2015.symbol.wellknown.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,gCAAgC;AAChC,mEAAmE;AACnE,2BAA2B;;;AAI3B,+CAAqC;AACrC,mDAAgD;AAEnC,QAAA,uBAAuB,GAAG;IACrC,GAAG,6BAAa;IAChB,KAAK,EAAE,kBAAI;IACX,WAAW,EAAE,kBAAI;IACjB,sBAAsB,EAAE,kBAAI;IAC5B,gBAAgB,EAAE,kBAAI;IACtB,QAAQ,EAAE,kBAAI;IACd,IAAI,EAAE,kBAAI;IACV,YAAY,EAAE,kBAAI;IAClB,YAAY,EAAE,kBAAI;IAClB,QAAQ,EAAE,kBAAI;IACd,iBAAiB,EAAE,kBAAI;IACvB,SAAS,EAAE,kBAAI;IACf,UAAU,EAAE,kBAAI;IAChB,UAAU,EAAE,kBAAI;IAChB,IAAI,EAAE,kBAAI;IACV,GAAG,EAAE,kBAAI;IACT,cAAc,EAAE,kBAAI;IACpB,IAAI,EAAE,kBAAI;IACV,OAAO,EAAE,kBAAI;IACb,kBAAkB,EAAE,kBAAI;IACxB,aAAa,EAAE,kBAAI;IACnB,MAAM,EAAE,kBAAI;IACZ,iBAAiB,EAAE,kBAAI;IACvB,GAAG,EAAE,kBAAI;IACT,cAAc,EAAE,kBAAI;IACpB,MAAM,EAAE,kBAAI;IACZ,MAAM,EAAE,kBAAI;IACZ,iBAAiB,EAAE,kBAAI;IACvB,UAAU,EAAE,kBAAI;IAChB,iBAAiB,EAAE,kBAAI;IACvB,WAAW,EAAE,kBAAI;IACjB,WAAW,EAAE,kBAAI;IACjB,OAAO,EAAE,kBAAI;IACb,OAAO,EAAE,kBAAI;CACgC,CAAC"}
@@ -0,0 +1,22 @@
"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.es2016_array_include = void 0;
const base_config_1 = require("./base-config");
exports.es2016_array_include = {
Array: base_config_1.TYPE,
Float32Array: base_config_1.TYPE,
Float64Array: base_config_1.TYPE,
Int8Array: base_config_1.TYPE,
Int16Array: base_config_1.TYPE,
Int32Array: base_config_1.TYPE,
ReadonlyArray: base_config_1.TYPE,
Uint8Array: base_config_1.TYPE,
Uint8ClampedArray: base_config_1.TYPE,
Uint16Array: base_config_1.TYPE,
Uint32Array: base_config_1.TYPE,
};
//# sourceMappingURL=es2016.array.include.js.map
@@ -0,0 +1 @@
{"version":3,"file":"es2016.array.include.js","sourceRoot":"","sources":["../../src/lib/es2016.array.include.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,gCAAgC;AAChC,mEAAmE;AACnE,2BAA2B;;;AAI3B,+CAAqC;AAExB,QAAA,oBAAoB,GAAG;IAClC,KAAK,EAAE,kBAAI;IACX,YAAY,EAAE,kBAAI;IAClB,YAAY,EAAE,kBAAI;IAClB,SAAS,EAAE,kBAAI;IACf,UAAU,EAAE,kBAAI;IAChB,UAAU,EAAE,kBAAI;IAChB,aAAa,EAAE,kBAAI;IACnB,UAAU,EAAE,kBAAI;IAChB,iBAAiB,EAAE,kBAAI;IACvB,WAAW,EAAE,kBAAI;IACjB,WAAW,EAAE,kBAAI;CAC4B,CAAC"}
@@ -0,0 +1,20 @@
"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.es2017_typedarrays = void 0;
const base_config_1 = require("./base-config");
exports.es2017_typedarrays = {
Float32ArrayConstructor: base_config_1.TYPE,
Float64ArrayConstructor: base_config_1.TYPE,
Int8ArrayConstructor: base_config_1.TYPE,
Int16ArrayConstructor: base_config_1.TYPE,
Int32ArrayConstructor: base_config_1.TYPE,
Uint8ArrayConstructor: base_config_1.TYPE,
Uint8ClampedArrayConstructor: base_config_1.TYPE,
Uint16ArrayConstructor: base_config_1.TYPE,
Uint32ArrayConstructor: base_config_1.TYPE,
};
//# sourceMappingURL=es2017.typedarrays.js.map
@@ -0,0 +1 @@
{"version":3,"file":"es2017.typedarrays.js","sourceRoot":"","sources":["../../src/lib/es2017.typedarrays.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,gCAAgC;AAChC,mEAAmE;AACnE,2BAA2B;;;AAI3B,+CAAqC;AAExB,QAAA,kBAAkB,GAAG;IAChC,uBAAuB,EAAE,kBAAI;IAC7B,uBAAuB,EAAE,kBAAI;IAC7B,oBAAoB,EAAE,kBAAI;IAC1B,qBAAqB,EAAE,kBAAI;IAC3B,qBAAqB,EAAE,kBAAI;IAC3B,qBAAqB,EAAE,kBAAI;IAC3B,4BAA4B,EAAE,kBAAI;IAClC,sBAAsB,EAAE,kBAAI;IAC5B,sBAAsB,EAAE,kBAAI;CACiB,CAAC"}
+24
View File
@@ -0,0 +1,24 @@
"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.es2022_array = void 0;
const base_config_1 = require("./base-config");
exports.es2022_array = {
Array: base_config_1.TYPE,
BigInt64Array: base_config_1.TYPE,
BigUint64Array: base_config_1.TYPE,
Float32Array: base_config_1.TYPE,
Float64Array: base_config_1.TYPE,
Int8Array: base_config_1.TYPE,
Int16Array: base_config_1.TYPE,
Int32Array: base_config_1.TYPE,
ReadonlyArray: base_config_1.TYPE,
Uint8Array: base_config_1.TYPE,
Uint8ClampedArray: base_config_1.TYPE,
Uint16Array: base_config_1.TYPE,
Uint32Array: base_config_1.TYPE,
};
//# sourceMappingURL=es2022.array.js.map
@@ -0,0 +1 @@
{"version":3,"file":"es2022.array.js","sourceRoot":"","sources":["../../src/lib/es2022.array.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,gCAAgC;AAChC,mEAAmE;AACnE,2BAA2B;;;AAI3B,+CAAqC;AAExB,QAAA,YAAY,GAAG;IAC1B,KAAK,EAAE,kBAAI;IACX,aAAa,EAAE,kBAAI;IACnB,cAAc,EAAE,kBAAI;IACpB,YAAY,EAAE,kBAAI;IAClB,YAAY,EAAE,kBAAI;IAClB,SAAS,EAAE,kBAAI;IACf,UAAU,EAAE,kBAAI;IAChB,UAAU,EAAE,kBAAI;IAChB,aAAa,EAAE,kBAAI;IACnB,UAAU,EAAE,kBAAI;IAChB,iBAAiB,EAAE,kBAAI;IACvB,WAAW,EAAE,kBAAI;IACjB,WAAW,EAAE,kBAAI;CAC4B,CAAC"}
+24
View File
@@ -0,0 +1,24 @@
"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.es2023_array = void 0;
const base_config_1 = require("./base-config");
exports.es2023_array = {
Array: base_config_1.TYPE,
BigInt64Array: base_config_1.TYPE,
BigUint64Array: base_config_1.TYPE,
Float32Array: base_config_1.TYPE,
Float64Array: base_config_1.TYPE,
Int8Array: base_config_1.TYPE,
Int16Array: base_config_1.TYPE,
Int32Array: base_config_1.TYPE,
ReadonlyArray: base_config_1.TYPE,
Uint8Array: base_config_1.TYPE,
Uint8ClampedArray: base_config_1.TYPE,
Uint16Array: base_config_1.TYPE,
Uint32Array: base_config_1.TYPE,
};
//# sourceMappingURL=es2023.array.js.map
@@ -0,0 +1 @@
{"version":3,"file":"es2023.array.js","sourceRoot":"","sources":["../../src/lib/es2023.array.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,gCAAgC;AAChC,mEAAmE;AACnE,2BAA2B;;;AAI3B,+CAAqC;AAExB,QAAA,YAAY,GAAG;IAC1B,KAAK,EAAE,kBAAI;IACX,aAAa,EAAE,kBAAI;IACnB,cAAc,EAAE,kBAAI;IACpB,YAAY,EAAE,kBAAI;IAClB,YAAY,EAAE,kBAAI;IAClB,SAAS,EAAE,kBAAI;IACf,UAAU,EAAE,kBAAI;IAChB,UAAU,EAAE,kBAAI;IAChB,aAAa,EAAE,kBAAI;IACnB,UAAU,EAAE,kBAAI;IAChB,iBAAiB,EAAE,kBAAI;IACvB,WAAW,EAAE,kBAAI;IACjB,WAAW,EAAE,kBAAI;CAC4B,CAAC"}
+118
View File
@@ -0,0 +1,118 @@
"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.es5 = void 0;
const base_config_1 = require("./base-config");
const decorators_1 = require("./decorators");
const decorators_legacy_1 = require("./decorators.legacy");
exports.es5 = {
...decorators_1.decorators,
...decorators_legacy_1.decorators_legacy,
Array: base_config_1.TYPE_VALUE,
ArrayBuffer: base_config_1.TYPE_VALUE,
ArrayBufferConstructor: base_config_1.TYPE,
ArrayBufferLike: base_config_1.TYPE,
ArrayBufferTypes: base_config_1.TYPE,
ArrayBufferView: base_config_1.TYPE,
ArrayConstructor: base_config_1.TYPE,
ArrayLike: base_config_1.TYPE,
Awaited: base_config_1.TYPE,
Boolean: base_config_1.TYPE_VALUE,
BooleanConstructor: base_config_1.TYPE,
CallableFunction: base_config_1.TYPE,
Capitalize: base_config_1.TYPE,
ConcatArray: base_config_1.TYPE,
ConstructorParameters: base_config_1.TYPE,
DataView: base_config_1.TYPE_VALUE,
DataViewConstructor: base_config_1.TYPE,
Date: base_config_1.TYPE_VALUE,
DateConstructor: base_config_1.TYPE,
Error: base_config_1.TYPE_VALUE,
ErrorConstructor: base_config_1.TYPE,
EvalError: base_config_1.TYPE_VALUE,
EvalErrorConstructor: base_config_1.TYPE,
Exclude: base_config_1.TYPE,
Extract: base_config_1.TYPE,
Float32Array: base_config_1.TYPE_VALUE,
Float32ArrayConstructor: base_config_1.TYPE,
Float64Array: base_config_1.TYPE_VALUE,
Float64ArrayConstructor: base_config_1.TYPE,
Function: base_config_1.TYPE_VALUE,
FunctionConstructor: base_config_1.TYPE,
IArguments: base_config_1.TYPE,
ImportAssertions: base_config_1.TYPE,
ImportAttributes: base_config_1.TYPE,
ImportCallOptions: base_config_1.TYPE,
ImportMeta: base_config_1.TYPE,
InstanceType: base_config_1.TYPE,
Int8Array: base_config_1.TYPE_VALUE,
Int8ArrayConstructor: base_config_1.TYPE,
Int16Array: base_config_1.TYPE_VALUE,
Int16ArrayConstructor: base_config_1.TYPE,
Int32Array: base_config_1.TYPE_VALUE,
Int32ArrayConstructor: base_config_1.TYPE,
Intl: base_config_1.TYPE_VALUE,
JSON: base_config_1.TYPE_VALUE,
Lowercase: base_config_1.TYPE,
Math: base_config_1.TYPE_VALUE,
NewableFunction: base_config_1.TYPE,
NoInfer: base_config_1.TYPE,
NonNullable: base_config_1.TYPE,
Number: base_config_1.TYPE_VALUE,
NumberConstructor: base_config_1.TYPE,
Object: base_config_1.TYPE_VALUE,
ObjectConstructor: base_config_1.TYPE,
Omit: base_config_1.TYPE,
OmitThisParameter: base_config_1.TYPE,
Parameters: base_config_1.TYPE,
Partial: base_config_1.TYPE,
Pick: base_config_1.TYPE,
Promise: base_config_1.TYPE,
PromiseConstructorLike: base_config_1.TYPE,
PromiseLike: base_config_1.TYPE,
PropertyDescriptor: base_config_1.TYPE,
PropertyDescriptorMap: base_config_1.TYPE,
PropertyKey: base_config_1.TYPE,
RangeError: base_config_1.TYPE_VALUE,
RangeErrorConstructor: base_config_1.TYPE,
Readonly: base_config_1.TYPE,
ReadonlyArray: base_config_1.TYPE,
Record: base_config_1.TYPE,
ReferenceError: base_config_1.TYPE_VALUE,
ReferenceErrorConstructor: base_config_1.TYPE,
RegExp: base_config_1.TYPE_VALUE,
RegExpConstructor: base_config_1.TYPE,
RegExpExecArray: base_config_1.TYPE,
RegExpMatchArray: base_config_1.TYPE,
Required: base_config_1.TYPE,
ReturnType: base_config_1.TYPE,
String: base_config_1.TYPE_VALUE,
StringConstructor: base_config_1.TYPE,
Symbol: base_config_1.TYPE,
SyntaxError: base_config_1.TYPE_VALUE,
SyntaxErrorConstructor: base_config_1.TYPE,
TemplateStringsArray: base_config_1.TYPE,
ThisParameterType: base_config_1.TYPE,
ThisType: base_config_1.TYPE,
TypedPropertyDescriptor: base_config_1.TYPE,
TypeError: base_config_1.TYPE_VALUE,
TypeErrorConstructor: base_config_1.TYPE,
Uint8Array: base_config_1.TYPE_VALUE,
Uint8ArrayConstructor: base_config_1.TYPE,
Uint8ClampedArray: base_config_1.TYPE_VALUE,
Uint8ClampedArrayConstructor: base_config_1.TYPE,
Uint16Array: base_config_1.TYPE_VALUE,
Uint16ArrayConstructor: base_config_1.TYPE,
Uint32Array: base_config_1.TYPE_VALUE,
Uint32ArrayConstructor: base_config_1.TYPE,
Uncapitalize: base_config_1.TYPE,
Uppercase: base_config_1.TYPE,
URIError: base_config_1.TYPE_VALUE,
URIErrorConstructor: base_config_1.TYPE,
WeakKey: base_config_1.TYPE,
WeakKeyTypes: base_config_1.TYPE,
};
//# sourceMappingURL=es5.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"es5.js","sourceRoot":"","sources":["../../src/lib/es5.ts"],"names":[],"mappings":"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"}
+30
View File
@@ -0,0 +1,30 @@
"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.es6 = void 0;
const es5_1 = require("./es5");
const es2015_collection_1 = require("./es2015.collection");
const es2015_core_1 = require("./es2015.core");
const es2015_generator_1 = require("./es2015.generator");
const es2015_iterable_1 = require("./es2015.iterable");
const es2015_promise_1 = require("./es2015.promise");
const es2015_proxy_1 = require("./es2015.proxy");
const es2015_reflect_1 = require("./es2015.reflect");
const es2015_symbol_1 = require("./es2015.symbol");
const es2015_symbol_wellknown_1 = require("./es2015.symbol.wellknown");
exports.es6 = {
...es5_1.es5,
...es2015_core_1.es2015_core,
...es2015_collection_1.es2015_collection,
...es2015_iterable_1.es2015_iterable,
...es2015_generator_1.es2015_generator,
...es2015_promise_1.es2015_promise,
...es2015_proxy_1.es2015_proxy,
...es2015_reflect_1.es2015_reflect,
...es2015_symbol_1.es2015_symbol,
...es2015_symbol_wellknown_1.es2015_symbol_wellknown,
};
//# sourceMappingURL=es6.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"es6.js","sourceRoot":"","sources":["../../src/lib/es6.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,gCAAgC;AAChC,mEAAmE;AACnE,2BAA2B;;;AAI3B,+BAA4B;AAC5B,2DAAwD;AACxD,+CAA4C;AAC5C,yDAAsD;AACtD,uDAAoD;AACpD,qDAAkD;AAClD,iDAA8C;AAC9C,qDAAkD;AAClD,mDAAgD;AAChD,uEAAoE;AAEvD,QAAA,GAAG,GAAG;IACjB,GAAG,SAAG;IACN,GAAG,yBAAW;IACd,GAAG,qCAAiB;IACpB,GAAG,iCAAe;IAClB,GAAG,mCAAgB;IACnB,GAAG,+BAAc;IACjB,GAAG,2BAAY;IACf,GAAG,+BAAc;IACjB,GAAG,6BAAa;IAChB,GAAG,iDAAuB;CACmB,CAAC"}
+100
View File
@@ -0,0 +1,100 @@
declare const lib: {
readonly decorators: Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'decorators.legacy': Record<string, import("..").ImplicitLibVariableOptions>;
readonly dom: Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'dom.asynciterable': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'dom.iterable': Record<string, import("..").ImplicitLibVariableOptions>;
readonly es5: Record<string, import("..").ImplicitLibVariableOptions>;
readonly es6: Record<string, import("..").ImplicitLibVariableOptions>;
readonly es7: Record<string, import("..").ImplicitLibVariableOptions>;
readonly es2015: Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2015.collection': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2015.core': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2015.generator': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2015.iterable': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2015.promise': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2015.proxy': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2015.reflect': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2015.symbol': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2015.symbol.wellknown': Record<string, import("..").ImplicitLibVariableOptions>;
readonly es2016: Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2016.array.include': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2016.full': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2016.intl': Record<string, import("..").ImplicitLibVariableOptions>;
readonly es2017: Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2017.date': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2017.full': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2017.intl': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2017.object': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2017.sharedmemory': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2017.string': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2017.typedarrays': Record<string, import("..").ImplicitLibVariableOptions>;
readonly es2018: Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2018.asyncgenerator': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2018.asynciterable': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2018.full': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2018.intl': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2018.promise': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2018.regexp': Record<string, import("..").ImplicitLibVariableOptions>;
readonly es2019: Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2019.array': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2019.full': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2019.intl': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2019.object': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2019.string': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2019.symbol': Record<string, import("..").ImplicitLibVariableOptions>;
readonly es2020: Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2020.bigint': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2020.date': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2020.full': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2020.intl': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2020.number': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2020.promise': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2020.sharedmemory': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2020.string': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2020.symbol.wellknown': Record<string, import("..").ImplicitLibVariableOptions>;
readonly es2021: Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2021.full': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2021.intl': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2021.promise': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2021.string': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2021.weakref': Record<string, import("..").ImplicitLibVariableOptions>;
readonly es2022: Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2022.array': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2022.error': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2022.full': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2022.intl': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2022.object': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2022.regexp': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2022.sharedmemory': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2022.string': Record<string, import("..").ImplicitLibVariableOptions>;
readonly es2023: Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2023.array': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2023.collection': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2023.full': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'es2023.intl': Record<string, import("..").ImplicitLibVariableOptions>;
readonly esnext: Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'esnext.array': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'esnext.asynciterable': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'esnext.bigint': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'esnext.collection': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'esnext.decorators': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'esnext.disposable': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'esnext.full': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'esnext.intl': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'esnext.iterator': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'esnext.object': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'esnext.promise': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'esnext.regexp': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'esnext.string': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'esnext.symbol': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'esnext.weakref': Record<string, import("..").ImplicitLibVariableOptions>;
readonly lib: Record<string, import("..").ImplicitLibVariableOptions>;
readonly scripthost: Record<string, import("..").ImplicitLibVariableOptions>;
readonly webworker: Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'webworker.asynciterable': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'webworker.importscripts': Record<string, import("..").ImplicitLibVariableOptions>;
readonly 'webworker.iterable': Record<string, import("..").ImplicitLibVariableOptions>;
};
export { lib };
//# sourceMappingURL=index.d.ts.map
+203
View File
@@ -0,0 +1,203 @@
"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.lib = void 0;
const decorators_1 = require("./decorators");
const decorators_legacy_1 = require("./decorators.legacy");
const dom_1 = require("./dom");
const dom_asynciterable_1 = require("./dom.asynciterable");
const dom_iterable_1 = require("./dom.iterable");
const es5_1 = require("./es5");
const es6_1 = require("./es6");
const es7_1 = require("./es7");
const es2015_1 = require("./es2015");
const es2015_collection_1 = require("./es2015.collection");
const es2015_core_1 = require("./es2015.core");
const es2015_generator_1 = require("./es2015.generator");
const es2015_iterable_1 = require("./es2015.iterable");
const es2015_promise_1 = require("./es2015.promise");
const es2015_proxy_1 = require("./es2015.proxy");
const es2015_reflect_1 = require("./es2015.reflect");
const es2015_symbol_1 = require("./es2015.symbol");
const es2015_symbol_wellknown_1 = require("./es2015.symbol.wellknown");
const es2016_1 = require("./es2016");
const es2016_array_include_1 = require("./es2016.array.include");
const es2016_full_1 = require("./es2016.full");
const es2016_intl_1 = require("./es2016.intl");
const es2017_1 = require("./es2017");
const es2017_date_1 = require("./es2017.date");
const es2017_full_1 = require("./es2017.full");
const es2017_intl_1 = require("./es2017.intl");
const es2017_object_1 = require("./es2017.object");
const es2017_sharedmemory_1 = require("./es2017.sharedmemory");
const es2017_string_1 = require("./es2017.string");
const es2017_typedarrays_1 = require("./es2017.typedarrays");
const es2018_1 = require("./es2018");
const es2018_asyncgenerator_1 = require("./es2018.asyncgenerator");
const es2018_asynciterable_1 = require("./es2018.asynciterable");
const es2018_full_1 = require("./es2018.full");
const es2018_intl_1 = require("./es2018.intl");
const es2018_promise_1 = require("./es2018.promise");
const es2018_regexp_1 = require("./es2018.regexp");
const es2019_1 = require("./es2019");
const es2019_array_1 = require("./es2019.array");
const es2019_full_1 = require("./es2019.full");
const es2019_intl_1 = require("./es2019.intl");
const es2019_object_1 = require("./es2019.object");
const es2019_string_1 = require("./es2019.string");
const es2019_symbol_1 = require("./es2019.symbol");
const es2020_1 = require("./es2020");
const es2020_bigint_1 = require("./es2020.bigint");
const es2020_date_1 = require("./es2020.date");
const es2020_full_1 = require("./es2020.full");
const es2020_intl_1 = require("./es2020.intl");
const es2020_number_1 = require("./es2020.number");
const es2020_promise_1 = require("./es2020.promise");
const es2020_sharedmemory_1 = require("./es2020.sharedmemory");
const es2020_string_1 = require("./es2020.string");
const es2020_symbol_wellknown_1 = require("./es2020.symbol.wellknown");
const es2021_1 = require("./es2021");
const es2021_full_1 = require("./es2021.full");
const es2021_intl_1 = require("./es2021.intl");
const es2021_promise_1 = require("./es2021.promise");
const es2021_string_1 = require("./es2021.string");
const es2021_weakref_1 = require("./es2021.weakref");
const es2022_1 = require("./es2022");
const es2022_array_1 = require("./es2022.array");
const es2022_error_1 = require("./es2022.error");
const es2022_full_1 = require("./es2022.full");
const es2022_intl_1 = require("./es2022.intl");
const es2022_object_1 = require("./es2022.object");
const es2022_regexp_1 = require("./es2022.regexp");
const es2022_sharedmemory_1 = require("./es2022.sharedmemory");
const es2022_string_1 = require("./es2022.string");
const es2023_1 = require("./es2023");
const es2023_array_1 = require("./es2023.array");
const es2023_collection_1 = require("./es2023.collection");
const es2023_full_1 = require("./es2023.full");
const es2023_intl_1 = require("./es2023.intl");
const esnext_1 = require("./esnext");
const esnext_array_1 = require("./esnext.array");
const esnext_asynciterable_1 = require("./esnext.asynciterable");
const esnext_bigint_1 = require("./esnext.bigint");
const esnext_collection_1 = require("./esnext.collection");
const esnext_decorators_1 = require("./esnext.decorators");
const esnext_disposable_1 = require("./esnext.disposable");
const esnext_full_1 = require("./esnext.full");
const esnext_intl_1 = require("./esnext.intl");
const esnext_iterator_1 = require("./esnext.iterator");
const esnext_object_1 = require("./esnext.object");
const esnext_promise_1 = require("./esnext.promise");
const esnext_regexp_1 = require("./esnext.regexp");
const esnext_string_1 = require("./esnext.string");
const esnext_symbol_1 = require("./esnext.symbol");
const esnext_weakref_1 = require("./esnext.weakref");
const lib_1 = require("./lib");
const scripthost_1 = require("./scripthost");
const webworker_1 = require("./webworker");
const webworker_asynciterable_1 = require("./webworker.asynciterable");
const webworker_importscripts_1 = require("./webworker.importscripts");
const webworker_iterable_1 = require("./webworker.iterable");
const lib = {
decorators: decorators_1.decorators,
'decorators.legacy': decorators_legacy_1.decorators_legacy,
dom: dom_1.dom,
'dom.asynciterable': dom_asynciterable_1.dom_asynciterable,
'dom.iterable': dom_iterable_1.dom_iterable,
es5: es5_1.es5,
es6: es6_1.es6,
es7: es7_1.es7,
es2015: es2015_1.es2015,
'es2015.collection': es2015_collection_1.es2015_collection,
'es2015.core': es2015_core_1.es2015_core,
'es2015.generator': es2015_generator_1.es2015_generator,
'es2015.iterable': es2015_iterable_1.es2015_iterable,
'es2015.promise': es2015_promise_1.es2015_promise,
'es2015.proxy': es2015_proxy_1.es2015_proxy,
'es2015.reflect': es2015_reflect_1.es2015_reflect,
'es2015.symbol': es2015_symbol_1.es2015_symbol,
'es2015.symbol.wellknown': es2015_symbol_wellknown_1.es2015_symbol_wellknown,
es2016: es2016_1.es2016,
'es2016.array.include': es2016_array_include_1.es2016_array_include,
'es2016.full': es2016_full_1.es2016_full,
'es2016.intl': es2016_intl_1.es2016_intl,
es2017: es2017_1.es2017,
'es2017.date': es2017_date_1.es2017_date,
'es2017.full': es2017_full_1.es2017_full,
'es2017.intl': es2017_intl_1.es2017_intl,
'es2017.object': es2017_object_1.es2017_object,
'es2017.sharedmemory': es2017_sharedmemory_1.es2017_sharedmemory,
'es2017.string': es2017_string_1.es2017_string,
'es2017.typedarrays': es2017_typedarrays_1.es2017_typedarrays,
es2018: es2018_1.es2018,
'es2018.asyncgenerator': es2018_asyncgenerator_1.es2018_asyncgenerator,
'es2018.asynciterable': es2018_asynciterable_1.es2018_asynciterable,
'es2018.full': es2018_full_1.es2018_full,
'es2018.intl': es2018_intl_1.es2018_intl,
'es2018.promise': es2018_promise_1.es2018_promise,
'es2018.regexp': es2018_regexp_1.es2018_regexp,
es2019: es2019_1.es2019,
'es2019.array': es2019_array_1.es2019_array,
'es2019.full': es2019_full_1.es2019_full,
'es2019.intl': es2019_intl_1.es2019_intl,
'es2019.object': es2019_object_1.es2019_object,
'es2019.string': es2019_string_1.es2019_string,
'es2019.symbol': es2019_symbol_1.es2019_symbol,
es2020: es2020_1.es2020,
'es2020.bigint': es2020_bigint_1.es2020_bigint,
'es2020.date': es2020_date_1.es2020_date,
'es2020.full': es2020_full_1.es2020_full,
'es2020.intl': es2020_intl_1.es2020_intl,
'es2020.number': es2020_number_1.es2020_number,
'es2020.promise': es2020_promise_1.es2020_promise,
'es2020.sharedmemory': es2020_sharedmemory_1.es2020_sharedmemory,
'es2020.string': es2020_string_1.es2020_string,
'es2020.symbol.wellknown': es2020_symbol_wellknown_1.es2020_symbol_wellknown,
es2021: es2021_1.es2021,
'es2021.full': es2021_full_1.es2021_full,
'es2021.intl': es2021_intl_1.es2021_intl,
'es2021.promise': es2021_promise_1.es2021_promise,
'es2021.string': es2021_string_1.es2021_string,
'es2021.weakref': es2021_weakref_1.es2021_weakref,
es2022: es2022_1.es2022,
'es2022.array': es2022_array_1.es2022_array,
'es2022.error': es2022_error_1.es2022_error,
'es2022.full': es2022_full_1.es2022_full,
'es2022.intl': es2022_intl_1.es2022_intl,
'es2022.object': es2022_object_1.es2022_object,
'es2022.regexp': es2022_regexp_1.es2022_regexp,
'es2022.sharedmemory': es2022_sharedmemory_1.es2022_sharedmemory,
'es2022.string': es2022_string_1.es2022_string,
es2023: es2023_1.es2023,
'es2023.array': es2023_array_1.es2023_array,
'es2023.collection': es2023_collection_1.es2023_collection,
'es2023.full': es2023_full_1.es2023_full,
'es2023.intl': es2023_intl_1.es2023_intl,
esnext: esnext_1.esnext,
'esnext.array': esnext_array_1.esnext_array,
'esnext.asynciterable': esnext_asynciterable_1.esnext_asynciterable,
'esnext.bigint': esnext_bigint_1.esnext_bigint,
'esnext.collection': esnext_collection_1.esnext_collection,
'esnext.decorators': esnext_decorators_1.esnext_decorators,
'esnext.disposable': esnext_disposable_1.esnext_disposable,
'esnext.full': esnext_full_1.esnext_full,
'esnext.intl': esnext_intl_1.esnext_intl,
'esnext.iterator': esnext_iterator_1.esnext_iterator,
'esnext.object': esnext_object_1.esnext_object,
'esnext.promise': esnext_promise_1.esnext_promise,
'esnext.regexp': esnext_regexp_1.esnext_regexp,
'esnext.string': esnext_string_1.esnext_string,
'esnext.symbol': esnext_symbol_1.esnext_symbol,
'esnext.weakref': esnext_weakref_1.esnext_weakref,
lib: lib_1.lib,
scripthost: scripthost_1.scripthost,
webworker: webworker_1.webworker,
'webworker.asynciterable': webworker_asynciterable_1.webworker_asynciterable,
'webworker.importscripts': webworker_importscripts_1.webworker_importscripts,
'webworker.iterable': webworker_iterable_1.webworker_iterable,
};
exports.lib = lib;
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lib/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
import type { Lib, TSESTree } from '@typescript-eslint/types';
import type { Scope } from '../scope';
import type { ScopeManager } from '../ScopeManager';
import type { ReferenceImplicitGlobal } from './Reference';
import type { VisitorOptions } from './Visitor';
import { Visitor } from './Visitor';
interface ReferencerOptions extends VisitorOptions {
jsxFragmentName: string | null;
jsxPragma: string | null;
lib: Lib[];
}
declare class Referencer extends Visitor {
#private;
readonly scopeManager: ScopeManager;
constructor(options: ReferencerOptions, scopeManager: ScopeManager);
private populateGlobalsFromLib;
close(node: TSESTree.Node): void;
currentScope(): Scope;
currentScope(throwOnNull: true): Scope | null;
referencingDefaultValue(pattern: TSESTree.Identifier, assignments: (TSESTree.AssignmentExpression | TSESTree.AssignmentPattern)[], maybeImplicitGlobal: ReferenceImplicitGlobal | null, init: boolean): void;
/**
* Searches for a variable named "name" in the upper scopes and adds a pseudo-reference from itself to itself
*/
private referenceInSomeUpperScope;
private referenceJsxFragment;
private referenceJsxPragma;
protected visitClass(node: TSESTree.ClassDeclaration | TSESTree.ClassExpression): void;
protected visitForIn(node: TSESTree.ForInStatement | TSESTree.ForOfStatement): void;
protected visitFunction(node: TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclaration | TSESTree.FunctionExpression | TSESTree.TSDeclareFunction | TSESTree.TSEmptyBodyFunctionExpression): void;
protected visitFunctionParameterTypeAnnotation(node: TSESTree.Parameter): void;
protected visitProperty(node: TSESTree.Property): void;
protected visitType(node: TSESTree.Node | null | undefined): void;
protected visitTypeAssertion(node: TSESTree.TSAsExpression | TSESTree.TSSatisfiesExpression | TSESTree.TSTypeAssertion): void;
protected ArrowFunctionExpression(node: TSESTree.ArrowFunctionExpression): void;
protected AssignmentExpression(node: TSESTree.AssignmentExpression): void;
protected BlockStatement(node: TSESTree.BlockStatement): void;
protected BreakStatement(): void;
protected CallExpression(node: TSESTree.CallExpression): void;
protected CatchClause(node: TSESTree.CatchClause): void;
protected ClassDeclaration(node: TSESTree.ClassDeclaration): void;
protected ClassExpression(node: TSESTree.ClassExpression): void;
protected ContinueStatement(): void;
protected ExportAllDeclaration(): void;
protected ExportDefaultDeclaration(node: TSESTree.ExportDefaultDeclaration): void;
protected ExportNamedDeclaration(node: TSESTree.ExportNamedDeclaration): void;
protected ForInStatement(node: TSESTree.ForInStatement): void;
protected ForOfStatement(node: TSESTree.ForOfStatement): void;
protected ForStatement(node: TSESTree.ForStatement): void;
protected FunctionDeclaration(node: TSESTree.FunctionDeclaration): void;
protected FunctionExpression(node: TSESTree.FunctionExpression): void;
protected Identifier(node: TSESTree.Identifier): void;
protected ImportAttribute(): void;
protected ImportDeclaration(node: TSESTree.ImportDeclaration): void;
protected JSXAttribute(node: TSESTree.JSXAttribute): void;
protected JSXClosingElement(): void;
protected JSXFragment(node: TSESTree.JSXFragment): void;
protected JSXIdentifier(node: TSESTree.JSXIdentifier): void;
protected JSXMemberExpression(node: TSESTree.JSXMemberExpression): void;
protected JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
protected LabeledStatement(node: TSESTree.LabeledStatement): void;
protected MemberExpression(node: TSESTree.MemberExpression): void;
protected MetaProperty(): void;
protected NewExpression(node: TSESTree.NewExpression): void;
protected PrivateIdentifier(): void;
protected Program(node: TSESTree.Program): void;
protected Property(node: TSESTree.Property): void;
protected SwitchStatement(node: TSESTree.SwitchStatement): void;
protected TaggedTemplateExpression(node: TSESTree.TaggedTemplateExpression): void;
protected TSAsExpression(node: TSESTree.TSAsExpression): void;
protected TSDeclareFunction(node: TSESTree.TSDeclareFunction): void;
protected TSEmptyBodyFunctionExpression(node: TSESTree.TSEmptyBodyFunctionExpression): void;
protected TSEnumDeclaration(node: TSESTree.TSEnumDeclaration): void;
protected TSExportAssignment(node: TSESTree.TSExportAssignment): void;
protected TSImportEqualsDeclaration(node: TSESTree.TSImportEqualsDeclaration): void;
protected TSInstantiationExpression(node: TSESTree.TSInstantiationExpression): void;
protected TSInterfaceDeclaration(node: TSESTree.TSInterfaceDeclaration): void;
protected TSModuleDeclaration(node: TSESTree.TSModuleDeclaration): void;
protected TSSatisfiesExpression(node: TSESTree.TSSatisfiesExpression): void;
protected TSTypeAliasDeclaration(node: TSESTree.TSTypeAliasDeclaration): void;
protected TSTypeAssertion(node: TSESTree.TSTypeAssertion): void;
protected UpdateExpression(node: TSESTree.UpdateExpression): void;
protected VariableDeclaration(node: TSESTree.VariableDeclaration): void;
protected WithStatement(node: TSESTree.WithStatement): void;
private visitExpressionTarget;
}
export { Referencer, type ReferencerOptions };
//# sourceMappingURL=Referencer.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"Referencer.d.ts","sourceRoot":"","sources":["../../src/referencer/Referencer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAI9D,OAAO,KAAK,EAAe,KAAK,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAoBhD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,UAAU,iBAAkB,SAAQ,cAAc;IAChD,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,GAAG,EAAE,GAAG,EAAE,CAAC;CACZ;AAGD,cAAM,UAAW,SAAQ,OAAO;;IAM9B,SAAgB,YAAY,EAAE,YAAY,CAAC;gBAE/B,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY;IAQlE,OAAO,CAAC,sBAAsB;IAmBvB,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,GAAG,IAAI;IAOhC,YAAY,IAAI,KAAK;IAErB,YAAY,CAAC,WAAW,EAAE,IAAI,GAAG,KAAK,GAAG,IAAI;IAS7C,uBAAuB,CAC5B,OAAO,EAAE,QAAQ,CAAC,UAAU,EAC5B,WAAW,EAAE,CAAC,QAAQ,CAAC,oBAAoB,GAAG,QAAQ,CAAC,iBAAiB,CAAC,EAAE,EAC3E,mBAAmB,EAAE,uBAAuB,GAAG,IAAI,EACnD,IAAI,EAAE,OAAO,GACZ,IAAI;IAYP;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAgBjC,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,kBAAkB;IAa1B,SAAS,CAAC,UAAU,CAClB,IAAI,EAAE,QAAQ,CAAC,gBAAgB,GAAG,QAAQ,CAAC,eAAe,GACzD,IAAI;IAIP,SAAS,CAAC,UAAU,CAClB,IAAI,EAAE,QAAQ,CAAC,cAAc,GAAG,QAAQ,CAAC,cAAc,GACtD,IAAI;IAoDP,SAAS,CAAC,aAAa,CACrB,IAAI,EACA,QAAQ,CAAC,uBAAuB,GAChC,QAAQ,CAAC,mBAAmB,GAC5B,QAAQ,CAAC,kBAAkB,GAC3B,QAAQ,CAAC,iBAAiB,GAC1B,QAAQ,CAAC,6BAA6B,GACzC,IAAI;IA0DP,SAAS,CAAC,oCAAoC,CAC5C,IAAI,EAAE,QAAQ,CAAC,SAAS,GACvB,IAAI;IAcP,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI;IAQtD,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI;IAOjE,SAAS,CAAC,kBAAkB,CAC1B,IAAI,EACA,QAAQ,CAAC,cAAc,GACvB,QAAQ,CAAC,qBAAqB,GAC9B,QAAQ,CAAC,eAAe,GAC3B,IAAI;IASP,SAAS,CAAC,uBAAuB,CAC/B,IAAI,EAAE,QAAQ,CAAC,uBAAuB,GACrC,IAAI;IAIP,SAAS,CAAC,oBAAoB,CAAC,IAAI,EAAE,QAAQ,CAAC,oBAAoB,GAAG,IAAI;IA2CzE,SAAS,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,GAAG,IAAI;IAQ7D,SAAS,CAAC,cAAc,IAAI,IAAI;IAIhC,SAAS,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,GAAG,IAAI;IAK7D,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,WAAW,GAAG,IAAI;IAsBvD,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,GAAG,IAAI;IAIjE,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,eAAe,GAAG,IAAI;IAI/D,SAAS,CAAC,iBAAiB,IAAI,IAAI;IAInC,SAAS,CAAC,oBAAoB,IAAI,IAAI;IAItC,SAAS,CAAC,wBAAwB,CAChC,IAAI,EAAE,QAAQ,CAAC,wBAAwB,GACtC,IAAI;IAQP,SAAS,CAAC,sBAAsB,CAC9B,IAAI,EAAE,QAAQ,CAAC,sBAAsB,GACpC,IAAI;IAQP,SAAS,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,GAAG,IAAI;IAI7D,SAAS,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,GAAG,IAAI;IAI7D,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,YAAY,GAAG,IAAI;IAiBzD,SAAS,CAAC,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC,mBAAmB,GAAG,IAAI;IAIvE,SAAS,CAAC,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,GAAG,IAAI;IAIrE,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,UAAU,GAAG,IAAI;IAKrD,SAAS,CAAC,eAAe,IAAI,IAAI;IAIjC,SAAS,CAAC,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,iBAAiB,GAAG,IAAI;IASnE,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,YAAY,GAAG,IAAI;IAIzD,SAAS,CAAC,iBAAiB,IAAI,IAAI;IAInC,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,WAAW,GAAG,IAAI;IAMvD,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,aAAa,GAAG,IAAI;IAI3D,SAAS,CAAC,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC,mBAAmB,GAAG,IAAI;IASvE,SAAS,CAAC,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,iBAAiB,GAAG,IAAI;IAuBnE,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,GAAG,IAAI;IAIjE,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,GAAG,IAAI;IAOjE,SAAS,CAAC,YAAY,IAAI,IAAI;IAI9B,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,aAAa,GAAG,IAAI;IAK3D,SAAS,CAAC,iBAAiB,IAAI,IAAI;IAInC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,GAAG,IAAI;IAsB/C,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI;IAIjD,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,eAAe,GAAG,IAAI;IAY/D,SAAS,CAAC,wBAAwB,CAChC,IAAI,EAAE,QAAQ,CAAC,wBAAwB,GACtC,IAAI;IAMP,SAAS,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,GAAG,IAAI;IAI7D,SAAS,CAAC,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,iBAAiB,GAAG,IAAI;IAInE,SAAS,CAAC,6BAA6B,CACrC,IAAI,EAAE,QAAQ,CAAC,6BAA6B,GAC3C,IAAI;IAIP,SAAS,CAAC,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,iBAAiB,GAAG,IAAI;IAwCnE,SAAS,CAAC,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,GAAG,IAAI;IAarE,SAAS,CAAC,yBAAyB,CACjC,IAAI,EAAE,QAAQ,CAAC,yBAAyB,GACvC,IAAI;IAiBP,SAAS,CAAC,yBAAyB,CACjC,IAAI,EAAE,QAAQ,CAAC,yBAAyB,GACvC,IAAI;IAKP,SAAS,CAAC,sBAAsB,CAC9B,IAAI,EAAE,QAAQ,CAAC,sBAAsB,GACpC,IAAI;IAIP,SAAS,CAAC,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC,mBAAmB,GAAG,IAAI;IAevE,SAAS,CAAC,qBAAqB,CAAC,IAAI,EAAE,QAAQ,CAAC,qBAAqB,GAAG,IAAI;IAI3E,SAAS,CAAC,sBAAsB,CAC9B,IAAI,EAAE,QAAQ,CAAC,sBAAsB,GACpC,IAAI;IAIP,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,eAAe,GAAG,IAAI;IAI/D,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,GAAG,IAAI;IAgBjE,SAAS,CAAC,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC,mBAAmB,GAAG,IAAI;IAoCvE,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,aAAa,GAAG,IAAI;IAW3D,OAAO,CAAC,qBAAqB;CAc9B;AAED,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,540 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Referencer = void 0;
const types_1 = require("@typescript-eslint/types");
const assert_1 = require("../assert");
const definition_1 = require("../definition");
const lib_1 = require("../lib");
const ClassVisitor_1 = require("./ClassVisitor");
const ExportVisitor_1 = require("./ExportVisitor");
const ImportVisitor_1 = require("./ImportVisitor");
const PatternVisitor_1 = require("./PatternVisitor");
const Reference_1 = require("./Reference");
const TypeVisitor_1 = require("./TypeVisitor");
const Visitor_1 = require("./Visitor");
// Referencing variables and creating bindings.
class Referencer extends Visitor_1.Visitor {
#hasReferencedJsxFactory = false;
#hasReferencedJsxFragmentFactory = false;
#jsxFragmentName;
#jsxPragma;
#lib;
scopeManager;
constructor(options, scopeManager) {
super(options);
this.scopeManager = scopeManager;
this.#jsxPragma = options.jsxPragma;
this.#jsxFragmentName = options.jsxFragmentName;
this.#lib = options.lib;
}
populateGlobalsFromLib(globalScope) {
for (const lib of this.#lib) {
const variables = lib_1.lib[lib];
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
/* istanbul ignore if */ if (!variables) {
throw new Error(`Invalid value for lib provided: ${lib}`);
}
for (const [name, variable] of Object.entries(variables)) {
globalScope.defineImplicitVariable(name, variable);
}
}
// for const assertions (`{} as const` / `<const>{}`)
globalScope.defineImplicitVariable('const', {
eslintImplicitGlobalSetting: 'readonly',
isTypeVariable: true,
isValueVariable: false,
});
}
close(node) {
while (this.currentScope(true) && node === this.currentScope().block) {
this.scopeManager.currentScope = this.currentScope().close(this.scopeManager);
}
}
currentScope(dontThrowOnNull) {
if (!dontThrowOnNull) {
(0, assert_1.assert)(this.scopeManager.currentScope, 'aaa');
}
return this.scopeManager.currentScope;
}
referencingDefaultValue(pattern, assignments, maybeImplicitGlobal, init) {
assignments.forEach(assignment => {
this.currentScope().referenceValue(pattern, Reference_1.ReferenceFlag.Write, assignment.right, maybeImplicitGlobal, init);
});
}
/**
* Searches for a variable named "name" in the upper scopes and adds a pseudo-reference from itself to itself
*/
referenceInSomeUpperScope(name) {
let scope = this.scopeManager.currentScope;
while (scope) {
const variable = scope.set.get(name);
if (!variable) {
scope = scope.upper;
continue;
}
scope.referenceValue(variable.identifiers[0]);
return true;
}
return false;
}
referenceJsxFragment() {
if (this.#jsxFragmentName == null ||
this.#hasReferencedJsxFragmentFactory) {
return;
}
this.#hasReferencedJsxFragmentFactory = this.referenceInSomeUpperScope(this.#jsxFragmentName);
}
referenceJsxPragma() {
if (this.#jsxPragma == null || this.#hasReferencedJsxFactory) {
return;
}
this.#hasReferencedJsxFactory = this.referenceInSomeUpperScope(this.#jsxPragma);
}
///////////////////
// Visit helpers //
///////////////////
visitClass(node) {
ClassVisitor_1.ClassVisitor.visit(this, node);
}
visitForIn(node) {
if (node.left.type === types_1.AST_NODE_TYPES.VariableDeclaration &&
node.left.kind !== 'var') {
this.scopeManager.nestForScope(node);
}
if (node.left.type === types_1.AST_NODE_TYPES.VariableDeclaration) {
this.visit(node.left);
this.visitPattern(node.left.declarations[0].id, pattern => {
this.currentScope().referenceValue(pattern, Reference_1.ReferenceFlag.Write, node.right, null, true);
});
}
else {
this.visitPattern(node.left, (pattern, info) => {
const maybeImplicitGlobal = !this.currentScope().isStrict
? {
node,
pattern,
}
: null;
this.referencingDefaultValue(pattern, info.assignments, maybeImplicitGlobal, false);
this.currentScope().referenceValue(pattern, Reference_1.ReferenceFlag.Write, node.right, maybeImplicitGlobal, false);
}, { processRightHandNodes: true });
}
this.visit(node.right);
this.visit(node.body);
this.close(node);
}
visitFunction(node) {
// FunctionDeclaration name is defined in upper scope
// NOTE: Not referring variableScope. It is intended.
// Since
// in ES5, FunctionDeclaration should be in FunctionBody.
// in ES6, FunctionDeclaration should be block scoped.
if (node.type === types_1.AST_NODE_TYPES.FunctionExpression) {
if (node.id) {
// FunctionExpression with name creates its special scope;
// FunctionExpressionNameScope.
this.scopeManager.nestFunctionExpressionNameScope(node);
}
}
else if (node.id) {
// id is defined in upper scope
this.currentScope().defineIdentifier(node.id, new definition_1.FunctionNameDefinition(node.id, node));
}
// Consider this function is in the MethodDefinition.
this.scopeManager.nestFunctionScope(node, false);
// Process parameter declarations.
for (const param of node.params) {
this.visitPattern(param, (pattern, info) => {
this.currentScope().defineIdentifier(pattern, new definition_1.ParameterDefinition(pattern, node, info.rest));
this.referencingDefaultValue(pattern, info.assignments, null, true);
}, { processRightHandNodes: true });
this.visitFunctionParameterTypeAnnotation(param);
param.decorators.forEach(d => this.visit(d));
}
this.visitType(node.returnType);
this.visitType(node.typeParameters);
// In TypeScript there are a number of function-like constructs which have no body,
// so check it exists before traversing
if (node.body) {
// Skip BlockStatement to prevent creating BlockStatement scope.
if (node.body.type === types_1.AST_NODE_TYPES.BlockStatement) {
this.visitChildren(node.body);
}
else {
this.visit(node.body);
}
}
this.close(node);
}
visitFunctionParameterTypeAnnotation(node) {
switch (node.type) {
case types_1.AST_NODE_TYPES.AssignmentPattern:
this.visitType(node.left.typeAnnotation);
break;
case types_1.AST_NODE_TYPES.TSParameterProperty:
this.visitFunctionParameterTypeAnnotation(node.parameter);
break;
default:
this.visitType(node.typeAnnotation);
break;
}
}
visitProperty(node) {
if (node.computed) {
this.visit(node.key);
}
this.visit(node.value);
}
visitType(node) {
if (!node) {
return;
}
TypeVisitor_1.TypeVisitor.visit(this, node);
}
visitTypeAssertion(node) {
this.visit(node.expression);
this.visitType(node.typeAnnotation);
}
/////////////////////
// Visit selectors //
/////////////////////
ArrowFunctionExpression(node) {
this.visitFunction(node);
}
AssignmentExpression(node) {
const left = this.visitExpressionTarget(node.left);
if (PatternVisitor_1.PatternVisitor.isPattern(left)) {
if (node.operator === '=') {
this.visitPattern(left, (pattern, info) => {
const maybeImplicitGlobal = !this.currentScope().isStrict
? {
node,
pattern,
}
: null;
this.referencingDefaultValue(pattern, info.assignments, maybeImplicitGlobal, false);
this.currentScope().referenceValue(pattern, Reference_1.ReferenceFlag.Write, node.right, maybeImplicitGlobal, false);
}, { processRightHandNodes: true });
}
else if (left.type === types_1.AST_NODE_TYPES.Identifier) {
this.currentScope().referenceValue(left, Reference_1.ReferenceFlag.ReadWrite, node.right);
}
}
else {
this.visit(left);
}
this.visit(node.right);
}
BlockStatement(node) {
this.scopeManager.nestBlockScope(node);
this.visitChildren(node);
this.close(node);
}
BreakStatement() {
// don't reference the break statement's label
}
CallExpression(node) {
this.visitChildren(node, ['typeArguments']);
this.visitType(node.typeArguments);
}
CatchClause(node) {
this.scopeManager.nestCatchScope(node);
if (node.param) {
const param = node.param;
this.visitPattern(param, (pattern, info) => {
this.currentScope().defineIdentifier(pattern, new definition_1.CatchClauseDefinition(param, node));
this.referencingDefaultValue(pattern, info.assignments, null, true);
}, { processRightHandNodes: true });
}
this.visit(node.body);
this.close(node);
}
ClassDeclaration(node) {
this.visitClass(node);
}
ClassExpression(node) {
this.visitClass(node);
}
ContinueStatement() {
// don't reference the continue statement's label
}
ExportAllDeclaration() {
// this defines no local variables
}
ExportDefaultDeclaration(node) {
if (node.declaration.type === types_1.AST_NODE_TYPES.Identifier) {
ExportVisitor_1.ExportVisitor.visit(this, node);
}
else {
this.visit(node.declaration);
}
}
ExportNamedDeclaration(node) {
if (node.declaration) {
this.visit(node.declaration);
}
else {
ExportVisitor_1.ExportVisitor.visit(this, node);
}
}
ForInStatement(node) {
this.visitForIn(node);
}
ForOfStatement(node) {
this.visitForIn(node);
}
ForStatement(node) {
// Create ForStatement declaration.
// NOTE: In ES6, ForStatement dynamically generates per iteration environment. However, this is
// a static analyzer, we only generate one scope for ForStatement.
if (node.init &&
node.init.type === types_1.AST_NODE_TYPES.VariableDeclaration &&
node.init.kind !== 'var') {
this.scopeManager.nestForScope(node);
}
this.visitChildren(node);
this.close(node);
}
FunctionDeclaration(node) {
this.visitFunction(node);
}
FunctionExpression(node) {
this.visitFunction(node);
}
Identifier(node) {
this.currentScope().referenceValue(node);
this.visitType(node.typeAnnotation);
}
ImportAttribute() {
// import assertions are module metadata and thus have no variables to reference
}
ImportDeclaration(node) {
(0, assert_1.assert)(this.scopeManager.isModule(), 'ImportDeclaration should appear when the mode is ES6 and in the module context.');
ImportVisitor_1.ImportVisitor.visit(this, node);
}
JSXAttribute(node) {
this.visit(node.value);
}
JSXClosingElement() {
// should not be counted as a reference
}
JSXFragment(node) {
this.referenceJsxPragma();
this.referenceJsxFragment();
this.visitChildren(node);
}
JSXIdentifier(node) {
this.currentScope().referenceValue(node);
}
JSXMemberExpression(node) {
if (node.object.type !== types_1.AST_NODE_TYPES.JSXIdentifier ||
node.object.name !== 'this') {
this.visit(node.object);
}
// we don't ever reference the property as it's always going to be a property on the thing
}
JSXOpeningElement(node) {
this.referenceJsxPragma();
if (node.name.type === types_1.AST_NODE_TYPES.JSXIdentifier) {
if (node.name.name[0].toUpperCase() === node.name.name[0] ||
node.name.name === 'this') {
// lower cased component names are always treated as "intrinsic" names, and are converted to a string,
// not a variable by JSX transforms:
// <div /> => React.createElement("div", null)
// the only case we want to visit a lower-cased component has its name as "this",
this.visit(node.name);
}
}
else {
this.visit(node.name);
}
this.visitType(node.typeArguments);
for (const attr of node.attributes) {
this.visit(attr);
}
}
LabeledStatement(node) {
this.visit(node.body);
}
MemberExpression(node) {
this.visit(node.object);
if (node.computed) {
this.visit(node.property);
}
}
MetaProperty() {
// meta properties all builtin globals
}
NewExpression(node) {
this.visitChildren(node, ['typeArguments']);
this.visitType(node.typeArguments);
}
PrivateIdentifier() {
// private identifiers are members on classes and thus have no variables to reference
}
Program(node) {
const globalScope = this.scopeManager.nestGlobalScope(node);
this.populateGlobalsFromLib(globalScope);
if (this.scopeManager.isGlobalReturn()) {
// Force strictness of GlobalScope to false when using node.js scope.
this.currentScope().isStrict = false;
this.scopeManager.nestFunctionScope(node, false);
}
if (this.scopeManager.isModule()) {
this.scopeManager.nestModuleScope(node);
}
if (this.scopeManager.isImpliedStrict()) {
this.currentScope().isStrict = true;
}
this.visitChildren(node);
this.close(node);
}
Property(node) {
this.visitProperty(node);
}
SwitchStatement(node) {
this.visit(node.discriminant);
this.scopeManager.nestSwitchScope(node);
for (const switchCase of node.cases) {
this.visit(switchCase);
}
this.close(node);
}
TaggedTemplateExpression(node) {
this.visit(node.tag);
this.visit(node.quasi);
this.visitType(node.typeArguments);
}
TSAsExpression(node) {
this.visitTypeAssertion(node);
}
TSDeclareFunction(node) {
this.visitFunction(node);
}
TSEmptyBodyFunctionExpression(node) {
this.visitFunction(node);
}
TSEnumDeclaration(node) {
this.currentScope().defineIdentifier(node.id, new definition_1.TSEnumNameDefinition(node.id, node));
// enum members can be referenced within the enum body
this.scopeManager.nestTSEnumScope(node);
for (const member of node.body.members) {
// TS resolves literal named members to be actual names
// enum Foo {
// 'a' = 1,
// b = a, // this references the 'a' member
// }
if (member.id.type === types_1.AST_NODE_TYPES.Literal &&
typeof member.id.value === 'string') {
const name = member.id;
this.currentScope().defineLiteralIdentifier(name, new definition_1.TSEnumMemberDefinition(name, member));
}
else if (!member.computed &&
member.id.type === types_1.AST_NODE_TYPES.Identifier) {
this.currentScope().defineIdentifier(member.id, new definition_1.TSEnumMemberDefinition(member.id, member));
}
this.visit(member.initializer);
}
this.close(node);
}
TSExportAssignment(node) {
if (node.expression.type === types_1.AST_NODE_TYPES.Identifier) {
// this is a special case - you can `export = T` where `T` is a type OR a
// value however `T[U]` is illegal when `T` is a type and `T.U` is illegal
// when `T.U` is a type
// i.e. if the expression is JUST an Identifier - it could be either ref
// kind; otherwise the standard rules apply
this.currentScope().referenceDualValueType(node.expression);
}
else {
this.visit(node.expression);
}
}
TSImportEqualsDeclaration(node) {
this.currentScope().defineIdentifier(node.id, new definition_1.ImportBindingDefinition(node.id, node, node));
if (node.moduleReference.type === types_1.AST_NODE_TYPES.TSQualifiedName) {
let moduleIdentifier = node.moduleReference.left;
while (moduleIdentifier.type === types_1.AST_NODE_TYPES.TSQualifiedName) {
moduleIdentifier = moduleIdentifier.left;
}
this.visit(moduleIdentifier);
}
else {
this.visit(node.moduleReference);
}
}
TSInstantiationExpression(node) {
this.visitChildren(node, ['typeArguments']);
this.visitType(node.typeArguments);
}
TSInterfaceDeclaration(node) {
this.visitType(node);
}
TSModuleDeclaration(node) {
if (node.id.type === types_1.AST_NODE_TYPES.Identifier && node.kind !== 'global') {
this.currentScope().defineIdentifier(node.id, new definition_1.TSModuleNameDefinition(node.id, node));
}
this.scopeManager.nestTSModuleScope(node);
this.visit(node.body);
this.close(node);
}
TSSatisfiesExpression(node) {
this.visitTypeAssertion(node);
}
TSTypeAliasDeclaration(node) {
this.visitType(node);
}
TSTypeAssertion(node) {
this.visitTypeAssertion(node);
}
UpdateExpression(node) {
const argument = this.visitExpressionTarget(node.argument);
if (PatternVisitor_1.PatternVisitor.isPattern(argument)) {
this.visitPattern(argument, pattern => {
this.currentScope().referenceValue(pattern, Reference_1.ReferenceFlag.ReadWrite, null);
});
}
else {
this.visitChildren(node);
}
}
VariableDeclaration(node) {
const variableTargetScope = node.kind === 'var'
? this.currentScope().variableScope
: this.currentScope();
for (const decl of node.declarations) {
const init = decl.init;
this.visitPattern(decl.id, (pattern, info) => {
variableTargetScope.defineIdentifier(pattern, new definition_1.VariableDefinition(pattern, decl, node));
this.referencingDefaultValue(pattern, info.assignments, null, true);
if (init) {
this.currentScope().referenceValue(pattern, Reference_1.ReferenceFlag.Write, init, null, true);
}
}, { processRightHandNodes: true });
this.visit(decl.init);
this.visitType(decl.id.typeAnnotation);
}
}
WithStatement(node) {
this.visit(node.object);
// Then nest scope for WithStatement.
this.scopeManager.nestWithScope(node);
this.visit(node.body);
this.close(node);
}
visitExpressionTarget(left) {
switch (left.type) {
case types_1.AST_NODE_TYPES.TSAsExpression:
case types_1.AST_NODE_TYPES.TSTypeAssertion:
// explicitly visit the type annotation
this.visitType(left.typeAnnotation);
// intentional fallthrough
case types_1.AST_NODE_TYPES.TSNonNullExpression:
// unwrap the expression
left = left.expression;
}
return left;
}
}
exports.Referencer = Referencer;
//# sourceMappingURL=Referencer.js.map
File diff suppressed because one or more lines are too long
+74
View File
@@ -0,0 +1,74 @@
{
"name": "@typescript-eslint/scope-manager",
"version": "8.14.0",
"description": "TypeScript scope analyser for ESLint",
"files": [
"dist",
"package.json",
"README.md",
"LICENSE"
],
"type": "commonjs",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./package.json": "./package.json"
},
"types": "./dist/index.d.ts",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"repository": {
"type": "git",
"url": "https://github.com/typescript-eslint/typescript-eslint.git",
"directory": "packages/scope-manager"
},
"bugs": {
"url": "https://github.com/typescript-eslint/typescript-eslint/issues"
},
"homepage": "https://typescript-eslint.io/packages/scope-manager",
"license": "MIT",
"keywords": [
"eslint",
"typescript",
"estree"
],
"scripts": {
"build": "npx nx build",
"clean": "npx nx clean",
"clean-fixtures": "npx nx clean-fixtures",
"format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore",
"generate-lib": "npx nx generate-lib repo",
"lint": "npx nx lint",
"test": "npx nx test --code-coverage",
"typecheck": "npx nx typecheck"
},
"dependencies": {
"@typescript-eslint/types": "8.14.0",
"@typescript-eslint/visitor-keys": "8.14.0"
},
"devDependencies": {
"@jest/types": "29.6.3",
"@types/glob": "*",
"@typescript-eslint/typescript-estree": "8.14.0",
"glob": "*",
"jest-specific-snapshot": "*",
"make-dir": "*",
"prettier": "^3.2.5",
"pretty-format": "*",
"typescript": "*"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"typesVersions": {
"<4.7": {
"*": [
"_ts4.3/*"
]
}
}
}
+80
View File
@@ -0,0 +1,80 @@
{
"name": "@typescript-eslint/type-utils",
"version": "8.14.0",
"description": "Type utilities for working with TypeScript + ESLint together",
"files": [
"dist",
"_ts4.3",
"package.json",
"README.md",
"LICENSE"
],
"type": "commonjs",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./package.json": "./package.json"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"repository": {
"type": "git",
"url": "https://github.com/typescript-eslint/typescript-eslint.git",
"directory": "packages/type-utils"
},
"bugs": {
"url": "https://github.com/typescript-eslint/typescript-eslint/issues"
},
"homepage": "https://typescript-eslint.io",
"license": "MIT",
"keywords": [
"eslint",
"typescript",
"estree"
],
"scripts": {
"build": "tsc -b tsconfig.build.json",
"postbuild": "downlevel-dts dist _ts4.3/dist --to=4.3",
"clean": "tsc -b tsconfig.build.json --clean",
"postclean": "rimraf dist && rimraf _ts3.4 && rimraf _ts4.3 && rimraf coverage",
"format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore",
"lint": "npx nx lint",
"test": "jest --coverage",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@typescript-eslint/typescript-estree": "8.14.0",
"@typescript-eslint/utils": "8.14.0",
"debug": "^4.3.4",
"ts-api-utils": "^1.3.0"
},
"devDependencies": {
"@jest/types": "29.6.3",
"@typescript-eslint/parser": "8.14.0",
"ajv": "^6.12.6",
"downlevel-dts": "*",
"jest": "29.7.0",
"prettier": "^3.2.5",
"rimraf": "*",
"typescript": "*"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"typesVersions": {
"<4.7": {
"*": [
"_ts4.3/*"
]
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+173
View File
@@ -0,0 +1,173 @@
import type * as TSESTree from './generated/ast-spec';
declare module './generated/ast-spec' {
interface BaseNode {
parent: TSESTree.Node;
}
interface Program {
/**
* @remarks This never-used property exists only as a convenience for code that tries to access node parents repeatedly.
*/
parent?: never;
}
interface AccessorPropertyComputedName {
parent: TSESTree.ClassBody;
}
interface AccessorPropertyNonComputedName {
parent: TSESTree.ClassBody;
}
interface TSAbstractAccessorPropertyComputedName {
parent: TSESTree.ClassBody;
}
interface TSAbstractAccessorPropertyNonComputedName {
parent: TSESTree.ClassBody;
}
interface VariableDeclaratorDefiniteAssignment {
parent: TSESTree.VariableDeclaration;
}
interface VariableDeclaratorMaybeInit {
parent: TSESTree.VariableDeclaration;
}
interface VariableDeclaratorNoInit {
parent: TSESTree.VariableDeclaration;
}
interface UsingInForOfDeclarator {
parent: TSESTree.VariableDeclaration;
}
interface UsingInNormalContextDeclarator {
parent: TSESTree.VariableDeclaration;
}
interface CatchClause {
parent: TSESTree.TryStatement;
}
interface ClassBody {
parent: TSESTree.ClassDeclaration | TSESTree.ClassExpression;
}
interface ImportAttribute {
parent: TSESTree.ExportAllDeclaration | TSESTree.ExportNamedDeclaration | TSESTree.ImportDeclaration;
}
interface ImportDefaultSpecifier {
parent: TSESTree.ImportDeclaration;
}
interface ImportNamespaceSpecifier {
parent: TSESTree.ImportDeclaration;
}
interface ImportSpecifier {
parent: TSESTree.ExportAllDeclaration | TSESTree.ExportNamedDeclaration | TSESTree.ImportDeclaration;
}
interface JSXAttribute {
parent: TSESTree.JSXOpeningElement;
}
interface JSXClosingElement {
parent: TSESTree.JSXElement;
}
interface JSXClosingFragment {
parent: TSESTree.JSXFragment;
}
interface JSXOpeningElement {
parent: TSESTree.JSXElement;
}
interface JSXOpeningFragment {
parent: TSESTree.JSXFragment;
}
interface JSXSpreadAttribute {
parent: TSESTree.JSXOpeningElement;
}
interface MethodDefinitionComputedName {
parent: TSESTree.ClassBody;
}
interface MethodDefinitionNonComputedName {
parent: TSESTree.ClassBody;
}
interface TSAbstractMethodDefinitionComputedName {
parent: TSESTree.ClassBody;
}
interface TSAbstractMethodDefinitionNonComputedName {
parent: TSESTree.ClassBody;
}
interface PropertyComputedName {
parent: TSESTree.ObjectExpression | TSESTree.ObjectPattern;
}
interface PropertyNonComputedName {
parent: TSESTree.ObjectExpression | TSESTree.ObjectPattern;
}
interface PropertyDefinitionComputedName {
parent: TSESTree.ClassBody;
}
interface PropertyDefinitionNonComputedName {
parent: TSESTree.ClassBody;
}
interface TSAbstractPropertyDefinitionComputedName {
parent: TSESTree.ClassBody;
}
interface TSAbstractPropertyDefinitionNonComputedName {
parent: TSESTree.ClassBody;
}
interface SpreadElement {
parent: TSESTree.ArrayExpression | TSESTree.CallExpression | TSESTree.NewExpression | TSESTree.ObjectExpression;
}
interface StaticBlock {
parent: TSESTree.ClassBody;
}
interface SwitchCase {
parent: TSESTree.SwitchStatement;
}
interface TemplateElement {
parent: TSESTree.TemplateLiteral | TSESTree.TSTemplateLiteralType;
}
interface TSCallSignatureDeclaration {
parent: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral;
}
interface TSConstructSignatureDeclaration {
parent: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral;
}
interface TSClassImplements {
parent: TSESTree.ClassDeclaration | TSESTree.ClassExpression;
}
interface TSEnumBody {
parent: TSESTree.TSEnumDeclaration;
}
interface TSEnumMemberComputedName {
parent: TSESTree.TSEnumBody;
}
interface TSEnumMemberNonComputedName {
parent: TSESTree.TSEnumBody;
}
interface TSIndexSignature {
parent: TSESTree.ClassBody | TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral;
}
interface TSInterfaceBody {
parent: TSESTree.TSInterfaceDeclaration;
}
interface TSInterfaceHeritage {
parent: TSESTree.TSInterfaceBody;
}
interface TSMethodSignatureComputedName {
parent: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral;
}
interface TSMethodSignatureNonComputedName {
parent: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral;
}
interface TSModuleBlock {
parent: TSESTree.TSModuleDeclaration;
}
interface TSParameterProperty {
parent: TSESTree.FunctionLike;
}
interface TSPropertySignatureComputedName {
parent: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral;
}
interface TSPropertySignatureNonComputedName {
parent: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral;
}
interface TSTypeParameter {
parent: TSESTree.TSInferType | TSESTree.TSMappedType | TSESTree.TSTypeParameterDeclaration;
}
interface ExportSpecifierWithIdentifierLocal {
parent: TSESTree.ExportNamedDeclaration;
}
interface ExportSpecifierWithStringOrLiteralLocal {
parent: TSESTree.ExportNamedDeclaration;
}
}
export * as TSESTree from './generated/ast-spec';
//# sourceMappingURL=ts-estree.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"ts-estree.d.ts","sourceRoot":"","sources":["../src/ts-estree.ts"],"names":[],"mappings":"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"}
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"ts-estree.js","sourceRoot":"","sources":["../src/ts-estree.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAkOA,iEAAiD"}
+88
View File
@@ -0,0 +1,88 @@
{
"name": "@typescript-eslint/types",
"version": "8.14.0",
"description": "Types for the TypeScript-ESTree AST spec",
"files": [
"dist",
"_ts4.3",
"package.json",
"README.md",
"LICENSE"
],
"type": "commonjs",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./package.json": "./package.json"
},
"types": "./dist/index.d.ts",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"repository": {
"type": "git",
"url": "https://github.com/typescript-eslint/typescript-eslint.git",
"directory": "packages/types"
},
"bugs": {
"url": "https://github.com/typescript-eslint/typescript-eslint/issues"
},
"homepage": "https://typescript-eslint.io",
"license": "MIT",
"keywords": [
"eslint",
"typescript",
"estree"
],
"scripts": {
"copy-ast-spec": "tsx ./tools/copy-ast-spec.ts",
"build": "tsc -b tsconfig.build.json",
"postbuild": "downlevel-dts dist _ts4.3/dist --to=4.3",
"clean": "tsc -b tsconfig.build.json --clean",
"postclean": "rimraf dist && rimraf src/generated && rimraf _ts3.4 && rimraf _ts4.3 && rimraf coverage",
"format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore",
"generate-lib": "npx nx run scope-manager:generate-lib",
"lint": "npx nx lint",
"typecheck": "tsc --noEmit"
},
"nx": {
"targets": {
"copy-ast-spec": {
"dependsOn": [
"^build"
],
"outputs": [
"{projectRoot}/src/generated"
],
"cache": true
},
"build": {
"dependsOn": [
"^build",
"copy-ast-spec"
]
}
}
},
"devDependencies": {
"@jest/types": "29.6.3",
"downlevel-dts": "*",
"prettier": "^3.2.5",
"rimraf": "*",
"tsx": "*",
"typescript": "*"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"typesVersions": {
"<4.7": {
"*": [
"_ts4.3/*"
]
}
}
}
@@ -0,0 +1 @@
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EACV,aAAa,EACb,2BAA2B,EAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAoB,MAAM,EAAE,MAAM,aAAa,CAAC;AAmCtE,MAAM,WAAW,gBAAgB;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,kCAAkC,CAAC,EAAE,OAAO,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,wBAAwB,GAAG,EAAE,CAAC,sBAAsB,GAC1D,OAAO,CAMT;AAED,MAAM,WAAW,OAAO;IACtB,qBAAqB,EAAE,2BAA2B,CAAC;IACnD,qBAAqB,EAAE,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED,qBAAa,SAAS;;IACpB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAgB;IACpC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiB;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiB;IAEvD;;;;;OAKG;gBACS,GAAG,EAAE,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,gBAAgB;IAsZ1D,OAAO,CAAC,qBAAqB;IAsB7B,OAAO,CAAC,oCAAoC;IAe5C;;;;;OAKG;IACH,OAAO,CAAC,sBAAsB;IAiC9B,OAAO,CAAC,sBAAsB;IA4C9B;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAIpB;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAItB;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAsB7B;;;;;OAKG;IACH,OAAO,CAAC,gDAAgD;IAexD;;;;OAIG;IACH,OAAO,CAAC,kDAAkD;IAmB1D;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;;;;;OAMG;IACH,OAAO,CAAC,SAAS;IA8BjB,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,+BAA+B;IAiDvC;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IA8BzB,OAAO,CAAC,sBAAsB;IAoC9B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAczB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IA09EnB,OAAO,CAAC,UAAU;IAelB,cAAc,IAAI,QAAQ,CAAC,OAAO;IAIlC;;;;OAIG;IACH,OAAO,CAAC,UAAU;IA0FlB;;;OAGG;IACH,OAAO,CAAC,UAAU;IAiFlB,UAAU,IAAI,OAAO;IAOrB;;OAEG;IACH,OAAO,CAAC,uBAAuB;CAYhC"}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+91
View File
@@ -0,0 +1,91 @@
{
"name": "@typescript-eslint/typescript-estree",
"version": "8.14.0",
"description": "A parser that converts TypeScript source code into an ESTree compatible form",
"files": [
"dist",
"_ts4.3",
"README.md",
"LICENSE"
],
"type": "commonjs",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./package.json": "./package.json",
"./use-at-your-own-risk": {
"types": "./dist/use-at-your-own-risk.d.ts",
"default": "./dist/use-at-your-own-risk.js"
}
},
"types": "./dist/index.d.ts",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"repository": {
"type": "git",
"url": "https://github.com/typescript-eslint/typescript-eslint.git",
"directory": "packages/typescript-estree"
},
"bugs": {
"url": "https://github.com/typescript-eslint/typescript-eslint/issues"
},
"homepage": "https://typescript-eslint.io/packages/typescript-estree",
"license": "BSD-2-Clause",
"keywords": [
"ast",
"estree",
"ecmascript",
"javascript",
"typescript",
"parser",
"syntax"
],
"scripts": {
"build": "tsc -b tsconfig.build.json",
"postbuild": "downlevel-dts dist _ts4.3/dist --to=4.3",
"clean": "tsc -b tsconfig.build.json --clean",
"postclean": "rimraf dist && rimraf _ts4.3 && rimraf coverage",
"format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore",
"lint": "npx nx lint",
"test": "jest --coverage --runInBand --verbose",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@typescript-eslint/types": "8.14.0",
"@typescript-eslint/visitor-keys": "8.14.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
"minimatch": "^9.0.4",
"semver": "^7.6.0",
"ts-api-utils": "^1.3.0"
},
"devDependencies": {
"@jest/types": "29.6.3",
"glob": "*",
"jest": "29.7.0",
"prettier": "^3.2.5",
"rimraf": "*",
"tmp": "*",
"typescript": "*"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"typesVersions": {
"<4.7": {
"*": [
"_ts4.3/*"
]
}
}
}
+265
View File
@@ -0,0 +1,265 @@
import type { Parser as ParserType } from './Parser';
import type * as ParserOptionsTypes from './ParserOptions';
import type { Processor as ProcessorType } from './Processor';
import type { LooseRuleDefinition, SharedConfigurationSettings } from './Rule';
/** @internal */
export declare namespace SharedConfig {
type Severity = 0 | 1 | 2;
type SeverityString = 'error' | 'off' | 'warn';
type RuleLevel = Severity | SeverityString;
type RuleLevelAndOptions = [RuleLevel, ...unknown[]];
type RuleEntry = RuleLevel | RuleLevelAndOptions;
type RulesRecord = Partial<Record<string, RuleEntry>>;
type GlobalVariableOptionBase = 'off' | /** @deprecated use `'readonly'` */ 'readable' | 'readonly' | 'writable' | /** @deprecated use `'writable'` */ 'writeable';
type GlobalVariableOptionBoolean = /** @deprecated use `'readonly'` */ false | /** @deprecated use `'writable'` */ true;
type GlobalVariableOption = GlobalVariableOptionBase | GlobalVariableOptionBoolean;
interface GlobalsConfig {
[name: string]: GlobalVariableOption;
}
interface EnvironmentConfig {
[name: string]: boolean;
}
type ParserOptions = ParserOptionsTypes.ParserOptions;
interface PluginMeta {
/**
* The meta.name property should match the npm package name for your plugin.
*/
name: string;
/**
* The meta.version property should match the npm package version for your plugin.
*/
version: string;
}
}
export declare namespace ClassicConfig {
export type EnvironmentConfig = SharedConfig.EnvironmentConfig;
export type GlobalsConfig = SharedConfig.GlobalsConfig;
export type GlobalVariableOption = SharedConfig.GlobalVariableOption;
export type GlobalVariableOptionBase = SharedConfig.GlobalVariableOptionBase;
export type ParserOptions = SharedConfig.ParserOptions;
export type RuleEntry = SharedConfig.RuleEntry;
export type RuleLevel = SharedConfig.RuleLevel;
export type RuleLevelAndOptions = SharedConfig.RuleLevelAndOptions;
export type RulesRecord = SharedConfig.RulesRecord;
export type Severity = SharedConfig.Severity;
export type SeverityString = SharedConfig.SeverityString;
interface BaseConfig {
$schema?: string;
/**
* The environment settings.
*/
env?: EnvironmentConfig;
/**
* The path to other config files or the package name of shareable configs.
*/
extends?: string | string[];
/**
* The global variable settings.
*/
globals?: GlobalsConfig;
/**
* The flag that disables directive comments.
*/
noInlineConfig?: boolean;
/**
* The override settings per kind of files.
*/
overrides?: ConfigOverride[];
/**
* The path to a parser or the package name of a parser.
*/
parser?: string | null;
/**
* The parser options.
*/
parserOptions?: ParserOptions;
/**
* The plugin specifiers.
*/
plugins?: string[];
/**
* The processor specifier.
*/
processor?: string;
/**
* The flag to report unused `eslint-disable` comments.
*/
reportUnusedDisableDirectives?: boolean;
/**
* The rule settings.
*/
rules?: RulesRecord;
/**
* The shared settings.
*/
settings?: SharedConfigurationSettings;
}
export interface ConfigOverride extends BaseConfig {
excludedFiles?: string | string[];
files: string | string[];
}
export interface Config extends BaseConfig {
/**
* The glob patterns that ignore to lint.
*/
ignorePatterns?: string | string[];
/**
* The root flag.
*/
root?: boolean;
}
export {};
}
export declare namespace FlatConfig {
type EcmaVersion = ParserOptionsTypes.EcmaVersion;
type GlobalsConfig = SharedConfig.GlobalsConfig;
type Parser = ParserType.LooseParserModule;
type ParserOptions = SharedConfig.ParserOptions;
type PluginMeta = SharedConfig.PluginMeta;
type Processor = ProcessorType.LooseProcessorModule;
type RuleEntry = SharedConfig.RuleEntry;
type RuleLevel = SharedConfig.RuleLevel;
type RuleLevelAndOptions = SharedConfig.RuleLevelAndOptions;
type Rules = SharedConfig.RulesRecord;
type Settings = SharedConfigurationSettings;
type Severity = SharedConfig.Severity;
type SeverityString = SharedConfig.SeverityString;
type SourceType = 'commonjs' | ParserOptionsTypes.SourceType;
interface SharedConfigs {
[key: string]: Config | ConfigArray;
}
interface Plugin {
/**
* Shared configurations bundled with the plugin.
* Users will reference these directly in their config (i.e. `plugin.configs.recommended`).
*/
configs?: SharedConfigs;
/**
* Metadata about your plugin for easier debugging and more effective caching of plugins.
*/
meta?: {
[K in keyof PluginMeta]?: PluginMeta[K] | undefined;
};
/**
* The definition of plugin processors.
* Users can stringly reference the processor using the key in their config (i.e., `"pluginName/processorName"`).
*/
processors?: Partial<Record<string, Processor>> | undefined;
/**
* The definition of plugin rules.
* The key must be the name of the rule that users will use
* Users can stringly reference the rule using the key they registered the plugin under combined with the rule name.
* i.e. for the user config `plugins: { foo: pluginReference }` - the reference would be `"foo/ruleName"`.
*/
rules?: Record<string, LooseRuleDefinition> | undefined;
}
interface Plugins {
/**
* We intentionally omit the `configs` key from this object because it avoids
* type conflicts with old plugins that haven't updated their configs to flat configs yet.
* It's valid to reference these old plugins because ESLint won't access the
* `.config` property of a plugin when evaluating a flat config.
*/
[pluginAlias: string]: Omit<Plugin, 'configs'>;
}
interface LinterOptions {
/**
* A Boolean value indicating if inline configuration is allowed.
*/
noInlineConfig?: boolean;
/**
* A severity string indicating if and how unused disable and enable
* directives should be tracked and reported. For legacy compatibility, `true`
* is equivalent to `"warn"` and `false` is equivalent to `"off"`.
* @default "off"
*/
reportUnusedDisableDirectives?: boolean | SharedConfig.Severity | SharedConfig.SeverityString;
}
interface LanguageOptions {
/**
* The version of ECMAScript to support.
* May be any year (i.e., `2022`) or version (i.e., `5`).
* Set to `"latest"` for the most recent supported version.
* @default "latest"
*/
ecmaVersion?: EcmaVersion | undefined;
/**
* An object specifying additional objects that should be added to the global scope during linting.
*/
globals?: GlobalsConfig | undefined;
/**
* An object containing a `parse()` method or a `parseForESLint()` method.
* @default
* ```
* // https://github.com/eslint/espree
* require('espree')
* ```
*/
parser?: Parser | undefined;
/**
* An object specifying additional options that are passed directly to the parser.
* The available options are parser-dependent.
*/
parserOptions?: ParserOptions | undefined;
/**
* The type of JavaScript source code.
* Possible values are `"script"` for traditional script files, `"module"` for ECMAScript modules (ESM), and `"commonjs"` for CommonJS files.
* @default
* ```
* // for `.js` and `.mjs` files
* "module"
* // for `.cjs` files
* "commonjs"
* ```
*/
sourceType?: SourceType | undefined;
}
interface Config {
/**
* An array of glob patterns indicating the files that the configuration object should apply to.
* If not specified, the configuration object applies to all files matched by any other configuration object.
*/
files?: (string | string[])[];
/**
* An array of glob patterns indicating the files that the configuration object should not apply to.
* If not specified, the configuration object applies to all files matched by files.
*/
ignores?: string[];
/**
* An object containing settings related to how JavaScript is configured for linting.
*/
languageOptions?: LanguageOptions;
/**
* An object containing settings related to the linting process.
*/
linterOptions?: LinterOptions;
/**
* An string to identify the configuration object. Used in error messages and inspection tools.
*/
name?: string;
/**
* An object containing a name-value mapping of plugin names to plugin objects.
* When `files` is specified, these plugins are only available to the matching files.
*/
plugins?: Plugins;
/**
* Either an object containing `preprocess()` and `postprocess()` methods or
* a string indicating the name of a processor inside of a plugin
* (i.e., `"pluginName/processorName"`).
*/
processor?: string | Processor;
/**
* An object containing the configured rules.
* When `files` or `ignores` are specified, these rule configurations are only available to the matching files.
*/
rules?: Rules;
/**
* An object containing name-value pairs of information that should be available to all rules.
*/
settings?: Settings;
}
type ConfigArray = Config[];
type ConfigPromise = Promise<ConfigArray>;
type ConfigFile = ConfigArray | ConfigPromise;
}
//# sourceMappingURL=Config.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../src/ts-eslint/Config.ts"],"names":[],"mappings":"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"}
+92
View File
@@ -0,0 +1,92 @@
{
"name": "@typescript-eslint/utils",
"version": "8.14.0",
"description": "Utilities for working with TypeScript + ESLint together",
"files": [
"dist",
"_ts4.3",
"package.json",
"README.md",
"LICENSE"
],
"type": "commonjs",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./ast-utils": {
"types": "./dist/ast-utils/index.d.ts",
"default": "./dist/ast-utils/index.js"
},
"./eslint-utils": {
"types": "./dist/eslint-utils/index.d.ts",
"default": "./dist/eslint-utils/index.js"
},
"./json-schema": {
"types": "./dist/json-schema.d.ts",
"default": "./dist/json-schema.js"
},
"./ts-eslint": {
"types": "./dist/ts-eslint/index.d.ts",
"default": "./dist/ts-eslint/index.js"
},
"./package.json": "./package.json"
},
"types": "./dist/index.d.ts",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"repository": {
"type": "git",
"url": "https://github.com/typescript-eslint/typescript-eslint.git",
"directory": "packages/utils"
},
"bugs": {
"url": "https://github.com/typescript-eslint/typescript-eslint/issues"
},
"homepage": "https://typescript-eslint.io/packages/utils",
"license": "MIT",
"keywords": [
"eslint",
"typescript",
"estree"
],
"scripts": {
"build": "tsc -b tsconfig.build.json",
"postbuild": "downlevel-dts dist _ts4.3/dist --to=4.3",
"clean": "tsc -b tsconfig.build.json --clean",
"postclean": "rimraf dist && rimraf _ts3.4 && rimraf _ts4.3 && rimraf coverage",
"format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore",
"lint": "npx nx lint",
"test": "jest --coverage",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"@typescript-eslint/scope-manager": "8.14.0",
"@typescript-eslint/types": "8.14.0",
"@typescript-eslint/typescript-estree": "8.14.0"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0"
},
"devDependencies": {
"downlevel-dts": "*",
"jest": "29.7.0",
"prettier": "^3.2.5",
"rimraf": "*",
"typescript": "*"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"typesVersions": {
"<4.7": {
"*": [
"_ts4.3/*"
]
}
}
}
+186
View File
@@ -0,0 +1,186 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.visitorKeys = void 0;
const eslintVisitorKeys = __importStar(require("eslint-visitor-keys"));
/*
********************************** IMPORTANT NOTE ********************************
* *
* The key arrays should be sorted in the order in which you would want to visit *
* the child keys. *
* *
* DO NOT SORT THEM ALPHABETICALLY! *
* *
* They should be sorted in the order that they appear in the source code. *
* For example: *
* *
* class Foo extends Bar { prop: 1 } *
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ClassDeclaration *
* ^^^ id ^^^ superClass *
* ^^^^^^^^^^^ body *
* *
* It would be incorrect to provide the visitor keys ['body', 'id', 'superClass'] *
* because the body comes AFTER everything else in the source code. *
* Instead the correct ordering would be ['id', 'superClass', 'body']. *
* *
**********************************************************************************
*/
const SharedVisitorKeys = (() => {
const FunctionType = ['typeParameters', 'params', 'returnType'];
const AnonymousFunction = [...FunctionType, 'body'];
const AbstractPropertyDefinition = [
'decorators',
'key',
'typeAnnotation',
];
return {
AbstractPropertyDefinition: ['decorators', 'key', 'typeAnnotation'],
AnonymousFunction,
AsExpression: ['expression', 'typeAnnotation'],
ClassDeclaration: [
'decorators',
'id',
'typeParameters',
'superClass',
'superTypeArguments',
'implements',
'body',
],
Function: ['id', ...AnonymousFunction],
FunctionType,
PropertyDefinition: [...AbstractPropertyDefinition, 'value'],
};
})();
const additionalKeys = {
AccessorProperty: SharedVisitorKeys.PropertyDefinition,
ArrayPattern: ['decorators', 'elements', 'typeAnnotation'],
ArrowFunctionExpression: SharedVisitorKeys.AnonymousFunction,
AssignmentPattern: ['decorators', 'left', 'right', 'typeAnnotation'],
CallExpression: ['callee', 'typeArguments', 'arguments'],
ClassDeclaration: SharedVisitorKeys.ClassDeclaration,
ClassExpression: SharedVisitorKeys.ClassDeclaration,
Decorator: ['expression'],
ExportAllDeclaration: ['exported', 'source', 'assertions'],
ExportNamedDeclaration: ['declaration', 'specifiers', 'source', 'assertions'],
FunctionDeclaration: SharedVisitorKeys.Function,
FunctionExpression: SharedVisitorKeys.Function,
Identifier: ['decorators', 'typeAnnotation'],
ImportAttribute: ['key', 'value'],
ImportDeclaration: ['specifiers', 'source', 'assertions'],
ImportExpression: ['source', 'options'],
JSXClosingFragment: [],
JSXOpeningElement: ['name', 'typeArguments', 'attributes'],
JSXOpeningFragment: [],
JSXSpreadChild: ['expression'],
MethodDefinition: ['decorators', 'key', 'value'],
NewExpression: ['callee', 'typeArguments', 'arguments'],
ObjectPattern: ['decorators', 'properties', 'typeAnnotation'],
PropertyDefinition: SharedVisitorKeys.PropertyDefinition,
RestElement: ['decorators', 'argument', 'typeAnnotation'],
StaticBlock: ['body'],
TaggedTemplateExpression: ['tag', 'typeArguments', 'quasi'],
TSAbstractAccessorProperty: SharedVisitorKeys.AbstractPropertyDefinition,
TSAbstractKeyword: [],
TSAbstractMethodDefinition: ['key', 'value'],
TSAbstractPropertyDefinition: SharedVisitorKeys.AbstractPropertyDefinition,
TSAnyKeyword: [],
TSArrayType: ['elementType'],
TSAsExpression: SharedVisitorKeys.AsExpression,
TSAsyncKeyword: [],
TSBigIntKeyword: [],
TSBooleanKeyword: [],
TSCallSignatureDeclaration: SharedVisitorKeys.FunctionType,
TSClassImplements: ['expression', 'typeArguments'],
TSConditionalType: ['checkType', 'extendsType', 'trueType', 'falseType'],
TSConstructorType: SharedVisitorKeys.FunctionType,
TSConstructSignatureDeclaration: SharedVisitorKeys.FunctionType,
TSDeclareFunction: SharedVisitorKeys.Function,
TSDeclareKeyword: [],
TSEmptyBodyFunctionExpression: ['id', ...SharedVisitorKeys.FunctionType],
TSEnumBody: ['members'],
TSEnumDeclaration: ['id', 'body'],
TSEnumMember: ['id', 'initializer'],
TSExportAssignment: ['expression'],
TSExportKeyword: [],
TSExternalModuleReference: ['expression'],
TSFunctionType: SharedVisitorKeys.FunctionType,
TSImportEqualsDeclaration: ['id', 'moduleReference'],
TSImportType: ['argument', 'qualifier', 'typeArguments'],
TSIndexedAccessType: ['indexType', 'objectType'],
TSIndexSignature: ['parameters', 'typeAnnotation'],
TSInferType: ['typeParameter'],
TSInstantiationExpression: ['expression', 'typeArguments'],
TSInterfaceBody: ['body'],
TSInterfaceDeclaration: ['id', 'typeParameters', 'extends', 'body'],
TSInterfaceHeritage: ['expression', 'typeArguments'],
TSIntersectionType: ['types'],
TSIntrinsicKeyword: [],
TSLiteralType: ['literal'],
TSMappedType: ['key', 'constraint', 'nameType', 'typeAnnotation'],
TSMethodSignature: ['typeParameters', 'key', 'params', 'returnType'],
TSModuleBlock: ['body'],
TSModuleDeclaration: ['id', 'body'],
TSNamedTupleMember: ['label', 'elementType'],
TSNamespaceExportDeclaration: ['id'],
TSNeverKeyword: [],
TSNonNullExpression: ['expression'],
TSNullKeyword: [],
TSNumberKeyword: [],
TSObjectKeyword: [],
TSOptionalType: ['typeAnnotation'],
TSParameterProperty: ['decorators', 'parameter'],
TSPrivateKeyword: [],
TSPropertySignature: ['typeAnnotation', 'key'],
TSProtectedKeyword: [],
TSPublicKeyword: [],
TSQualifiedName: ['left', 'right'],
TSReadonlyKeyword: [],
TSRestType: ['typeAnnotation'],
TSSatisfiesExpression: SharedVisitorKeys.AsExpression,
TSStaticKeyword: [],
TSStringKeyword: [],
TSSymbolKeyword: [],
TSTemplateLiteralType: ['quasis', 'types'],
TSThisType: [],
TSTupleType: ['elementTypes'],
TSTypeAliasDeclaration: ['id', 'typeParameters', 'typeAnnotation'],
TSTypeAnnotation: ['typeAnnotation'],
TSTypeAssertion: ['typeAnnotation', 'expression'],
TSTypeLiteral: ['members'],
TSTypeOperator: ['typeAnnotation'],
TSTypeParameter: ['name', 'constraint', 'default'],
TSTypeParameterDeclaration: ['params'],
TSTypeParameterInstantiation: ['params'],
TSTypePredicate: ['typeAnnotation', 'parameterName'],
TSTypeQuery: ['exprName', 'typeArguments'],
TSTypeReference: ['typeName', 'typeArguments'],
TSUndefinedKeyword: [],
TSUnionType: ['types'],
TSUnknownKeyword: [],
TSVoidKeyword: [],
};
const visitorKeys = eslintVisitorKeys.unionWith(additionalKeys);
exports.visitorKeys = visitorKeys;
//# sourceMappingURL=visitor-keys.js.map
@@ -0,0 +1 @@
{"version":3,"file":"visitor-keys.js","sourceRoot":"","sources":["../src/visitor-keys.ts"],"names":[],"mappings":"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"}
+73
View File
@@ -0,0 +1,73 @@
{
"name": "@typescript-eslint/visitor-keys",
"version": "8.14.0",
"description": "Visitor keys used to help traverse the TypeScript-ESTree AST",
"files": [
"dist",
"_ts4.3",
"package.json",
"README.md",
"LICENSE"
],
"type": "commonjs",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./package.json": "./package.json"
},
"types": "./dist/index.d.ts",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"repository": {
"type": "git",
"url": "https://github.com/typescript-eslint/typescript-eslint.git",
"directory": "packages/visitor-keys"
},
"bugs": {
"url": "https://github.com/typescript-eslint/typescript-eslint/issues"
},
"homepage": "https://typescript-eslint.io",
"license": "MIT",
"keywords": [
"eslint",
"typescript",
"estree"
],
"scripts": {
"build": "tsc -b tsconfig.build.json",
"postbuild": "downlevel-dts dist _ts4.3/dist --to=4.3",
"clean": "tsc -b tsconfig.build.json --clean",
"postclean": "rimraf dist && rimraf _ts3.4 && rimraf _ts4.3 && rimraf coverage",
"format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore",
"lint": "npx nx lint",
"test": "jest --coverage",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@typescript-eslint/types": "8.14.0",
"eslint-visitor-keys": "^3.4.3"
},
"devDependencies": {
"@jest/types": "29.6.3",
"@types/eslint-visitor-keys": "*",
"downlevel-dts": "*",
"jest": "29.7.0",
"prettier": "^3.2.5",
"rimraf": "*",
"typescript": "*"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"typesVersions": {
"<4.7": {
"*": [
"_ts4.3/*"
]
}
}
}