Files
codegraph/__tests__
Colby MchenryandClaude Opus 5.5 f1da755a91 fix(resolution): calls on the browser's own objects link no project method (#3026)
`window.open('/help')`, `localStorage.getItem('token')`,
`location.reload()` and `history.back()` linked to a project class's
method of the same name, like an app's `WindowService::open` or
`StorageService::getItem`, so callers and impact on such a wrapper
listed every direct browser call in the app. Three readings did it:
- an untyped receiver went to matchMethodCall's guesses, by the
  receiver's word (`window` ~ WindowService) or a lone method name;
- a chain from `window`, which the extractor records by its bare method
  name so a project object hung on `window` can be found (#1707), fell to
  the exact-name match when the chain names no project object:
  `window.localStorage.getItem()`;
- a JS `self.close()` was read as `this.close()` by bareCallReceiver and
  callReceiverKind, though a `self` the file doesn't bind is the global
  object (a worker's scope, or `window.self`).

Now, in the JS family:
- a call on one of JS_BROWSER_HOST_GLOBALS (window, self, globalThis,
  document, localStorage, sessionStorage, location, history, navigator,
  screen, performance) gets no edge when the file writes that name only
  as a receiver (`document.x`, `history.back()`, `self?.close()`) or after
  `typeof`, decided before the receiver-type reader, whose backward scan
  has no scope. Any other mention (a parameter, destructured ones
  included, a declaration, an import, an argument) keeps the name the
  file's own: outline passes its Document model as `({ document }:
  Props)`, and those `document.save()` calls keep their links;
- matchCollapsedObjectCall declines a `window`/`globalThis` chain whose
  first link is one of them, after its project-object lookup; a chain
  through a project object (`window.App.init()`) is unchanged;
- an unbound `self` reaches matchCollapsedObjectCall as
  `globalThis.self`, and callReceiverKind no longer counts it as the
  instance. A `self` the file binds (`var self = this`) reads as before.

Validation: new browser-host-globals tests (4) pass with the fix. On
main the first fails with 8 wrong edges and the third (outline's
destructured `document`, a `typeof window` guard) with 2; the two that
pin what must keep working (a bound, imported or parameter name; `this`,
`var self = this`, `window.App`) pass on both. A first version that
asked only whether the file binds the name dropped outline's
destructured `document` calls; the third test fails against it.
A/B against main: only removals. excalidraw 12 (`window.open` ->
Portal::open, `document.createElement` -> DraggableTool::createElement,
a worker's `self.postMessage` -> WorkerPool::postMessage), outline 21
(test and app `sessionStorage`/`localStorage` calls -> MemoryStorage,
`window.document.body.*`, `window.history.back()` -> a Props property),
bitwarden apps/browser + apps/web 7 (`window.postMessage`,
`window.location.reload()`, `window.navigator.permissions.query()`), and
express unchanged. 39 of the 40 linked a project method by name only;
the 40th linked outline's own `declare global` typing of a browser API
(Document.modelContext.registerTool).

Reimplements PR #2915 by @KissFeng.

Fixes #2907

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 20:57:27 +00:00
..