зеркало из https://github.com/golang/tools.git
gopls/internal/golang/extract: preserve comments in extracted block
Use printer.CommentedNode to preserve comments in function and method extraction. Fixes golang/go#50851 Change-Id: I7d8aa2683c980e613592f64646f8077952ea61be Reviewed-on: https://go-review.googlesource.com/c/tools/+/629376 Reviewed-by: Alan Donovan <adonovan@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Родитель
8c3ba8c103
Коммит
9dff42e52e
|
@ -10,6 +10,7 @@ import (
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/format"
|
"go/format"
|
||||||
"go/parser"
|
"go/parser"
|
||||||
|
"go/printer"
|
||||||
"go/token"
|
"go/token"
|
||||||
"go/types"
|
"go/types"
|
||||||
"slices"
|
"slices"
|
||||||
|
@ -449,7 +450,8 @@ func extractFunctionMethod(fset *token.FileSet, start, end token.Pos, src []byte
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
selection := src[startOffset:endOffset]
|
selection := src[startOffset:endOffset]
|
||||||
extractedBlock, err := parseBlockStmt(fset, selection)
|
|
||||||
|
extractedBlock, extractedComments, err := parseStmts(fset, selection)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -570,40 +572,16 @@ func extractFunctionMethod(fset *token.FileSet, start, end token.Pos, src []byte
|
||||||
if canDefine {
|
if canDefine {
|
||||||
sym = token.DEFINE
|
sym = token.DEFINE
|
||||||
}
|
}
|
||||||
var name, funName string
|
var funName string
|
||||||
if isMethod {
|
if isMethod {
|
||||||
name = "newMethod"
|
|
||||||
// TODO(suzmue): generate a name that does not conflict for "newMethod".
|
// TODO(suzmue): generate a name that does not conflict for "newMethod".
|
||||||
funName = name
|
funName = "newMethod"
|
||||||
} else {
|
} else {
|
||||||
name = "newFunction"
|
funName, _ = generateAvailableName(start, path, pkg, info, "newFunction", 0)
|
||||||
funName, _ = generateAvailableName(start, path, pkg, info, name, 0)
|
|
||||||
}
|
}
|
||||||
extractedFunCall := generateFuncCall(hasNonNestedReturn, hasReturnValues, params,
|
extractedFunCall := generateFuncCall(hasNonNestedReturn, hasReturnValues, params,
|
||||||
append(returns, getNames(retVars)...), funName, sym, receiverName)
|
append(returns, getNames(retVars)...), funName, sym, receiverName)
|
||||||
|
|
||||||
// Build the extracted function.
|
|
||||||
newFunc := &ast.FuncDecl{
|
|
||||||
Name: ast.NewIdent(funName),
|
|
||||||
Type: &ast.FuncType{
|
|
||||||
Params: &ast.FieldList{List: paramTypes},
|
|
||||||
Results: &ast.FieldList{List: append(returnTypes, getDecls(retVars)...)},
|
|
||||||
},
|
|
||||||
Body: extractedBlock,
|
|
||||||
}
|
|
||||||
if isMethod {
|
|
||||||
var names []*ast.Ident
|
|
||||||
if receiverUsed {
|
|
||||||
names = append(names, ast.NewIdent(receiverName))
|
|
||||||
}
|
|
||||||
newFunc.Recv = &ast.FieldList{
|
|
||||||
List: []*ast.Field{{
|
|
||||||
Names: names,
|
|
||||||
Type: receiver.Type,
|
|
||||||
}},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create variable declarations for any identifiers that need to be initialized prior to
|
// Create variable declarations for any identifiers that need to be initialized prior to
|
||||||
// calling the extracted function. We do not manually initialize variables if every return
|
// calling the extracted function. We do not manually initialize variables if every return
|
||||||
// value is uninitialized. We can use := to initialize the variables in this situation.
|
// value is uninitialized. We can use := to initialize the variables in this situation.
|
||||||
|
@ -624,17 +602,49 @@ func extractFunctionMethod(fset *token.FileSet, start, end token.Pos, src []byte
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build the extracted function. We format the function declaration and body
|
||||||
|
// separately, so that comments are printed relative to the extracted
|
||||||
|
// BlockStmt.
|
||||||
|
//
|
||||||
|
// In other words, extractedBlock and extractedComments were parsed from a
|
||||||
|
// synthetic function declaration of the form func _() { ... }. If we now
|
||||||
|
// print the real function declaration, the length of the signature will have
|
||||||
|
// grown, causing some comment positions to be computed as inside the
|
||||||
|
// signature itself.
|
||||||
|
newFunc := &ast.FuncDecl{
|
||||||
|
Name: ast.NewIdent(funName),
|
||||||
|
Type: &ast.FuncType{
|
||||||
|
Params: &ast.FieldList{List: paramTypes},
|
||||||
|
Results: &ast.FieldList{List: append(returnTypes, getDecls(retVars)...)},
|
||||||
|
},
|
||||||
|
// Body handled separately -- see above.
|
||||||
|
}
|
||||||
|
if isMethod {
|
||||||
|
var names []*ast.Ident
|
||||||
|
if receiverUsed {
|
||||||
|
names = append(names, ast.NewIdent(receiverName))
|
||||||
|
}
|
||||||
|
newFunc.Recv = &ast.FieldList{
|
||||||
|
List: []*ast.Field{{
|
||||||
|
Names: names,
|
||||||
|
Type: receiver.Type,
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
}
|
||||||
if err := format.Node(&newFuncBuf, fset, newFunc); err != nil {
|
if err := format.Node(&newFuncBuf, fset, newFunc); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
// Find all the comments within the range and print them to be put somewhere.
|
// Write a space between the end of the function signature and opening '{'.
|
||||||
// TODO(suzmue): print these in the extracted function at the correct place.
|
if err := newFuncBuf.WriteByte(' '); err != nil {
|
||||||
for _, cg := range file.Comments {
|
return nil, nil, err
|
||||||
if cg.Pos().IsValid() && cg.Pos() < end && cg.Pos() >= start {
|
}
|
||||||
for _, c := range cg.List {
|
commentedNode := &printer.CommentedNode{
|
||||||
fmt.Fprintln(&commentBuf, c.Text)
|
Node: extractedBlock,
|
||||||
}
|
Comments: extractedComments,
|
||||||
}
|
}
|
||||||
|
if err := format.Node(&newFuncBuf, fset, commentedNode); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// We're going to replace the whole enclosing function,
|
// We're going to replace the whole enclosing function,
|
||||||
|
@ -1187,25 +1197,25 @@ func varOverridden(info *types.Info, firstUse *ast.Ident, obj types.Object, isFr
|
||||||
return isOverriden
|
return isOverriden
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseBlockStmt generates an AST file from the given text. We then return the portion of the
|
// parseStmts parses the specified source (a list of statements) and
|
||||||
// file that represents the text.
|
// returns them as a BlockStmt along with any associated comments.
|
||||||
func parseBlockStmt(fset *token.FileSet, src []byte) (*ast.BlockStmt, error) {
|
func parseStmts(fset *token.FileSet, src []byte) (*ast.BlockStmt, []*ast.CommentGroup, error) {
|
||||||
text := "package main\nfunc _() { " + string(src) + " }"
|
text := "package main\nfunc _() { " + string(src) + " }"
|
||||||
extract, err := parser.ParseFile(fset, "", text, parser.SkipObjectResolution)
|
file, err := parser.ParseFile(fset, "", text, parser.ParseComments|parser.SkipObjectResolution)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
if len(extract.Decls) == 0 {
|
if len(file.Decls) != 1 {
|
||||||
return nil, fmt.Errorf("parsed file does not contain any declarations")
|
return nil, nil, fmt.Errorf("got %d declarations, want 1", len(file.Decls))
|
||||||
}
|
}
|
||||||
decl, ok := extract.Decls[0].(*ast.FuncDecl)
|
decl, ok := file.Decls[0].(*ast.FuncDecl)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("parsed file does not contain expected function declaration")
|
return nil, nil, bug.Errorf("parsed file does not contain expected function declaration")
|
||||||
}
|
}
|
||||||
if decl.Body == nil {
|
if decl.Body == nil {
|
||||||
return nil, fmt.Errorf("extracted function has no body")
|
return nil, nil, bug.Errorf("extracted function has no body")
|
||||||
}
|
}
|
||||||
return decl.Body, nil
|
return decl.Body, file.Comments, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// generateReturnInfo generates the information we need to adjust the return statements and
|
// generateReturnInfo generates the information we need to adjust the return statements and
|
||||||
|
|
|
@ -237,20 +237,14 @@ func (b *B) LongListWithT(ctx context.Context, t *testing.T) (int, error) {
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
-- @contextFuncB/context.go --
|
-- @contextFuncB/context.go --
|
||||||
@@ -33 +33,6 @@
|
@@ -33 +33,4 @@
|
||||||
- sum := b.x + b.y //@loc(B_AddPWithB, re`(?s:^.*?Err\(\))`)
|
|
||||||
+ //@loc(B_AddPWithB, re`(?s:^.*?Err\(\))`)
|
|
||||||
+ return newFunction(ctx, tB, b)
|
+ return newFunction(ctx, tB, b)
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+func newFunction(ctx context.Context, tB *testing.B, b *B) (int, error) {
|
+func newFunction(ctx context.Context, tB *testing.B, b *B) (int, error) {
|
||||||
+ sum := b.x + b.y
|
|
||||||
-- @contextFuncT/context.go --
|
-- @contextFuncT/context.go --
|
||||||
@@ -42 +42,6 @@
|
@@ -42 +42,4 @@
|
||||||
- p4 := p1 + p2 //@loc(B_LongListWithT, re`(?s:^.*?Err\(\))`)
|
|
||||||
+ //@loc(B_LongListWithT, re`(?s:^.*?Err\(\))`)
|
|
||||||
+ return newFunction(ctx, t, p1, p2, p3)
|
+ return newFunction(ctx, t, p1, p2, p3)
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+func newFunction(ctx context.Context, t *testing.T, p1 int, p2 int, p3 int) (int, error) {
|
+func newFunction(ctx context.Context, t *testing.T, p1 int, p2 int, p3 int) (int, error) {
|
||||||
+ p4 := p1 + p2
|
|
||||||
|
|
|
@ -17,12 +17,11 @@ func _() { //@codeaction("{", "refactor.extract.function", end=closeBracket, res
|
||||||
package extract
|
package extract
|
||||||
|
|
||||||
func _() { //@codeaction("{", "refactor.extract.function", end=closeBracket, result=outer)
|
func _() { //@codeaction("{", "refactor.extract.function", end=closeBracket, result=outer)
|
||||||
//@codeaction("a", "refactor.extract.function", end=end, result=inner)
|
|
||||||
newFunction() //@loc(end, "4")
|
newFunction() //@loc(end, "4")
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction() {
|
func newFunction() {
|
||||||
a := 1
|
a := 1 //@codeaction("a", "refactor.extract.function", end=end, result=inner)
|
||||||
_ = a + 4
|
_ = a + 4
|
||||||
} //@loc(closeBracket, "}")
|
} //@loc(closeBracket, "}")
|
||||||
|
|
||||||
|
@ -30,12 +29,11 @@ func newFunction() {
|
||||||
package extract
|
package extract
|
||||||
|
|
||||||
func _() { //@codeaction("{", "refactor.extract.function", end=closeBracket, result=outer)
|
func _() { //@codeaction("{", "refactor.extract.function", end=closeBracket, result=outer)
|
||||||
//@codeaction("a", "refactor.extract.function", end=end, result=inner)
|
|
||||||
newFunction() //@loc(end, "4")
|
newFunction() //@loc(end, "4")
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction() {
|
func newFunction() {
|
||||||
a := 1
|
a := 1 //@codeaction("a", "refactor.extract.function", end=end, result=inner)
|
||||||
_ = a + 4
|
_ = a + 4
|
||||||
} //@loc(closeBracket, "}")
|
} //@loc(closeBracket, "}")
|
||||||
|
|
||||||
|
@ -55,7 +53,6 @@ package extract
|
||||||
|
|
||||||
func _() bool {
|
func _() bool {
|
||||||
x := 1
|
x := 1
|
||||||
//@codeaction("if", "refactor.extract.function", end=ifend, result=return)
|
|
||||||
shouldReturn, b := newFunction(x)
|
shouldReturn, b := newFunction(x)
|
||||||
if shouldReturn {
|
if shouldReturn {
|
||||||
return b
|
return b
|
||||||
|
@ -64,7 +61,7 @@ func _() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction(x int) (bool, bool) {
|
func newFunction(x int) (bool, bool) {
|
||||||
if x == 0 {
|
if x == 0 { //@codeaction("if", "refactor.extract.function", end=ifend, result=return)
|
||||||
return true, true
|
return true, true
|
||||||
}
|
}
|
||||||
return false, false
|
return false, false
|
||||||
|
@ -85,12 +82,11 @@ func _() bool {
|
||||||
package extract
|
package extract
|
||||||
|
|
||||||
func _() bool {
|
func _() bool {
|
||||||
//@codeaction("x", "refactor.extract.function", end=rnnEnd, result=rnn)
|
|
||||||
return newFunction() //@loc(rnnEnd, "false")
|
return newFunction() //@loc(rnnEnd, "false")
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction() bool {
|
func newFunction() bool {
|
||||||
x := 1
|
x := 1 //@codeaction("x", "refactor.extract.function", end=rnnEnd, result=rnn)
|
||||||
if x == 0 {
|
if x == 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -123,7 +119,6 @@ import "fmt"
|
||||||
func _() (int, string, error) {
|
func _() (int, string, error) {
|
||||||
x := 1
|
x := 1
|
||||||
y := "hello"
|
y := "hello"
|
||||||
//@codeaction("z", "refactor.extract.function", end=rcEnd, result=rc)
|
|
||||||
z, shouldReturn, i, s, err := newFunction(y, x)
|
z, shouldReturn, i, s, err := newFunction(y, x)
|
||||||
if shouldReturn {
|
if shouldReturn {
|
||||||
return i, s, err
|
return i, s, err
|
||||||
|
@ -132,7 +127,7 @@ func _() (int, string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction(y string, x int) (string, bool, int, string, error) {
|
func newFunction(y string, x int) (string, bool, int, string, error) {
|
||||||
z := "bye"
|
z := "bye" //@codeaction("z", "refactor.extract.function", end=rcEnd, result=rc)
|
||||||
if y == z {
|
if y == z {
|
||||||
return "", true, x, y, fmt.Errorf("same")
|
return "", true, x, y, fmt.Errorf("same")
|
||||||
} else if false {
|
} else if false {
|
||||||
|
@ -168,12 +163,11 @@ import "fmt"
|
||||||
func _() (int, string, error) {
|
func _() (int, string, error) {
|
||||||
x := 1
|
x := 1
|
||||||
y := "hello"
|
y := "hello"
|
||||||
//@codeaction("z", "refactor.extract.function", end=rcnnEnd, result=rcnn)
|
|
||||||
return newFunction(y, x) //@loc(rcnnEnd, "nil")
|
return newFunction(y, x) //@loc(rcnnEnd, "nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction(y string, x int) (int, string, error) {
|
func newFunction(y string, x int) (int, string, error) {
|
||||||
z := "bye"
|
z := "bye" //@codeaction("z", "refactor.extract.function", end=rcnnEnd, result=rcnn)
|
||||||
if y == z {
|
if y == z {
|
||||||
return x, y, fmt.Errorf("same")
|
return x, y, fmt.Errorf("same")
|
||||||
} else if false {
|
} else if false {
|
||||||
|
@ -204,7 +198,6 @@ import "go/ast"
|
||||||
|
|
||||||
func _() {
|
func _() {
|
||||||
ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool {
|
ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool {
|
||||||
//@codeaction("if", "refactor.extract.function", end=rflEnd, result=rfl)
|
|
||||||
shouldReturn, b := newFunction(n)
|
shouldReturn, b := newFunction(n)
|
||||||
if shouldReturn {
|
if shouldReturn {
|
||||||
return b
|
return b
|
||||||
|
@ -214,7 +207,7 @@ func _() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction(n ast.Node) (bool, bool) {
|
func newFunction(n ast.Node) (bool, bool) {
|
||||||
if n == nil {
|
if n == nil { //@codeaction("if", "refactor.extract.function", end=rflEnd, result=rfl)
|
||||||
return true, true
|
return true, true
|
||||||
}
|
}
|
||||||
return false, false
|
return false, false
|
||||||
|
@ -241,13 +234,12 @@ import "go/ast"
|
||||||
|
|
||||||
func _() {
|
func _() {
|
||||||
ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool {
|
ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool {
|
||||||
//@codeaction("if", "refactor.extract.function", end=rflnnEnd, result=rflnn)
|
|
||||||
return newFunction(n) //@loc(rflnnEnd, "false")
|
return newFunction(n) //@loc(rflnnEnd, "false")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction(n ast.Node) bool {
|
func newFunction(n ast.Node) bool {
|
||||||
if n == nil {
|
if n == nil { //@codeaction("if", "refactor.extract.function", end=rflnnEnd, result=rflnn)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
@ -271,7 +263,6 @@ package extract
|
||||||
|
|
||||||
func _() string {
|
func _() string {
|
||||||
x := 1
|
x := 1
|
||||||
//@codeaction("if", "refactor.extract.function", end=riEnd, result=ri)
|
|
||||||
shouldReturn, s := newFunction(x)
|
shouldReturn, s := newFunction(x)
|
||||||
if shouldReturn {
|
if shouldReturn {
|
||||||
return s
|
return s
|
||||||
|
@ -281,7 +272,7 @@ func _() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction(x int) (bool, string) {
|
func newFunction(x int) (bool, string) {
|
||||||
if x == 0 {
|
if x == 0 { //@codeaction("if", "refactor.extract.function", end=riEnd, result=ri)
|
||||||
x = 3
|
x = 3
|
||||||
return true, "a"
|
return true, "a"
|
||||||
}
|
}
|
||||||
|
@ -306,12 +297,11 @@ package extract
|
||||||
|
|
||||||
func _() string {
|
func _() string {
|
||||||
x := 1
|
x := 1
|
||||||
//@codeaction("if", "refactor.extract.function", end=rinnEnd, result=rinn)
|
|
||||||
return newFunction(x) //@loc(rinnEnd, "\"b\"")
|
return newFunction(x) //@loc(rinnEnd, "\"b\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction(x int) string {
|
func newFunction(x int) string {
|
||||||
if x == 0 {
|
if x == 0 { //@codeaction("if", "refactor.extract.function", end=rinnEnd, result=rinn)
|
||||||
x = 3
|
x = 3
|
||||||
return "a"
|
return "a"
|
||||||
}
|
}
|
||||||
|
@ -336,7 +326,6 @@ package extract
|
||||||
|
|
||||||
func _() {
|
func _() {
|
||||||
a := 1
|
a := 1
|
||||||
//@codeaction("a", "refactor.extract.function", end=araend, result=ara)
|
|
||||||
a = newFunction(a) //@loc(araend, "2")
|
a = newFunction(a) //@loc(araend, "2")
|
||||||
|
|
||||||
b := a * 2 //@codeaction("b", "refactor.extract.function", end=arbend, result=arb)
|
b := a * 2 //@codeaction("b", "refactor.extract.function", end=arbend, result=arb)
|
||||||
|
@ -344,7 +333,7 @@ func _() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction(a int) int {
|
func newFunction(a int) int {
|
||||||
a = 5
|
a = 5 //@codeaction("a", "refactor.extract.function", end=araend, result=ara)
|
||||||
a = a + 2
|
a = a + 2
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
@ -357,12 +346,11 @@ func _() {
|
||||||
a = 5 //@codeaction("a", "refactor.extract.function", end=araend, result=ara)
|
a = 5 //@codeaction("a", "refactor.extract.function", end=araend, result=ara)
|
||||||
a = a + 2 //@loc(araend, "2")
|
a = a + 2 //@loc(araend, "2")
|
||||||
|
|
||||||
//@codeaction("b", "refactor.extract.function", end=arbend, result=arb)
|
|
||||||
newFunction(a) //@loc(arbend, "4")
|
newFunction(a) //@loc(arbend, "4")
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction(a int) {
|
func newFunction(a int) {
|
||||||
b := a * 2
|
b := a * 2 //@codeaction("b", "refactor.extract.function", end=arbend, result=arb)
|
||||||
_ = b + 4
|
_ = b + 4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,13 +400,12 @@ package extract
|
||||||
|
|
||||||
func _() {
|
func _() {
|
||||||
var a []int
|
var a []int
|
||||||
//@codeaction("a", "refactor.extract.function", end=siEnd, result=si)
|
|
||||||
a, b := newFunction(a) //@loc(siEnd, "4")
|
a, b := newFunction(a) //@loc(siEnd, "4")
|
||||||
a = append(a, b)
|
a = append(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction(a []int) ([]int, int) {
|
func newFunction(a []int) ([]int, int) {
|
||||||
a = append(a, 2)
|
a = append(a, 2) //@codeaction("a", "refactor.extract.function", end=siEnd, result=si)
|
||||||
b := 4
|
b := 4
|
||||||
return a, b
|
return a, b
|
||||||
}
|
}
|
||||||
|
@ -441,13 +428,12 @@ package extract
|
||||||
func _() {
|
func _() {
|
||||||
var b []int
|
var b []int
|
||||||
var a int
|
var a int
|
||||||
//@codeaction("a", "refactor.extract.function", end=srEnd, result=sr)
|
|
||||||
b = newFunction(a, b) //@loc(srEnd, ")")
|
b = newFunction(a, b) //@loc(srEnd, ")")
|
||||||
b[0] = 1
|
b[0] = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction(a int, b []int) []int {
|
func newFunction(a int, b []int) []int {
|
||||||
a = 2
|
a = 2 //@codeaction("a", "refactor.extract.function", end=srEnd, result=sr)
|
||||||
b = []int{}
|
b = []int{}
|
||||||
b = append(b, a)
|
b = append(b, a)
|
||||||
return b
|
return b
|
||||||
|
@ -472,7 +458,6 @@ package extract
|
||||||
|
|
||||||
func _() {
|
func _() {
|
||||||
var b []int
|
var b []int
|
||||||
//@codeaction("a", "refactor.extract.function", end=upEnd, result=up)
|
|
||||||
a, b := newFunction(b) //@loc(upEnd, ")")
|
a, b := newFunction(b) //@loc(upEnd, ")")
|
||||||
b[0] = 1
|
b[0] = 1
|
||||||
if a == 2 {
|
if a == 2 {
|
||||||
|
@ -481,7 +466,7 @@ func _() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction(b []int) (int, []int) {
|
func newFunction(b []int) (int, []int) {
|
||||||
a := 2
|
a := 2 //@codeaction("a", "refactor.extract.function", end=upEnd, result=up)
|
||||||
b = []int{}
|
b = []int{}
|
||||||
b = append(b, a)
|
b = append(b, a)
|
||||||
return a, b
|
return a, b
|
||||||
|
@ -503,9 +488,6 @@ func _() {
|
||||||
package extract
|
package extract
|
||||||
|
|
||||||
func _() {
|
func _() {
|
||||||
/* comment in the middle of a line */
|
|
||||||
//@codeaction("a", "refactor.extract.function", end=commentEnd, result=comment1)
|
|
||||||
// Comment on its own line //@codeaction("Comment", "refactor.extract.function", end=commentEnd, result=comment2)
|
|
||||||
newFunction() //@loc(commentEnd, "4"),codeaction("_", "refactor.extract.function", end=lastComment, result=comment3)
|
newFunction() //@loc(commentEnd, "4"),codeaction("_", "refactor.extract.function", end=lastComment, result=comment3)
|
||||||
// Comment right after 3 + 4
|
// Comment right after 3 + 4
|
||||||
|
|
||||||
|
@ -513,8 +495,8 @@ func _() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction() {
|
func newFunction() {
|
||||||
a := 1
|
a := /* comment in the middle of a line */ 1 //@codeaction("a", "refactor.extract.function", end=commentEnd, result=comment1)
|
||||||
|
// Comment on its own line //@codeaction("Comment", "refactor.extract.function", end=commentEnd, result=comment2)
|
||||||
_ = a + 4
|
_ = a + 4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,12 +584,11 @@ import "slices"
|
||||||
|
|
||||||
// issue go#64821
|
// issue go#64821
|
||||||
func _() {
|
func _() {
|
||||||
//@codeaction("var", "refactor.extract.function", end=anonEnd, result=anon1)
|
|
||||||
newFunction() //@loc(anonEnd, ")")
|
newFunction() //@loc(anonEnd, ")")
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction() {
|
func newFunction() {
|
||||||
var s []string
|
var s []string //@codeaction("var", "refactor.extract.function", end=anonEnd, result=anon1)
|
||||||
slices.SortFunc(s, func(a, b string) int {
|
slices.SortFunc(s, func(a, b string) int {
|
||||||
return cmp.Compare(a, b)
|
return cmp.Compare(a, b)
|
||||||
})
|
})
|
||||||
|
|
|
@ -26,13 +26,12 @@ package extract
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
//@codeaction("x", "refactor.extract.function", end=end, result=ext)
|
|
||||||
x := newFunction() //@loc(end, "}")
|
x := newFunction() //@loc(end, "}")
|
||||||
fmt.Printf("%x\n", x)
|
fmt.Printf("%x\n", x)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction() []rune {
|
func newFunction() []rune {
|
||||||
x := []rune{}
|
x := []rune{} //@codeaction("x", "refactor.extract.function", end=end, result=ext)
|
||||||
s := "HELLO"
|
s := "HELLO"
|
||||||
for _, c := range s {
|
for _, c := range s {
|
||||||
x = append(x, c)
|
x = append(x, c)
|
||||||
|
|
35
gopls/internal/test/marker/testdata/codeaction/functionextraction_issue50851.txt
поставляемый
Normal file
35
gopls/internal/test/marker/testdata/codeaction/functionextraction_issue50851.txt
поставляемый
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
This test checks that function extraction moves comments along with the
|
||||||
|
extracted code.
|
||||||
|
|
||||||
|
-- main.go --
|
||||||
|
package main
|
||||||
|
|
||||||
|
type F struct{}
|
||||||
|
|
||||||
|
func (f *F) func1() {
|
||||||
|
println("a")
|
||||||
|
|
||||||
|
println("b") //@ codeaction("print", "refactor.extract.function", end=end, result=result)
|
||||||
|
// This line prints the third letter of the alphabet.
|
||||||
|
println("c") //@loc(end, ")")
|
||||||
|
|
||||||
|
println("d")
|
||||||
|
}
|
||||||
|
-- @result/main.go --
|
||||||
|
package main
|
||||||
|
|
||||||
|
type F struct{}
|
||||||
|
|
||||||
|
func (f *F) func1() {
|
||||||
|
println("a")
|
||||||
|
|
||||||
|
newFunction() //@loc(end, ")")
|
||||||
|
|
||||||
|
println("d")
|
||||||
|
}
|
||||||
|
|
||||||
|
func newFunction() {
|
||||||
|
println("b") //@ codeaction("print", "refactor.extract.function", end=end, result=result)
|
||||||
|
// This line prints the third letter of the alphabet.
|
||||||
|
println("c")
|
||||||
|
}
|
|
@ -29,7 +29,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func F() error {
|
func F() error {
|
||||||
//@codeaction("a", "refactor.extract.function", end=endF, result=F)
|
|
||||||
a, b, shouldReturn, err := newFunction()
|
a, b, shouldReturn, err := newFunction()
|
||||||
if shouldReturn {
|
if shouldReturn {
|
||||||
return err
|
return err
|
||||||
|
@ -39,7 +38,7 @@ func F() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction() ([]byte, []byte, bool, error) {
|
func newFunction() ([]byte, []byte, bool, error) {
|
||||||
a, err := json.Marshal(0)
|
a, err := json.Marshal(0) //@codeaction("a", "refactor.extract.function", end=endF, result=F)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, true, fmt.Errorf("1: %w", err)
|
return nil, nil, true, fmt.Errorf("1: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -78,7 +77,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func G() (x, y int) {
|
func G() (x, y int) {
|
||||||
//@codeaction("v", "refactor.extract.function", end=endG, result=G)
|
|
||||||
v, shouldReturn, x1, y1 := newFunction()
|
v, shouldReturn, x1, y1 := newFunction()
|
||||||
if shouldReturn {
|
if shouldReturn {
|
||||||
return x1, y1
|
return x1, y1
|
||||||
|
@ -88,7 +86,7 @@ func G() (x, y int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFunction() (int, bool, int, int) {
|
func newFunction() (int, bool, int, int) {
|
||||||
v := rand.Int()
|
v := rand.Int() //@codeaction("v", "refactor.extract.function", end=endG, result=G)
|
||||||
if v < 0 {
|
if v < 0 {
|
||||||
return 0, true, 1, 2
|
return 0, true, 1, 2
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче