go/ast/astutil: handle documentation of imports in DeleteNamedImport.
If the parens of an ast.GenDecl are dropped, move the documentation of the ImportSpec above the import statement, otherwise the the code is invalid. Fixes golang/go#15432. Change-Id: I715750b8f528380b96a6bc8b5f216043937976c2 Reviewed-on: https://go-review.googlesource.com/22415 Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
5e567c6dff
commit
f4e1751b91
|
@ -180,6 +180,7 @@ func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool)
|
||||||
// DeleteNamedImport deletes the import with the given name and path from the file f, if present.
|
// DeleteNamedImport deletes the import with the given name and path from the file f, if present.
|
||||||
func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (deleted bool) {
|
func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (deleted bool) {
|
||||||
var delspecs []*ast.ImportSpec
|
var delspecs []*ast.ImportSpec
|
||||||
|
var delcomments []*ast.CommentGroup
|
||||||
|
|
||||||
// Find the import nodes that import path, if any.
|
// Find the import nodes that import path, if any.
|
||||||
for i := 0; i < len(f.Decls); i++ {
|
for i := 0; i < len(f.Decls); i++ {
|
||||||
|
@ -216,7 +217,35 @@ func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (del
|
||||||
i--
|
i--
|
||||||
break
|
break
|
||||||
} else if len(gen.Specs) == 1 {
|
} else if len(gen.Specs) == 1 {
|
||||||
|
if impspec.Doc != nil {
|
||||||
|
delcomments = append(delcomments, impspec.Doc)
|
||||||
|
}
|
||||||
|
if impspec.Comment != nil {
|
||||||
|
delcomments = append(delcomments, impspec.Comment)
|
||||||
|
}
|
||||||
|
for _, cg := range f.Comments {
|
||||||
|
// Found comment on the same line as the import spec.
|
||||||
|
if cg.End() < impspec.Pos() && fset.Position(cg.End()).Line == fset.Position(impspec.Pos()).Line {
|
||||||
|
delcomments = append(delcomments, cg)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gen.Lparen = token.NoPos // drop parens
|
gen.Lparen = token.NoPos // drop parens
|
||||||
|
spec := gen.Specs[0].(*ast.ImportSpec)
|
||||||
|
if spec.Doc != nil {
|
||||||
|
// Move the documentation above the import statement.
|
||||||
|
gen.TokPos = spec.Doc.End() + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, cg := range f.Comments {
|
||||||
|
if cg.End() < spec.Pos() && fset.Position(cg.End()).Line == fset.Position(spec.Pos()).Line {
|
||||||
|
for fset.Position(gen.TokPos).Line != fset.Position(spec.Pos()).Line {
|
||||||
|
fset.File(gen.TokPos).MergeLine(fset.Position(gen.TokPos).Line)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if j > 0 {
|
if j > 0 {
|
||||||
lastImpspec := gen.Specs[j-1].(*ast.ImportSpec)
|
lastImpspec := gen.Specs[j-1].(*ast.ImportSpec)
|
||||||
|
@ -238,7 +267,7 @@ func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (del
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete them from f.Imports.
|
// Delete imports from f.Imports.
|
||||||
for i := 0; i < len(f.Imports); i++ {
|
for i := 0; i < len(f.Imports); i++ {
|
||||||
imp := f.Imports[i]
|
imp := f.Imports[i]
|
||||||
for j, del := range delspecs {
|
for j, del := range delspecs {
|
||||||
|
@ -253,6 +282,21 @@ func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (del
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete comments from f.Comments.
|
||||||
|
for i := 0; i < len(f.Comments); i++ {
|
||||||
|
cg := f.Comments[i]
|
||||||
|
for j, del := range delcomments {
|
||||||
|
if cg == del {
|
||||||
|
copy(f.Comments[i:], f.Comments[i+1:])
|
||||||
|
f.Comments = f.Comments[:len(f.Comments)-1]
|
||||||
|
copy(delcomments[j:], delcomments[j+1:])
|
||||||
|
delcomments = delcomments[:len(delcomments)-1]
|
||||||
|
i--
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(delspecs) > 0 {
|
if len(delspecs) > 0 {
|
||||||
panic(fmt.Sprintf("deleted specs from Decls but not Imports: %v", delspecs))
|
panic(fmt.Sprintf("deleted specs from Decls but not Imports: %v", delspecs))
|
||||||
}
|
}
|
||||||
|
|
|
@ -923,6 +923,270 @@ import y "fmt"
|
||||||
out: `package main
|
out: `package main
|
||||||
|
|
||||||
import y "fmt"
|
import y "fmt"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
// Issue #15432
|
||||||
|
{
|
||||||
|
name: "import.19",
|
||||||
|
pkg: "fmt",
|
||||||
|
in: `package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
// Some comment.
|
||||||
|
"io"
|
||||||
|
)`,
|
||||||
|
out: `package main
|
||||||
|
|
||||||
|
// Some comment.
|
||||||
|
import "io"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "import.20",
|
||||||
|
pkg: "fmt",
|
||||||
|
in: `package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
// Some
|
||||||
|
// comment.
|
||||||
|
"io"
|
||||||
|
)`,
|
||||||
|
out: `package main
|
||||||
|
|
||||||
|
// Some
|
||||||
|
// comment.
|
||||||
|
import "io"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "import.21",
|
||||||
|
pkg: "fmt",
|
||||||
|
in: `package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Some
|
||||||
|
comment.
|
||||||
|
*/
|
||||||
|
"io"
|
||||||
|
)`,
|
||||||
|
out: `package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
Some
|
||||||
|
comment.
|
||||||
|
*/
|
||||||
|
import "io"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "import.22",
|
||||||
|
pkg: "fmt",
|
||||||
|
in: `package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
/* Some */
|
||||||
|
// comment.
|
||||||
|
"io"
|
||||||
|
"fmt"
|
||||||
|
)`,
|
||||||
|
out: `package main
|
||||||
|
|
||||||
|
/* Some */
|
||||||
|
// comment.
|
||||||
|
import "io"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "import.23",
|
||||||
|
pkg: "fmt",
|
||||||
|
in: `package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
// comment 1
|
||||||
|
"fmt"
|
||||||
|
// comment 2
|
||||||
|
"io"
|
||||||
|
)`,
|
||||||
|
out: `package main
|
||||||
|
|
||||||
|
// comment 2
|
||||||
|
import "io"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "import.24",
|
||||||
|
pkg: "fmt",
|
||||||
|
in: `package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt" // comment 1
|
||||||
|
"io" // comment 2
|
||||||
|
)`,
|
||||||
|
out: `package main
|
||||||
|
|
||||||
|
import "io" // comment 2
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "import.25",
|
||||||
|
pkg: "fmt",
|
||||||
|
in: `package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
/* comment */ "io"
|
||||||
|
)`,
|
||||||
|
out: `package main
|
||||||
|
|
||||||
|
import /* comment */ "io"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "import.26",
|
||||||
|
pkg: "fmt",
|
||||||
|
in: `package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io" /* comment */
|
||||||
|
)`,
|
||||||
|
out: `package main
|
||||||
|
|
||||||
|
import "io" /* comment */
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "import.27",
|
||||||
|
pkg: "fmt",
|
||||||
|
in: `package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt" /* comment */
|
||||||
|
"io"
|
||||||
|
)`,
|
||||||
|
out: `package main
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "import.28",
|
||||||
|
pkg: "fmt",
|
||||||
|
in: `package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
/* comment */ "fmt"
|
||||||
|
"io"
|
||||||
|
)`,
|
||||||
|
out: `package main
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "import.29",
|
||||||
|
pkg: "fmt",
|
||||||
|
in: `package main
|
||||||
|
|
||||||
|
// comment 1
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io" // comment 2
|
||||||
|
)`,
|
||||||
|
out: `package main
|
||||||
|
|
||||||
|
// comment 1
|
||||||
|
import "io" // comment 2
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "import.30",
|
||||||
|
pkg: "fmt",
|
||||||
|
in: `package main
|
||||||
|
|
||||||
|
// comment 1
|
||||||
|
import (
|
||||||
|
"fmt" // comment 2
|
||||||
|
"io"
|
||||||
|
)`,
|
||||||
|
out: `package main
|
||||||
|
|
||||||
|
// comment 1
|
||||||
|
import "io"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "import.31",
|
||||||
|
pkg: "fmt",
|
||||||
|
in: `package main
|
||||||
|
|
||||||
|
// comment 1
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
/* comment 2 */ "io"
|
||||||
|
)`,
|
||||||
|
out: `package main
|
||||||
|
|
||||||
|
// comment 1
|
||||||
|
import /* comment 2 */ "io"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "import.32",
|
||||||
|
pkg: "fmt",
|
||||||
|
renamedPkg: "f",
|
||||||
|
in: `package main
|
||||||
|
|
||||||
|
// comment 1
|
||||||
|
import (
|
||||||
|
f "fmt"
|
||||||
|
/* comment 2 */ i "io"
|
||||||
|
)`,
|
||||||
|
out: `package main
|
||||||
|
|
||||||
|
// comment 1
|
||||||
|
import /* comment 2 */ i "io"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "import.33",
|
||||||
|
pkg: "fmt",
|
||||||
|
renamedPkg: "f",
|
||||||
|
in: `package main
|
||||||
|
|
||||||
|
// comment 1
|
||||||
|
import (
|
||||||
|
/* comment 2 */ f "fmt"
|
||||||
|
i "io"
|
||||||
|
)`,
|
||||||
|
out: `package main
|
||||||
|
|
||||||
|
// comment 1
|
||||||
|
import i "io"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "import.34",
|
||||||
|
pkg: "fmt",
|
||||||
|
renamedPkg: "f",
|
||||||
|
in: `package main
|
||||||
|
|
||||||
|
// comment 1
|
||||||
|
import (
|
||||||
|
f "fmt" /* comment 2 */
|
||||||
|
i "io"
|
||||||
|
)`,
|
||||||
|
out: `package main
|
||||||
|
|
||||||
|
// comment 1
|
||||||
|
import i "io"
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue