Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(utils): add ESLint CodePath selector types #7551

Merged
merged 15 commits into from Nov 13, 2023
79 changes: 76 additions & 3 deletions packages/eslint-plugin/typings/eslint-rules.d.ts
bradzacher marked this conversation as resolved.
Show resolved Hide resolved
Expand Up @@ -817,17 +817,90 @@ declare module 'eslint/lib/rules/no-invalid-this' {
],
{
// for ESLint < v8.7.0

Program?: (node: TSESTree.Program) => void;
'Program:exit'?: (node: TSESTree.Program) => void;

FunctionDeclaration?: (node: TSESTree.FunctionDeclaration) => void;
'FunctionDeclaration:exit'?: (node: TSESTree.FunctionDeclaration) => void;

FunctionExpression?: (node: TSESTree.FunctionExpression) => void;
'FunctionExpression:exit'?: (node: TSESTree.FunctionExpression) => void;

// for ESLint >= v8.7.0
// We don't use it and we don't have the CodePath types, so comment out it.
// onCodePathStart?: (codePath: unknown, node: TSESTree.Node) => void
// onCodePathEnd?: (codePath: unknown, node: TSESTree.Node) => void

/**
* The second parameter of `node` (with a type of `TSESTree.Node`) is
* [intentionally omitted in order to prevent TypeScript
* errors](https://github.com/typescript-eslint/typescript-eslint/issues/6993).
*
* If you want to use this method, you can either ignore the `node`
* parameter or specify it with a type assertion, depending on what you
* want to do.
*/
onCodePathStart?: (
codePath: TSESLint.CodePath,
// node: TSESTree.Node,
) => void;

/**
* The second parameter of `node` (with a type of `TSESTree.Node`) is
* [intentionally omitted in order to prevent TypeScript
* errors](https://github.com/typescript-eslint/typescript-eslint/issues/6993).
*
* If you want to use this method, you can either ignore the `node`
* parameter or specify it with a type assertion, depending on what you
* want to do.
*/
onCodePathEnd?: (
codePath: TSESLint.CodePath,
// node: TSESTree.Node,
) => void;

/**
* The second parameter of `node` (with a type of `TSESTree.Node`) is
* [intentionally omitted in order to prevent TypeScript
* errors](https://github.com/typescript-eslint/typescript-eslint/issues/6993).
*
* If you want to use this method, you can either ignore the `node`
* parameter or specify it with a type assertion, depending on what you
* want to do.
*/
onCodePathSegmentStart?: (
segment: TSESLint.CodePathSegment,
// node: TSESTree.Node,
) => void;

/**
* The second parameter of `node` (with a type of `TSESTree.Node`) is
* [intentionally omitted in order to prevent TypeScript
* errors](https://github.com/typescript-eslint/typescript-eslint/issues/6993).
*
* If you want to use this method, you can either ignore the `node`
* parameter or specify it with a type assertion, depending on what you
* want to do.
*/
onCodePathSegmentEnd?: (
segment: TSESLint.CodePathSegment,
// node: TSESTree.Node,
) => void;

/**
* The second parameter of `toSegment` (with a type of
* `TSESLint.CodePathSegment`) and the third parameter of `node` (with a
* type of `TSESTree.Node`) is [intentionally omitted in order to prevent
* TypeScript
* errors](https://github.com/typescript-eslint/typescript-eslint/issues/6993).
*
* If you want to use this method, you can either ignore those parameters
* or specify them with a type assertion, depending on what you want to
* do.
*/
onCodePathSegmentLoop?: (
fromSegment: TSESLint.CodePathSegment,
// toSegment: TSESLint.CodePathSegment,
// node: TSESTree.Node,
) => void;
Zamiell marked this conversation as resolved.
Show resolved Hide resolved

// Common
ThisExpression(node: TSESTree.ThisExpression): void;
Expand Down
58 changes: 58 additions & 0 deletions packages/utils/src/ts-eslint/Rule.ts
Expand Up @@ -284,6 +284,61 @@ interface RuleContext<
report(descriptor: ReportDescriptor<TMessageIds>): void;
}

/**
* Part of the code path analysis feature of ESLint:
* https://eslint.org/docs/latest/extend/code-path-analysis
*
* These are used in the `onCodePath*` methods. (Note that the `node` parameter
* of these methods is intentionally omitted.)
*
* @see https://github.com/typescript-eslint/typescript-eslint/issues/6993
*/
interface CodePath {
id: string;
initialSegment: CodePathSegment;
finalSegments: CodePathSegment[];
returnedSegments: CodePathSegment[];
thrownSegments: CodePathSegment[];
currentSegments: CodePathSegment[];
upper: CodePath | null;
childCodePaths: CodePath[];
Zamiell marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Part of the code path analysis feature of ESLint:
* https://eslint.org/docs/latest/extend/code-path-analysis
*
* These are used in the `onCodePath*` methods. (Note that the `node` parameter
* of these methods is intentionally omitted.)
*
* @see https://github.com/typescript-eslint/typescript-eslint/issues/6993
*/
interface CodePathSegment {
id: string;
nextSegments: CodePathSegment[];
prevSegments: CodePathSegment[];
reachable: boolean;
}

/**
* Part of the code path analysis feature of ESLint:
* https://eslint.org/docs/latest/extend/code-path-analysis
*
* This type is unused in the `typescript-eslint` codebase since putting it on
* the `nodeSelector` for `RuleListener` would break the existing definition.
* However, it is exported here for the purposes of manual type-assertion.
*
* @see https://github.com/typescript-eslint/typescript-eslint/issues/6993
*/
type CodePathFunction =
| ((
fromSegment: CodePathSegment,
toSegment: CodePathSegment,
node: TSESTree.Node,
) => void)
| ((codePath: CodePath, node: TSESTree.Node) => void)
| ((segment: CodePathSegment, node: TSESTree.Node) => void);

// This isn't the correct signature, but it makes it easier to do custom unions within reusable listeners
// never will break someone's code unless they specifically type the function argument
type RuleFunction<T extends TSESTree.NodeOrTokenData = never> = (
Expand Down Expand Up @@ -494,6 +549,9 @@ type AnyRuleCreateFunction = RuleCreateFunction<string, readonly unknown[]>;
export {
AnyRuleCreateFunction,
AnyRuleModule,
CodePath,
CodePathFunction,
CodePathSegment,
ReportDescriptor,
ReportDescriptorMessageData,
ReportFixFunction,
Expand Down