gopls/internal/regtest: make RegexpSearch return a Location
...along with various other Editor methods.
Do we need a more convenient way to say
env.Sandbox.Workdir.URIToPath(loc.URI) ?
Change-Id: I452028db4b99843e07861909ad8cef87cf9fb118
Reviewed-on: https://go-review.googlesource.com/c/tools/+/463655
Run-TryBot: Alan Donovan <adonovan@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.go
index c9214a8..9a1f0dd 100644
--- a/gopls/internal/lsp/fake/editor.go
+++ b/gopls/internal/lsp/fake/editor.go
@@ -39,6 +39,7 @@
sandbox *Sandbox
defaultEnv map[string]string
+ // TODO(adonovan): buffers should be keyed by protocol.DocumentURI.
mu sync.Mutex
config EditorConfig // editor configuration
buffers map[string]buffer // open buffers (relative path -> buffer content)
@@ -597,17 +598,17 @@
ErrUnknownBuffer = errors.New("unknown buffer")
)
-// regexpRange returns the start and end of the first occurrence of either re
+// regexpLocation returns the location of the first occurrence of either re
// or its singular subgroup. It returns ErrNoMatch if the regexp doesn't match.
-func regexpRange(mapper *protocol.Mapper, re string) (protocol.Range, error) {
+func regexpLocation(mapper *protocol.Mapper, re string) (protocol.Location, error) {
var start, end int
rec, err := regexp.Compile(re)
if err != nil {
- return protocol.Range{}, err
+ return protocol.Location{}, err
}
indexes := rec.FindSubmatchIndex(mapper.Content)
if indexes == nil {
- return protocol.Range{}, ErrNoMatch
+ return protocol.Location{}, ErrNoMatch
}
switch len(indexes) {
case 2:
@@ -617,33 +618,26 @@
// one subgroup: return its range
start, end = indexes[2], indexes[3]
default:
- return protocol.Range{}, fmt.Errorf("invalid search regexp %q: expect either 0 or 1 subgroups, got %d", re, len(indexes)/2-1)
+ return protocol.Location{}, fmt.Errorf("invalid search regexp %q: expect either 0 or 1 subgroups, got %d", re, len(indexes)/2-1)
}
- return mapper.OffsetRange(start, end)
+ return mapper.OffsetLocation(start, end)
}
-// RegexpRange returns the first range in the buffer bufName matching re. See
-// RegexpSearch for more information on matching.
-func (e *Editor) RegexpRange(bufName, re string) (protocol.Range, error) {
- e.mu.Lock()
- defer e.mu.Unlock()
- buf, ok := e.buffers[bufName]
- if !ok {
- return protocol.Range{}, ErrUnknownBuffer
- }
- return regexpRange(buf.mapper, re)
-}
-
-// RegexpSearch returns the position of the first match for re in the buffer
+// RegexpSearch returns the Location of the first match for re in the buffer
// bufName. For convenience, RegexpSearch supports the following two modes:
// 1. If re has no subgroups, return the position of the match for re itself.
// 2. If re has one subgroup, return the position of the first subgroup.
//
// It returns an error re is invalid, has more than one subgroup, or doesn't
// match the buffer.
-func (e *Editor) RegexpSearch(bufName, re string) (protocol.Position, error) {
- rng, err := e.RegexpRange(bufName, re)
- return rng.Start, err
+func (e *Editor) RegexpSearch(bufName, re string) (protocol.Location, error) {
+ e.mu.Lock()
+ buf, ok := e.buffers[bufName]
+ e.mu.Unlock()
+ if !ok {
+ return protocol.Location{}, ErrUnknownBuffer
+ }
+ return regexpLocation(buf.mapper, re)
}
// RegexpReplace edits the buffer corresponding to path by replacing the first
@@ -658,12 +652,12 @@
if !ok {
return ErrUnknownBuffer
}
- rng, err := regexpRange(buf.mapper, re)
+ loc, err := regexpLocation(buf.mapper, re)
if err != nil {
return err
}
edits := []protocol.TextEdit{{
- Range: rng,
+ Range: loc.Range,
NewText: replace,
}}
patched, err := applyEdits(buf.mapper, edits, e.config.WindowsLineEndings)
@@ -765,53 +759,53 @@
}
// GoToDefinition jumps to the definition of the symbol at the given position
-// in an open buffer. It returns the path and position of the resulting jump.
-func (e *Editor) GoToDefinition(ctx context.Context, path string, pos protocol.Position) (string, protocol.Position, error) {
- if err := e.checkBufferPosition(path, pos); err != nil {
- return "", protocol.Position{}, err
+// in an open buffer. It returns the location of the resulting jump.
+func (e *Editor) GoToDefinition(ctx context.Context, loc protocol.Location) (protocol.Location, error) {
+ if err := e.checkBufferLocation(loc); err != nil {
+ return protocol.Location{}, err
}
params := &protocol.DefinitionParams{}
- params.TextDocument.URI = e.sandbox.Workdir.URI(path)
- params.Position = pos
+ params.TextDocument.URI = loc.URI
+ params.Position = loc.Range.Start
resp, err := e.Server.Definition(ctx, params)
if err != nil {
- return "", protocol.Position{}, fmt.Errorf("definition: %w", err)
+ return protocol.Location{}, fmt.Errorf("definition: %w", err)
}
- return e.extractFirstPathAndPos(ctx, resp)
+ return e.extractFirstLocation(ctx, resp)
}
-// GoToTypeDefinition jumps to the type definition of the symbol at the given position
+// GoToTypeDefinition jumps to the type definition of the symbol at the given location
// in an open buffer.
-func (e *Editor) GoToTypeDefinition(ctx context.Context, path string, pos protocol.Position) (string, protocol.Position, error) {
- if err := e.checkBufferPosition(path, pos); err != nil {
- return "", protocol.Position{}, err
+func (e *Editor) GoToTypeDefinition(ctx context.Context, loc protocol.Location) (protocol.Location, error) {
+ if err := e.checkBufferLocation(loc); err != nil {
+ return protocol.Location{}, err
}
params := &protocol.TypeDefinitionParams{}
- params.TextDocument.URI = e.sandbox.Workdir.URI(path)
- params.Position = pos
+ params.TextDocument.URI = loc.URI
+ params.Position = loc.Range.Start
resp, err := e.Server.TypeDefinition(ctx, params)
if err != nil {
- return "", protocol.Position{}, fmt.Errorf("type definition: %w", err)
+ return protocol.Location{}, fmt.Errorf("type definition: %w", err)
}
- return e.extractFirstPathAndPos(ctx, resp)
+ return e.extractFirstLocation(ctx, resp)
}
-// extractFirstPathAndPos returns the path and the position of the first location.
+// extractFirstPathAndPos returns the first location.
// It opens the file if needed.
-func (e *Editor) extractFirstPathAndPos(ctx context.Context, locs []protocol.Location) (string, protocol.Position, error) {
+func (e *Editor) extractFirstLocation(ctx context.Context, locs []protocol.Location) (protocol.Location, error) {
if len(locs) == 0 {
- return "", protocol.Position{}, nil
+ return protocol.Location{}, nil
}
newPath := e.sandbox.Workdir.URIToPath(locs[0].URI)
if !e.HasBuffer(newPath) {
if err := e.OpenFile(ctx, newPath); err != nil {
- return "", protocol.Position{}, fmt.Errorf("OpenFile: %w", err)
+ return protocol.Location{}, fmt.Errorf("OpenFile: %w", err)
}
}
- return newPath, locs[0].Range.Start, nil
+ return locs[0], nil
}
// Symbol performs a workspace symbol search using query
@@ -822,13 +816,14 @@
// OrganizeImports requests and performs the source.organizeImports codeAction.
func (e *Editor) OrganizeImports(ctx context.Context, path string) error {
- _, err := e.applyCodeActions(ctx, path, nil, nil, protocol.SourceOrganizeImports)
+ loc := protocol.Location{URI: e.sandbox.Workdir.URI(path)} // zero Range => whole file
+ _, err := e.applyCodeActions(ctx, loc, nil, protocol.SourceOrganizeImports)
return err
}
// RefactorRewrite requests and performs the source.refactorRewrite codeAction.
-func (e *Editor) RefactorRewrite(ctx context.Context, path string, rng *protocol.Range) error {
- applied, err := e.applyCodeActions(ctx, path, rng, nil, protocol.RefactorRewrite)
+func (e *Editor) RefactorRewrite(ctx context.Context, loc protocol.Location) error {
+ applied, err := e.applyCodeActions(ctx, loc, nil, protocol.RefactorRewrite)
if err != nil {
return err
}
@@ -839,8 +834,8 @@
}
// ApplyQuickFixes requests and performs the quickfix codeAction.
-func (e *Editor) ApplyQuickFixes(ctx context.Context, path string, rng *protocol.Range, diagnostics []protocol.Diagnostic) error {
- applied, err := e.applyCodeActions(ctx, path, rng, diagnostics, protocol.SourceFixAll, protocol.QuickFix)
+func (e *Editor) ApplyQuickFixes(ctx context.Context, loc protocol.Location, diagnostics []protocol.Diagnostic) error {
+ applied, err := e.applyCodeActions(ctx, loc, diagnostics, protocol.SourceFixAll, protocol.QuickFix)
if applied == 0 {
return fmt.Errorf("no quick fixes were applied")
}
@@ -876,12 +871,12 @@
}
// GetQuickFixes returns the available quick fix code actions.
-func (e *Editor) GetQuickFixes(ctx context.Context, path string, rng *protocol.Range, diagnostics []protocol.Diagnostic) ([]protocol.CodeAction, error) {
- return e.getCodeActions(ctx, path, rng, diagnostics, protocol.QuickFix, protocol.SourceFixAll)
+func (e *Editor) GetQuickFixes(ctx context.Context, loc protocol.Location, diagnostics []protocol.Diagnostic) ([]protocol.CodeAction, error) {
+ return e.getCodeActions(ctx, loc, diagnostics, protocol.QuickFix, protocol.SourceFixAll)
}
-func (e *Editor) applyCodeActions(ctx context.Context, path string, rng *protocol.Range, diagnostics []protocol.Diagnostic, only ...protocol.CodeActionKind) (int, error) {
- actions, err := e.getCodeActions(ctx, path, rng, diagnostics, only...)
+func (e *Editor) applyCodeActions(ctx context.Context, loc protocol.Location, diagnostics []protocol.Diagnostic, only ...protocol.CodeActionKind) (int, error) {
+ actions, err := e.getCodeActions(ctx, loc, diagnostics, only...)
if err != nil {
return 0, err
}
@@ -908,19 +903,17 @@
return applied, nil
}
-func (e *Editor) getCodeActions(ctx context.Context, path string, rng *protocol.Range, diagnostics []protocol.Diagnostic, only ...protocol.CodeActionKind) ([]protocol.CodeAction, error) {
+func (e *Editor) getCodeActions(ctx context.Context, loc protocol.Location, diagnostics []protocol.Diagnostic, only ...protocol.CodeActionKind) ([]protocol.CodeAction, error) {
if e.Server == nil {
return nil, nil
}
params := &protocol.CodeActionParams{}
- params.TextDocument.URI = e.sandbox.Workdir.URI(path)
+ params.TextDocument.URI = loc.URI
params.Context.Only = only
+ params.Range = loc.Range // may be zero => whole file
if diagnostics != nil {
params.Context.Diagnostics = diagnostics
}
- if rng != nil {
- params.Range = *rng
- }
return e.Server.CodeAction(ctx, params)
}
@@ -976,15 +969,16 @@
return e.editBufferLocked(ctx, path, edits)
}
-func (e *Editor) checkBufferPosition(path string, pos protocol.Position) error {
+func (e *Editor) checkBufferLocation(loc protocol.Location) error {
e.mu.Lock()
defer e.mu.Unlock()
+ path := e.sandbox.Workdir.URIToPath(loc.URI)
buf, ok := e.buffers[path]
if !ok {
return fmt.Errorf("buffer %q is not open", path)
}
- _, err := buf.mapper.PositionOffset(pos)
+ _, _, err := buf.mapper.RangeOffsets(loc.Range)
return err
}
@@ -1041,10 +1035,11 @@
}
// Completion executes a completion request on the server.
-func (e *Editor) Completion(ctx context.Context, path string, pos protocol.Position) (*protocol.CompletionList, error) {
+func (e *Editor) Completion(ctx context.Context, loc protocol.Location) (*protocol.CompletionList, error) {
if e.Server == nil {
return nil, nil
}
+ path := e.sandbox.Workdir.URIToPath(loc.URI)
e.mu.Lock()
_, ok := e.buffers[path]
e.mu.Unlock()
@@ -1054,7 +1049,7 @@
params := &protocol.CompletionParams{
TextDocumentPositionParams: protocol.TextDocumentPositionParams{
TextDocument: e.TextDocumentIdentifier(path),
- Position: pos,
+ Position: loc.Range.Start,
},
}
completions, err := e.Server.Completion(ctx, params)
@@ -1066,12 +1061,13 @@
// AcceptCompletion accepts a completion for the given item at the given
// position.
-func (e *Editor) AcceptCompletion(ctx context.Context, path string, pos protocol.Position, item protocol.CompletionItem) error {
+func (e *Editor) AcceptCompletion(ctx context.Context, loc protocol.Location, item protocol.CompletionItem) error {
if e.Server == nil {
return nil
}
e.mu.Lock()
defer e.mu.Unlock()
+ path := e.sandbox.Workdir.URIToPath(loc.URI)
_, ok := e.buffers[path]
if !ok {
return fmt.Errorf("buffer %q is not open", path)
@@ -1112,12 +1108,13 @@
return hints, nil
}
-// References returns references to the object at (path, pos), as returned by
+// References returns references to the object at loc, as returned by
// the connected LSP server. If no server is connected, it returns (nil, nil).
-func (e *Editor) References(ctx context.Context, path string, pos protocol.Position) ([]protocol.Location, error) {
+func (e *Editor) References(ctx context.Context, loc protocol.Location) ([]protocol.Location, error) {
if e.Server == nil {
return nil, nil
}
+ path := e.sandbox.Workdir.URIToPath(loc.URI)
e.mu.Lock()
_, ok := e.buffers[path]
e.mu.Unlock()
@@ -1127,7 +1124,7 @@
params := &protocol.ReferenceParams{
TextDocumentPositionParams: protocol.TextDocumentPositionParams{
TextDocument: e.TextDocumentIdentifier(path),
- Position: pos,
+ Position: loc.Range.Start,
},
Context: protocol.ReferenceContext{
IncludeDeclaration: true,
@@ -1140,24 +1137,25 @@
return locations, nil
}
-// Rename performs a rename of the object at (path, pos) to newName, using the
+// Rename performs a rename of the object at loc to newName, using the
// connected LSP server. If no server is connected, it returns nil.
-func (e *Editor) Rename(ctx context.Context, path string, pos protocol.Position, newName string) error {
+func (e *Editor) Rename(ctx context.Context, loc protocol.Location, newName string) error {
if e.Server == nil {
return nil
}
+ path := e.sandbox.Workdir.URIToPath(loc.URI)
// Verify that PrepareRename succeeds.
prepareParams := &protocol.PrepareRenameParams{}
prepareParams.TextDocument = e.TextDocumentIdentifier(path)
- prepareParams.Position = pos
+ prepareParams.Position = loc.Range.Start
if _, err := e.Server.PrepareRename(ctx, prepareParams); err != nil {
return fmt.Errorf("preparing rename: %v", err)
}
params := &protocol.RenameParams{
TextDocument: e.TextDocumentIdentifier(path),
- Position: pos,
+ Position: loc.Range.Start,
NewName: newName,
}
wsEdits, err := e.Server.Rename(ctx, params)
@@ -1172,13 +1170,14 @@
return nil
}
-// Implementations returns implementations for the object at (path, pos), as
+// Implementations returns implementations for the object at loc, as
// returned by the connected LSP server. If no server is connected, it returns
// (nil, nil).
-func (e *Editor) Implementations(ctx context.Context, path string, pos protocol.Position) ([]protocol.Location, error) {
+func (e *Editor) Implementations(ctx context.Context, loc protocol.Location) ([]protocol.Location, error) {
if e.Server == nil {
return nil, nil
}
+ path := e.sandbox.Workdir.URIToPath(loc.URI)
e.mu.Lock()
_, ok := e.buffers[path]
e.mu.Unlock()
@@ -1188,7 +1187,7 @@
params := &protocol.ImplementationParams{
TextDocumentPositionParams: protocol.TextDocumentPositionParams{
TextDocument: e.TextDocumentIdentifier(path),
- Position: pos,
+ Position: loc.Range.Start,
},
}
return e.Server.Implementation(ctx, params)
@@ -1368,10 +1367,12 @@
}
// CodeAction executes a codeAction request on the server.
-func (e *Editor) CodeAction(ctx context.Context, path string, rng *protocol.Range, diagnostics []protocol.Diagnostic) ([]protocol.CodeAction, error) {
+// If loc.Range is zero, the whole file is implied.
+func (e *Editor) CodeAction(ctx context.Context, loc protocol.Location, diagnostics []protocol.Diagnostic) ([]protocol.CodeAction, error) {
if e.Server == nil {
return nil, nil
}
+ path := e.sandbox.Workdir.URIToPath(loc.URI)
e.mu.Lock()
_, ok := e.buffers[path]
e.mu.Unlock()
@@ -1383,9 +1384,7 @@
Context: protocol.CodeActionContext{
Diagnostics: diagnostics,
},
- }
- if rng != nil {
- params.Range = *rng
+ Range: loc.Range, // may be zero
}
lens, err := e.Server.CodeAction(ctx, params)
if err != nil {
@@ -1395,22 +1394,22 @@
}
// Hover triggers a hover at the given position in an open buffer.
-func (e *Editor) Hover(ctx context.Context, path string, pos protocol.Position) (*protocol.MarkupContent, protocol.Position, error) {
- if err := e.checkBufferPosition(path, pos); err != nil {
- return nil, protocol.Position{}, err
+func (e *Editor) Hover(ctx context.Context, loc protocol.Location) (*protocol.MarkupContent, protocol.Location, error) {
+ if err := e.checkBufferLocation(loc); err != nil {
+ return nil, protocol.Location{}, err
}
params := &protocol.HoverParams{}
- params.TextDocument.URI = e.sandbox.Workdir.URI(path)
- params.Position = pos
+ params.TextDocument.URI = loc.URI
+ params.Position = loc.Range.Start
resp, err := e.Server.Hover(ctx, params)
if err != nil {
- return nil, protocol.Position{}, fmt.Errorf("hover: %w", err)
+ return nil, protocol.Location{}, fmt.Errorf("hover: %w", err)
}
if resp == nil {
- return nil, protocol.Position{}, nil
+ return nil, protocol.Location{}, nil
}
- return &resp.Contents, resp.Range.Start, nil
+ return &resp.Contents, protocol.Location{URI: loc.URI, Range: resp.Range}, nil
}
func (e *Editor) DocumentLink(ctx context.Context, path string) ([]protocol.DocumentLink, error) {
@@ -1422,16 +1421,16 @@
return e.Server.DocumentLink(ctx, params)
}
-func (e *Editor) DocumentHighlight(ctx context.Context, path string, pos protocol.Position) ([]protocol.DocumentHighlight, error) {
+func (e *Editor) DocumentHighlight(ctx context.Context, loc protocol.Location) ([]protocol.DocumentHighlight, error) {
if e.Server == nil {
return nil, nil
}
- if err := e.checkBufferPosition(path, pos); err != nil {
+ if err := e.checkBufferLocation(loc); err != nil {
return nil, err
}
params := &protocol.DocumentHighlightParams{}
- params.TextDocument.URI = e.sandbox.Workdir.URI(path)
- params.Position = pos
+ params.TextDocument.URI = loc.URI
+ params.Position = loc.Range.Start
return e.Server.DocumentHighlight(ctx, params)
}
diff --git a/gopls/internal/lsp/fake/workdir.go b/gopls/internal/lsp/fake/workdir.go
index 2470e74..97d70b9 100644
--- a/gopls/internal/lsp/fake/workdir.go
+++ b/gopls/internal/lsp/fake/workdir.go
@@ -196,25 +196,15 @@
}
}
-func (w *Workdir) RegexpRange(path, re string) (protocol.Range, error) {
- content, err := w.ReadFile(path)
- if err != nil {
- return protocol.Range{}, err
- }
- mapper := protocol.NewMapper(w.URI(path).SpanURI(), content)
- return regexpRange(mapper, re)
-}
-
// RegexpSearch searches the file corresponding to path for the first position
// matching re.
-func (w *Workdir) RegexpSearch(path string, re string) (protocol.Position, error) {
+func (w *Workdir) RegexpSearch(path string, re string) (protocol.Location, error) {
content, err := w.ReadFile(path)
if err != nil {
- return protocol.Position{}, err
+ return protocol.Location{}, err
}
mapper := protocol.NewMapper(w.URI(path).SpanURI(), content)
- rng, err := regexpRange(mapper, re)
- return rng.Start, err
+ return regexpLocation(mapper, re)
}
// RemoveFile removes a workdir-relative file path and notifies watchers of the
diff --git a/gopls/internal/lsp/regtest/expectation.go b/gopls/internal/lsp/regtest/expectation.go
index 6d3f334..cba4c60 100644
--- a/gopls/internal/lsp/regtest/expectation.go
+++ b/gopls/internal/lsp/regtest/expectation.go
@@ -712,11 +712,11 @@
// TODO(rfindley): pass in the editor to expectations, so that they may depend
// on editor state and AtRegexp can be a function rather than a method.
func (e *Env) AtRegexp(name, pattern string) DiagnosticFilter {
- pos := e.RegexpSearch(name, pattern)
+ loc := e.RegexpSearch(name, pattern)
return DiagnosticFilter{
desc: fmt.Sprintf("at the first position matching %#q in %q", pattern, name),
check: func(diagName string, d protocol.Diagnostic) bool {
- return diagName == name && d.Range.Start == pos
+ return diagName == name && d.Range.Start == loc.Range.Start
},
}
}
diff --git a/gopls/internal/lsp/regtest/wrappers.go b/gopls/internal/lsp/regtest/wrappers.go
index c206296..1207a14 100644
--- a/gopls/internal/lsp/regtest/wrappers.go
+++ b/gopls/internal/lsp/regtest/wrappers.go
@@ -113,37 +113,19 @@
}
}
-// RegexpRange returns the range of the first match for re in the buffer
-// specified by name, calling t.Fatal on any error. It first searches for the
-// position in open buffers, then in workspace files.
-func (e *Env) RegexpRange(name, re string) protocol.Range {
- e.T.Helper()
- rng, err := e.Editor.RegexpRange(name, re)
- if err == fake.ErrUnknownBuffer {
- rng, err = e.Sandbox.Workdir.RegexpRange(name, re)
- }
- if err != nil {
- e.T.Fatalf("RegexpRange: %v, %v", name, err)
- }
- return rng
-}
-
// RegexpSearch returns the starting position of the first match for re in the
// buffer specified by name, calling t.Fatal on any error. It first searches
// for the position in open buffers, then in workspace files.
-//
-// TODO(rfindley): RegexpSearch should return a protocol.Location (but that is
-// a large change).
-func (e *Env) RegexpSearch(name, re string) protocol.Position {
+func (e *Env) RegexpSearch(name, re string) protocol.Location {
e.T.Helper()
- pos, err := e.Editor.RegexpSearch(name, re)
+ loc, err := e.Editor.RegexpSearch(name, re)
if err == fake.ErrUnknownBuffer {
- pos, err = e.Sandbox.Workdir.RegexpSearch(name, re)
+ loc, err = e.Sandbox.Workdir.RegexpSearch(name, re)
}
if err != nil {
e.T.Fatalf("RegexpSearch: %v, %v for %q", name, err, re)
}
- return pos
+ return loc
}
// RegexpReplace replaces the first group in the first match of regexpStr with
@@ -172,13 +154,13 @@
// GoToDefinition goes to definition in the editor, calling t.Fatal on any
// error. It returns the path and position of the resulting jump.
-func (e *Env) GoToDefinition(name string, pos protocol.Position) (string, protocol.Position) {
+func (e *Env) GoToDefinition(loc protocol.Location) protocol.Location {
e.T.Helper()
- n, p, err := e.Editor.GoToDefinition(e.Ctx, name, pos)
+ loc, err := e.Editor.GoToDefinition(e.Ctx, loc)
if err != nil {
e.T.Fatal(err)
}
- return n, p
+ return loc
}
// FormatBuffer formats the editor buffer, calling t.Fatal on any error.
@@ -201,7 +183,8 @@
// ApplyQuickFixes processes the quickfix codeAction, calling t.Fatal on any error.
func (e *Env) ApplyQuickFixes(path string, diagnostics []protocol.Diagnostic) {
e.T.Helper()
- if err := e.Editor.ApplyQuickFixes(e.Ctx, path, nil, diagnostics); err != nil {
+ loc := protocol.Location{URI: e.Sandbox.Workdir.URI(path)} // zero Range => whole file
+ if err := e.Editor.ApplyQuickFixes(e.Ctx, loc, diagnostics); err != nil {
e.T.Fatal(err)
}
}
@@ -217,7 +200,8 @@
// GetQuickFixes returns the available quick fix code actions.
func (e *Env) GetQuickFixes(path string, diagnostics []protocol.Diagnostic) []protocol.CodeAction {
e.T.Helper()
- actions, err := e.Editor.GetQuickFixes(e.Ctx, path, nil, diagnostics)
+ loc := protocol.Location{URI: e.Sandbox.Workdir.URI(path)} // zero Range => whole file
+ actions, err := e.Editor.GetQuickFixes(e.Ctx, loc, diagnostics)
if err != nil {
e.T.Fatal(err)
}
@@ -225,13 +209,13 @@
}
// Hover in the editor, calling t.Fatal on any error.
-func (e *Env) Hover(name string, pos protocol.Position) (*protocol.MarkupContent, protocol.Position) {
+func (e *Env) Hover(loc protocol.Location) (*protocol.MarkupContent, protocol.Location) {
e.T.Helper()
- c, p, err := e.Editor.Hover(e.Ctx, name, pos)
+ c, loc, err := e.Editor.Hover(e.Ctx, loc)
if err != nil {
e.T.Fatal(err)
}
- return c, p
+ return c, loc
}
func (e *Env) DocumentLink(name string) []protocol.DocumentLink {
@@ -243,9 +227,9 @@
return links
}
-func (e *Env) DocumentHighlight(name string, pos protocol.Position) []protocol.DocumentHighlight {
+func (e *Env) DocumentHighlight(loc protocol.Location) []protocol.DocumentHighlight {
e.T.Helper()
- highlights, err := e.Editor.DocumentHighlight(e.Ctx, name, pos)
+ highlights, err := e.Editor.DocumentHighlight(e.Ctx, loc)
if err != nil {
e.T.Fatal(err)
}
@@ -398,9 +382,9 @@
}
// References wraps Editor.References, calling t.Fatal on any error.
-func (e *Env) References(path string, pos protocol.Position) []protocol.Location {
+func (e *Env) References(loc protocol.Location) []protocol.Location {
e.T.Helper()
- locations, err := e.Editor.References(e.Ctx, path, pos)
+ locations, err := e.Editor.References(e.Ctx, loc)
if err != nil {
e.T.Fatal(err)
}
@@ -408,17 +392,17 @@
}
// Rename wraps Editor.Rename, calling t.Fatal on any error.
-func (e *Env) Rename(path string, pos protocol.Position, newName string) {
+func (e *Env) Rename(loc protocol.Location, newName string) {
e.T.Helper()
- if err := e.Editor.Rename(e.Ctx, path, pos, newName); err != nil {
+ if err := e.Editor.Rename(e.Ctx, loc, newName); err != nil {
e.T.Fatal(err)
}
}
// Implementations wraps Editor.Implementations, calling t.Fatal on any error.
-func (e *Env) Implementations(path string, pos protocol.Position) []protocol.Location {
+func (e *Env) Implementations(loc protocol.Location) []protocol.Location {
e.T.Helper()
- locations, err := e.Editor.Implementations(e.Ctx, path, pos)
+ locations, err := e.Editor.Implementations(e.Ctx, loc)
if err != nil {
e.T.Fatal(err)
}
@@ -434,9 +418,9 @@
}
// Completion executes a completion request on the server.
-func (e *Env) Completion(path string, pos protocol.Position) *protocol.CompletionList {
+func (e *Env) Completion(loc protocol.Location) *protocol.CompletionList {
e.T.Helper()
- completions, err := e.Editor.Completion(e.Ctx, path, pos)
+ completions, err := e.Editor.Completion(e.Ctx, loc)
if err != nil {
e.T.Fatal(err)
}
@@ -445,9 +429,9 @@
// AcceptCompletion accepts a completion for the given item at the given
// position.
-func (e *Env) AcceptCompletion(path string, pos protocol.Position, item protocol.CompletionItem) {
+func (e *Env) AcceptCompletion(loc protocol.Location, item protocol.CompletionItem) {
e.T.Helper()
- if err := e.Editor.AcceptCompletion(e.Ctx, path, pos, item); err != nil {
+ if err := e.Editor.AcceptCompletion(e.Ctx, loc, item); err != nil {
e.T.Fatal(err)
}
}
@@ -456,7 +440,8 @@
// t.Fatal if there are errors.
func (e *Env) CodeAction(path string, diagnostics []protocol.Diagnostic) []protocol.CodeAction {
e.T.Helper()
- actions, err := e.Editor.CodeAction(e.Ctx, path, nil, diagnostics)
+ loc := protocol.Location{URI: e.Sandbox.Workdir.URI(path)} // no Range => whole file
+ actions, err := e.Editor.CodeAction(e.Ctx, loc, diagnostics)
if err != nil {
e.T.Fatal(err)
}
diff --git a/gopls/internal/regtest/bench/completion_test.go b/gopls/internal/regtest/bench/completion_test.go
index 1a464ca..ffccf34 100644
--- a/gopls/internal/regtest/bench/completion_test.go
+++ b/gopls/internal/regtest/bench/completion_test.go
@@ -57,8 +57,8 @@
}
// Run a completion to make sure the system is warm.
- pos := env.RegexpSearch(options.file, options.locationRegexp)
- completions := env.Completion(options.file, pos)
+ loc := env.RegexpSearch(options.file, options.locationRegexp)
+ completions := env.Completion(loc)
if testing.Verbose() {
fmt.Println("Results:")
@@ -77,7 +77,7 @@
if options.beforeCompletion != nil {
options.beforeCompletion(env)
}
- env.Completion(options.file, pos)
+ env.Completion(loc)
}
})
}
diff --git a/gopls/internal/regtest/bench/editor_features_test.go b/gopls/internal/regtest/bench/editor_features_test.go
index bba6baa..ea6727b 100644
--- a/gopls/internal/regtest/bench/editor_features_test.go
+++ b/gopls/internal/regtest/bench/editor_features_test.go
@@ -13,14 +13,14 @@
env := benchmarkEnv(b)
env.OpenFile("internal/imports/mod.go")
- pos := env.RegexpSearch("internal/imports/mod.go", "ModuleJSON")
- env.GoToDefinition("internal/imports/mod.go", pos)
+ loc := env.RegexpSearch("internal/imports/mod.go", "ModuleJSON")
+ env.GoToDefinition(loc)
env.Await(env.DoneWithOpen())
b.ResetTimer()
for i := 0; i < b.N; i++ {
- env.GoToDefinition("internal/imports/mod.go", pos)
+ env.GoToDefinition(loc)
}
}
@@ -28,14 +28,14 @@
env := benchmarkEnv(b)
env.OpenFile("internal/imports/mod.go")
- pos := env.RegexpSearch("internal/imports/mod.go", "gopathwalk")
- env.References("internal/imports/mod.go", pos)
+ loc := env.RegexpSearch("internal/imports/mod.go", "gopathwalk")
+ env.References(loc)
env.Await(env.DoneWithOpen())
b.ResetTimer()
for i := 0; i < b.N; i++ {
- env.References("internal/imports/mod.go", pos)
+ env.References(loc)
}
}
@@ -48,9 +48,9 @@
b.ResetTimer()
for i := 1; i < b.N; i++ {
- pos := env.RegexpSearch("internal/imports/mod.go", "gopathwalk")
+ loc := env.RegexpSearch("internal/imports/mod.go", "gopathwalk")
newName := fmt.Sprintf("%s%d", "gopathwalk", i)
- env.Rename("internal/imports/mod.go", pos, newName)
+ env.Rename(loc, newName)
}
}
@@ -58,13 +58,13 @@
env := benchmarkEnv(b)
env.OpenFile("internal/imports/mod.go")
- pos := env.RegexpSearch("internal/imports/mod.go", "initAllMods")
+ loc := env.RegexpSearch("internal/imports/mod.go", "initAllMods")
env.Await(env.DoneWithOpen())
b.ResetTimer()
for i := 0; i < b.N; i++ {
- env.Implementations("internal/imports/mod.go", pos)
+ env.Implementations(loc)
}
}
@@ -72,12 +72,12 @@
env := benchmarkEnv(b)
env.OpenFile("internal/imports/mod.go")
- pos := env.RegexpSearch("internal/imports/mod.go", "bytes")
+ loc := env.RegexpSearch("internal/imports/mod.go", "bytes")
env.Await(env.DoneWithOpen())
b.ResetTimer()
for i := 0; i < b.N; i++ {
- env.Hover("internal/imports/mod.go", pos)
+ env.Hover(loc)
}
}
diff --git a/gopls/internal/regtest/completion/completion18_test.go b/gopls/internal/regtest/completion/completion18_test.go
index b9edf06..18e81bc 100644
--- a/gopls/internal/regtest/completion/completion18_test.go
+++ b/gopls/internal/regtest/completion/completion18_test.go
@@ -42,9 +42,9 @@
env.OpenFile("main.go")
env.Await(env.DoneWithOpen())
for _, tst := range tests {
- pos := env.RegexpSearch("main.go", tst.pat)
- pos.Character += uint32(protocol.UTF16Len([]byte(tst.pat)))
- completions := env.Completion("main.go", pos)
+ loc := env.RegexpSearch("main.go", tst.pat)
+ loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte(tst.pat)))
+ completions := env.Completion(loc)
result := compareCompletionLabels(tst.want, completions.Items)
if result != "" {
t.Errorf("%s: wanted %v", result, tst.want)
@@ -109,9 +109,9 @@
for _, test := range tests {
env.OpenFile(test.file)
env.Await(env.DoneWithOpen())
- pos := env.RegexpSearch(test.file, test.pat)
- pos.Character += test.offset // character user just typed? will type?
- completions := env.Completion(test.file, pos)
+ loc := env.RegexpSearch(test.file, test.pat)
+ loc.Range.Start.Character += test.offset // character user just typed? will type?
+ completions := env.Completion(loc)
result := compareCompletionLabels(test.want, completions.Items)
if result != "" {
t.Errorf("pat %q %q", test.pat, result)
diff --git a/gopls/internal/regtest/completion/completion_test.go b/gopls/internal/regtest/completion/completion_test.go
index 6d0bfc5..7d9214f 100644
--- a/gopls/internal/regtest/completion/completion_test.go
+++ b/gopls/internal/regtest/completion/completion_test.go
@@ -176,7 +176,7 @@
env.Await(env.DoneWithChangeWatchedFiles())
}
env.OpenFile(tc.filename)
- completions := env.Completion(tc.filename, env.RegexpSearch(tc.filename, tc.triggerRegexp))
+ completions := env.Completion(env.RegexpSearch(tc.filename, tc.triggerRegexp))
// Check that the completion item suggestions are in the range
// of the file. {Start,End}.Line are zero-based.
@@ -191,12 +191,12 @@
}
if tc.want != nil {
- expectedRng := env.RegexpRange(tc.filename, tc.editRegexp)
+ expectedLoc := env.RegexpSearch(tc.filename, tc.editRegexp)
for _, item := range completions.Items {
gotRng := item.TextEdit.Range
- if expectedRng != gotRng {
+ if expectedLoc.Range != gotRng {
t.Errorf("unexpected completion range for completion item %s: got %v, want %v",
- item.Label, gotRng, expectedRng)
+ item.Label, gotRng, expectedLoc.Range)
}
}
}
@@ -223,7 +223,7 @@
want := []string{"ma", "ma_test", "main", "math", "math_test"}
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("math/add.go")
- completions := env.Completion("math/add.go", env.RegexpSearch("math/add.go", "package ma()"))
+ completions := env.Completion(env.RegexpSearch("math/add.go", "package ma()"))
diff := compareCompletionLabels(want, completions.Items)
if diff != "" {
@@ -293,19 +293,19 @@
// Trigger unimported completions for the example.com/blah package.
env.OpenFile("main.go")
env.Await(env.DoneWithOpen())
- pos := env.RegexpSearch("main.go", "ah")
- completions := env.Completion("main.go", pos)
+ loc := env.RegexpSearch("main.go", "ah")
+ completions := env.Completion(loc)
if len(completions.Items) == 0 {
t.Fatalf("no completion items")
}
- env.AcceptCompletion("main.go", pos, completions.Items[0])
+ env.AcceptCompletion(loc, completions.Items[0])
env.Await(env.DoneWithChange())
// Trigger completions once again for the blah.<> selector.
env.RegexpReplace("main.go", "_ = blah", "_ = blah.")
env.Await(env.DoneWithChange())
- pos = env.RegexpSearch("main.go", "\n}")
- completions = env.Completion("main.go", pos)
+ loc = env.RegexpSearch("main.go", "\n}")
+ completions = env.Completion(loc)
if len(completions.Items) != 1 {
t.Fatalf("expected 1 completion item, got %v", len(completions.Items))
}
@@ -313,7 +313,7 @@
if item.Label != "Name" {
t.Fatalf("expected completion item blah.Name, got %v", item.Label)
}
- env.AcceptCompletion("main.go", pos, item)
+ env.AcceptCompletion(loc, item)
// Await the diagnostics to add example.com/blah to the go.mod file.
env.AfterChange(
@@ -381,7 +381,7 @@
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("foo.go")
- completions := env.Completion("foo.go", env.RegexpSearch("foo.go", `if s\.()`))
+ completions := env.Completion(env.RegexpSearch("foo.go", `if s\.()`))
diff := compareCompletionLabels([]string{"i"}, completions.Items)
if diff != "" {
t.Fatal(diff)
@@ -441,7 +441,7 @@
{`var _ e = xxxx()`, []string{"xxxxc", "xxxxd", "xxxxe"}},
}
for _, tt := range tests {
- completions := env.Completion("main.go", env.RegexpSearch("main.go", tt.re))
+ completions := env.Completion(env.RegexpSearch("main.go", tt.re))
diff := compareCompletionLabels(tt.want, completions.Items)
if diff != "" {
t.Errorf("%s: %s", tt.re, diff)
@@ -474,9 +474,9 @@
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("prog.go")
- pos := env.RegexpSearch("prog.go", "if fooF")
- pos.Character += uint32(protocol.UTF16Len([]byte("if fooF")))
- completions := env.Completion("prog.go", pos)
+ loc := env.RegexpSearch("prog.go", "if fooF")
+ loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte("if fooF")))
+ completions := env.Completion(loc)
diff := compareCompletionLabels([]string{"fooFunc"}, completions.Items)
if diff != "" {
t.Error(diff)
@@ -484,9 +484,9 @@
if completions.Items[0].Tags == nil {
t.Errorf("expected Tags to show deprecation %#v", diff[0])
}
- pos = env.RegexpSearch("prog.go", "= badP")
- pos.Character += uint32(protocol.UTF16Len([]byte("= badP")))
- completions = env.Completion("prog.go", pos)
+ loc = env.RegexpSearch("prog.go", "= badP")
+ loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte("= badP")))
+ completions = env.Completion(loc)
diff = compareCompletionLabels([]string{"badPi"}, completions.Items)
if diff != "" {
t.Error(diff)
@@ -520,12 +520,12 @@
// Trigger unimported completions for the example.com/blah package.
env.OpenFile("main.go")
env.Await(env.DoneWithOpen())
- pos := env.RegexpSearch("main.go", "Sqr()")
- completions := env.Completion("main.go", pos)
+ loc := env.RegexpSearch("main.go", "Sqr()")
+ completions := env.Completion(loc)
if len(completions.Items) == 0 {
t.Fatalf("no completion items")
}
- env.AcceptCompletion("main.go", pos, completions.Items[0])
+ env.AcceptCompletion(loc, completions.Items[0])
env.Await(env.DoneWithChange())
got := env.BufferText("main.go")
want := "package main\r\n\r\nimport (\r\n\t\"fmt\"\r\n\t\"math\"\r\n)\r\n\r\nfunc main() {\r\n\tfmt.Println(\"a\")\r\n\tmath.Sqrt(${1:})\r\n}\r\n"
@@ -574,9 +574,9 @@
env.Await(env.DoneWithOpen())
for _, tst := range tests {
env.SetBufferContent(fname, "package foo\n"+tst.line)
- pos := env.RegexpSearch(fname, tst.pat)
- pos.Character += uint32(protocol.UTF16Len([]byte(tst.pat)))
- completions := env.Completion(fname, pos)
+ loc := env.RegexpSearch(fname, tst.pat)
+ loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte(tst.pat)))
+ completions := env.Completion(loc)
result := compareCompletionLabels(tst.want, completions.Items)
if result != "" {
t.Errorf("\npat:%q line:%q failed: %s:%q", tst.pat, tst.line, result, tst.want)
@@ -656,14 +656,14 @@
tst.after = strings.Trim(tst.after, "\n")
env.SetBufferContent("foo_test.go", tst.before)
- pos := env.RegexpSearch("foo_test.go", tst.name)
- pos.Character = uint32(protocol.UTF16Len([]byte(tst.name)))
- completions := env.Completion("foo_test.go", pos)
+ loc := env.RegexpSearch("foo_test.go", tst.name)
+ loc.Range.Start.Character = uint32(protocol.UTF16Len([]byte(tst.name)))
+ completions := env.Completion(loc)
if len(completions.Items) == 0 {
t.Fatalf("no completion items")
}
- env.AcceptCompletion("foo_test.go", pos, completions.Items[0])
+ env.AcceptCompletion(loc, completions.Items[0])
env.Await(env.DoneWithChange())
if buf := env.BufferText("foo_test.go"); buf != tst.after {
t.Errorf("%s:incorrect completion: got %q, want %q", tst.name, buf, tst.after)
@@ -708,7 +708,7 @@
{`use ./dir/foobar/()`, []string{}},
}
for _, tt := range tests {
- completions := env.Completion("go.work", env.RegexpSearch("go.work", tt.re))
+ completions := env.Completion(env.RegexpSearch("go.work", tt.re))
diff := compareCompletionLabels(tt.want, completions.Items)
if diff != "" {
t.Errorf("%s: %s", tt.re, diff)
diff --git a/gopls/internal/regtest/completion/postfix_snippet_test.go b/gopls/internal/regtest/completion/postfix_snippet_test.go
index 6d2be05..df69703 100644
--- a/gopls/internal/regtest/completion/postfix_snippet_test.go
+++ b/gopls/internal/regtest/completion/postfix_snippet_test.go
@@ -447,13 +447,13 @@
env.SetBufferContent("foo.go", c.before)
- pos := env.RegexpSearch("foo.go", "\n}")
- completions := env.Completion("foo.go", pos)
+ loc := env.RegexpSearch("foo.go", "\n}")
+ completions := env.Completion(loc)
if len(completions.Items) != 1 {
t.Fatalf("expected one completion, got %v", completions.Items)
}
- env.AcceptCompletion("foo.go", pos, completions.Items[0])
+ env.AcceptCompletion(loc, completions.Items[0])
if buf := env.BufferText("foo.go"); buf != c.after {
t.Errorf("\nGOT:\n%s\nEXPECTED:\n%s", buf, c.after)
diff --git a/gopls/internal/regtest/diagnostics/builtin_test.go b/gopls/internal/regtest/diagnostics/builtin_test.go
index 193bbe0..935a7f9 100644
--- a/gopls/internal/regtest/diagnostics/builtin_test.go
+++ b/gopls/internal/regtest/diagnostics/builtin_test.go
@@ -26,9 +26,9 @@
`
Run(t, src, func(t *testing.T, env *Env) {
env.OpenFile("a.go")
- name, _ := env.GoToDefinition("a.go", env.RegexpSearch("a.go", "iota"))
- if !strings.HasSuffix(name, "builtin.go") {
- t.Fatalf("jumped to %q, want builtin.go", name)
+ loc := env.GoToDefinition(env.RegexpSearch("a.go", "iota"))
+ if !strings.HasSuffix(string(loc.URI), "builtin.go") {
+ t.Fatalf("jumped to %q, want builtin.go", loc.URI)
}
env.AfterChange(NoDiagnostics(ForFile("builtin.go")))
})
diff --git a/gopls/internal/regtest/misc/call_hierarchy_test.go b/gopls/internal/regtest/misc/call_hierarchy_test.go
index b807ee9..f0f5d4a 100644
--- a/gopls/internal/regtest/misc/call_hierarchy_test.go
+++ b/gopls/internal/regtest/misc/call_hierarchy_test.go
@@ -23,11 +23,11 @@
// TODO(rfindley): this could probably just be a marker test.
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("p.go")
- pos := env.RegexpSearch("p.go", "pkg")
+ loc := env.RegexpSearch("p.go", "pkg")
var params protocol.CallHierarchyPrepareParams
- params.TextDocument.URI = env.Sandbox.Workdir.URI("p.go")
- params.Position = pos
+ params.TextDocument.URI = loc.URI
+ params.Position = loc.Range.Start
// Check that this doesn't panic.
env.Editor.Server.PrepareCallHierarchy(env.Ctx, ¶ms)
diff --git a/gopls/internal/regtest/misc/definition_test.go b/gopls/internal/regtest/misc/definition_test.go
index 0186d50..cad69c1 100644
--- a/gopls/internal/regtest/misc/definition_test.go
+++ b/gopls/internal/regtest/misc/definition_test.go
@@ -38,12 +38,13 @@
func TestGoToInternalDefinition(t *testing.T) {
Run(t, internalDefinition, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
- name, pos := env.GoToDefinition("main.go", env.RegexpSearch("main.go", "message"))
+ loc := env.GoToDefinition(env.RegexpSearch("main.go", "message"))
+ name := env.Sandbox.Workdir.URIToPath(loc.URI)
if want := "const.go"; name != want {
t.Errorf("GoToDefinition: got file %q, want %q", name, want)
}
- if want := env.RegexpSearch("const.go", "message"); pos != want {
- t.Errorf("GoToDefinition: got position %v, want %v", pos, want)
+ if want := env.RegexpSearch("const.go", "message"); loc != want {
+ t.Errorf("GoToDefinition: got location %v, want %v", loc, want)
}
})
}
@@ -65,19 +66,21 @@
func TestGoToStdlibDefinition_Issue37045(t *testing.T) {
Run(t, stdlibDefinition, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
- name, pos := env.GoToDefinition("main.go", env.RegexpSearch("main.go", `fmt.(Printf)`))
+ loc := env.GoToDefinition(env.RegexpSearch("main.go", `fmt.(Printf)`))
+ name := env.Sandbox.Workdir.URIToPath(loc.URI)
if got, want := path.Base(name), "print.go"; got != want {
t.Errorf("GoToDefinition: got file %q, want %q", name, want)
}
// Test that we can jump to definition from outside our workspace.
// See golang.org/issues/37045.
- newName, newPos := env.GoToDefinition(name, pos)
+ newLoc := env.GoToDefinition(loc)
+ newName := env.Sandbox.Workdir.URIToPath(newLoc.URI)
if newName != name {
t.Errorf("GoToDefinition is not idempotent: got %q, want %q", newName, name)
}
- if newPos != pos {
- t.Errorf("GoToDefinition is not idempotent: got %v, want %v", newPos, pos)
+ if newLoc != loc {
+ t.Errorf("GoToDefinition is not idempotent: got %v, want %v", newLoc, loc)
}
})
}
@@ -85,23 +88,24 @@
func TestUnexportedStdlib_Issue40809(t *testing.T) {
Run(t, stdlibDefinition, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
- name, _ := env.GoToDefinition("main.go", env.RegexpSearch("main.go", `fmt.(Printf)`))
+ loc := env.GoToDefinition(env.RegexpSearch("main.go", `fmt.(Printf)`))
+ name := env.Sandbox.Workdir.URIToPath(loc.URI)
- pos := env.RegexpSearch(name, `:=\s*(newPrinter)\(\)`)
+ loc = env.RegexpSearch(name, `:=\s*(newPrinter)\(\)`)
// Check that we can find references on a reference
- refs := env.References(name, pos)
+ refs := env.References(loc)
if len(refs) < 5 {
t.Errorf("expected 5+ references to newPrinter, found: %#v", refs)
}
- name, pos = env.GoToDefinition(name, pos)
- content, _ := env.Hover(name, pos)
+ loc = env.GoToDefinition(loc)
+ content, _ := env.Hover(loc)
if !strings.Contains(content.Value, "newPrinter") {
t.Fatal("definition of newPrinter went to the incorrect place")
}
// And on the definition too.
- refs = env.References(name, pos)
+ refs = env.References(loc)
if len(refs) < 5 {
t.Errorf("expected 5+ references to newPrinter, found: %#v", refs)
}
@@ -125,7 +129,7 @@
}`
Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
- content, _ := env.Hover("main.go", env.RegexpSearch("main.go", "Error"))
+ content, _ := env.Hover(env.RegexpSearch("main.go", "Error"))
if content == nil {
t.Fatalf("nil hover content for Error")
}
@@ -163,10 +167,10 @@
Settings{"importShortcut": tt.importShortcut},
).Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
- file, pos := env.GoToDefinition("main.go", env.RegexpSearch("main.go", `"fmt"`))
- if !tt.wantDef && (file != "" || pos != (protocol.Position{})) {
- t.Fatalf("expected no definition, got one: %s:%v", file, pos)
- } else if tt.wantDef && file == "" && pos == (protocol.Position{}) {
+ loc := env.GoToDefinition(env.RegexpSearch("main.go", `"fmt"`))
+ if !tt.wantDef && (loc != (protocol.Location{})) {
+ t.Fatalf("expected no definition, got one: %v", loc)
+ } else if tt.wantDef && loc == (protocol.Location{}) {
t.Fatalf("expected definition, got none")
}
links := env.DocumentLink("main.go")
@@ -213,7 +217,7 @@
Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
- _, pos, err := env.Editor.GoToTypeDefinition(env.Ctx, "main.go", env.RegexpSearch("main.go", tt.re))
+ loc, err := env.Editor.GoToTypeDefinition(env.Ctx, env.RegexpSearch("main.go", tt.re))
if tt.wantError {
if err == nil {
t.Fatal("expected error, got nil")
@@ -224,9 +228,9 @@
t.Fatalf("expected nil error, got %s", err)
}
- typePos := env.RegexpSearch("main.go", tt.wantTypeRe)
- if pos != typePos {
- t.Errorf("invalid pos: want %+v, got %+v", typePos, pos)
+ typeLoc := env.RegexpSearch("main.go", tt.wantTypeRe)
+ if loc != typeLoc {
+ t.Errorf("invalid pos: want %+v, got %+v", typeLoc, loc)
}
})
})
@@ -269,7 +273,7 @@
`
Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("client/client_role_test.go")
- env.GoToDefinition("client/client_role_test.go", env.RegexpSearch("client/client_role_test.go", "RoleSetup"))
+ env.GoToDefinition(env.RegexpSearch("client/client_role_test.go", "RoleSetup"))
})
}
@@ -327,10 +331,11 @@
}
env.OpenFile("a.go")
- refPos := env.RegexpSearch("a.go", "K") // find "b.K" reference
+ refLoc := env.RegexpSearch("a.go", "K") // find "b.K" reference
// Initially, b.K is defined in the module cache.
- gotFile, _ := env.GoToDefinition("a.go", refPos)
+ gotLoc := env.GoToDefinition(refLoc)
+ gotFile := env.Sandbox.Workdir.URIToPath(gotLoc.URI)
wantCache := filepath.ToSlash(env.Sandbox.GOPATH()) + "/pkg/mod/other.com/b@v1.0.0/b.go"
if gotFile != wantCache {
t.Errorf("GoToDefinition, before: got file %q, want %q", gotFile, wantCache)
@@ -345,7 +350,7 @@
env.Await(env.DoneWithChangeWatchedFiles())
// Now, b.K is defined in the vendor tree.
- gotFile, _ = env.GoToDefinition("a.go", refPos)
+ gotLoc = env.GoToDefinition(refLoc)
wantVendor := "vendor/other.com/b/b.go"
if gotFile != wantVendor {
t.Errorf("GoToDefinition, after go mod vendor: got file %q, want %q", gotFile, wantVendor)
@@ -364,7 +369,8 @@
env.Await(env.DoneWithChangeWatchedFiles())
// b.K is once again defined in the module cache.
- gotFile, _ = env.GoToDefinition("a.go", refPos)
+ gotLoc = env.GoToDefinition(gotLoc)
+ gotFile = env.Sandbox.Workdir.URIToPath(gotLoc.URI)
if gotFile != wantCache {
t.Errorf("GoToDefinition, after rm -rf vendor: got file %q, want %q", gotFile, wantCache)
}
diff --git a/gopls/internal/regtest/misc/extract_test.go b/gopls/internal/regtest/misc/extract_test.go
index f159e5e..23efffb 100644
--- a/gopls/internal/regtest/misc/extract_test.go
+++ b/gopls/internal/regtest/misc/extract_test.go
@@ -28,11 +28,8 @@
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
-
- start := env.RegexpSearch("main.go", "a := 5")
- end := env.RegexpSearch("main.go", "return a")
-
- actions, err := env.Editor.CodeAction(env.Ctx, "main.go", &protocol.Range{Start: start, End: end}, nil)
+ loc := env.RegexpSearch("main.go", `a := 5\n.*return a`)
+ actions, err := env.Editor.CodeAction(env.Ctx, loc, nil)
if err != nil {
t.Fatal(err)
}
@@ -53,8 +50,7 @@
want := `package main
func Foo() int {
- a := newFunction()
- return a
+ return newFunction()
}
func newFunction() int {
diff --git a/gopls/internal/regtest/misc/failures_test.go b/gopls/internal/regtest/misc/failures_test.go
index 9ab456d..42aa372 100644
--- a/gopls/internal/regtest/misc/failures_test.go
+++ b/gopls/internal/regtest/misc/failures_test.go
@@ -34,7 +34,7 @@
}`
Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
- content, _ := env.Hover("main.go", env.RegexpSearch("main.go", "Error"))
+ content, _ := env.Hover(env.RegexpSearch("main.go", "Error"))
if content == nil {
t.Fatalf("Hover('Error') returned nil")
}
diff --git a/gopls/internal/regtest/misc/fix_test.go b/gopls/internal/regtest/misc/fix_test.go
index 42096a8..7a5e530 100644
--- a/gopls/internal/regtest/misc/fix_test.go
+++ b/gopls/internal/regtest/misc/fix_test.go
@@ -34,11 +34,7 @@
`
Run(t, basic, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
- pos := env.RegexpSearch("main.go", "Info{}")
- if err := env.Editor.RefactorRewrite(env.Ctx, "main.go", &protocol.Range{
- Start: pos,
- End: pos,
- }); err != nil {
+ if err := env.Editor.RefactorRewrite(env.Ctx, env.RegexpSearch("main.go", "Info{}")); err != nil {
t.Fatal(err)
}
want := `package main
diff --git a/gopls/internal/regtest/misc/highlight_test.go b/gopls/internal/regtest/misc/highlight_test.go
index 587e7d6..8835d60 100644
--- a/gopls/internal/regtest/misc/highlight_test.go
+++ b/gopls/internal/regtest/misc/highlight_test.go
@@ -30,9 +30,9 @@
Run(t, mod, func(t *testing.T, env *Env) {
const file = "main.go"
env.OpenFile(file)
- _, pos := env.GoToDefinition(file, env.RegexpSearch(file, `var (A) string`))
+ loc := env.GoToDefinition(env.RegexpSearch(file, `var (A) string`))
- checkHighlights(env, file, pos, 3)
+ checkHighlights(env, loc, 3)
})
}
@@ -53,10 +53,11 @@
Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
- file, _ := env.GoToDefinition("main.go", env.RegexpSearch("main.go", `fmt\.(Printf)`))
- pos := env.RegexpSearch(file, `func Printf\((format) string`)
+ defLoc := env.GoToDefinition(env.RegexpSearch("main.go", `fmt\.(Printf)`))
+ file := env.Sandbox.Workdir.URIToPath(defLoc.URI)
+ loc := env.RegexpSearch(file, `func Printf\((format) string`)
- checkHighlights(env, file, pos, 2)
+ checkHighlights(env, loc, 2)
})
}
@@ -112,26 +113,28 @@
).Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
- file, _ := env.GoToDefinition("main.go", env.RegexpSearch("main.go", `"example.com/global"`))
- pos := env.RegexpSearch(file, `const (A)`)
- checkHighlights(env, file, pos, 4)
+ defLoc := env.GoToDefinition(env.RegexpSearch("main.go", `"example.com/global"`))
+ file := env.Sandbox.Workdir.URIToPath(defLoc.URI)
+ loc := env.RegexpSearch(file, `const (A)`)
+ checkHighlights(env, loc, 4)
- file, _ = env.GoToDefinition("main.go", env.RegexpSearch("main.go", `"example.com/local"`))
- pos = env.RegexpSearch(file, `const (b)`)
- checkHighlights(env, file, pos, 5)
+ defLoc = env.GoToDefinition(env.RegexpSearch("main.go", `"example.com/local"`))
+ file = env.Sandbox.Workdir.URIToPath(defLoc.URI)
+ loc = env.RegexpSearch(file, `const (b)`)
+ checkHighlights(env, loc, 5)
})
}
-func checkHighlights(env *Env, file string, pos protocol.Position, highlightCount int) {
+func checkHighlights(env *Env, loc protocol.Location, highlightCount int) {
t := env.T
t.Helper()
- highlights := env.DocumentHighlight(file, pos)
+ highlights := env.DocumentHighlight(loc)
if len(highlights) != highlightCount {
t.Fatalf("expected %v highlight(s), got %v", highlightCount, len(highlights))
}
- references := env.References(file, pos)
+ references := env.References(loc)
if len(highlights) != len(references) {
t.Fatalf("number of highlights and references is expected to be equal: %v != %v", len(highlights), len(references))
}
diff --git a/gopls/internal/regtest/misc/hover_test.go b/gopls/internal/regtest/misc/hover_test.go
index 013c4d1..6b1d243 100644
--- a/gopls/internal/regtest/misc/hover_test.go
+++ b/gopls/internal/regtest/misc/hover_test.go
@@ -59,21 +59,22 @@
ProxyFiles(proxy),
).Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
- mixedPos := env.RegexpSearch("main.go", "Mixed")
- got, _ := env.Hover("main.go", mixedPos)
+ mixedLoc := env.RegexpSearch("main.go", "Mixed")
+ got, _ := env.Hover(mixedLoc)
if !strings.Contains(got.Value, "unexported") {
t.Errorf("Workspace hover: missing expected field 'unexported'. Got:\n%q", got.Value)
}
- cacheFile, _ := env.GoToDefinition("main.go", mixedPos)
- argPos := env.RegexpSearch(cacheFile, "printMixed.*(Mixed)")
- got, _ = env.Hover(cacheFile, argPos)
+ cacheLoc := env.GoToDefinition(mixedLoc)
+ cacheFile := env.Sandbox.Workdir.URIToPath(cacheLoc.URI)
+ argLoc := env.RegexpSearch(cacheFile, "printMixed.*(Mixed)")
+ got, _ = env.Hover(argLoc)
if !strings.Contains(got.Value, "unexported") {
t.Errorf("Non-workspace hover: missing expected field 'unexported'. Got:\n%q", got.Value)
}
- exportedFieldPos := env.RegexpSearch("main.go", "Exported")
- got, _ = env.Hover("main.go", exportedFieldPos)
+ exportedFieldLoc := env.RegexpSearch("main.go", "Exported")
+ got, _ = env.Hover(exportedFieldLoc)
if !strings.Contains(got.Value, "comment") {
t.Errorf("Workspace hover: missing comment for field 'Exported'. Got:\n%q", got.Value)
}
@@ -97,13 +98,13 @@
Run(t, source, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
hexExpected := "58190"
- got, _ := env.Hover("main.go", env.RegexpSearch("main.go", "hex"))
+ got, _ := env.Hover(env.RegexpSearch("main.go", "hex"))
if got != nil && !strings.Contains(got.Value, hexExpected) {
t.Errorf("Hover: missing expected field '%s'. Got:\n%q", hexExpected, got.Value)
}
binExpected := "73"
- got, _ = env.Hover("main.go", env.RegexpSearch("main.go", "bigBin"))
+ got, _ = env.Hover(env.RegexpSearch("main.go", "bigBin"))
if got != nil && !strings.Contains(got.Value, binExpected) {
t.Errorf("Hover: missing expected field '%s'. Got:\n%q", binExpected, got.Value)
}
@@ -119,7 +120,7 @@
type Example struct`
Run(t, source, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
- env.Editor.Hover(env.Ctx, "main.go", env.RegexpSearch("main.go", "Example"))
+ env.Editor.Hover(env.Ctx, env.RegexpSearch("main.go", "Example"))
})
}
@@ -135,7 +136,7 @@
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
env.EditBuffer("main.go", fake.NewEdit(0, 0, 1, 0, "package main\nfunc main() {\nconst x = `\nfoo\n`\n}"))
- env.Editor.Hover(env.Ctx, "main.go", env.RegexpSearch("main.go", "foo"))
+ env.Editor.Hover(env.Ctx, env.RegexpSearch("main.go", "foo"))
})
}
@@ -203,7 +204,7 @@
Run(t, source, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
for _, test := range tests {
- got, _ := env.Hover("main.go", env.RegexpSearch("main.go", test.hoverPackage))
+ got, _ := env.Hover(env.RegexpSearch("main.go", test.hoverPackage))
if got == nil {
t.Error("nil hover for", test.hoverPackage)
continue
@@ -213,7 +214,7 @@
}
}
- got, _ := env.Hover("main.go", env.RegexpSearch("main.go", "mod.com/lib4"))
+ got, _ := env.Hover(env.RegexpSearch("main.go", "mod.com/lib4"))
if got != nil {
t.Errorf("Hover: got:\n%q\nwant:\n%v", got.Value, nil)
}
@@ -250,7 +251,7 @@
env.OpenFile("a.go")
z := env.RegexpSearch("a.go", "lib")
t.Logf("%#v", z)
- got, _ := env.Hover("a.go", env.RegexpSearch("a.go", "lib"))
+ got, _ := env.Hover(env.RegexpSearch("a.go", "lib"))
if strings.Contains(got.Value, "{#hdr-") {
t.Errorf("Hover: got {#hdr- tag:\n%q", got)
}
@@ -266,6 +267,6 @@
`
Run(t, source, func(t *testing.T, env *Env) {
env.OpenFile("go.mod")
- env.Hover("go.mod", env.RegexpSearch("go.mod", "go")) // no panic
+ env.Hover(env.RegexpSearch("go.mod", "go")) // no panic
})
}
diff --git a/gopls/internal/regtest/misc/imports_test.go b/gopls/internal/regtest/misc/imports_test.go
index 513171a..bea9552 100644
--- a/gopls/internal/regtest/misc/imports_test.go
+++ b/gopls/internal/regtest/misc/imports_test.go
@@ -159,7 +159,8 @@
env.AfterChange(Diagnostics(env.AtRegexp("main.go", `y.Y`)))
env.SaveBuffer("main.go")
env.AfterChange(NoDiagnostics(ForFile("main.go")))
- path, _ := env.GoToDefinition("main.go", env.RegexpSearch("main.go", `y.(Y)`))
+ loc := env.GoToDefinition(env.RegexpSearch("main.go", `y.(Y)`))
+ path := env.Sandbox.Workdir.URIToPath(loc.URI)
if !strings.HasPrefix(path, filepath.ToSlash(modcache)) {
t.Errorf("found module dependency outside of GOMODCACHE: got %v, wanted subdir of %v", path, filepath.ToSlash(modcache))
}
diff --git a/gopls/internal/regtest/misc/link_test.go b/gopls/internal/regtest/misc/link_test.go
index b782fff..8a64c54 100644
--- a/gopls/internal/regtest/misc/link_test.go
+++ b/gopls/internal/regtest/misc/link_test.go
@@ -53,11 +53,11 @@
pkgLink := "https://pkg.go.dev/import.test@v1.2.3/pkg"
// First, check that we get the expected links via hover and documentLink.
- content, _ := env.Hover("main.go", env.RegexpSearch("main.go", "pkg.Hello"))
+ content, _ := env.Hover(env.RegexpSearch("main.go", "pkg.Hello"))
if content == nil || !strings.Contains(content.Value, pkgLink) {
t.Errorf("hover: got %v in main.go, want contains %q", content, pkgLink)
}
- content, _ = env.Hover("go.mod", env.RegexpSearch("go.mod", "import.test"))
+ content, _ = env.Hover(env.RegexpSearch("go.mod", "import.test"))
if content == nil || !strings.Contains(content.Value, pkgLink) {
t.Errorf("hover: got %v in go.mod, want contains %q", content, pkgLink)
}
@@ -76,11 +76,11 @@
env.ChangeConfiguration(cfg)
// Finally, verify that the links are gone.
- content, _ = env.Hover("main.go", env.RegexpSearch("main.go", "pkg.Hello"))
+ content, _ = env.Hover(env.RegexpSearch("main.go", "pkg.Hello"))
if content == nil || strings.Contains(content.Value, pkgLink) {
t.Errorf("hover: got %v in main.go, want non-empty hover without %q", content, pkgLink)
}
- content, _ = env.Hover("go.mod", env.RegexpSearch("go.mod", "import.test"))
+ content, _ = env.Hover(env.RegexpSearch("go.mod", "import.test"))
if content == nil || strings.Contains(content.Value, modLink) {
t.Errorf("hover: got %v in go.mod, want contains %q", content, modLink)
}
diff --git a/gopls/internal/regtest/misc/multiple_adhoc_test.go b/gopls/internal/regtest/misc/multiple_adhoc_test.go
index 400e784..981b74e 100644
--- a/gopls/internal/regtest/misc/multiple_adhoc_test.go
+++ b/gopls/internal/regtest/misc/multiple_adhoc_test.go
@@ -30,14 +30,14 @@
}
`, func(t *testing.T, env *Env) {
env.OpenFile("a/a.go")
- if list := env.Completion("a/a.go", env.RegexpSearch("a/a.go", "Println")); list == nil || len(list.Items) == 0 {
+ if list := env.Completion(env.RegexpSearch("a/a.go", "Println")); list == nil || len(list.Items) == 0 {
t.Fatal("expected completions, got none")
}
env.OpenFile("a/b.go")
- if list := env.Completion("a/b.go", env.RegexpSearch("a/b.go", "Println")); list == nil || len(list.Items) == 0 {
+ if list := env.Completion(env.RegexpSearch("a/b.go", "Println")); list == nil || len(list.Items) == 0 {
t.Fatal("expected completions, got none")
}
- if list := env.Completion("a/a.go", env.RegexpSearch("a/a.go", "Println")); list == nil || len(list.Items) == 0 {
+ if list := env.Completion(env.RegexpSearch("a/a.go", "Println")); list == nil || len(list.Items) == 0 {
t.Fatal("expected completions, got none")
}
})
diff --git a/gopls/internal/regtest/misc/references_test.go b/gopls/internal/regtest/misc/references_test.go
index 8e99a1c..e1f5d8e 100644
--- a/gopls/internal/regtest/misc/references_test.go
+++ b/gopls/internal/regtest/misc/references_test.go
@@ -34,8 +34,8 @@
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
- file, pos := env.GoToDefinition("main.go", env.RegexpSearch("main.go", `fmt.(Print)`))
- refs, err := env.Editor.References(env.Ctx, file, pos)
+ loc := env.GoToDefinition(env.RegexpSearch("main.go", `fmt.(Print)`))
+ refs, err := env.Editor.References(env.Ctx, loc)
if err != nil {
t.Fatal(err)
}
@@ -79,8 +79,8 @@
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
- file, pos := env.GoToDefinition("main.go", env.RegexpSearch("main.go", `Error`))
- refs, err := env.Editor.References(env.Ctx, file, pos)
+ loc := env.GoToDefinition(env.RegexpSearch("main.go", `Error`))
+ refs, err := env.Editor.References(env.Ctx, loc)
if err != nil {
t.Fatalf("references on (*s).Error failed: %v", err)
}
@@ -157,10 +157,10 @@
`
Run(t, files, func(t *testing.T, env *Env) {
for _, test := range tests {
- f := fmt.Sprintf("%s/a.go", test.packageName)
- env.OpenFile(f)
- pos := env.RegexpSearch(f, test.packageName)
- refs := env.References(fmt.Sprintf("%s/a.go", test.packageName), pos)
+ file := fmt.Sprintf("%s/a.go", test.packageName)
+ env.OpenFile(file)
+ loc := env.RegexpSearch(file, test.packageName)
+ refs := env.References(loc)
if len(refs) != test.wantRefCount {
// TODO(adonovan): make this assertion less maintainer-hostile.
t.Fatalf("got %v reference(s), want %d", len(refs), test.wantRefCount)
@@ -277,8 +277,8 @@
}
for _, test := range refTests {
- pos := env.RegexpSearch("foo/foo.go", test.re)
- refs := env.References("foo/foo.go", pos)
+ loc := env.RegexpSearch("foo/foo.go", test.re)
+ refs := env.References(loc)
got := fileLocations(refs)
if diff := cmp.Diff(test.wantRefs, got); diff != "" {
@@ -301,8 +301,8 @@
}
for _, test := range implTests {
- pos := env.RegexpSearch("foo/foo.go", test.re)
- impls := env.Implementations("foo/foo.go", pos)
+ loc := env.RegexpSearch("foo/foo.go", test.re)
+ impls := env.Implementations(loc)
got := fileLocations(impls)
if diff := cmp.Diff(test.wantImpls, got); diff != "" {
@@ -364,11 +364,11 @@
}
env.OpenFile("a.go")
- refPos := env.RegexpSearch("a.go", "I") // find "I" reference
+ refLoc := env.RegexpSearch("a.go", "I") // find "I" reference
// Initially, a.I has one implementation b.B in
// the module cache, not the vendor tree.
- checkVendor(env.Implementations("a.go", refPos), false)
+ checkVendor(env.Implementations(refLoc), false)
// Run 'go mod vendor' outside the editor.
if err := env.Sandbox.RunGoCommand(env.Ctx, ".", "mod", []string{"vendor"}, true); err != nil {
@@ -379,7 +379,7 @@
env.Await(env.DoneWithChangeWatchedFiles())
// Now, b.B is found in the vendor tree.
- checkVendor(env.Implementations("a.go", refPos), true)
+ checkVendor(env.Implementations(refLoc), true)
// Delete the vendor tree.
if err := os.RemoveAll(env.Sandbox.Workdir.AbsPath("vendor")); err != nil {
@@ -394,6 +394,6 @@
env.Await(env.DoneWithChangeWatchedFiles())
// b.B is once again defined in the module cache.
- checkVendor(env.Implementations("a.go", refPos), false)
+ checkVendor(env.Implementations(refLoc), false)
})
}
diff --git a/gopls/internal/regtest/misc/rename_test.go b/gopls/internal/regtest/misc/rename_test.go
index 86fd567..833d3db 100644
--- a/gopls/internal/regtest/misc/rename_test.go
+++ b/gopls/internal/regtest/misc/rename_test.go
@@ -34,10 +34,11 @@
const wantErr = "can't rename package \"main\""
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
- pos := env.RegexpSearch("main.go", `main`)
+ loc := env.RegexpSearch("main.go", `main`)
+ // TODO(adonovan): define a helper from Location to TextDocumentPositionParams.
tdpp := protocol.TextDocumentPositionParams{
TextDocument: env.Editor.TextDocumentIdentifier("main.go"),
- Position: pos,
+ Position: loc.Range.Start,
}
params := &protocol.PrepareRenameParams{
TextDocumentPositionParams: tdpp,
@@ -79,7 +80,7 @@
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("p.go")
- env.Rename("p.go", env.RegexpSearch("p.go", "M"), "N") // must not panic
+ env.Rename(env.RegexpSearch("p.go", "M"), "N") // must not panic
})
}
@@ -107,9 +108,7 @@
const wantErr = "no object found"
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("lib/a.go")
- pos := env.RegexpSearch("lib/a.go", "fmt")
-
- err := env.Editor.Rename(env.Ctx, "lib/a.go", pos, "fmt1")
+ err := env.Editor.Rename(env.Ctx, env.RegexpSearch("lib/a.go", "fmt"), "fmt1")
if err == nil {
t.Errorf("missing no object found from Rename")
}
@@ -142,10 +141,10 @@
`
const wantErr = "can't rename package: missing module information for package"
Run(t, files, func(t *testing.T, env *Env) {
- pos := env.RegexpSearch("lib/a.go", "lib")
+ loc := env.RegexpSearch("lib/a.go", "lib")
tdpp := protocol.TextDocumentPositionParams{
TextDocument: env.Editor.TextDocumentIdentifier("lib/a.go"),
- Position: pos,
+ Position: loc.Range.Start,
}
params := &protocol.PrepareRenameParams{
TextDocumentPositionParams: tdpp,
@@ -194,8 +193,7 @@
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("lib/a.go")
- pos := env.RegexpSearch("lib/a.go", "lib")
- env.Rename("lib/a.go", pos, "nested")
+ env.Rename(env.RegexpSearch("lib/a.go", "lib"), "nested")
// Check if the new package name exists.
env.RegexpSearch("nested/a.go", "package nested")
@@ -236,8 +234,7 @@
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("lib/a.go")
- pos := env.RegexpSearch("lib/a.go", "lib")
- env.Rename("lib/a.go", pos, "nested")
+ env.Rename(env.RegexpSearch("lib/a.go", "lib"), "nested")
// Check if the new package name exists.
env.RegexpSearch("nested/a.go", "package nested")
@@ -277,8 +274,7 @@
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("lib/a.go")
- pos := env.RegexpSearch("lib/a.go", "lib")
- env.Rename("lib/a.go", pos, "nested")
+ env.Rename(env.RegexpSearch("lib/a.go", "lib"), "nested")
// Check if the new package name exists.
env.RegexpSearch("nested/a.go", "package nested")
@@ -323,8 +319,7 @@
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("lib/a.go")
- pos := env.RegexpSearch("lib/a.go", "lib")
- env.Rename("lib/a.go", pos, "lib1")
+ env.Rename(env.RegexpSearch("lib/a.go", "lib"), "lib1")
// Check if the new package name exists.
env.RegexpSearch("lib1/a.go", "package lib1")
@@ -371,8 +366,7 @@
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
- pos := env.RegexpSearch("main.go", `stringutil\.(Identity)`)
- env.Rename("main.go", pos, "Identityx")
+ env.Rename(env.RegexpSearch("main.go", `stringutil\.(Identity)`), "Identityx")
text := env.BufferText("stringutil/stringutil_test.go")
if !strings.Contains(text, "Identityx") {
t.Errorf("stringutil/stringutil_test.go: missing expected token `Identityx` after rename:\n%s", text)
@@ -495,8 +489,7 @@
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("lib/a.go")
- pos := env.RegexpSearch("lib/a.go", "lib")
- env.Rename("lib/a.go", pos, "lib1")
+ env.Rename(env.RegexpSearch("lib/a.go", "lib"), "lib1")
// Check if the new package name exists.
env.RegexpSearch("lib1/a.go", "package lib1")
@@ -577,8 +570,7 @@
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("foo/foo.go")
- pos := env.RegexpSearch("foo/foo.go", "foo")
- env.Rename("foo/foo.go", pos, "foox")
+ env.Rename(env.RegexpSearch("foo/foo.go", "foo"), "foox")
env.RegexpSearch("foox/foo.go", "package foox")
env.OpenFile("foox/bar/bar.go")
@@ -625,8 +617,7 @@
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("lib/a.go")
- pos := env.RegexpSearch("lib/a.go", "lib")
- env.Rename("lib/a.go", pos, "nested")
+ env.Rename(env.RegexpSearch("lib/a.go", "lib"), "nested")
// Check if the new package name exists.
env.RegexpSearch("nested/a.go", "package nested")
@@ -668,8 +659,7 @@
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("lib/a.go")
- pos := env.RegexpSearch("lib/a.go", "lib")
- env.Rename("lib/a.go", pos, "nested")
+ env.Rename(env.RegexpSearch("lib/a.go", "lib"), "nested")
// Check if the new package name exists.
env.RegexpSearch("nested/a.go", "package nested")
@@ -716,7 +706,7 @@
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("foo/foo.go")
- env.Rename("foo/foo.go", env.RegexpSearch("foo/foo.go", "package (foo)"), "foox")
+ env.Rename(env.RegexpSearch("foo/foo.go", "package (foo)"), "foox")
checkTestdata(t, env)
})
@@ -796,7 +786,7 @@
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("foo/foo.go")
- env.Rename("foo/foo.go", env.RegexpSearch("foo/foo.go", "package (foo)"), "foox")
+ env.Rename(env.RegexpSearch("foo/foo.go", "package (foo)"), "foox")
checkTestdata(t, env)
})
@@ -846,8 +836,7 @@
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("lib/a.go")
- pos := env.RegexpSearch("lib/a.go", "package (lib)")
- env.Rename("lib/a.go", pos, "libx")
+ env.Rename(env.RegexpSearch("lib/a.go", "package (lib)"), "libx")
checkTestdata(t, env)
})
@@ -870,10 +859,10 @@
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("lib/a.go")
- pos := env.RegexpSearch("lib/a.go", "package (lib)")
+ loc := env.RegexpSearch("lib/a.go", "package (lib)")
for _, badName := range []string{"$$$", "lib_test"} {
- if err := env.Editor.Rename(env.Ctx, "lib/a.go", pos, badName); err == nil {
+ if err := env.Editor.Rename(env.Ctx, loc, badName); err == nil {
t.Errorf("Rename(lib, libx) succeeded, want non-nil error")
}
}
@@ -917,8 +906,7 @@
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("lib/internal/x/a.go")
- pos := env.RegexpSearch("lib/internal/x/a.go", "x")
- env.Rename("lib/internal/x/a.go", pos, "utils")
+ env.Rename(env.RegexpSearch("lib/internal/x/a.go", "x"), "utils")
// Check if the new package name exists.
env.RegexpSearch("lib/a.go", "mod.com/lib/internal/utils")
@@ -928,8 +916,7 @@
env.RegexpSearch("lib/internal/utils/a.go", "package utils")
env.OpenFile("lib/a.go")
- pos = env.RegexpSearch("lib/a.go", "lib")
- env.Rename("lib/a.go", pos, "lib1")
+ env.Rename(env.RegexpSearch("lib/a.go", "lib"), "lib1")
// Check if the new package name exists.
env.RegexpSearch("lib1/a.go", "package lib1")
diff --git a/gopls/internal/regtest/misc/signature_help_test.go b/gopls/internal/regtest/misc/signature_help_test.go
index 05f5830..fd9f4f0 100644
--- a/gopls/internal/regtest/misc/signature_help_test.go
+++ b/gopls/internal/regtest/misc/signature_help_test.go
@@ -49,10 +49,10 @@
env.OpenFile("a/a/a.go")
env.OpenFile("b/b/b.go")
signatureHelp := func(filename string) *protocol.SignatureHelp {
- pos := env.RegexpSearch(filename, `DoSomething\(()\)`)
+ loc := env.RegexpSearch(filename, `DoSomething\(()\)`)
var params protocol.SignatureHelpParams
- params.Position = pos
- params.TextDocument.URI = env.Sandbox.Workdir.URI(filename)
+ params.TextDocument.URI = loc.URI
+ params.Position = loc.Range.Start
help, err := env.Editor.Server.SignatureHelp(env.Ctx, ¶ms)
if err != nil {
t.Fatal(err)
diff --git a/gopls/internal/regtest/misc/vuln_test.go b/gopls/internal/regtest/misc/vuln_test.go
index 9d73272..bbf99b3 100644
--- a/gopls/internal/regtest/misc/vuln_test.go
+++ b/gopls/internal/regtest/misc/vuln_test.go
@@ -644,9 +644,9 @@
"go.mod": {IDs: []string{"GO-2022-01", "GO-2022-02", "GO-2022-03"}, Mode: govulncheck.ModeGovulncheck},
})
env.OpenFile("x/x.go")
- lineX := env.RegexpSearch("x/x.go", `c\.C1\(\)\.Vuln1\(\)`)
+ lineX := env.RegexpSearch("x/x.go", `c\.C1\(\)\.Vuln1\(\)`).Range.Start
env.OpenFile("y/y.go")
- lineY := env.RegexpSearch("y/y.go", `c\.C2\(\)\(\)`)
+ lineY := env.RegexpSearch("y/y.go", `c\.C2\(\)\(\)`).Range.Start
wantDiagnostics := map[string]vulnDiagExpectation{
"golang.org/amod": {
applyAction: "Upgrade to v1.0.6",
@@ -862,14 +862,14 @@
// and runs checks if diagnostics and code actions associated with the line match expectation.
func testVulnDiagnostics(t *testing.T, env *Env, pattern string, want vulnDiagExpectation, got *protocol.PublishDiagnosticsParams) []protocol.Diagnostic {
t.Helper()
- pos := env.RegexpSearch("go.mod", pattern)
+ loc := env.RegexpSearch("go.mod", pattern)
var modPathDiagnostics []protocol.Diagnostic
for _, w := range want.diagnostics {
- // Find the diagnostics at pos.
+ // Find the diagnostics at loc.start.
var diag *protocol.Diagnostic
for _, g := range got.Diagnostics {
g := g
- if g.Range.Start == pos && w.msg == g.Message {
+ if g.Range.Start == loc.Range.Start && w.msg == g.Message {
modPathDiagnostics = append(modPathDiagnostics, g)
diag = &g
break
@@ -895,7 +895,7 @@
}
// Check that useful info is supplemented as hover.
if len(want.hover) > 0 {
- hover, _ := env.Hover("go.mod", pos)
+ hover, _ := env.Hover(loc)
for _, part := range want.hover {
if !strings.Contains(hover.Value, part) {
t.Errorf("hover contents for %q do not match, want %v, got %v\n", pattern, strings.Join(want.hover, ","), hover.Value)
diff --git a/gopls/internal/regtest/modfile/modfile_test.go b/gopls/internal/regtest/modfile/modfile_test.go
index f44eefa..483118d 100644
--- a/gopls/internal/regtest/modfile/modfile_test.go
+++ b/gopls/internal/regtest/modfile/modfile_test.go
@@ -913,13 +913,13 @@
env.RegexpReplace("go.mod", "module", "modul")
// Confirm that we still have metadata with only on-disk edits.
env.OpenFile("main.go")
- file, _ := env.GoToDefinition("main.go", env.RegexpSearch("main.go", "hello"))
- if filepath.Base(file) != "hello.go" {
- t.Fatalf("expected definition in hello.go, got %s", file)
+ loc := env.GoToDefinition(env.RegexpSearch("main.go", "hello"))
+ if filepath.Base(string(loc.URI)) != "hello.go" {
+ t.Fatalf("expected definition in hello.go, got %s", loc.URI)
}
// Confirm that we no longer have metadata when the file is saved.
env.SaveBufferWithoutActions("go.mod")
- _, _, err := env.Editor.GoToDefinition(env.Ctx, "main.go", env.RegexpSearch("main.go", "hello"))
+ _, err := env.Editor.GoToDefinition(env.Ctx, env.RegexpSearch("main.go", "hello"))
if err == nil {
t.Fatalf("expected error, got none")
}
@@ -1017,7 +1017,7 @@
).Run(t, mod, func(t *testing.T, env *Env) {
d := &protocol.PublishDiagnosticsParams{}
env.OpenFile("go.mod")
- pos := env.RegexpSearch("go.mod", "require hasdep.com v1.2.3")
+ pos := env.RegexpSearch("go.mod", "require hasdep.com v1.2.3").Range.Start
env.AfterChange(
Diagnostics(AtPosition("go.mod", pos.Line, pos.Character)),
ReadDiagnostics("go.mod", d),
diff --git a/gopls/internal/regtest/template/template_test.go b/gopls/internal/regtest/template/template_test.go
index c81bf1a..4863564 100644
--- a/gopls/internal/regtest/template/template_test.go
+++ b/gopls/internal/regtest/template/template_test.go
@@ -191,8 +191,8 @@
).Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("a.tmpl")
x := env.RegexpSearch("a.tmpl", `A`)
- file, pos := env.GoToDefinition("a.tmpl", x)
- refs := env.References(file, pos)
+ loc := env.GoToDefinition(x)
+ refs := env.References(loc)
if len(refs) != 2 {
t.Fatalf("got %v reference(s), want 2", len(refs))
}
@@ -205,9 +205,9 @@
}
}
- content, npos := env.Hover(file, pos)
- if pos != npos {
- t.Errorf("pos? got %v, wanted %v", npos, pos)
+ content, nloc := env.Hover(loc)
+ if loc != nloc {
+ t.Errorf("loc? got %v, wanted %v", nloc, loc)
}
if content.Value != "template A defined" {
t.Errorf("got %s, wanted 'template A defined", content.Value)
diff --git a/gopls/internal/regtest/workspace/broken_test.go b/gopls/internal/regtest/workspace/broken_test.go
index 5c5a68a..005a7e9 100644
--- a/gopls/internal/regtest/workspace/broken_test.go
+++ b/gopls/internal/regtest/workspace/broken_test.go
@@ -113,7 +113,7 @@
env.Await(NoOutstandingWork())
// Check that definitions in package1 go to the copy vendored in package2.
- location, _ := env.GoToDefinition("package1/main.go", env.RegexpSearch("package1/main.go", "CompleteMe"))
+ location := env.GoToDefinition(env.RegexpSearch("package1/main.go", "CompleteMe")).URI.SpanURI().Filename()
const wantLocation = "package2/vendor/example.com/foo/foo.go"
if !strings.HasSuffix(location, wantLocation) {
t.Errorf("got definition of CompleteMe at %q, want %q", location, wantLocation)
diff --git a/gopls/internal/regtest/workspace/metadata_test.go b/gopls/internal/regtest/workspace/metadata_test.go
index 11dfe67..ac64b07 100644
--- a/gopls/internal/regtest/workspace/metadata_test.go
+++ b/gopls/internal/regtest/workspace/metadata_test.go
@@ -172,7 +172,8 @@
// Now, to satisfy a definition request, gopls will try to reload moda. But
// without access to the proxy (because this is no longer a
// reinitialization), this loading will fail.
- got, _ := env.GoToDefinition("moda/a/a.go", env.RegexpSearch("moda/a/a.go", "Hello"))
+ loc := env.GoToDefinition(env.RegexpSearch("moda/a/a.go", "Hello"))
+ got := env.Sandbox.Workdir.URIToPath(loc.URI)
if want := "b.com@v1.2.3/b/b.go"; !strings.HasSuffix(got, want) {
t.Errorf("expected %s, got %v", want, got)
}
diff --git a/gopls/internal/regtest/workspace/standalone_test.go b/gopls/internal/regtest/workspace/standalone_test.go
index c9618eb..e1021df 100644
--- a/gopls/internal/regtest/workspace/standalone_test.go
+++ b/gopls/internal/regtest/workspace/standalone_test.go
@@ -83,10 +83,10 @@
env.RegexpReplace("lib/lib.go", "D", "C")
env.AfterChange(NoDiagnostics())
- refs := env.References("lib/lib.go", env.RegexpSearch("lib/lib.go", "C"))
+ refs := env.References(env.RegexpSearch("lib/lib.go", "C"))
checkLocations("References", refs, "lib/lib.go")
- impls := env.Implementations("lib/lib.go", env.RegexpSearch("lib/lib.go", "I"))
+ impls := env.Implementations(env.RegexpSearch("lib/lib.go", "I"))
checkLocations("Implementations", impls) // no implementations
// Opening the standalone file should not result in any diagnostics.
@@ -113,19 +113,17 @@
}
// We should resolve workspace definitions in the standalone file.
- file, _ := env.GoToDefinition("lib/ignore.go", env.RegexpSearch("lib/ignore.go", "lib.(C)"))
+ fileLoc := env.GoToDefinition(env.RegexpSearch("lib/ignore.go", "lib.(C)"))
+ file := env.Sandbox.Workdir.URIToPath(fileLoc.URI)
if got, want := file, "lib/lib.go"; got != want {
t.Errorf("GoToDefinition(lib.C) = %v, want %v", got, want)
}
// ...as well as intra-file definitions
- file, pos := env.GoToDefinition("lib/ignore.go", env.RegexpSearch("lib/ignore.go", "\\+ (C)"))
- if got, want := file, "lib/ignore.go"; got != want {
- t.Errorf("GoToDefinition(C) = %v, want %v", got, want)
- }
- wantPos := env.RegexpSearch("lib/ignore.go", "const (C)")
- if pos != wantPos {
- t.Errorf("GoToDefinition(C) = %v, want %v", pos, wantPos)
+ loc := env.GoToDefinition(env.RegexpSearch("lib/ignore.go", "\\+ (C)"))
+ wantLoc := env.RegexpSearch("lib/ignore.go", "const (C)")
+ if loc != wantLoc {
+ t.Errorf("GoToDefinition(C) = %v, want %v", loc, wantLoc)
}
// Renaming "lib.C" to "lib.D" should cause a diagnostic in the standalone
@@ -139,14 +137,14 @@
// Now that our workspace has no errors, we should be able to find
// references and rename.
- refs = env.References("lib/lib.go", env.RegexpSearch("lib/lib.go", "C"))
+ refs = env.References(env.RegexpSearch("lib/lib.go", "C"))
checkLocations("References", refs, "lib/lib.go", "lib/ignore.go")
- impls = env.Implementations("lib/lib.go", env.RegexpSearch("lib/lib.go", "I"))
+ impls = env.Implementations(env.RegexpSearch("lib/lib.go", "I"))
checkLocations("Implementations", impls, "lib/ignore.go")
// Renaming should rename in the standalone package.
- env.Rename("lib/lib.go", env.RegexpSearch("lib/lib.go", "C"), "D")
+ env.Rename(env.RegexpSearch("lib/lib.go", "C"), "D")
env.RegexpSearch("lib/ignore.go", "lib.D")
})
}
diff --git a/gopls/internal/regtest/workspace/workspace_test.go b/gopls/internal/regtest/workspace/workspace_test.go
index 3699fa8..0aff471 100644
--- a/gopls/internal/regtest/workspace/workspace_test.go
+++ b/gopls/internal/regtest/workspace/workspace_test.go
@@ -131,7 +131,7 @@
WithOptions(opts...).Run(t, workspaceModule, func(t *testing.T, env *Env) {
f := "pkg/inner/inner.go"
env.OpenFile(f)
- locations := env.References(f, env.RegexpSearch(f, `SaySomething`))
+ locations := env.References(env.RegexpSearch(f, `SaySomething`))
want := 3
if got := len(locations); got != want {
t.Fatalf("expected %v locations, got %v", want, got)
@@ -378,7 +378,8 @@
env.OpenFile("moda/a/a.go")
env.Await(env.DoneWithOpen())
- original, _ := env.GoToDefinition("moda/a/a.go", env.RegexpSearch("moda/a/a.go", "Hello"))
+ originalLoc := env.GoToDefinition(env.RegexpSearch("moda/a/a.go", "Hello"))
+ original := env.Sandbox.Workdir.URIToPath(originalLoc.URI)
if want := "modb/b/b.go"; !strings.HasSuffix(original, want) {
t.Errorf("expected %s, got %v", want, original)
}
@@ -390,7 +391,8 @@
env.WriteWorkspaceFile("go.work", "go 1.18\nuse moda/a")
env.AfterChange()
- got, _ := env.GoToDefinition("moda/a/a.go", env.RegexpSearch("moda/a/a.go", "Hello"))
+ gotLoc := env.GoToDefinition(env.RegexpSearch("moda/a/a.go", "Hello"))
+ got := env.Sandbox.Workdir.URIToPath(gotLoc.URI)
if want := "b.com@v1.2.3/b/b.go"; !strings.HasSuffix(got, want) {
t.Errorf("expected %s, got %v", want, got)
}
@@ -431,7 +433,8 @@
ProxyFiles(workspaceModuleProxy),
).Run(t, multiModule, func(t *testing.T, env *Env) {
env.OpenFile("moda/a/a.go")
- original, _ := env.GoToDefinition("moda/a/a.go", env.RegexpSearch("moda/a/a.go", "Hello"))
+ loc := env.GoToDefinition(env.RegexpSearch("moda/a/a.go", "Hello"))
+ original := env.Sandbox.Workdir.URIToPath(loc.URI)
if want := "b.com@v1.2.3/b/b.go"; !strings.HasSuffix(original, want) {
t.Errorf("expected %s, got %v", want, original)
}
@@ -453,7 +456,8 @@
`,
})
env.AfterChange(Diagnostics(env.AtRegexp("modb/b/b.go", "x")))
- got, _ := env.GoToDefinition("moda/a/a.go", env.RegexpSearch("moda/a/a.go", "Hello"))
+ gotLoc := env.GoToDefinition(env.RegexpSearch("moda/a/a.go", "Hello"))
+ got := env.Sandbox.Workdir.URIToPath(gotLoc.URI)
if want := "modb/b/b.go"; !strings.HasSuffix(got, want) {
t.Errorf("expected %s, got %v", want, original)
}
@@ -581,9 +585,10 @@
// To verify which modules are loaded, we'll jump to the definition of
// b.Hello.
checkHelloLocation := func(want string) error {
- location, _ := env.GoToDefinition("moda/a/a.go", env.RegexpSearch("moda/a/a.go", "Hello"))
- if !strings.HasSuffix(location, want) {
- return fmt.Errorf("expected %s, got %v", want, location)
+ loc := env.GoToDefinition(env.RegexpSearch("moda/a/a.go", "Hello"))
+ file := env.Sandbox.Workdir.URIToPath(loc.URI)
+ if !strings.HasSuffix(file, want) {
+ return fmt.Errorf("expected %s, got %v", want, file)
}
return nil
}
@@ -749,8 +754,7 @@
}
for hoverRE, want := range tcs {
- pos := env.RegexpSearch("go.work", hoverRE)
- got, _ := env.Hover("go.work", pos)
+ got, _ := env.Hover(env.RegexpSearch("go.work", hoverRE))
if got.Value != want {
t.Errorf(`hover on %q: got %q, want %q`, hoverRE, got, want)
}
@@ -799,21 +803,22 @@
).Run(t, workspace, func(t *testing.T, env *Env) {
env.OpenFile("moda/a/a.go")
env.Await(env.DoneWithOpen())
- location, _ := env.GoToDefinition("moda/a/a.go", env.RegexpSearch("moda/a/a.go", "Hello"))
+ loc := env.GoToDefinition(env.RegexpSearch("moda/a/a.go", "Hello"))
+ file := env.Sandbox.Workdir.URIToPath(loc.URI)
want := "modb/b/b.go"
- if !strings.HasSuffix(location, want) {
- t.Errorf("expected %s, got %v", want, location)
+ if !strings.HasSuffix(file, want) {
+ t.Errorf("expected %s, got %v", want, file)
}
})
}
func TestNonWorkspaceFileCreation(t *testing.T) {
const files = `
--- go.mod --
+-- work/go.mod --
module mod.com
go 1.12
--- x.go --
+-- work/x.go --
package x
`
@@ -822,10 +827,12 @@
import "fmt"
var _ = fmt.Printf
`
- Run(t, files, func(t *testing.T, env *Env) {
- env.CreateBuffer("/tmp/foo.go", "")
- env.EditBuffer("/tmp/foo.go", fake.NewEdit(0, 0, 0, 0, code))
- env.GoToDefinition("/tmp/foo.go", env.RegexpSearch("/tmp/foo.go", `Printf`))
+ WithOptions(
+ WorkspaceFolders("work"), // so that outside/... is outside the workspace
+ ).Run(t, files, func(t *testing.T, env *Env) {
+ env.CreateBuffer("outside/foo.go", "")
+ env.EditBuffer("outside/foo.go", fake.NewEdit(0, 0, 0, 0, code))
+ env.GoToDefinition(env.RegexpSearch("outside/foo.go", `Printf`))
})
}
@@ -1124,7 +1131,7 @@
)
// This will cause a test failure if other_test.go is not in any package.
- _, _ = env.GoToDefinition("other_test.go", env.RegexpSearch("other_test.go", "Server"))
+ _ = env.GoToDefinition(env.RegexpSearch("other_test.go", "Server"))
})
}