summary refs log tree commit diff stats
path: root/tools/nimsuggest
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2017-03-08 00:38:48 +0100
committerAndreas Rumpf <rumpf_a@web.de>2017-03-08 00:38:48 +0100
commit91a4b448fdfb1a28e5bd1f1d5785e0308fedcb1a (patch)
tree9d34b447df1bf08f7207a82c5f4fdc65a619c006 /tools/nimsuggest
parent538c6c98985399314a845617e566313b70ac71e4 (diff)
downloadNim-91a4b448fdfb1a28e5bd1f1d5785e0308fedcb1a.tar.gz
nimsuggest: chk checks the full project lazily; much better suggestions orderings
Diffstat (limited to 'tools/nimsuggest')
-rw-r--r--tools/nimsuggest/nimsuggest.nim33
-rw-r--r--tools/nimsuggest/tester.nim8
-rw-r--r--tools/nimsuggest/tests/tno_deref.nim2
-rw-r--r--tools/nimsuggest/tests/tsug_regression.nim28
-rw-r--r--tools/nimsuggest/tests/twithin_macro.nim12
-rw-r--r--tools/nimsuggest/tests/twithin_macro_prefix.nim4
6 files changed, 68 insertions, 19 deletions
diff --git a/tools/nimsuggest/nimsuggest.nim b/tools/nimsuggest/nimsuggest.nim
index 628f2bc4c..1798ac4e9 100644
--- a/tools/nimsuggest/nimsuggest.nim
+++ b/tools/nimsuggest/nimsuggest.nim
@@ -17,7 +17,7 @@ import compiler / [options, commands, modules, sem,
   passes, passaux, msgs, nimconf,
   extccomp, condsyms,
   sigmatch, ast, scriptconfig,
-  idents, modulegraphs, vm]
+  idents, modulegraphs, vm, prefixmatches]
 
 when defined(windows):
   import winlean
