Repository navigation
merge: 同步 257 个上游提交并兼容 Pinable 历史索引 - #6
Merged
Merged
Conversation
… never by name alone (colbymchenry#2125) Found by the README-wide sweep — Django/Flask/FastAPI apps' most-depended-on lists were test and serializer methods: netbox `UserConfig.all` (3,610 from `X.objects.all()`), `PortSerializer.create` (2,093 from `.objects.create`), a test-local `FakeQuerySet.count` (1,910); healthchecks `AuthTestCase.get` (880 from `Channel.objects.get()`), `ProfileAdmin.login` (702 from `self.client.login()`); mealie `_FakeHTTPResponse.json`. Python keeps a call through a receiver it cannot name (`User.objects.get`, `self.client.login`, `request.POST.get`) as the bare `get` / `login`, and exact-name matching then took any class's method by proximity. The call's shape is now read at its column (the call's start): - `bare` (`get(1)`): not a method — Python has no implicit self — and not a project symbol when the file takes that name `from` a module the project doesn't contain (`from django.shortcuts import render`); - `chained`: only a member of what the chain names last — a method of a class of that name (case/underscores ignored: `self.store` → `Store`, `self.user_service` → `UserService`) or a function/class in a module of that name (`app.helpers.slugify()` → helpers.py); - `self.x()` / `cls.x()`, and chains split across lines: unchanged. Fuzzy matching is case-exact for Python (`dir(…)` ≠ class `Dir`). Lexical reachability now walks every enclosing scope, so a method of a class declared inside a function is only reachable in there (memoized per candidate). A/B vs main (edge diffs, every change classified): netbox −18,091/+73 (indexes 8s → 5s), healthchecks −3,354/+361, pytest −2,950/+105, mealie −1,802/+6, allauth −1,086/+57, DRF −943/+50, flask −167/+17, httpx −147/+24. Gains are precise member links (`self.channel.notify` → Channel.notify, `item.stash.get` → Stash.get, `config.cache.get` → Cache.get, `self.provider.verify_token`); the one deliberate loss class is calls through an instance whose type needs inference (`flask.g.setdefault` in flask's own repo). excalidraw, typeorm, gson, okio, AutoMapper, gin and hono byte-identical. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…atic imports (colbymchenry#2126) Found by the README-wide sweep: halo's most-depended-on symbols were an `EmailVerificationService.verify` (1,038 — Mockito's `verify(mock)`) and a builder's `eq` (845 — ArgumentMatchers `eq`); retrofit's a test helper's `assertThat` (1,357 — Truth); mall's a DTO's `hashCode` (Object's). A bare Java call (`verify(x)`, `helper()`, `this.x()`, `super.x()`) now has only method candidates declared on a class around it, on one of that class's supertypes (read transitively from the declarations' `extends` / `implements` — the resolved edges don't exist yet on the first pass), or imported statically (`import static a.B.m;` / `a.B.*`). Memoized per type and per file. A/B vs main (edge diffs, every change classified): halo −2,103/+145, retrofit −1,380/+18, commons-lang −202/+87, jsoup −92/+45, mall −76, gson −7/+4. Gains are the right target where one exists: halo's `and` / `equal` / `isNull` through `import static …Queries.*`, jsoup's `attr(…)` through `LeafNode`, commons-lang's `addExact` on its own class instead of a nested MathBridge, retrofit's `getRawType` through `CallAdapter.Factory`. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…olbymchenry#2128) Calls in `.vue`, `.svelte` and `.astro` files carry their own language, so the JS/TS rules from colbymchenry#2120 never applied to them: halo's `t('…')` from `useI18n()` went to an interface property `t` (562 callers) and `ref(…)` from `vue` to a local `ref` (523). "Outside the repository" is now a package the importing file's package.json chain (or a Deno import map) declares, a Node built-in, `@std/…`, or a framework's virtual module. An alias the resolver can't follow — SvelteKit's `$lib/…`, a nested Nuxt app's `~/…`, a nested app's own `@/…` — stays the project's, and a `workspace:`/`file:`/`link:` dependency is in the repo. SFC files also get the JS built-ins (`fetch`, `Error`, `Map`), and a file's own import of a built-in's name (`import Map from './Map.svelte'`) is the import. Untyped three-segment chains (`api.groupReports.getAll()`) keep resolving in SFCs, where they reach their API client class. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…repo (colbymchenry#2129) create-t3-turbo, tamagui's starter and react-native-reusables keep an Expo app beside a Next.js app. Expo Router read the Next app's `app/` folder as its own, so `layout.tsx` became a `/layout` screen, `page.tsx` a `/page` one, `_components/posts.tsx` and `api/auth/[...all]/route.ts` screens too, and a shared `packages/app/` library's files became screens as well. A resolver can now name `appDependencies`; its extractor runs on a file only when that file's package.json or an enclosing one declares one of them. When no manifest in the project declares any, detection found the framework by other evidence and it runs everywhere, as before. Expo Router names `expo-router`, Next.js `next`. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…uxt routes only in Nuxt (colbymchenry#2130) vue-element-admin, vue-admin-template and vben had no routes: their tables are named arrays (`export const constantRoutes = [...]`, `const routes: RouteRecordRaw[] = [...]`) or per-module objects (`const tableRouter = {…}`) handed to `new Router(...)`, and most of their screens are `children`. The Vue Router reader now reads those tables in any file that builds a router, imports vue-router or lives in a router/ directory; joins children onto their parent's path (a parent is a screen only when no child claims its address and it doesn't redirect); binds a lazy view by the FILE it imports (all of vue-element-admin's are `…/index.vue`), through an alias the resolver can't follow by the one file in the app with that path; links each screen to its parents' components as layouts; and takes `this.$router.push`. Nuxt's file routes move into their own `nuxt` resolver, detected only in a Nuxt app: halo's plain-Vue console got 30 made-up screens from its `pages/` folders. A Nuxt app at the repository root now gets its routes, and a top-level `pages/index.vue` is `/`, not `/index`. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…rs (colbymchenry#2131) A `(group)` directory shares a layout and is never part of the URL, and a parameter's `=matcher` checks its value. Kept in the name, shadcn-svelte's `src/routes/(app)/(layout)/blocks/+page.svelte` was `/(app)/(layout)/blocks`, so no `goto('/blocks')` or `<a href="/blocks">` ever reached it and its Screens showed no navigation at all. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
colbymchenry#2132) react-boilerplate's header links are `export default styled(Link)`…``, used as `<HeaderLink to="/features">`; takenote's guards render v5's `<Redirect to="/" />`. Neither tag was read, so both apps had routes and no links between their screens. The link synthesizer now reads `<Redirect to>` (navMethod `redirect`) and any styled-components / emotion wrapper of `Link` / `NavLink` — declared in the file, or imported from a file that declares or default-exports one. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…elative navigate (colbymchenry#2133) From the router sweep: - angular-spotify had 12 routes all named `/` and no navigation. Its lazy routes are `async () => (await import('@ws/home')).HomeModule` through an Nx library's `src/index.ts` barrel, which the mount pass never looked through; and every lib is its own `src/`, so each routes file got its own route table and no template's `routerLink` found the screen it names. - jira-clone had 3 routes and no navigation: its issue route is `issue/:${ProjectConst.IssueId}` (a class `static readonly`), its root redirect lives in `app.routes.ts`, which only mounts, and `navigate(['project', 'issue', id])` has no leading `/`. Now: lazy mounts follow `export … from` barrels (and an NgModule's routing imports); `(await import(x)).M` is read; route constants may be class statics (strings or objects), enum members, or live behind a barrel, and a template-literal path takes constant holes; a routes file that only mounts contributes its redirects at its mount prefix; the route table is keyed by the `angular.json` / `nx.json` workspace; and `router.navigate` / `createUrlTree` without `relativeTo` resolve a bare first command from the root, as Angular does (template `routerLink` stays relative). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ly imports (colbymchenry#2134) - Expo Modules: a JS call on a `requireNativeModule('N')` binding — typed (`<CameraNativeModule>`) or not, local or imported (expo-camera's `import CameraManager from './ExpoCameraManager'`) — resolves to module N's declared function, Swift first and Kotlin beside it, else to the member on the binding's declared type. It went to the same-named static method making the call. - A JS/TS member call on an import binding never picks a method declared in the calling file, and ruling those out never manufactures a unique guess. - `import type { X }` was parsed as a default import named `type` (every type-only import bound `type`), and `{ a, type B }` bound `type B`. - A name the file binds from an out-of-repo package names nothing in the project, for every reference kind, and JS/TS fuzzy matching is exact-case: trpc's 402 `Record<…>` references went to a `record` property, element-plus's 121 `mount` imports from @vue/test-utils to a test helper. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…st decides (colbymchenry#2135) - `app/blog/og-image/[post]+api.ts` was a screen named `/blog/og-image/[post]+api` (evanbacon.dev). An Expo API route is now one endpoint per exported HTTP method (`GET /blog/og-image/:post`), bound to its handler, the way Next.js `route.ts` files are. - The per-app framework gate (colbymchenry#2129) took ANY enclosing manifest's declaration: react-native-true-sheet's root declares expo-router for its example app, so its `docs/` Next.js app got 16 Expo screens (`/layout`, `/page`, `/api/search/route`, …). Walking up from a file, the first manifest that names any gated framework now decides. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ymchenry#2136) Extraction keeps `super.didMoveToWindow()` under the bare method name, so every strategy resolved it to the enclosing override itself. Across the bridge sweep that was 139 self-edges on Charts, 142 on commons-lang, 101 on BookStack, 92 on realm-swift, 82 on react-native-svg — lifecycle overrides and delegates drawn as recursion. `gateSuperSelfCall` declines a `calls` result that targets the calling node when the call site is written through `super` / `base` (C#) / `[super …]` (Objective-C) / `parent::` (PHP) / `super().` / `super(C, self).` (Python). Plain recursion keeps its edge. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…SX via default imports (colbymchenry#2137) - `requireNativeComponent('X')` (Paper) now emits the same JS `component` node a Codegen spec does, so the Fabric pass links it to the native view / manager classes; the extractor also runs on `.js` / `.jsx` spec modules (segmented-control's spec is Flow `.js`). react-native-maps' `AIRMap` gains its iOS implementation. - A JSX tag that names no node is the file's DEFAULT import of a module's one component: `<RNCSegmentedControlNativeComponent>`, and element-plus's test `<Autocomplete>` for `autocomplete.vue` (whose component node is `autocomplete`). A named import never takes a barrel's one component. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…hannel (colbymchenry#2138) The rn-event-channel pairs a native emit with a JS listener on the event's LITERAL name. Most libraries name events through constants — NetInfo listens with `addListener(PrivateTypes.DEVICE_CONNECTIVITY_EVENT, …)`, many emit with `.emit(EVENT_NAME, …)` or `sendEventWithName:kEvent` — so their channels were empty. Identifier / member-chain event names are now read to the literal their declaration holds (JS/TS const & enum, Java `static final`, Kotlin `const val`, ObjC `NSString *const` / `#define`, Swift `let` / enum case), scoped as the language scopes them: a bare name in the same file or behind an import, `Owner.NAME` inside Owner or a namespace import's file. The handler of a constant-named listener is a function in the same file, else the enclosing one. A first cut that read constants by name alone turned a `.emit(eventName, …)` parameter into some test's `eventName = "pong"`. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…e languages (colbymchenry#2139) The last-resort fuzzy match looks names up in a lowercase index — right for PHP, Pascal/Delphi, CFML, COBOL and VB.NET, whose identifiers ignore case, and wrong for every other language. jsoup's 1,844 `@Test` annotations decorated a `CharPredicate.test` method; commons-lang's `new BitSet()` instantiated a `bitSet` field accessor 64 times; mall's `new Info()` an `info()` endpoint; gson's `Method` type a test's `method()`; fmt's `#include <optional>` gtest's `Optional`. This generalizes the per-language exact-case rules (Rust, Python, JS) into one: outside CASE_INSENSITIVE_LANGUAGES a fuzzy candidate must match the reference's exact name. The cross-language fuzzy-gate test now builds its winner from an exact-case name. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ls (colbymchenry#2140) A `<script>` block goes through the TS/JS extractor, which extracts no symbol for a method in an object literal — so every Vue 2 component, and every Vue 3 one not on `<script setup>`, had no `handleLogin`, no `mounted`: their calls, their `this.$router.push`, and the template's `@click="handleLogin"` all belonged to the file. `vue-options-api.ts` reads the options object the default export is (directly, or via defineComponent / Vue.extend / Vue.component) and names each function in it — `methods`, `computed` (incl. get/set objects), `watch` (incl. `{ handler }`), `data`, `setup`, lifecycle hooks, Nuxt 2's asyncData/fetch — as `method` nodes owned by the component; the Vue extractor re-attributes the references and edges written inside each. A component's own method is only reached as `this.m()` in that component: the member-call and exact-name strategies no longer hand it `e.preventDefault()` (ImageCropper's `preventDefault` method took every event's call), `this.editor.setValue()`, or `this.$refs['input'].click()`. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…n()` is a bare call (colbymchenry#2141) - The name prefilter checks a case-SENSITIVE set of known names, so in PHP, Pascal, CFML, COBOL and VB.NET — whose identifiers ignore case — a call written in another case (`formatprice()` for `FormatPrice`, TestBox's `ToMatchWithCase()`) was dropped before any strategy ran. Those languages now also check a lowercase set (built lazily, only when asked). - `isBarePhpCall` took any `>` before a name for `->`: every call after `=>` in a PHP array (`'total' => count($items)`, `'by' => user()->id`, `'label' => trans('…')`) was a member call, and found a same-named method — 166 wrong edges on BookStack (`trans` → LocaleDefinition::trans, `new Response` → ImageStorageDisk::response, `url()`, `config()`, `count()`). It now requires `->` / `?->` / `::`. - A fuzzy `instantiates` never names a method. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…archy (colbymchenry#2142) Extraction records `$this->m()` under the bare name, so exact and fuzzy matching took ANY same-named method: Drupal core's tests' `$this->assertEquals()` (PHPUnit's) went to a comparator class 8,832 times, `$this->assertSession()` to WebDriverTestBase 9,556 times, `$this->t()` to `Views::t` 6,811 times; Laravel's `$this->assertCount()` to FilesystemAdapter 1,722 times. A call written through `$this->` / `self::` / `static::` (or `parent::`) now takes only a METHOD of the enclosing class's ancestry — `extends` and trait `use`, read from source and resolved through the file's `namespace` / `use` imports (aliases included) to fully qualified classes — or a subclass's (a base calling what a subclass defines). Past an ancestor outside the repository (Orchestra's TestCase) a repository trait's method still counts, an unrelated class's never does. Inside a trait, `$this` is the using class, so trait bodies are not scoped. Multi-line `use A,\n B;` trait lists parse. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
A Lua `local` (variable or function) belongs to the file that declares it, but cross-file name matching treated it like a global. kong's spec helpers re-bind busted's globals (`local it = it`, `local assert = require "luassert"`), and every other spec file's `it(…)` / `assert(…)` / `describe(…)` linked to them — 15,776 edges; koreader's `local ipairs = ipairs` in one module took the project's `ipairs` / `pairs` / `type` / `tonumber` (2,329). isVisibleAcrossFiles now reads a Lua/Luau variable or function's declaration line and rejects a `local` one from another file (the reference stays unresolved rather than taking a runner-up). Globals stay visible. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…enry#2144) testthat runs each test file in an environment of its own, so a variable a test assigns is invisible to the package and to other tests. ggplot2's `c <- ggplot(…)` in test-facet-grid-.R was the one node named `c`, and took 2,455 of the package's `c(…)` calls (the sweep's top-depended symbol). isVisibleAcrossFiles rejects an R variable/constant under `tests/` from another file — except `helper-*.R` / `setup-*.R`, which testthat sources for every test. (A first cut that limited every R call to function nodes lost ggplot2's factory-defined `geom_point <- make_constructor(…)`, dplyr's `summarize <- summarise` and shiny's aliases.) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
A receiver-less Dart call now reaches only a method of the enclosing class, something it extends / mixes in / implements, or an extension on one of those types, and the nearest one wins. The hierarchy is read from each declaration's head (comments and type arguments dropped), since supertype edges don't exist on the first pass. Body-less abstract members (extracted as owned functions) are scoped too. Mixin-application classes (`class A = B with C;`) were extracted as `<anonymous>` with no supertypes; both the wasm extractor and the Rust kernel now name them and emit their extends/implements refs (kernel parity verified on bloc, riverpod, shelf, dio, getx). A/B (edges removed / added): riverpod -1945/+517, shelf -785, getx -855/+18, bloc -178/+95, dio -78. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…olbymchenry#2146) A Kotlin call's top-level candidate (a function, an extension function, a property) must be in the caller's package, imported by name, or in a star-imported package. Class members aren't judged: a lambda's receiver can put any type's members in scope. A function type with a qualified receiver (`(A.Builder.() -> Unit)?`) broke the tree-sitter-kotlin parse badly enough to drop the enclosing class; an offset-preserving preParse blanks the qualifier (hoisted, so the kernel parses the same bytes — parity 0 diffs on Exposed, okhttp, nowinandroid). A/B (edges removed / added): Exposed -5370/+4256 (1,318 R2DBC assertEquals misroutes; DatabaseTestsBase's members and 250 extends/imports edges back), koin -965/+960, okhttp -690/+675 (567 MockResponse to the imported mockwebserver3 class), okio -98/+44, nowinandroid -14. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…nry#2147) Ruby types nothing, so two guesses produced most of a Ruby repo's wrong call edges: - `receiver.m()` through an untyped receiver took the project's one method named `m`. It now also needs a word shared between the receiver and the method's owner (`web_push_request.legacy_encrypt` → WebPushRequest); `self` / `self.class` are exempt. - a bare `m()` inside a class took any class's `m`. It now reaches only the class's ancestry — superclasses and include/extend/prepend modules, read from source and resolved against the lexical nesting. Calls in module bodies and top-level blocks (specs, DSLs) are not judged. A/B (edges removed / added): rubocop -4406/+262, mastodon -2642/+540, jekyll -343/+10, lobsters -243/+4, sinatra -207/+2, devise -112/+3. Deliberate losses: instance_eval'd DSL blocks inside a class method (sinatra's own tests' `mock_app { get '/' }`), and helpers on a framework class the repo reopens past an external superclass (devise setup_mailer). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…olbymchenry#2148) - A bare call in a .cfc reaches only the component's own methods and those of the components it extends (extends="a.b.C" read from source, matched to indexed .cfc files by longest path suffix). Calls in .cfm templates and multi-line chain links (name not on the ref's line) are not judged. - The untyped-receiver rule from the Ruby fix now covers CFML too: the one project method named `m` needs a receiver named after its owner. The word match also accepts the receiver's whole name (`cbsecurity` → CBSecurity) and ignores trailing digits (`executor1` → Executor); Ruby is byte-identical to main. A/B (edges removed / added): coldbox -2429/+295, TestBox -255/+31, fw1 -103/+4, cbsecurity -8/+5, cfdocs 0. Deliberate losses: framework-repo calls through conventionally named, untyped receivers (ColdBox's `event.*` → RequestContext, TestBox's `variables.assert.*` → Assertion). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…bymchenry#2149) VB.NET's extractor keeps a call's last name only, so `Me.Panel.Controls.Add(x)` and `New System.Drawing.Size(1, 2)` arrived as bare `Add` / `Size` and exact / fuzzy matching took any class's member (even an enum case). The receiver is now read from the line: a member candidate needs `Me` / `MyBase` / `MyClass`, its own type or module as the last receiver segment, or a `(Of T)` type argument (`GetService(Of Notifier).Notify()`). Genuinely bare names are unchanged. A/B (edges removed / added): SCrawler -3452/+6, remoteapptool -143/+0, CompactGUI -31/+5, ViVeTool-GUI -1, TaskbarX 0. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…enry#2150) * fix(objc): a message reached by name alone must be in reach - `[self m]` / `[super m]` / `[[self class] m]` (receiver dropped by the extractor) reach only methods of the sender's hierarchy, read from `@interface Name : Super` plus a small UIKit/AppKit/MapKit superclass table for categories on system classes. When tree-sitter-objc loses an @implementation and its methods become functions, a same-file function, one in the file named after a hierarchy class, or any when the sender's class itself was lost, still counts; `[super init]` never lands on another file's function. - C call syntax (`completionBlock()`) never means a method or property. - Local receivers are typed from ObjC declarations (`FMResultSet *rs`, `(nullable FMResultSet *)rs`, block params), and objc joins the untyped- receiver languages for the unique-name guess (`weakSelf` / `strongSelf` count as self). Shared receiver words must be 3+ letters so class prefixes (`SD`, `NS`) don't match; Ruby/CFML unchanged but one wrong lobsters edge. A/B (edges removed / added): SDWebImage -321/+47, fmdb -28/+85, CocoaLumberjack -19/+10, AFNetworking -13/+1, MBProgressHUD 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(objc): a class or typed-property receiver keeps its inherited method `[AllTypesObject objectsInRealm:…]` (a class method inherited from RLMObject) and `[managed.anyDataObj containsObject:]` (a property declared `RLMSet<…> *anyDataObj`) now keep the unique-name match when the receiver's class — or one of the property's declared types — has the method's owner in its hierarchy. realm-swift goes from -2562/+588 to -504/+529 vs main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…2151) A bare C# name (a `calls` or `references` ref with no dot, where the line shows no receiver) can mean a member only of the types around it (outer classes included), their base types (read from `class X : Base, IFoo` heads, every partial declaration), or a static using: the file's `using static`, any `global using static`, or `<Using Include="…" Static="true"/>` in the .csproj / Directory.Build.props files above it. Names outside any recovered type are not judged. A/B (edges removed / added): Newtonsoft.Json -1394/+910 (enum-valued properties now reach the enum type), AutoMapper -135/+58, eShop -117/+5, serilog -20/+17, CleanArchitecture 0. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…or it (colbymchenry#2152) PHP joins the untyped-receiver languages for the unique-name method guess: `$x->m()` takes the one project method named `m` only when the receiver shares a word with its owner, or names a class (the whole name, or its last camel word: `$newRole` → Role) whose ancestry — extends + trait `use`, namespace-aware — has the method. A/B (edges removed / added): guzzle -359, BookStack -302, console -124, Slim -124, monica -53. Removals are PSR-7 / framework / exception calls bound to a test double or unrelated helper; the deliberate loss is calls through receivers named after neither (`$loaner->loansAsLoaner()`). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…colbymchenry#2153) The unique-name method guess no longer applies to a Lua/Luau call through a standard or host library table (string, table, math, io, os, coroutine, debug, utf8, package, bit, jit, ffi, vim, ngx, busted's assert/spy/stub/mock, love) unless the project defines that function on the table itself (kong's globalpatches define ngx.sleep), nor to a string method called on a value (`s:find`, `s:match`, `s:gsub` …). Other untyped receivers keep the guess: a word rule like Ruby's was tried and lost koreader's OO calls (`self.ui:reloadDocument()` → ReaderUI). A/B (edges removed / added): kong -2742, koreader -101, lazy.nvim -84, telescope.nvim -47, Fusion -9, lua-resty-core -1. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ymchenry#2154) `bp.add_url_rule('/path', 'name', view_func | positional view, methods=[…])` and a project's own wrapper that hands a list of paths and a `view_func=` over (flaskbb's `register_view(auth, routes=[…], view_func=X.as_view(…))`) now produce route nodes linked to the view. A class-based view is ANY unless `methods=` says; a function defaults to GET. A call whose path isn't a string literal (the wrapper's own `add_url_rule(route, …)`) adds nothing. flaskbb 0 → 103 routes (+104 edges); flask's own tests +27; CTFd, microblog, bluelog byte-identical. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…colbymchenry#2155) - Route files (`routes.draw`, or under config/routes/) are read as a block structure: `namespace` / `scope` add path + controller module, nested `resources … do` sit under `/:parent_id`, `member` / `collection` add `/:id/x` / `/x` actions, `root` and `resource` / `resources` options (`only:` / `except:` across lines, `path:`, `controller:`) are honored; `do` and `if` / `unless` / `case` / `begin` open frames an `end` closes. - Detection accepts `gem "rails"` (double quotes), railties, and a Rails engine's `config/routes.rb` anywhere (solidus). - A namespaced `controller#action` only reaches controllers of its own module path when any exist — an admin controller that inherits `index` is not the API's `ZonesController#index`. Route→action edges main → this branch: mastodon 221→578, solidus 0→319, rubygems.org 108→192, maybe 127→189, lobsters 141→196; no non-route edge lost except solidus's CamelCase refs now resolved by the Rails model resolver (`Order` → Spree::Order model, was a state-machine module). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ater (colbymchenry#2425) A router's navigation call (`history.push('/login')`, `navigate('/login')`, `router.push('/x')`, `goto('/x')`) names its route by path and its reference by the router's method, so sync never noticed a route that changed in another file. A synced index then kept answers a fresh index of the same files does not have (CG-33): - A call parked as failed while its route was missing never matched the colbymchenry#1240 retry, which keys on the names the synced files define. - A call bound to a catch-all, a parameter route or the other arm of a conditional kept that binding. - A route renamed in place by runPostExtract kept the calls bound to it. - Template links from a routes file that matches no synthesis trigger were never redrawn. When a navigation router is detected, sync now reads the route nodes at its first file change and again after runPostExtract. For each route on one side only, it puts back the calls the routers' new `navigation` hook (method tails and app scope) says that route can answer: the failed ones, and the `navigates` edges a resolver made. The orchestrator's orphan sweep resolves them, under the same 500-per-name ceiling, and the sync refreshes synthesis. This covers re-extracted and removed files, postExtract renames and cross-file table routes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…colbymchenry#2419) goImplementsEdges (colbymchenry#584) offered only structs as implementers. A Go defined type over a slice, map, function or basic type declares methods the same way (gin's `formSource map[string][]string` has TrySet, prometheus's `staticDiscoverer []*targetgroup.Group` has Run, an adapter `HandlerFunc func(...)` has ServeHTTP) and is extracted as a `type_alias` that owns them through go-method-contains edges. So it never satisfied an interface, and interfaceOverrideEdges, which walks only class, struct and union, could not link a call through the interface to its methods. Structs and defined types are now candidates together, in one canonical (file, line) order. A defined type declares every method it has, so under the per-interface cap it ranks with the structs that declare theirs, ahead of promoted-only ones. interfaceOverrideEdges also walks Go `type_alias` nodes. Every Go type's embeddings come from the batched prefetch (the per-type lazy lookup for defined types is gone), and a type without a method is dropped before the per-interface loop. A true alias (`type A = B`) is not extracted, so it never implements anything itself. iterateNodesByKindIn takes several kinds, interleaved in its one order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…owercase name calls that type's own member (colbymchenry#2413) A C++ call on a variable, parameter or member the calling function or its class declares as a namespace-qualified type the project does not declare, with a lowercase name (std::string, std::vector, absl::flat_hash_set, ...), no longer falls through to Strategy 3's guess by the method's name. leveldb's `std::string saved_key_; saved_key_.clear()` reached Slice::clear, protobuf's `std::string proto; proto.append(...)` LeftoverBuffer::append. The gate applies to `.` on a value and `->` through a raw pointer; `->` on a smart pointer, iterator or optional still reaches the element type. It skips declarations it cannot trust: read from outside the caller's function and class (including a class nested in the caller's), contradicted by the call (`.` on a pointer), shadowed by an unreadable re-declaration (`auto`, range-for, structured binding), unqualified, with unbalanced `<>` (the tail of a multi-line declaration), or a `_t` name (scalars, tags, traits like std::conditional_t). A `std::` name counts as the project's only when the project declares it in `std` (vendored googletest's testing::internal::string). Receiver inference now blanks comments before matching declarations, so `// ... non-null imm_` no longer types leveldb's imm_ as `null`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t names (colbymchenry#2417) tree-sitter-go parses `type Event = mvccpb.Event` as a `type_alias`, beside the `type_spec` of a defined type, and both extractors read `type_spec` only. etcd's client/v3 `Event` had no node; a use through its package (`clientv3.Event`, prometheus's `storage.AOptions{…}`) linked to nothing, and a use inside it linked by name to any type so named, another package's included. - Extraction (TS and kernel): an alias is a `type_alias` node referencing each type its right-hand side names, at the name so resolution reads the package back; an alias of a struct or interface literal is a struct or interface. The alias's own type parameters and Go's predeclared types are skipped. A generic alias, which tree-sitter-go 0.23 parses as a `type_spec` around an error, reads as an alias on wasm; the kernel defers its file. - A method called on an alias-typed value is the aliased type's: an alias of a project type is followed in its own package, through pointers and further aliases; one of an outside type resolves by name as before. - An alias's target written through a package that is none of the file's imports as indexed stays unresolved, as an embedded type's does, so the alias never links to itself or a namesake. - With Go defined types as implementers (colbymchenry#2419), an alias that owns methods written with it as the receiver implements what they satisfy, in place of the type it names. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ers no JSX child (colbymchenry#2442) The jsx-render pass reads tag names off a parent's source with a pattern, and two kinds of name it read that way linked a same-named class or component elsewhere: - A name written only in a type argument or type parameter list: outline's `<PaginatedList<Document> …>` and `useState<User>()`, or bulletproof-react's generic `<Entry extends BaseEntity>(…) =>`. A `<Name` right after an identifier opens a type argument list (the rule colbymchenry#2420 applies to the values a file declares, here for every name), and a `<Name extends …` opens a type parameter list. - A name the parent binds itself by its first tag, a `const`/`let`/`var` or a parameter (name-matcher's `jsCodeBindsName`, now exported): outline's `const Content = variant === "dropdown" ? DropdownMenu.SubContent : ContextMenu.SubContent`, `(Widget, index) => <Widget />`. Such a tag renders only a component the parent declares inside itself, else nothing. The check runs only for names the parent also writes outside a tag. Destructured names still link by name, as for a destructured call. Fresh before/after indexes on 13 repos (main ed199e6): 66 jsx-render edges removed and none added; no other edge, node, ref or file changes. Every removal checks out against the TypeScript compiler (38 names with no JSX tag in the parent, 28 tags bound to a local); 64 of the 66 targets were wrong, 2 right by luck. mantis, proshop_mern, next-saas-starter and create-t3-turbo are byte-identical, and Screens is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…edder's method of that name (colbymchenry#2430) Go has no inheritance. A struct that embeds another (`type Engine struct { RouterGroup }`) has an `extends` edge to it since colbymchenry#2397, and the interface-dispatch bridge read every `extends` edge as an override, so it linked RouterGroup.Use to Engine.Use. A call on a *RouterGroup only ever runs RouterGroup's own Use, so a flow or impact walk through it went on into Engine.Use and the code only the engine runs. The bridge now skips a Go type's supertype edge unless it points at an interface: only a call through an interface dispatches. Structs that embed an interface keep their links, and so do the go-implements edges, so a call through IRoutes still reaches both RouterGroup.Use and Engine.Use. Other languages are unchanged. Removed on gin / prometheus / etcd: 1 / 112 / 60 interface-impl edges, all from a struct's method to a struct embedding it; nothing else in the graph changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…can't read (colbymchenry#2449) tree-sitter-cpp has no preprocessor, so an attribute macro where it expects a name or a type misparses the declaration around it. The C++ preParse already blanked one export macro before a class name, an inline macro before a return type, and a lone macro line before a declaration. It missed: - several macros, or one with arguments, between `class` and the name (protobuf's generated `class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Any final : public Message`, rocksdb's `struct ALIGN_AS(64U) HandleImpl`), and a macro before a partial specialization's name; - a macro between a pointer and the declared name (`const Descriptor* PROTOBUF_NONNULL descriptor()`), after a parameter list (`unknown_fields() const ABSL_ATTRIBUTE_LIFETIME_BOUND {`, leveldb's `LOCKS_EXCLUDED(mu_) {`), after a declared name (`int count_ GUARDED_BY(mu_);`), or opening a declaration (`PROTOBUF_FUTURE_ADD_EARLY_NODISCARD absl::string_view name() const`); - a lone macro line with a comment under it ({fmt}'s `FMT_BEGIN_EXPORT` above `// A generic formatting context ...`). Every generated protobuf message class misparsed, so its members were indexed as namespace-level functions; leveldb's annotated methods became phantoms named after the annotation. The new passes match on the code alone (comments and directives as spaces, literals as placeholders), blank only the macro tokens, and keep every offset. They run in the hoisted preParse, so files that now parse clean go through the native kernel, at parity. The passes share one mask per file: a pass that blanks nothing hands the next the same string, and one that blanks hands it the mask blanked the same way. colbymchenry#2426's brace-scope fixtures misparsed only through PROTOBUF_FUTURE_ADD_EARLY_NODISCARD and ALIGN_AS(64U), which the preParse now blanks. They now use macros it doesn't know (NODISCARD, cacheline_aligned(64U)), with the same expected scopes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…xport (colbymchenry#2433) `const X = require('./x').default` and `const { default: X } = require('./x')` map to a named import of `default`. That is right for a CommonJS module that sets the property itself (`exports.default = fn`, or the dual `module.exports = X; module.exports.default = X`), but a module written as an ES module and compiled to CommonJS sets it to its default export, which is no named export. References through the binding stayed unresolved (bitwarden's `new OsBiometricsServiceMac(...)`) or fell to name matching: the local variable holding the module, or a namesake method in another package. findExportedSymbolWalk now falls back to the module's ESM default export when the named lookup finds no `default`. Only for JS-family refs, only in the module the require names (`export * from` forwards no default), and only when that module has an ESM default export at all: a single-file component, or an `export default` statement. A CommonJS module's `exports.x = function` declarations are flagged exported, so without that gate the first-exported-function guess would invent a default for it. bitwarden +2 edges (the two failed `instantiates` refs). react-native +872 -617: all 617 re-resolved at the same site (541 from the local require binding to the real function or class, 47 from a namesake method in another package to the right module, 28 metadata only, 1 from a type signature to the implementation), 870 of 872 added edges on the declared default or what it holds. express, eslint, mocha, koa, body-parser, fastify, topcoder, proshop_mern, next-saas-starter and create-t3-turbo byte-identical. Dead-code claims unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…method (colbymchenry#2444) Both extractors record `srv.(KVServer).Range(ctx, in)` as a bare `Range` call at the column where its receiver expression starts, as they record any call through an expression. Resolution matched the name alone, so every handler protoc-gen-go-grpc emits went to the `UnimplementedKVServer` stub beside the `KVServer` interface (72 edges in etcd), and calls like `c.Reader.(*pipe).Close()`, `p.(Pausable).Pause()` or `v.(featuregate.MutableFeatureGate).Set(…)` linked to a namesake or to nothing. The call's chain is now read back from its column (operand, selectors, assertions, calls and indexes, past strings, runes and comments, and on to the next line after a trailing `.`). When the link of the call's name follows an assertion, the call is a method of the asserted type, found where Go finds it: - a bare `T` or `*T` in the call's own package, or one it dot-imports; - a `pkg.T` in the imported project package; - its own method, the one its interface declares, or one promoted from a type it embeds, through the package-scoped lookup colbymchenry#2361 added; an alias is followed to the type it names (colbymchenry#2417). A type from outside the project (`http.Flusher`), a predeclared one (`error`), an alias of an outside type (`type Ctx = context.Context`, for which the package-scoped lookup would fall back to matching by name) or a type literal (`interface{ Flush() }`) links nothing. The check runs ahead of the framework, import and name strategies, and ahead of the built-in filter, which dropped a method named `close` or `copy` called through an assertion. Two calls of one name in a chain share the column (`b.(*Builder).Add(1).Add(2)`); both are taken for the one made through the assertion, whose edge is there either way. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…a test (colbymchenry#2434) Google names C++ tests `foo_unittest.cc` (protobuf, Breakpad, glog, Chromium), not `foo_test.cc`. The test-file check wanted a separator right before `test`, so each one read as production code: search and explore ranked it alongside the code it tests, `codegraph affected` never listed it, and the resolver's test rules ran backwards for it. Production calls landed on a unittest's own declarations (`stack_frame_entries_.size()` on a unittest's `StackHelper`, a template's `AddressType()` on a unittest's typedef), and a unittest's calls into test suites outside what it includes (a Python `*_unittest.py` using a `tests/` fake) were treated as production calls. colbymchenry#2421 already links a C/C++ unittest to the test helpers it includes. `unittest` and `unittests` join the separator-delimited test suffixes (`foo_unittest.cc`, `foo-unittest.cpp`, `foo.unittest.js`), and a file named so is a test suite to the resolver, as `foo_test.cc` is. A bare `unittest.go` stays production code: promtool's runs rule tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…al named like an import is that variable (colbymchenry#2448) goRefQualification read a dotted Go call's package qualifier from its line, as the line's only `X.Name` spelling. A second spelling of the name left it with none (`Digest:` beside `digest.Digest(dig)`, `"Log using Infof"`), and another selector before it was taken instead (`klog` for `err.Error` in `klog.Error(err.Error())`). It now takes the reference name's first segment, the only one that can be a package. A call through a parameter or local that takes an import's name (etcd's `jwt, err := newTokenProviderJWT(…)`, testify suites' `suite` receivers) is a call on that variable. A per-file scope reader finds the parameters, receivers, results, `:=`, `var` and `const` names in scope at the call, so such a call is no longer one into the package. The variable's declared type, when its declaration writes one, decides what the call reaches: - An outside package's type, or a value an outside package's function hands out (`clock := clocktesting.NewFakePassiveClock(…)`), has none of the project's methods. - A project package's type is resolved as the receiver's type. This also covers parameters declared through a package (`logger logger.Interface`). - A field read through the local (`metadata.Type.String()`) keeps its own type. A sync drops a file's scope reading with the other per-file memos. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ckage imports look local (colbymchenry#2437) The out-of-repo import guard (`isOutOfRepoImport`) never fired in two setups: - A catch-all `paths` key. The guard started with `isExternalImport`, which treats an import as local when it starts with a root alias's prefix, and a `"*"` key's prefix is empty. On cord-field (`"*": ["./typings/*"]`), 169 imports of `Typography` from `@mui/material` bound to the project's own `Typography`. - An alias that lands on disk but outside the index. `fileExists` falls back to `fs.existsSync`, which also answers for a directory or a file under `node_modules`. home-assistant's `"lit/decorators": ["./node_modules/lit/decorators.js"]` bound 4,916 `@property()` decorators to an unrelated `property` field, and topcoder's `config` package landed on its `config/` folder. The guard now skips the alias-prefix test (it already asks `resolveImportPath` whether an alias maps the import to a file) and counts that resolution only when it lands on an indexed file. Other callers of `isExternalImport` are unchanged: resolving an import still needs the prefix test so `"*": ["src/*"]` aliases resolve at all. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e first — graph byte-identical (colbymchenry#2431) bareCallReceiver joined the ref's line with the seven after it for every bare-recorded call, then cut the text at the ref's column. On a minified bundle that line is the whole file, so every call copied it: about 1 MB per call on go-ethereum's graphiql.min.js, 9 GB over that repo's call refs. It now searches the ref's own line from the column first. Every match of the call pattern starts with the name, so a match there with no earlier occurrence of the name on the line is where the joined lines match first too. With no match on the line (a call that continues on the next one), or with the name earlier on it (an earlier `name[…` or `name<…` can run past the line break and enclose the match), the joined lines decide as before. The result is the same for every input. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nry#2441) A Go defined type (`type WatchChan <-chan WatchResponse`, gin's `type HandlerFunc func(*Context)` and `type HandlersChain []HandlerFunc`) is a `type_alias` node, and it referenced nothing: only an `=` alias (colbymchenry#2417) named the types on its right-hand side. Impact on `WatchResponse` or gin's `Context` missed the declarations built from them, and everything that uses those. Fix (TS extractor and the Rust kernel, mirrored): goAliasTypeNames / alias_type_names walk the `type` field of every type_alias node, a defined type's as well as an alias's, so each type it names becomes a `references` ref on that name, where resolution reads the package qualifier back. Still skipped: the declaration's own type parameters, Go's predeclared types, and now its own name written bare, which in a recursive type (prometheus' `type stateFn func(*Lexer) stateFn`) is the declaration itself: no self-edge, and no failed row that would make dead code treat every namesake as referenced. A qualified name is never skipped (`type PutResponse pb.PutResponse` names pb's). Resolution is unchanged. A defined type is a new type: goAliasTarget still follows `=` aliases only, so a method called on a defined type is not looked up on its underlying type. The gateTargetKind rule that leaves a type_alias's reference written through a package the index doesn't know unresolved now covers defined types too; without it, every such name bound to the same-file declaration of its name (`type Op clientv3.Op` linked itself). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ds (colbymchenry#2436) A data router's `lazy: () => import('@/pages/invocation_page')` loads the folder's `index.ts`. When that file only forwards the page, with `export * from './invocation_page'`, `export { default } from './page'` or `export { Page as Component } from './page'`, the route linked nothing: the module was read for an export of its own and none was found. The lookup now follows the module's re-exports a few hops to the file that declares the page, the way JavaScript resolves them (`export *` never forwards the default, a name two `export *` modules both forward is exported by neither), and reads a module's own `export { Page as Component }` clause. `React.lazy` values in a route file, which go through the same lookup, follow such barrels too. On luci-go's milo/ui, 51 of 91 failed lazy route refs now link; the rest load a file under `src/build/` (not indexed), export only a `loader` or a `handle`, or pick a named export in an async loader. Sync links a page added or edited behind its barrel the way a fresh index does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t counts (colbymchenry#2447) goImplementsEdges matched method names only, so a struct whose same-named method takes or returns a different number of values, which Go can never accept, was linked as an implementation (etcd's watch cache as a peerGetter), and enough such look-alikes filled the per-interface cap before the real implementer (grpc-go's xDS TransportBuilder). Each wanted method now also needs a declaration with its parameter and result counts, read off the stored signature text; a signature that doesn't read rules nothing out. A gRPC client interface (every method takes `opts ...grpc.CallOption` last) also accepts its RPCs' server arities, so `KVClient.Range -> kvServer.Range`, the bridge explore follows from a client call to its handler, stays. Defined types (colbymchenry#2419) are held to the same counts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s own class's method (colbymchenry#2443) normalizeCppTypeName cut each `<…>` at its first `>`, so a declared type with template arguments nested in its template arguments kept debris: `autovector<std::pair<int, FileMetaData*>>` read as `autovector >` and `Striped<CacheAlignedWrapper<port::Mutex>>` as `Striped >`. No class has such a name, so the call was never resolved on the receiver's class. A capitalized debris name made isUndeclaredTypeName take the type for an outside one and silence the call (rocksdb's `mutex_.Get(key)`), and a lowercase one fell to a guess by the receiver's words (rocksdb's `files_marked_for_compaction_.clear()` reached `CompactionInputFiles::clear`). Template arguments are now stripped with their nesting by cpp-type-aliases' depth-tracking helper, exported as stripCppTemplateArguments; cpp-supertypes' identical private copy now imports it. A `>` that closes no `<` is the end of a declaration begun on an earlier line (`std::unique_ptr<BlobContents>>>& blob_reqs` under `autovector<std::pair<…,`): a depth strip alone would read the argument's type there, so such text names no type. The scan back to the receiver's declaration then marks it shadowed (colbymchenry#2413), as it does for a declaration whose type it can't read, so a member or earlier variable of the same name found further up doesn't decide the call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tion the query names (colbymchenry#2453) Explore's named walk is breadth-first, and the first callee listed claimed each node it reached. An interface method calls every implementation at the same depth, so when several of them call the next named symbol, the Flow went through whichever implementation the index listed first, even when the query named another one. On prometheus, `Engine.execEvalStmt Queryable.Querier fanout.Querier NewMergeQuerier` went through the TSDB's `DB.Querier`; on gin, once defined types count as implementers, `setter.TrySet` went through `headerSource.TrySet` when the query named `formSource.TrySet`. A node reached again from the same depth now takes the route that ends on fewer unnamed hops, then the one through more named symbols, and keeps the first otherwise. Of two equally deep named ends, the seed keeps the one whose route passes more named symbols. The expansion order, the visited set and the NAMED_VISIT_CAP bound are unchanged, so the walk makes the same callee lookups. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…aration is indexed (colbymchenry#2446) `struct Foo { … } foo;`, `class Bar { … } bar;` and `static struct { … } SPT;` outside any function or class body went to the variable extractor, which skipped the declaration's children, so the type, its methods and its enumerators were never indexed in either extraction engine. Both engines now walk such a type before the variables: in C always, and in C++ when the tree has no errors or the file is walked in brace scopes. This converges with colbymchenry#2426's walk for erroring C++ files; a C++ file whose braces don't balance is still left alone, since error recovery can run a class past its own `}` there. The declaration's function-as-value scan skips the walked type, which captured its own. An unnamed struct, union or enum takes the name of the first variable its declaration declares (also inside function bodies, where it was `<anonymous>`), as `typedef struct { … } Name;` already takes the typedef name, and the comment above the declaration is the type's docstring. cDeclaratorIdentifier moves to languages/c-cpp.ts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…of exactly that name (colbymchenry#2445) The resolver's name-existence pre-filter read no leading `::`: its `::` branch wanted the separator past the first character, and the single-`:` loop skips names holding `::`. So `::leveldb::RepairDB(…)`, `::ROCKSDB_NAMESPACE::RepairDB(…)` or protobuf's `::_pbi::…` calls were dropped before any strategy ran, unless a detected framework claimed them. protobuf's got through only because it ships three Swift files: the Swift ↔ Objective-C bridge claims any name with a `:` in it, which is why colbymchenry#2415 left claimsReference() universal. - The pre-filter checks a C or C++ name without its leading `::`. - claimsReference() is asked only of the frameworks that resolve the reference's language (frameworksFor), like resolve() since colbymchenry#2415. - matchByQualifiedName takes a global-qualified C/C++ name as exactly that qualified name. Its suffix match took a namesake nested in another namespace or class: with the pre-filter alone, 23 of the 24 edges it added on leveldb, fmt and rocksdb were wrong, mostly wrappers like fmt's mock `test::open` linked to the `::open(…)` they wrap, and protobuf's `::operator delete` went to `DynamicMessage::operator delete`. A declaration inside a namespace a macro opens (fmt's `struct pipe`) only looks global in the index, so it is skipped; step 5 still reads those. - `::std::…` and `::memset` count as `std::…` and `memset` for the built-in check, and step 5 returns early for a single-segment name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…olbymchenry#2429) `const Wrapper = styled.div<WrapperProps>` + a template literal came out as a `constant`, so the JSX-render synthesizer skipped it: `<Wrapper>` got no render edge, or bound to a same-named component in another file. tree-sitter's tagged-template call takes no type arguments, so when the type argument also reads as an expression the initializer parses as comparisons, `(styled.div < WrapperProps) > template`, not as a call. (A type argument that can't be an expression, `<{ open: boolean }>`, error-recovers into a call on the tag, which colbymchenry#841 already took.) reactComponentHoc now also takes that comparison chain: the leftmost operand is the `styled` tag against a `<`, the rightmost is the template against a `>` (`>>` when the type argument ends in its own `<...>`), and operators in between belong to the type argument (`<A & B>`). Mirrored in the kernel's TS/JS walker. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n the module appears later (colbymchenry#2450) A default, namespace or aliased import binds a name its module never declares: `import tagsController from './tag/tag.controller'`, `import { Component as GroupsPageWrapper } from './groups_page'`. Every reference through that name (the import, a call, `new`, a base class, a JSX or template tag, an Express mount) was parked under the name, which no file a sync adds or changes carries. So a module added after its importers were indexed, restored after a delete, or given its export in a later edit never relinked them, while a fresh index did. Such a reference is now parked under its project module's key (`module:tag`), which sync already looks up for every file it adds or changes (colbymchenry#2422), and it is still found by its own name: a binding its module never resolves is linked by that name alone, as vben's `{ VbenFormSchema as FormSchema }` from a workspace package is. Schema v15 adds the partial index that by-name lookup needs; its leading `status` keeps the planner off idx_unresolved_status, which read 830K rows on vscode's index. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ry#2438) tree-sitter-go puts the comment above `type Foo struct{}` before the `type_declaration`, but the node is made from the spec inside it, so both extractors found no docstring for an ungrouped struct, interface, defined type or alias. A type inside a `type ( ... )` group kept its own comment, which sits beside it in the parentheses. Go's docstring is now read from the declaration when the declaration holds one spec and nothing precedes that spec inside it. The leading comment of a group with several members stays the group's. Reading from the declaration exposed comments that trail the line above: `const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package` would have become `type MetricType int32`'s doc. For every Go declaration, a comment that begins after code on its line, and one that begins on the line such a comment ends, is now left out, as go/parser reads them. Seven function docstrings on etcd and prometheus lose one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Preserve both parents, G6, workspace, locale/theme customizations and runtime packaging. Resolve lock version and legacy v12 schema collision by feature-detected transactional repairs without claiming upstream migration numbers. No release or main update.
Retain the exhaustive visible-copy test and add a Chinese-English-Chinese DOM localization round trip that also verifies the navigation target stays unchanged.
Owner
Author
|
验证发现并修复一个非文本冲突:上游 当前 PR 文件树为 原提交的 Rust kernel 专项 134/134 通过;macOS 定向验证数据库新回归 10/10、既有迁移兼容 5/5 及工作区/G6 通过,但中文覆盖检查有 1 项失败(97 通过 / 1 失败 / 0 跳过)。这些是旧提交诊断,不作为新提交的成功凭据。新 head 的完整 engine/UI、native kernel 与 Windows/macOS 同源定向检查正在重新执行。main 保持不变,只有全部检查成功才合入。 |
Preserve the existing non-missing-path error contract when Windows reports ENOENT for a child of a regular file. Verify resolved existing parents are directories before treating descendants as offline. Keep the original regression and add two real-filesystem deep-path cases, including a file symlink.
PinableAgents
marked this pull request as ready for review
October 9, 2026 06:18
Owner
Author
|
已完成合并后核验(2026-10-09):
没有重新发布 runtime Release、改动发布凭据或保护规则。临时 maintenance 工作流不在最终 main 文件树/祖先中;本次 source 同步已完成。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
同步范围
69f4e5d206c3f85aea2ae37142d77c43dfd725d0b635dd467f0578926a9c01a37b9d28d2b26689f17639c787e48be92ea4ca83c5c014d8dd480de4700c460b2f7638ca4529bf26bd2bf73ef24d09f66af1c2b04a7b662bf37631380bffb378c327c5cd385a72489f1d536e6cf76d786beb88754a43906f36保留 fork/upstream 历史,其上正常追加两次小修复;没有 squash/rebase。a628a68ece02846f1e32c3bb4c7be7025c4dcdb8的父提交为 fork 起点与最终 PR head,文件树与最终 head 完全一致。合并前验收已全部通过。以下统计均为最终 head/相同文件树的真实结果,不使用上一轮红灯或取消运行代替。仅通过 Create a merge commit 合入,禁止 squash/rebase。
冲突处理及减少重复冲突
1. 锁文件版本冲突
package-lock.json仅将冲突的 workspace 版本合并为上游 1.6.2,保留 Pinable 的@antv/g65.1.1、layout 依赖与双方非冲突更新。2. 历史 schema 编号冲突
旧 Pinable v10/v12 与上游后续迁移编号不同义,不能整份覆盖或再次占用新的上游编号。保留全部上游数字迁移体和 v15 当前版本,独立
src/db/pinable-schema.ts根据实际表/索引检测缺失能力,在事务内复用原上游 v10/v12 迁移体,补齐 fork 游标索引。保留原schema_versions记录、图数据与索引;只读连接不修复,较新未知 schema 不修改,健康重复打开不重复写入。新增 10 项真实 SQLite 回归覆盖 legacy v12→v15、upstream v12/current v15、单个缺失索引、只读访问、失败原子回滚、幂等重复打开及未来版本保护。既有兼容测试只更新当前版本和模拟旧版本的历史范围,不降低断言。FORK.md 记录以后 fork 专属修复不再分配上游数字迁移编号,减少下一次同步的重复冲突。
3. 验证中拦截并修复的语义问题
Its callers and callees →,原中文模板覆盖测试失败。补齐词典,新增中文→英文→中文 DOM 本地化回归并断言 href 不变,保留原覆盖测试。本次共新增 13 项回归,同时进入完整套件及 Windows/macOS 定向验收。
最终验收结果
完整 CI:https://github.com/PinableAgents/codegraph/actions/runs/37891757909
桌面定向 CI:https://github.com/PinableAgents/codegraph/actions/runs/37891776905
npm ci、npm run build、npm run build:lib均通过;本地 Linux Go launcher 单元测试及 go vet 通过。未新增 skip、删除/降低断言或忽略退出码;356 个条件跳过没有计为通过,不宣称 100% 全部测试执行或覆盖率。完整日志 artifact ID
11599210773,下载 ZIP SHA2568b37634c6d9d79a423582aba967e445bd60e142f9b1c9a5831ddedf3e685864d;原生日志 artifact ID11599065031。日志已实际下载、核对摘要和最终统计,新增 schema 10 项、原迁移 5 项、工作区路径 7 项、i18n 15 项和 UI 组件 53 项均通过。桌面 CI 在隔离 maintenance 分支发起,但明确 checkout 最终 PR head
0c460b2,核对 SHA/文件树和祖先关系后才构建测试;不是使用 helper 源码冒充 PR 验收。前轮失败和取消运行保留为诊断,不作为最终成功凭据。定制与操作边界
sync-upstream.mjs正常三方合并与--finish更新.pinable/upstream.json为本次实际合并的上游 SHA;README 与该上游 blob 相同。CODEGRAPH_UI=1显式开关与 Windows 隐窗修复。合并操作仍需最后重读 PR head、main、upstream main,防止并发改动;合并后核对上游祖先与落后提交数。