internal/lsp: suggest "fallthrough" only inside switches
Change-Id: I3a6ddbc12e068da151699a1d0377670695dcf5aa
Reviewed-on: https://go-review.googlesource.com/c/tools/+/210358
Run-TryBot: Iskander Sharipov <quasilyte@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
diff --git a/internal/lsp/source/completion_keywords.go b/internal/lsp/source/completion_keywords.go
index ef787b7..526de65 100644
--- a/internal/lsp/source/completion_keywords.go
+++ b/internal/lsp/source/completion_keywords.go
@@ -55,14 +55,22 @@
// Filter out keywords depending on scope
// Skip the first one because we want to look at the enclosing scopes
- for _, n := range c.path[1:] {
+ path := c.path[1:]
+ for i, n := range path {
switch node := n.(type) {
case *ast.CaseClause:
// only recommend "fallthrough" and "break" within the bodies of a case clause
if c.pos > node.Colon {
valid[BREAK] = stdScore
- // TODO: "fallthrough" is only valid in switch statements
- valid[FALLTHROUGH] = stdScore
+ // "fallthrough" is only valid in switch statements.
+ // A case clause is always nested within a block statement in a switch statement,
+ // that block statement is nested within either a TypeSwitchStmt or a SwitchStmt.
+ if i+2 >= len(path) {
+ continue
+ }
+ if _, ok := path[i+2].(*ast.SwitchStmt); ok {
+ valid[FALLTHROUGH] = stdScore
+ }
}
case *ast.CommClause:
if c.pos > node.Colon {
diff --git a/internal/lsp/testdata/keywords/keywords.go b/internal/lsp/testdata/keywords/keywords.go
index ce3bfdc..5fda68d 100644
--- a/internal/lsp/testdata/keywords/keywords.go
+++ b/internal/lsp/testdata/keywords/keywords.go
@@ -17,7 +17,7 @@
case int:
b //@complete(" //", break)
case int32:
- f //@complete(" //", fallthrough, for)
+ f //@complete(" //", for)
d //@complete(" //", default, defer)
r //@complete(" //", return)
c //@complete(" //", case, const)