nimsuggest: added --refresh command line option; added 'known' command; fixes 'chck' command for EPC

This commit is contained in:
Andreas Rumpf 2017-02-22 16:27:24 +01:00
commit 311253ef2f
2 changed files with 28 additions and 16 deletions

View file

@ -100,7 +100,7 @@ type
IdeCmd* = enum IdeCmd* = enum
ideNone, ideSug, ideCon, ideDef, ideUse, ideDus, ideChk, ideMod, ideNone, ideSug, ideCon, ideDef, ideUse, ideDus, ideChk, ideMod,
ideHighlight, ideOutline ideHighlight, ideOutline, ideKnown
ConfigRef* = ref object ## eventually all global configuration should be moved here ConfigRef* = ref object ## eventually all global configuration should be moved here
cppDefines*: HashSet[string] cppDefines*: HashSet[string]
@ -442,6 +442,7 @@ proc parseIdeCmd*(s: string): IdeCmd =
of "mod": ideMod of "mod": ideMod
of "highlight": ideHighlight of "highlight": ideHighlight
of "outline": ideOutline of "outline": ideOutline
of "known": ideKnown
else: ideNone else: ideNone
proc `$`*(c: IdeCmd): string = proc `$`*(c: IdeCmd): string =
@ -456,3 +457,4 @@ proc `$`*(c: IdeCmd): string =
of ideNone: "none" of ideNone: "none"
of ideHighlight: "highlight" of ideHighlight: "highlight"
of ideOutline: "outline" of ideOutline: "outline"
of ideKnown: "known"

View file

