imports: handle arbitrarily long lines

Previous work to resolve golang/go#18201 increased the maximum line
length that goimports could handle to 1MiB (CL83800), but generated code
can result in Go files with longer lines. Use a bufio.Reader instead of
a bufio.Scanner to support arbitrarily long lines, as permitted by the
Go spec.

Change-Id: If719e531859804304d60a8c00db6304ab3d5fe5e
Reviewed-on: https://go-review.googlesource.com/93439
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Nikhil Benesch 2018-02-12 19:48:13 -05:00 committed by Brad Fitzpatrick
parent 006ac430a0
commit c0251d31d2
2 changed files with 10 additions and 37 deletions

View File

@ -5,7 +5,6 @@
package imports
import (
"bufio"
"bytes"
"flag"
"go/build"
@ -2033,29 +2032,3 @@ const x = mypkg.Sprintf("%s", "my package")
t.Errorf("Process returned unexpected result.\ngot:\n%v\nwant:\n%v", got, want)
}
}
// Ensures a token that is larger that
// https://golang.org/issues/18201
func TestProcessTokenTooLarge(t *testing.T) {
const largeSize = maxScanTokenSize + 1
largeString := strings.Repeat("x", largeSize)
in := `package testimports
import (
"fmt"
"mydomain.mystuff/mypkg"
)
const s = fmt.Sprintf("%s", "` + largeString + `")
const x = mypkg.Sprintf("%s", "my package")
// end
`
_, err := Process("foo", []byte(in), nil)
if err != bufio.ErrTooLong {
t.Errorf("Process did not returned expected error.\n got:\n%v\nwant:\n%v", err, bufio.ErrTooLong)
}
}

View File

@ -259,18 +259,18 @@ func matchSpace(orig []byte, src []byte) []byte {
var impLine = regexp.MustCompile(`^\s+(?:[\w\.]+\s+)?"(.+)"`)
// Used to set Scanner buffer size so that large tokens can be handled.
// see https://github.com/golang/go/issues/18201
const maxScanTokenSize = bufio.MaxScanTokenSize * 16
func addImportSpaces(r io.Reader, breaks []string) ([]byte, error) {
var out bytes.Buffer
sc := bufio.NewScanner(r)
sc.Buffer(nil, maxScanTokenSize)
in := bufio.NewReader(r)
inImports := false
done := false
for sc.Scan() {
s := sc.Text()
for {
s, err := in.ReadString('\n')
if err == io.EOF {
break
} else if err != nil {
return nil, err
}
if !inImports && !done && strings.HasPrefix(s, "import") {
inImports = true
@ -291,7 +291,7 @@ func addImportSpaces(r io.Reader, breaks []string) ([]byte, error) {
}
}
fmt.Fprintln(&out, s)
fmt.Fprint(&out, s)
}
return out.Bytes(), sc.Err()
return out.Bytes(), nil
}