mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-28 14:08:56 +08:00
fix(go): a project package named like a standard-library package is not the standard library
A Go reference written through a package qualifier was dropped as a standard-library reference whenever the qualifier matched a name in the built-in list (errors, log, types, parser, encoding, template, ...). The check looked at the name alone, never at what the file imports under that name, so a project with its own package of such a name lost nearly every call into it: harbor's errors.New(...) through its lib/errors, prometheus's parser.Inspect(...) through promql/parser. What the file imports now decides before the name does. A qualifier the file imports, by its last path segment, the name goimports assumes for an unaliased import, or an alias, from a package of one of the project's own modules is a project package, and the reference goes on to normal resolution. A file that imports the standard library's package of that name, and a qualifier the file doesn't import at all, are skipped as before. Validation: the new test file has 7 cases, 4 of which fail on main; all pass here, with the native kernel and with CODEGRAPH_KERNEL=0. A/B against main: harbor 296f304 (its Go tree, 1,611 Go files) +2,889 edges, prometheus a2fda0e +454, 0 removed and 0 retargeted on both, nodes unchanged. Every added edge was checked against its source: the line spells qualifier.Name and the file imports the target's package directory under that qualifier from inside the module (3,343 of 3,343), and a sample of 10 was read by eye. gin and cobra, and the controls express and flask, are byte-identical. Index CPU on harbor, median of 3 interleaved: 40.0 s on main, 39.9 s here. Original PR #2368 by @danusha2345. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
committed by
Colby Mchenry
co-authored by
Claude Opus 5.5
parent
449eefa7da
commit
16f2d357bc
+13
-1
@@ -3307,6 +3307,16 @@ export class ReferenceResolver {
|
||||
!PYTHON_BUILT_IN_TYPES.has(ref.referenceName.slice(0, dot));
|
||||
}
|
||||
|
||||
/**
|
||||
* True when the Go file imports `qualifier` — by its last path segment or
|
||||
* an alias — from a package of one of the project's own modules.
|
||||
*/
|
||||
private isGoProjectPackage(ref: UnresolvedRef, qualifier: string): boolean {
|
||||
return this.context
|
||||
.getImportMappings(ref.filePath, ref.language)
|
||||
.some((imp) => imp.localName === qualifier && this.context.getGoPackageDir?.(imp.source, ref.filePath) != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if reference is to a built-in or external symbol
|
||||
*/
|
||||
@@ -3401,7 +3411,9 @@ export class ReferenceResolver {
|
||||
// Go standard library packages — refs like "fmt.Println", "http.ListenAndServe", etc.
|
||||
if (ref.language === 'go') {
|
||||
const dotIdx = name.indexOf('.');
|
||||
if (dotIdx > 0) {
|
||||
// What the file imports decides before the name does: a project package
|
||||
// may be called `errors`, `log` or `types` too.
|
||||
if (dotIdx > 0 && !this.isGoProjectPackage(ref, name.substring(0, dotIdx))) {
|
||||
const pkg = name.substring(0, dotIdx);
|
||||
// Not a local bound from a type assertion that is named like one:
|
||||
// grpc-go's `parser.ParseConfig(…)` after `parser, ok :=
|
||||
|
||||
Reference in New Issue
Block a user