mirror of
https://github.com/golang/go
synced 2024-09-30 16:08:36 -06:00
internal/lsp: de-duplicate logic for canExtractVariable
We'd like to call canExtractVariable in extractVariable without duplicating logic. The same needs to be done for canExtractFunction. Change-Id: Ia99befabbafffcf13dd3bc12355f9ddb81a71002 Reviewed-on: https://go-review.googlesource.com/c/tools/+/245135 Run-TryBot: Rebecca Stambler <rstambler@golang.org> Reviewed-by: Josh Baum <joshbaum@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
342ee1054f
commit
edd3c8e9e2
@ -105,7 +105,10 @@ var (
|
|||||||
Name: "extract_variable",
|
Name: "extract_variable",
|
||||||
Title: "Extract to variable",
|
Title: "Extract to variable",
|
||||||
suggestedFixFn: extractVariable,
|
suggestedFixFn: extractVariable,
|
||||||
appliesFn: canExtractVariable,
|
appliesFn: func(fset *token.FileSet, rng span.Range, src []byte, file *ast.File, pkg *types.Package, info *types.Info) bool {
|
||||||
|
_, _, ok, _ := canExtractVariable(fset, rng, src, file, pkg, info)
|
||||||
|
return ok
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandExtractFunction extracts statements to a function.
|
// CommandExtractFunction extracts statements to a function.
|
||||||
|
@ -22,22 +22,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func extractVariable(fset *token.FileSet, rng span.Range, src []byte, file *ast.File, pkg *types.Package, info *types.Info) (*analysis.SuggestedFix, error) {
|
func extractVariable(fset *token.FileSet, rng span.Range, src []byte, file *ast.File, pkg *types.Package, info *types.Info) (*analysis.SuggestedFix, error) {
|
||||||
if rng.Start == rng.End {
|
expr, path, ok, err := canExtractVariable(fset, rng, src, file, pkg, info)
|
||||||
return nil, fmt.Errorf("extractVariable: start and end are equal (%v)", fset.Position(rng.Start))
|
|
||||||
}
|
|
||||||
path, _ := astutil.PathEnclosingInterval(file, rng.Start, rng.End)
|
|
||||||
if len(path) == 0 {
|
|
||||||
return nil, fmt.Errorf("extractVariable: no path enclosing interval")
|
|
||||||
}
|
|
||||||
node := path[0]
|
|
||||||
if rng.Start != node.Pos() || rng.End != node.End() {
|
|
||||||
return nil, fmt.Errorf("extractVariable: node doesn't perfectly enclose range")
|
|
||||||
}
|
|
||||||
expr, ok := node.(ast.Expr)
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("extractVariable: node is not an expression")
|
return nil, fmt.Errorf("extractVariable: cannot extract %s: %v", fset.Position(rng.Start), err)
|
||||||
}
|
}
|
||||||
name := generateAvailableIdentifier(node.Pos(), file, path, info, "x", 0)
|
|
||||||
|
name := generateAvailableIdentifier(expr.Pos(), file, path, info, "x", 0)
|
||||||
|
|
||||||
// Create new AST node for extracted code.
|
// Create new AST node for extracted code.
|
||||||
var assignment string
|
var assignment string
|
||||||
@ -65,7 +55,7 @@ func extractVariable(fset *token.FileSet, rng span.Range, src []byte, file *ast.
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tok := fset.File(node.Pos())
|
tok := fset.File(expr.Pos())
|
||||||
if tok == nil {
|
if tok == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@ -88,22 +78,23 @@ func extractVariable(fset *token.FileSet, rng span.Range, src []byte, file *ast.
|
|||||||
|
|
||||||
// canExtractVariable reports whether the code in the given range can be
|
// canExtractVariable reports whether the code in the given range can be
|
||||||
// extracted to a variable.
|
// extracted to a variable.
|
||||||
// TODO(rstambler): De-duplicate the logic between extractVariable and
|
func canExtractVariable(fset *token.FileSet, rng span.Range, src []byte, file *ast.File, pkg *types.Package, info *types.Info) (ast.Expr, []ast.Node, bool, error) {
|
||||||
// canExtractVariable.
|
|
||||||
func canExtractVariable(fset *token.FileSet, rng span.Range, src []byte, file *ast.File, pkg *types.Package, info *types.Info) bool {
|
|
||||||
if rng.Start == rng.End {
|
if rng.Start == rng.End {
|
||||||
return false
|
return nil, nil, false, fmt.Errorf("start and end are equal")
|
||||||
}
|
}
|
||||||
path, _ := astutil.PathEnclosingInterval(file, rng.Start, rng.End)
|
path, _ := astutil.PathEnclosingInterval(file, rng.Start, rng.End)
|
||||||
if len(path) == 0 {
|
if len(path) == 0 {
|
||||||
return false
|
return nil, nil, false, fmt.Errorf("no path enclosing interval")
|
||||||
}
|
}
|
||||||
node := path[0]
|
node := path[0]
|
||||||
if rng.Start != node.Pos() || rng.End != node.End() {
|
if rng.Start != node.Pos() || rng.End != node.End() {
|
||||||
return false
|
return nil, nil, false, fmt.Errorf("range does not map to an AST node")
|
||||||
}
|
}
|
||||||
_, ok := node.(ast.Expr)
|
expr, ok := node.(ast.Expr)
|
||||||
return ok
|
if !ok {
|
||||||
|
return nil, nil, false, fmt.Errorf("node is not an expression")
|
||||||
|
}
|
||||||
|
return expr, path, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate indentation for insertion.
|
// Calculate indentation for insertion.
|
||||||
@ -415,7 +406,8 @@ func extractFunction(fset *token.FileSet, rng span.Range, src []byte, file *ast.
|
|||||||
hasReturnValues := len(returns)+len(retVars) > 0
|
hasReturnValues := len(returns)+len(retVars) > 0
|
||||||
if hasReturnValues {
|
if hasReturnValues {
|
||||||
extractedBlock.List = append(extractedBlock.List, &ast.ReturnStmt{
|
extractedBlock.List = append(extractedBlock.List, &ast.ReturnStmt{
|
||||||
Results: append(returns, getZeroVals(retVars)...)})
|
Results: append(returns, getZeroVals(retVars)...),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct the appropriate call to the extracted function.
|
// Construct the appropriate call to the extracted function.
|
||||||
|
Loading…
Reference in New Issue
Block a user