Skip to content

Commit 6d1e33f

Browse files
committed
internal/lsp: handle panic in hoverRune by using token.Pos
All operations within a file should be in terms of token.Pos, until the value must be returned. Fixes golang/go#48492 Change-Id: I2adfcad8b4729386700c08ba4618e033bf7c3db5 Reviewed-on: https://go-review.googlesource.com/c/tools/+/351629 Run-TryBot: Rebecca Stambler <[email protected]> Trust: Rebecca Stambler <[email protected]> gopls-CI: kokoro <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent c8db761 commit 6d1e33f

File tree

2 files changed

+24
-13
lines changed

2 files changed

+24
-13
lines changed

gopls/internal/regtest/misc/hover_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"strings"
99
"testing"
1010

11+
"golang.org/x/tools/internal/lsp/fake"
1112
. "golang.org/x/tools/internal/lsp/regtest"
1213
"golang.org/x/tools/internal/testenv"
1314
)
@@ -113,3 +114,19 @@ type Example struct`
113114
env.Editor.Hover(env.Ctx, "main.go", env.RegexpSearch("main.go", "Example"))
114115
})
115116
}
117+
118+
func TestHoverRune_48492(t *testing.T) {
119+
const files = `
120+
-- go.mod --
121+
module mod.com
122+
123+
go 1.18
124+
-- main.go --
125+
package main
126+
`
127+
Run(t, files, func(t *testing.T, env *Env) {
128+
env.OpenFile("main.go")
129+
env.EditBuffer("main.go", fake.NewEdit(0, 0, 1, 0, "package main\nfunc main() {\nconst x = `\nfoo\n`\n}"))
130+
env.Editor.Hover(env.Ctx, "main.go", env.RegexpSearch("main.go", "foo"))
131+
})
132+
}

internal/lsp/source/hover.go

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -137,19 +137,20 @@ func hoverRune(ctx context.Context, snapshot Snapshot, fh FileHandle, position p
137137
var ErrNoRuneFound = errors.New("no rune found")
138138

139139
// findRune returns rune information for a position in a file.
140-
func findRune(ctx context.Context, snapshot Snapshot, fh FileHandle, pos protocol.Position) (rune, MappedRange, error) {
140+
func findRune(ctx context.Context, snapshot Snapshot, fh FileHandle, position protocol.Position) (rune, MappedRange, error) {
141141
pkg, pgf, err := GetParsedFile(ctx, snapshot, fh, NarrowestPackage)
142142
if err != nil {
143143
return 0, MappedRange{}, err
144144
}
145-
spn, err := pgf.Mapper.PointSpan(pos)
145+
spn, err := pgf.Mapper.PointSpan(position)
146146
if err != nil {
147147
return 0, MappedRange{}, err
148148
}
149149
rng, err := spn.Range(pgf.Mapper.Converter)
150150
if err != nil {
151151
return 0, MappedRange{}, err
152152
}
153+
pos := rng.Start
153154

154155
// Find the basic literal enclosing the given position, if there is one.
155156
var lit *ast.BasicLit
@@ -158,7 +159,7 @@ func findRune(ctx context.Context, snapshot Snapshot, fh FileHandle, pos protoco
158159
if found {
159160
return false
160161
}
161-
if n, ok := n.(*ast.BasicLit); ok && rng.Start >= n.Pos() && rng.Start <= n.End() {
162+
if n, ok := n.(*ast.BasicLit); ok && pos >= n.Pos() && pos <= n.End() {
162163
lit = n
163164
found = true
164165
}
@@ -202,16 +203,9 @@ func findRune(ctx context.Context, snapshot Snapshot, fh FileHandle, pos protoco
202203
// It's a string, scan only if it contains a unicode escape sequence under or before the
203204
// current cursor position.
204205
var found bool
205-
strMappedRng, err := posToMappedRange(snapshot, pkg, lit.Pos(), lit.End())
206-
if err != nil {
207-
return 0, MappedRange{}, err
208-
}
209-
strRng, err := strMappedRng.Range()
210-
if err != nil {
211-
return 0, MappedRange{}, err
212-
}
213-
offset := strRng.Start.Character
214-
for i := pos.Character - offset; i > 0; i-- {
206+
litOffset := pgf.Tok.Offset(lit.Pos())
207+
offset := pgf.Tok.Offset(pos)
208+
for i := offset - litOffset; i > 0; i-- {
215209
// Start at the cursor position and search backward for the beginning of a rune escape sequence.
216210
rr, _ := utf8.DecodeRuneInString(lit.Value[i:])
217211
if rr == utf8.RuneError {

0 commit comments

Comments
 (0)