Files
codegraph/__tests__
Colby MchenryandClaude Opus 5.5 f7820b584f fix(dart): calls to a private name in another part of the same library link again (#2832)
Dart keeps a `_name` to its library: the library file and every file its
`part` directives name. isVisibleAcrossFiles still listed Dart in
PRIVATE_IS_FILE_LOCAL (added with PR #1745 for Kotlin, Java, C#, Swift,
Scala and PHP), and both Dart extractors mark a `_` function, method or
class `private`. So once the name-matching pipeline had picked a private
candidate in another file, the pick was declined and the reference stayed
unresolved. A library split into parts, generated `.g.dart` and
`.freezed.dart` parts included, lost the calls and type uses between its
files.

Fix:
- dartPrivateVisible (dart-libraries.ts) says whether a file belongs to the
  reference's library, read from `part` / `part of` alone. Unlike
  inSameDartLibrary it needs no pubspec.yaml, since a part names its library
  by a path or a library name. When the reference's library can't be found,
  the name stays file-local, as before.
- isVisibleAcrossFiles takes Dart out of PRIVATE_IS_FILE_LOCAL and lets a
  private Dart candidate through when it is in the reference's library.
- matchByExactName drops another library's private Dart candidates before
  the ranking, as it does for C#, PHP, Java and Go names the file can't see.
  Otherwise another library's namesake can rank first, be declined, and take
  the library's own declaration down with it. Without a pubspec nothing else
  filters a top-level `_name`, and a member's class hierarchy is matched by
  type name, which can reach another library's class of the same name (the
  SDK's wasm and VM `_ImmutableLinkedHashMapMixin`).

Validation:
- New __tests__/dart-part-privacy.test.ts, run with and without a pubspec:
  the issue's library plus a receiver call, a generated part's
  `_$UserFromJson` and `_$Counter`, another library that imports the one
  declaring the names, a namesake beside a part, a part named by library
  name, and a part whose library is missing. 6 of 12 fail on main's
  resolver, 12 pass. With the pre-ranking filter disabled, 1 fails (the
  namesake without a pubspec).
- A/B vs main 58eb57a3, each arm with its own dist and kernel; the kernel
  and wasm paths give the same changed-site sets. Re-run after the rebases,
  on 5b47bc49 (kernel) and 8fdc8a1e (wasm), with the same changed sites.
  Edges added: getx (217 Dart files) 0, bloc (616) +49, riverpod (1,300)
  +542, localsend (393) +1, protobuf.dart (225) +143, apidash (954) +342,
  dart-lang/sdk sdk/lib (480, no pubspec) +207. Nothing removed or
  retargeted, and 1,064 edges changed only their confidence. Every newly
  resolved ref has its edge at the same site; nodes and files are
  unchanged.
- Triage of all 1,284 added edges: 1,274 right. An independent
  part/part-of oracle confirms 1,195 (a top-level `_name` unique in its
  library, a member of the call site's own hierarchy, or a member of the
  receiver's declared type); 79 were checked by hand. 10 are wrong, all
  receiver-name guesses (instance-method 0.65-0.8) that pick one
  implementation of an abstract member, or the first of a tie: the guess
  public names already get, which the file-local rule had hidden. The
  1,064 confidence changes are same-file targets that had another
  library's namesake beside them (exact-match 0.7 to 0.9).
- gin and moshi controls byte-identical, kernel and wasm. Kernel and wasm
  full-index dumps byte-identical on every Dart repo. kernel-parity --lang
  dart: 0 diffs on all seven repos.
- Index time, median of 3 interleaved runs on the kernel path, CPU with
  workers, main vs fix: riverpod 55.6 / 50.3 s, sdk/lib 59.4 / 59.6 s,
  apidash 29.5 / 30.8 s, bloc 18.6 / 18.3 s, protobuf.dart 14.7 / 14.3 s.
  Within noise.

Fixes #2466

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 07:18:05 +00:00
..