mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-18 22:02:49 +08:00
fix(swift): a call through a type path lands on the type it names (#2118)
`API.PackageController.GetRoute.query(on:)` kept only `query` — the
receiver was a navigation_expression, not an identifier — and the bare
name exact-matched whichever type's `query` came first. On
SwiftPackageIndex-Server every route type has one, so health checks and
package-controller tests "called" the dependency controller (or a test's
own `query`).
Extraction (TS and the kernel's swift walker, byte-parity): a receiver that
is a path of capitalized type names, two segments or more, not led by
`Self.`, is kept: `API.PackageController.GetRoute.query`. Instance chains
(`self.store.load()`) and mixed paths (`URLSession.shared.data`) are
unchanged.
Resolution (swift-type-visibility.ts, called decisively from
matchReferenceInner so nothing falls through to name guessing): the member
on the type the path names — a method, an enum case with associated values,
or a nested type's initializer. A member's owner path is its qualified name
with the outermost extension's written path read back from its line
(`extension API.PackageController { enum ShowRoute … }` →
`API::PackageController::ShowRoute`), so twin `Feature::State`s declared in
`extension BasicsView.Feature` and `extension ObservableBasicsView.Feature`
are told apart. A path shortened inside its namespace or behind a module
qualifier fits; two owners, or none, leave the call unresolved. TCA's
`@Reducer enum Path { case detail }` generates `Path.State`/`Path.Action`,
so `Path.State.detail(…)` lands on the written case.
A/B vs main (edge diffs, every change classified): SPI 76 retargeted, all to
the type the line names, 7 dropped (Fluent `App.Version.query`, `Plot.Node.*`
— SDK members main pinned on project methods); TCA 61 retargeted, 1 dropped
(`State.StateReducer.scope` → an unrelated `Store::scope`); mastodon-ios 177
retargeted (`Mastodon.API.V2.Instance.instance`, `L10n.Plural.Count.vote`),
11 SDK drops; swift-nio 6 calls into a deprecated alias became instantiates
of `ChannelOptions.Types.*`; IceCubes 1/1, Alamofire 2 SDK drops.
Kernel/wasm parity 0 diffs over 2,752 files on six repos.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -110,6 +110,24 @@ fn strip_js_ws(s: &str) -> String {
|
||||
s.chars().filter(|c| !is_js_space(*c)).collect()
|
||||
}
|
||||
|
||||
/// SWIFT_TYPE_PATH_RECEIVER (tree-sitter.ts): `API.PackageController.GetRoute` —
|
||||
/// two segments or more, each an ASCII capital then `[A-Za-z0-9_]*` (JS `\w`),
|
||||
/// not led by `Self.`.
|
||||
fn is_type_path(s: &str) -> bool {
|
||||
if s.starts_with("Self.") {
|
||||
return false;
|
||||
}
|
||||
let mut segments = 0;
|
||||
for seg in s.split('.') {
|
||||
let b = seg.as_bytes();
|
||||
if b.is_empty() || !b[0].is_ascii_uppercase() || !b[1..].iter().all(|c| c.is_ascii_alphanumeric() || *c == b'_') {
|
||||
return false;
|
||||
}
|
||||
segments += 1;
|
||||
}
|
||||
segments >= 2
|
||||
}
|
||||
|
||||
struct Scope {
|
||||
row: u32,
|
||||
kind: &'static str,
|
||||
@@ -1061,8 +1079,16 @@ impl<'t> Walker<'t> {
|
||||
} else {
|
||||
method_name.to_string()
|
||||
};
|
||||
} else if let Some(path) = receiver
|
||||
.filter(|r| r.kind() == "navigation_expression")
|
||||
.map(|r| strip_js_ws(self.text(r)))
|
||||
.filter(|p| is_type_path(p))
|
||||
{
|
||||
// A type path, `API.PackageController.GetRoute.query(on:)`:
|
||||
// keep it for the resolver (tree-sitter.ts SWIFT_TYPE_PATH_RECEIVER).
|
||||
callee_name = format!("{path}.{method_name}");
|
||||
} else {
|
||||
// self_expression / super_expression / inner nav /
|
||||
// self_expression / super_expression / instance nav /
|
||||
// postfix / multi_line_string_literal → bare method name.
|
||||
callee_name = method_name.to_string();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user