-
Notifications
You must be signed in to change notification settings - Fork 18k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
x/tools/go/gcexportdata: can't import package from pkg/mod #52269
Comments
got expected result:
But it ran slowly (not in this example, but in a real package). |
CC @golang/tools-team |
As of https://go.dev/cl/310515, |
I need a types.Importer, but |
@xushiwei depending on your use-case, it is probably not too hard to implement an importer by memoizing the response of packages.Load. If you don't ask for source/syntax, this should load from export data. If that is still too slow it is worth profiling to understand why. I'd be interested in hearing how this goes. |
I had written an importer by packages.Load. There is a lot of trouble here. For example, suppose package E depends A and B, and package F depends A and C. When I loaded E, it created an A package instance (called it A1) and B. And when I loaded F, it also create an A package instance (called it A2) and C. The big trouble is: E depends A1, F depends A2, but types.Identical(A1.Foo, A2.Foo) is NOT true. A normal importer doesn't have this problem. When I load E, it created an A package instance (called it A1) and B. And when I loaded F, it reused A1 and only create a C package instance. |
Right, sorry I didn't really think through my suggestion. Next suggestion: use go/packages only to get the correct exportfile (using |
FWIW, after https://go.dev/cl/310515 it looks gcexportdata.Import should actually work correctly (despite being deprecated), so you could also test at that CL. As the commit message indicates using go/packages is preferable, but if you are only loading one package at a time they are probably equivalent. |
@findleyr Thx. I will try your suggestion. |
@findleyr I try pkgs, err := packages.Load(&packages.Config{Dir: dir, Mode: packages.NeedExportsFile}, "fmt") and it returns But I use go list -export directly: type listExport struct {
Export string `json:"Export"`
}
func findExport(dir, pkgPath string) (expfile string) {
var ret listExport
if data, err := golistExport(dir, pkgPath); err == nil {
json.Unmarshal(data, &ret)
}
return ret.Export
}
func golistExport(dir, pkgPath string) (ret []byte, err error) {
var stdout, stderr bytes.Buffer
cmd := exec.Command("go", "list", "-json", "-export", pkgPath)
cmd.Stdout = &stdout
cmd.Stderr = &stderr
cmd.Dir = dir
err = cmd.Run()
if err == nil {
ret = stdout.Bytes()
}
return
} It works well. |
go/types/resolver.go collectObjects() line:259 fileDir := dir(check.fset.Position(file.Name.Pos()).Filename)
check.importPackage(d.spec.Path, path, fileDir) Has the same problem as you.Maybe not fixed yet. check.Files(files) //types.check to check source code. It will cause the same error |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
https://go.dev/play/p/1Us1Xqxqori
What did you expect to see?
What did you see instead?
Local output:
Output of go.dev/play:
The text was updated successfully, but these errors were encountered: