fix.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848
  1. // Copyright 2011 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. package main
  5. import (
  6. "fmt"
  7. "go/ast"
  8. "go/parser"
  9. "go/token"
  10. "os"
  11. "path"
  12. "reflect"
  13. "strconv"
  14. "strings"
  15. )
  16. type fix struct {
  17. name string
  18. date string // date that fix was introduced, in YYYY-MM-DD format
  19. f func(*ast.File) bool
  20. desc string
  21. }
  22. // main runs sort.Sort(byName(fixes)) before printing list of fixes.
  23. type byName []fix
  24. func (f byName) Len() int { return len(f) }
  25. func (f byName) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
  26. func (f byName) Less(i, j int) bool { return f[i].name < f[j].name }
  27. // main runs sort.Sort(byDate(fixes)) before applying fixes.
  28. type byDate []fix
  29. func (f byDate) Len() int { return len(f) }
  30. func (f byDate) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
  31. func (f byDate) Less(i, j int) bool { return f[i].date < f[j].date }
  32. var fixes []fix
  33. func register(f fix) {
  34. fixes = append(fixes, f)
  35. }
  36. // walk traverses the AST x, calling visit(y) for each node y in the tree but
  37. // also with a pointer to each ast.Expr, ast.Stmt, and *ast.BlockStmt,
  38. // in a bottom-up traversal.
  39. func walk(x interface{}, visit func(interface{})) {
  40. walkBeforeAfter(x, nop, visit)
  41. }
  42. func nop(interface{}) {}
  43. // walkBeforeAfter is like walk but calls before(x) before traversing
  44. // x's children and after(x) afterward.
  45. func walkBeforeAfter(x interface{}, before, after func(interface{})) {
  46. before(x)
  47. switch n := x.(type) {
  48. default:
  49. panic(fmt.Errorf("unexpected type %T in walkBeforeAfter", x))
  50. case nil:
  51. // pointers to interfaces
  52. case *ast.Decl:
  53. walkBeforeAfter(*n, before, after)
  54. case *ast.Expr:
  55. walkBeforeAfter(*n, before, after)
  56. case *ast.Spec:
  57. walkBeforeAfter(*n, before, after)
  58. case *ast.Stmt:
  59. walkBeforeAfter(*n, before, after)
  60. // pointers to struct pointers
  61. case **ast.BlockStmt:
  62. walkBeforeAfter(*n, before, after)
  63. case **ast.CallExpr:
  64. walkBeforeAfter(*n, before, after)
  65. case **ast.FieldList:
  66. walkBeforeAfter(*n, before, after)
  67. case **ast.FuncType:
  68. walkBeforeAfter(*n, before, after)
  69. case **ast.Ident:
  70. walkBeforeAfter(*n, before, after)
  71. case **ast.BasicLit:
  72. walkBeforeAfter(*n, before, after)
  73. // pointers to slices
  74. case *[]ast.Decl:
  75. walkBeforeAfter(*n, before, after)
  76. case *[]ast.Expr:
  77. walkBeforeAfter(*n, before, after)
  78. case *[]*ast.File:
  79. walkBeforeAfter(*n, before, after)
  80. case *[]*ast.Ident:
  81. walkBeforeAfter(*n, before, after)
  82. case *[]ast.Spec:
  83. walkBeforeAfter(*n, before, after)
  84. case *[]ast.Stmt:
  85. walkBeforeAfter(*n, before, after)
  86. // These are ordered and grouped to match ../../pkg/go/ast/ast.go
  87. case *ast.Field:
  88. walkBeforeAfter(&n.Names, before, after)
  89. walkBeforeAfter(&n.Type, before, after)
  90. walkBeforeAfter(&n.Tag, before, after)
  91. case *ast.FieldList:
  92. for _, field := range n.List {
  93. walkBeforeAfter(field, before, after)
  94. }
  95. case *ast.BadExpr:
  96. case *ast.Ident:
  97. case *ast.Ellipsis:
  98. walkBeforeAfter(&n.Elt, before, after)
  99. case *ast.BasicLit:
  100. case *ast.FuncLit:
  101. walkBeforeAfter(&n.Type, before, after)
  102. walkBeforeAfter(&n.Body, before, after)
  103. case *ast.CompositeLit:
  104. walkBeforeAfter(&n.Type, before, after)
  105. walkBeforeAfter(&n.Elts, before, after)
  106. case *ast.ParenExpr:
  107. walkBeforeAfter(&n.X, before, after)
  108. case *ast.SelectorExpr:
  109. walkBeforeAfter(&n.X, before, after)
  110. case *ast.IndexExpr:
  111. walkBeforeAfter(&n.X, before, after)
  112. walkBeforeAfter(&n.Index, before, after)
  113. case *ast.SliceExpr:
  114. walkBeforeAfter(&n.X, before, after)
  115. if n.Low != nil {
  116. walkBeforeAfter(&n.Low, before, after)
  117. }
  118. if n.High != nil {
  119. walkBeforeAfter(&n.High, before, after)
  120. }
  121. case *ast.TypeAssertExpr:
  122. walkBeforeAfter(&n.X, before, after)
  123. walkBeforeAfter(&n.Type, before, after)
  124. case *ast.CallExpr:
  125. walkBeforeAfter(&n.Fun, before, after)
  126. walkBeforeAfter(&n.Args, before, after)
  127. case *ast.StarExpr:
  128. walkBeforeAfter(&n.X, before, after)
  129. case *ast.UnaryExpr:
  130. walkBeforeAfter(&n.X, before, after)
  131. case *ast.BinaryExpr:
  132. walkBeforeAfter(&n.X, before, after)
  133. walkBeforeAfter(&n.Y, before, after)
  134. case *ast.KeyValueExpr:
  135. walkBeforeAfter(&n.Key, before, after)
  136. walkBeforeAfter(&n.Value, before, after)
  137. case *ast.ArrayType:
  138. walkBeforeAfter(&n.Len, before, after)
  139. walkBeforeAfter(&n.Elt, before, after)
  140. case *ast.StructType:
  141. walkBeforeAfter(&n.Fields, before, after)
  142. case *ast.FuncType:
  143. walkBeforeAfter(&n.Params, before, after)
  144. if n.Results != nil {
  145. walkBeforeAfter(&n.Results, before, after)
  146. }
  147. case *ast.InterfaceType:
  148. walkBeforeAfter(&n.Methods, before, after)
  149. case *ast.MapType:
  150. walkBeforeAfter(&n.Key, before, after)
  151. walkBeforeAfter(&n.Value, before, after)
  152. case *ast.ChanType:
  153. walkBeforeAfter(&n.Value, before, after)
  154. case *ast.BadStmt:
  155. case *ast.DeclStmt:
  156. walkBeforeAfter(&n.Decl, before, after)
  157. case *ast.EmptyStmt:
  158. case *ast.LabeledStmt:
  159. walkBeforeAfter(&n.Stmt, before, after)
  160. case *ast.ExprStmt:
  161. walkBeforeAfter(&n.X, before, after)
  162. case *ast.SendStmt:
  163. walkBeforeAfter(&n.Chan, before, after)
  164. walkBeforeAfter(&n.Value, before, after)
  165. case *ast.IncDecStmt:
  166. walkBeforeAfter(&n.X, before, after)
  167. case *ast.AssignStmt:
  168. walkBeforeAfter(&n.Lhs, before, after)
  169. walkBeforeAfter(&n.Rhs, before, after)
  170. case *ast.GoStmt:
  171. walkBeforeAfter(&n.Call, before, after)
  172. case *ast.DeferStmt:
  173. walkBeforeAfter(&n.Call, before, after)
  174. case *ast.ReturnStmt:
  175. walkBeforeAfter(&n.Results, before, after)
  176. case *ast.BranchStmt:
  177. case *ast.BlockStmt:
  178. walkBeforeAfter(&n.List, before, after)
  179. case *ast.IfStmt:
  180. walkBeforeAfter(&n.Init, before, after)
  181. walkBeforeAfter(&n.Cond, before, after)
  182. walkBeforeAfter(&n.Body, before, after)
  183. walkBeforeAfter(&n.Else, before, after)
  184. case *ast.CaseClause:
  185. walkBeforeAfter(&n.List, before, after)
  186. walkBeforeAfter(&n.Body, before, after)
  187. case *ast.SwitchStmt:
  188. walkBeforeAfter(&n.Init, before, after)
  189. walkBeforeAfter(&n.Tag, before, after)
  190. walkBeforeAfter(&n.Body, before, after)
  191. case *ast.TypeSwitchStmt:
  192. walkBeforeAfter(&n.Init, before, after)
  193. walkBeforeAfter(&n.Assign, before, after)
  194. walkBeforeAfter(&n.Body, before, after)
  195. case *ast.CommClause:
  196. walkBeforeAfter(&n.Comm, before, after)
  197. walkBeforeAfter(&n.Body, before, after)
  198. case *ast.SelectStmt:
  199. walkBeforeAfter(&n.Body, before, after)
  200. case *ast.ForStmt:
  201. walkBeforeAfter(&n.Init, before, after)
  202. walkBeforeAfter(&n.Cond, before, after)
  203. walkBeforeAfter(&n.Post, before, after)
  204. walkBeforeAfter(&n.Body, before, after)
  205. case *ast.RangeStmt:
  206. walkBeforeAfter(&n.Key, before, after)
  207. walkBeforeAfter(&n.Value, before, after)
  208. walkBeforeAfter(&n.X, before, after)
  209. walkBeforeAfter(&n.Body, before, after)
  210. case *ast.ImportSpec:
  211. case *ast.ValueSpec:
  212. walkBeforeAfter(&n.Type, before, after)
  213. walkBeforeAfter(&n.Values, before, after)
  214. walkBeforeAfter(&n.Names, before, after)
  215. case *ast.TypeSpec:
  216. walkBeforeAfter(&n.Type, before, after)
  217. case *ast.BadDecl:
  218. case *ast.GenDecl:
  219. walkBeforeAfter(&n.Specs, before, after)
  220. case *ast.FuncDecl:
  221. if n.Recv != nil {
  222. walkBeforeAfter(&n.Recv, before, after)
  223. }
  224. walkBeforeAfter(&n.Type, before, after)
  225. if n.Body != nil {
  226. walkBeforeAfter(&n.Body, before, after)
  227. }
  228. case *ast.File:
  229. walkBeforeAfter(&n.Decls, before, after)
  230. case *ast.Package:
  231. walkBeforeAfter(&n.Files, before, after)
  232. case []*ast.File:
  233. for i := range n {
  234. walkBeforeAfter(&n[i], before, after)
  235. }
  236. case []ast.Decl:
  237. for i := range n {
  238. walkBeforeAfter(&n[i], before, after)
  239. }
  240. case []ast.Expr:
  241. for i := range n {
  242. walkBeforeAfter(&n[i], before, after)
  243. }
  244. case []*ast.Ident:
  245. for i := range n {
  246. walkBeforeAfter(&n[i], before, after)
  247. }
  248. case []ast.Stmt:
  249. for i := range n {
  250. walkBeforeAfter(&n[i], before, after)
  251. }
  252. case []ast.Spec:
  253. for i := range n {
  254. walkBeforeAfter(&n[i], before, after)
  255. }
  256. }
  257. after(x)
  258. }
  259. // imports returns true if f imports path.
  260. func imports(f *ast.File, path string) bool {
  261. return importSpec(f, path) != nil
  262. }
  263. // importSpec returns the import spec if f imports path,
  264. // or nil otherwise.
  265. func importSpec(f *ast.File, path string) *ast.ImportSpec {
  266. for _, s := range f.Imports {
  267. if importPath(s) == path {
  268. return s
  269. }
  270. }
  271. return nil
  272. }
  273. // importPath returns the unquoted import path of s,
  274. // or "" if the path is not properly quoted.
  275. func importPath(s *ast.ImportSpec) string {
  276. t, err := strconv.Unquote(s.Path.Value)
  277. if err == nil {
  278. return t
  279. }
  280. return ""
  281. }
  282. // declImports reports whether gen contains an import of path.
  283. func declImports(gen *ast.GenDecl, path string) bool {
  284. if gen.Tok != token.IMPORT {
  285. return false
  286. }
  287. for _, spec := range gen.Specs {
  288. impspec := spec.(*ast.ImportSpec)
  289. if importPath(impspec) == path {
  290. return true
  291. }
  292. }
  293. return false
  294. }
  295. // isPkgDot returns true if t is the expression "pkg.name"
  296. // where pkg is an imported identifier.
  297. func isPkgDot(t ast.Expr, pkg, name string) bool {
  298. sel, ok := t.(*ast.SelectorExpr)
  299. return ok && isTopName(sel.X, pkg) && sel.Sel.String() == name
  300. }
  301. // isPtrPkgDot returns true if f is the expression "*pkg.name"
  302. // where pkg is an imported identifier.
  303. func isPtrPkgDot(t ast.Expr, pkg, name string) bool {
  304. ptr, ok := t.(*ast.StarExpr)
  305. return ok && isPkgDot(ptr.X, pkg, name)
  306. }
  307. // isTopName returns true if n is a top-level unresolved identifier with the given name.
  308. func isTopName(n ast.Expr, name string) bool {
  309. id, ok := n.(*ast.Ident)
  310. return ok && id.Name == name && id.Obj == nil
  311. }
  312. // isName returns true if n is an identifier with the given name.
  313. func isName(n ast.Expr, name string) bool {
  314. id, ok := n.(*ast.Ident)
  315. return ok && id.String() == name
  316. }
  317. // isCall returns true if t is a call to pkg.name.
  318. func isCall(t ast.Expr, pkg, name string) bool {
  319. call, ok := t.(*ast.CallExpr)
  320. return ok && isPkgDot(call.Fun, pkg, name)
  321. }
  322. // If n is an *ast.Ident, isIdent returns it; otherwise isIdent returns nil.
  323. func isIdent(n interface{}) *ast.Ident {
  324. id, _ := n.(*ast.Ident)
  325. return id
  326. }
  327. // refersTo returns true if n is a reference to the same object as x.
  328. func refersTo(n ast.Node, x *ast.Ident) bool {
  329. id, ok := n.(*ast.Ident)
  330. // The test of id.Name == x.Name handles top-level unresolved
  331. // identifiers, which all have Obj == nil.
  332. return ok && id.Obj == x.Obj && id.Name == x.Name
  333. }
  334. // isBlank returns true if n is the blank identifier.
  335. func isBlank(n ast.Expr) bool {
  336. return isName(n, "_")
  337. }
  338. // isEmptyString returns true if n is an empty string literal.
  339. func isEmptyString(n ast.Expr) bool {
  340. lit, ok := n.(*ast.BasicLit)
  341. return ok && lit.Kind == token.STRING && len(lit.Value) == 2
  342. }
  343. func warn(pos token.Pos, msg string, args ...interface{}) {
  344. if pos.IsValid() {
  345. msg = "%s: " + msg
  346. arg1 := []interface{}{fset.Position(pos).String()}
  347. args = append(arg1, args...)
  348. }
  349. fmt.Fprintf(os.Stderr, msg+"\n", args...)
  350. }
  351. // countUses returns the number of uses of the identifier x in scope.
  352. func countUses(x *ast.Ident, scope []ast.Stmt) int {
  353. count := 0
  354. ff := func(n interface{}) {
  355. if n, ok := n.(ast.Node); ok && refersTo(n, x) {
  356. count++
  357. }
  358. }
  359. for _, n := range scope {
  360. walk(n, ff)
  361. }
  362. return count
  363. }
  364. // rewriteUses replaces all uses of the identifier x and !x in scope
  365. // with f(x.Pos()) and fnot(x.Pos()).
  366. func rewriteUses(x *ast.Ident, f, fnot func(token.Pos) ast.Expr, scope []ast.Stmt) {
  367. var lastF ast.Expr
  368. ff := func(n interface{}) {
  369. ptr, ok := n.(*ast.Expr)
  370. if !ok {
  371. return
  372. }
  373. nn := *ptr
  374. // The child node was just walked and possibly replaced.
  375. // If it was replaced and this is a negation, replace with fnot(p).
  376. not, ok := nn.(*ast.UnaryExpr)
  377. if ok && not.Op == token.NOT && not.X == lastF {
  378. *ptr = fnot(nn.Pos())
  379. return
  380. }
  381. if refersTo(nn, x) {
  382. lastF = f(nn.Pos())
  383. *ptr = lastF
  384. }
  385. }
  386. for _, n := range scope {
  387. walk(n, ff)
  388. }
  389. }
  390. // assignsTo returns true if any of the code in scope assigns to or takes the address of x.
  391. func assignsTo(x *ast.Ident, scope []ast.Stmt) bool {
  392. assigned := false
  393. ff := func(n interface{}) {
  394. if assigned {
  395. return
  396. }
  397. switch n := n.(type) {
  398. case *ast.UnaryExpr:
  399. // use of &x
  400. if n.Op == token.AND && refersTo(n.X, x) {
  401. assigned = true
  402. return
  403. }
  404. case *ast.AssignStmt:
  405. for _, l := range n.Lhs {
  406. if refersTo(l, x) {
  407. assigned = true
  408. return
  409. }
  410. }
  411. }
  412. }
  413. for _, n := range scope {
  414. if assigned {
  415. break
  416. }
  417. walk(n, ff)
  418. }
  419. return assigned
  420. }
  421. // newPkgDot returns an ast.Expr referring to "pkg.name" at position pos.
  422. func newPkgDot(pos token.Pos, pkg, name string) ast.Expr {
  423. return &ast.SelectorExpr{
  424. X: &ast.Ident{
  425. NamePos: pos,
  426. Name: pkg,
  427. },
  428. Sel: &ast.Ident{
  429. NamePos: pos,
  430. Name: name,
  431. },
  432. }
  433. }
  434. // renameTop renames all references to the top-level name old.
  435. // It returns true if it makes any changes.
  436. func renameTop(f *ast.File, old, new string) bool {
  437. var fixed bool
  438. // Rename any conflicting imports
  439. // (assuming package name is last element of path).
  440. for _, s := range f.Imports {
  441. if s.Name != nil {
  442. if s.Name.Name == old {
  443. s.Name.Name = new
  444. fixed = true
  445. }
  446. } else {
  447. _, thisName := path.Split(importPath(s))
  448. if thisName == old {
  449. s.Name = ast.NewIdent(new)
  450. fixed = true
  451. }
  452. }
  453. }
  454. // Rename any top-level declarations.
  455. for _, d := range f.Decls {
  456. switch d := d.(type) {
  457. case *ast.FuncDecl:
  458. if d.Recv == nil && d.Name.Name == old {
  459. d.Name.Name = new
  460. d.Name.Obj.Name = new
  461. fixed = true
  462. }
  463. case *ast.GenDecl:
  464. for _, s := range d.Specs {
  465. switch s := s.(type) {
  466. case *ast.TypeSpec:
  467. if s.Name.Name == old {
  468. s.Name.Name = new
  469. s.Name.Obj.Name = new
  470. fixed = true
  471. }
  472. case *ast.ValueSpec:
  473. for _, n := range s.Names {
  474. if n.Name == old {
  475. n.Name = new
  476. n.Obj.Name = new
  477. fixed = true
  478. }
  479. }
  480. }
  481. }
  482. }
  483. }
  484. // Rename top-level old to new, both unresolved names
  485. // (probably defined in another file) and names that resolve
  486. // to a declaration we renamed.
  487. walk(f, func(n interface{}) {
  488. id, ok := n.(*ast.Ident)
  489. if ok && isTopName(id, old) {
  490. id.Name = new
  491. fixed = true
  492. }
  493. if ok && id.Obj != nil && id.Name == old && id.Obj.Name == new {
  494. id.Name = id.Obj.Name
  495. fixed = true
  496. }
  497. })
  498. return fixed
  499. }
  500. // matchLen returns the length of the longest prefix shared by x and y.
  501. func matchLen(x, y string) int {
  502. i := 0
  503. for i < len(x) && i < len(y) && x[i] == y[i] {
  504. i++
  505. }
  506. return i
  507. }
  508. // addImport adds the import path to the file f, if absent.
  509. func addImport(f *ast.File, ipath string) (added bool) {
  510. if imports(f, ipath) {
  511. return false
  512. }
  513. // Determine name of import.
  514. // Assume added imports follow convention of using last element.
  515. _, name := path.Split(ipath)
  516. // Rename any conflicting top-level references from name to name_.
  517. renameTop(f, name, name+"_")
  518. newImport := &ast.ImportSpec{
  519. Path: &ast.BasicLit{
  520. Kind: token.STRING,
  521. Value: strconv.Quote(ipath),
  522. },
  523. }
  524. // Find an import decl to add to.
  525. var (
  526. bestMatch = -1
  527. lastImport = -1
  528. impDecl *ast.GenDecl
  529. impIndex = -1
  530. )
  531. for i, decl := range f.Decls {
  532. gen, ok := decl.(*ast.GenDecl)
  533. if ok && gen.Tok == token.IMPORT {
  534. lastImport = i
  535. // Do not add to import "C", to avoid disrupting the
  536. // association with its doc comment, breaking cgo.
  537. if declImports(gen, "C") {
  538. continue
  539. }
  540. // Compute longest shared prefix with imports in this block.
  541. for j, spec := range gen.Specs {
  542. impspec := spec.(*ast.ImportSpec)
  543. n := matchLen(importPath(impspec), ipath)
  544. if n > bestMatch {
  545. bestMatch = n
  546. impDecl = gen
  547. impIndex = j
  548. }
  549. }
  550. }
  551. }
  552. // If no import decl found, add one after the last import.
  553. if impDecl == nil {
  554. impDecl = &ast.GenDecl{
  555. Tok: token.IMPORT,
  556. }
  557. f.Decls = append(f.Decls, nil)
  558. copy(f.Decls[lastImport+2:], f.Decls[lastImport+1:])
  559. f.Decls[lastImport+1] = impDecl
  560. }
  561. // Ensure the import decl has parentheses, if needed.
  562. if len(impDecl.Specs) > 0 && !impDecl.Lparen.IsValid() {
  563. impDecl.Lparen = impDecl.Pos()
  564. }
  565. insertAt := impIndex + 1
  566. if insertAt == 0 {
  567. insertAt = len(impDecl.Specs)
  568. }
  569. impDecl.Specs = append(impDecl.Specs, nil)
  570. copy(impDecl.Specs[insertAt+1:], impDecl.Specs[insertAt:])
  571. impDecl.Specs[insertAt] = newImport
  572. if insertAt > 0 {
  573. // Assign same position as the previous import,
  574. // so that the sorter sees it as being in the same block.
  575. prev := impDecl.Specs[insertAt-1]
  576. newImport.Path.ValuePos = prev.Pos()
  577. newImport.EndPos = prev.Pos()
  578. }
  579. f.Imports = append(f.Imports, newImport)
  580. return true
  581. }
  582. // deleteImport deletes the import path from the file f, if present.
  583. func deleteImport(f *ast.File, path string) (deleted bool) {
  584. oldImport := importSpec(f, path)
  585. // Find the import node that imports path, if any.
  586. for i, decl := range f.Decls {
  587. gen, ok := decl.(*ast.GenDecl)
  588. if !ok || gen.Tok != token.IMPORT {
  589. continue
  590. }
  591. for j, spec := range gen.Specs {
  592. impspec := spec.(*ast.ImportSpec)
  593. if oldImport != impspec {
  594. continue
  595. }
  596. // We found an import spec that imports path.
  597. // Delete it.
  598. deleted = true
  599. copy(gen.Specs[j:], gen.Specs[j+1:])
  600. gen.Specs = gen.Specs[:len(gen.Specs)-1]
  601. // If this was the last import spec in this decl,
  602. // delete the decl, too.
  603. if len(gen.Specs) == 0 {
  604. copy(f.Decls[i:], f.Decls[i+1:])
  605. f.Decls = f.Decls[:len(f.Decls)-1]
  606. } else if len(gen.Specs) == 1 {
  607. gen.Lparen = token.NoPos // drop parens
  608. }
  609. if j > 0 {
  610. // We deleted an entry but now there will be
  611. // a blank line-sized hole where the import was.
  612. // Close the hole by making the previous
  613. // import appear to "end" where this one did.
  614. gen.Specs[j-1].(*ast.ImportSpec).EndPos = impspec.End()
  615. }
  616. break
  617. }
  618. }
  619. // Delete it from f.Imports.
  620. for i, imp := range f.Imports {
  621. if imp == oldImport {
  622. copy(f.Imports[i:], f.Imports[i+1:])
  623. f.Imports = f.Imports[:len(f.Imports)-1]
  624. break
  625. }
  626. }
  627. return
  628. }
  629. // rewriteImport rewrites any import of path oldPath to path newPath.
  630. func rewriteImport(f *ast.File, oldPath, newPath string) (rewrote bool) {
  631. for _, imp := range f.Imports {
  632. if importPath(imp) == oldPath {
  633. rewrote = true
  634. // record old End, because the default is to compute
  635. // it using the length of imp.Path.Value.
  636. imp.EndPos = imp.End()
  637. imp.Path.Value = strconv.Quote(newPath)
  638. }
  639. }
  640. return
  641. }
  642. func usesImport(f *ast.File, path string) (used bool) {
  643. spec := importSpec(f, path)
  644. if spec == nil {
  645. return
  646. }
  647. name := spec.Name.String()
  648. switch name {
  649. case "<nil>":
  650. // If the package name is not explicitly specified,
  651. // make an educated guess. This is not guaranteed to be correct.
  652. lastSlash := strings.LastIndex(path, "/")
  653. if lastSlash == -1 {
  654. name = path
  655. } else {
  656. name = path[lastSlash+1:]
  657. }
  658. case "_", ".":
  659. // Not sure if this import is used - err on the side of caution.
  660. return true
  661. }
  662. walk(f, func(n interface{}) {
  663. sel, ok := n.(*ast.SelectorExpr)
  664. if ok && isTopName(sel.X, name) {
  665. used = true
  666. }
  667. })
  668. return
  669. }
  670. func expr(s string) ast.Expr {
  671. x, err := parser.ParseExpr(s)
  672. if err != nil {
  673. panic("parsing " + s + ": " + err.Error())
  674. }
  675. // Remove position information to avoid spurious newlines.
  676. killPos(reflect.ValueOf(x))
  677. return x
  678. }
  679. var posType = reflect.TypeOf(token.Pos(0))
  680. func killPos(v reflect.Value) {
  681. switch v.Kind() {
  682. case reflect.Ptr, reflect.Interface:
  683. if !v.IsNil() {
  684. killPos(v.Elem())
  685. }
  686. case reflect.Slice:
  687. n := v.Len()
  688. for i := 0; i < n; i++ {
  689. killPos(v.Index(i))
  690. }
  691. case reflect.Struct:
  692. n := v.NumField()
  693. for i := 0; i < n; i++ {
  694. f := v.Field(i)
  695. if f.Type() == posType {
  696. f.SetInt(0)
  697. continue
  698. }
  699. killPos(f)
  700. }
  701. }
  702. }
  703. // A Rename describes a single renaming.
  704. type rename struct {
  705. OldImport string // only apply rename if this import is present
  706. NewImport string // add this import during rewrite
  707. Old string // old name: p.T or *p.T
  708. New string // new name: p.T or *p.T
  709. }
  710. func renameFix(tab []rename) func(*ast.File) bool {
  711. return func(f *ast.File) bool {
  712. return renameFixTab(f, tab)
  713. }
  714. }
  715. func parseName(s string) (ptr bool, pkg, nam string) {
  716. i := strings.Index(s, ".")
  717. if i < 0 {
  718. panic("parseName: invalid name " + s)
  719. }
  720. if strings.HasPrefix(s, "*") {
  721. ptr = true
  722. s = s[1:]
  723. i--
  724. }
  725. pkg = s[:i]
  726. nam = s[i+1:]
  727. return
  728. }
  729. func renameFixTab(f *ast.File, tab []rename) bool {
  730. fixed := false
  731. added := map[string]bool{}
  732. check := map[string]bool{}
  733. for _, t := range tab {
  734. if !imports(f, t.OldImport) {
  735. continue
  736. }
  737. optr, opkg, onam := parseName(t.Old)
  738. walk(f, func(n interface{}) {
  739. np, ok := n.(*ast.Expr)
  740. if !ok {
  741. return
  742. }
  743. x := *np
  744. if optr {
  745. p, ok := x.(*ast.StarExpr)
  746. if !ok {
  747. return
  748. }
  749. x = p.X
  750. }
  751. if !isPkgDot(x, opkg, onam) {
  752. return
  753. }
  754. if t.NewImport != "" && !added[t.NewImport] {
  755. addImport(f, t.NewImport)
  756. added[t.NewImport] = true
  757. }
  758. *np = expr(t.New)
  759. check[t.OldImport] = true
  760. fixed = true
  761. })
  762. }
  763. for ipath := range check {
  764. if !usesImport(f, ipath) {
  765. deleteImport(f, ipath)
  766. }
  767. }
  768. return fixed
  769. }