internal/lsp: adjust extract function range if block statement
If the selected region is a block statement, gopls
does not return a valid function extraction. This
change adjusts the range to be the statements inside
of the selected block statement.
Fixes golang/go#48963
Change-Id: I9b1fb5005f961f30c1fa0333cd1f2050ed5eedef
Reviewed-on: https://go-review.googlesource.com/c/tools/+/357615
Trust: Suzy Mueller <suzmue@golang.org>
Run-TryBot: Suzy Mueller <suzmue@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
diff --git a/internal/lsp/source/extract.go b/internal/lsp/source/extract.go
index 54170fd..43b414a 100644
--- a/internal/lsp/source/extract.go
+++ b/internal/lsp/source/extract.go
@@ -995,6 +995,16 @@
if start == nil || end == nil {
return nil, false, false, fmt.Errorf("range does not map to AST nodes")
}
+ // If the region is a blockStmt, use the first and last nodes in the block
+ // statement.
+ // <rng.start>{ ... }<rng.end> => { <rng.start>...<rng.end> }
+ if blockStmt, ok := start.(*ast.BlockStmt); ok {
+ if len(blockStmt.List) == 0 {
+ return nil, false, false, fmt.Errorf("range maps to empty block statement")
+ }
+ start, end = blockStmt.List[0], blockStmt.List[len(blockStmt.List)-1]
+ rng.Start, rng.End = start.Pos(), end.End()
+ }
return &fnExtractParams{
tok: tok,
path: path,
diff --git a/internal/lsp/testdata/extract/extract_function/extract_basic.go b/internal/lsp/testdata/extract/extract_function/extract_basic.go
index b5b9efd..5e44de2 100644
--- a/internal/lsp/testdata/extract/extract_function/extract_basic.go
+++ b/internal/lsp/testdata/extract/extract_function/extract_basic.go
@@ -1,7 +1,8 @@
package extract
-func _() {
+func _() { //@mark(exSt25, "{")
a := 1 //@mark(exSt1, "a")
_ = 3 + 4 //@mark(exEn1, "4")
//@extractfunc(exSt1, exEn1)
-}
+ //@extractfunc(exSt25, exEn25)
+} //@mark(exEn25, "}")
diff --git a/internal/lsp/testdata/extract/extract_function/extract_basic.go.golden b/internal/lsp/testdata/extract/extract_function/extract_basic.go.golden
index ba40ff2..18adc4d 100644
--- a/internal/lsp/testdata/extract/extract_function/extract_basic.go.golden
+++ b/internal/lsp/testdata/extract/extract_function/extract_basic.go.golden
@@ -1,14 +1,30 @@
--- functionextraction_extract_basic_4_2 --
+-- functionextraction_extract_basic_3_10 --
package extract
-func _() {
+func _() { //@mark(exSt25, "{")
//@mark(exSt1, "a")
newFunction() //@mark(exEn1, "4")
//@extractfunc(exSt1, exEn1)
+ //@extractfunc(exSt25, exEn25)
}
func newFunction() {
a := 1
_ = 3 + 4
+} //@mark(exEn25, "}")
+
+-- functionextraction_extract_basic_4_2 --
+package extract
+
+func _() { //@mark(exSt25, "{")
+ //@mark(exSt1, "a")
+ newFunction() //@mark(exEn1, "4")
+ //@extractfunc(exSt1, exEn1)
+ //@extractfunc(exSt25, exEn25)
}
+func newFunction() {
+ a := 1
+ _ = 3 + 4
+} //@mark(exEn25, "}")
+
diff --git a/internal/lsp/testdata/summary.txt.golden b/internal/lsp/testdata/summary.txt.golden
index 9e6334a..fa1bddf 100644
--- a/internal/lsp/testdata/summary.txt.golden
+++ b/internal/lsp/testdata/summary.txt.golden
@@ -14,7 +14,7 @@
ImportCount = 8
SemanticTokenCount = 3
SuggestedFixCount = 49
-FunctionExtractionCount = 24
+FunctionExtractionCount = 25
MethodExtractionCount = 6
DefinitionsCount = 95
TypeDefinitionsCount = 18
diff --git a/internal/lsp/testdata/summary_go1.18.txt.golden b/internal/lsp/testdata/summary_go1.18.txt.golden
index fefd3d2..61ca3b1 100644
--- a/internal/lsp/testdata/summary_go1.18.txt.golden
+++ b/internal/lsp/testdata/summary_go1.18.txt.golden
@@ -14,7 +14,7 @@
ImportCount = 8
SemanticTokenCount = 3
SuggestedFixCount = 49
-FunctionExtractionCount = 24
+FunctionExtractionCount = 25
MethodExtractionCount = 6
DefinitionsCount = 99
TypeDefinitionsCount = 18