Skip to content

Commit

Permalink
feat(getStaticValue): Dereference variables that are effectively `con…
Browse files Browse the repository at this point in the history
…st` (#80)
  • Loading branch information
RunDevelopment authored Mar 24, 2023
1 parent 22ad79f commit 0540eb3
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 5 deletions.
21 changes: 20 additions & 1 deletion src/get-static-value.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,23 @@ function getElementValues(nodeList, initialScope) {
return valueList
}

/**
* Returns whether the given variable is never written to after initialization.
* @param {import("eslint").Scope.Variable} variable
* @returns {boolean}
*/
function isEffectivelyConst(variable) {
const refs = variable.references

const inits = refs.filter((r) => r.init).length
const reads = refs.filter((r) => r.isReadOnly()).length
if (inits === 1 && reads + inits === refs.length) {
// there is only one init and all other references only read
return true
}
return false
}

const operations = Object.freeze({
ArrayExpression(node, initialScope) {
const elements = getElementValues(node.elements, initialScope)
Expand Down Expand Up @@ -407,7 +424,9 @@ const operations = Object.freeze({
const def = variable.defs[0]
if (
def.parent &&
def.parent.kind === "const" &&
def.type === "Variable" &&
(def.parent.kind === "const" ||
isEffectivelyConst(variable)) &&
// TODO(mysticatea): don't support destructuring here.
def.node.id.type === "Identifier"
) {
Expand Down
15 changes: 13 additions & 2 deletions test/get-static-value.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ describe("The 'getStaticValue' function", () => {
{ code: "var undefined; undefined", expected: null },
{ code: "const undefined = 1; undefined", expected: { value: 1 } },
{ code: "const a = 2; a", expected: { value: 2 } },
{ code: "let a = 2; a", expected: null },
{ code: "let a = 2; a", expected: { value: 2 } },
{ code: "var a = 2; a", expected: { value: 2 } },
{ code: "let a = 2; a = 1; a", expected: null },
{ code: "let a = 2; a++; a", expected: null },
{ code: "let a; a = 1; a", expected: null },
{ code: "const a = 2; a", expected: null, noScope: true },
{ code: "const a = { b: 7 }; a.b", expected: { value: 7 } },
{ code: "null", expected: { value: null } },
Expand Down Expand Up @@ -158,7 +162,14 @@ describe("The 'getStaticValue' function", () => {
code: "const obj = {b: 2}; ({a: 1, ...obj})",
expected: { value: { a: 1, b: 2 } },
},
{ code: "var obj = {b: 2}; ({a: 1, ...obj})", expected: null },
{
code: "var obj = {b: 2}; ({a: 1, ...obj})",
expected: { value: { a: 1, b: 2 } },
},
{
code: "var obj = {b: 2}; obj = {}; ({a: 1, ...obj})",
expected: null,
},
{ code: "({ get a() {} })", expected: null },
{ code: "({ a })", expected: null },
{ code: "({ a: b })", expected: null },
Expand Down
6 changes: 4 additions & 2 deletions test/get-string-if-constant.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ describe("The 'getStringIfConstant' function", () => {
for (const { code, expected } of [
{ code: "id", expected: null },
{ code: "const id = 'abc'; id", expected: "abc" },
{ code: "let id = 'abc'; id", expected: null },
{ code: "var id = 'abc'; id", expected: null },
{ code: "let id = 'abc'; id", expected: "abc" },
{ code: "var id = 'abc'; id", expected: "abc" },
{ code: "let id = 'abc'; id = 'foo'; id", expected: null },
{ code: "var id = 'abc'; id = 'foo'; id", expected: null },
{ code: "const id = otherId; id", expected: null },
]) {
it(`should return ${JSON.stringify(expected)} from ${code}`, () => {
Expand Down

0 comments on commit 0540eb3

Please sign in to comment.