github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/analysis/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 "github.com/powerman/golang-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 func importMap(imports []*types.Package) map[string]*types.Package { 25 objects := make(map[types.Object]bool) 26 packages := make(map[string]*types.Package) 27 28 var addObj func(obj types.Object) bool 29 var addType func(T types.Type) 30 31 addObj = func(obj types.Object) bool { 32 if !objects[obj] { 33 objects[obj] = true 34 addType(obj.Type()) 35 if pkg := obj.Pkg(); pkg != nil { 36 packages[pkg.Path()] = pkg 37 } 38 return true 39 } 40 return false 41 } 42 43 addType = func(T types.Type) { 44 switch T := T.(type) { 45 case *types.Basic: 46 // nop 47 case *types.Named: 48 if addObj(T.Obj()) { 49 // TODO(taking): Investigate why the Underlying type is not added here. 50 for i := 0; i < T.NumMethods(); i++ { 51 addObj(T.Method(i)) 52 } 53 if tparams := typeparams.ForNamed(T); tparams != nil { 54 for i := 0; i < tparams.Len(); i++ { 55 addType(tparams.At(i)) 56 } 57 } 58 if targs := typeparams.NamedTypeArgs(T); targs != nil { 59 for i := 0; i < targs.Len(); i++ { 60 addType(targs.At(i)) 61 } 62 } 63 } 64 case *types.Pointer: 65 addType(T.Elem()) 66 case *types.Slice: 67 addType(T.Elem()) 68 case *types.Array: 69 addType(T.Elem()) 70 case *types.Chan: 71 addType(T.Elem()) 72 case *types.Map: 73 addType(T.Key()) 74 addType(T.Elem()) 75 case *types.Signature: 76 addType(T.Params()) 77 addType(T.Results()) 78 if tparams := typeparams.ForSignature(T); tparams != nil { 79 for i := 0; i < tparams.Len(); i++ { 80 addType(tparams.At(i)) 81 } 82 } 83 case *types.Struct: 84 for i := 0; i < T.NumFields(); i++ { 85 addObj(T.Field(i)) 86 } 87 case *types.Tuple: 88 for i := 0; i < T.Len(); i++ { 89 addObj(T.At(i)) 90 } 91 case *types.Interface: 92 for i := 0; i < T.NumMethods(); i++ { 93 addObj(T.Method(i)) 94 } 95 for i := 0; i < T.NumEmbeddeds(); i++ { 96 addType(T.EmbeddedType(i)) // walk Embedded for implicits 97 } 98 case *typeparams.Union: 99 for i := 0; i < T.Len(); i++ { 100 addType(T.Term(i).Type()) 101 } 102 case *typeparams.TypeParam: 103 if addObj(T.Obj()) { 104 addType(T.Constraint()) 105 } 106 } 107 } 108 109 for _, imp := range imports { 110 packages[imp.Path()] = imp 111 112 scope := imp.Scope() 113 for _, name := range scope.Names() { 114 addObj(scope.Lookup(name)) 115 } 116 } 117 118 return packages 119 }