mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-25 20:12:11 +08:00
fix(go): an interface or struct embedding a standard-library type counts its methods (#2759)
goImplementsEdges (#584) follows declared embeddings since #2402, but an embedding of a type outside the index resolves to nothing, so it added no methods: prometheus's TBRun (testing.TB plus Run) went to a struct with only a Run, QueryLogger (slog.Handler plus io.Closer) had no implementations, kapacitor's Diagnostic (a third-party Logger plus Log) took every struct with a Log, and the predeclared `error` was not recorded at all. - go-stdlib-methods.ts lists the methods of 130 standard-library types, each as `name:params/results`, generated from go1.27.3's source and counted the way goSignatureArity counts a stored signature. - Both extractors record an embedded `error`, which stays unresolved. The predeclared-type set is unchanged, so alias and defined-type references still skip it. - goImplementsEdges reads each Go type's failed `extends` rows and reads the package back off the line (goRefQualification, now exported). A standard-library type's methods join the method set, keyed as goMethodKey keys the project's (`std:<import path>` for an unexported one), and the arity gate holds them to the table's counts on both sides: a `sync.Mutex` makes a struct hugo's `Locker`, not etcd's gRPC `LockClient`. Any other outside type is met by a type embedding the same one, or by the only type with every other method the interface names. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
1f3a274c53
commit
847f1df77d
@@ -936,7 +936,7 @@ impl<'t> Walker<'t> {
|
||||
/// embedding names — `T`, `*T` (the `*` is a sibling token), `pkg.T` and
|
||||
/// `T[X]` all embed `T`. A qualified type yields its name; resolution reads
|
||||
/// the package back from the source at that position. None for any other
|
||||
/// type and for a predeclared one.
|
||||
/// type and for a predeclared one but `error`, an interface with a method.
|
||||
fn embedded_type_name(&self, ty: Option<Node<'t>>) -> Option<Node<'t>> {
|
||||
let mut ty = ty?;
|
||||
if ty.kind() == "generic_type" {
|
||||
@@ -944,7 +944,10 @@ impl<'t> Walker<'t> {
|
||||
}
|
||||
match ty.kind() {
|
||||
"qualified_type" => ty.child_by_field_name("name"),
|
||||
"type_identifier" if !is_go_predeclared_type(self.text(ty)) => Some(ty),
|
||||
"type_identifier" => {
|
||||
let name = self.text(ty);
|
||||
(name == "error" || !is_go_predeclared_type(name)).then_some(ty)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user