mirror of https://github.com/golang/go.git
gopls: fix out of bounds bug in extract
There was a bug where the code would try to access an out of bounds index when trimming extra space and comments in extract. This change also adds a regtest for extract. Fixes golang/go#55271 Change-Id: I7da716a6a68a9678011abf15def47acdea0b33fe Reviewed-on: https://go-review.googlesource.com/c/tools/+/432135 Run-TryBot: Suzy Mueller <suzmue@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> gopls-CI: kokoro <noreply+kokoro@google.com> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
16b974289f
commit
2f04713366
|
|
@ -676,7 +676,7 @@ func adjustRangeForCommentsAndWhiteSpace(rng span.Range, tok *token.File, conten
|
|||
prevStart = start
|
||||
// If start is within a comment, move start to the end
|
||||
// of the comment group.
|
||||
if file.Comments[startComment].Pos() <= start && start < file.Comments[startComment].End() {
|
||||
if startComment < len(file.Comments) && file.Comments[startComment].Pos() <= start && start < file.Comments[startComment].End() {
|
||||
start = file.Comments[startComment].End()
|
||||
startComment++
|
||||
}
|
||||
|
|
@ -697,11 +697,16 @@ func adjustRangeForCommentsAndWhiteSpace(rng span.Range, tok *token.File, conten
|
|||
// Find the index for the first comment that ends after the range end.
|
||||
return file.Comments[i].End() >= rng.End
|
||||
})
|
||||
// Search will return n if not found, so we need to adjust if there are no
|
||||
// comments that would match.
|
||||
if endComment == len(file.Comments) {
|
||||
endComment = -1
|
||||
}
|
||||
for prevEnd != end {
|
||||
prevEnd = end
|
||||
// If end is within a comment, move end to the start
|
||||
// of the comment group.
|
||||
if file.Comments[endComment].Pos() < end && end <= file.Comments[endComment].End() {
|
||||
if endComment >= 0 && file.Comments[endComment].Pos() < end && end <= file.Comments[endComment].End() {
|
||||
end = file.Comments[endComment].Pos()
|
||||
endComment--
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
package misc
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "golang.org/x/tools/gopls/internal/lsp/regtest"
|
||||
"golang.org/x/tools/gopls/internal/lsp/tests/compare"
|
||||
|
||||
"golang.org/x/tools/gopls/internal/lsp/protocol"
|
||||
)
|
||||
|
||||
func TestExtractFunction(t *testing.T) {
|
||||
const files = `
|
||||
-- go.mod --
|
||||
module mod.com
|
||||
|
||||
go 1.12
|
||||
-- main.go --
|
||||
package main
|
||||
|
||||
func Foo() int {
|
||||
a := 5
|
||||
return a
|
||||
}
|
||||
`
|
||||
Run(t, files, func(t *testing.T, env *Env) {
|
||||
env.OpenFile("main.go")
|
||||
|
||||
start := env.RegexpSearch("main.go", "a := 5").ToProtocolPosition()
|
||||
end := env.RegexpSearch("main.go", "return a").ToProtocolPosition()
|
||||
|
||||
actions, err := env.Editor.CodeAction(env.Ctx, "main.go", &protocol.Range{Start: start, End: end}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Find the extract function code action.
|
||||
var extractFunc *protocol.CodeAction
|
||||
for _, action := range actions {
|
||||
if action.Kind == protocol.RefactorExtract && action.Title == "Extract function" {
|
||||
extractFunc = &action
|
||||
break
|
||||
}
|
||||
}
|
||||
if extractFunc == nil {
|
||||
t.Fatal("could not find extract function action")
|
||||
}
|
||||
|
||||
env.ApplyCodeAction(*extractFunc)
|
||||
want := `package main
|
||||
|
||||
func Foo() int {
|
||||
a := newFunction()
|
||||
return a
|
||||
}
|
||||
|
||||
func newFunction() int {
|
||||
a := 5
|
||||
return a
|
||||
}
|
||||
`
|
||||
if got := env.Editor.BufferText("main.go"); got != want {
|
||||
t.Fatalf("TestFillStruct failed:\n%s", compare.Text(want, got))
|
||||
}
|
||||
})
|
||||
}
|
||||
Loading…
Reference in New Issue