mirror of
https://github.com/golang/go
synced 2024-11-18 19:44:46 -07:00
internal/lsp/source: improve completion for "range" and "<-"
Now that we understand object "kind" for builtin generic functions, we can apply it to a couple more places as well: // prefer rangeable object kinds for i := range <> { } // prefer channels <- <> Change-Id: If9cfba3a06b3abde073a9d397000bb3f3b0e9853 Reviewed-on: https://go-review.googlesource.com/c/tools/+/214678 Run-TryBot: Muir Manders <muir@mnd.rs> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
parent
f80fb1dfa1
commit
473961ec04
@ -1290,7 +1290,6 @@ Nodes:
|
|||||||
}
|
}
|
||||||
if tv, ok := c.pkg.GetTypesInfo().Types[node.Lhs[i]]; ok {
|
if tv, ok := c.pkg.GetTypesInfo().Types[node.Lhs[i]]; ok {
|
||||||
inf.objType = tv.Type
|
inf.objType = tv.Type
|
||||||
break Nodes
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return inf
|
return inf
|
||||||
@ -1298,7 +1297,7 @@ Nodes:
|
|||||||
if node.Type != nil && c.pos > node.Type.End() {
|
if node.Type != nil && c.pos > node.Type.End() {
|
||||||
inf.objType = c.pkg.GetTypesInfo().TypeOf(node.Type)
|
inf.objType = c.pkg.GetTypesInfo().TypeOf(node.Type)
|
||||||
}
|
}
|
||||||
break Nodes
|
return inf
|
||||||
case *ast.CallExpr:
|
case *ast.CallExpr:
|
||||||
// Only consider CallExpr args if position falls between parens.
|
// Only consider CallExpr args if position falls between parens.
|
||||||
if node.Lparen <= c.pos && c.pos <= node.Rparen {
|
if node.Lparen <= c.pos && c.pos <= node.Rparen {
|
||||||
@ -1387,7 +1386,6 @@ Nodes:
|
|||||||
if resultIdx := indexExprAtPos(c.pos, node.Results); resultIdx < len(node.Results) {
|
if resultIdx := indexExprAtPos(c.pos, node.Results); resultIdx < len(node.Results) {
|
||||||
if resultIdx < sig.Results().Len() {
|
if resultIdx < sig.Results().Len() {
|
||||||
inf.objType = sig.Results().At(resultIdx).Type()
|
inf.objType = sig.Results().At(resultIdx).Type()
|
||||||
break Nodes
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1396,7 +1394,6 @@ Nodes:
|
|||||||
if swtch, ok := findSwitchStmt(c.path[i+1:], c.pos, node).(*ast.SwitchStmt); ok {
|
if swtch, ok := findSwitchStmt(c.path[i+1:], c.pos, node).(*ast.SwitchStmt); ok {
|
||||||
if tv, ok := c.pkg.GetTypesInfo().Types[swtch.Tag]; ok {
|
if tv, ok := c.pkg.GetTypesInfo().Types[swtch.Tag]; ok {
|
||||||
inf.objType = tv.Type
|
inf.objType = tv.Type
|
||||||
break Nodes
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return inf
|
return inf
|
||||||
@ -1404,7 +1401,6 @@ Nodes:
|
|||||||
// Make sure position falls within the brackets (e.g. "foo[a:<>]").
|
// Make sure position falls within the brackets (e.g. "foo[a:<>]").
|
||||||
if node.Lbrack < c.pos && c.pos <= node.Rbrack {
|
if node.Lbrack < c.pos && c.pos <= node.Rbrack {
|
||||||
inf.objType = types.Typ[types.Int]
|
inf.objType = types.Typ[types.Int]
|
||||||
break Nodes
|
|
||||||
}
|
}
|
||||||
return inf
|
return inf
|
||||||
case *ast.IndexExpr:
|
case *ast.IndexExpr:
|
||||||
@ -1416,10 +1412,7 @@ Nodes:
|
|||||||
inf.objType = t.Key()
|
inf.objType = t.Key()
|
||||||
case *types.Slice, *types.Array:
|
case *types.Slice, *types.Array:
|
||||||
inf.objType = types.Typ[types.Int]
|
inf.objType = types.Typ[types.Int]
|
||||||
default:
|
|
||||||
return inf
|
|
||||||
}
|
}
|
||||||
break Nodes
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return inf
|
return inf
|
||||||
@ -1429,11 +1422,18 @@ Nodes:
|
|||||||
if tv, ok := c.pkg.GetTypesInfo().Types[node.Chan]; ok {
|
if tv, ok := c.pkg.GetTypesInfo().Types[node.Chan]; ok {
|
||||||
if ch, ok := tv.Type.Underlying().(*types.Chan); ok {
|
if ch, ok := tv.Type.Underlying().(*types.Chan); ok {
|
||||||
inf.objType = ch.Elem()
|
inf.objType = ch.Elem()
|
||||||
break Nodes
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return inf
|
return inf
|
||||||
|
case *ast.RangeStmt:
|
||||||
|
if nodeContains(node.X, c.pos) {
|
||||||
|
inf.objKind |= kindSlice | kindArray | kindMap | kindString
|
||||||
|
if node.Value == nil {
|
||||||
|
inf.objKind |= kindChan
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return inf
|
||||||
case *ast.StarExpr:
|
case *ast.StarExpr:
|
||||||
inf.modifiers = append(inf.modifiers, typeModifier{mod: star})
|
inf.modifiers = append(inf.modifiers, typeModifier{mod: star})
|
||||||
case *ast.UnaryExpr:
|
case *ast.UnaryExpr:
|
||||||
@ -1442,6 +1442,7 @@ Nodes:
|
|||||||
inf.modifiers = append(inf.modifiers, typeModifier{mod: address})
|
inf.modifiers = append(inf.modifiers, typeModifier{mod: address})
|
||||||
case token.ARROW:
|
case token.ARROW:
|
||||||
inf.modifiers = append(inf.modifiers, typeModifier{mod: chanRead})
|
inf.modifiers = append(inf.modifiers, typeModifier{mod: chanRead})
|
||||||
|
inf.objKind |= kindChan
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if breaksExpectedTypeInference(node) {
|
if breaksExpectedTypeInference(node) {
|
||||||
|
34
internal/lsp/testdata/builtins/builtin_args.go
vendored
34
internal/lsp/testdata/builtins/builtin_args.go
vendored
@ -2,26 +2,26 @@ package builtins
|
|||||||
|
|
||||||
func _() {
|
func _() {
|
||||||
var (
|
var (
|
||||||
slice_ []int //@item(builtinSlice, "slice_", "[]int", "var")
|
aSlice []int //@item(builtinSlice, "aSlice", "[]int", "var")
|
||||||
map_ map[string]int //@item(builtinMap, "map_", "map[string]int", "var")
|
aMap map[string]int //@item(builtinMap, "aMap", "map[string]int", "var")
|
||||||
string_ string //@item(builtinString, "string_", "string", "var")
|
aString string //@item(builtinString, "aString", "string", "var")
|
||||||
array_ [0]int //@item(builtinArray, "array_", "[0]int", "var")
|
aArray [0]int //@item(builtinArray, "aArray", "[0]int", "var")
|
||||||
arrayPtr_ *[0]int //@item(builtinArrayPtr, "arrayPtr_", "*[0]int", "var")
|
aArrayPtr *[0]int //@item(builtinArrayPtr, "aArrayPtr", "*[0]int", "var")
|
||||||
chan_ chan int //@item(builtinChan, "chan_", "chan int", "var")
|
aChan chan int //@item(builtinChan, "aChan", "chan int", "var")
|
||||||
ptr_ *int //@item(builtinPtr, "ptr_", "*int", "var")
|
aPtr *int //@item(builtinPtr, "aPtr", "*int", "var")
|
||||||
int_ int //@item(builtinInt, "int_", "int", "var")
|
aInt int //@item(builtinInt, "aInt", "int", "var")
|
||||||
)
|
)
|
||||||
|
|
||||||
close() //@rank(")", builtinChan, builtinSlice)
|
close() //@rank(")", builtinChan, builtinSlice)
|
||||||
|
|
||||||
append() //@rank(")", builtinSlice, builtinChan)
|
append() //@rank(")", builtinSlice, builtinChan)
|
||||||
|
|
||||||
copy() //@rank(")", builtinSlice, builtinChan)
|
copy() //@rank(")", builtinSlice, builtinChan)
|
||||||
copy(slice_, s) //@rank(")", builtinSlice, builtinString)
|
copy(aSlice, aS) //@rank(")", builtinSlice, builtinString)
|
||||||
copy(s, slice_) //@rank(",", builtinSlice, builtinString)
|
copy(aS, aSlice) //@rank(",", builtinSlice, builtinString)
|
||||||
|
|
||||||
delete() //@rank(")", builtinMap, builtinChan)
|
delete() //@rank(")", builtinMap, builtinChan)
|
||||||
delete(map_, s) //@rank(")", builtinString, builtinSlice)
|
delete(aMap, aS) //@rank(")", builtinString, builtinSlice)
|
||||||
|
|
||||||
len() //@rank(")", builtinSlice, builtinInt),rank(")", builtinMap, builtinInt),rank(")", builtinString, builtinInt),rank(")", builtinArray, builtinInt),rank(")", builtinArrayPtr, builtinPtr),rank(")", builtinChan, builtinInt)
|
len() //@rank(")", builtinSlice, builtinInt),rank(")", builtinMap, builtinInt),rank(")", builtinString, builtinInt),rank(")", builtinArray, builtinInt),rank(")", builtinArrayPtr, builtinPtr),rank(")", builtinChan, builtinInt)
|
||||||
|
|
||||||
@ -34,4 +34,12 @@ func _() {
|
|||||||
type myStruct struct{} //@item(builtinStructType, "myStruct", "struct{...}", "struct")
|
type myStruct struct{} //@item(builtinStructType, "myStruct", "struct{...}", "struct")
|
||||||
new() //@rank(")", builtinStructType, builtinInt)
|
new() //@rank(")", builtinStructType, builtinInt)
|
||||||
var _ *myStruct = new() //@rank(")", builtinStructType, int)
|
var _ *myStruct = new() //@rank(")", builtinStructType, int)
|
||||||
|
|
||||||
|
for k := range a { //@rank(" {", builtinSlice, builtinInt),rank(" {", builtinString, builtinInt),rank(" {", builtinChan, builtinInt),rank(" {", builtinArray, builtinInt),rank(" {", builtinArrayPtr, builtinInt),rank(" {", builtinMap, builtinInt),
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range a { //@rank(" {", builtinSlice, builtinChan)
|
||||||
|
}
|
||||||
|
|
||||||
|
<-a //@rank(" //", builtinChan, builtinInt)
|
||||||
}
|
}
|
||||||
|
2
internal/lsp/testdata/summary.txt.golden
vendored
2
internal/lsp/testdata/summary.txt.golden
vendored
@ -4,7 +4,7 @@ CompletionSnippetCount = 63
|
|||||||
UnimportedCompletionsCount = 9
|
UnimportedCompletionsCount = 9
|
||||||
DeepCompletionsCount = 5
|
DeepCompletionsCount = 5
|
||||||
FuzzyCompletionsCount = 8
|
FuzzyCompletionsCount = 8
|
||||||
RankedCompletionsCount = 55
|
RankedCompletionsCount = 63
|
||||||
CaseSensitiveCompletionsCount = 4
|
CaseSensitiveCompletionsCount = 4
|
||||||
DiagnosticsCount = 35
|
DiagnosticsCount = 35
|
||||||
FoldingRangesCount = 2
|
FoldingRangesCount = 2
|
||||||
|
Loading…
Reference in New Issue
Block a user