@@ -50,7 +50,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
50
50
return ! strings .Contains (path , "." )
51
51
}
52
52
53
- handleDeprecation := func (depr * deprecated.IsDeprecated , node ast.Node , deprecatedObjName string , pkgPath string , tfn types.Object ) {
53
+ handleDeprecation := func (depr * deprecated.IsDeprecated , node ast.Node , deprecatedObjName string , pkgPath string , tfn types.Object , nodeRender func () string ) {
54
54
std , ok := knowledge .StdlibDeprecations [deprecatedObjName ]
55
55
if ! ok && isStdlibPath (pkgPath ) {
56
56
// Deprecated object in the standard library, but we don't know the details of the deprecation.
@@ -105,32 +105,20 @@ func run(pass *analysis.Pass) (interface{}, error) {
105
105
report .Render (pass , node ), std .DeprecatedSince , std .AlternativeAvailableSince , depr .Msg ))
106
106
}
107
107
} else {
108
- report .Report (pass , node , fmt .Sprintf ("%s is deprecated: %s" , report . Render ( pass , node ), depr .Msg ))
108
+ report .Report (pass , node , fmt .Sprintf ("%s is deprecated: %s" , nodeRender ( ), depr .Msg ))
109
109
}
110
110
}
111
111
112
112
var tfn types.Object
113
113
stack := 0
114
- fn := func (node ast.Node , push bool ) bool {
115
- if ! push {
116
- stack --
117
- return false
118
- }
119
- stack ++
120
- if stack == 1 {
121
- tfn = nil
122
- }
123
- if fn , ok := node .(* ast.FuncDecl ); ok {
124
- tfn = pass .TypesInfo .ObjectOf (fn .Name )
125
- }
126
114
127
- // FIXME(dh): this misses dot-imported objects
128
- sel , ok := node .( * ast.SelectorExpr )
129
- if ! ok {
130
- return true
131
- }
132
-
133
- obj := pass . TypesInfo . ObjectOf ( sel . Sel )
115
+ checkIdentObj := func (
116
+ node ast.Node ,
117
+ id * ast. Ident ,
118
+ obj types. Object ,
119
+ nameFunc func () string ,
120
+ nodeRender func () string ,
121
+ ) bool {
134
122
if obj_ , ok := obj .(* types.Func ); ok {
135
123
obj = obj_ .Origin ()
136
124
}
@@ -161,7 +149,60 @@ func run(pass *analysis.Pass) (interface{}, error) {
161
149
}
162
150
163
151
if depr , ok := deprs .Objects [obj ]; ok {
164
- handleDeprecation (depr , sel , code .SelectorName (pass , sel ), obj .Pkg ().Path (), tfn )
152
+ handleDeprecation (depr , node , nameFunc (), obj .Pkg ().Path (), tfn , nodeRender )
153
+ }
154
+ return true
155
+ }
156
+
157
+ fn := func (node ast.Node , push bool ) bool {
158
+ if ! push {
159
+ stack --
160
+ return false
161
+ }
162
+ stack ++
163
+ if stack == 1 {
164
+ tfn = nil
165
+ }
166
+ if fn , ok := node .(* ast.FuncDecl ); ok {
167
+ tfn = pass .TypesInfo .ObjectOf (fn .Name )
168
+ }
169
+
170
+ switch v := node .(type ) {
171
+ // FIXME(dh): this misses dot-imported objects
172
+ case * ast.SelectorExpr :
173
+ sel := v
174
+ obj := pass .TypesInfo .ObjectOf (sel .Sel )
175
+ return checkIdentObj (sel , sel .Sel , obj , func () string {
176
+ return code .SelectorName (pass , sel )
177
+ }, func () string {
178
+ return report .Render (pass , sel )
179
+ })
180
+
181
+ case * ast.CompositeLit :
182
+ for _ , elt := range v .Elts {
183
+ kv , ok := elt .(* ast.KeyValueExpr )
184
+ if ! ok {
185
+ return true
186
+ }
187
+ key , ok := kv .Key .(* ast.Ident )
188
+ // ast.KeyValueExpr also represents key value pairs in maps, where the `Key` can be a *ast.BasicLit
189
+ if ! ok {
190
+ return true
191
+ }
192
+ obj := pass .TypesInfo .ObjectOf (key )
193
+ checkIdentObj (key , key , obj , func () string {
194
+ return key .Name
195
+ }, func () string {
196
+ if se , ok := v .Type .(* ast.SelectorExpr ); ok {
197
+ if xI , ok := se .X .(* ast.Ident ); ok {
198
+ return fmt .Sprintf ("%s.%s.%s" , xI .Name , se .Sel .Name , key .Name )
199
+ } else {
200
+ return fmt .Sprintf ("%s.%s" , se .Sel .Name , key .Name )
201
+ }
202
+ }
203
+ return key .Name
204
+ })
205
+ }
165
206
}
166
207
return true
167
208
}
@@ -198,7 +239,9 @@ func run(pass *analysis.Pass) (interface{}, error) {
198
239
return
199
240
}
200
241
201
- handleDeprecation (depr , spec .Path , path , path , nil )
242
+ handleDeprecation (depr , spec .Path , path , path , nil , func () string {
243
+ return report .Render (pass , node )
244
+ })
202
245
}
203
246
}
204
247
pass .ResultOf [inspect .Analyzer ].(* inspector.Inspector ).Nodes (nil , fn )
0 commit comments