mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-07 20:34:21 +00:00
experimental support for answering idetools --def requests from
an in-memory index built during compilation in caas mode
This commit is contained in:
@@ -215,7 +215,8 @@ proc track(arg: string, info: TLineInfo) =
|
||||
LocalError(info, errInvalidNumber, a[1])
|
||||
if parseUtils.parseInt(a[2], column) <= 0:
|
||||
LocalError(info, errInvalidNumber, a[2])
|
||||
msgs.addCheckpoint(newLineInfo(a[0], line, column))
|
||||
optTrackPos = newLineInfo(a[0], line, column)
|
||||
msgs.addCheckpoint(optTrackPos)
|
||||
|
||||
proc dynlibOverride(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
|
||||
if pass in {passCmd2, passPP}:
|
||||
|
||||
@@ -16,7 +16,7 @@ import
|
||||
wordrecg, sem, semdata, idents, passes, docgen, extccomp,
|
||||
cgen, jsgen, cgendata, json, nversion,
|
||||
platform, nimconf, importer, passaux, depends, evals, types, idgen,
|
||||
tables, docgen2, service, magicsys, parser, crc, ccgutils
|
||||
tables, docgen2, service, magicsys, parser, crc, ccgutils, sigmatch
|
||||
|
||||
const
|
||||
has_LLVM_Backend = false
|
||||
@@ -64,7 +64,7 @@ proc crcChanged(fileIdx: int32): bool =
|
||||
gMemCacheData[fileIdx].crcStatus = if result: crcHasChanged
|
||||
else: crcNotChanged
|
||||
# echo "TESTING CRC: ", fileIdx.toFilename, " ", result
|
||||
|
||||
|
||||
case gMemCacheData[fileIdx].crcStatus:
|
||||
of crcHasChanged:
|
||||
result = true
|
||||
@@ -90,18 +90,19 @@ proc addDep(x: Psym, dep: int32) =
|
||||
gMemCacheData[x.position].deps.safeAdd(dep)
|
||||
|
||||
proc ResetModule(fileIdx: int32) =
|
||||
echo "HARD RESETTING ", fileIdx.toFilename
|
||||
writeStackTrace()
|
||||
# echo "HARD RESETTING ", fileIdx.toFilename
|
||||
gMemCacheData[fileIdx].needsRecompile = Yes
|
||||
gCompiledModules[fileIdx] = nil
|
||||
cgendata.gModules[fileIdx] = nil
|
||||
resetSourceMap(fileIdx)
|
||||
|
||||
proc ResetAllModules =
|
||||
for i in 0..gCompiledModules.high:
|
||||
if gCompiledModules[i] != nil:
|
||||
ResetModule(i.int32)
|
||||
|
||||
for m in cgenModules():
|
||||
echo "CGEN MODULE FOUND"
|
||||
# for m in cgenModules(): echo "CGEN MODULE FOUND"
|
||||
|
||||
proc checkDepMem(fileIdx: int32): TNeedRecompile =
|
||||
template markDirty =
|
||||
@@ -112,15 +113,15 @@ proc checkDepMem(fileIdx: int32): TNeedRecompile =
|
||||
return gMemCacheData[fileIdx].needsRecompile
|
||||
|
||||
if optForceFullMake in gGlobalOptions or
|
||||
curCaasCmd != lastCaasCmd or
|
||||
crcChanged(fileIdx): markDirty
|
||||
crcChanged(fileIdx):
|
||||
markDirty
|
||||
|
||||
if gMemCacheData[fileIdx].deps != nil:
|
||||
gMemCacheData[fileIdx].needsRecompile = Probing
|
||||
for dep in gMemCacheData[fileIdx].deps:
|
||||
let d = checkDepMem(dep)
|
||||
if d in { Yes, Recompiled }:
|
||||
echo fileIdx.toFilename, " depends on ", dep.toFilename, " ", d
|
||||
# echo fileIdx.toFilename, " depends on ", dep.toFilename, " ", d
|
||||
markDirty
|
||||
|
||||
gMemCacheData[fileIdx].needsRecompile = No
|
||||
@@ -381,6 +382,9 @@ proc CommandSuggest =
|
||||
semanticPasses()
|
||||
rodPass()
|
||||
compileProject()
|
||||
if isServing:
|
||||
if optDef in gGlobalOptions:
|
||||
defFromSourceMap(optTrackPos)
|
||||
|
||||
proc wantMainModule =
|
||||
if gProjectFull.len == 0:
|
||||
|
||||
@@ -606,6 +606,7 @@ proc `??`* (info: TLineInfo, filename: string): bool =
|
||||
result = filename in info.toFilename
|
||||
|
||||
var checkPoints*: seq[TLineInfo] = @[]
|
||||
var optTrackPos*: TLineInfo
|
||||
|
||||
proc addCheckpoint*(info: TLineInfo) =
|
||||
checkPoints.add(info)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user