unused.go 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965
  1. package unused
  2. import (
  3. "fmt"
  4. "go/ast"
  5. "go/token"
  6. "go/types"
  7. "io"
  8. "strings"
  9. "sync"
  10. "sync/atomic"
  11. "golang.org/x/tools/go/analysis"
  12. "honnef.co/go/tools/go/types/typeutil"
  13. "honnef.co/go/tools/internal/passes/buildssa"
  14. "honnef.co/go/tools/lint"
  15. "honnef.co/go/tools/lint/lintdsl"
  16. "honnef.co/go/tools/ssa"
  17. )
  18. // The graph we construct omits nodes along a path that do not
  19. // contribute any new information to the solution. For example, the
  20. // full graph for a function with a receiver would be Func ->
  21. // Signature -> Var -> Type. However, since signatures cannot be
  22. // unused, and receivers are always considered used, we can compact
  23. // the graph down to Func -> Type. This makes the graph smaller, but
  24. // harder to debug.
  25. // TODO(dh): conversions between structs mark fields as used, but the
  26. // conversion itself isn't part of that subgraph. even if the function
  27. // containing the conversion is unused, the fields will be marked as
  28. // used.
  29. // TODO(dh): we cannot observe function calls in assembly files.
  30. /*
  31. - packages use:
  32. - (1.1) exported named types (unless in package main)
  33. - (1.2) exported functions (unless in package main)
  34. - (1.3) exported variables (unless in package main)
  35. - (1.4) exported constants (unless in package main)
  36. - (1.5) init functions
  37. - (1.6) functions exported to cgo
  38. - (1.7) the main function iff in the main package
  39. - (1.8) symbols linked via go:linkname
  40. - named types use:
  41. - (2.1) exported methods
  42. - (2.2) the type they're based on
  43. - (2.3) all their aliases. we can't easily track uses of aliases
  44. because go/types turns them into uses of the aliased types. assume
  45. that if a type is used, so are all of its aliases.
  46. - (2.4) the pointer type. this aids with eagerly implementing
  47. interfaces. if a method that implements an interface is defined on
  48. a pointer receiver, and the pointer type is never used, but the
  49. named type is, then we still want to mark the method as used.
  50. - variables and constants use:
  51. - their types
  52. - functions use:
  53. - (4.1) all their arguments, return parameters and receivers
  54. - (4.2) anonymous functions defined beneath them
  55. - (4.3) closures and bound methods.
  56. this implements a simplified model where a function is used merely by being referenced, even if it is never called.
  57. that way we don't have to keep track of closures escaping functions.
  58. - (4.4) functions they return. we assume that someone else will call the returned function
  59. - (4.5) functions/interface methods they call
  60. - types they instantiate or convert to
  61. - (4.7) fields they access
  62. - (4.8) types of all instructions
  63. - (4.9) package-level variables they assign to iff in tests (sinks for benchmarks)
  64. - conversions use:
  65. - (5.1) when converting between two equivalent structs, the fields in
  66. either struct use each other. the fields are relevant for the
  67. conversion, but only if the fields are also accessed outside the
  68. conversion.
  69. - (5.2) when converting to or from unsafe.Pointer, mark all fields as used.
  70. - structs use:
  71. - (6.1) fields of type NoCopy sentinel
  72. - (6.2) exported fields
  73. - (6.3) embedded fields that help implement interfaces (either fully implements it, or contributes required methods) (recursively)
  74. - (6.4) embedded fields that have exported methods (recursively)
  75. - (6.5) embedded structs that have exported fields (recursively)
  76. - (7.1) field accesses use fields
  77. - (7.2) fields use their types
  78. - (8.0) How we handle interfaces:
  79. - (8.1) We do not technically care about interfaces that only consist of
  80. exported methods. Exported methods on concrete types are always
  81. marked as used.
  82. - Any concrete type implements all known interfaces. Even if it isn't
  83. assigned to any interfaces in our code, the user may receive a value
  84. of the type and expect to pass it back to us through an interface.
  85. Concrete types use their methods that implement interfaces. If the
  86. type is used, it uses those methods. Otherwise, it doesn't. This
  87. way, types aren't incorrectly marked reachable through the edge
  88. from method to type.
  89. - (8.3) All interface methods are marked as used, even if they never get
  90. called. This is to accomodate sum types (unexported interface
  91. method that must exist but never gets called.)
  92. - (8.4) All embedded interfaces are marked as used. This is an
  93. extension of 8.3, but we have to explicitly track embedded
  94. interfaces because in a chain C->B->A, B wouldn't be marked as
  95. used by 8.3 just because it contributes A's methods to C.
  96. - Inherent uses:
  97. - thunks and other generated wrappers call the real function
  98. - (9.2) variables use their types
  99. - (9.3) types use their underlying and element types
  100. - (9.4) conversions use the type they convert to
  101. - (9.5) instructions use their operands
  102. - (9.6) instructions use their operands' types
  103. - (9.7) variable _reads_ use variables, writes do not, except in tests
  104. - (9.8) runtime functions that may be called from user code via the compiler
  105. - const groups:
  106. (10.1) if one constant out of a block of constants is used, mark all
  107. of them used. a lot of the time, unused constants exist for the sake
  108. of completeness. See also
  109. https://github.com/dominikh/go-tools/issues/365
  110. - (11.1) anonymous struct types use all their fields. we cannot
  111. deduplicate struct types, as that leads to order-dependent
  112. reportings. we can't not deduplicate struct types while still
  113. tracking fields, because then each instance of the unnamed type in
  114. the data flow chain will get its own fields, causing false
  115. positives. Thus, we only accurately track fields of named struct
  116. types, and assume that unnamed struct types use all their fields.
  117. - Differences in whole program mode:
  118. - (e2) types aim to implement all exported interfaces from all packages
  119. - (e3) exported identifiers aren't automatically used. for fields and
  120. methods this poses extra issues due to reflection. We assume
  121. that all exported fields are used. We also maintain a list of
  122. known reflection-based method callers.
  123. */
  124. func assert(b bool) {
  125. if !b {
  126. panic("failed assertion")
  127. }
  128. }
  129. func typString(obj types.Object) string {
  130. switch obj := obj.(type) {
  131. case *types.Func:
  132. return "func"
  133. case *types.Var:
  134. if obj.IsField() {
  135. return "field"
  136. }
  137. return "var"
  138. case *types.Const:
  139. return "const"
  140. case *types.TypeName:
  141. return "type"
  142. default:
  143. return "identifier"
  144. }
  145. }
  146. // /usr/lib/go/src/runtime/proc.go:433:6: func badmorestackg0 is unused (U1000)
  147. // Functions defined in the Go runtime that may be called through
  148. // compiler magic or via assembly.
  149. var runtimeFuncs = map[string]bool{
  150. // The first part of the list is copied from
  151. // cmd/compile/internal/gc/builtin.go, var runtimeDecls
  152. "newobject": true,
  153. "panicindex": true,
  154. "panicslice": true,
  155. "panicdivide": true,
  156. "panicmakeslicelen": true,
  157. "throwinit": true,
  158. "panicwrap": true,
  159. "gopanic": true,
  160. "gorecover": true,
  161. "goschedguarded": true,
  162. "printbool": true,
  163. "printfloat": true,
  164. "printint": true,
  165. "printhex": true,
  166. "printuint": true,
  167. "printcomplex": true,
  168. "printstring": true,
  169. "printpointer": true,
  170. "printiface": true,
  171. "printeface": true,
  172. "printslice": true,
  173. "printnl": true,
  174. "printsp": true,
  175. "printlock": true,
  176. "printunlock": true,
  177. "concatstring2": true,
  178. "concatstring3": true,
  179. "concatstring4": true,
  180. "concatstring5": true,
  181. "concatstrings": true,
  182. "cmpstring": true,
  183. "intstring": true,
  184. "slicebytetostring": true,
  185. "slicebytetostringtmp": true,
  186. "slicerunetostring": true,
  187. "stringtoslicebyte": true,
  188. "stringtoslicerune": true,
  189. "slicecopy": true,
  190. "slicestringcopy": true,
  191. "decoderune": true,
  192. "countrunes": true,
  193. "convI2I": true,
  194. "convT16": true,
  195. "convT32": true,
  196. "convT64": true,
  197. "convTstring": true,
  198. "convTslice": true,
  199. "convT2E": true,
  200. "convT2Enoptr": true,
  201. "convT2I": true,
  202. "convT2Inoptr": true,
  203. "assertE2I": true,
  204. "assertE2I2": true,
  205. "assertI2I": true,
  206. "assertI2I2": true,
  207. "panicdottypeE": true,
  208. "panicdottypeI": true,
  209. "panicnildottype": true,
  210. "ifaceeq": true,
  211. "efaceeq": true,
  212. "fastrand": true,
  213. "makemap64": true,
  214. "makemap": true,
  215. "makemap_small": true,
  216. "mapaccess1": true,
  217. "mapaccess1_fast32": true,
  218. "mapaccess1_fast64": true,
  219. "mapaccess1_faststr": true,
  220. "mapaccess1_fat": true,
  221. "mapaccess2": true,
  222. "mapaccess2_fast32": true,
  223. "mapaccess2_fast64": true,
  224. "mapaccess2_faststr": true,
  225. "mapaccess2_fat": true,
  226. "mapassign": true,
  227. "mapassign_fast32": true,
  228. "mapassign_fast32ptr": true,
  229. "mapassign_fast64": true,
  230. "mapassign_fast64ptr": true,
  231. "mapassign_faststr": true,
  232. "mapiterinit": true,
  233. "mapdelete": true,
  234. "mapdelete_fast32": true,
  235. "mapdelete_fast64": true,
  236. "mapdelete_faststr": true,
  237. "mapiternext": true,
  238. "mapclear": true,
  239. "makechan64": true,
  240. "makechan": true,
  241. "chanrecv1": true,
  242. "chanrecv2": true,
  243. "chansend1": true,
  244. "closechan": true,
  245. "writeBarrier": true,
  246. "typedmemmove": true,
  247. "typedmemclr": true,
  248. "typedslicecopy": true,
  249. "selectnbsend": true,
  250. "selectnbrecv": true,
  251. "selectnbrecv2": true,
  252. "selectsetpc": true,
  253. "selectgo": true,
  254. "block": true,
  255. "makeslice": true,
  256. "makeslice64": true,
  257. "growslice": true,
  258. "memmove": true,
  259. "memclrNoHeapPointers": true,
  260. "memclrHasPointers": true,
  261. "memequal": true,
  262. "memequal8": true,
  263. "memequal16": true,
  264. "memequal32": true,
  265. "memequal64": true,
  266. "memequal128": true,
  267. "int64div": true,
  268. "uint64div": true,
  269. "int64mod": true,
  270. "uint64mod": true,
  271. "float64toint64": true,
  272. "float64touint64": true,
  273. "float64touint32": true,
  274. "int64tofloat64": true,
  275. "uint64tofloat64": true,
  276. "uint32tofloat64": true,
  277. "complex128div": true,
  278. "racefuncenter": true,
  279. "racefuncenterfp": true,
  280. "racefuncexit": true,
  281. "raceread": true,
  282. "racewrite": true,
  283. "racereadrange": true,
  284. "racewriterange": true,
  285. "msanread": true,
  286. "msanwrite": true,
  287. "x86HasPOPCNT": true,
  288. "x86HasSSE41": true,
  289. "arm64HasATOMICS": true,
  290. // The second part of the list is extracted from assembly code in
  291. // the standard library, with the exception of the runtime package itself
  292. "abort": true,
  293. "aeshashbody": true,
  294. "args": true,
  295. "asminit": true,
  296. "badctxt": true,
  297. "badmcall2": true,
  298. "badmcall": true,
  299. "badmorestackg0": true,
  300. "badmorestackgsignal": true,
  301. "badsignal2": true,
  302. "callbackasm1": true,
  303. "callCfunction": true,
  304. "cgocallback_gofunc": true,
  305. "cgocallbackg": true,
  306. "checkgoarm": true,
  307. "check": true,
  308. "debugCallCheck": true,
  309. "debugCallWrap": true,
  310. "emptyfunc": true,
  311. "entersyscall": true,
  312. "exit": true,
  313. "exits": true,
  314. "exitsyscall": true,
  315. "externalthreadhandler": true,
  316. "findnull": true,
  317. "goexit1": true,
  318. "gostring": true,
  319. "i386_set_ldt": true,
  320. "_initcgo": true,
  321. "init_thread_tls": true,
  322. "ldt0setup": true,
  323. "libpreinit": true,
  324. "load_g": true,
  325. "morestack": true,
  326. "mstart": true,
  327. "nacl_sysinfo": true,
  328. "nanotimeQPC": true,
  329. "nanotime": true,
  330. "newosproc0": true,
  331. "newproc": true,
  332. "newstack": true,
  333. "noted": true,
  334. "nowQPC": true,
  335. "osinit": true,
  336. "printf": true,
  337. "racecallback": true,
  338. "reflectcallmove": true,
  339. "reginit": true,
  340. "rt0_go": true,
  341. "save_g": true,
  342. "schedinit": true,
  343. "setldt": true,
  344. "settls": true,
  345. "sighandler": true,
  346. "sigprofNonGo": true,
  347. "sigtrampgo": true,
  348. "_sigtramp": true,
  349. "sigtramp": true,
  350. "stackcheck": true,
  351. "syscall_chdir": true,
  352. "syscall_chroot": true,
  353. "syscall_close": true,
  354. "syscall_dup2": true,
  355. "syscall_execve": true,
  356. "syscall_exit": true,
  357. "syscall_fcntl": true,
  358. "syscall_forkx": true,
  359. "syscall_gethostname": true,
  360. "syscall_getpid": true,
  361. "syscall_ioctl": true,
  362. "syscall_pipe": true,
  363. "syscall_rawsyscall6": true,
  364. "syscall_rawSyscall6": true,
  365. "syscall_rawsyscall": true,
  366. "syscall_RawSyscall": true,
  367. "syscall_rawsysvicall6": true,
  368. "syscall_setgid": true,
  369. "syscall_setgroups": true,
  370. "syscall_setpgid": true,
  371. "syscall_setsid": true,
  372. "syscall_setuid": true,
  373. "syscall_syscall6": true,
  374. "syscall_syscall": true,
  375. "syscall_Syscall": true,
  376. "syscall_sysvicall6": true,
  377. "syscall_wait4": true,
  378. "syscall_write": true,
  379. "traceback": true,
  380. "tstart": true,
  381. "usplitR0": true,
  382. "wbBufFlush": true,
  383. "write": true,
  384. }
  385. type pkg struct {
  386. Fset *token.FileSet
  387. Files []*ast.File
  388. Pkg *types.Package
  389. TypesInfo *types.Info
  390. TypesSizes types.Sizes
  391. SSA *ssa.Package
  392. SrcFuncs []*ssa.Function
  393. }
  394. type Checker struct {
  395. WholeProgram bool
  396. Debug io.Writer
  397. mu sync.Mutex
  398. initialPackages map[*types.Package]struct{}
  399. allPackages map[*types.Package]struct{}
  400. graph *Graph
  401. }
  402. func NewChecker(wholeProgram bool) *Checker {
  403. return &Checker{
  404. initialPackages: map[*types.Package]struct{}{},
  405. allPackages: map[*types.Package]struct{}{},
  406. WholeProgram: wholeProgram,
  407. }
  408. }
  409. func (c *Checker) Analyzer() *analysis.Analyzer {
  410. name := "U1000"
  411. if c.WholeProgram {
  412. name = "U1001"
  413. }
  414. return &analysis.Analyzer{
  415. Name: name,
  416. Doc: "Unused code",
  417. Run: c.Run,
  418. Requires: []*analysis.Analyzer{buildssa.Analyzer},
  419. }
  420. }
  421. func (c *Checker) Run(pass *analysis.Pass) (interface{}, error) {
  422. c.mu.Lock()
  423. if c.graph == nil {
  424. c.graph = NewGraph()
  425. c.graph.wholeProgram = c.WholeProgram
  426. c.graph.fset = pass.Fset
  427. }
  428. var visit func(pkg *types.Package)
  429. visit = func(pkg *types.Package) {
  430. if _, ok := c.allPackages[pkg]; ok {
  431. return
  432. }
  433. c.allPackages[pkg] = struct{}{}
  434. for _, imp := range pkg.Imports() {
  435. visit(imp)
  436. }
  437. }
  438. visit(pass.Pkg)
  439. c.initialPackages[pass.Pkg] = struct{}{}
  440. c.mu.Unlock()
  441. ssapkg := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA)
  442. pkg := &pkg{
  443. Fset: pass.Fset,
  444. Files: pass.Files,
  445. Pkg: pass.Pkg,
  446. TypesInfo: pass.TypesInfo,
  447. TypesSizes: pass.TypesSizes,
  448. SSA: ssapkg.Pkg,
  449. SrcFuncs: ssapkg.SrcFuncs,
  450. }
  451. c.processPkg(c.graph, pkg)
  452. return nil, nil
  453. }
  454. func (c *Checker) ProblemObject(fset *token.FileSet, obj types.Object) lint.Problem {
  455. name := obj.Name()
  456. if sig, ok := obj.Type().(*types.Signature); ok && sig.Recv() != nil {
  457. switch sig.Recv().Type().(type) {
  458. case *types.Named, *types.Pointer:
  459. typ := types.TypeString(sig.Recv().Type(), func(*types.Package) string { return "" })
  460. if len(typ) > 0 && typ[0] == '*' {
  461. name = fmt.Sprintf("(%s).%s", typ, obj.Name())
  462. } else if len(typ) > 0 {
  463. name = fmt.Sprintf("%s.%s", typ, obj.Name())
  464. }
  465. }
  466. }
  467. checkName := "U1000"
  468. if c.WholeProgram {
  469. checkName = "U1001"
  470. }
  471. return lint.Problem{
  472. Pos: lint.DisplayPosition(fset, obj.Pos()),
  473. Message: fmt.Sprintf("%s %s is unused", typString(obj), name),
  474. Check: checkName,
  475. }
  476. }
  477. func (c *Checker) Result() []types.Object {
  478. out := c.results()
  479. out2 := make([]types.Object, 0, len(out))
  480. for _, v := range out {
  481. if _, ok := c.initialPackages[v.Pkg()]; !ok {
  482. continue
  483. }
  484. out2 = append(out2, v)
  485. }
  486. return out2
  487. }
  488. func (c *Checker) debugf(f string, v ...interface{}) {
  489. if c.Debug != nil {
  490. fmt.Fprintf(c.Debug, f, v...)
  491. }
  492. }
  493. func (graph *Graph) quieten(node *Node) {
  494. if node.seen {
  495. return
  496. }
  497. switch obj := node.obj.(type) {
  498. case *types.Named:
  499. for i := 0; i < obj.NumMethods(); i++ {
  500. m := obj.Method(i)
  501. if node, ok := graph.nodeMaybe(m); ok {
  502. node.quiet = true
  503. }
  504. }
  505. case *types.Struct:
  506. for i := 0; i < obj.NumFields(); i++ {
  507. if node, ok := graph.nodeMaybe(obj.Field(i)); ok {
  508. node.quiet = true
  509. }
  510. }
  511. case *types.Interface:
  512. for i := 0; i < obj.NumExplicitMethods(); i++ {
  513. m := obj.ExplicitMethod(i)
  514. if node, ok := graph.nodeMaybe(m); ok {
  515. node.quiet = true
  516. }
  517. }
  518. }
  519. }
  520. func (c *Checker) results() []types.Object {
  521. if c.graph == nil {
  522. // We never analyzed any packages
  523. return nil
  524. }
  525. var out []types.Object
  526. if c.WholeProgram {
  527. var ifaces []*types.Interface
  528. var notIfaces []types.Type
  529. // implement as many interfaces as possible
  530. c.graph.seenTypes.Iterate(func(t types.Type, _ interface{}) {
  531. switch t := t.(type) {
  532. case *types.Interface:
  533. if t.NumMethods() > 0 {
  534. ifaces = append(ifaces, t)
  535. }
  536. default:
  537. if _, ok := t.Underlying().(*types.Interface); !ok {
  538. notIfaces = append(notIfaces, t)
  539. }
  540. }
  541. })
  542. for pkg := range c.allPackages {
  543. for _, iface := range interfacesFromExportData(pkg) {
  544. if iface.NumMethods() > 0 {
  545. ifaces = append(ifaces, iface)
  546. }
  547. }
  548. }
  549. ctx := &context{
  550. g: c.graph,
  551. seenTypes: &c.graph.seenTypes,
  552. }
  553. // (8.0) handle interfaces
  554. // (e2) types aim to implement all exported interfaces from all packages
  555. for _, t := range notIfaces {
  556. // OPT(dh): it is unfortunate that we do not have access
  557. // to a populated method set at this point.
  558. ms := types.NewMethodSet(t)
  559. for _, iface := range ifaces {
  560. if sels, ok := c.graph.implements(t, iface, ms); ok {
  561. for _, sel := range sels {
  562. c.graph.useMethod(ctx, t, sel, t, edgeImplements)
  563. }
  564. }
  565. }
  566. }
  567. }
  568. if c.Debug != nil {
  569. debugNode := func(node *Node) {
  570. if node.obj == nil {
  571. c.debugf("n%d [label=\"Root\"];\n", node.id)
  572. } else {
  573. c.debugf("n%d [label=%q];\n", node.id, fmt.Sprintf("(%T) %s", node.obj, node.obj))
  574. }
  575. for _, e := range node.used {
  576. for i := edgeKind(1); i < 64; i++ {
  577. if e.kind.is(1 << i) {
  578. c.debugf("n%d -> n%d [label=%q];\n", node.id, e.node.id, edgeKind(1<<i))
  579. }
  580. }
  581. }
  582. }
  583. c.debugf("digraph{\n")
  584. debugNode(c.graph.Root)
  585. c.graph.Nodes.Range(func(k, v interface{}) bool {
  586. debugNode(v.(*Node))
  587. return true
  588. })
  589. c.graph.TypeNodes.Iterate(func(key types.Type, value interface{}) {
  590. debugNode(value.(*Node))
  591. })
  592. c.debugf("}\n")
  593. }
  594. c.graph.color(c.graph.Root)
  595. // if a node is unused, don't report any of the node's
  596. // children as unused. for example, if a function is unused,
  597. // don't flag its receiver. if a named type is unused, don't
  598. // flag its methods.
  599. c.graph.Nodes.Range(func(k, v interface{}) bool {
  600. c.graph.quieten(v.(*Node))
  601. return true
  602. })
  603. c.graph.TypeNodes.Iterate(func(_ types.Type, value interface{}) {
  604. c.graph.quieten(value.(*Node))
  605. })
  606. report := func(node *Node) {
  607. if node.seen {
  608. return
  609. }
  610. if node.quiet {
  611. c.debugf("n%d [color=purple];\n", node.id)
  612. return
  613. }
  614. c.debugf("n%d [color=red];\n", node.id)
  615. switch obj := node.obj.(type) {
  616. case *types.Var:
  617. // don't report unnamed variables (interface embedding)
  618. if obj.Name() != "" || obj.IsField() {
  619. out = append(out, obj)
  620. }
  621. return
  622. case types.Object:
  623. if obj.Name() != "_" {
  624. out = append(out, obj)
  625. }
  626. return
  627. }
  628. c.debugf("n%d [color=gray];\n", node.id)
  629. }
  630. c.graph.Nodes.Range(func(k, v interface{}) bool {
  631. report(v.(*Node))
  632. return true
  633. })
  634. c.graph.TypeNodes.Iterate(func(_ types.Type, value interface{}) {
  635. report(value.(*Node))
  636. })
  637. return out
  638. }
  639. func (c *Checker) processPkg(graph *Graph, pkg *pkg) {
  640. if pkg.Pkg.Path() == "unsafe" {
  641. return
  642. }
  643. graph.entry(pkg)
  644. }
  645. func objNodeKeyFor(fset *token.FileSet, obj types.Object) objNodeKey {
  646. var kind objType
  647. switch obj.(type) {
  648. case *types.PkgName:
  649. kind = otPkgName
  650. case *types.Const:
  651. kind = otConst
  652. case *types.TypeName:
  653. kind = otTypeName
  654. case *types.Var:
  655. kind = otVar
  656. case *types.Func:
  657. kind = otFunc
  658. case *types.Label:
  659. kind = otLabel
  660. case *types.Builtin:
  661. kind = otBuiltin
  662. case *types.Nil:
  663. kind = otNil
  664. default:
  665. panic(fmt.Sprintf("unreachable: %T", obj))
  666. }
  667. position := fset.PositionFor(obj.Pos(), false)
  668. position.Column = 0
  669. position.Offset = 0
  670. return objNodeKey{
  671. position: position,
  672. kind: kind,
  673. name: obj.Name(),
  674. }
  675. }
  676. type objType uint8
  677. const (
  678. otPkgName objType = iota
  679. otConst
  680. otTypeName
  681. otVar
  682. otFunc
  683. otLabel
  684. otBuiltin
  685. otNil
  686. )
  687. // An objNodeKey describes a types.Object node in the graph.
  688. //
  689. // Due to test variants we may end up with multiple instances of the
  690. // same object, which is why we have to deduplicate based on their
  691. // source position. And because export data lacks column information,
  692. // we also have to incorporate the object's string representation in
  693. // the key.
  694. //
  695. // Previously we used the object's full string representation
  696. // (types.ObjectString), but that causes a significant amount of
  697. // allocations. Currently we're using the object's type and name, in
  698. // the hope that it is impossible for two objects to have the same
  699. // type, name and file position.
  700. type objNodeKey struct {
  701. position token.Position
  702. kind objType
  703. name string
  704. }
  705. type Graph struct {
  706. // accessed atomically
  707. nodeOffset uint64
  708. // Safe for concurrent use
  709. fset *token.FileSet
  710. Root *Node
  711. seenTypes typeutil.Map
  712. Nodes sync.Map // map[interface{}]*Node
  713. objNodes sync.Map // map[objNodeKey]*Node
  714. // read-only
  715. wholeProgram bool
  716. // need synchronisation
  717. mu sync.Mutex
  718. TypeNodes typeutil.Map
  719. }
  720. type context struct {
  721. g *Graph
  722. pkg *pkg
  723. seenFns map[string]struct{}
  724. seenTypes *typeutil.Map
  725. nodeCounter uint64
  726. // local cache for the map in Graph
  727. typeNodes typeutil.Map
  728. }
  729. func NewGraph() *Graph {
  730. g := &Graph{}
  731. g.Root = g.newNode(&context{}, nil)
  732. return g
  733. }
  734. func (g *Graph) color(root *Node) {
  735. if root.seen {
  736. return
  737. }
  738. root.seen = true
  739. for _, e := range root.used {
  740. g.color(e.node)
  741. }
  742. }
  743. type ConstGroup struct {
  744. // give the struct a size to get unique pointers
  745. _ byte
  746. }
  747. func (ConstGroup) String() string { return "const group" }
  748. type edge struct {
  749. node *Node
  750. kind edgeKind
  751. }
  752. type Node struct {
  753. obj interface{}
  754. id uint64
  755. mu sync.Mutex
  756. used []edge
  757. // set during final graph walk if node is reachable
  758. seen bool
  759. // a parent node (e.g. the struct type containing a field) is
  760. // already unused, don't report children
  761. quiet bool
  762. }
  763. func (g *Graph) nodeMaybe(obj types.Object) (*Node, bool) {
  764. if node, ok := g.Nodes.Load(obj); ok {
  765. return node.(*Node), true
  766. }
  767. return nil, false
  768. }
  769. func (g *Graph) node(ctx *context, obj interface{}) (node *Node, new bool) {
  770. if t, ok := obj.(types.Type); ok {
  771. if v := ctx.typeNodes.At(t); v != nil {
  772. return v.(*Node), false
  773. }
  774. g.mu.Lock()
  775. defer g.mu.Unlock()
  776. if v := g.TypeNodes.At(t); v != nil {
  777. return v.(*Node), false
  778. }
  779. node := g.newNode(ctx, t)
  780. g.TypeNodes.Set(t, node)
  781. ctx.typeNodes.Set(t, node)
  782. return node, true
  783. }
  784. if node, ok := g.Nodes.Load(obj); ok {
  785. return node.(*Node), false
  786. }
  787. if obj, ok := obj.(types.Object); ok {
  788. key := objNodeKeyFor(g.fset, obj)
  789. if o, ok := g.objNodes.Load(key); ok {
  790. onode := o.(*Node)
  791. return onode, false
  792. }
  793. node = g.newNode(ctx, obj)
  794. g.Nodes.Store(obj, node)
  795. g.objNodes.Store(key, node)
  796. return node, true
  797. }
  798. node = g.newNode(ctx, obj)
  799. g.Nodes.Store(obj, node)
  800. return node, true
  801. }
  802. func (g *Graph) newNode(ctx *context, obj interface{}) *Node {
  803. ctx.nodeCounter++
  804. return &Node{
  805. obj: obj,
  806. id: ctx.nodeCounter,
  807. }
  808. }
  809. func (n *Node) use(node *Node, kind edgeKind) {
  810. n.mu.Lock()
  811. defer n.mu.Unlock()
  812. assert(node != nil)
  813. n.used = append(n.used, edge{node: node, kind: kind})
  814. }
  815. // isIrrelevant reports whether an object's presence in the graph is
  816. // of any relevance. A lot of objects will never have outgoing edges,
  817. // nor meaningful incoming ones. Examples are basic types and empty
  818. // signatures, among many others.
  819. //
  820. // Dropping these objects should have no effect on correctness, but
  821. // may improve performance. It also helps with debugging, as it
  822. // greatly reduces the size of the graph.
  823. func isIrrelevant(obj interface{}) bool {
  824. if obj, ok := obj.(types.Object); ok {
  825. switch obj := obj.(type) {
  826. case *types.Var:
  827. if obj.IsField() {
  828. // We need to track package fields
  829. return false
  830. }
  831. if obj.Pkg() != nil && obj.Parent() == obj.Pkg().Scope() {
  832. // We need to track package-level variables
  833. return false
  834. }
  835. return isIrrelevant(obj.Type())
  836. default:
  837. return false
  838. }
  839. }
  840. if T, ok := obj.(types.Type); ok {
  841. switch T := T.(type) {
  842. case *types.Array:
  843. return isIrrelevant(T.Elem())
  844. case *types.Slice:
  845. return isIrrelevant(T.Elem())
  846. case *types.Basic:
  847. return true
  848. case *types.Tuple:
  849. for i := 0; i < T.Len(); i++ {
  850. if !isIrrelevant(T.At(i).Type()) {
  851. return false
  852. }
  853. }
  854. return true
  855. case *types.Signature:
  856. if T.Recv() != nil {
  857. return false
  858. }
  859. for i := 0; i < T.Params().Len(); i++ {
  860. if !isIrrelevant(T.Params().At(i)) {
  861. return false
  862. }
  863. }
  864. for i := 0; i < T.Results().Len(); i++ {
  865. if !isIrrelevant(T.Results().At(i)) {
  866. return false
  867. }
  868. }
  869. return true
  870. case *types.Interface:
  871. return T.NumMethods() == 0 && T.NumEmbeddeds() == 0
  872. case *types.Pointer:
  873. return isIrrelevant(T.Elem())
  874. case *types.Map:
  875. return isIrrelevant(T.Key()) && isIrrelevant(T.Elem())
  876. case *types.Struct:
  877. return T.NumFields() == 0
  878. case *types.Chan:
  879. return isIrrelevant(T.Elem())
  880. default:
  881. return false
  882. }
  883. }
  884. return false
  885. }
  886. func (ctx *context) see(obj interface{}) *Node {
  887. if isIrrelevant(obj) {
  888. return nil
  889. }
  890. assert(obj != nil)
  891. // add new node to graph
  892. node, _ := ctx.g.node(ctx, obj)
  893. return node
  894. }
  895. func (ctx *context) use(used, by interface{}, kind edgeKind) {
  896. if isIrrelevant(used) {
  897. return
  898. }
  899. assert(used != nil)
  900. if obj, ok := by.(types.Object); ok && obj.Pkg() != nil {
  901. if !ctx.g.wholeProgram && obj.Pkg() != ctx.pkg.Pkg {
  902. return
  903. }
  904. }
  905. usedNode, new := ctx.g.node(ctx, used)
  906. assert(!new)
  907. if by == nil {
  908. ctx.g.Root.use(usedNode, kind)
  909. } else {
  910. byNode, new := ctx.g.node(ctx, by)
  911. assert(!new)
  912. byNode.use(usedNode, kind)
  913. }
  914. }
  915. func (ctx *context) seeAndUse(used, by interface{}, kind edgeKind) *Node {
  916. node := ctx.see(used)
  917. ctx.use(used, by, kind)
  918. return node
  919. }
  920. // trackExportedIdentifier reports whether obj should be considered
  921. // used due to being exported, checking various conditions that affect
  922. // the decision.
  923. func (g *Graph) trackExportedIdentifier(ctx *context, obj types.Object) bool {
  924. if !obj.Exported() {
  925. // object isn't exported, the question is moot
  926. return false
  927. }
  928. path := g.fset.Position(obj.Pos()).Filename
  929. if g.wholeProgram {
  930. // Example functions without "Output:" comments aren't being
  931. // run and thus don't show up in the graph.
  932. if strings.HasSuffix(path, "_test.go") && strings.HasPrefix(obj.Name(), "Example") {
  933. return true
  934. }
  935. // whole program mode tracks exported identifiers accurately
  936. return false
  937. }
  938. if ctx.pkg.Pkg.Name() == "main" && !strings.HasSuffix(path, "_test.go") {
  939. // exported identifiers in package main can't be imported.
  940. // However, test functions can be called, and xtest packages
  941. // even have access to exported identifiers.
  942. return false
  943. }
  944. if strings.HasSuffix(path, "_test.go") {
  945. if strings.HasPrefix(obj.Name(), "Test") ||
  946. strings.HasPrefix(obj.Name(), "Benchmark") ||
  947. strings.HasPrefix(obj.Name(), "Example") {
  948. return true
  949. }
  950. return false
  951. }
  952. return true
  953. }
  954. func (g *Graph) entry(pkg *pkg) {
  955. no := atomic.AddUint64(&g.nodeOffset, 1)
  956. ctx := &context{
  957. g: g,
  958. pkg: pkg,
  959. nodeCounter: no * 1e9,
  960. seenFns: map[string]struct{}{},
  961. }
  962. if g.wholeProgram {
  963. ctx.seenTypes = &g.seenTypes
  964. } else {
  965. ctx.seenTypes = &typeutil.Map{}
  966. }
  967. scopes := map[*types.Scope]*ssa.Function{}
  968. for _, fn := range pkg.SrcFuncs {
  969. if fn.Object() != nil {
  970. scope := fn.Object().(*types.Func).Scope()
  971. scopes[scope] = fn
  972. }
  973. }
  974. for _, f := range pkg.Files {
  975. for _, cg := range f.Comments {
  976. for _, c := range cg.List {
  977. if strings.HasPrefix(c.Text, "//go:linkname ") {
  978. // FIXME(dh): we're looking at all comments. The
  979. // compiler only looks at comments in the
  980. // left-most column. The intention probably is to
  981. // only look at top-level comments.
  982. // (1.8) packages use symbols linked via go:linkname
  983. fields := strings.Fields(c.Text)
  984. if len(fields) == 3 {
  985. if m, ok := pkg.SSA.Members[fields[1]]; ok {
  986. var obj types.Object
  987. switch m := m.(type) {
  988. case *ssa.Global:
  989. obj = m.Object()
  990. case *ssa.Function:
  991. obj = m.Object()
  992. default:
  993. panic(fmt.Sprintf("unhandled type: %T", m))
  994. }
  995. assert(obj != nil)
  996. ctx.seeAndUse(obj, nil, edgeLinkname)
  997. }
  998. }
  999. }
  1000. }
  1001. }
  1002. }
  1003. surroundingFunc := func(obj types.Object) *ssa.Function {
  1004. scope := obj.Parent()
  1005. for scope != nil {
  1006. if fn := scopes[scope]; fn != nil {
  1007. return fn
  1008. }
  1009. scope = scope.Parent()
  1010. }
  1011. return nil
  1012. }
  1013. // SSA form won't tell us about locally scoped types that aren't
  1014. // being used. Walk the list of Defs to get all named types.
  1015. //
  1016. // SSA form also won't tell us about constants; use Defs and Uses
  1017. // to determine which constants exist and which are being used.
  1018. for _, obj := range pkg.TypesInfo.Defs {
  1019. switch obj := obj.(type) {
  1020. case *types.TypeName:
  1021. // types are being handled by walking the AST
  1022. case *types.Const:
  1023. ctx.see(obj)
  1024. fn := surroundingFunc(obj)
  1025. if fn == nil && g.trackExportedIdentifier(ctx, obj) {
  1026. // (1.4) packages use exported constants (unless in package main)
  1027. ctx.use(obj, nil, edgeExportedConstant)
  1028. }
  1029. g.typ(ctx, obj.Type(), nil)
  1030. ctx.seeAndUse(obj.Type(), obj, edgeType)
  1031. }
  1032. }
  1033. // Find constants being used inside functions, find sinks in tests
  1034. for _, fn := range pkg.SrcFuncs {
  1035. if fn.Object() != nil {
  1036. ctx.see(fn.Object())
  1037. }
  1038. node := fn.Syntax()
  1039. if node == nil {
  1040. continue
  1041. }
  1042. ast.Inspect(node, func(node ast.Node) bool {
  1043. switch node := node.(type) {
  1044. case *ast.Ident:
  1045. obj, ok := pkg.TypesInfo.Uses[node]
  1046. if !ok {
  1047. return true
  1048. }
  1049. switch obj := obj.(type) {
  1050. case *types.Const:
  1051. ctx.seeAndUse(obj, owningObject(fn), edgeUsedConstant)
  1052. }
  1053. case *ast.AssignStmt:
  1054. for _, expr := range node.Lhs {
  1055. ident, ok := expr.(*ast.Ident)
  1056. if !ok {
  1057. continue
  1058. }
  1059. obj := pkg.TypesInfo.ObjectOf(ident)
  1060. if obj == nil {
  1061. continue
  1062. }
  1063. path := g.fset.File(obj.Pos()).Name()
  1064. if strings.HasSuffix(path, "_test.go") {
  1065. if obj.Parent() != nil && obj.Parent().Parent() != nil && obj.Parent().Parent().Parent() == nil {
  1066. // object's scope is the package, whose
  1067. // parent is the file, whose parent is nil
  1068. // (4.9) functions use package-level variables they assign to iff in tests (sinks for benchmarks)
  1069. // (9.7) variable _reads_ use variables, writes do not, except in tests
  1070. ctx.seeAndUse(obj, owningObject(fn), edgeTestSink)
  1071. }
  1072. }
  1073. }
  1074. }
  1075. return true
  1076. })
  1077. }
  1078. // Find constants being used in non-function contexts
  1079. for _, obj := range pkg.TypesInfo.Uses {
  1080. _, ok := obj.(*types.Const)
  1081. if !ok {
  1082. continue
  1083. }
  1084. ctx.seeAndUse(obj, nil, edgeUsedConstant)
  1085. }
  1086. var fns []*types.Func
  1087. var fn *types.Func
  1088. var stack []ast.Node
  1089. for _, f := range pkg.Files {
  1090. ast.Inspect(f, func(n ast.Node) bool {
  1091. if n == nil {
  1092. pop := stack[len(stack)-1]
  1093. stack = stack[:len(stack)-1]
  1094. if _, ok := pop.(*ast.FuncDecl); ok {
  1095. fns = fns[:len(fns)-1]
  1096. if len(fns) == 0 {
  1097. fn = nil
  1098. } else {
  1099. fn = fns[len(fns)-1]
  1100. }
  1101. }
  1102. return true
  1103. }
  1104. stack = append(stack, n)
  1105. switch n := n.(type) {
  1106. case *ast.FuncDecl:
  1107. fn = pkg.TypesInfo.ObjectOf(n.Name).(*types.Func)
  1108. fns = append(fns, fn)
  1109. ctx.see(fn)
  1110. case *ast.GenDecl:
  1111. switch n.Tok {
  1112. case token.CONST:
  1113. groups := lintdsl.GroupSpecs(pkg.Fset, n.Specs)
  1114. for _, specs := range groups {
  1115. if len(specs) > 1 {
  1116. cg := &ConstGroup{}
  1117. ctx.see(cg)
  1118. for _, spec := range specs {
  1119. for _, name := range spec.(*ast.ValueSpec).Names {
  1120. obj := pkg.TypesInfo.ObjectOf(name)
  1121. // (10.1) const groups
  1122. ctx.seeAndUse(obj, cg, edgeConstGroup)
  1123. ctx.use(cg, obj, edgeConstGroup)
  1124. }
  1125. }
  1126. }
  1127. }
  1128. case token.VAR:
  1129. for _, spec := range n.Specs {
  1130. v := spec.(*ast.ValueSpec)
  1131. for _, name := range v.Names {
  1132. T := pkg.TypesInfo.TypeOf(name)
  1133. if fn != nil {
  1134. ctx.seeAndUse(T, fn, edgeVarDecl)
  1135. } else {
  1136. // TODO(dh): we likely want to make
  1137. // the type used by the variable, not
  1138. // the package containing the
  1139. // variable. But then we have to take
  1140. // special care of blank identifiers.
  1141. ctx.seeAndUse(T, nil, edgeVarDecl)
  1142. }
  1143. g.typ(ctx, T, nil)
  1144. }
  1145. }
  1146. case token.TYPE:
  1147. for _, spec := range n.Specs {
  1148. // go/types doesn't provide a way to go from a
  1149. // types.Named to the named type it was based on
  1150. // (the t1 in type t2 t1). Therefore we walk the
  1151. // AST and process GenDecls.
  1152. //
  1153. // (2.2) named types use the type they're based on
  1154. v := spec.(*ast.TypeSpec)
  1155. T := pkg.TypesInfo.TypeOf(v.Type)
  1156. obj := pkg.TypesInfo.ObjectOf(v.Name)
  1157. ctx.see(obj)
  1158. ctx.see(T)
  1159. ctx.use(T, obj, edgeType)
  1160. g.typ(ctx, obj.Type(), nil)
  1161. g.typ(ctx, T, nil)
  1162. if v.Assign != 0 {
  1163. aliasFor := obj.(*types.TypeName).Type()
  1164. // (2.3) named types use all their aliases. we can't easily track uses of aliases
  1165. if isIrrelevant(aliasFor) {
  1166. // We do not track the type this is an
  1167. // alias for (for example builtins), so
  1168. // just mark the alias used.
  1169. //
  1170. // FIXME(dh): what about aliases declared inside functions?
  1171. ctx.use(obj, nil, edgeAlias)
  1172. } else {
  1173. ctx.see(aliasFor)
  1174. ctx.seeAndUse(obj, aliasFor, edgeAlias)
  1175. }
  1176. }
  1177. }
  1178. }
  1179. }
  1180. return true
  1181. })
  1182. }
  1183. for _, m := range pkg.SSA.Members {
  1184. switch m := m.(type) {
  1185. case *ssa.NamedConst:
  1186. // nothing to do, we collect all constants from Defs
  1187. case *ssa.Global:
  1188. if m.Object() != nil {
  1189. ctx.see(m.Object())
  1190. if g.trackExportedIdentifier(ctx, m.Object()) {
  1191. // (1.3) packages use exported variables (unless in package main)
  1192. ctx.use(m.Object(), nil, edgeExportedVariable)
  1193. }
  1194. }
  1195. case *ssa.Function:
  1196. mObj := owningObject(m)
  1197. if mObj != nil {
  1198. ctx.see(mObj)
  1199. }
  1200. //lint:ignore SA9003 handled implicitly
  1201. if m.Name() == "init" {
  1202. // (1.5) packages use init functions
  1203. //
  1204. // This is handled implicitly. The generated init
  1205. // function has no object, thus everything in it will
  1206. // be owned by the package.
  1207. }
  1208. // This branch catches top-level functions, not methods.
  1209. if m.Object() != nil && g.trackExportedIdentifier(ctx, m.Object()) {
  1210. // (1.2) packages use exported functions (unless in package main)
  1211. ctx.use(mObj, nil, edgeExportedFunction)
  1212. }
  1213. if m.Name() == "main" && pkg.Pkg.Name() == "main" {
  1214. // (1.7) packages use the main function iff in the main package
  1215. ctx.use(mObj, nil, edgeMainFunction)
  1216. }
  1217. if pkg.Pkg.Path() == "runtime" && runtimeFuncs[m.Name()] {
  1218. // (9.8) runtime functions that may be called from user code via the compiler
  1219. ctx.use(mObj, nil, edgeRuntimeFunction)
  1220. }
  1221. if m.Syntax() != nil {
  1222. doc := m.Syntax().(*ast.FuncDecl).Doc
  1223. if doc != nil {
  1224. for _, cmt := range doc.List {
  1225. if strings.HasPrefix(cmt.Text, "//go:cgo_export_") {
  1226. // (1.6) packages use functions exported to cgo
  1227. ctx.use(mObj, nil, edgeCgoExported)
  1228. }
  1229. }
  1230. }
  1231. }
  1232. g.function(ctx, m)
  1233. case *ssa.Type:
  1234. if m.Object() != nil {
  1235. ctx.see(m.Object())
  1236. if g.trackExportedIdentifier(ctx, m.Object()) {
  1237. // (1.1) packages use exported named types (unless in package main)
  1238. ctx.use(m.Object(), nil, edgeExportedType)
  1239. }
  1240. }
  1241. g.typ(ctx, m.Type(), nil)
  1242. default:
  1243. panic(fmt.Sprintf("unreachable: %T", m))
  1244. }
  1245. }
  1246. if !g.wholeProgram {
  1247. // When not in whole program mode we reset seenTypes after each package,
  1248. // which means g.seenTypes only contains types of
  1249. // interest to us. In whole program mode, we're better off
  1250. // processing all interfaces at once, globally, both for
  1251. // performance reasons and because in whole program mode we
  1252. // actually care about all interfaces, not just the subset
  1253. // that has unexported methods.
  1254. var ifaces []*types.Interface
  1255. var notIfaces []types.Type
  1256. ctx.seenTypes.Iterate(func(t types.Type, _ interface{}) {
  1257. switch t := t.(type) {
  1258. case *types.Interface:
  1259. // OPT(dh): (8.1) we only need interfaces that have unexported methods
  1260. ifaces = append(ifaces, t)
  1261. default:
  1262. if _, ok := t.Underlying().(*types.Interface); !ok {
  1263. notIfaces = append(notIfaces, t)
  1264. }
  1265. }
  1266. })
  1267. // (8.0) handle interfaces
  1268. for _, t := range notIfaces {
  1269. ms := pkg.SSA.Prog.MethodSets.MethodSet(t)
  1270. for _, iface := range ifaces {
  1271. if sels, ok := g.implements(t, iface, ms); ok {
  1272. for _, sel := range sels {
  1273. g.useMethod(ctx, t, sel, t, edgeImplements)
  1274. }
  1275. }
  1276. }
  1277. }
  1278. }
  1279. }
  1280. func (g *Graph) useMethod(ctx *context, t types.Type, sel *types.Selection, by interface{}, kind edgeKind) {
  1281. obj := sel.Obj()
  1282. path := sel.Index()
  1283. assert(obj != nil)
  1284. if len(path) > 1 {
  1285. base := lintdsl.Dereference(t).Underlying().(*types.Struct)
  1286. for _, idx := range path[:len(path)-1] {
  1287. next := base.Field(idx)
  1288. // (6.3) structs use embedded fields that help implement interfaces
  1289. ctx.see(base)
  1290. ctx.seeAndUse(next, base, edgeProvidesMethod)
  1291. base, _ = lintdsl.Dereference(next.Type()).Underlying().(*types.Struct)
  1292. }
  1293. }
  1294. ctx.seeAndUse(obj, by, kind)
  1295. }
  1296. func owningObject(fn *ssa.Function) types.Object {
  1297. if fn.Object() != nil {
  1298. return fn.Object()
  1299. }
  1300. if fn.Parent() != nil {
  1301. return owningObject(fn.Parent())
  1302. }
  1303. return nil
  1304. }
  1305. func (g *Graph) function(ctx *context, fn *ssa.Function) {
  1306. if fn.Package() != nil && fn.Package() != ctx.pkg.SSA {
  1307. return
  1308. }
  1309. name := fn.RelString(nil)
  1310. if _, ok := ctx.seenFns[name]; ok {
  1311. return
  1312. }
  1313. ctx.seenFns[name] = struct{}{}
  1314. // (4.1) functions use all their arguments, return parameters and receivers
  1315. g.signature(ctx, fn.Signature, owningObject(fn))
  1316. g.instructions(ctx, fn)
  1317. for _, anon := range fn.AnonFuncs {
  1318. // (4.2) functions use anonymous functions defined beneath them
  1319. //
  1320. // This fact is expressed implicitly. Anonymous functions have
  1321. // no types.Object, so their owner is the surrounding
  1322. // function.
  1323. g.function(ctx, anon)
  1324. }
  1325. }
  1326. func (g *Graph) typ(ctx *context, t types.Type, parent types.Type) {
  1327. if g.wholeProgram {
  1328. g.mu.Lock()
  1329. }
  1330. if ctx.seenTypes.At(t) != nil {
  1331. if g.wholeProgram {
  1332. g.mu.Unlock()
  1333. }
  1334. return
  1335. }
  1336. if g.wholeProgram {
  1337. g.mu.Unlock()
  1338. }
  1339. if t, ok := t.(*types.Named); ok && t.Obj().Pkg() != nil {
  1340. if t.Obj().Pkg() != ctx.pkg.Pkg {
  1341. return
  1342. }
  1343. }
  1344. if g.wholeProgram {
  1345. g.mu.Lock()
  1346. }
  1347. ctx.seenTypes.Set(t, struct{}{})
  1348. if g.wholeProgram {
  1349. g.mu.Unlock()
  1350. }
  1351. if isIrrelevant(t) {
  1352. return
  1353. }
  1354. ctx.see(t)
  1355. switch t := t.(type) {
  1356. case *types.Struct:
  1357. for i := 0; i < t.NumFields(); i++ {
  1358. ctx.see(t.Field(i))
  1359. if t.Field(i).Exported() {
  1360. // (6.2) structs use exported fields
  1361. ctx.use(t.Field(i), t, edgeExportedField)
  1362. } else if t.Field(i).Name() == "_" {
  1363. ctx.use(t.Field(i), t, edgeBlankField)
  1364. } else if isNoCopyType(t.Field(i).Type()) {
  1365. // (6.1) structs use fields of type NoCopy sentinel
  1366. ctx.use(t.Field(i), t, edgeNoCopySentinel)
  1367. } else if parent == nil {
  1368. // (11.1) anonymous struct types use all their fields.
  1369. ctx.use(t.Field(i), t, edgeAnonymousStruct)
  1370. }
  1371. if t.Field(i).Anonymous() {
  1372. // (e3) exported identifiers aren't automatically used.
  1373. if !g.wholeProgram {
  1374. // does the embedded field contribute exported methods to the method set?
  1375. T := t.Field(i).Type()
  1376. if _, ok := T.Underlying().(*types.Pointer); !ok {
  1377. // An embedded field is addressable, so check
  1378. // the pointer type to get the full method set
  1379. T = types.NewPointer(T)
  1380. }
  1381. ms := ctx.pkg.SSA.Prog.MethodSets.MethodSet(T)
  1382. for j := 0; j < ms.Len(); j++ {
  1383. if ms.At(j).Obj().Exported() {
  1384. // (6.4) structs use embedded fields that have exported methods (recursively)
  1385. ctx.use(t.Field(i), t, edgeExtendsExportedMethodSet)
  1386. break
  1387. }
  1388. }
  1389. }
  1390. seen := map[*types.Struct]struct{}{}
  1391. var hasExportedField func(t types.Type) bool
  1392. hasExportedField = func(T types.Type) bool {
  1393. t, ok := lintdsl.Dereference(T).Underlying().(*types.Struct)
  1394. if !ok {
  1395. return false
  1396. }
  1397. if _, ok := seen[t]; ok {
  1398. return false
  1399. }
  1400. seen[t] = struct{}{}
  1401. for i := 0; i < t.NumFields(); i++ {
  1402. field := t.Field(i)
  1403. if field.Exported() {
  1404. return true
  1405. }
  1406. if field.Embedded() && hasExportedField(field.Type()) {
  1407. return true
  1408. }
  1409. }
  1410. return false
  1411. }
  1412. // does the embedded field contribute exported fields?
  1413. if hasExportedField(t.Field(i).Type()) {
  1414. // (6.5) structs use embedded structs that have exported fields (recursively)
  1415. ctx.use(t.Field(i), t, edgeExtendsExportedFields)
  1416. }
  1417. }
  1418. g.variable(ctx, t.Field(i))
  1419. }
  1420. case *types.Basic:
  1421. // Nothing to do
  1422. case *types.Named:
  1423. // (9.3) types use their underlying and element types
  1424. ctx.seeAndUse(t.Underlying(), t, edgeUnderlyingType)
  1425. ctx.seeAndUse(t.Obj(), t, edgeTypeName)
  1426. ctx.seeAndUse(t, t.Obj(), edgeNamedType)
  1427. // (2.4) named types use the pointer type
  1428. if _, ok := t.Underlying().(*types.Interface); !ok && t.NumMethods() > 0 {
  1429. ctx.seeAndUse(types.NewPointer(t), t, edgePointerType)
  1430. }
  1431. for i := 0; i < t.NumMethods(); i++ {
  1432. ctx.see(t.Method(i))
  1433. // don't use trackExportedIdentifier here, we care about
  1434. // all exported methods, even in package main or in tests.
  1435. if t.Method(i).Exported() && !g.wholeProgram {
  1436. // (2.1) named types use exported methods
  1437. ctx.use(t.Method(i), t, edgeExportedMethod)
  1438. }
  1439. g.function(ctx, ctx.pkg.SSA.Prog.FuncValue(t.Method(i)))
  1440. }
  1441. g.typ(ctx, t.Underlying(), t)
  1442. case *types.Slice:
  1443. // (9.3) types use their underlying and element types
  1444. ctx.seeAndUse(t.Elem(), t, edgeElementType)
  1445. g.typ(ctx, t.Elem(), nil)
  1446. case *types.Map:
  1447. // (9.3) types use their underlying and element types
  1448. ctx.seeAndUse(t.Elem(), t, edgeElementType)
  1449. // (9.3) types use their underlying and element types
  1450. ctx.seeAndUse(t.Key(), t, edgeKeyType)
  1451. g.typ(ctx, t.Elem(), nil)
  1452. g.typ(ctx, t.Key(), nil)
  1453. case *types.Signature:
  1454. g.signature(ctx, t, nil)
  1455. case *types.Interface:
  1456. for i := 0; i < t.NumMethods(); i++ {
  1457. m := t.Method(i)
  1458. // (8.3) All interface methods are marked as used
  1459. ctx.seeAndUse(m, t, edgeInterfaceMethod)
  1460. ctx.seeAndUse(m.Type().(*types.Signature), m, edgeSignature)
  1461. g.signature(ctx, m.Type().(*types.Signature), nil)
  1462. }
  1463. for i := 0; i < t.NumEmbeddeds(); i++ {
  1464. tt := t.EmbeddedType(i)
  1465. // (8.4) All embedded interfaces are marked as used
  1466. ctx.seeAndUse(tt, t, edgeEmbeddedInterface)
  1467. }
  1468. case *types.Array:
  1469. // (9.3) types use their underlying and element types
  1470. ctx.seeAndUse(t.Elem(), t, edgeElementType)
  1471. g.typ(ctx, t.Elem(), nil)
  1472. case *types.Pointer:
  1473. // (9.3) types use their underlying and element types
  1474. ctx.seeAndUse(t.Elem(), t, edgeElementType)
  1475. g.typ(ctx, t.Elem(), nil)
  1476. case *types.Chan:
  1477. // (9.3) types use their underlying and element types
  1478. ctx.seeAndUse(t.Elem(), t, edgeElementType)
  1479. g.typ(ctx, t.Elem(), nil)
  1480. case *types.Tuple:
  1481. for i := 0; i < t.Len(); i++ {
  1482. // (9.3) types use their underlying and element types
  1483. ctx.seeAndUse(t.At(i).Type(), t, edgeTupleElement|edgeType)
  1484. g.typ(ctx, t.At(i).Type(), nil)
  1485. }
  1486. default:
  1487. panic(fmt.Sprintf("unreachable: %T", t))
  1488. }
  1489. }
  1490. func (g *Graph) variable(ctx *context, v *types.Var) {
  1491. // (9.2) variables use their types
  1492. ctx.seeAndUse(v.Type(), v, edgeType)
  1493. g.typ(ctx, v.Type(), nil)
  1494. }
  1495. func (g *Graph) signature(ctx *context, sig *types.Signature, fn types.Object) {
  1496. var user interface{} = fn
  1497. if fn == nil {
  1498. user = sig
  1499. ctx.see(sig)
  1500. }
  1501. if sig.Recv() != nil {
  1502. ctx.seeAndUse(sig.Recv().Type(), user, edgeReceiver|edgeType)
  1503. g.typ(ctx, sig.Recv().Type(), nil)
  1504. }
  1505. for i := 0; i < sig.Params().Len(); i++ {
  1506. param := sig.Params().At(i)
  1507. ctx.seeAndUse(param.Type(), user, edgeFunctionArgument|edgeType)
  1508. g.typ(ctx, param.Type(), nil)
  1509. }
  1510. for i := 0; i < sig.Results().Len(); i++ {
  1511. param := sig.Results().At(i)
  1512. ctx.seeAndUse(param.Type(), user, edgeFunctionResult|edgeType)
  1513. g.typ(ctx, param.Type(), nil)
  1514. }
  1515. }
  1516. func (g *Graph) instructions(ctx *context, fn *ssa.Function) {
  1517. fnObj := owningObject(fn)
  1518. for _, b := range fn.Blocks {
  1519. for _, instr := range b.Instrs {
  1520. ops := instr.Operands(nil)
  1521. switch instr.(type) {
  1522. case *ssa.Store:
  1523. // (9.7) variable _reads_ use variables, writes do not
  1524. ops = ops[1:]
  1525. case *ssa.DebugRef:
  1526. ops = nil
  1527. }
  1528. for _, arg := range ops {
  1529. walkPhi(*arg, func(v ssa.Value) {
  1530. switch v := v.(type) {
  1531. case *ssa.Function:
  1532. // (4.3) functions use closures and bound methods.
  1533. // (4.5) functions use functions they call
  1534. // (9.5) instructions use their operands
  1535. // (4.4) functions use functions they return. we assume that someone else will call the returned function
  1536. if owningObject(v) != nil {
  1537. ctx.seeAndUse(owningObject(v), fnObj, edgeInstructionOperand)
  1538. }
  1539. g.function(ctx, v)
  1540. case *ssa.Const:
  1541. // (9.6) instructions use their operands' types
  1542. ctx.seeAndUse(v.Type(), fnObj, edgeType)
  1543. g.typ(ctx, v.Type(), nil)
  1544. case *ssa.Global:
  1545. if v.Object() != nil {
  1546. // (9.5) instructions use their operands
  1547. ctx.seeAndUse(v.Object(), fnObj, edgeInstructionOperand)
  1548. }
  1549. }
  1550. })
  1551. }
  1552. if v, ok := instr.(ssa.Value); ok {
  1553. if _, ok := v.(*ssa.Range); !ok {
  1554. // See https://github.com/golang/go/issues/19670
  1555. // (4.8) instructions use their types
  1556. // (9.4) conversions use the type they convert to
  1557. ctx.seeAndUse(v.Type(), fnObj, edgeType)
  1558. g.typ(ctx, v.Type(), nil)
  1559. }
  1560. }
  1561. switch instr := instr.(type) {
  1562. case *ssa.Field:
  1563. st := instr.X.Type().Underlying().(*types.Struct)
  1564. field := st.Field(instr.Field)
  1565. // (4.7) functions use fields they access
  1566. ctx.seeAndUse(field, fnObj, edgeFieldAccess)
  1567. case *ssa.FieldAddr:
  1568. st := lintdsl.Dereference(instr.X.Type()).Underlying().(*types.Struct)
  1569. field := st.Field(instr.Field)
  1570. // (4.7) functions use fields they access
  1571. ctx.seeAndUse(field, fnObj, edgeFieldAccess)
  1572. case *ssa.Store:
  1573. // nothing to do, handled generically by operands
  1574. case *ssa.Call:
  1575. c := instr.Common()
  1576. if !c.IsInvoke() {
  1577. // handled generically as an instruction operand
  1578. if g.wholeProgram {
  1579. // (e3) special case known reflection-based method callers
  1580. switch lintdsl.CallName(c) {
  1581. case "net/rpc.Register", "net/rpc.RegisterName", "(*net/rpc.Server).Register", "(*net/rpc.Server).RegisterName":
  1582. var arg ssa.Value
  1583. switch lintdsl.CallName(c) {
  1584. case "net/rpc.Register":
  1585. arg = c.Args[0]
  1586. case "net/rpc.RegisterName":
  1587. arg = c.Args[1]
  1588. case "(*net/rpc.Server).Register":
  1589. arg = c.Args[1]
  1590. case "(*net/rpc.Server).RegisterName":
  1591. arg = c.Args[2]
  1592. }
  1593. walkPhi(arg, func(v ssa.Value) {
  1594. if v, ok := v.(*ssa.MakeInterface); ok {
  1595. walkPhi(v.X, func(vv ssa.Value) {
  1596. ms := ctx.pkg.SSA.Prog.MethodSets.MethodSet(vv.Type())
  1597. for i := 0; i < ms.Len(); i++ {
  1598. if ms.At(i).Obj().Exported() {
  1599. g.useMethod(ctx, vv.Type(), ms.At(i), fnObj, edgeNetRPCRegister)
  1600. }
  1601. }
  1602. })
  1603. }
  1604. })
  1605. }
  1606. }
  1607. } else {
  1608. // (4.5) functions use functions/interface methods they call
  1609. ctx.seeAndUse(c.Method, fnObj, edgeInterfaceCall)
  1610. }
  1611. case *ssa.Return:
  1612. // nothing to do, handled generically by operands
  1613. case *ssa.ChangeType:
  1614. // conversion type handled generically
  1615. s1, ok1 := lintdsl.Dereference(instr.Type()).Underlying().(*types.Struct)
  1616. s2, ok2 := lintdsl.Dereference(instr.X.Type()).Underlying().(*types.Struct)
  1617. if ok1 && ok2 {
  1618. // Converting between two structs. The fields are
  1619. // relevant for the conversion, but only if the
  1620. // fields are also used outside of the conversion.
  1621. // Mark fields as used by each other.
  1622. assert(s1.NumFields() == s2.NumFields())
  1623. for i := 0; i < s1.NumFields(); i++ {
  1624. ctx.see(s1.Field(i))
  1625. ctx.see(s2.Field(i))
  1626. // (5.1) when converting between two equivalent structs, the fields in
  1627. // either struct use each other. the fields are relevant for the
  1628. // conversion, but only if the fields are also accessed outside the
  1629. // conversion.
  1630. ctx.seeAndUse(s1.Field(i), s2.Field(i), edgeStructConversion)
  1631. ctx.seeAndUse(s2.Field(i), s1.Field(i), edgeStructConversion)
  1632. }
  1633. }
  1634. case *ssa.MakeInterface:
  1635. // nothing to do, handled generically by operands
  1636. case *ssa.Slice:
  1637. // nothing to do, handled generically by operands
  1638. case *ssa.RunDefers:
  1639. // nothing to do, the deferred functions are already marked use by defering them.
  1640. case *ssa.Convert:
  1641. // to unsafe.Pointer
  1642. if typ, ok := instr.Type().(*types.Basic); ok && typ.Kind() == types.UnsafePointer {
  1643. if ptr, ok := instr.X.Type().Underlying().(*types.Pointer); ok {
  1644. if st, ok := ptr.Elem().Underlying().(*types.Struct); ok {
  1645. for i := 0; i < st.NumFields(); i++ {
  1646. // (5.2) when converting to or from unsafe.Pointer, mark all fields as used.
  1647. ctx.seeAndUse(st.Field(i), fnObj, edgeUnsafeConversion)
  1648. }
  1649. }
  1650. }
  1651. }
  1652. // from unsafe.Pointer
  1653. if typ, ok := instr.X.Type().(*types.Basic); ok && typ.Kind() == types.UnsafePointer {
  1654. if ptr, ok := instr.Type().Underlying().(*types.Pointer); ok {
  1655. if st, ok := ptr.Elem().Underlying().(*types.Struct); ok {
  1656. for i := 0; i < st.NumFields(); i++ {
  1657. // (5.2) when converting to or from unsafe.Pointer, mark all fields as used.
  1658. ctx.seeAndUse(st.Field(i), fnObj, edgeUnsafeConversion)
  1659. }
  1660. }
  1661. }
  1662. }
  1663. case *ssa.TypeAssert:
  1664. // nothing to do, handled generically by instruction
  1665. // type (possibly a tuple, which contains the asserted
  1666. // to type). redundantly handled by the type of
  1667. // ssa.Extract, too
  1668. case *ssa.MakeClosure:
  1669. // nothing to do, handled generically by operands
  1670. case *ssa.Alloc:
  1671. // nothing to do
  1672. case *ssa.UnOp:
  1673. // nothing to do
  1674. case *ssa.BinOp:
  1675. // nothing to do
  1676. case *ssa.If:
  1677. // nothing to do
  1678. case *ssa.Jump:
  1679. // nothing to do
  1680. case *ssa.IndexAddr:
  1681. // nothing to do
  1682. case *ssa.Extract:
  1683. // nothing to do
  1684. case *ssa.Panic:
  1685. // nothing to do
  1686. case *ssa.DebugRef:
  1687. // nothing to do
  1688. case *ssa.BlankStore:
  1689. // nothing to do
  1690. case *ssa.Phi:
  1691. // nothing to do
  1692. case *ssa.MakeMap:
  1693. // nothing to do
  1694. case *ssa.MapUpdate:
  1695. // nothing to do
  1696. case *ssa.Lookup:
  1697. // nothing to do
  1698. case *ssa.MakeSlice:
  1699. // nothing to do
  1700. case *ssa.Send:
  1701. // nothing to do
  1702. case *ssa.MakeChan:
  1703. // nothing to do
  1704. case *ssa.Range:
  1705. // nothing to do
  1706. case *ssa.Next:
  1707. // nothing to do
  1708. case *ssa.Index:
  1709. // nothing to do
  1710. case *ssa.Select:
  1711. // nothing to do
  1712. case *ssa.ChangeInterface:
  1713. // nothing to do
  1714. case *ssa.Go:
  1715. // nothing to do, handled generically by operands
  1716. case *ssa.Defer:
  1717. // nothing to do, handled generically by operands
  1718. default:
  1719. panic(fmt.Sprintf("unreachable: %T", instr))
  1720. }
  1721. }
  1722. }
  1723. }
  1724. // isNoCopyType reports whether a type represents the NoCopy sentinel
  1725. // type. The NoCopy type is a named struct with no fields and exactly
  1726. // one method `func Lock()` that is empty.
  1727. //
  1728. // FIXME(dh): currently we're not checking that the function body is
  1729. // empty.
  1730. func isNoCopyType(typ types.Type) bool {
  1731. st, ok := typ.Underlying().(*types.Struct)
  1732. if !ok {
  1733. return false
  1734. }
  1735. if st.NumFields() != 0 {
  1736. return false
  1737. }
  1738. named, ok := typ.(*types.Named)
  1739. if !ok {
  1740. return false
  1741. }
  1742. if named.NumMethods() != 1 {
  1743. return false
  1744. }
  1745. meth := named.Method(0)
  1746. if meth.Name() != "Lock" {
  1747. return false
  1748. }
  1749. sig := meth.Type().(*types.Signature)
  1750. if sig.Params().Len() != 0 || sig.Results().Len() != 0 {
  1751. return false
  1752. }
  1753. return true
  1754. }
  1755. func walkPhi(v ssa.Value, fn func(v ssa.Value)) {
  1756. phi, ok := v.(*ssa.Phi)
  1757. if !ok {
  1758. fn(v)
  1759. return
  1760. }
  1761. seen := map[ssa.Value]struct{}{}
  1762. var impl func(v *ssa.Phi)
  1763. impl = func(v *ssa.Phi) {
  1764. if _, ok := seen[v]; ok {
  1765. return
  1766. }
  1767. seen[v] = struct{}{}
  1768. for _, e := range v.Edges {
  1769. if ev, ok := e.(*ssa.Phi); ok {
  1770. impl(ev)
  1771. } else {
  1772. fn(e)
  1773. }
  1774. }
  1775. }
  1776. impl(phi)
  1777. }
  1778. func interfacesFromExportData(pkg *types.Package) []*types.Interface {
  1779. var out []*types.Interface
  1780. scope := pkg.Scope()
  1781. for _, name := range scope.Names() {
  1782. obj := scope.Lookup(name)
  1783. out = append(out, interfacesFromObject(obj)...)
  1784. }
  1785. return out
  1786. }
  1787. func interfacesFromObject(obj types.Object) []*types.Interface {
  1788. var out []*types.Interface
  1789. switch obj := obj.(type) {
  1790. case *types.Func:
  1791. sig := obj.Type().(*types.Signature)
  1792. for i := 0; i < sig.Results().Len(); i++ {
  1793. out = append(out, interfacesFromObject(sig.Results().At(i))...)
  1794. }
  1795. for i := 0; i < sig.Params().Len(); i++ {
  1796. out = append(out, interfacesFromObject(sig.Params().At(i))...)
  1797. }
  1798. case *types.TypeName:
  1799. if named, ok := obj.Type().(*types.Named); ok {
  1800. for i := 0; i < named.NumMethods(); i++ {
  1801. out = append(out, interfacesFromObject(named.Method(i))...)
  1802. }
  1803. if iface, ok := named.Underlying().(*types.Interface); ok {
  1804. out = append(out, iface)
  1805. }
  1806. }
  1807. case *types.Var:
  1808. // No call to Underlying here. We want unnamed interfaces
  1809. // only. Named interfaces are gotten directly from the
  1810. // package's scope.
  1811. if iface, ok := obj.Type().(*types.Interface); ok {
  1812. out = append(out, iface)
  1813. }
  1814. case *types.Const:
  1815. case *types.Builtin:
  1816. default:
  1817. panic(fmt.Sprintf("unhandled type: %T", obj))
  1818. }
  1819. return out
  1820. }