github.com/cockroachdb/tools@v0.0.0-20230222021103-a6d27438930d/internal/facts/imports.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package facts 6 7 import ( 8 "go/types" 9 10 "golang.org/x/tools/internal/typeparams" 11 ) 12 13 // importMap computes the import map for a package by traversing the 14 // entire exported API each of its imports. 15 // 16 // This is a workaround for the fact that we cannot access the map used 17 // internally by the types.Importer returned by go/importer. The entries 18 // in this map are the packages and objects that may be relevant to the 19 // current analysis unit. 20 // 21 // Packages in the map that are only indirectly imported may be 22 // incomplete (!pkg.Complete()). 23 // 24 // TODO(adonovan): opt: compute this information more efficiently 25 // by obtaining it from the internals of the gcexportdata decoder. 26 func importMap(imports []*types.Package) map[string]*types.Package { 27 objects := make(map[types.Object]bool) 28 typs := make(map[types.Type]bool) // Named and TypeParam 29 packages := make(map[string]*types.Package) 30 31 var addObj func(obj types.Object) 32 var addType func(T types.Type) 33 34 addObj = func(obj types.Object) { 35 if !objects[obj] { 36 objects[obj] = true 37 addType(obj.Type()) 38 if pkg := obj.Pkg(); pkg != nil { 39 packages[pkg.Path()] = pkg 40 } 41 } 42 } 43 44 addType = func(T types.Type) { 45 switch T := T.(type) { 46 case *types.Basic: 47 // nop 48 case *types.Named: 49 // Remove infinite expansions of *types.Named by always looking at the origin. 50 // Some named types with type parameters [that will not type check] have 51 // infinite expansions: 52 // type N[T any] struct { F *N[N[T]] } 53 // importMap() is called on such types when Analyzer.RunDespiteErrors is true. 54 T = typeparams.NamedTypeOrigin(T).(*types.Named) 55 if !typs[T] { 56 typs[T] = true 57 addObj(T.Obj()) 58 addType(T.Underlying()) 59 for i := 0; i < T.NumMethods(); i++ { 60 addObj(T.Method(i)) 61 } 62 if tparams := typeparams.ForNamed(T); tparams != nil { 63 for i := 0; i < tparams.Len(); i++ { 64 addType(tparams.At(i)) 65 } 66 } 67 if targs := typeparams.NamedTypeArgs(T); targs != nil { 68 for i := 0; i < targs.Len(); i++ { 69 addType(targs.At(i)) 70 } 71 } 72 } 73 case *types.Pointer: 74 addType(T.Elem()) 75 case *types.Slice: 76 addType(T.Elem()) 77 case *types.Array: 78 addType(T.Elem()) 79 case *types.Chan: 80 addType(T.Elem()) 81 case *types.Map: 82 addType(T.Key()) 83 addType(T.Elem()) 84 case *types.Signature: 85 addType(T.Params()) 86 addType(T.Results()) 87 if tparams := typeparams.ForSignature(T); tparams != nil { 88 for i := 0; i < tparams.Len(); i++ { 89 addType(tparams.At(i)) 90 } 91 } 92 case *types.Struct: 93 for i := 0; i < T.NumFields(); i++ { 94 addObj(T.Field(i)) 95 } 96 case *types.Tuple: 97 for i := 0; i < T.Len(); i++ { 98 addObj(T.At(i)) 99 } 100 case *types.Interface: 101 for i := 0; i < T.NumMethods(); i++ { 102 addObj(T.Method(i)) 103 } 104 for i := 0; i < T.NumEmbeddeds(); i++ { 105 addType(T.EmbeddedType(i)) // walk Embedded for implicits 106 } 107 case *typeparams.Union: 108 for i := 0; i < T.Len(); i++ { 109 addType(T.Term(i).Type()) 110 } 111 case *typeparams.TypeParam: 112 if !typs[T] { 113 typs[T] = true 114 addObj(T.Obj()) 115 addType(T.Constraint()) 116 } 117 } 118 } 119 120 for _, imp := range imports { 121 packages[imp.Path()] = imp 122 123 scope := imp.Scope() 124 for _, name := range scope.Names() { 125 addObj(scope.Lookup(name)) 126 } 127 } 128 129 return packages 130 }