summary refs log tree commit diff stats
diff options
context:
space:
mode:
authoralaviss <leorize+oss@disroot.org>2020-10-14 10:08:56 -0500
committerGitHub <noreply@github.com>2020-10-14 17:08:56 +0200
commitc2ba4ef9799a097fec8b2bb1b033448860d60f1b (patch)
tree62c4a458ad3060a8f6983b04562d29e59f25f25c
parent977bccdbff9db889bebfa963d1292c4d433f6779 (diff)
downloadNim-c2ba4ef9799a097fec8b2bb1b033448860d60f1b.tar.gz
suggest: try to find the implementation of a symbol when def is used (#15555)
* suggest: try to find the implementation of a symbol when def is used

* suggest: return all declarations of the symbol on `def`
-rw-r--r--changelog.md4
-rw-r--r--compiler/semstmts.nim1
-rw-r--r--compiler/suggest.nim22
-rw-r--r--nimsuggest/tests/tdef_forward.nim13
4 files changed, 33 insertions, 7 deletions
diff --git a/changelog.md b/changelog.md
index 694d9635f..2c8f9b5e2 100644
--- a/changelog.md
+++ b/changelog.md
@@ -361,3 +361,7 @@ proc mydiv(a, b): int {.raises: [].} =
 
 
 ## Tool changes
+
+- `nimsuggest` will now return both the forward declaration and the
+  implementation location upon a `def` query. Previously the behavior was
+  just to return the forward declaration.
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 44a31c2ea..27cd9019f 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -1943,6 +1943,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
     if not comesFromShadowScope:
       excl(proto.flags, sfForward)
       incl(proto.flags, sfWasForwarded)
+    suggestSym(c.config, s.info, proto, c.graph.usageSym)
     closeScope(c)         # close scope with wrong parameter symbols
     openScope(c)          # open scope for old (correct) parameter symbols
     if proto.ast[genericParamsPos].kind != nkEmpty:
diff --git a/compiler/suggest.nim b/compiler/suggest.nim
index 4943603ce..be337af12 100644
--- a/compiler/suggest.nim
+++ b/compiler/suggest.nim
@@ -119,7 +119,8 @@ proc getTokenLenFromSource(conf: ConfigRef; ident: string; info: TLineInfo): int
 
 proc symToSuggest(conf: ConfigRef; s: PSym, isLocal: bool, section: IdeCmd, info: TLineInfo;
                   quality: range[0..100]; prefix: PrefixMatch;
-                  inTypeContext: bool; scope: int): Suggest =
+                  inTypeContext: bool; scope: int;
+                  useSuppliedInfo = false): Suggest =
   new(result)
   result.section = section
   result.quality = quality
@@ -156,7 +157,11 @@ proc symToSuggest(conf: ConfigRef; s: PSym, isLocal: bool, section: IdeCmd, info
       result.forth = ""
     when defined(nimsuggest) and not defined(noDocgen) and not defined(leanCompiler):
       result.doc = s.extractDocComment
-  let infox = if section in {ideUse, ideHighlight, ideOutline}: info else: s.info
+  let infox =
+    if useSuppliedInfo or section in {ideUse, ideHighlight, ideOutline}:
+      info
+    else:
+      s.info
   result.filePath = toFullPath(conf, infox)
   result.line = toLinenumber(infox)
   result.column = toColumn(infox)
@@ -463,11 +468,14 @@ when defined(nimsuggest):
       let x = if info == s.info and info.col == s.info.col: ideDef else: ideUse
       suggestResult(conf, symToSuggest(conf, s, isLocal=false, x, info, 100, PrefixMatch.None, false, 0))
 
-proc findDefinition(conf: ConfigRef; info: TLineInfo; s: PSym) =
+proc findDefinition(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym) =
   if s.isNil: return
-  if isTracked(info, conf.m.trackPos, s.name.s.len):
-    suggestResult(conf, symToSuggest(conf, s, isLocal=false, ideDef, info, 100, PrefixMatch.None, false, 0))
-    suggestQuit()
+  if isTracked(info, conf.m.trackPos, s.name.s.len) or (s == usageSym and sfForward notin s.flags):
+    suggestResult(conf, symToSuggest(conf, s, isLocal=false, ideDef, info, 100, PrefixMatch.None, false, 0, useSuppliedInfo = s == usageSym))
+    if sfForward notin s.flags:
+      suggestQuit()
+    else:
+      usageSym = s
 
 proc ensureIdx[T](x: var T, y: int) =
   if x.len <= y: x.setLen(y+1)
@@ -487,7 +495,7 @@ proc suggestSym*(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym;
     if conf.ideCmd == ideUse:
       findUsages(conf, info, s, usageSym)
     elif conf.ideCmd == ideDef:
-      findDefinition(conf, info, s)
+      findDefinition(conf, info, s, usageSym)
     elif conf.ideCmd == ideDus and s != nil:
       if isTracked(info, conf.m.trackPos, s.name.s.len):
         suggestResult(conf, symToSuggest(conf, s, isLocal=false, ideDef, info, 100, PrefixMatch.None, false, 0))
diff --git a/nimsuggest/tests/tdef_forward.nim b/nimsuggest/tests/tdef_forward.nim
new file mode 100644
index 000000000..9bdd8b21d
--- /dev/null
+++ b/nimsuggest/tests/tdef_forward.nim
@@ -0,0 +1,13 @@
+discard """
+$nimsuggest --tester $file
+>def $1
+def;;skProc;;tdef_forward.hello;;proc (): string;;$file;;8;;5;;"";;100
+def;;skProc;;tdef_forward.hello;;proc (): string;;$file;;12;;5;;"";;100
+"""
+
+proc hello(): string
+
+hel#[!]#lo()
+
+proc hello(): string =
+  "Hello"