Skip to content

Commit de675d5

Browse files
committed
tools/gopls: argument in function bodies marked as parameter by semantic tokens
In func f(x int) int {return x;} the second x used to be marked as a variable, but now is marked as a parameter, visually tying it to its definition. Fixes golang/go#56257 Change-Id: I8aa506b1ddff5ed9a3d2716d48c64521bdea0fd5 Reviewed-on: https://go-review.googlesource.com/c/tools/+/445095 Reviewed-by: Robert Findley <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Peter Weinberger <[email protected]> gopls-CI: kokoro <[email protected]>
1 parent 3e1371f commit de675d5

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

gopls/internal/lsp/semantic.go

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,9 +526,14 @@ func (e *encoded) ident(x *ast.Ident) {
526526
tok(x.Pos(), len(x.Name), tokFunction, nil)
527527
} else if _, ok := y.Type().(*typeparams.TypeParam); ok {
528528
tok(x.Pos(), len(x.Name), tokTypeParam, nil)
529+
} else if e.isParam(use.Pos()) {
530+
// variable, unless use.pos is the pos of a Field in an ancestor FuncDecl
531+
// or FuncLit and then it's a parameter
532+
tok(x.Pos(), len(x.Name), tokParameter, nil)
529533
} else {
530534
tok(x.Pos(), len(x.Name), tokVariable, nil)
531535
}
536+
532537
default:
533538
// can't happen
534539
if use == nil {
@@ -543,6 +548,30 @@ func (e *encoded) ident(x *ast.Ident) {
543548
}
544549
}
545550

551+
func (e *encoded) isParam(pos token.Pos) bool {
552+
for i := len(e.stack) - 1; i >= 0; i-- {
553+
switch n := e.stack[i].(type) {
554+
case *ast.FuncDecl:
555+
for _, f := range n.Type.Params.List {
556+
for _, id := range f.Names {
557+
if id.Pos() == pos {
558+
return true
559+
}
560+
}
561+
}
562+
case *ast.FuncLit:
563+
for _, f := range n.Type.Params.List {
564+
for _, id := range f.Names {
565+
if id.Pos() == pos {
566+
return true
567+
}
568+
}
569+
}
570+
}
571+
}
572+
return false
573+
}
574+
546575
func isSignature(use types.Object) bool {
547576
if true {
548577
return false //PJW: fix after generics seem ok
@@ -640,7 +669,7 @@ func (e *encoded) unkIdent(x *ast.Ident) (tokenType, []string) {
640669
if nd.Tok != token.DEFINE {
641670
def = nil
642671
}
643-
return tokVariable, def
672+
return tokVariable, def // '_' in _ = ...
644673
}
645674
}
646675
// RHS, = x

gopls/internal/lsp/testdata/semantic/a.go.golden

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,17 @@
6565
/*⇒2,variable,[definition]*/ff /*⇒2,operator,[]*/:= /*⇒4,keyword,[]*/func() {}
6666
/*⇒5,keyword,[]*/defer /*⇒2,variable,[]*/ff()
6767
/*⇒2,keyword,[]*/go /*⇒3,namespace,[]*/utf./*⇒9,function,[]*/RuneCount(/*⇒2,string,[]*/"")
68-
/*⇒2,keyword,[]*/go /*⇒4,namespace,[]*/utf8./*⇒9,function,[]*/RuneCount(/*⇒2,variable,[]*/vv.(/*⇒6,type,[]*/string))
68+
/*⇒2,keyword,[]*/go /*⇒4,namespace,[]*/utf8./*⇒9,function,[]*/RuneCount(/*⇒2,parameter,[]*/vv.(/*⇒6,type,[]*/string))
6969
/*⇒2,keyword,[]*/if /*⇒4,variable,[readonly]*/true {
7070
} /*⇒4,keyword,[]*/else {
7171
}
7272
/*⇒5,parameter,[definition]*/Never:
7373
/*⇒3,keyword,[]*/for /*⇒1,variable,[definition]*/i /*⇒2,operator,[]*/:= /*⇒1,number,[]*/0; /*⇒1,variable,[]*/i /*⇒1,operator,[]*/< /*⇒2,number,[]*/10; {
7474
/*⇒5,keyword,[]*/break Never
7575
}
76-
_, /*⇒2,variable,[definition]*/ok /*⇒2,operator,[]*/:= /*⇒2,variable,[]*/vv[/*⇒1,number,[]*/0].(/*⇒1,type,[]*/A)
76+
_, /*⇒2,variable,[definition]*/ok /*⇒2,operator,[]*/:= /*⇒2,parameter,[]*/vv[/*⇒1,number,[]*/0].(/*⇒1,type,[]*/A)
7777
/*⇒2,keyword,[]*/if /*⇒1,operator,[]*/!/*⇒2,variable,[]*/ok {
78-
/*⇒6,keyword,[]*/switch /*⇒1,variable,[definition]*/x /*⇒2,operator,[]*/:= /*⇒2,variable,[]*/vv[/*⇒1,number,[]*/0].(/*⇒4,keyword,[]*/type) {
78+
/*⇒6,keyword,[]*/switch /*⇒1,variable,[definition]*/x /*⇒2,operator,[]*/:= /*⇒2,parameter,[]*/vv[/*⇒1,number,[]*/0].(/*⇒4,keyword,[]*/type) {
7979
}
8080
/*⇒4,keyword,[]*/goto Never
8181
}

0 commit comments

Comments
 (0)