gopls/internal/lsp/source: put testing.T/B first when extracting
Put the testing.T/B second when extracting functions/methods.
It's next after context.Context.
Fixes golang/go#69341
Change-Id: Idcfc0e09e4174646a3f136dcc5badfda4af9938e
GitHub-Last-Rev: 99de9722e6856e13dc2bc4d069cee149c62e3631
GitHub-Pull-Request: golang/tools#517
Reviewed-on: https://go-review.googlesource.com/c/tools/+/610976
Auto-Submit: Robert Findley <rfindley@google.com>
Reviewed-by: Tim King <taking@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Run-TryBot: Tim King <taking@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Tim King <taking@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/gopls/internal/golang/extract.go b/gopls/internal/golang/extract.go
index cc82a53..3610dee 100644
--- a/gopls/internal/golang/extract.go
+++ b/gopls/internal/golang/extract.go
@@ -651,8 +651,12 @@
}, nil
}
-// isSelector reports if e is the selector expr <x>, <sel>.
+// isSelector reports if e is the selector expr <x>, <sel>. It works for pointer and non-pointer selector expressions.
func isSelector(e ast.Expr, x, sel string) bool {
+ unary, ok := e.(*ast.UnaryExpr)
+ if ok && unary.Op == token.MUL {
+ e = unary.X
+ }
selectorExpr, ok := e.(*ast.SelectorExpr)
if !ok {
return false
@@ -666,9 +670,15 @@
// reorderParams reorders the given parameters in-place to follow common Go conventions.
func reorderParams(params []ast.Expr, paramTypes []*ast.Field) {
+ moveParamToFrontIfFound(params, paramTypes, "testing", "T")
+ moveParamToFrontIfFound(params, paramTypes, "testing", "B")
+ moveParamToFrontIfFound(params, paramTypes, "context", "Context")
+}
+
+func moveParamToFrontIfFound(params []ast.Expr, paramTypes []*ast.Field, x, sel string) {
// Move Context parameter (if any) to front.
for i, t := range paramTypes {
- if isSelector(t.Type, "context", "Context") {
+ if isSelector(t.Type, x, sel) {
p, t := params[i], paramTypes[i]
copy(params[1:], params[:i])
copy(paramTypes[1:], paramTypes[:i])
diff --git a/gopls/internal/test/marker/testdata/codeaction/extract_method.txt b/gopls/internal/test/marker/testdata/codeaction/extract_method.txt
index 2b357be..7580050 100644
--- a/gopls/internal/test/marker/testdata/codeaction/extract_method.txt
+++ b/gopls/internal/test/marker/testdata/codeaction/extract_method.txt
@@ -157,12 +157,17 @@
-- context.go --
package extract
-import "context"
+import (
+ "context"
+ "testing"
+)
//@codeactionedit(B_AddP, "refactor.extract", contextMeth1, "Extract method")
//@codeactionedit(B_AddP, "refactor.extract", contextFunc1, "Extract function")
//@codeactionedit(B_LongList, "refactor.extract", contextMeth2, "Extract method")
//@codeactionedit(B_LongList, "refactor.extract", contextFunc2, "Extract function")
+//@codeactionedit(B_AddPWithB, "refactor.extract", contextFuncB, "Extract function")
+//@codeactionedit(B_LongListWithT, "refactor.extract", contextFuncT, "Extract function")
type B struct {
x int
@@ -180,39 +185,72 @@
p3 := 1
return p1 + p2 + p3, ctx.Err() //@loc(B_LongList, re`return.*ctx\.Err\(\)`)
}
+
+func (b *B) AddPWithB(ctx context.Context, tB *testing.B) (int, error) {
+ sum := b.x + b.y //@loc(B_AddPWithB, re`(?s:^.*?Err\(\))`)
+ tB.Skip()
+ return sum, ctx.Err()
+}
+
+func (b *B) LongListWithT(ctx context.Context, t *testing.T) (int, error) {
+ p1 := 1
+ p2 := 1
+ p3 := 1
+ p4 := p1 + p2 //@loc(B_LongListWithT, re`(?s:^.*?Err\(\))`)
+ t.Skip()
+ return p4 + p3, ctx.Err()
+}
-- @contextMeth1/context.go --
-@@ -17 +17 @@
+@@ -22 +22 @@
- return sum, ctx.Err() //@loc(B_AddP, re`return.*ctx\.Err\(\)`)
+ return b.newMethod(ctx, sum) //@loc(B_AddP, re`return.*ctx\.Err\(\)`)
-@@ -20 +20,4 @@
+@@ -25 +25,4 @@
+func (*B) newMethod(ctx context.Context, sum int) (int, error) {
+ return sum, ctx.Err()
+}
+
-- @contextMeth2/context.go --
-@@ -24 +24 @@
+@@ -29 +29 @@
- return p1 + p2 + p3, ctx.Err() //@loc(B_LongList, re`return.*ctx\.Err\(\)`)
+ return b.newMethod(ctx, p1, p2, p3) //@loc(B_LongList, re`return.*ctx\.Err\(\)`)
-@@ -26 +26,4 @@
-+
+@@ -32 +32,4 @@
+func (*B) newMethod(ctx context.Context, p1 int, p2 int, p3 int) (int, error) {
+ return p1 + p2 + p3, ctx.Err()
+}
++
-- @contextFunc2/context.go --
-@@ -24 +24 @@
+@@ -29 +29 @@
- return p1 + p2 + p3, ctx.Err() //@loc(B_LongList, re`return.*ctx\.Err\(\)`)
+ return newFunction(ctx, p1, p2, p3) //@loc(B_LongList, re`return.*ctx\.Err\(\)`)
-@@ -26 +26,4 @@
-+
+@@ -32 +32,4 @@
+func newFunction(ctx context.Context, p1 int, p2 int, p3 int) (int, error) {
+ return p1 + p2 + p3, ctx.Err()
+}
++
-- @contextFunc1/context.go --
-@@ -17 +17 @@
+@@ -22 +22 @@
- return sum, ctx.Err() //@loc(B_AddP, re`return.*ctx\.Err\(\)`)
+ return newFunction(ctx, sum) //@loc(B_AddP, re`return.*ctx\.Err\(\)`)
-@@ -20 +20,4 @@
+@@ -25 +25,4 @@
+func newFunction(ctx context.Context, sum int) (int, error) {
+ return sum, ctx.Err()
+}
+
+-- @contextFuncB/context.go --
+@@ -33 +33,6 @@
+- sum := b.x + b.y //@loc(B_AddPWithB, re`(?s:^.*?Err\(\))`)
++ //@loc(B_AddPWithB, re`(?s:^.*?Err\(\))`)
++ return newFunction(ctx, tB, b)
++}
++
++func newFunction(ctx context.Context, tB *testing.B, b *B) (int, error) {
++ sum := b.x + b.y
+-- @contextFuncT/context.go --
+@@ -42 +42,6 @@
+- p4 := p1 + p2 //@loc(B_LongListWithT, re`(?s:^.*?Err\(\))`)
++ //@loc(B_LongListWithT, re`(?s:^.*?Err\(\))`)
++ return newFunction(ctx, t, p1, p2, p3)
++}
++
++func newFunction(ctx context.Context, t *testing.T, p1 int, p2 int, p3 int) (int, error) {
++ p4 := p1 + p2