nimsuggest: more things work
This commit is contained in:
parent
4755795416
commit
57ea01309e
6 changed files with 51 additions and 25 deletions
|
|
@ -213,7 +213,8 @@ proc openLexer*(lex: var TLexer, fileIdx: int32, inputstream: PLLStream;
|
||||||
lex.currLineIndent = 0
|
lex.currLineIndent = 0
|
||||||
inc(lex.lineNumber, inputstream.lineOffset)
|
inc(lex.lineNumber, inputstream.lineOffset)
|
||||||
lex.cache = cache
|
lex.cache = cache
|
||||||
lex.previousToken.fileIndex = fileIdx
|
when defined(nimsuggest):
|
||||||
|
lex.previousToken.fileIndex = fileIdx
|
||||||
|
|
||||||
proc openLexer*(lex: var TLexer, filename: string, inputstream: PLLStream;
|
proc openLexer*(lex: var TLexer, filename: string, inputstream: PLLStream;
|
||||||
cache: IdentCache) =
|
cache: IdentCache) =
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,8 @@ proc commonType*(x, y: PType): PType =
|
||||||
|
|
||||||
proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym =
|
proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym =
|
||||||
result = newSym(kind, considerQuotedIdent(n), getCurrOwner(c), n.info)
|
result = newSym(kind, considerQuotedIdent(n), getCurrOwner(c), n.info)
|
||||||
|
when defined(nimsuggest):
|
||||||
|
suggestDecl(c, n, result)
|
||||||
|
|
||||||
proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
|
proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
|
||||||
proc `$`(kind: TSymKind): string = substr(system.`$`(kind), 2).toLowerAscii
|
proc `$`(kind: TSymKind): string = substr(system.`$`(kind), 2).toLowerAscii
|
||||||
|
|
@ -191,6 +193,8 @@ proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
|
||||||
result = newSym(kind, considerQuotedIdent(n), getCurrOwner(c), n.info)
|
result = newSym(kind, considerQuotedIdent(n), getCurrOwner(c), n.info)
|
||||||
#if kind in {skForVar, skLet, skVar} and result.owner.kind == skModule:
|
#if kind in {skForVar, skLet, skVar} and result.owner.kind == skModule:
|
||||||
# incl(result.flags, sfGlobal)
|
# incl(result.flags, sfGlobal)
|
||||||
|
when defined(nimsuggest):
|
||||||
|
suggestDecl(c, n, result)
|
||||||
|
|
||||||
proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
|
proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
|
||||||
allowed: TSymFlags): PSym
|
allowed: TSymFlags): PSym
|
||||||
|
|
|
||||||
|
|
@ -1054,7 +1054,9 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
# here at all!
|
# here at all!
|
||||||
#if isSymChoice(n.sons[1]): return
|
#if isSymChoice(n.sons[1]): return
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
if gCmd == cmdIdeTools: suggestExpr(c, n)
|
if gCmd == cmdIdeTools:
|
||||||
|
suggestExpr(c, n)
|
||||||
|
if exactEquals(gTrackPos, n[1].info): suggestExprNoCheck(c, n)
|
||||||
|
|
||||||
var s = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared, checkModule})
|
var s = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared, checkModule})
|
||||||
if s != nil:
|
if s != nil:
|
||||||
|
|
@ -2234,6 +2236,8 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit:
|
of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit:
|
||||||
# check if it is an expression macro:
|
# check if it is an expression macro:
|
||||||
checkMinSonsLen(n, 1)
|
checkMinSonsLen(n, 1)
|
||||||
|
#when defined(nimsuggest):
|
||||||
|
# if gIdeCmd == ideCon and gTrackPos == n.info: suggestExprNoCheck(c, n)
|
||||||
let mode = if nfDotField in n.flags: {} else: {checkUndeclared}
|
let mode = if nfDotField in n.flags: {} else: {checkUndeclared}
|
||||||
var s = qualifiedLookUp(c, n.sons[0], mode)
|
var s = qualifiedLookUp(c, n.sons[0], mode)
|
||||||
if s != nil:
|
if s != nil:
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ proc `$`*(suggest: Suggest): string =
|
||||||
result.add(sep)
|
result.add(sep)
|
||||||
when not defined(noDocgen):
|
when not defined(noDocgen):
|
||||||
result.add(suggest.doc.escape)
|
result.add(suggest.doc.escape)
|
||||||
if suggestVersion == 2:
|
if suggestVersion == 0:
|
||||||
result.add(sep)
|
result.add(sep)
|
||||||
result.add($suggest.quality)
|
result.add($suggest.quality)
|
||||||
if suggest.section == ideSug:
|
if suggest.section == ideSug:
|
||||||
|
|
@ -202,6 +202,10 @@ proc suggestResult(s: Suggest) =
|
||||||
proc produceOutput(a: var Suggestions) =
|
proc produceOutput(a: var Suggestions) =
|
||||||
if gIdeCmd in {ideSug, ideCon}:
|
if gIdeCmd in {ideSug, ideCon}:
|
||||||
a.sort cmpSuggestions
|
a.sort cmpSuggestions
|
||||||
|
when false:
|
||||||
|
# debug code
|
||||||
|
writeStackTrace()
|
||||||
|
if a.len > 10: a.setLen(10)
|
||||||
if not isNil(suggestionResultHook):
|
if not isNil(suggestionResultHook):
|
||||||
for s in a:
|
for s in a:
|
||||||
suggestionResultHook(s)
|
suggestionResultHook(s)
|
||||||
|
|
@ -332,7 +336,7 @@ proc suggestEverything(c: PContext, n, f: PNode, outputs: var Suggestions) =
|
||||||
var pm: PrefixMatch
|
var pm: PrefixMatch
|
||||||
if filterSym(it, f, pm):
|
if filterSym(it, f, pm):
|
||||||
outputs.add(symToSuggest(it, isLocal = isLocal, $ideSug, 0, pm, c.inTypeContext > 0, scopeN))
|
outputs.add(symToSuggest(it, isLocal = isLocal, $ideSug, 0, pm, c.inTypeContext > 0, scopeN))
|
||||||
if scope == c.topLevelScope and f.isNil: break
|
#if scope == c.topLevelScope and f.isNil: break
|
||||||
|
|
||||||
proc suggestFieldAccess(c: PContext, n, field: PNode, outputs: var Suggestions) =
|
proc suggestFieldAccess(c: PContext, n, field: PNode, outputs: var Suggestions) =
|
||||||
# special code that deals with ``myObj.``. `n` is NOT the nkDotExpr-node, but
|
# special code that deals with ``myObj.``. `n` is NOT the nkDotExpr-node, but
|
||||||
|
|
@ -340,7 +344,7 @@ proc suggestFieldAccess(c: PContext, n, field: PNode, outputs: var Suggestions)
|
||||||
var typ = n.typ
|
var typ = n.typ
|
||||||
var pm: PrefixMatch
|
var pm: PrefixMatch
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
if n.kind == nkSym and n.sym.kind == skError and suggestVersion == 2:
|
if n.kind == nkSym and n.sym.kind == skError and suggestVersion == 0:
|
||||||
# consider 'foo.|' where 'foo' is some not imported module.
|
# consider 'foo.|' where 'foo' is some not imported module.
|
||||||
let fullPath = findModule(n.sym.name.s, n.info.toFullPath)
|
let fullPath = findModule(n.sym.name.s, n.info.toFullPath)
|
||||||
if fullPath.len == 0:
|
if fullPath.len == 0:
|
||||||
|
|
@ -429,7 +433,7 @@ var
|
||||||
lastLineInfo*: TLineInfo
|
lastLineInfo*: TLineInfo
|
||||||
|
|
||||||
proc findUsages(info: TLineInfo; s: PSym; usageSym: var PSym) =
|
proc findUsages(info: TLineInfo; s: PSym; usageSym: var PSym) =
|
||||||
if suggestVersion < 2:
|
if suggestVersion == 1:
|
||||||
if usageSym == nil and isTracked(info, s.name.s.len):
|
if usageSym == nil and isTracked(info, s.name.s.len):
|
||||||
usageSym = s
|
usageSym = s
|
||||||
suggestResult(symToSuggest(s, isLocal=false, $ideUse, 100, PrefixMatch.None, false, 0))
|
suggestResult(symToSuggest(s, isLocal=false, $ideUse, 100, PrefixMatch.None, false, 0))
|
||||||
|
|
@ -460,7 +464,7 @@ proc ensureSeq[T](x: var seq[T]) =
|
||||||
proc suggestSym*(info: TLineInfo; s: PSym; usageSym: var PSym; isDecl=true) {.inline.} =
|
proc suggestSym*(info: TLineInfo; s: PSym; usageSym: var PSym; isDecl=true) {.inline.} =
|
||||||
## misnamed: should be 'symDeclared'
|
## misnamed: should be 'symDeclared'
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
if suggestVersion == 2:
|
if suggestVersion == 0:
|
||||||
if s.allUsages.isNil:
|
if s.allUsages.isNil:
|
||||||
s.allUsages = @[info]
|
s.allUsages = @[info]
|
||||||
else:
|
else:
|
||||||
|
|
@ -509,7 +513,6 @@ proc sugExpr(c: PContext, n: PNode, outputs: var Suggestions) =
|
||||||
# line as the object to prevent this from happening:
|
# line as the object to prevent this from happening:
|
||||||
let prefix = if n.len == 2 and n[1].info.line == n[0].info.line and
|
let prefix = if n.len == 2 and n[1].info.line == n[0].info.line and
|
||||||
not gTrackPosAttached: n[1] else: nil
|
not gTrackPosAttached: n[1] else: nil
|
||||||
echo n[1].kind
|
|
||||||
suggestFieldAccess(c, obj, prefix, outputs)
|
suggestFieldAccess(c, obj, prefix, outputs)
|
||||||
|
|
||||||
#if optIdeDebug in gGlobalOptions:
|
#if optIdeDebug in gGlobalOptions:
|
||||||
|
|
@ -519,8 +522,7 @@ proc sugExpr(c: PContext, n: PNode, outputs: var Suggestions) =
|
||||||
let prefix = if gTrackPosAttached: nil else: n
|
let prefix = if gTrackPosAttached: nil else: n
|
||||||
suggestEverything(c, n, prefix, outputs)
|
suggestEverything(c, n, prefix, outputs)
|
||||||
|
|
||||||
proc suggestExpr*(c: PContext, n: PNode) =
|
proc suggestExprNoCheck*(c: PContext, n: PNode) =
|
||||||
if not exactEquals(gTrackPos, n.info): return
|
|
||||||
# This keeps semExpr() from coming here recursively:
|
# This keeps semExpr() from coming here recursively:
|
||||||
if c.compilesContextId > 0: return
|
if c.compilesContextId > 0: return
|
||||||
inc(c.compilesContextId)
|
inc(c.compilesContextId)
|
||||||
|
|
@ -545,6 +547,16 @@ proc suggestExpr*(c: PContext, n: PNode) =
|
||||||
produceOutput(outputs)
|
produceOutput(outputs)
|
||||||
suggestQuit()
|
suggestQuit()
|
||||||
|
|
||||||
|
proc suggestExpr*(c: PContext, n: PNode) =
|
||||||
|
if exactEquals(gTrackPos, n.info): suggestExprNoCheck(c, n)
|
||||||
|
|
||||||
|
proc suggestDecl*(c: PContext, n: PNode; s: PSym) =
|
||||||
|
let attached = gTrackPosAttached
|
||||||
|
if attached: inc(c.inTypeContext)
|
||||||
|
defer:
|
||||||
|
if attached: dec(c.inTypeContext)
|
||||||
|
suggestExpr(c, n)
|
||||||
|
|
||||||
proc suggestStmt*(c: PContext, n: PNode) =
|
proc suggestStmt*(c: PContext, n: PNode) =
|
||||||
suggestExpr(c, n)
|
suggestExpr(c, n)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,9 @@ Options:
|
||||||
--epc use emacs epc mode
|
--epc use emacs epc mode
|
||||||
--debug enable debug output
|
--debug enable debug output
|
||||||
--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
|
--v1 use version 1 of the protocol; for backwards compatibility
|
||||||
much faster
|
|
||||||
--refresh perform automatic refreshes to keep the analysis precise
|
--refresh perform automatic refreshes to keep the analysis precise
|
||||||
--tester implies --v2 and --stdin and outputs a line
|
--tester implies --stdin and outputs a line
|
||||||
'""" & DummyEof & """' for the tester
|
'""" & DummyEof & """' for the tester
|
||||||
|
|
||||||
The server then listens to the connection and takes line-based commands.
|
The server then listens to the connection and takes line-based commands.
|
||||||
|
|
@ -50,7 +49,7 @@ In addition, all command line options of Nim that do not affect code generation
|
||||||
are supported.
|
are supported.
|
||||||
"""
|
"""
|
||||||
type
|
type
|
||||||
Mode = enum mstdin, mtcp, mepc, mcmdline
|
Mode = enum mstdin, mtcp, mepc, mcmdsug, mcmdcon
|
||||||
CachedMsg = object
|
CachedMsg = object
|
||||||
info: TLineInfo
|
info: TLineInfo
|
||||||
msg: string
|
msg: string
|
||||||
|
|
@ -165,7 +164,7 @@ proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int;
|
||||||
else:
|
else:
|
||||||
msgs.structuredErrorHook = nil
|
msgs.structuredErrorHook = nil
|
||||||
msgs.writelnHook = proc (s: string) = discard
|
msgs.writelnHook = proc (s: string) = discard
|
||||||
if cmd == ideUse and suggestVersion != 2:
|
if cmd == ideUse and suggestVersion != 0:
|
||||||
graph.resetAllModules()
|
graph.resetAllModules()
|
||||||
var isKnownFile = true
|
var isKnownFile = true
|
||||||
let dirtyIdx = file.fileInfoIdx(isKnownFile)
|
let dirtyIdx = file.fileInfoIdx(isKnownFile)
|
||||||
|
|
@ -176,11 +175,11 @@ proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int;
|
||||||
gTrackPos = newLineInfo(dirtyIdx, line, col)
|
gTrackPos = newLineInfo(dirtyIdx, line, col)
|
||||||
gTrackPosAttached = false
|
gTrackPosAttached = false
|
||||||
gErrorCounter = 0
|
gErrorCounter = 0
|
||||||
if suggestVersion < 2:
|
if suggestVersion == 1:
|
||||||
graph.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 == 0 and gIdeCmd in {ideUse, ideDus} and
|
||||||
dirtyfile.len == 0:
|
dirtyfile.len == 0:
|
||||||
discard "no need to recompile anything"
|
discard "no need to recompile anything"
|
||||||
else:
|
else:
|
||||||
|
|
@ -190,7 +189,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: graph.usageSym
|
let u = if suggestVersion != 1: graph.symFromInfo(gTrackPos) else: graph.usageSym
|
||||||
if u != nil:
|
if u != nil:
|
||||||
listUsages(u)
|
listUsages(u)
|
||||||
else:
|
else:
|
||||||
|
|
@ -503,8 +502,10 @@ proc mainCommand(graph: ModuleGraph; cache: IdentCache) =
|
||||||
of mstdin: createThread(inputThread, replStdin, (gPort, gAddress))
|
of mstdin: createThread(inputThread, replStdin, (gPort, gAddress))
|
||||||
of mtcp: createThread(inputThread, replTcp, (gPort, gAddress))
|
of mtcp: createThread(inputThread, replTcp, (gPort, gAddress))
|
||||||
of mepc: createThread(inputThread, replEpc, (gPort, gAddress))
|
of mepc: createThread(inputThread, replEpc, (gPort, gAddress))
|
||||||
of mcmdline: createThread(inputThread, replCmdline,
|
of mcmdsug: createThread(inputThread, replCmdline,
|
||||||
(gPort, "sug \"" & options.gProjectFull & "\":" & gAddress))
|
(gPort, "sug \"" & options.gProjectFull & "\":" & gAddress))
|
||||||
|
of mcmdcon: createThread(inputThread, replCmdline,
|
||||||
|
(gPort, "con \"" & options.gProjectFull & "\":" & gAddress))
|
||||||
mainThread(graph, cache)
|
mainThread(graph, cache)
|
||||||
joinThread(inputThread)
|
joinThread(inputThread)
|
||||||
close(requests)
|
close(requests)
|
||||||
|
|
@ -525,17 +526,21 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
|
||||||
gAddress = p.val
|
gAddress = p.val
|
||||||
gMode = mtcp
|
gMode = mtcp
|
||||||
of "stdin": gMode = mstdin
|
of "stdin": gMode = mstdin
|
||||||
of "cmdline":
|
of "cmdsug":
|
||||||
gMode = mcmdline
|
gMode = mcmdsug
|
||||||
suggestVersion = 2
|
|
||||||
gAddress = p.val
|
gAddress = p.val
|
||||||
|
incl(gGlobalOptions, optIdeDebug)
|
||||||
|
of "cmdcon":
|
||||||
|
gMode = mcmdcon
|
||||||
|
gAddress = p.val
|
||||||
|
incl(gGlobalOptions, optIdeDebug)
|
||||||
of "epc":
|
of "epc":
|
||||||
gMode = mepc
|
gMode = mepc
|
||||||
gVerbosity = 0 # Port number gotta be first.
|
gVerbosity = 0 # Port number gotta be first.
|
||||||
of "debug": incl(gGlobalOptions, optIdeDebug)
|
of "debug": incl(gGlobalOptions, optIdeDebug)
|
||||||
of "v2": suggestVersion = 2
|
of "v2": suggestVersion = 0
|
||||||
|
of "v1": suggestVersion = 1
|
||||||
of "tester":
|
of "tester":
|
||||||
suggestVersion = 2
|
|
||||||
gMode = mstdin
|
gMode = mstdin
|
||||||
gEmitEof = true
|
gEmitEof = true
|
||||||
gRefresh = false
|
gRefresh = false
|
||||||
|
|
|
||||||
|
|
@ -22,4 +22,4 @@ define:nimsuggest
|
||||||
--path:"$nim"
|
--path:"$nim"
|
||||||
--threads:on
|
--threads:on
|
||||||
--noNimblePath
|
--noNimblePath
|
||||||
--path:"../../compiler"
|
--path:"../compiler"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue