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