@ -17,7 +17,7 @@ import compiler / [options, commands, modules, sem,
passes, passaux, msgs, nimconf, passes, passaux, msgs, nimconf,
extccomp, condsyms, lists, extccomp, condsyms, lists,
sigmatch, ast, scriptconfig, sigmatch, ast, scriptconfig,
idents, modulegraphs, compilerlog] idents, modulegraphs, compilerlog, vm]
when defined(windows): when defined(windows):
import winlean import winlean
@ -40,6 +40,7 @@ Options:
--log enable verbose logging to nimsuggest.log file --log enable verbose logging to nimsuggest.log file
--v2 use version 2 of the protocol; more features and --v2 use version 2 of the protocol; more features and
much faster much faster
--refresh perform automatic refreshes to keep the analysis precise
--tester implies --v2 and --stdin and outputs a line --tester implies --v2 and --stdin and outputs a line
'""" & DummyEof & """' for the tester '""" & DummyEof & """' for the tester
@ -57,10 +58,11 @@ var
gMode: Mode gMode: Mode
gEmitEof: bool # whether we write '!EOF!' dummy lines gEmitEof: bool # whether we write '!EOF!' dummy lines
gLogging = false gLogging = false
gRefresh: bool
const const
seps = {':', ';', ' ', '\t'} seps = {':', ';', ' ', '\t'}
Help = "usage: sug|con|def|use|dus|chk|mod|highlight|outline file.nim[;dirtyfile.nim]:line:col\n" & Help = "usage: sug|con|def|use|dus|chk|mod|highlight|outline|known file.nim[;dirtyfile.nim]:line:col\n" &
"type 'quit' to quit\n" & "type 'quit' to quit\n" &
"type 'debug' to toggle debug mode on/off\n" & "type 'debug' to toggle debug mode on/off\n" &
"type 'terse' to toggle terse mode on/off" "type 'terse' to toggle terse mode on/off"
@ -144,7 +146,7 @@ proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int;
gTrackPos = newLineInfo(dirtyIdx, line, col) gTrackPos = newLineInfo(dirtyIdx, line, col)
gErrorCounter = 0 gErrorCounter = 0
if suggestVersion < 2: if suggestVersion < 2:
usageSym = nil graph.usageSym = nil
if not isKnownFile: if not isKnownFile:
graph.compileProject(cache) graph.compileProject(cache)
if suggestVersion == 2 and gIdeCmd in {ideUse, ideDus} and if suggestVersion == 2 and gIdeCmd in {ideUse, ideDus} and
@ -157,7 +159,7 @@ proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int;
if gIdeCmd != ideMod: if gIdeCmd != ideMod:
graph.compileProject(cache, modIdx) graph.compileProject(cache, modIdx)
if gIdeCmd in {ideUse, ideDus}: if gIdeCmd in {ideUse, ideDus}:
let u = if suggestVersion >= 2: graph.symFromInfo(gTrackPos) else: usageSym let u = if suggestVersion >= 2: graph.symFromInfo(gTrackPos) else: graph.usageSym
if u != nil: if u != nil:
listUsages(u) listUsages(u)
else: else:
@ -212,6 +214,7 @@ proc toStdout() {.gcsafe.} =
case res.section case res.section
of ideNone: break of ideNone: break
of ideChk: echo res.doc of ideChk: echo res.doc
of ideKnown: echo res.quality == 1
else: echo res else: echo res
proc toSocket(stdoutSocket: Socket) {.gcsafe.} = proc toSocket(stdoutSocket: Socket) {.gcsafe.} =
@ -220,6 +223,7 @@ proc toSocket(stdoutSocket: Socket) {.gcsafe.} =
case res.section case res.section
of ideNone: break of ideNone: break
of ideChk: stdoutSocket.send(res.doc & "\c\L") of ideChk: stdoutSocket.send(res.doc & "\c\L")
of ideKnown: stdoutSocket.send($(res.quality == 1) & "\c\L")
else: stdoutSocket.send($res & "\c\L") else: stdoutSocket.send($res & "\c\L")
proc toEpc(client: Socket; uid: BiggestInt) {.gcsafe.} = proc toEpc(client: Socket; uid: BiggestInt) {.gcsafe.} =
@ -229,10 +233,11 @@ proc toEpc(client: Socket; uid: BiggestInt) {.gcsafe.} =
case res.section case res.section
of ideNone: break of ideNone: break
of ideChk: of ideChk:
returnEpc(client, uid, sexp(res.doc)) list.add sexp(res.doc)
of ideKnown:
list.add sexp(res.quality == 1)
else: else:
list.add sexp(res) list.add sexp(res)
if gIdeCmd != ideChk:
returnEpc(client, uid, list) returnEpc(client, uid, list)
proc writelnToChannel(line: string) = proc writelnToChannel(line: string) =
@ -391,6 +396,7 @@ proc execCmd(cmd: string; graph: ModuleGraph; cache: IdentCache) =
of "quit": quit() of "quit": quit()
of "debug": toggle optIdeDebug of "debug": toggle optIdeDebug
of "terse": toggle optIdeTerse of "terse": toggle optIdeTerse
of "known": gIdeCmd = ideKnown
else: err() else: err()
var dirtyfile = "" var dirtyfile = ""
var orig = "" var orig = ""
@ -404,14 +410,20 @@ proc execCmd(cmd: string; graph: ModuleGraph; cache: IdentCache) =
i += skipWhile(cmd, seps, i) i += skipWhile(cmd, seps, i)
i += parseInt(cmd, col, i) i += parseInt(cmd, col, i)
if gIdeCmd == ideKnown:
results.send(Suggest(section: ideKnown, quality: ord(fileInfoKnown(orig))))
else:
execute(gIdeCmd, orig, dirtyfile, line, col-1, graph, cache) execute(gIdeCmd, orig, dirtyfile, line, col-1, graph, cache)
sentinel() sentinel()
proc recompileFullProject(graph: ModuleGraph; cache: IdentCache) = proc recompileFullProject(graph: ModuleGraph; cache: IdentCache) =
echo "recompiling full project" echo "recompiling full project"
resetSystemArtifacts() resetSystemArtifacts()
vm.globalCtx = nil
graph.resetAllModules() graph.resetAllModules()
GC_fullcollect()
compileProject(graph, cache) compileProject(graph, cache)
echo "recompiled!"
proc mainThread(graph: ModuleGraph; cache: IdentCache) = proc mainThread(graph: ModuleGraph; cache: IdentCache) =
if gLogging: if gLogging:
@ -441,7 +453,7 @@ proc mainThread(graph: ModuleGraph; cache: IdentCache) =
else: else:
os.sleep 250 os.sleep 250
idle += 1 idle += 1
if idle == 20 and false: if idle == 20 and gRefresh:
# we use some nimsuggest activity to enable a lazy recompile: # we use some nimsuggest activity to enable a lazy recompile:
gIdeCmd = ideChk gIdeCmd = ideChk
msgs.writelnHook = proc (s: string) = discard msgs.writelnHook = proc (s: string) = discard
@ -609,16 +621,14 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
of "epc": of "epc":
gMode = mepc gMode = mepc
gVerbosity = 0 # Port number gotta be first. gVerbosity = 0 # Port number gotta be first.
of "debug": of "debug": incl(gGlobalOptions, optIdeDebug)
incl(gGlobalOptions, optIdeDebug) of "v2": suggestVersion = 2
of "v2":
suggestVersion = 2
of "tester": of "tester":
suggestVersion = 2 suggestVersion = 2
gMode = mstdin gMode = mstdin
gEmitEof = true gEmitEof = true
of "log": of "log": gLogging = true
gLogging = true of "refresh": gRefresh = true
else: processSwitch(pass, p) else: processSwitch(pass, p)
of cmdArgument: of cmdArgument:
options.gProjectName = unixToNativePath(p.key) options.gProjectName = unixToNativePath(p.key)