diff --git a/internal/lsp/cache/view.go b/internal/lsp/cache/view.go index 4ff2fcb4e8..5ba18e2e02 100644 --- a/internal/lsp/cache/view.go +++ b/internal/lsp/cache/view.go @@ -450,7 +450,7 @@ func (v *view) FindPosInPackage(searchpkg source.Package, pos token.Pos) (*ast.F if tok == nil { return nil, nil, nil, errors.Errorf("no file for pos in package %s", searchpkg.ID()) } - uri := span.FileURI(tok.Name()) + uri := span.FileURI(tok.Position(pos).Filename) // Special case for ignored files. var ( diff --git a/internal/span/token.go b/internal/span/token.go index ce44541b2f..01b5ed2d0a 100644 --- a/internal/span/token.go +++ b/internal/span/token.go @@ -64,7 +64,7 @@ func (r Range) Span() (Span, error) { if f == nil { return Span{}, fmt.Errorf("file not found in FileSet") } - s := Span{v: span{URI: FileURI(f.Name())}} + s := Span{} var err error s.v.Start.Offset, err = offset(f, r.Start) if err != nil { @@ -76,6 +76,16 @@ func (r Range) Span() (Span, error) { return Span{}, err } } + // In the presence of line directives, a single File can have sections from + // multiple file names. + filename := f.Position(r.Start).Filename + if r.End.IsValid() { + if endFilename := f.Position(r.End).Filename; filename != endFilename { + return Span{}, fmt.Errorf("span begins in file %q but ends in %q", filename, endFilename) + } + } + s.v.URI = FileURI(filename) + s.v.Start.clean() s.v.End.clean() s.v.clean()