diff --git a/gopls/internal/golang/codeaction.go b/gopls/internal/golang/codeaction.go index 27ed29faf06..691b54634a8 100644 --- a/gopls/internal/golang/codeaction.go +++ b/gopls/internal/golang/codeaction.go @@ -548,7 +548,12 @@ func refactorRewriteRemoveUnusedParam(ctx context.Context, req *codeActionsReque } func refactorRewriteMoveParamLeft(ctx context.Context, req *codeActionsRequest) error { - if info := findParam(req.pgf, req.loc.Range); info != nil && info.paramIndex > 0 { + if info := findParam(req.pgf, req.loc.Range); info != nil && + info.paramIndex > 0 && + !is[*ast.Ellipsis](info.field.Type) { + + // ^^ we can't currently handle moving a variadic param. + // TODO(rfindley): implement. transform := identityTransform(info.decl.Type.Params) transform[info.paramIndex] = command.ChangeSignatureParam{OldIndex: info.paramIndex - 1} @@ -566,19 +571,27 @@ func refactorRewriteMoveParamLeft(ctx context.Context, req *codeActionsRequest) } func refactorRewriteMoveParamRight(ctx context.Context, req *codeActionsRequest) error { - if info := findParam(req.pgf, req.loc.Range); info != nil && info.paramIndex >= 0 && // found a param - info.paramIndex < info.decl.Type.Params.NumFields()-1 { // not the last param + if info := findParam(req.pgf, req.loc.Range); info != nil && info.paramIndex >= 0 { + params := info.decl.Type.Params + nparams := params.NumFields() + if info.paramIndex < nparams-1 { // not the last param + if info.paramIndex == nparams-2 && is[*ast.Ellipsis](params.List[len(params.List)-1].Type) { + // We can't currently handle moving a variadic param. + // TODO(rfindley): implement. + return nil + } - transform := identityTransform(info.decl.Type.Params) - transform[info.paramIndex] = command.ChangeSignatureParam{OldIndex: info.paramIndex + 1} - transform[info.paramIndex+1] = command.ChangeSignatureParam{OldIndex: info.paramIndex} - cmd := command.NewChangeSignatureCommand("Move parameter right", command.ChangeSignatureArgs{ - Location: req.loc, - NewParams: transform, - NewResults: identityTransform(info.decl.Type.Results), - ResolveEdits: req.resolveEdits(), - }) - req.addCommandAction(cmd, true) + transform := identityTransform(info.decl.Type.Params) + transform[info.paramIndex] = command.ChangeSignatureParam{OldIndex: info.paramIndex + 1} + transform[info.paramIndex+1] = command.ChangeSignatureParam{OldIndex: info.paramIndex} + cmd := command.NewChangeSignatureCommand("Move parameter right", command.ChangeSignatureArgs{ + Location: req.loc, + NewParams: transform, + NewResults: identityTransform(info.decl.Type.Results), + ResolveEdits: req.resolveEdits(), + }) + req.addCommandAction(cmd, true) + } } return nil } diff --git a/gopls/internal/test/marker/marker_test.go b/gopls/internal/test/marker/marker_test.go index d9368ded260..654bca4ae5b 100644 --- a/gopls/internal/test/marker/marker_test.go +++ b/gopls/internal/test/marker/marker_test.go @@ -11,6 +11,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "flag" "fmt" "go/token" @@ -2250,10 +2251,12 @@ func codeActionChanges(env *integration.Env, uri protocol.DocumentURI, rng proto } } if len(candidates) != 1 { + var msg bytes.Buffer + fmt.Fprintf(&msg, "found %d CodeActions of kind %s for this diagnostic, want 1", len(candidates), kind) for _, act := range actions { - env.T.Logf("found CodeAction Kind=%s Title=%q", act.Kind, act.Title) + fmt.Fprintf(&msg, "\n\tfound %q (%s)", act.Title, act.Kind) } - return nil, fmt.Errorf("found %d CodeActions of kind %s for this diagnostic, want 1", len(candidates), kind) + return nil, errors.New(msg.String()) } action := candidates[0] diff --git a/gopls/internal/test/marker/testdata/codeaction/moveparam_issue70599.txt b/gopls/internal/test/marker/testdata/codeaction/moveparam_issue70599.txt index 84292bb5ea3..bf4a19536c0 100644 --- a/gopls/internal/test/marker/testdata/codeaction/moveparam_issue70599.txt +++ b/gopls/internal/test/marker/testdata/codeaction/moveparam_issue70599.txt @@ -94,7 +94,7 @@ package a // We should not offer movement involving variadic parameters if it is not well // supported. -func Variadic(x int, y ...string) { //@codeaction("x", "refactor.rewrite.moveParamRight", err="type checking rewritten package") +func Variadic(x int, y ...string) { //@codeaction("x", "refactor.rewrite.moveParamRight", err="0 CodeActions"), codeaction("y", "refactor.rewrite.moveParamLeft", err="0 CodeActions") } func _() {