experimental support for answering idetools --def requests from

an in-memory index built during compilation in caas mode
This commit is contained in:
Zahary Karadjov 2013-05-04 23:02:03 +03:00
commit 519d5b834a
4 changed files with 72 additions and 10 deletions

View file

@ -9,7 +9,9 @@
## This file implements features required for IDE support.
# imported from sigmatch.nim
# included from sigmatch.nim
import algorithm
const
sep = '\t'
@ -238,12 +240,66 @@ proc findDefinition(node: PNode, s: PSym) =
SuggestWriteln(SymToStr(s, isLocal=false, sectionDef))
SuggestQuit()
type
TSourceMap = object
lines: seq[TLineMap]
TEntry = object
pos: int
sym: PSym
TLineMap = object
entries: seq[TEntry]
var
gSourceMaps: seq[TSourceMap] = @[]
proc ensureIdx[T](x: var T, y: int) =
if x.len <= y: x.setLen(y+1)
proc ensureSeq[T](x: var seq[T]) =
if x == nil: newSeq(x, 0)
proc resetSourceMap*(fileIdx: int32) =
ensureIdx(gSourceMaps, fileIdx)
gSourceMaps[fileIdx].lines = @[]
proc addToSourceMap(sym: Psym, info: TLineInfo) =
ensureIdx(gSourceMaps, info.fileIndex)
ensureSeq(gSourceMaps[info.fileIndex].lines)
ensureIdx(gSourceMaps[info.fileIndex].lines, info.line)
ensureSeq(gSourceMaps[info.fileIndex].lines[info.line].entries)
gSourceMaps[info.fileIndex].lines[info.line].entries.add(TEntry(pos: info.col, sym: sym))
proc defFromLine(entries: var seq[TEntry], col: int32) =
# The sorting is done lazily here on purpose.
# No need to pay the price for it unless the user requests
# "goto definition" on a particular line
sort(entries) do (a,b: TEntry) -> int:
return cmp(a.pos, b.pos)
for e in entries:
# currently, the line-infos for most expressions point to
# one position past the end of the expression. This means
# that the first expr that ends after the cursor column is
# the one we are looking for.
if e.pos >= col:
SuggestWriteln(SymToStr(e.sym, isLocal=false, sectionDef))
return
proc defFromSourceMap*(i: TLineInfo) =
InternalAssert i.fileIndex < gSourceMaps.len and
i.line < gSourceMaps[i.fileIndex].lines.len
defFromLine(gSourceMaps[i.fileIndex].lines[i.line].entries, i.col)
proc suggestSym*(n: PNode, s: PSym) {.inline.} =
## misnamed: should be 'symDeclared'
if optUsages in gGlobalOptions:
findUsages(n, s)
if optDef in gGlobalOptions:
findDefinition(n, s)
if isServing:
addToSourceMap(s, n.info)
proc markUsed(n: PNode, s: PSym) =
incl(s.flags, sfUsed)