1
2
3
4
5 package facts
6
7 import (
8 "go/types"
9
10 "golang.org/x/tools/internal/typesinternal"
11 )
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 func importMap(imports []*types.Package) map[string]*types.Package {
31 objects := make(map[types.Object]bool)
32 typs := make(map[types.Type]bool)
33 packages := make(map[string]*types.Package)
34
35 var addObj func(obj types.Object)
36 var addType func(T types.Type)
37
38 addObj = func(obj types.Object) {
39 if !objects[obj] {
40 objects[obj] = true
41 addType(obj.Type())
42 if pkg := obj.Pkg(); pkg != nil {
43 packages[pkg.Path()] = pkg
44 }
45 }
46 }
47
48 addType = func(T types.Type) {
49 switch T := T.(type) {
50 case *types.Basic:
51
52 case typesinternal.NamedOrAlias:
53
54 if targs := T.TypeArgs(); targs.Len() > 0 {
55 for t := range targs.Types() {
56 addType(t)
57 }
58 }
59
60
61
62
63
64
65 T = typesinternal.Origin(T)
66 if !typs[T] {
67 typs[T] = true
68
69
70 addObj(T.Obj())
71 if tparams := T.TypeParams(); tparams.Len() > 0 {
72 for tparam := range tparams.TypeParams() {
73 addType(tparam)
74 }
75 }
76
77
78 switch T := T.(type) {
79 case *types.Alias:
80 addType(T.Rhs())
81 case *types.Named:
82 addType(T.Underlying())
83 for method := range T.Methods() {
84 addObj(method)
85 }
86 }
87 }
88 case *types.Pointer:
89 addType(T.Elem())
90 case *types.Slice:
91 addType(T.Elem())
92 case *types.Array:
93 addType(T.Elem())
94 case *types.Chan:
95 addType(T.Elem())
96 case *types.Map:
97 addType(T.Key())
98 addType(T.Elem())
99 case *types.Signature:
100 addType(T.Params())
101 addType(T.Results())
102 if tparams := T.TypeParams(); tparams != nil {
103 for tparam := range tparams.TypeParams() {
104 addType(tparam)
105 }
106 }
107 case *types.Struct:
108 for field := range T.Fields() {
109 addObj(field)
110 }
111 case *types.Tuple:
112 for v := range T.Variables() {
113 addObj(v)
114 }
115 case *types.Interface:
116 for method := range T.Methods() {
117 addObj(method)
118 }
119 for etyp := range T.EmbeddedTypes() {
120 addType(etyp)
121 }
122 case *types.Union:
123 for term := range T.Terms() {
124 addType(term.Type())
125 }
126 case *types.TypeParam:
127 if !typs[T] {
128 typs[T] = true
129 addObj(T.Obj())
130 addType(T.Constraint())
131 }
132 }
133 }
134
135 for _, imp := range imports {
136 packages[imp.Path()] = imp
137
138 scope := imp.Scope()
139 for _, name := range scope.Names() {
140 addObj(scope.Lookup(name))
141 }
142 }
143
144 return packages
145 }
146
View as plain text