mysticatea / eslint-utils

Utilities for ESLint plugins and custom rules.
https://eslint-utils.mysticatea.dev/
MIT License
74 stars 40 forks source link

Misleading result from getStaticValue() when called on mutable const-declared variables #10

Open ninevra opened 4 years ago

ninevra commented 4 years ago

When getStaticValue() is called with a scope and encounters an identifier referring to a variable declared with const, it computes that variable's static value based on its const declaration initializer only. If the variable is initialized to a mutable value, it can later be modified, resulting in the return value from getStaticValue() not matching the variable's true value at time of use.

Example:

const mutable = {a: 1};
mutable.b = 2;
mutable;

Calling getStaticValue() on the Identifier node mutable on line 3 returns {value: {a: 1}}, but mutable's actual value is {a: 1, b: 2}.

Minimal working example

This can also result in erroneously identifying identifiers as static. For example:

const mutable = {a: 1};
mutable.b = foo();
mutable;

mutable on line 3 is not static-valued, but getStaticValue() returns {value: {a: 1}}.

liangyuanruo commented 3 years ago

What happens if the following happens?

const mutable = {a: 1};
mutable.a = 2;
mutable;

Will getStaticValue() return {a: 1} or {a: 2}?

ninevra commented 3 years ago

@liangyuanruo, in your example, getStaticValue() returns {value: {a: 1}} for each of the three mutable Identifier nodes. getStaticValue() doesn't examine anything besides the given node and the declarations of any variables it references, so it doesn't see the mutation on line 2, regardless of what form that mutation takes.

MichaelDeBoey commented 1 year ago

Hi @ninevra!

Since this repo is unmaintained, you might want to re-open this issue in the @eslint-community fork https://github.com/eslint-community/eslint-utils

For more info about why we created this organization, you can read https://eslint.org/blog/2023/03/announcing-eslint-community-org