1
2
3
4
5 package inline
6
7
8
9 import (
10 "go/ast"
11 "go/constant"
12 "go/token"
13 "go/types"
14 "reflect"
15 "strings"
16
17 "golang.org/x/tools/internal/typeparams"
18 )
19
20 func is[T any](x any) bool {
21 _, ok := x.(T)
22 return ok
23 }
24
25 func btoi(b bool) int {
26 if b {
27 return 1
28 } else {
29 return 0
30 }
31 }
32
33 func offsetOf(fset *token.FileSet, pos token.Pos) int {
34 return fset.PositionFor(pos, false).Offset
35 }
36
37
38 func objectKind(obj types.Object) string {
39 return strings.TrimPrefix(strings.ToLower(reflect.TypeOf(obj).String()), "*types.")
40 }
41
42
43 func within(pos token.Pos, n ast.Node) bool {
44 return n.Pos() <= pos && pos < n.End()
45 }
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 func trivialConversion(fromValue constant.Value, from, to types.Type) bool {
72 if fromValue != nil {
73 var defaultType types.Type
74 switch fromValue.Kind() {
75 case constant.Bool:
76 defaultType = types.Typ[types.Bool]
77 case constant.String:
78 defaultType = types.Typ[types.String]
79 case constant.Int:
80 defaultType = types.Typ[types.Int]
81 case constant.Float:
82 defaultType = types.Typ[types.Float64]
83 case constant.Complex:
84 defaultType = types.Typ[types.Complex128]
85 default:
86 return false
87 }
88 return types.Identical(defaultType, to)
89 }
90 return types.Identical(from, to)
91 }
92
93 func checkInfoFields(info *types.Info) {
94 assert(info.Defs != nil, "types.Info.Defs is nil")
95 assert(info.Implicits != nil, "types.Info.Implicits is nil")
96 assert(info.Scopes != nil, "types.Info.Scopes is nil")
97 assert(info.Selections != nil, "types.Info.Selections is nil")
98 assert(info.Types != nil, "types.Info.Types is nil")
99 assert(info.Uses != nil, "types.Info.Uses is nil")
100 assert(info.FileVersions != nil, "types.Info.FileVersions is nil")
101 }
102
103
104 func intersects[K comparable, T1, T2 any](x map[K]T1, y map[K]T2) bool {
105 if len(x) > len(y) {
106 return intersects(y, x)
107 }
108 for k := range x {
109 if _, ok := y[k]; ok {
110 return true
111 }
112 }
113 return false
114 }
115
116
117 func convert(T, x ast.Expr) *ast.CallExpr {
118
119
120
121 if ch, ok := T.(*ast.ChanType); ok && ch.Dir == ast.RECV {
122 T = &ast.ParenExpr{X: T}
123 }
124 return &ast.CallExpr{
125 Fun: T,
126 Args: []ast.Expr{x},
127 }
128 }
129
130
131 func isPointer(t types.Type) bool {
132 return is[*types.Pointer](typeparams.CoreType(t))
133 }
134
135
136 func indirectSelection(seln *types.Selection) bool {
137
138 if seln.Kind() == types.MethodVal {
139 tArg, indirect := effectiveReceiver(seln)
140 if indirect {
141 return true
142 }
143
144 tParam := seln.Obj().Type().Underlying().(*types.Signature).Recv().Type()
145 return isPointer(tArg) && !isPointer(tParam)
146 }
147
148 return seln.Indirect()
149 }
150
151
152
153
154
155
156 func effectiveReceiver(seln *types.Selection) (types.Type, bool) {
157 assert(seln.Kind() == types.MethodVal, "not MethodVal")
158 t := seln.Recv()
159 indices := seln.Index()
160 indirect := false
161 for _, index := range indices[:len(indices)-1] {
162 if isPointer(t) {
163 indirect = true
164 t = typeparams.MustDeref(t)
165 }
166 t = typeparams.CoreType(t).(*types.Struct).Field(index).Type()
167 }
168 return t, indirect
169 }
170
View as plain text