Skip to content

javascript: a function assigned to exports.x, obj.x or an object-literal key is named for the property - #1587

Merged
swapnilpaliwal-sd merged 1 commit into
0.1.4from
loop/ja-js-anon-fn-member-naming
Sep 28, 2026
Merged

swapnilpaliwal-sd merged 1 commit into
0.1.4from
loop/ja-js-anon-fn-member-naming

Conversation

@swapnilpaliwal-sd

Copy link
Copy Markdown
Contributor

Symptom

In JavaScript, a function assigned to exports.x, module.exports.x or obj.x, or used as an object-literal key's value ({ all: page => … }), was indexed as <function-expression> / <arrow>. The call edges to it resolved, but impact getUser answered type getUser (not declared here) and impact Articles.all answered nothing named. Only a file:line target reached the declaration.

Fix

The index's naming pass already names const x = function … after its variable. It now also names a function expression that is:

  • the right side of recv.key = …, with a non-computed property target: the name is key, and the owner is recv as written (Foo.prototype → Foo); there is no owner for exports, module.exports or this;
  • the value of a non-computed key in an object literal: the name is the key, and the owner is the variable the literal initialises, or the key chain of the enclosing literal.

A named function expression keeps its own name, since only placeholders are renamed, and an arrow passed as an argument stays anonymous.

Tests

Measurements

call_edges symbols placeholder symbols owned symbols index time
fixture before → after 16 → 16 16 → 16 9 → 3 0 → 3 2s → 2s
a real React/Redux app before → after 432 → 432 337 → 323 159 → 80 36 → 62 147s → 143s

On the real app, all 79 changed lines are renames, e.g. <arrow> → Articles.all, Auth.login, requests.get, and onLoad in a mapDispatchToProps literal. The 14 fewer symbols are this.x = ev => … field rows at the same line, now folded into the function they hold, the same way a const x = function variable row already is.

The same shape in TypeScript is #1585.

…ral key is named for the property

`exports.getUser = function …`, `obj.x = () => …` and `{ all: page => … }` were indexed as
`<function-expression>` / `<arrow>`, so `impact getUser` or `impact Articles.all` answered
"not declared here" although the call edge was resolved. The function now takes the property's
name, as the language's own name inference does, and is owned by the receiver (`helpers`, `Foo`
for `Foo.prototype`) or by the variable the literal initialises (`Articles.all`); none for
exports / module.exports / this. A named function expression keeps its own name, and an arrow
passed as an argument stays anonymous.

Call edges are unchanged (a real React/Redux app: 432 -> 432); symbol placeholders 159 -> 80.

Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
Co-Authored-By: Claude <noreply@anthropic.com>
@swapnilpaliwal-sd
swapnilpaliwal-sd force-pushed the loop/ja-js-anon-fn-member-naming branch from cfb04f5 to a78e150 Compare September 28, 2026 05:18
@swapnilpaliwal-sd
swapnilpaliwal-sd merged commit a213002 into 0.1.4 Sep 28, 2026
11 checks passed
@swapnilpaliwal-sd
swapnilpaliwal-sd deleted the loop/ja-js-anon-fn-member-naming branch September 28, 2026 05:22
@swapnilpaliwal-sd swapnilpaliwal-sd mentioned this pull request Sep 28, 2026
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

Successfully merging this pull request may close these issues.

1 participant