summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/modulegraphs.nim22
-rw-r--r--compiler/suggest.nim15
-rw-r--r--nimsuggest/nimsuggest.nim72
-rw-r--r--nimsuggest/tests/tv3.nim6
-rw-r--r--nimsuggest/tests/tv3_definition.nim9
5 files changed, 76 insertions, 48 deletions
diff --git a/compiler/modulegraphs.nim b/compiler/modulegraphs.nim
index 932f5a0b0..0df72c43b 100644
--- a/compiler/modulegraphs.nim
+++ b/compiler/modulegraphs.nim
@@ -53,6 +53,10 @@ type
     concreteTypes*: seq[FullId]
     inst*: PInstantiation
 
+  SymInfoPair* = object
+    sym*: PSym
+    info*: TLineInfo
+
   ModuleGraph* {.acyclic.} = ref object
     ifaces*: seq[Iface]  ## indexed by int32 fileIdx
     packed*: PackedModuleGraph
@@ -83,7 +87,7 @@ type
     doStopCompile*: proc(): bool {.closure.}
     usageSym*: PSym # for nimsuggest
     owners*: seq[PSym]
-    suggestSymbols*: Table[FileIndex, seq[tuple[sym: PSym, info: TLineInfo]]]
+    suggestSymbols*: Table[FileIndex, seq[SymInfoPair]]
     suggestErrors*: Table[FileIndex, seq[Suggest]]
     methods*: seq[tuple[methods: seq[PSym], dispatcher: PSym]] # needs serialization!
     systemModule*: PSym
@@ -374,12 +378,6 @@ template getPContext(): untyped =
 
 when defined(nimsuggest):
   template onUse*(info: TLineInfo; s: PSym) = discard
-
-  template onDef*(info: TLineInfo; s: PSym) =
-    let c = getPContext()
-    if c.graph.config.suggestVersion == 3:
-      suggestSym(c.graph, info, s, c.graph.usageSym)
-
   template onDefResolveForward*(info: TLineInfo; s: PSym) = discard
 else:
   template onUse*(info: TLineInfo; s: PSym) = discard
@@ -442,7 +440,7 @@ proc initModuleGraphFields(result: ModuleGraph) =
   result.importStack = @[]
   result.inclToMod = initTable[FileIndex, FileIndex]()
   result.owners = @[]
-  result.suggestSymbols = initTable[FileIndex, seq[tuple[sym: PSym, info: TLineInfo]]]()
+  result.suggestSymbols = initTable[FileIndex, seq[SymInfoPair]]()
   result.suggestErrors = initTable[FileIndex, seq[Suggest]]()
   result.methods = @[]
   initStrTable(result.compilerprocs)
@@ -641,7 +639,13 @@ func belongsToStdlib*(graph: ModuleGraph, sym: PSym): bool =
   ## Check if symbol belongs to the 'stdlib' package.
   sym.getPackageSymbol.getPackageId == graph.systemModule.getPackageId
 
-iterator suggestSymbolsIter*(g: ModuleGraph): tuple[sym: PSym, info: TLineInfo] =
+proc `==`*(a, b: SymInfoPair): bool =
+  result = a.sym == b.sym and a.info.exactEquals(b.info)
+
+proc fileSymbols*(graph: ModuleGraph, fileIdx: FileIndex): seq[SymInfoPair] =
+  result = graph.suggestSymbols.getOrDefault(fileIdx, @[]).deduplicate
+
+iterator suggestSymbolsIter*(g: ModuleGraph): SymInfoPair =
   for xs in g.suggestSymbols.values:
     for x in xs.deduplicate:
       yield x
