internal/lsp/source: do not allow extraction of an import spec

Fixes golang/go#40635

Change-Id: Iab8ca37d251a95334c19f32873f9ba9cc1bdd2f4
Reviewed-on: https://go-review.googlesource.com/c/tools/+/251018
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
diff --git a/internal/lsp/source/extract.go b/internal/lsp/source/extract.go
index 76bfc8b..0c30fd5 100644
--- a/internal/lsp/source/extract.go
+++ b/internal/lsp/source/extract.go
@@ -31,10 +31,9 @@
 	var lhsNames []string
 	switch expr := expr.(type) {
 	// TODO: stricter rules for selectorExpr.
-	case *ast.BasicLit, *ast.CompositeLit, *ast.IndexExpr, *ast.SliceExpr, *ast.UnaryExpr,
-		*ast.BinaryExpr, *ast.SelectorExpr:
-		lhsNames = append(lhsNames,
-			generateAvailableIdentifier(expr.Pos(), file, path, info, "x", 0))
+	case *ast.BasicLit, *ast.CompositeLit, *ast.IndexExpr, *ast.SliceExpr,
+		*ast.UnaryExpr, *ast.BinaryExpr, *ast.SelectorExpr:
+		lhsNames = append(lhsNames, generateAvailableIdentifier(expr.Pos(), file, path, info, "x", 0))
 	case *ast.CallExpr:
 		tup, ok := info.TypeOf(expr).(*types.Tuple)
 		if !ok {
@@ -101,6 +100,11 @@
 	if len(path) == 0 {
 		return nil, nil, false, fmt.Errorf("no path enclosing interval")
 	}
+	for _, n := range path {
+		if _, ok := n.(*ast.ImportSpec); ok {
+			return nil, nil, false, fmt.Errorf("cannot extract variable in an import block")
+		}
+	}
 	node := path[0]
 	if rng.Start != node.Pos() || rng.End != node.End() {
 		return nil, nil, false, fmt.Errorf("range does not map to an AST node")