@@ -51,6 +51,11 @@ are supported.
 """
 type
   Mode = enum mstdin, mtcp, mepc, mcmdline
+  CachedMsg = object
+    info: TLineInfo
+    msg: string
+    sev: Severity
+  CachedMsgs = seq[CachedMsg]
 
 var
   gPort = 6000.Port
@@ -93,7 +98,7 @@ proc parseQuoted(cmd: string; outp: var string; start: int): int =
     i += parseUntil(cmd, outp, seps, i)
   result = i
 
-proc sexp(s: IdeCmd|TSymKind): SexpNode = sexp($s)
+proc sexp(s: IdeCmd|TSymKind|PrefixMatch): SexpNode = sexp($s)
 
 proc sexp(s: Suggest): SexpNode =
   # If you change the order here, make sure to change it over in
@@ -110,6 +115,8 @@ proc sexp(s: Suggest): SexpNode =
     s.doc,
     s.quality
   ])
+  if s.section == ideSug:
+    result.add convertSexp(s.prefix)
 
 proc sexp(s: seq[Suggest]): SexpNode =
   result = newSList()
@@ -363,7 +370,7 @@ proc replEpc(x: ThreadParams) {.thread.} =
                          "unexpected call: " & epcAPI
       quit errMessage
 
-proc execCmd(cmd: string; graph: ModuleGraph; cache: IdentCache) =
+proc execCmd(cmd: string; graph: ModuleGraph; cache: IdentCache; cachedMsgs: CachedMsgs) =
   template sentinel() =
     # send sentinel for the input reading thread:
     results.send(Suggest(section: ideNone))
@@ -415,17 +422,19 @@ proc execCmd(cmd: string; graph: ModuleGraph; cache: IdentCache) =
   if gIdeCmd == ideKnown:
     results.send(Suggest(section: ideKnown, quality: ord(fileInfoKnown(orig))))
   else:
+    if gIdeCmd == ideChk:
+      for cm in cachedMsgs: errorHook(cm.info, cm.msg, cm.sev)
     execute(gIdeCmd, orig, dirtyfile, line, col-1, graph, cache)
   sentinel()
 
 proc recompileFullProject(graph: ModuleGraph; cache: IdentCache) =
-  echo "recompiling full project"
+  #echo "recompiling full project"
   resetSystemArtifacts()
   vm.globalCtx = nil
   graph.resetAllModules()
   GC_fullcollect()
   compileProject(graph, cache)
-  echo GC_getStatistics()
+  #echo GC_getStatistics()
 
 proc mainThread(graph: ModuleGraph; cache: IdentCache) =
   if gLogging:
@@ -442,12 +451,13 @@ proc mainThread(graph: ModuleGraph; cache: IdentCache) =
   suggestionResultHook = sugResultHook
   graph.doStopCompile = proc (): bool = requests.peek() > 0
   var idle = 0
+  var cachedMsgs: CachedMsgs = @[]
   while true:
     let (hasData, req) = requests.tryRecv()
     if hasData:
       msgs.writelnHook = wrHook
       suggestionResultHook = sugResultHook
-      execCmd(req, graph, cache)
+      execCmd(req, graph, cache, cachedMsgs)
       idle = 0
     else:
       os.sleep 250
@@ -456,7 +466,9 @@ proc mainThread(graph: ModuleGraph; cache: IdentCache) =
       # we use some nimsuggest activity to enable a lazy recompile:
       gIdeCmd = ideChk
       msgs.writelnHook = proc (s: string) = discard
-      msgs.structuredErrorHook = nil
+      cachedMsgs.setLen 0
+      msgs.structuredErrorHook = proc (info: TLineInfo; msg: string; sev: Severity) =
+        cachedMsgs.add(CachedMsg(info: info, msg: msg, sev: sev))
       suggestionResultHook = proc (s: Suggest) = discard
       recompileFullProject(graph, cache)
 
@@ -525,8 +537,13 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
         suggestVersion = 2
         gMode = mstdin
         gEmitEof = true
+        gRefresh = false
       of "log": gLogging = true
-      of "refresh": gRefresh = true
+      of "refresh":
+        if p.val.len > 0:
+          gRefresh = parseBool(p.val)
+        else:
+          gRefresh = true
       else: processSwitch(pass, p)
     of cmdArgument:
       options.gProjectName = unixToNativePath(p.key)
diff --git a/tools/nimsuggest/tester.nim b/tools/nimsuggest/tester.nim
index 840d1e27c..0bee14254 100644
--- a/tools/nimsuggest/tester.nim
+++ b/tools/nimsuggest/tester.nim
@@ -20,6 +20,7 @@ template tpath(): untyped = getAppDir() / "tests"
 proc parseTest(filename: string; epcMode=false): Test =
   const cursorMarker = "#[!]#"
   let nimsug = curDir & addFileExt("nimsuggest", ExeExt)
+  let libpath = findExe("nim").splitFile().dir /../ "lib"
   result.dest = getTempDir() / extractFilename(filename)
   result.cmd = nimsug & " --tester " & result.dest
   result.script = @[]
@@ -42,7 +43,7 @@ proc parseTest(filename: string; epcMode=false): Test =
       inc specSection
     elif specSection == 1:
       if x.startsWith("$nimsuggest"):
-        result.cmd = x % ["nimsuggest", nimsug, "file", filename]
+        result.cmd = x % ["nimsuggest", nimsug, "file", filename, "lib", libpath]
       elif x.startsWith("!"):
         if result.cmd.len == 0:
           result.startup.add x
@@ -54,7 +55,7 @@ proc parseTest(filename: string; epcMode=false): Test =
         result.script.add((x.substr(1).replaceWord("$path", tpath()), ""))
       elif x.len > 0:
         # expected output line:
-        let x = x % ["file", filename]
+        let x = x % ["file", filename, "lib", libpath]
         result.script[^1][1].add x.replace(";;", "\t") & '\L'
         # else: ignore empty lines for better readability of the specs
     inc i
@@ -203,6 +204,9 @@ proc sexpToAnswer(s: SexpNode): string =
       result.add doc
       result.add '\t'
       result.add a[8].getNum
+      if a.len >= 10:
+        result.add '\t'
+        result.add a[9].getStr
     result.add '\L'
 
 proc doReport(filename, answer, resp: string; report: var string) =
diff --git a/tools/nimsuggest/tests/tno_deref.nim b/tools/nimsuggest/tests/tno_deref.nim
index 0f8ba3bd8..05cffa507 100644
--- a/tools/nimsuggest/tests/tno_deref.nim
+++ b/tools/nimsuggest/tests/tno_deref.nim
@@ -9,6 +9,6 @@ x.#[!]#
 discard """
 $nimsuggest --tester $file
 >sug $1
