addImport adds the import path to the file f, if absent.
(f *ast.File, ipath string)
| 544 | |
| 545 | // addImport adds the import path to the file f, if absent. |
| 546 | func addImport(f *ast.File, ipath string) (added bool) { |
| 547 | if imports(f, ipath) { |
| 548 | return false |
| 549 | } |
| 550 | |
| 551 | // Determine name of import. |
| 552 | // Assume added imports follow convention of using last element. |
| 553 | _, name := path.Split(ipath) |
| 554 | |
| 555 | // Rename any conflicting top-level references from name to name_. |
| 556 | renameTop(f, name, name+"_") |
| 557 | |
| 558 | newImport := &ast.ImportSpec{ |
| 559 | Path: &ast.BasicLit{ |
| 560 | Kind: token.STRING, |
| 561 | Value: strconv.Quote(ipath), |
| 562 | }, |
| 563 | } |
| 564 | |
| 565 | // Find an import decl to add to. |
| 566 | var ( |
| 567 | bestMatch = -1 |
| 568 | lastImport = -1 |
| 569 | impDecl *ast.GenDecl |
| 570 | impIndex = -1 |
| 571 | ) |
| 572 | for i, decl := range f.Decls { |
| 573 | gen, ok := decl.(*ast.GenDecl) |
| 574 | if ok && gen.Tok == token.IMPORT { |
| 575 | lastImport = i |
| 576 | // Do not add to import "C", to avoid disrupting the |
| 577 | // association with its doc comment, breaking cgo. |
| 578 | if declImports(gen, "C") { |
| 579 | continue |
| 580 | } |
| 581 | |
| 582 | // Compute longest shared prefix with imports in this block. |
| 583 | for j, spec := range gen.Specs { |
| 584 | impspec := spec.(*ast.ImportSpec) |
| 585 | n := matchLen(importPath(impspec), ipath) |
| 586 | if n > bestMatch { |
| 587 | bestMatch = n |
| 588 | impDecl = gen |
| 589 | impIndex = j |
| 590 | } |
| 591 | } |
| 592 | } |
| 593 | } |
| 594 | |
| 595 | // If no import decl found, add one after the last import. |
| 596 | if impDecl == nil { |
| 597 | impDecl = &ast.GenDecl{ |
| 598 | Tok: token.IMPORT, |
| 599 | } |
| 600 | f.Decls = append(f.Decls, nil) |
| 601 | copy(f.Decls[lastImport+2:], f.Decls[lastImport+1:]) |
| 602 | f.Decls[lastImport+1] = impDecl |
| 603 | } |