]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.unified] go/internal/gcimporter: flatten imports
authorMatthew Dempsky <mdempsky@google.com>
Wed, 27 Jul 2022 21:24:46 +0000 (14:24 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Thu, 28 Jul 2022 07:31:58 +0000 (07:31 +0000)
The current documentation for go/types.(*Packages).Imports requires
that the import graph be flattened when read from export data. I think
this is a documentation bug (incorrectly codifying the existing
behavior, rather than documenting it as a known bug), but until that's
decided, we can at least flatten imports ourselves.

Updates #54096.

Change-Id: Idc054a2efc908b3e6651e6567d0ea0e89bb0c54d
Reviewed-on: https://go-review.googlesource.com/c/go/+/419596
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/go/internal/gcimporter/ureader.go

index 2047ad8ae9057648d7f5cefe32bf7c503cd255a6..5e133f890b1b3f5d2b9fda392fe9216f1542dd51 100644 (file)
@@ -206,11 +206,41 @@ func (r *reader) doPkg() *types.Package {
        for i := range imports {
                imports[i] = r.pkg()
        }
-       pkg.SetImports(imports)
+
+       // The documentation for (*types.Package).Imports requires
+       // flattening the import graph when reading from export data, as
+       // obviously incorrect as that is.
+       //
+       // TODO(mdempsky): Remove this if go.dev/issue/54096 is accepted.
+       pkg.SetImports(flattenImports(imports))
 
        return pkg
 }
 
+// flattenImports returns the transitive closure of all imported
+// packages rooted from pkgs.
+func flattenImports(pkgs []*types.Package) []*types.Package {
+       var res []*types.Package
+
+       seen := make(map[*types.Package]bool)
+       var add func(pkg *types.Package)
+       add = func(pkg *types.Package) {
+               if seen[pkg] {
+                       return
+               }
+               seen[pkg] = true
+               res = append(res, pkg)
+               for _, imp := range pkg.Imports() {
+                       add(imp)
+               }
+       }
+
+       for _, pkg := range pkgs {
+               add(pkg)
+       }
+       return res
+}
+
 // @@@ Types
 
 func (r *reader) typ() types.Type {