Reputation: 5736
After parsing a file and removing some functions, is it possible to also remove any now-unused imports before writing the new file?
Upvotes: 1
Views: 1163
Reputation: 964
I recently had a need for something similar when writing a code generator tool. Here's an outline of my solution:
golang.org/x/tools/imports
exports a func Process
that will take a Go source file (as []byte
), and automatically "fixes" imports: remove unused imports and add unlisted imports that are referenced in the source file. The goimports
command is based on this.go/format
. Note that this does not write to a disk file; it produces the string form of the AST in memory.imports.Process
to "fix" the imports of the file. It is important to pass the true file path of the Go source file to Process
, even if it does not exist on disk yet. The result of this call is a "fixed" Go source file as a []byte
"string"; i.e. any unused imports are removed.go/parser
on the "fixed" source file using parser.ParseFile
. I use the true file path of the Go source file, and an empty token.NewFileSet()
when calling ParseFile
. Again, the Go source file does not have to exist on disk.[]*ast.ImportSpec
slice (field ast.File.Imports
) between each of the two file-root AST nodes. (My implementation uses a map
to index each []*ast.ImportSpec
first, making it easier to cross-check without a double-nested loop.)*ast.ImportSpec
that have been removed (unused), I use golang.org/x/tools/go/ast/astutil
to rewrite the original AST, using the cursor to remove these known *ast.ImportSpec
nodes when visited.An aside: the imports
package cited above has an "internal" package that will provide a FixImports
function that essentially provides the raw "diff" derived manually above. Unfortunately we can't use it because it is marked as internal.
Upvotes: 3