-sug;;skProc;;tno_deref.foo;;proc (y: ptr int)*;;$file;;4;;5;;"";;100
+sug;;skProc;;tno_deref.foo;;proc (y: ptr int)*;;$file;;4;;5;;"";;100;;None
 *
 """
diff --git a/tools/nimsuggest/tests/tsug_regression.nim b/tools/nimsuggest/tests/tsug_regression.nim
new file mode 100644
index 000000000..1e440db2d
--- /dev/null
+++ b/tools/nimsuggest/tests/tsug_regression.nim
@@ -0,0 +1,28 @@
+# test we only get suggestions, not error messages:
+
+import tables, sets, parsecfg
+
+type X = object
+
+proc main =
+  # bug #52
+  var
+    set0 = initSet[int]()
+    set1 = initSet[X]()
+    set2 = initSet[ref int]()
+
+    map0 = initTable[int, int]()
+    map1 = initOrderedTable[string, int]()
+    cfg = loadConfig("file")
+  map0.#[!]#
+
+discard """
+$nimsuggest --tester $file
+>sug $1
+sug;;skProc;;tables.getOrDefault;;proc (t: Table[getOrDefault.A, getOrDefault.B], key: A): B;;$lib/pure/collections/tables.nim;;178;;5;;"";;100;;None
+sug;;skProc;;tables.hasKey;;proc (t: Table[hasKey.A, hasKey.B], key: A): bool;;$lib/pure/collections/tables.nim;;233;;5;;"returns true iff `key` is in the table `t`.";;100;;None
+sug;;skProc;;tables.add;;proc (t: var Table[add.A, add.B], key: A, val: B);;$lib/pure/collections/tables.nim;;297;;5;;"puts a new (key, value)-pair into `t` even if ``t[key]`` already exists.";;100;;None
+sug;;skIterator;;tables.allValues;;iterator (t: Table[allValues.A, allValues.B], key: A): B{.inline.};;$lib/pure/collections/tables.nim;;225;;9;;"iterates over any value in the table `t` that belongs to the given `key`.";;100;;None
+sug;;skProc;;tables.clear;;proc (t: var Table[clear.A, clear.B]);;$lib/pure/collections/tables.nim;;121;;5;;"Resets the table so that it is empty.";;100;;None
+*
+"""
diff --git a/tools/nimsuggest/tests/twithin_macro.nim b/tools/nimsuggest/tests/twithin_macro.nim
index 7392dd605..e0df03542 100644
--- a/tools/nimsuggest/tests/twithin_macro.nim
+++ b/tools/nimsuggest/tests/twithin_macro.nim
@@ -204,10 +204,10 @@ echo r
 discard """
 $nimsuggest --tester $file
 >sug $1
-sug;;skField;;name;;string;;$file;;166;;6;;"";;100
-sug;;skField;;age;;int;;$file;;167;;6;;"";;100
-sug;;skMethod;;twithin_macro.age_human_yrs;;proc (self: Animal): int;;$file;;169;;9;;"";;100
-sug;;skMacro;;twithin_macro.class;;proc (head: untyped, body: untyped): untyped{.gcsafe, locks: <unknown>.};;$file;;4;;6;;"Iterates over the children of the NimNode ``n``.";;100
-sug;;skMethod;;twithin_macro.vocalize;;proc (self: Animal): string;;$file;;168;;9;;"";;100
-sug;;skMethod;;twithin_macro.vocalize;;proc (self: Rabbit): string;;$file;;184;;9;;"";;100*
+sug;;skField;;age;;int;;$file;;167;;6;;"";;100;;None
+sug;;skField;;name;;string;;$file;;166;;6;;"";;100;;None
+sug;;skMethod;;twithin_macro.age_human_yrs;;proc (self: Animal): int;;$file;;169;;9;;"";;100;;None
+sug;;skMethod;;twithin_macro.vocalize;;proc (self: Animal): string;;$file;;168;;9;;"";;100;;None
+sug;;skMethod;;twithin_macro.vocalize;;proc (self: Rabbit): string;;$file;;184;;9;;"";;100;;None
+sug;;skMacro;;twithin_macro.class;;proc (head: untyped, body: untyped): untyped{.gcsafe, locks: <unknown>.};;$file;;4;;6;;"";;50;;None*
 """
diff --git a/tools/nimsuggest/tests/twithin_macro_prefix.nim b/tools/nimsuggest/tests/twithin_macro_prefix.nim
index 6ee9fb2dc..86e406c5d 100644
--- a/tools/nimsuggest/tests/twithin_macro_prefix.nim
+++ b/tools/nimsuggest/tests/twithin_macro_prefix.nim
@@ -204,6 +204,6 @@ echo r
 discard """
 $nimsuggest --tester $file
 >sug $1
-sug;;skField;;age;;int;;$file;;167;;6;;"";;100
-sug;;skMethod;;twithin_macro_prefix.age_human_yrs;;proc (self: Animal): int;;$file;;169;;9;;"";;100
+sug;;skField;;age;;int;;$file;;167;;6;;"";;100;;Prefix
+sug;;skMethod;;twithin_macro_prefix.age_human_yrs;;proc (self: Animal): int;;$file;;169;;9;;"";;100;;Prefix
 """