go/ast/astutil: fix loop logic in AddNamedImport

When merging import declarations into a single block, AddNamedImport
modifies the list of declarations in the provided file while
iterating over the list. Take care to adjust the index into the list
so as to not skip entries or fall off the end.

Fixes golang/go#17213

Change-Id: I807246f762c965ea1fc51eb57759f6088336db86
Reviewed-on: https://go-review.googlesource.com/29681
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/go/ast/astutil/imports.go b/go/ast/astutil/imports.go
index cfaa864..070ff35 100644
--- a/go/ast/astutil/imports.go
+++ b/go/ast/astutil/imports.go
@@ -150,7 +150,8 @@
 
 	// Merge all the import declarations into the first one.
 	var first *ast.GenDecl
-	for i, decl := range f.Decls {
+	for i := 0; i < len(f.Decls); i++ {
+		decl := f.Decls[i]
 		gen, ok := decl.(*ast.GenDecl)
 		if !ok || gen.Tok != token.IMPORT || declImports(gen, "C") {
 			continue
@@ -165,6 +166,7 @@
 			first.Specs = append(first.Specs, spec)
 		}
 		f.Decls = append(f.Decls[:i], f.Decls[i+1:]...)
+		i--
 	}
 
 	return true
diff --git a/go/ast/astutil/imports_test.go b/go/ast/astutil/imports_test.go
index 3f6d00d..eb00e47 100644
--- a/go/ast/astutil/imports_test.go
+++ b/go/ast/astutil/imports_test.go
@@ -511,6 +511,25 @@
 import "bufio"
 `,
 	},
+	{
+		name: `issue 17213 many single-import lines`,
+		pkg:  "fmt",
+		in: `package main
+
+import "bufio"
+import "bytes"
+import "errors"
+`,
+		out: `package main
+
+import (
+	"bufio"
+	"bytes"
+	"errors"
+	"fmt"
+)
+`,
+	},
 }
 
 func TestAddImport(t *testing.T) {