Commit Graph

501 Commits

Author SHA1 Message Date
Colby Mchenry 60b2f1e7bb fix(rust): a call reaches a project impl on a std type only as Rust would pick it (#2697)
A crate can't declare a method on String, Vec, Arc or NonNull, only
implement a trait for one, and name matching took those impls for any
call of that name. Every String::from("...") in dioxus's CLI went to its
impl From<IDI> for String, tokio's NonNull::from(waiter) calls to its
impl From<&Handle> for NonNull<Entry>, its tests' files.iter() to an
internal Storage trait's impl for Vec, and clap's String::from calls
to its impl From<Str> for OsString.

A call into a method of a project impl on a std type now stands only
when Rust could pick it. A std trait (From, PartialEq, ...) is
implemented for the crate's own type argument, so the call must pass
one: built from it (IDI::Install), self in an impl of it, or a name
the enclosing function declares with it (fn from(name: Str)). A trait
of the project's must be in scope in the calling file: declared,
implemented or imported there, or brought in by a glob that may carry
it. Otherwise the call is left unresolved, since what it calls is the
standard library's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 01:37:17 +00:00
Colby Mchenry 6f8e6caad9 fix(c,cpp): a source implements the header beside it that it reaches through other headers (#2693)
upb's reflection sources include only their internal header:
upb/reflection/field_def.c includes upb/reflection/internal/field_def.h,
which reaches the upb/reflection/field_def.h it implements through def.h.
So the translation-unit rule of PR 2684 never read field_def.c as that
header's implementation, and 343 calls from protobuf's Python extension,
plus 88 from its Lua binding, still went to the copy of upb that the PHP
extension bundles in php-upb.c.

When a source includes no header named like it in its own folder, one
there that it includes through other headers counts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 01:00:25 +00:00
Colby Mchenry 65d734236e fix(rust): a private item, or one another crate holds, no longer takes a name a file imports (#2692)
A Rust type alias declared without pub recorded no visibility in either
engine, so name matching took dioxus's private type Result in
src/build/patch.rs for the Result<...> a file means through
use crate::Result. Type aliases now record it, as functions and structs
already do, and a private module item is out of scope outside its own
module ahead of the ranking. The pipeline's veto already rejected such
a pick after the ranking, which left the reference unresolved: that is
what kept tokio's timeout(...), split(...) and sleep(...) calls from
linking, since a private namesake outranked the function they import.

With the private items gone, a runner-up from an unrelated crate could
win instead: tokio's tests' spawn(...) calls, under
use tokio_test::task::spawn, went to the examples crate's pub fn spawn.
So a name a use binds is now an item of the crate its path starts from,
or of a project crate that one's [dependencies] name, in turn, which a
facade's re-exports need: clap::Command is clap_builder's. crate::,
self:: and super:: start from the file's own crate; a named root counts
when the file's own manifest lists it. Dependencies are found by path
(their own, or the workspace's for workspace = true), so renamed keys
and crates outside the members land, and dotted keys such as
helper.workspace = true are read. Dev and build dependencies are not
re-exported, so they don't count: tokio's own use crate::spawn, whose
spawn sits in a macro the index doesn't see, stays unresolved instead
of going to tokio-test's. A file in no crate the manifests name, or a
path from anything else, is matched as before.

reference-target-kind's sibling-crate fixture re-exported pupil_core
without depending on it, which Cargo rejects; it now declares it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 00:44:52 +00:00
Colby Mchenry 40987d7776 fix(objc): a macro alone on its line no longer hides the declaration below it (#2691)
A macro on a line of its own, like NS_ASSUME_NONNULL_BEGIN,
OF_SUBCLASSING_RESTRICTED or RCT_EXTERN_C_BEGIN, reads to tree-sitter-objc
as the start of a declaration and swallows what follows: an @interface
under it became a function named after its last protocol, and a typedef
under it a variable `typedef` plus a variable named after the type. C and
C++ already blank such a macro in preParse (blankLoneMacroLines);
Objective-C had no preParse.

- c-cpp.ts: blankLoneMacroLines takes the language's rules, and C and C++
  keep theirs unchanged. OBJC_LONE_MACROS lets the code below the macro
  start with `@` (@interface, @end). It reads a preprocessor line above the
  macro as ending at its own line: `#import <Foundation/Foundation.h>` ends
  in `>`, an operator to C's rule, which left NS_ASSUME_NONNULL_BEGIN in
  place while the OF_SUBCLASSING_RESTRICTED below it was blanked, a worse
  parse than either. And it leaves a macro that is a method's whole body
  (`{ OF_UNRECOGNIZED_SELECTOR }`): blanking it changed how the parser
  recovered from an earlier misread, and OFMutableString.m lost 11 calls.
- objc.ts: preParse blanks with those rules.
- name-matcher.ts: objcSupertypesOf reads the superclass from the
  @interface line within the class rather than the class's first line. A
  class now starts at an attribute macro written above its @interface, like
  NS_SWIFT_NAME(...), and KSCrash's [super validateSetupWithError:] had lost
  its superclass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 00:41:26 +00:00
Colby Mchenry 6c202bca32 fix(objc): a struct, union or enum defined in a variable declaration is indexed (#2690)
Objective-C kept the gap that PR #2446 closed for C and C++: a struct,
union or enum defined in the type of a file-scope declaration, like
`static struct { Class isa; } placeholder;`, `struct Foo { int a; } foo;`
or `enum { ModeA, ModeB } mode;`, never became a node. The walker's
declaration branch extracted the variable and skipped the declaration's
children, and Objective-C did not take the declared-type walk.

- tree-sitter.ts: Objective-C walks a type defined in a declaration's
  type, as C does, also when the tree has errors. Most Objective-C trees
  have errors (a lone macro like NS_ASSUME_NONNULL_BEGIN is enough; 832 of
  ObjFW's 1087 Objective-C files), so a clean-tree gate would skip nearly
  every real site, and neither grammar has a namespace or a class written
  as a type that error recovery could close at the wrong brace.
- objc.ts: resolveName composes selector naming with C's
  unnamedTypeVariableName, so an unnamed type takes the first variable its
  declaration declares (in function and method bodies too), and
  getDeclarationWrapper makes the declaration's comment the docstring.
- c-cpp.ts: export definingDeclaration and unnamedTypeVariableName.
- name-matcher.ts: a struct, union, enum or typedef that a .m or .mm file
  defines is visible only to that file, as isCppTranslationUnitLocal keeps
  a .c file's. Without it, ObjFW's calls of AmigaOS's Lock(path, mode)
  linked to the runtime's private struct Lock in synchronized.m. A class
  stays visible: it is the runtime's, wherever it is written.

The walk also recovers a typedef written right after a line holding only a
macro (OF_ASSUME_NONNULL_BEGIN, RCT_EXTERN_C_BEGIN), which the parser reads
as a declaration of a variable: ObjFW's public enums with their values,
and React Native's RCTMethodInfo, were missing. Objective-C has no kernel
walker, so the kernel is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 00:03:37 +00:00
Colby Mchenry 12ea27faf4 fix(swift): a local declared through try, await or a generic constructor has the type constructed (#2689)
The Swift declaration pattern behind receiver typing read `name = Type(`
only, so a local declared through `try`, `try!`, `try?` or `await`, or with
a generic type's constructor, had no type at all. Kingfisher's
`let storage = try! DiskStorage.Backend<String>(config: config)` left
`storage.store(…)` to name matching among every `store` in the project.

The pattern now reads type arguments, as the Java and C# patterns do, and
steps over `try`/`await` where the line declares the local (`let`/`var`)
and no member follows the constructor call there. A bare assignment through
`try` is left as before: swift-nio's `channel = try ServerBootstrap(…)` goes
on into `.bind(…).wait()` on the lines below, a value of another type, and
typing it by the chain's head hid the `var channel: Channel?` it was
declared as. Likewise realm-swift's `let obj = try! Realm().write { … }` is
a value of what `write` returns. resolveMethodOnType still checks the
method on the type, so a local typed wrongly links nothing.

swift-try-initialized-locals.test.ts gives every target a namesake declared
before it on another type, names no local after its type, and pins the
assignment and the chained-call cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 23:36:16 +00:00
Colby Mchenry 951d575e62 fix(resolution): a barrel's export { A } from './x' links what ./x exports, not a namesake (#2685)
A barrel's own export { A, B as C } from './x' emits one imports
reference per name it passes on, named as ./x calls it. No import binds
a re-exported name, so the resolver looked each one up by its name alone
and could reach a namesake elsewhere in the project, or a project
function named like a package's export.

Each such name now resolves through the module the statement names, as
an import does, following barrels of barrels and renames. A name passed
on from an outside package counts as bound to that package, so it never
name-matches a project symbol. A name two statements re-export from
different modules keeps the old lookup.

Sync re-opens a barrel's re-exported names when the module they go
through is deleted or added, as it already did for the names an importer
binds, so a synced graph keeps matching a fresh index.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 22:18:47 +00:00
Colby Mchenry 32b839acae fix(c,cpp): a name in C or C++ code outside tests links to what the file's own includes declare (#2684)
PR #2675 narrowed a C or C++ test's same-named candidates to the ones its
translation unit declares. Production code now gets the same rule:
protobuf's Python extension called the copies of upb's C API that the PHP
extension bundles in php-upb.c, and its Java generator's calls of the free
HasHasbit() went to ImmutableFieldGenerator::HasHasbit, a method beside the
caller.

Refinements the wider scope needed:
- a source implements the same-stem header beside it, when it includes one:
  pyext/message.cc is no implementation of google/protobuf/message.h;
- a header's own overloads reach the definitions its source holds:
  conformance/binary_wireformat.h's template Varint calls the .cc's;
- narrowing never leaves a call with only functions its arguments can't
  fill, past one outside the unit that they can: glog's three-argument
  GetStackTrace(...) is not utilities.h's GetStackTrace(). This also mends
  9 breakpad unittest calls #2675 had narrowed the same way;
- nor, for a C call, to definitions only a flag nothing sets compiles,
  past one the build without it does: that stays #2615's choice.
A file-level "call" (a macro, or a declaration read as a call) is left as
it was.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 22:12:26 +00:00
Colby Mchenry 22d420ec8a fix(react): a name the file destructures at its top renders no JSX child (#2677)
Since PR 2676, a tag whose name the parent, or a function around it,
destructures renders only a component that function declares inside
itself. A name the file destructures at its top was left out, because no
function's code holds it: refine's pages take `const { Title, Text } =
Typography;` from antd once, above their components, and every `<Title>`
and `<Text>` in them linked to another example's `Title` or `Text`
component by name.

The pass now reads the destructuring patterns the file declares outside
every brace (`topLevelPatterns`, on the code-only view), so in no
function, class or block, and never a top-level callback's parameter.
Only braces are counted: JSX text may hold a stray parenthesis or
bracket, never a brace that opens no expression, and `jsxCode` returns
null for a file whose braces don't balance, which then binds nothing
here. A tag that no function in its scope chain binds, but that such a
pattern binds (`bindingElementAt`, so not a `require(...)` or `import(...)`
declaration), renders only a component the outermost of those functions
declares inside itself, else nothing.

Fresh before/after indexes on 31 repos (main 24ea3c54): 177 jsx-render
edges removed, all in refine-examples (94 to one example's `Text`, 83 to
another's `Title`), and every tag of each is a module-level destructured
local by the TypeScript checker. Nothing else changes; 30 repos are
byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 20:04:13 +00:00
Colby Mchenry 24ea3c54b2 fix(react): a name a component destructures, or a function around it binds, renders no JSX child (#2676)
#2442 made a tag the parent binds itself, as a `const` or a parameter,
render only a component the parent declares inside itself. Destructuring
was left out, as name-matcher leaves it out for a bare call (`const { t }
= useI18n()` is that function more often than not), so a destructured tag
still linked any same-named component in the repository. For a tag that
is the wrong default: what a component destructures is a component its
props or a library hand in, which is no node here.

- refine's layouts, `({ children, Header, Footer, Sider, OffLayoutArea })
  =>`, rendered other examples' `Header`, `Footer`, `Sider` and
  `OffLayoutArea`; `const { Title } = Typography` (antd) and `const {
  Link } = useRouterContext()` rendered other examples' `Title` and `Link`.
- excalidraw's example app, `const { Sidebar, Footer, WelcomeScreen, … } =
  excalidrawLib`, rendered its own `ExampleSidebar.tsx` for the library's
  `Sidebar`, and `Footer.tsx` though the library exports `FooterCenter` as
  `Footer`. Its other tags landed on the library's components by luck.

A tag now checks the parent's code through its first tag for a
destructuring pattern that binds the name (`destructures`, read off the
code-only view): a declaration's or a parameter's, nested patterns, rest
elements, rename targets and array patterns included. A rename's key, a
default value and a type literal after a pattern bind nothing, nor does an
object argument or a control-flow head, and a declaration of `require(…)`
or `import(…)` binds the module's own export, which links as before.

The same check, and #2442's `const`/parameter check, now also reads the
functions around the parent: excalidraw's `renderExcalidraw` and
`renderTopRightUI` render what `ExampleApp` destructures. The function
that binds the name is the one whose own components a tag may still
render (`declaredInside`), so a helper rendering a component its enclosing
function declares (binner's `recursiveTreeItem` → `StyledTreeItem`) keeps
its edge.

Fresh before/after indexes on 31 repos (main a50104c8): 24 jsx-render
edges removed (excalidraw 14, refine-examples 10), every one graded
all-local by the TypeScript checker (each tag a destructured local);
15 targets were wrong, 9 right by luck. One of them, ExampleApp →
ExampleSidebar's `Sidebar`, comes back with `via` ExampleSidebar, the
default import that renders it, which the wrong `<Sidebar>` edge used to
hide. No other edge, node, ref or file changes; 29 repos are
byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 19:38:59 +00:00
Colby Mchenry bb8a0f732b fix(c,cpp): a name in a C or C++ test links to what the test's own includes declare (#2675)
When several files declare a name a C or C++ test uses, the test now links
to one its translation unit declares, when there is one: a definition in its
own file, in a file it includes (directly or through other includes), or in
the source file that implements such a header (the same-stem file that
includes it), unless that source keeps the definition to itself (a `static`,
an unnamed namespace, a class it declares). Before, the candidates were
ranked by directory and index order, so a test took whichever namesake came
first:

- protobuf's C# generator tests called test_util2.h's
  `TestUtil::TestSourceDir()`, a test suite they never include, instead of
  the `TestSourceDir()` googletest.h declares;
- protobuf's upb and hpb tests left `upb_Arena_New()` and the rest of upb's
  C API unlinked: the copies bundled for PHP and Ruby won the ranking and
  were then rejected;
- rocksdb's c_test.c left `rocksdb_open()` and the rest of the C API in
  db/c.cc unlinked, and its histogram test's `clock->SleepForMicroseconds()`
  went to emulated_clock.h's `EmulatedSystemClock`, which it doesn't include.

The narrowing applies to test files only, to the exact-name strategy, typed
receivers (resolveMethodOnType), and the class-name and receiver-word
strategies of matchMethodCall. When the translation unit declares none of
the candidates, as when a test's includes don't resolve (jemalloc's tests
include a generated header), the candidates stay as they were. A name a
test writes alone (no receiver, no qualifier) is narrowed only to what C++
finds for it outside a class: a function, a namespace-scope type or a
constructor, never another class's method or nested type, and a call the
extractor recorded without the receiver it is written on is left as it
was. The qualified-name strategy is unchanged.

Validated on main 3695818f (site-keyed edge diffs, every group triaged):
rocksdb +1,442 / 47 retargeted / -12, protobuf +2,316 / 55 / -67,
fmt +33 / 40, breakpad +13 / 14, glog +22, leveldb +10, llm.c 6
retargeted; jq, tokio, excalidraw, okhttp and typeorm byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 19:22:03 +00:00
Colby Mchenry bf6995e911 fix(js): a JavaScript file's import of a TypeScript module links that module (#2674)
An extensionless import from a `.js` or `.jsx` file of a TypeScript module,
like mastodon's `import AudioModal from './audio_modal'` in modal_root.jsx
beside audio_modal.tsx, never resolved by path: the import resolver's
javascript and jsx extension lists held only JavaScript extensions, while
the typescript and tsx lists already try `.js`/`.jsx`. In a codebase
moving to TypeScript those imports were matched by name instead, so an
import under another name linked nothing, and a repeated name could link
the wrong file (mastodon's `<IconButton>` and `<Status>` tags rendered
other same-named components than the ones each file imports).

The javascript and jsx lists now try `.ts`/`.tsx` (and their index files)
after their own extensions, as a bundler and tsc's allowJs resolve them.
JavaScript stays first, so a `helpers.ts` beside `helpers.js` does not
take its importers, and never `.d.ts`, which is no module a JavaScript
file runs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 19:12:04 +00:00
Colby Mchenry ab6ec218ff fix(js,ts): a function value imported from the project links only to what its import binds (#2673)
A function passed as a value whose name the file imports from its own
project still fell back to the project's one function of that name
whenever the import resolver bound the name to something that is not a
function: outline's `isCloudHosted` constant landed on the server's
`isCloudHosted()` check, its `Star` model class on the `<Star>` icon,
`import * as Slack` on the Slack settings component, and topcoder's
`import TCO21 from './themes/TCO21.scss'` on a route component.

matchFunctionRef's unique cross-file fallback now also declines when a
project import binds the name to something else (importBindsOther): a
namespace import, an asset import (stylesheet, image, GraphQL, JSON,
font, media; judged by the specifier's extension), or an import the
import resolver binds to a node that is not a function or method. A
wrapper declared beside the namesake (`export default
styled(Disclosure)`) and a lazy loader (`lazy(() => import(...))`)
still lead to it, and an import the resolver can't follow at all keeps
the fallback.

Follow-up to #2671.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 18:43:16 +00:00
Colby Mchenry a50104c895 fix(react-router): read every table a route-building function returns, and the one behind useMemo (#2672)
The route-table pass (`returnedTable`) took the first `return [` anywhere in
a route-building function's body for its table:

- An early guard's `[]` (`if (!user) return [];`) hid the real table.
- A callback's `[]` did too: devanshthakker15/BANKFORM1's `generateRoutes`
  returns `[]` from a `.forEach` callback before its own table.
- A menu that a helper inside the function returns could be read as routes.
- Of `if (admin) return [ … ]; return [ … ]`, only the first branch was read.

A function that returns another function's table (`return buildRoutes()`)
was not followed, and neither was `useMemo`, which hooks-based routers wrap
their table in.

Now `returnedTables` reads what the function's expression body gives, or
what each of its own `return`s gives (`ownReturns`). It steps over the
bodies of arrows, `function`s and methods written inside it, found by a
brace matcher tolerant of JSX text: in `blockEnd` and `opensString`, a quote
right after a word is an apostrophe. `heldTable` reads parentheses around a
value, and reads `useMemo(() => getRoutes(user), [user])` and
`useMemo(getRoutes, [])` as the function's tables. `tableNamed`,
`exportedTable` and `declaredTable` now return every table they find.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 18:31:31 +00:00
Colby Mchenry b8f81e2c8e fix(js,ts): a function value imported from a package no longer links a project function of that name (#2671)
A function passed as a value (`styled(Link)`, `createContext({ onClose:
noop })`, `Chart.register(Legend)`) whose name the file imports from a
package is that package's function. matchFunctionRef still bound it to
the one project function of that name whenever there was exactly one:
outline's react-router-dom `Link` landed on an email template's
`Footer.tsx:Link`, cord-field's lodash `noop` on a test's own stub.

The cross-file fallback now consults the same out-of-repo guard the
call and value paths use (isOutOfRepoBinding). A same-file declaration
still wins (a local that shadows the import is what the name means
there), a project import still resolves through its import, and a
specifier no package.json declares may be an alias and stays the
project's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 18:11:07 +00:00
Colby Mchenry 1aebd3a30f fix(react-router): a route that renders <Outlet /> renders nothing of its own (#2670)
A route with no element renders an `<Outlet />`, and JSX routes already read
`element={<Outlet />}` that way. Route objects did not:

- `element: <Outlet />` and `Component: Outlet` made `Outlet` the route's
  page and the layout of every route inside it. Those `layout:Outlet`
  references link nothing: 93 failed rows on Medusa's admin dashboard, 106
  on Mercur's, 87 on mercurjs/vendor-panel.
- A `lazy` loader returning `{ Component: Outlet, loader }` (Medusa's `:id`
  routes import their page module only for its loader and breadcrumb) read
  as unreadable, so the route fell back to that module's page, which became
  the layout of the routes inside: a product's detail page drawn around its
  variants' pages.

Such a route object is now an `outlet` scope. It is a route at its own
address, so a navigation there still lands, and it sits inside the layouts
around it, but it has no page reference and is no layout. A page inside at
the same address claims the address as before, and a `path: ''` one only
groups its children at its parent's address. `lazyRouteReference` returns
`Outlet` for a loader that hands it back, and the JSX branch drops it the way
it drops `element={<Outlet />}`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 17:59:29 +00:00
Colby Mchenry 654a853f5a fix(react-router): read the table a function returns when a variable hands it to the router (#2668)
Medusa's admin dashboard builds its router in a class's `render()`:
`const routes = getRouteMap({ settingsRoutes, coreRoutes })`, then
`createBrowserRouter(routes, { basename })`. `getRouteMap`, imported from
its own module, returns the literal table. The route-table pass
(`tableRoutes` in frameworks/react.ts) read a variable only when it held
the literal itself, so none of the 221 routes existed, and the dashboard's
`navigate()` calls and `<Link>`s led nowhere.

- `declaredTable` now reports a value initialized with a call
  (`getRouteMap({ … })`, `await loadRoutes()`) as the function to follow,
  and `tableNamed` / `exportedTable` follow it to the table it returns,
  local or imported. `export const routes = buildRoutes()` and
  `export default buildRoutes()` are read the same way.
- Of several declarations of a name in a file, the one in scope at the use
  is read (`visibleAt`). Scope comes from the graph's functions; a
  function-local declaration has no node of its own, so the declarations
  are read from the text. Another function's `const routes = getMenu()` is
  that function's own and is never followed. An exported name is a
  top-level one.
- What the function's parameters spread in (Medusa's `...coreRoutes`,
  filled from plugins) stays unread: no declaration in scope names it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 17:22:57 +00:00
Colby Mchenry 437b5c329f fix(sync): an import links an added file whose name a popular import shares (#2666)
Sync retries a failed import by what an added file can be imported as (its
name, its stem, its folder) and skips a key more than 500 failed imports
share, as noise one file cannot answer. A path import is parked under its
path's stem, though, and a package's imports share that stem with every file
of the name: `utils` is the stem of every `jotai/utils` and `@scope/pkg/utils`
as much as of a project's own `./utils`, and `assert` the name of every binding
of `import * as assert from 'assert'`. In a large project those crowded the key
past the ceiling, so a project's own `utils.ts` added after its importers were
indexed, or restored after a delete, never linked them: folo's
`modules/settings/utils.ts` and `components/ui/modal/stacked/hooks.ts`, and
vscode's `base/common/assert.ts`.

A key past the ceiling is now looked through for the imports that could name
an added file, and those are retried. A JavaScript or TypeScript import names
a file by its module (the path branch of resolveViaImport, shared with it as
jsModuleFile), by a framework alias, or by the file's own name. What that
accepts is no noise, so it is held to the module ceiling, as the specifiers
that resolve to an added file already are: bitwarden imports its
account.service from 724 files. An import in another language is not
accepted, so a crowded key there is skipped as before; a key within the
ceiling is retried whole, as it was.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:58:56 +00:00
Colby Mchenry 5c1e55f44c fix(go): a call on a package-level variable or constant links through the type it is declared with (#2667)
Nothing read the declaration of a Go variable or constant declared at the
top level of a package (the scope reader skips them, and the pattern scan
reads only the calling function), so a method call through one was matched
by the method's name: etcd's `var lg *zap.Logger` made `lg.Panic(...)` a
project logger's `Panic`, prometheus's protobuf `xxx_messageInfo_*` values
reached project `Marshal` methods, and kubernetes' registry tests' calls on
each package's `var Strategy = fooStrategy{...}` reached another package's
exported `Strategy` type.

matchGoPackageValueCall reads a same-package `variable` or `constant` node's
spec when the call's receiver is a plain name that no local or parameter
binds and no import names: a written type, a composite literal's or a
conversion's type, or for a constant alone in a `const ( ... )` group the
spec above it. A project type gives its own method (0.9) through the
package that declares it; a type or value from outside the project, a
predeclared type or a type literal gives nothing. A value a project
function returns, an untyped constant, declarations that differ between
build-tag files, and a project type whose methods aren't found are left to
the strategies below. A `package foo_test` file in the directory is another
package.

A/B on main 90d6501b, same kernel for both arms, full index per arm:
- gin: 4 guesses now typed at 0.9.
- prometheus: 59 dropped (gogo-protobuf `xxx_messageInfo_*`, `sync.Pool`
  values), 40 new links (`RoleEndpoint.String()` and its siblings).
- etcd: 18 dropped (`var lg *zap.Logger`, a cobra command), 43 new links
  (`var display printer = &simplePrinter{}`), 3 now typed.
- harbor: 2 dropped (`var handler http.Handler`), 24 new, 38 retargeted
  (`var configManager *cfgPkg.CfgManager`), 34 now typed.
- kubernetes: 46 dropped (outside-typed values), 260 new, 405 retargeted
  (each registry package's own strategy type), 430 now typed.
fmt, llmc and typeorm are identical. Every dropped link, grouped by
receiver, and every retargeted owner pair was checked against the
receiver's declaration.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:46:07 +00:00
Colby Mchenry a6cfb52371 fix(sync): an import a barrel passes on under another name relinks when its module gains it (#2665)
A sync that gives a module a definition retries the failed references
waiting for the names the module declares, and rebinds the edges into the
names that changed (CG-33). An importer that reaches the module through a
barrel passing it on under another name waits under neither: matx's
`export { default as MatxLoading } from './MatxLoading'` hands
MatxLoading.jsx to `import { MatxLoading } from 'app/components'`, a name
the file never declares. That import and the calls through it stayed
failed, and where a name match had taken the name elsewhere while the
module lacked it (vben's `alert`, which its alert barrel passes on from
`vbenAlert`, onto the `alert.vue` component), the edge stayed there, until
the importer changed or the project was indexed again.

reopenReferencesThroughBarrels now records each importer below a barrel
with the names the barrel passes the changed files on as, and re-opens that
importer's failed references through those names and, for the names the
files never declare, its edges bound before the sync resolved anything, as
the added-file path does. A declared name stays the retry's and the
rebind's, which cap a common one. The per-importer lookup replaces the
repo-wide retry by the passed-on names, whose per-name ceiling skips a name
as common as `alert`; the barrels' module keys are still retried for lazy
routes. passedOn, which the added-file path shares, now also reads an
import a barrel exports again, with the names it exports it as (`import
Card from './Card'; export { Card as AppCard }`), which only the lazy-route
walk followed before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:05:15 +00:00
Colby Mchenry 90d6501b09 fix(go): a call of a standard method name like err.Error() links to its receiver's declared type, never to one it shares a word with (#2664)
A Go call of a standard method name (GO_STD_METHODS: Error, String, Err,
Lock, Len, Header, ...) on a receiver whose type wasn't worked out was
guessed by a word the receiver shares with a type's name: kubernetes'
`err.Error()` linked to `notRegisteredErr::Error`, prometheus's to
`ParseErr::Error`, etcd's `leaderID.String()` to `MoveLeaderRequest`, and
a receiver declared as a type from outside the project to a project type
of its name (etcd's `var pendingMu sync.Mutex` to its concurrency `Mutex`).

In matchMethodCall, for a standard method name on a plain Go variable:
- The receiver's declaration in scope (goLocalDecl, the scope reader)
  decides, over the unscoped pattern scan: a project type's own method,
  through the package that declares it; nothing for a predeclared type, a
  type from outside the project, a type literal, a value an outside
  package hands out, or a declared type that lacks the method.
- Otherwise a guess needs the receiver to name the owner type itself,
  case and a trailing number aside (`id` an `ID`, `urlsMap` a `URLsMap`):
  in Strategy 3 through receiverNamesOwner, and in Strategy 2, which took
  any method of the owner's file whose name contained the type's
  (`status` reached `RuntimeStatus::String` beside a `Status` type).
- Only a declaration the scope reader finds rules a call out. The pattern
  scan reads back for the name without block scope and can find another
  declaration of it, like a test table's `version string` above
  `version, _ := parse(...)`; valid Go calls no method but `Error` on a
  predeclared type, so such a read says nothing.

A/B on main b4e10138, same kernel for both arms, full index per arm:
- gin: 17 guesses dropped; 14 calls newly typed (`c.String(...)` in
  `func(c *gin.Context)` handlers).
- prometheus: 265 dropped, 89 newly typed, 6 retargeted.
- etcd: 335 dropped (23 of them typed links of `sync.Mutex` and
  `sync.RWMutex` values to project namesakes), 52 newly typed, 7
  retargeted.
- harbor: 174 dropped, 6 newly typed, 6 retargeted.
- kubernetes: 2489 dropped, 241 newly typed, 77 retargeted.
No link of any other method name changed, and the fmt, llmc and typeorm
controls are identical. Of 132 dropped links sampled, 3 were right
(locals typed by a project call's result, which no reader types yet).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 15:51:16 +00:00
Colby Mchenry 0d33925aa3 fix(ts): a method whose name has a $ resolves through its receiver's type (#2662)
The method-call pattern read the method name as \w+, which has no $, so
a JS/TS call like bitwarden's this.organizationService.organizations$(id)
or vscode's RPC this._proxy.$acceptModelChanged(…) matched no method-call
shape and linked nothing, however well its receiver was typed. For the
JS family the method part now admits $; the receiver part is unchanged,
so RxJS receivers like this.destroy$.next() stay out of name guessing.

A/B on main b4e10138: vscode +1514 (mostly RPC calls onto their shape
interfaces), bitwarden +2116, qwik +68, none removed or retargeted; 12
other JS/TS repos byte-identical, Vue 2 options-API apps included.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 11:44:17 +00:00
Colby Mchenry b4e101387f fix(ts): a receiver a dependency-injection call sets up has the class it is given (#2661)
Angular's `private readonly dataService = inject(DataService)` or
`inject<DialogParams>(DIALOG_DATA)`, and vscode's
`this._register(this.instantiationService.createInstance(Widget, …))` or
`const widget = this.instantiationService.createInstance(Widget)`, gave
the field or local no type, so calls through them linked nowhere or by
name alone. The field reader and the TS local patterns now read them:
`inject` only when the file imports it from `@angular/core` (Vue's
`inject(key)` returns whatever was provided under the key), its type
argument first; `createInstance` only when the project declares one that
returns an `InstanceType` of its constructor argument. A local set from a
member of what the injector returns isn't read as the class.

A type the file imports under another name, like bitwarden's
`OrganizationApiServiceAbstraction as OrganizationApiService` or vscode's
`Engine as FileSearchEngine`, is now found through that import rather
than as a class with the local name.

A/B on main 383c2cd9: vscode +594 links, 351 retargets to the created or
imported class, 677 confidence-ups, 0 removed; bitwarden +1835, 35
retargets, 3 Angular Router guesses removed; ghostfolio +277; 8 other
JS/TS repos byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 11:12:49 +00:00
Colby Mchenry 93f85d10ce fix(go): an explicitly named import owns its name over an unaliased import's last path element (#2660)
fix(go): an explicitly named import owns its name over an unaliased import's last path element

Go binds a name to one import per file. etcd's benchmark tool imports
"github.com/cheggaaa/pb/v3" (package pb) beside
v3 "go.etcd.io/etcd/client/v3", so `v3.Op` is clientv3's. The import
mappings also listed the unaliased import under its last path element,
`v3`, and the first one listed, the progress-bar library outside the
project, took every `v3.` qualifier: `op v3.Op`, `c *v3.Client` and
`[]v3.OpOption` linked to nothing.

extractGoImports no longer lists an unaliased import under a name another
import is explicitly given; it keeps the name goimports assumes for it
(`pb`), as before.

A/B on main 383c2cd9: etcd +8 edges (tools/benchmark and etcdctl), all to
client/v3's types; gin, prometheus and kubernetes unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 11:00:47 +00:00
Colby Mchenry 6692e05107 fix(go): an unexported name links its own package's declaration, and a local binding shadows the package (#2658)
Go keeps an unexported name inside its package, yet prometheus tsdb's
`[]*memSeries` in head_append.go linked to nothing. Name matching scored
head.go's `memSeries` and `tsdb/agent`'s the same, because directory
proximity counts shared leading directories (and caps at 80), so a child
or deep sibling package ties with the package's own directory. The first
one met, `tsdb/agent`'s, was then vetoed as invisible. Parameters,
results, struct fields, composite literals and calls all failed this way:
prometheus's `memSeries` and `sample{…}` (1,185 literals), and in
kubernetes client-go's per-version informer types and many test helpers.

- matchByExactName drops a Go candidate the reference cannot see before
  the ranking (isGoNameVisible, shared with isVisibleAcrossFiles' Go rule),
  as it already did for C#, Java, PHP and Scala, so the package's own
  declaration wins.
- That lets a name with more namesakes than the ambiguity ceiling resolve
  to its package's declaration. It also exposed bare calls to a local
  closure named like a package function: client-go's `init := func(…)`
  then `init(t)` bound to `func init()`. gateTargetKind now leaves a bare
  Go call or function value unresolved when the function around it binds
  the name itself (isGoLocallyBound: a parameter, `:=`, `var`), as Go's
  scoping says. The same rule drops existing wrong links: a test's
  `volumeSpec = volumeSpec(…)` var passed on, or a local `errors` map that
  linked to kubectl's `errors` method.

A/B on main a944ec35:
- gin: unchanged.
- etcd: +2 / -25.
- prometheus: +1251 / -112.
- kubernetes: +670 / -542.
Every added link is the package's own declaration, or the right method
for the 5 calls written through a value. Every dropped one is a name the
enclosing function binds (checked by text, the rest by hand). The other
changes are the same targets at confidence 0.9 instead of 0.7.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 10:13:17 +00:00
Colby Mchenry c38f2678ac fix(ts): a supertype import that names a constant reaches the interface beside it (#2657)
vscode's ILogService is both an interface and its createDecorator constant, and the import of it as ITerminalLogService's or IUserDataSyncLogService's supertype resolved to the constant, so the walk up to ILogger stopped there and their this.logService calls linked nowhere.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 10:10:03 +00:00
Colby Mchenry 0c22acf36c fix(ts): a call on a known class goes through that class's own bases (#2656)
A TS/JS call on a field or a typed local whose class the file's import
names went, when that class didn't declare the method itself, to any
class with the method and a matching name: vscode's
`this._storage.dispose` (`Storage extends Disposable`) reached a test
fixture's `Disposable`, Copilot's `Emitter extends lsp.Emitter`, whose
`fire` is the package's, reached a test fixture's `Emitter::fire`, and
`this.logService.trace()` on `ILogService extends ILogger` linked nowhere.
Now that class decides: its own method, or the nearest one up its head's
`extends` / `implements`, each supertype found the way its subtype's file
names it. For a field, a chain that is fully known and has no such
method, or leaves the project for a package, links nothing. A typed
local, whose type an unscoped scan reads, takes only a method found. A
supertype that can't be found, or a same-named function-typed property,
leaves the call to the lookups that follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 09:46:26 +00:00
Colby Mchenry a944ec3579 fix(go): a struct links the types its fields are declared with (#2655)
A Go struct referenced nothing through its fields: etcd's `type
PutResponse struct { Header *ResponseHeader }` or gin's `type Context
struct { handlers HandlersChain }` had no `references` edge to those
types, so impact on `ResponseHeader` or `HandlersChain` missed every
struct holding one, and their users. Main had 0 such edges on gin, etcd,
prometheus and kubernetes; only embedded fields were read (`extends`).

TS extractor and Rust kernel, mirrored:
- goStructFieldTypeNames / struct_field_type_names walk each named
  field's type and push a `references` ref per type name from the
  struct, on the name. Fields mint no nodes: impact never climbs
  `contains` upward (#536), so a field node would stop impact short of
  the struct; Dart attributes field types to the class too (#2327).
- #2441's alias walk is factored into collectGoTypeNames /
  collect_type_names + goDeclaredNames / declared_names, so struct
  fields skip what aliases skip: predeclared types and, written bare,
  the declaration's own type parameters and its own name (no self-edge,
  no failed row for `next *node`).
- An embedded field stays `extends`; an embedded generic's type
  arguments are references (client-go's
  `listers.ResourceIndexer[*v1.Pod]`: 651 such fields in kubernetes).

Resolver: gateTargetKind's unknown-qualifier rule (#2417) now covers
every Go type declaration (GO_TYPE_KINDS). Without it, a field
`op clientv3.Op` under an unaliased go.etcd.io/etcd/client/v3 import
bound to the same file's own `Op`.

Explore: a `references` edge whose ends are both type declarations no
longer makes either end connected to an entry. With the new edges alone
the #1500 CG-10 gate failed: payroll's 8-line `RunResult` (holding a
`[]Payslip`) became connected and displaced the 51-line
runPayrollCycleAll body. The rule alone changes no rendered symbol on
gin, etcd, prometheus, kubernetes, bloc, bulletproof or refine-examples.

Validation (main de3eb71d, site-keyed A/B, every added edge judged
against real package clauses): gin +41, etcd +1006, prometheus +1637,
kubernetes +20203, all correct; 0 dropped/retargeted/metadata-only; no
node changes or self-loops; kernel == wasm. Index time within noise,
DB +0.4-1.4%.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 09:35:01 +00:00
Colby Mchenry de3eb71df6 fix(js,ts): an import written from a jsconfig or tsconfig baseUrl links the file it names (#2649)
CRA and Vite admin templates (codedthemes' berry and mantis, uilibrary's
matx) set `"baseUrl": "src"` or `"paths": { "*": ["./src/*"] }` in a
jsconfig and write every cross-file import as `layout/MainLayout`. The
import resolver took each one for an npm package: loadProjectAliases
returned null for a config with a baseUrl and no paths, and
isExternalImport classifies a bare specifier from the root config alone,
before a nested app's config is read. The imports stayed unresolved,
their names linked by bare-name matching (vite components rendering the
remix app's namesakes), and React Router routes loaded through
`lazy(() => import('views/x'))` bound to the local Loadable value.

- path-aliases: a config with only `baseUrl` loads, marked
  `declaresBaseUrl`; aliasAndBaseUrlCandidates lists the most specific
  `paths` pattern's targets, then the specifier read from a declared
  baseUrl (paths alone never reads bare specifiers, as in TS 4.1+).
- import-resolver: a specifier isExternalImport takes for a package is
  read through the importing file's own config (nearest, else the root's)
  and binds only to a file the index holds (`fileExists` also answers for
  folders and node_modules). A package the file's package.json or an
  enclosing one declares, or a Node built-in, never binds to a project
  module that way, only to a `.d.ts` the project keeps for it (#2437's
  `"*": ["./typings/*"]`). A root catch-all `"*"` no longer marks every
  specifier local in isExternalImport's default mode either.
- The module ref of a one-segment import (`'config'`) links the file its
  specifier resolves to, as a path-shaped one already does (#2528).
- isBoundToOutOfRepoImport keeps the `extends` edge of a class whose base
  is imported through baseUrl.
- importBindingTail parks a binding under its module when the app's
  config maps the specifier to an indexed file, so a sync that edits the
  module relinks `import Layout from 'layout/MainLayout'` and
  `{ Foo as Bar }` (#2450's rule for relative imports). An undeclared name
  that maps to nothing (`express` under `"baseUrl": "."`) and a declared
  package keep their own tail, which root-"*" repos had lost.
- The TypeScript and TSX extension lists probe `/index.jsx` last, as tsc
  does: a route resolves its lazy module as TypeScript.

Validated against main 6071c9e4 on 21 repos (wasm path): every new
import-resolved edge lands in the file its specifier names; failed
imports naming a project file go 194/190/96 -> 0 on berry/mantis/matx;
their routes bind their lazily loaded pages and layouts (matx 7 -> 21
routes); 37 + 45 cross-app JSX renders move to the app's own components.
proshop, next-saas-starter, create-t3-turbo, excalidraw and six more are
byte-identical; root-"*" repos change only parked tails plus module
links. Same deltas with stubbed node_modules. Sync after late adds and
edits equals a fresh index, except one pre-existing barrel-edit gap that
relative imports share.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 08:36:56 +00:00
Colby Mchenry d3a778d0b9 fix(ts): a class extends the class after its type parameters (#2648)
fix(ts): a class extends the class after its type parameters

A TS/JS class head was read up to its first `extends`, which for
`class EditorPane<MementoType extends object = object> extends
Composite<MementoType>` is a type parameter's constraint: EditorPane read
as extending `object` (so nothing), and `MultiWindowParts<T extends
IMultiWindowPart, …>` as extending `IMultiWindowPart`. Fields, wrapper
methods and static methods inherited through such a head were missed or
found on the wrong class. The head is now read from its `class` keyword to
its body, over several lines, with type parameter lists and type arguments
left out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 08:11:37 +00:00
Colby Mchenry 6071c9e487 fix(ts): a field set through a wrapper has the wrapped class's type (#2647)
`private readonly _onDidChange = this._register(new Emitter<void>())` and
`this._store.add(new Emitter())` gave the field no type, so its `fire()`
calls linked nowhere. The field reader now reads `new X(` handed to
`this.<method>(…)` or `this.<holder>.<method>(…)` when that method's own
declaration returns its argument (`<T>(o: T): T`, T its own type
parameter) and the call ends the statement.

The end-of-statement check trims what follows the wrapper's `)`: a CRLF
checkout's lines keep their `\r`, which a `$` anchor never matched.

The field walk and the wrapper lookup now go ten classes up a class's
`extends` chain instead of four: vscode's editors inherit `_register`
and `_store` from `Disposable` up to eight classes above them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 07:44:00 +00:00
Colby Mchenry b210e0eb59 fix(ts): a this.<field> call finds a field a base class declares (#2645)
A field the calling class doesn't declare was read off any same-named
class elsewhere, never off the classes it extends. It is now looked up on
the calling class's base classes, each the class its subclass's file
imports or declares, and a same-named class elsewhere is read last, only
for a type the call's file imports or declares.

A type a file imports from a package outside the project now links to
nothing in the project, unless a project file declares the package with
`declare module`, Flow libdefs included: microsoft-authentication's
`TelemetryReporter` from `@vscode/extension-telemetry` reached another
extension's interface of that name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 05:39:23 +00:00
Colby Mchenry b860b214e5 fix(ts): a call on an imported value links to the class its file imports (#2644)
A call on a value another file exports, like `store.add(…)` after
`import { store } from './state'` with `export const store = new Store()`
there, read the type off the value's declaration but broke a tie between
same-named classes by the calling file, which declares neither, and then
by index order: on vscode, `MenuRegistry`, `FileAccess`, `extUri` and
`errorHandler` calls reached copilot's vendored copies or a test fixture.
The value's file now says which class it is, the one it imports or
declares, in Vue, Svelte and Astro components too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 05:38:48 +00:00
Colby Mchenry 34b17f6b9d fix(ts): a local annotated as one of a type's properties has that property's type (#2640)
A local or parameter annotated as one of a type's properties, like
`editor: IChatWidget['inputEditor']`, was read as the type it indexes, so
its calls reached that type's method of the same name or a guess by the
method's name: on vscode, `visibility.isVisible(…)` through
`ISessionChatPillVisibilityService['pullRequests']` reached the service's
own `isVisible`, and `chatModel.onDidChange(…)` a folding model's.

The property's declared type now decides alone, read off the indexed type
the call's file imports, with its class the one the declaring file
imports or declares, and an array property follows the array rules. A
property whose type isn't written there (a getter's, a `typeof`, a type
parameter of the class) or a key that isn't a name still reads as the
type it indexes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 05:38:10 +00:00
Colby Mchenry 10e316d9a7 fix(ts): a typed call links to the method of the class the file imports (#2641)
When several classes share a name, a TypeScript or JavaScript call on a
typed value broke the tie only by the call site's own file, then took the
first declaration indexed, and a `this.<field>` call by folder nearness.
On vscode, about 25,000 calls on classes vscode imports from its own
`vs/base` and `vs/platform` reached the copies the Copilot extension
vendors, 907 `Emitter` calls a copilot test fixture's copy, and 952 calls
whose first match was a test fixture's class linked to nothing.

The file declaring the class the call's file imports under the written
name, read through re-exports, `import type`, namespace imports, default
imports and `require`, is now passed to resolveMethodOnType, which picks
that file's method among several, through the supertype walk too.
`this.<field>` calls check the import of the call's own file before
folder nearness. Java, Kotlin and every other language are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 01:32:46 +00:00
Colby Mchenry fb213d0bc5 fix(ts): an array method on a local annotated as an array of a class links to nothing, not the class's method (#2639)
`items: Item[]` was read as an `Item`: the annotation's capture stopped at
`[`, so `items.find(…)` linked to `Item.find` whenever the class declares
a method of that name. On vscode that was 16 wrong edges, like
`distinctElements.find(…)` on an `ExplorerItem[]` reaching
`ExplorerItem.find` and `ranges.map(…)` on an `OffsetRange[]` reaching
`OffsetRange.map`.

The annotation pattern now captures a bracket suffix with the type. On an
array of a type, a method arrays have links to nothing and isn't matched
by its name either. Any other method can't be called on the array, so it
is called on an element that shares its name, as in `d.forEach(d =>
d.dispose())`, and keeps the element's type as before. An indexed type
(`Element["groupIds"]`) is still read as the type it indexes.

The sync parking that came with the previous change now reads arrays from
the type inference gives instead of re-reading the declaration line: an
array method on an array keeps its member's tail, and an element's or an
indexed type's call waits for that type's module.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 21:55:15 +00:00
Colby Mchenry 8ed0202071 fix(resolution): workspace globs reach nested members, and a negated glob leaves members out (#2638)
pnpm's `packages/**/*` (folo) and npm's `libs/**/*` (bitwarden) list
member packages at any depth, `packages/plugin-*` and `apps/*/web` name
them by part of a folder name or by a folder below the wildcard, and a
negated glob (`!**/example`, `!examples/with-nx`) leaves some out. The
workspace loader listed only the folders directly under the text before
the first `*` and took a negation for a folder name, so folo's
`@follow/utils`, two levels under `packages/`, was no member and every
import of it counted as an outside package's.

Globs now match folder by folder: `*`, `?` and `{a,b}` within a name,
`**` across folders, breadth-first so a member nearer the root keeps a
name a deeper copy also declares. A wildcard never enters a dot-folder,
`node_modules` or `bower_components`, and a `**` skips `test` and `tests`
folders as pnpm's default ignores do; a folder the glob names literally
is always entered. What a negated glob matches is no member.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 21:54:50 +00:00
Colby Mchenry 53ad0d48b3 fix(sync): a member call on a local typed by an imported class links when the class's module changes (#2637)
`cache.get(k)` after `const cache = new LRUCache(10)` (or an annotated
local, a typed parameter, a default or namespace import of the class) is
linked by a fresh index through the local's declaration. When the class's
module was missing or empty, the failed call was parked under its member's
name, `get`, which more failed refs share than the retry's ceiling, so a
sync that added, restored or filled in the module never retried it.

Such a call now waits under the key of the module the type's binding
imports, as a member of the binding itself does since the previous change
(2630), and keeps that change's member and receiver triggers. Only calls
are parked this way: in TypeScript a typed local's member is only ever a
call, and a method of `this` passed as a value is looked up in the
enclosing class.

A local declared as an array of the class (`results: URI[]`) keeps its
member's tail. Resolution reads the element type there too, but
`results.push` is the array's method, which no edit of the class's module
links. On vscode those calls were 60% of what the parking added and nearly
doubled what an edit of `uri.ts` retried. Inference now reports the line
it read the declaration from.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 20:06:03 +00:00
Colby Mchenry 986de95c35 fix(vue): an import through @/ or ~/ in a Vue project links the module's file (#2633)
In a project with a `vue` dependency or a `.vue` file, a script's module
import through `@/` or `~/` went through the Vue resolver's own mapping to
`src/`, which linked the first node of the file it found: a constant the
module declares, or a component. A tsconfig alias that starts like a Nuxt
virtual module (`#app/where`) linked the importing file itself. Without Vue
the import resolver links the module's file node, following tsconfig
paths. So the walks a sync makes from a module or barrel that appears or
goes away to the files importing it (#2512, #2560) never found these
importers. Which node the edge hit also depended on the order a file's
nodes were stored, so a sync and a fresh index could disagree.

The Vue resolver now leaves a module import to the import resolver whenever
that finds the file, and only adds what a Vue app's bundler finds from a
plain script: a component named without `.vue`, or a folder's `index.vue`
(`import Layout from '@/layout'`), linked to the file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 16:28:23 +00:00
Colby Mchenry baf190678f fix(sync): a member reference through an import binding links its module when the module changes (#2630)
`NODE_PATH_EXCLUDELIST.includes(p)` after `import { NODE_PATH_EXCLUDELIST }
from './constants'`, `store.get(k)` through a default import or
`api.get()` through a namespace import is linked by a fresh index through
the import. When the module was missing or lacked the export, the failed
reference was parked under its member's name (`includes`, `get`), which the
module seldom declares and which the retry skips past its 500 ceiling. A
sync that gave the module the export never relinked it, nor one that added
the module where no import edge reached its file.

A direct member reference through an import binding of a project module is
now parked under the module's key, as whole names through a binding are
since #2450, and keeps two more triggers. Its member's name, through a new
expression index on the tail its name gives (schema v16), under the same
ceiling as the references still parked under that name: a namespace
import's barrel forwards the member from another file, and a guess by name
links a receiver whose module never resolves. Its receiver's name, through
a prefix range on the module-name index of #2450: a barrel's import of the
declaring file that no walk finds. The router navigation retry and the
dead-code check read module-parked calls by their member through the new
index. A chain or a longer path keeps its member's tail: on vscode,
parking them too tripled the refs an edit of a hot module retries, and
none of them resolved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 07:56:42 +00:00
Colby Mchenry e2b0cf5eea fix(cpp): a call on an inherited member reached through a chain, like options.statistics->getTickerCount(…) on a RocksDB Options, links to the member's class (#2628)
Step 3 of member chains, after #2626 and #2627. The type of `x.member` was
read from x's class alone, so a member that class inherits was never found
and the call fell back to its bare name.

A temporary diagnostic on main measured why chain calls still fell through:
2,801 of 4,884 were a member declared in a base class. Nearly all were
rocksdb's `Options`, which declares no members of its own and inherits
`statistics`, `table_factory`, `listeners`, `prefix_extractor` and the rest
from `DBOptions` and `ColumnFamilyOptions`. The other causes are left for
later:
- a chain whose base can't be typed: 875;
- a class the index lacks, e.g. protobuf's generated `_impl_`: 626;
- a member found nowhere: 337.

cppExpressionType's member branch now uses cppInheritedDataMember, the
lookup the calling class's own members already use (#2533):
- the class's own declaration first;
- then the classes it derives from, through their base edges, to depth 4;
- a base that depends on the class's template parameters is skipped
  unless a using-declaration brings the name in.

Kit A/B against main e8ec7fd8:

| repo | removed | added | retargeted | same target, now typed |
|---|---|---|---|---|
| rocksdb | 1,410 | 634 | 392 | 184 |
| protobuf | 0 | 2 | 149 | 55 |
| leveldb, fmt, redis | identical | | | |

- Removed: the bare-name guesses on inherited std::shared_ptr and
  std::vector members, such as `options.table_factory.reset(…)` →
  FSWritableFilePtr::reset (654) and `options_.db_paths.emplace_back(…)` →
  autovector::emplace_back (256).
- Added: `options.statistics->getTickerCount(…)` → Statistics (432),
  `rate_limiter` → RateLimiter (51), `comparator` → Comparator (26).
- Retargeted: DummyOldStats -> Statistics, DB -> Env, ClockCacheShard -> Cache.
- protobuf's generated `this_._internal_metadata_.Clear<…>()`,
  `MergeFrom<…>` and `unknown_fields<…>` now reach InternalMetadata, a
  member every message inherits from MessageLite. Before, they reached the
  message's own `Clear` or `Any::MergeFrom`.

All 50 random sites read by hand (36 rocksdb, 14 protobuf) were correct.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 02:05:39 +00:00
Colby Mchenry e8ec7fd847 fix(cpp): a call on a member reached through other members, like thread->rand.Next() on a Random64, links to the method of the member's class (#2627)
Step 2 of member chains; #2626 was step 1. matchCppMemberChainCall (formerly
matchCppOutsideMemberChainCall) now also resolves a chain whose member is
of a project class, in the same steps matchCppUnspelledReceiverCall takes
for `it->second.Flush()`:
- the class C++ lookup finds for the member's type, where that type is
  written;
- then its method, or one it inherits (cppMethodOf, with overloads picked
  by argument types);
- or no edge when the class surely lacks it (cppLacksMethod).

Before, such a call went by its bare name to whichever class had a method
of that name. Inside a method it could also be taken for an implicit
`this` call on the method's own class.

A member is now read from the class node C++ lookup found (cppDataMemberIn),
not from the first class of that qualified name that declares it
(cppDataMemberType, removed). rocksdb's db_bench_tool.cc and
db_stress_shared_state.h each declare a ROCKSDB_NAMESPACE::ThreadState,
whose `rand` is a Random64 in one and a Random in the other.

Kit A/B against main 6e884d7b:

| repo | added | retargeted | same target, now typed | removed |
|---|---|---|---|---|
| rocksdb | 571 | 2,008 | 1,738 | 2 |
| protobuf | 42 | 95 | 142 | 0 |
| leveldb | 42 | 30 | 141 | 0 |
| fmt | 0 | 56 | 20 | 0 |
| redis | 0 | 0 | 0 | 0 (identical) |

The most common rocksdb retargets are DBImpl -> DB (calls on a `DB*`),
BlobContents -> Slice, BlobFileReader -> FileDescriptor and
EnvWrapper -> Env. Hand-reading random samples found one wrong
retarget (db_bench's `thread->rand.Next()`, the ThreadState namesake),
which led to the member-lookup fix above. After that fix, all 76 sites
sampled across the four repos were correct:
- 30 retargets and additions, plus both removals, in rocksdb;
- 20 in protobuf, 14 in leveldb and 10 in fmt.

The two removed calls are `task_reader->rep_->GetCoroutine(…)` on a
`SstFileReader::Rep`, which has no such method. They had linked to
`CoroDB`'s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 23:13:48 +00:00
Colby Mchenry 6e884d7bce fix(cpp): a call on a member reached through other members, like options.cf_paths.emplace_back(…) on a std::vector, no longer links to a project method of that name (#2626)
The extractor records a call on a member chain (`a.b.m()`, `a->b->m()`,
`this->p_.m()`) by its bare method name, so it went to whichever project
method shared the name. A census of the cgstd kit found most such calls
linked by name alone, and most of those links wrong. Above all, they were
on members of standard-library types, whose methods (`size`, `reset`,
`push_back`, `get`, `empty`) a large codebase has namesakes of.

matchCppOutsideMemberChainCall reads the chain where the call is written
(cppMemberChainReceiver) and types it with the existing cppMemberObject:
- a data member is typed by its declared type in its class
  (cppDataMemberType);
- `->` goes through a pointer, smart pointer, optional or iterator.

It gives no edge when the object the method is called on is a library type
(isCppLibraryType) or a type under a namespace the project declares nothing
in (isCppOutsideQualifiedType). These are the call-chain resolver's rules.
Unlike a call chain, the operator is read as written, so `.` on a
`std::vector<T>` or a `std::unique_ptr<T>` is that type's own member,
whatever `T` is.

Anything else, a member of a project class included, goes to the name
strategies as before.

Kit A/B against main a2570695 (only removals; nothing added or retargeted):

| repo | calls removed |
|---|---|
| rocksdb | 2,001 |
| protobuf | 234 |
| leveldb | 15 |
| fmt | 12 |
| redis | 0 (identical) |

Every removed link was a bare-name guess. Of the 2,235 removed sites in
rocksdb and protobuf, a judge reading the members' declarations across each
repo rated:
- 2,044 as wrong links (a library type's namesake, or an unrelated class);
- 165 unknown;
- 10 not counted as chains by its pattern (after a cast, like
  `(int)data->entries.size()`);
- 16 right. These turned out to be name collisions on the judge's side,
  checked in the source (`std::deque logs_`, `std::shared_ptr decompressor`,
  `std::vector ids`).

24 random removals were also read by hand, and all were correct.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 20:39:28 +00:00
Colby Mchenry 1981354476 fix(cpp): of two overloads alike but for a const, like protobuf's DynamicCastMessage(const MessageLite*) and DynamicCastMessage(MessageLite*), a call reaches the one C++ picks (#2618)
Overload fit by argument type (cppArgumentTypeChoice) scored a `const T*`
parameter and its `T*` twin alike, and the one declared first won: protobuf's
`DynamicCastMessage<T>(ptr.get())` on a `std::shared_ptr<Message>` took the
`const MessageLite*` overload.

- cppConstTwinChoice: of the best-fitting overload's twins, alike but for
  the `const` of a pointer or reference parameter, the one that adds `const`
  to the fewest arguments.
- cppWrittenTypeFit: a pointer or reference to a non-const type never takes
  a const object, nor a reference a value a call returns (cppNamesObject
  tells a named object from a call's result); an object is no pointer, nor a
  pointer to characters a pointer to another type (or the reverse). None of
  that for an argument of a template parameter's type, and the pointer and
  `const` rules not for a parameter the function's own template parameter
  types (it deduces the `const`).
- The argument's type keeps a `const` its declaration writes in front
  (`const Buffer* b`, `constexpr char key[]`), which the declarator regex
  leaves out; an array is a pointer to its element; `&ref` is a pointer to
  the referee; cppLibraryElementOf keeps a `const` in a holder's template
  argument (`std::shared_ptr<const Message>`).
- Template headers are read 8 lines up, not 3 (fmt's `join`).

A/B on the cgstd kit against main 0893606e: leveldb and redis identical;
fmt 14, rocksdb 25 and protobuf 194 calls retargeted, each triaged against
C++'s choice (const twins, objects and arrays off the wrong pointer
overloads, temporaries to `T&&`).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 07:20:21 +00:00
Colby Mchenry 0893606ed5 fix(cpp): a call on what a container's front()/back()/at() or a holder's get()/value() returns, like rocksdb's edits.back()->MarkAtomicGroup(…), calls the element's method (#2616)
A call on what a library container hands out linked to nothing: the
standard library's `front()` returns nothing the index can read, and the
library-receiver gate keeps the name strategies off a `std::vector`.

cppLibraryElementOf reads what such a member returns, where the
container's type is written:
- `front()`, `back()` and `at(i)` of a sequence (std/absl, and the project
  sequences cppRangeElementOf already treats as such) → its element;
- a library map's `at(key)` → the mapped value;
- `std::stack`/`std::priority_queue` `top()`, `std::queue` `front()`/`back()`
  → the element;
- `get()` of `std::unique_ptr`/`std::shared_ptr`/`absl::NoDestructor` → a
  pointer to the held type, `value()`/`value_or()` of an optional or an
  `absl::StatusOr` → the held type.
It is asked in cppChainInnerType (a chain `recv.front().m()`) and in
cppExpressionType (an `auto` local, a range, an argument), next to
cppLibraryIteratorOf.

A/B on the cgstd kit against main 98127e54: leveldb, fmt and redis
identical; rocksdb 299 calls added, 89 retargeted (overloads picked by a
typed `.get()` argument, like `test::PerThreadDBPath(env_.get(), …)`, and
inherited methods on a typed element), 10 removed (guesses on what turned
out to be library containers) and 56 confidence-only; protobuf 7 added and
16 retargeted (cast helpers off their `std::shared_ptr` overloads, `Add`
off a deleted one). Every site was joined with the element type an
instrumented arm logged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 06:26:34 +00:00
Colby Mchenry 98127e54d0 fix(c): a header's definition for a flag nothing sets, like lua-cjson's #ifdef USE_INTERNAL_FPCONV fpconv_init, gives way to the source file the build compiles (#2615)
lua-cjson's fpconv.h defines `static inline void fpconv_init()` only under
`#ifdef USE_INTERNAL_FPCONV` and otherwise declares it `extern` for fpconv.c
to define. Nothing in redis's tree sets the flag, so its build calls
fpconv.c's, but #2613's rule (the file's own or an included header's
definition first) took the header's.

c-feature-variants.ts decides whether a line is compiled only by a build
that sets a flag nothing sets. It reads the conditionals around the line
(cpp-macro-visibility's directiveLines, now exported): `#ifdef`/`#ifndef`,
and `#if` with defined, !, &&, ||, parentheses, integers and bare flags,
then `#elif` and `#else`. A flag is set nowhere when the line's own file
doesn't define it, no build file from the project root down to the
definition or the call names it, and no C/C++ file of their components
(the tree under the nearest directory with a build file) defines it.
Reserved and platform names stay unknown.

cppFunctionOverload's C branch then takes a non-static, non-variant
definition outside the file's tier when one exists, when every definition
the file sees is such a variant, and when the call itself is compiled by
the default build. A branch around both the definition and the call decides
nothing: redis's quicklist.c tests call their own `static mstime` inside
`#ifdef REDIS_TEST`.

A/B against main dc4ccf6b: leveldb, fmt, rocksdb and protobuf identical;
redis 1 call retargeted, lua_cjson.c's fpconv_init() from fpconv.h to
fpconv.c. Indexing time within noise (redis 10.5-11.9 s on main, 10.2-12.3 s
here).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 05:47:57 +00:00
Colby Mchenry dc4ccf6b14 fix(c): a C call, like redis's mstime(), reaches the function its own file can see, past another file's static copy (#2613)
A C call now links to the function of its name the call's own file can see:
its own, or one a header it includes defines, else one with external
linkage, the best placed of them (cppFunctionOverload's C branch). Before,
the name strategies took the function nearest the call; when that was
another source file's `static`, isVisibleAcrossFiles dropped it and the
call was left unlinked, so no call reached redis's `server.c` `mstime()`
or `ustime()`.

- A source file's `static` function is visible to a file that `#include`s
  that source file: hiredis's async.c includes dict.c, redis's ae.c its
  event-loop backend.
- The coordinator's `resolveImport` hook falls back to matchByFilePath for
  a C/C++ `#include` the import resolver can't place, as resolveOneInner
  already does, so cppIncluders sees includes only the end of their path
  names: protobuf's `google/protobuf/descriptor.upb.h`, which two generated
  copies end in, and jemalloc's `jemalloc/internal/*.h`. Standard headers
  are left out: otherwise `#include <math.h>` makes jemalloc's
  test/math.h visible to its own include through isIncludedCppTestSuite.

A/B on the cgstd kit against main 4a591aee: leveldb, fmt and rocksdb
identical; redis +194 calls linked and 115 retargeted (114 to hiredis
alloc.h's POSIX `static inline`s, 1 known miss: lua-cjson's fpconv_init to
an inline only `#ifdef USE_INTERNAL_FPCONV` builds use); protobuf 412 upb
calls retargeted from the unincluded php-upb.h amalgamation to the headers
the calling file includes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 04:34:50 +00:00
Colby Mchenry 4a591aeee8 fix(cpp): a call to an overloaded free function, like protobuf's ParseWithLimit(limit, data, result), reaches the overload its arguments fit (#2612)
A C++ call to a function outside a class took whichever same-named
function the name strategies ranked first, by file and line proximity,
never by its arguments. Methods already picked their overload by argument
count, string literals and written argument types (cppOverloadFor);
functions never did. protobuf's `ParseWithLimit(limit, data, result)` on an
`int32_t result` reached the `int64_t&` overload beside the call, and
rocksdb's `NewLRUCache(cache_opts)` the overload taking a `size_t
capacity`.

Exact, qualified (global, exact, partial) and macro-namespace matching now
keep their choice of function, then let the call's arguments pick among its
overloads, the functions of its qualified name the call's file can see
(cppFunctionOverload, with cppOverloadFor's count-then-type fit; the
macro-namespace scorer breaks its ties by type). The choice stays on a tie.
- An overload only another source file sees (another `.cc` file's
  `static`, an unnamed namespace's) never competes. When the name strategy
  had picked such a function, which was then rejected, the call now links
  to the overload its file sees: leveldb's `GetLengthPrefixedSlice(&input,
  &key)` reached memtable.cc's static and linked nothing.
- A function hides a class of its name, so a call to a name both have
  reaches the function.
- Only C++ calls: protobuf's Rust FFI calls lost their `extern` targets to
  the C definitions when every language went through it.

Argument types read better too: a parameter named like the function it
belongs to, protobuf's `std::string u64(uint64_t u64)`, was read as the
function's own declarator, so `u64` looked like a `std::string`.

Validated on the cgstd kit against main (627018eb), every changed site
classified by argument count against both targets, ~100 type-decided sites
read by hand:
- leveldb: 5 calls linked that linked nothing.
- fmt: 283 retargeted (139 to an overload that takes that many arguments,
  110 by type, 34 multi-line or defaulted); fmt's `fill_n(it, …)` on an
  iterator of unknown type now takes the `basic_appender` overload, right
  for fmt's usual iterator.
- rocksdb: 101 linked, 1118 retargeted (720 by count, 339 by type).
- protobuf: 29 linked, 941 retargeted (372 by count, 558 by type), e.g. the
  compiler helpers' `QualifiedClassName(enum_, …)` reaching the
  `EnumDescriptor*` overload and `Namespace(d->file())` no longer calling
  itself.
- redis (C): byte-identical.
Full suite: 7188 passed, 0 failed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 03:32:08 +00:00
Colby Mchenry 627018eb25 fix(cpp): an explicit specialization, like protobuf's WireFormatLite::ReadPrimitive<int32_t, WireFormatLite::TYPE_INT32>, is named after its template (#2609)
An explicit specialization of a function or member function template kept
its template arguments in its name: protobuf's `template <> bool
WireFormatLite::ReadPrimitive<int32_t, WireFormatLite::TYPE_INT32>(…)` was
named `TYPE_INT32>` and qualified `…::ReadPrimitive::TYPE_INT32>`, the
qualified id split at the `::` inside its arguments; rocksdb's `template <>
int64_t Deserialize<int64_t>(…)` was `Deserialize<int64_t>`. A call writes
the bare name, so nothing linked to them.

Both extractors (wasm and the native kernel) now name a specialization
after its template, from the template-id's own name, and take its receiver
from the text before the declarator's name. That text must end in a real
`::`: tree-sitter recovers Metal's `vertex VertexOut vertexShader(…)` with
a missing, zero-width one.

A specialization now meets its template among a name's candidates, so the
resolver chooses between them wherever it picks among C++ candidates (a
class's methods, the implicit-this walk and its bases, exact, qualified,
global, fuzzy and macro-namespace matching):
 - a call that writes template arguments reaches the specialization
   written with the same ones (spacing aside, or qualified further on one
   side), else the template itself or an ordinary overload, else nothing:
   fmt's `num_bits<unsigned short>()` stays on `num_bits<T>()` instead of
   the nearer `num_bits<uint128>()`; protobuf's `Arena::Create<T>` keeps
   calling `DefaultConstruct<T>`, not the tests' `DefaultConstruct<
   DispatcherTestProto>` hook; a dependent `ReadPrimitive<CType,
   DeclaredType>(…)` links nowhere rather than to the first specialization.
 - a call that writes none, or `<>`, reaches a specialization only when
   nothing else has the name.
 - a class's own member template, specialized but none for these
   arguments, ends the lookup there instead of falling to a base's
   namesake.
The `cpp-override` pass leaves specializations out on both sides: a member
template is never virtual.

Validated on the cgstd kit against main (f7951a13): leveldb and redis
byte-identical; fmt: 8 specializations renamed, every call target as on
main; rocksdb: the cassandra `Serialize<T>`/`Deserialize<T>` calls (25 in
format.cc, 75 in its tests, which main sent to `ColumnBase` methods) each
reach the specialization their argument names (100 of 100 agree);
protobuf: `MergeFrom<MessageLite>` (3 calls), `ReadPrimitive<int,
TYPE_ENUM>` (2) and a test's `ReadPackedPrimitive<uint32_t, TYPE_FIXED32>`
reach their specializations; 5 dependent calls like
`GetRepeatedFieldInternal<T>`, and one `MutableRepeatedFieldInternal<int>`
(the macro writes `<int32_t>`), no longer link to the first specialization
a macro defines. Kernel and wasm dumps identical (but for protobuf's known
Swift line). Full suite: 7179 passed, 0 failed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 02:40:57 +00:00
Colby Mchenry f7951a13db fix(cpp): a method a macro of its file defines, like protobuf's PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, number, int), is indexed where the macro is invoked (#2605)
protobuf declares its descriptor accessors in their classes and defines
them below with macros, like `PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor,
number, int)`; its reflection pastes `Reflection::Get##TYPENAME` in
another. The parser never sees those definitions (the preParse blanks the
invocations) and a declaration mints no node, so the methods had none and
every call to them linked to nothing.

- After either extractor (the kernel or the wasm walker), a step over the
  original source expands the file's own function-like macros whose body
  defines `Class::method(...) ... {`, at each invocation at namespace
  scope, and mints a method node per definition: named and qualified like
  an out-of-line definition, contained by the file and the same-file
  class, with the expanded head as its signature. Constructors,
  destructors and variadic macros are left out.
- The parse worker leaves the raw kernel fast path only for a file that
  may define one (a cheap text test), so the step sees it.
- The C++ resolver reads such a method's return type and parameters from
  its signature, and never takes it for a deleted overload.

A/B vs main on the kernel path, every changed site triaged: leveldb and
redis identical; fmt +13 nodes and rocksdb +11 (gtest's TestEventRepeater
overrides); protobuf +257 nodes, 6,203 calls and 2 references added, 252
calls retargeted, 11 metadata-only, none removed. Kernel and wasm dumps
are byte-identical, protobuf's one pre-existing Swift line aside.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 00:53:01 +00:00