Implement type command (#19944)

* Implement type command

- this will be mapped to textDocument/typeDefinition in LSP protocol. It will be
very useful for `nim` in particular because typically most of the time the type
is inferred.

* Update nimsuggest/nimsuggest.nim

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
Ivan Yonchovski 2022-07-15 20:56:05 +03:00 • committed by GitHub
commit e636c211b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 47 additions and 3 deletions

View file

@ -192,7 +192,7 @@ type
IdeCmd* = enum IdeCmd* = enum
ideNone, ideSug, ideCon, ideDef, ideUse, ideDus, ideChk, ideChkFile, ideMod, ideNone, ideSug, ideCon, ideDef, ideUse, ideDus, ideChk, ideChkFile, ideMod,
ideHighlight, ideOutline, ideKnown, ideMsg, ideProject, ideGlobalSymbols, ideHighlight, ideOutline, ideKnown, ideMsg, ideProject, ideGlobalSymbols,
ideRecompile, ideChanged ideRecompile, ideChanged, ideType
Feature* = enum ## experimental features; DO NOT RENAME THESE! Feature* = enum ## experimental features; DO NOT RENAME THESE!
implicitDeref, implicitDeref,
@ -1006,6 +1006,7 @@ proc parseIdeCmd*(s: string): IdeCmd =
of "globalSymbols": ideGlobalSymbols of "globalSymbols": ideGlobalSymbols
of "recompile": ideRecompile of "recompile": ideRecompile
of "changed": ideChanged of "changed": ideChanged
of "type": ideType
else: ideNone else: ideNone
proc `$`*(c: IdeCmd): string = proc `$`*(c: IdeCmd): string =
@ -1027,6 +1028,7 @@ proc `$`*(c: IdeCmd): string =
of ideGlobalSymbols: "globalSymbols" of ideGlobalSymbols: "globalSymbols"
of ideRecompile: "recompile" of ideRecompile: "recompile"
of ideChanged: "changed" of ideChanged: "changed"
of ideType: "type"
proc floatInt64Align*(conf: ConfigRef): int16 = proc floatInt64Align*(conf: ConfigRef): int16 =
## Returns either 4 or 8 depending on reasons. ## Returns either 4 or 8 depending on reasons.

View file

@ -457,6 +457,7 @@ proc execCmd(cmd: string; graph: ModuleGraph; cachedMsgs: CachedMsgs) =
of "globalsymbols": conf.ideCmd = ideGlobalSymbols of "globalsymbols": conf.ideCmd = ideGlobalSymbols
of "chkfile": conf.ideCmd = ideChkFile of "chkfile": conf.ideCmd = ideChkFile
of "recompile": conf.ideCmd = ideRecompile of "recompile": conf.ideCmd = ideRecompile
of "type": conf.ideCmd = ideType
else: err() else: err()
var dirtyfile = "" var dirtyfile = ""
var orig = "" var orig = ""
@ -786,7 +787,7 @@ proc executeNoHooksV3(cmd: IdeCmd, file: AbsoluteFile, dirtyfile: AbsoluteFile,
graph.unmarkAllDirty() graph.unmarkAllDirty()
# these commands require partially compiled project # these commands require partially compiled project
elif cmd in {ideSug, ideOutline, ideHighlight, ideDef, ideChkFile} and elif cmd in {ideSug, ideOutline, ideHighlight, ideDef, ideChkFile, ideType} and
(graph.needsCompilation(fileIndex) or cmd == ideSug): (graph.needsCompilation(fileIndex) or cmd == ideSug):
# for ideSug use v2 implementation # for ideSug use v2 implementation
if cmd == ideSug: if cmd == ideSug:
@ -802,6 +803,15 @@ proc executeNoHooksV3(cmd: IdeCmd, file: AbsoluteFile, dirtyfile: AbsoluteFile,
let (sym, info) = graph.findSymData(file, line, col) let (sym, info) = graph.findSymData(file, line, col)
if sym != nil: if sym != nil:
graph.suggestResult(sym, sym.info) graph.suggestResult(sym, sym.info)
of ideType:
let (sym, _) = graph.findSymData(file, line, col)
if sym != nil:
let typeSym = sym.typ.sym
if typeSym != nil:
graph.suggestResult(typeSym, typeSym.info, ideType)
elif sym.typ.len != 0:
let genericType = sym.typ[0].sym
graph.suggestResult(genericType, genericType.info, ideType)
of ideUse, ideDus: of ideUse, ideDus:
let symbol = graph.findSymData(file, line, col).sym let symbol = graph.findSymData(file, line, col).sym
if symbol != nil: if symbol != nil:

View file

@ -282,7 +282,7 @@ proc runEpcTest(filename: string): int =
socket.sendEpcStr(req) socket.sendEpcStr(req)
let sx = parseSexp(socket.recvEpc()) let sx = parseSexp(socket.recvEpc())
if not req.startsWith("mod "): if not req.startsWith("mod "):
let answer = sexpToAnswer(sx) let answer = if sx[2].kind == SNil: "" else: sexpToAnswer(sx)
doReport(filename, answer, resp, report) doReport(filename, answer, resp, report)
socket.sendEpcStr "return arg" socket.sendEpcStr "return arg"

View file

@ -0,0 +1,32 @@
# tests v3
type
Foo* = ref object of RootObj
bar*: string
proc test(ff: Foo) =
echo f#[!]#f.bar
type
Fo#[!]#o2* = ref object of RootObj
type
FooGeneric[T] = ref object of RootObj
bar*: T
let fooGeneric = FooGeneric[string]()
echo fo#[!]#oGeneric.bar
# bad type
echo unde#[!]#fined
discard """
$nimsuggest --v3 --tester $file
>type $1
type skType tv3_typeDefinition.Foo Foo $file 4 2 "" 100
>type $2
type skType tv3_typeDefinition.Foo2 Foo2 $file 11 2 "" 100
>type $3
type skType tv3_typeDefinition.FooGeneric FooGeneric $file 14 2 "" 100
>type $4
"""