diff --git a/compiler/suggest.nim b/compiler/suggest.nim
index 7e7d876fb..5e8d896bf 100644
--- a/compiler/suggest.nim
+++ b/compiler/suggest.nim
@@ -503,7 +503,7 @@ proc suggestSym*(g: ModuleGraph; info: TLineInfo; s: PSym; usageSym: var PSym; i
   ## misnamed: should be 'symDeclared'
   let conf = g.config
   when defined(nimsuggest):
-    g.suggestSymbols.mgetOrPut(info.fileIndex, @[]).add (s, info)
+    g.suggestSymbols.mgetOrPut(info.fileIndex, @[]).add SymInfoPair(sym: s, info: info)
 
     if conf.suggestVersion == 0:
       if s.allUsages.len == 0:
@@ -699,3 +699,16 @@ proc suggestSentinel*(c: PContext) =
 
   dec(c.compilesContextId)
   produceOutput(outputs, c.config)
+
+when defined(nimsuggest):
+  proc onDef(graph: ModuleGraph, s: PSym, info: TLineInfo) =
+    if graph.config.suggestVersion == 3 and info.exactEquals(s.info):
+       suggestSym(graph, info, s, graph.usageSym)
+
+  template getPContext(): untyped =
+    when c is PContext: c
+    else: c.c
+
+  template onDef*(info: TLineInfo; s: PSym) =
+    let c = getPContext()
+    onDef(c.graph, s, info)
diff --git a/nimsuggest/nimsuggest.nim b/nimsuggest/nimsuggest.nim
index 6f35be925..4fee8b2a2 100644
--- a/nimsuggest/nimsuggest.nim
+++ b/nimsuggest/nimsuggest.nim
@@ -711,17 +711,16 @@ proc recompilePartially(graph: ModuleGraph, projectFileIdx = InvalidFileIdx) =
     except Exception as e:
       myLog fmt "Failed clean recompilation:\n {e.msg} \n\n {e.getStackTrace()}"
 
-proc fileSymbols(graph: ModuleGraph, fileIdx: FileIndex): seq[tuple[sym: PSym, info: TLineInfo]] =
-  result = graph.suggestSymbols.getOrDefault(fileIdx, @[]).deduplicate
-
 proc findSymData(graph: ModuleGraph, file: AbsoluteFile; line, col: int):
-    tuple[sym: PSym, info: TLineInfo] =
+    ref SymInfoPair =
   let
     fileIdx = fileInfoIdx(graph.config, file)
     trackPos = newLineInfo(fileIdx, line, col)
-  for (sym, info) in graph.fileSymbols(fileIdx):
-    if isTracked(info, trackPos, sym.name.s.len):
-      return (sym, info)
+  for s in graph.fileSymbols(fileIdx):
+    if isTracked(s.info, trackPos, s.sym.name.s.len):
+      new(result)
+      result[] = s
+      break
 
 proc markDirtyIfNeeded(graph: ModuleGraph, file: string, originalFileIdx: FileIndex) =
   let sha = $sha1.secureHashFile(file)
@@ -735,7 +734,7 @@ proc markDirtyIfNeeded(graph: ModuleGraph, file: string, originalFileIdx: FileIn
 proc suggestResult(graph: ModuleGraph, sym: PSym, info: TLineInfo, defaultSection = ideNone) =
   let section = if defaultSection != ideNone:
                   defaultSection
-                elif sym.info == info:
+                elif sym.info.exactEquals(info):
                   ideDef
                 else:
                   ideUse
@@ -800,31 +799,31 @@ proc executeNoHooksV3(cmd: IdeCmd, file: AbsoluteFile, dirtyfile: AbsoluteFile,
 
   case cmd
   of ideDef:
-    let (sym, info) = graph.findSymData(file, line, col)
-    if sym != nil:
-      graph.suggestResult(sym, sym.info)
+    let s = graph.findSymData(file, line, col)
+    if not s.isNil:
+      graph.suggestResult(s.sym, s.sym.info)
   of ideType:
-    let (sym, _) = graph.findSymData(file, line, col)
-    if sym != nil:
-      let typeSym = sym.typ.sym
+    let s = graph.findSymData(file, line, col)
+    if not s.isNil:
+      let typeSym = s.sym.typ.sym
       if typeSym != nil:
         graph.suggestResult(typeSym, typeSym.info, ideType)
-      elif sym.typ.len != 0:
-        let genericType = sym.typ[0].sym
+      elif s.sym.typ.len != 0:
+        let genericType = s.sym.typ[0].sym
         graph.suggestResult(genericType, genericType.info, ideType)
   of ideUse, ideDus:
-    let symbol = graph.findSymData(file, line, col).sym
-    if symbol != nil:
-      for (sym, info) in graph.suggestSymbolsIter:
-        if sym == symbol:
-          graph.suggestResult(sym, info)
+    let symbol = graph.findSymData(file, line, col)
+    if not symbol.isNil:
+      for s in graph.suggestSymbolsIter:
+        if s.sym == symbol.sym:
+          graph.suggestResult(s.sym, s.info)
   of ideHighlight:
-    let sym = graph.findSymData(file, line, col).sym
-    if sym != nil:
-      let usages = graph.fileSymbols(fileIndex).filterIt(it.sym == sym)
+    let sym = graph.findSymData(file, line, col)
+    if not sym.isNil:
+      let usages = graph.fileSymbols(fileIndex).filterIt(it.sym == sym.sym)
       myLog fmt "Found {usages.len} usages in {file.string}"
-      for (sym, info) in usages:
-        graph.suggestResult(sym, info)
+      for s in usages:
+        graph.suggestResult(s.sym, s.info)
   of ideRecompile:
     graph.recompileFullProject()
   of ideChanged:
@@ -837,14 +836,12 @@ proc executeNoHooksV3(cmd: IdeCmd, file: AbsoluteFile, dirtyfile: AbsoluteFile,
     let
       module = graph.getModule fileIndex
       symbols = graph.fileSymbols(fileIndex)
-        .filterIt(it.sym.info == it.info and
+        .filterIt(it.sym.info.exactEquals(it.info) and
                     (it.sym.owner == module or
                      it.sym.kind in searchableSymKinds))
-    for (sym, _) in symbols:
-      suggestResult(
-        conf,
-        symToSuggest(graph, sym, false,
-                     ideOutline, sym.info, 100, PrefixMatch.None, false, 0))
+
+    for s in symbols:
+      graph.suggestResult(s.sym, s.info, ideOutline)
   of ideChk:
     myLog fmt "Reporting errors for {graph.suggestErrors.len} file(s)"
     for sug in graph.suggestErrorsIter:
@@ -856,13 +853,12 @@ proc executeNoHooksV3(cmd: IdeCmd, file: AbsoluteFile, dirtyfile: AbsoluteFile,
       suggestResult(graph.config, error)
   of ideGlobalSymbols:
     var counter = 0
-    for (sym, info) in graph.suggestSymbolsIter:
-      if sfGlobal in sym.flags or sym.kind in searchableSymKinds:
-        if contains(sym.name.s, file.string):
+    for s in graph.suggestSymbolsIter:
+      if (sfGlobal in s.sym.flags or s.sym.kind in searchableSymKinds) and
+          s.sym.info == s.info:
+        if contains(s.sym.name.s, file.string):
           inc counter
-          suggestResult(conf,
-                        symToSuggest(graph, sym, isLocal=false,
-                                     ideDef, info, 100, PrefixMatch.None, false, 0))
+          graph.suggestResult(s.sym, s.info)
         # stop after first 100 results
         if counter > 100:
           break
diff --git a/nimsuggest/tests/tv3.nim b/nimsuggest/tests/tv3.nim
index 99caa987b..57ad86e4d 100644
--- a/nimsuggest/tests/tv3.nim
+++ b/nimsuggest/tests/tv3.nim
@@ -7,6 +7,8 @@ type
 proc test(f: Foo) =
   echo f.ba#[!]#r
 
+#[!]#
+
 discard """
 $nimsuggest --v3 --tester $file
 >use $1
@@ -22,4 +24,8 @@ outline	skProc	tv3.test	proc (f: Foo){.gcsafe, locks: 0.}	$file	7	5	""	100
 sug	skField	bar	string	$file	5	4	""	100	Prefix
 >globalSymbols test
 def	skProc	tv3.test	proc (f: Foo){.gcsafe, locks: 0.}	$file	7	5	""	100
+>globalSymbols Foo
+def	skType	tv3.Foo	Foo	$file	4	2	""	100
+>def $2
+>use $2
 """
diff --git a/nimsuggest/tests/tv3_definition.nim b/nimsuggest/tests/tv3_definition.nim
new file mode 100644
index 000000000..03684b7cd
--- /dev/null
+++ b/nimsuggest/tests/tv3_definition.nim
@@ -0,0 +1,9 @@
+
+let foo = 30
+let bar = foo + fo#[!]#o + foo
+
+discard """
+$nimsuggest --v3 --tester $file
+>def $1
+def	skLet	tv3_definition.foo	int	$file	2	4	""	100
+"""