Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Enhancement: Support CodePath rule listener methods #6993

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

Closed
4 tasks done
NotWoods opened this issue May 5, 2023 · 8 comments Β· Fixed by #7551
Closed
4 tasks done

Enhancement: Support CodePath rule listener methods #6993

NotWoods opened this issue May 5, 2023 · 8 comments Β· Fixed by #7551
Labels
accepting prs Go ahead, send a pull request that resolves this issue enhancement New feature or request help wanted Extra attention is needed package: utils Issues related to the @typescript-eslint/utils package

Comments

@NotWoods
Copy link
Contributor

NotWoods commented May 5, 2023

Before You File a Proposal Please Confirm You Have Done The Following...

Relevant Package

utils

My proposal is suitable for this project

  • I believe my proposal would be useful to the broader TypeScript community (meaning it is not a niche proposal).

Description

Rules created using createRule currently don't have TypeScript support for the Code Path Analysis events. This would be great to add since they still work fine, its just that TypeScript complains.

I'd like to be able to use onCodePathStart, onCodePathEnd, onCodePathSegmentStart, onCodePathSegmentEnd, and onCodePathSegmentLoop as well as use an interface for CodePath and CodePathSegment,

Fail

N/A

Pass

createRule({
  meta: { ... },
  defaultOptions: [],
  create(context) {
    return {
      /**
       * @param {import('eslint').Rule.CodePath} codePath
       * @param {import('@typescript-eslint/utils').TSESTree.Node} node
       */
      onCodePathStart(codePath, node) {
        const isEffect = ASTUtils.isFunction(node) && isUseEffectCall(node.parent);
        functionInfoStack.push({ codePath, node, isEffect, listeners: [] });
      }
    }
  }
})

Additional Info

No response

@NotWoods NotWoods added enhancement New feature or request triage Waiting for team members to take a look labels May 5, 2023
@bradzacher
Copy link
Member

The reason we never added these is two fold:

  1. it's really, really rare that people want to use them - I don't think I've seen more than half a dozen rules that actually use them (including the ones in ESLint core).

  2. their form ((codePath: { id: string }, node: TSESTree.Node) => void) is incompatible with the node selector signature ((node: TSESTree.Node) => void). This causes TS errors because the code path signatures cannot be assigned to the index signature.

See existing Pr: #2930

Because the usecase is so very rare and it's a difficult problem to solve - we've just opted to not solve it yet.

If you can think of a way to add the definitions without harming the DevX of node selectors then I'm more than happy to have them added to the types!

I must really stress that it's important that we do not impact the DevX of selectors - there are thousands of node selectors written with our types - so we mustn't make them less safe, nor must we make them harder to use just to add types for this fraction of a fraction of a percent case.

@bradzacher bradzacher added help wanted Extra attention is needed package: utils Issues related to the @typescript-eslint/utils package accepting prs Go ahead, send a pull request that resolves this issue and removed triage Waiting for team members to take a look labels May 5, 2023
@Zamiell
Copy link
Contributor

Zamiell commented Aug 26, 2023

Just chiming in here to say that code paths are pretty nice to have.

Code paths are used in a few official ESLint rules, namely no-fallthrough. As you can see from looking at the source code for the rule, it is incredibly short, because all of the heavy-lifting is being done by the code paths feature. In other words, the code paths feature allows us to trivially determine when a particular switch statement case arm is a "fallthrough" case arm.

This functionality is also used in other rules that have to do with switch statements. For example, look at the source code for the newline-between-switch-case rule from eslint-plugin-switch-case. It also uses code paths to trivially detect the fallthrough case.

Of course, code paths are not just useful for rules about switch statements, but for other situations too. They are nice because we can detect certain kinds of situations without having the rule to be type aware, which obviously greatly hinders a rule's performance impact.

As a first baby step, I think that this project should export a CodePath interface at the very least. That would allow plugin authors to perform some manual type assertion. For example:

import type { TSESTree } from "@typescript-eslint/utils";

export const myRule = createRule<Options, MessageIds>({
  create(context) {
    return {
      // We must type assert `never` to `CodePath` because using the nodes
      // inside of a code path can cause problems with TypeScript.
      onCodePathStart(codePath as TSESTree.CodePath) {}
    };
  },

@bradzacher
Copy link
Member

To clarify - it's not that we don't think it's useful - there are some rare usecase for them and they can help solve some problems or simplify others!

Instead what were saying is that unfortunately TS isn't designed to support this usecase well - you can't define an index signature that has one value but also define members with a different, incompatible value.

So in order for us to add the signatures we'd have to break all the existing code that relies on the index signature - which is obviously an intractable solution - breaking 99.99% of cases to support 0.01% isn't good!

I'd welcome someone adding the codepath types - but we just can't add the signatures.

@armano2
Copy link
Collaborator

armano2 commented Aug 27, 2023

few months ago i tried to add it, but i got stuck with exactly same issue, see #6679

@Zamiell
Copy link
Contributor

Zamiell commented Aug 27, 2023

@armano2 What about a PR for just the interfaces?

@bradzacher
Copy link
Member

@Zamiell
Copy link
Contributor

Zamiell commented Nov 13, 2023

@JoshuaKGoldberg I don't think this issue should be closed actually, since I only added the CodePath interfaces in my PR (and not the rule listener methods).

@bradzacher
Copy link
Member

bradzacher commented Nov 13, 2023

We can't add the listener method definitions to the types without big changes in how TS works.
We rely on the [string]: (TSESTree.Node) => void signature to provide support for esquery selectors and that signature is fundamentally incompatible with the code path selector function signatures (none of which take TSESTree.Node as their first argument).

So unless TS adds a way for us to support both without degrading the experience of esquery selectors - we will have to close this as "fixed as best as we can for now".

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
accepting prs Go ahead, send a pull request that resolves this issue enhancement New feature or request help wanted Extra attention is needed package: utils Issues related to the @typescript-eslint/utils package
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants