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

Add methods that return information compatible with ESLint v9 #142

Closed
ota-meshi opened this issue Sep 23, 2023 · 8 comments
Closed

Add methods that return information compatible with ESLint v9 #142

ota-meshi opened this issue Sep 23, 2023 · 8 comments

Comments

@ota-meshi
Copy link
Member

ESLint v9 changes some context API.

eslint/eslint.org#471

So eslint plugin developers will need some workarounds if they want to support lower versions.

const scope = sourceCode.getScope
        ? sourceCode.getScope(node)
        : context.getScope();
const result = sourceCode.markVariableAsUsed
        ? sourceCode.markVariableAsUsed("foo", node)
        : context.markVariableAsUsed("foo");

const sourceCode = context.sourceCode ?? context.getSourceCode();
const cwd = context.cwd ?? context.getCwd();
const filename = context.filename ?? context.getFilename();
const physicalFilename = context.physicalFilename ?? context.getPhysicalFilename();

I would like to add a method to eslint-utils that can hide this workaround.

For example:

const sourceCode = eslintUtils.getSourceCode(context)

const scope = sourceCode.getScope(node) // The old ESLint works the same way as the ESLint v9 API.
const result = sourceCode.markVariableAsUsed("foo", node) // The old ESLint works the same way as the ESLint v9 API.
const cwd = eslintUtils.getCwd(context);
const filename = eslintUtils.getFilename(context);
const physicalFilename = eslintUtils.getPhysicalFilename(context);
@ota-meshi
Copy link
Member Author

@eslint-community/core-team What do you think about it?

@nzakas If these are added, do you think they should be introduced on the ESLint blog?
eslint/eslint.org#471

@nzakas
Copy link

nzakas commented Sep 25, 2023

@ota-meshi I'm not sure it's worth adding such methods. If people are going to need to update their rules, why would they update to use new eslint-util methods instead of just using what ESLint is providing?

@MichaelDeBoey
Copy link
Member

I agree we should not add methods that are already in ESLint core

@ota-meshi
Copy link
Member Author

ota-meshi commented Sep 25, 2023

why would they update to use new eslint-util methods instead of just using what ESLint is providing?

For example, eslint-plugin-n supports ESLint v7. I think there are many plugins that support older versions of ESLint.
I just briefly checked the source of eslint-plugin-n and found that 39 changes are required. I think it is easier to use eslintUtils.getX() than to write ?? for all of them.
I also think it would be easier for plugin contributors to ask them to use eslintUtils.getX() rather than using the ?? chain.
I think the plugins I maintain will make something similar in each plugin's utils, even if eslintUtils doesn't provide it.
Rather than having the same utils for all those plugins, I thought it might be useful if eslintUtils provided it, so I wanted to hear your opinion here.

@ota-meshi
Copy link
Member Author

For example, I want to create a util function like the following.

function getSourceCode(context) {
    const sourceCode = context.sourceCode ?? context.getSourceCode()
    return new Proxy(sourceCode, {
        get(_target, name) {
            if (sourceCode[name]) {
                return sourceCode[name]
            }
            if (name === 'getScope') {
                return node => {
                    // Emulate `getScope` using `sourceCode.scopeManager`.
                }
            }
            if (name === 'getDeclaredVariables') {
                return node => context.getDeclaredVariables(node)
            }
            // ...
        }
    })
}

@nzakas
Copy link

nzakas commented Sep 26, 2023

For example, eslint-plugin-n supports ESLint v7. I think there are many plugins that support older versions of ESLint.
I just briefly checked the source of eslint-plugin-n and found that 39 changes are required. I think it is easier to use eslintUtils.getX() than to write ?? for all of them.

You can certainly create a utility function inside the plugin to do that if you'd like. I'm just not sure how many other plugins will also need to support ESLint v7.

And keep in mind that proxies are much slower than other objects, so you definitely don't want that in your hot path. (We tested in this in ESLint core and found a 25% performance hit.)

@MichaelDeBoey
Copy link
Member

@ota-meshi In the blogpost @nzakas created, it's mentioned that all the necessary methods are already in ESLint for 6 years, so ESLint v7 should support all of them, no?

@ota-meshi
Copy link
Member Author

I see 😃. I implement them inside the plugin where it is needed.
I close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants