refactoring: make FileIndex a distinct type; make line information an uint16; fixes #7654

This commit is contained in:
Andreas Rumpf 2018-04-21 08:13:37 +02:00
commit 33b69f0ed0
29 changed files with 196 additions and 311 deletions

View file

@ -1042,9 +1042,9 @@ proc newNode*(kind: TNodeKind): PNode =
new(result) new(result)
result.kind = kind result.kind = kind
#result.info = UnknownLineInfo() inlined: #result.info = UnknownLineInfo() inlined:
result.info.fileIndex = int32(-1) result.info.fileIndex = InvalidFileIdx
result.info.col = int16(-1) result.info.col = int16(-1)
result.info.line = int16(-1) result.info.line = uint16(0)
when defined(useNodeIds): when defined(useNodeIds):
result.id = gNodeId result.id = gNodeId
if result.id == nodeIdToDebug: if result.id == nodeIdToDebug:
@ -1116,13 +1116,13 @@ proc linkTo*(s: PSym, t: PType): PSym {.discardable.} =
s.typ = t s.typ = t
result = s result = s
template fileIdx*(c: PSym): int32 = template fileIdx*(c: PSym): FileIndex =
# XXX: this should be used only on module symbols # XXX: this should be used only on module symbols
c.position.int32 c.position.FileIndex
template filename*(c: PSym): string = template filename*(c: PSym): string =
# XXX: this should be used only on module symbols # XXX: this should be used only on module symbols
c.position.int32.toFilename c.position.FileIndex.toFilename
proc appendToModule*(m: PSym, n: PNode) = proc appendToModule*(m: PSym, n: PNode) =
## The compiler will use this internally to add nodes that will be ## The compiler will use this internally to add nodes that will be

View file

@ -2023,7 +2023,7 @@ template genStmtListExprImpl(exprOrStmt) {.dirty.} =
let theMacro = it[0].sym let theMacro = it[0].sym
add p.s(cpsStmts), initFrameNoDebug(p, frameName, add p.s(cpsStmts), initFrameNoDebug(p, frameName,
makeCString theMacro.name.s, makeCString theMacro.name.s,
theMacro.info.quotedFilename, it.info.line) theMacro.info.quotedFilename, it.info.line.int)
else: else:
genStmts(p, it) genStmts(p, it)
if n.len > 0: exprOrStmt if n.len > 0: exprOrStmt

View file

@ -223,7 +223,7 @@ proc genLineDir(p: BProc, t: PNode) =
line.rope, makeCString(toFilename(tt.info))) line.rope, makeCString(toFilename(tt.info)))
elif ({optLineTrace, optStackTrace} * p.options == elif ({optLineTrace, optStackTrace} * p.options ==
{optLineTrace, optStackTrace}) and {optLineTrace, optStackTrace}) and
(p.prc == nil or sfPure notin p.prc.flags) and tt.info.fileIndex >= 0: (p.prc == nil or sfPure notin p.prc.flags) and tt.info.fileIndex != InvalidFileIDX:
if freshLineInfo(p, tt.info): if freshLineInfo(p, tt.info):
linefmt(p, cpsStmts, "nimln_($1, $2);$n", linefmt(p, cpsStmts, "nimln_($1, $2);$n",
line.rope, tt.info.quotedFilename) line.rope, tt.info.quotedFilename)
@ -1301,7 +1301,7 @@ proc resetCgenModules*(g: BModuleList) =
for m in cgenModules(g): resetModule(m) for m in cgenModules(g): resetModule(m)
proc rawNewModule(g: BModuleList; module: PSym): BModule = proc rawNewModule(g: BModuleList; module: PSym): BModule =
result = rawNewModule(g, module, module.position.int32.toFullPath) result = rawNewModule(g, module, module.position.FileIndex.toFullPath)
proc newModule(g: BModuleList; module: PSym): BModule = proc newModule(g: BModuleList; module: PSym): BModule =
# we should create only one cgen module for each module sym # we should create only one cgen module for each module sym
@ -1311,7 +1311,7 @@ proc newModule(g: BModuleList; module: PSym): BModule =
if (optDeadCodeElim in gGlobalOptions): if (optDeadCodeElim in gGlobalOptions):
if (sfDeadCodeElim in module.flags): if (sfDeadCodeElim in module.flags):
internalError("added pending module twice: " & module.filename) internalError("added pending module twice: " & toFilename(FileIndex module.position))
template injectG(config) {.dirty.} = template injectG(config) {.dirty.} =
if graph.backend == nil: if graph.backend == nil:

View file

@ -319,7 +319,7 @@ proc trackDirty(arg: string, info: TLineInfo) =
localError(info, errInvalidNumber, a[2]) localError(info, errInvalidNumber, a[2])
let dirtyOriginalIdx = a[1].fileInfoIdx let dirtyOriginalIdx = a[1].fileInfoIdx
if dirtyOriginalIdx >= 0: if dirtyOriginalIdx.int32 >= 0:
msgs.setDirtyFile(dirtyOriginalIdx, a[0]) msgs.setDirtyFile(dirtyOriginalIdx, a[0])
gTrackPos = newLineInfo(dirtyOriginalIdx, line, column) gTrackPos = newLineInfo(dirtyOriginalIdx, line, column)

View file

@ -544,7 +544,7 @@ proc genJsonItem(d: PDoc, n, nameNode: PNode, k: TSymKind): JsonNode =
initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments}) initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments})
result = %{ "name": %name, "type": %($k), "line": %n.info.line, result = %{ "name": %name, "type": %($k), "line": %n.info.line.int,
"col": %n.info.col} "col": %n.info.col}
if comm != nil and comm != "": if comm != nil and comm != "":
result["description"] = %comm result["description"] = %comm
@ -618,7 +618,7 @@ proc generateJson*(d: PDoc, n: PNode) =
of nkCommentStmt: of nkCommentStmt:
if n.comment != nil and startsWith(n.comment, "##"): if n.comment != nil and startsWith(n.comment, "##"):
let stripped = n.comment.substr(2).strip let stripped = n.comment.substr(2).strip
d.add %{ "comment": %stripped, "line": %n.info.line, d.add %{ "comment": %stripped, "line": %n.info.line.int,
"col": %n.info.col } "col": %n.info.col }
of nkProcDef: of nkProcDef:
when useEffectSystem: documentRaises(n) when useEffectSystem: documentRaises(n)
@ -790,7 +790,7 @@ proc writeOutputJson*(d: PDoc, filename, outExt: string,
discard "fixme: error report" discard "fixme: error report"
proc commandDoc*() = proc commandDoc*() =
var ast = parseFile(gProjectMainIdx, newIdentCache()) var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache())
if ast == nil: return if ast == nil: return
var d = newDocumentor(gProjectFull, options.gConfigVars) var d = newDocumentor(gProjectFull, options.gConfigVars)
d.hasToc = true d.hasToc = true
@ -840,7 +840,7 @@ proc commandRst2TeX*() =
commandRstAux(gProjectFull, TexExt) commandRstAux(gProjectFull, TexExt)
proc commandJson*() = proc commandJson*() =
var ast = parseFile(gProjectMainIdx, newIdentCache()) var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache())
if ast == nil: return if ast == nil: return
var d = newDocumentor(gProjectFull, options.gConfigVars) var d = newDocumentor(gProjectFull, options.gConfigVars)
d.hasToc = true d.hasToc = true
@ -855,7 +855,7 @@ proc commandJson*() =
writeRope(content, getOutFile(gProjectFull, JsonExt), useWarning = false) writeRope(content, getOutFile(gProjectFull, JsonExt), useWarning = false)
proc commandTags*() = proc commandTags*() =
var ast = parseFile(gProjectMainIdx, newIdentCache()) var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache())
if ast == nil: return if ast == nil: return
var d = newDocumentor(gProjectFull, options.gConfigVars) var d = newDocumentor(gProjectFull, options.gConfigVars)
d.hasToc = true d.hasToc = true

View file

@ -35,7 +35,7 @@ const
proc newLine(p: var TTmplParser) = proc newLine(p: var TTmplParser) =
llStreamWrite(p.outp, repeat(')', p.emitPar)) llStreamWrite(p.outp, repeat(')', p.emitPar))
p.emitPar = 0 p.emitPar = 0
if p.info.line > int16(1): llStreamWrite(p.outp, "\n") if p.info.line > uint16(1): llStreamWrite(p.outp, "\n")
if p.pendingExprLine: if p.pendingExprLine:
llStreamWrite(p.outp, spaces(2)) llStreamWrite(p.outp, spaces(2))
p.pendingExprLine = false p.pendingExprLine = false
@ -212,9 +212,9 @@ proc filterTmpl*(stdin: PLLStream, filename: string, call: PNode): PLLStream =
p.x = newStringOfCap(120) p.x = newStringOfCap(120)
# do not process the first line which contains the directive: # do not process the first line which contains the directive:
if llStreamReadLine(p.inp, p.x): if llStreamReadLine(p.inp, p.x):
p.info.line = p.info.line + int16(1) p.info.line = p.info.line + 1'u16
while llStreamReadLine(p.inp, p.x): while llStreamReadLine(p.inp, p.x):
p.info.line = p.info.line + int16(1) p.info.line = p.info.line + 1'u16
parseLine(p) parseLine(p)
newLine(p) newLine(p)
result = p.outp result = p.outp

View file

@ -2261,7 +2261,7 @@ proc myClose(graph: ModuleGraph; b: PPassContext, n: PNode): PNode =
var m = BModule(b) var m = BModule(b)
if sfMainModule in m.module.flags: if sfMainModule in m.module.flags:
let ext = "js" let ext = "js"
let f = if globals.classes.len == 0: m.module.filename let f = if globals.classes.len == 0: toFilename(FileIndex m.module.position)
else: "nimsystem" else: "nimsystem"
let code = wholeCode(graph, m) let code = wholeCode(graph, m)
let outfile = let outfile =

View file

@ -133,7 +133,7 @@ type
TErrorHandler* = proc (info: TLineInfo; msg: TMsgKind; arg: string) TErrorHandler* = proc (info: TLineInfo; msg: TMsgKind; arg: string)
TLexer* = object of TBaseLexer TLexer* = object of TBaseLexer
fileIdx*: int32 fileIdx*: FileIndex
indentAhead*: int # if > 0 an indendation has already been read indentAhead*: int # if > 0 an indendation has already been read
# this is needed because scanning comments # this is needed because scanning comments
# needs so much look-ahead # needs so much look-ahead
@ -222,7 +222,7 @@ proc fillToken(L: var TToken) =
L.commentOffsetA = 0 L.commentOffsetA = 0
L.commentOffsetB = 0 L.commentOffsetB = 0
proc openLexer*(lex: var TLexer, fileIdx: int32, inputstream: PLLStream; proc openLexer*(lex: var TLexer, fileIdx: FileIndex, inputstream: PLLStream;
cache: IdentCache) = cache: IdentCache) =
openBaseLexer(lex, inputstream) openBaseLexer(lex, inputstream)
lex.fileIdx = fileidx lex.fileIdx = fileidx
@ -274,7 +274,7 @@ template tokenEnd(tok, pos) {.dirty.} =
when defined(nimsuggest): when defined(nimsuggest):
let colB = getColNumber(L, pos)+1 let colB = getColNumber(L, pos)+1
if L.fileIdx == gTrackPos.fileIndex and gTrackPos.col in colA..colB and if L.fileIdx == gTrackPos.fileIndex and gTrackPos.col in colA..colB and
L.lineNumber == gTrackPos.line and gIdeCmd in {ideSug, ideCon}: L.lineNumber == gTrackPos.line.int and gIdeCmd in {ideSug, ideCon}:
L.cursor = CursorPosition.InToken L.cursor = CursorPosition.InToken
gTrackPos.col = colA.int16 gTrackPos.col = colA.int16
colA = 0 colA = 0
@ -285,9 +285,9 @@ template tokenEndIgnore(tok, pos) =
when defined(nimsuggest): when defined(nimsuggest):
let colB = getColNumber(L, pos) let colB = getColNumber(L, pos)
if L.fileIdx == gTrackPos.fileIndex and gTrackPos.col in colA..colB and if L.fileIdx == gTrackPos.fileIndex and gTrackPos.col in colA..colB and
L.lineNumber == gTrackPos.line and gIdeCmd in {ideSug, ideCon}: L.lineNumber == gTrackPos.line.int and gIdeCmd in {ideSug, ideCon}:
gTrackPos.fileIndex = trackPosInvalidFileIdx gTrackPos.fileIndex = trackPosInvalidFileIdx
gTrackPos.line = -1 gTrackPos.line = 0'u16
colA = 0 colA = 0
when defined(nimpretty): when defined(nimpretty):
tok.offsetB = L.offsetBase + pos tok.offsetB = L.offsetBase + pos
@ -299,7 +299,7 @@ template tokenEndPrevious(tok, pos) =
# the cursor in a string literal or comment: # the cursor in a string literal or comment:
let colB = getColNumber(L, pos) let colB = getColNumber(L, pos)
if L.fileIdx == gTrackPos.fileIndex and gTrackPos.col in colA..colB and if L.fileIdx == gTrackPos.fileIndex and gTrackPos.col in colA..colB and
L.lineNumber == gTrackPos.line and gIdeCmd in {ideSug, ideCon}: L.lineNumber == gTrackPos.line.int and gIdeCmd in {ideSug, ideCon}:
L.cursor = CursorPosition.BeforeToken L.cursor = CursorPosition.BeforeToken
gTrackPos = L.previousToken gTrackPos = L.previousToken
gTrackPosAttached = true gTrackPosAttached = true
@ -1066,7 +1066,7 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) =
when defined(nimsuggest): when defined(nimsuggest):
# we attach the cursor to the last *strong* token # we attach the cursor to the last *strong* token
if tok.tokType notin weakTokens: if tok.tokType notin weakTokens:
L.previousToken.line = tok.line.int16 L.previousToken.line = tok.line.uint16
L.previousToken.col = tok.col.int16 L.previousToken.col = tok.col.int16
when defined(nimsuggest): when defined(nimsuggest):
@ -1118,7 +1118,7 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) =
tok.tokType = tkParLe tok.tokType = tkParLe
when defined(nimsuggest): when defined(nimsuggest):
if L.fileIdx == gTrackPos.fileIndex and tok.col < gTrackPos.col and if L.fileIdx == gTrackPos.fileIndex and tok.col < gTrackPos.col and
tok.line == gTrackPos.line and gIdeCmd == ideCon: tok.line == gTrackPos.line.int and gIdeCmd == ideCon:
gTrackPos.col = tok.col.int16 gTrackPos.col = tok.col.int16
of ')': of ')':
tok.tokType = tkParRi tok.tokType = tkParRi
@ -1139,7 +1139,7 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) =
of '.': of '.':
when defined(nimsuggest): when defined(nimsuggest):
if L.fileIdx == gTrackPos.fileIndex and tok.col+1 == gTrackPos.col and if L.fileIdx == gTrackPos.fileIndex and tok.col+1 == gTrackPos.col and
tok.line == gTrackPos.line and gIdeCmd == ideSug: tok.line == gTrackPos.line.int and gIdeCmd == ideSug:
tok.tokType = tkDot tok.tokType = tkDot
L.cursor = CursorPosition.InToken L.cursor = CursorPosition.InToken
gTrackPos.col = tok.col.int16 gTrackPos.col = tok.col.int16

View file

@ -35,7 +35,7 @@ proc writeDepsFile(g: ModuleGraph; project: string) =
let f = open(changeFileExt(project, "deps"), fmWrite) let f = open(changeFileExt(project, "deps"), fmWrite)
for m in g.modules: for m in g.modules:
if m != nil: if m != nil:
f.writeLine(toFullPath(m.position.int32)) f.writeLine(toFullPath(m.position.FileIndex))
for k in g.inclToMod.keys: for k in g.inclToMod.keys:
if g.getModule(k).isNil: # don't repeat includes which are also modules if g.getModule(k).isNil: # don't repeat includes which are also modules
f.writeLine(k.toFullPath) f.writeLine(k.toFullPath)
@ -265,7 +265,7 @@ proc mainCommand*(graph: ModuleGraph; cache: IdentCache) =
of "parse": of "parse":
gCmd = cmdParse gCmd = cmdParse
wantMainModule() wantMainModule()
discard parseFile(gProjectMainIdx, cache) discard parseFile(FileIndex gProjectMainIdx, cache)
of "scan": of "scan":
gCmd = cmdScan gCmd = cmdScan
wantMainModule() wantMainModule()

View file

@ -25,7 +25,7 @@
## - Its dependent module stays the same. ## - Its dependent module stays the same.
## ##
import ast, intsets, tables, options, rod import ast, intsets, tables, options, rod, msgs, hashes
type type
ModuleGraph* = ref object ModuleGraph* = ref object
@ -34,10 +34,10 @@ type
deps*: IntSet # the dependency graph or potentially its transitive closure. deps*: IntSet # the dependency graph or potentially its transitive closure.
suggestMode*: bool # whether we are in nimsuggest mode or not. suggestMode*: bool # whether we are in nimsuggest mode or not.
invalidTransitiveClosure: bool invalidTransitiveClosure: bool
inclToMod*: Table[int32, int32] # mapping of include file to the inclToMod*: Table[FileIndex, FileIndex] # mapping of include file to the
# first module that included it # first module that included it
importStack*: seq[int32] # The current import stack. Used for detecting recursive importStack*: seq[FileIndex] # The current import stack. Used for detecting recursive
# module dependencies. # module dependencies.
backend*: RootRef # minor hack so that a backend can extend this easily backend*: RootRef # minor hack so that a backend can extend this easily
config*: ConfigRef config*: ConfigRef
doStopCompile*: proc(): bool {.closure.} doStopCompile*: proc(): bool {.closure.}
@ -45,6 +45,8 @@ type
owners*: seq[PSym] owners*: seq[PSym]
methods*: seq[tuple[methods: TSymSeq, dispatcher: PSym]] methods*: seq[tuple[methods: TSymSeq, dispatcher: PSym]]
proc hash*(x: FileIndex): Hash {.borrow.}
{.this: g.} {.this: g.}
proc stopCompile*(g: ModuleGraph): bool {.inline.} = proc stopCompile*(g: ModuleGraph): bool {.inline.} =
@ -56,7 +58,7 @@ proc newModuleGraph*(config: ConfigRef = nil): ModuleGraph =
result.deps = initIntSet() result.deps = initIntSet()
result.modules = @[] result.modules = @[]
result.importStack = @[] result.importStack = @[]
result.inclToMod = initTable[int32, int32]() result.inclToMod = initTable[FileIndex, FileIndex]()
if config.isNil: if config.isNil:
result.config = newConfigRef() result.config = newConfigRef()
else: else:
@ -69,35 +71,35 @@ proc resetAllModules*(g: ModuleGraph) =
deps = initIntSet() deps = initIntSet()
modules = @[] modules = @[]
importStack = @[] importStack = @[]
inclToMod = initTable[int32, int32]() inclToMod = initTable[FileIndex, FileIndex]()
usageSym = nil usageSym = nil
owners = @[] owners = @[]
methods = @[] methods = @[]
proc getModule*(g: ModuleGraph; fileIdx: int32): PSym = proc getModule*(g: ModuleGraph; fileIdx: FileIndex): PSym =
if fileIdx >= 0 and fileIdx < modules.len: if fileIdx.int32 >= 0 and fileIdx.int32 < modules.len:
result = modules[fileIdx] result = modules[fileIdx.int32]
proc dependsOn(a, b: int): int {.inline.} = (a shl 15) + b proc dependsOn(a, b: int): int {.inline.} = (a shl 15) + b
proc addDep*(g: ModuleGraph; m: PSym, dep: int32) = proc addDep*(g: ModuleGraph; m: PSym, dep: FileIndex) =
assert m.position == m.info.fileIndex assert m.position == m.info.fileIndex.int32
addModuleDep(m.info.fileIndex, dep, isIncludeFile = false) addModuleDep(m.info.fileIndex, dep, isIncludeFile = false)
if suggestMode: if suggestMode:
deps.incl m.position.dependsOn(dep) deps.incl m.position.dependsOn(dep.int)
# we compute the transitive closure later when quering the graph lazily. # we compute the transitive closure later when quering the graph lazily.
# this improve efficiency quite a lot: # this improve efficiency quite a lot:
#invalidTransitiveClosure = true #invalidTransitiveClosure = true
proc addIncludeDep*(g: ModuleGraph; module, includeFile: int32) = proc addIncludeDep*(g: ModuleGraph; module, includeFile: FileIndex) =
addModuleDep(module, includeFile, isIncludeFile = true) addModuleDep(module, includeFile, isIncludeFile = true)
discard hasKeyOrPut(inclToMod, includeFile, module) discard hasKeyOrPut(inclToMod, includeFile, module)
proc parentModule*(g: ModuleGraph; fileIdx: int32): int32 = proc parentModule*(g: ModuleGraph; fileIdx: FileIndex): FileIndex =
## returns 'fileIdx' if the file belonging to this index is ## returns 'fileIdx' if the file belonging to this index is
## directly used as a module or else the module that first ## directly used as a module or else the module that first
## references this include file. ## references this include file.
if fileIdx >= 0 and fileIdx < modules.len and modules[fileIdx] != nil: if fileIdx.int32 >= 0 and fileIdx.int32 < modules.len and modules[fileIdx.int32] != nil:
result = fileIdx result = fileIdx
else: else:
result = inclToMod.getOrDefault(fileIdx) result = inclToMod.getOrDefault(fileIdx)
@ -111,11 +113,11 @@ proc transitiveClosure(g: var IntSet; n: int) =
if g.contains(i.dependsOn(k)) and g.contains(k.dependsOn(j)): if g.contains(i.dependsOn(k)) and g.contains(k.dependsOn(j)):
g.incl i.dependsOn(j) g.incl i.dependsOn(j)
proc markDirty*(g: ModuleGraph; fileIdx: int32) = proc markDirty*(g: ModuleGraph; fileIdx: FileIndex) =
let m = getModule fileIdx let m = getModule fileIdx
if m != nil: incl m.flags, sfDirty if m != nil: incl m.flags, sfDirty
proc markClientsDirty*(g: ModuleGraph; fileIdx: int32) = proc markClientsDirty*(g: ModuleGraph; fileIdx: FileIndex) =
# we need to mark its dependent modules D as dirty right away because after # we need to mark its dependent modules D as dirty right away because after
# nimsuggest is done with this module, the module's dirty flag will be # nimsuggest is done with this module, the module's dirty flag will be
# cleared but D still needs to be remembered as 'dirty'. # cleared but D still needs to be remembered as 'dirty'.
@ -126,7 +128,7 @@ proc markClientsDirty*(g: ModuleGraph; fileIdx: int32) =
# every module that *depends* on this file is also dirty: # every module that *depends* on this file is also dirty:
for i in 0i32..<modules.len.int32: for i in 0i32..<modules.len.int32:
let m = modules[i] let m = modules[i]
if m != nil and deps.contains(i.dependsOn(fileIdx)): if m != nil and deps.contains(i.dependsOn(fileIdx.int)):
incl m.flags, sfDirty incl m.flags, sfDirty
proc isDirty*(g: ModuleGraph; m: PSym): bool = proc isDirty*(g: ModuleGraph; m: PSym): bool =

View file

@ -174,7 +174,7 @@ proc getModuleName*(n: PNode): string =
localError(n.info, errGenerated, "invalid module name: '$1'" % n.renderTree) localError(n.info, errGenerated, "invalid module name: '$1'" % n.renderTree)
result = "" result = ""
proc checkModuleName*(n: PNode; doLocalError=true): int32 = proc checkModuleName*(n: PNode; doLocalError=true): FileIndex =
# This returns the full canonical path for a given module import # This returns the full canonical path for a given module import
let modulename = n.getModuleName let modulename = n.getModuleName
let fullPath = findModule(modulename, n.info.toFullPath) let fullPath = findModule(modulename, n.info.toFullPath)

View file

@ -121,7 +121,7 @@ when false:
proc resetSystemArtifacts*() = proc resetSystemArtifacts*() =
magicsys.resetSysTypes() magicsys.resetSysTypes()
proc newModule(graph: ModuleGraph; fileIdx: int32): PSym = proc newModule(graph: ModuleGraph; fileIdx: FileIndex): PSym =
# We cannot call ``newSym`` here, because we have to circumvent the ID # We cannot call ``newSym`` here, because we have to circumvent the ID
# mechanism, which we do in order to assign each module a persistent ID. # mechanism, which we do in order to assign each module a persistent ID.
new(result) new(result)
@ -144,9 +144,9 @@ proc newModule(graph: ModuleGraph; fileIdx: int32): PSym =
graph.packageSyms.strTableAdd(packSym) graph.packageSyms.strTableAdd(packSym)
result.owner = packSym result.owner = packSym
result.position = fileIdx result.position = int fileIdx
growCache graph.modules, fileIdx growCache graph.modules, int fileIdx
graph.modules[result.position] = result graph.modules[result.position] = result
incl(result.flags, sfUsed) incl(result.flags, sfUsed)
@ -158,7 +158,7 @@ proc newModule(graph: ModuleGraph; fileIdx: int32): PSym =
# strTableIncl() for error corrections: # strTableIncl() for error corrections:
discard strTableIncl(packSym.tab, result) discard strTableIncl(packSym.tab, result)
proc compileModule*(graph: ModuleGraph; fileIdx: int32; cache: IdentCache, flags: TSymFlags): PSym = proc compileModule*(graph: ModuleGraph; fileIdx: FileIndex; cache: IdentCache, flags: TSymFlags): PSym =
result = graph.getModule(fileIdx) result = graph.getModule(fileIdx)
if result == nil: if result == nil:
#growCache gMemCacheData, fileIdx #growCache gMemCacheData, fileIdx
@ -199,7 +199,7 @@ proc compileModule*(graph: ModuleGraph; fileIdx: int32; cache: IdentCache, flags
else: else:
result = gCompiledModules[fileIdx] result = gCompiledModules[fileIdx]
proc importModule*(graph: ModuleGraph; s: PSym, fileIdx: int32; proc importModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex;
cache: IdentCache): PSym {.procvar.} = cache: IdentCache): PSym {.procvar.} =
# this is called by the semantic checking phase # this is called by the semantic checking phase
result = compileModule(graph, fileIdx, cache, {}) result = compileModule(graph, fileIdx, cache, {})
@ -210,11 +210,11 @@ proc importModule*(graph: ModuleGraph; s: PSym, fileIdx: int32;
gNotes = if s.owner.id == gMainPackageId: gMainPackageNotes gNotes = if s.owner.id == gMainPackageId: gMainPackageNotes
else: ForeignPackageNotes else: ForeignPackageNotes
proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: int32; proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex;
cache: IdentCache): PNode {.procvar.} = cache: IdentCache): PNode {.procvar.} =
result = syntaxes.parseFile(fileIdx, cache) result = syntaxes.parseFile(fileIdx, cache)
graph.addDep(s, fileIdx) graph.addDep(s, fileIdx)
graph.addIncludeDep(s.position.int32, fileIdx) graph.addIncludeDep(s.position.FileIndex, fileIdx)
proc compileSystemModule*(graph: ModuleGraph; cache: IdentCache) = proc compileSystemModule*(graph: ModuleGraph; cache: IdentCache) =
if magicsys.systemModule == nil: if magicsys.systemModule == nil:
@ -224,16 +224,16 @@ proc compileSystemModule*(graph: ModuleGraph; cache: IdentCache) =
proc wantMainModule* = proc wantMainModule* =
if gProjectFull.len == 0: if gProjectFull.len == 0:
fatal(gCmdLineInfo, errCommandExpectsFilename) fatal(gCmdLineInfo, errCommandExpectsFilename)
gProjectMainIdx = addFileExt(gProjectFull, NimExt).fileInfoIdx gProjectMainIdx = int32 addFileExt(gProjectFull, NimExt).fileInfoIdx
passes.gIncludeFile = includeModule passes.gIncludeFile = includeModule
passes.gImportModule = importModule passes.gImportModule = importModule
proc compileProject*(graph: ModuleGraph; cache: IdentCache; proc compileProject*(graph: ModuleGraph; cache: IdentCache;
projectFileIdx = -1'i32) = projectFileIdx = InvalidFileIDX) =
wantMainModule() wantMainModule()
let systemFileIdx = fileInfoIdx(options.libpath / "system.nim") let systemFileIdx = fileInfoIdx(options.libpath / "system.nim")
let projectFile = if projectFileIdx < 0: gProjectMainIdx else: projectFileIdx let projectFile = if projectFileIdx == InvalidFileIDX: FileIndex(gProjectMainIdx) else: projectFileIdx
graph.importStack.add projectFile graph.importStack.add projectFile
if projectFile == systemFileIdx: if projectFile == systemFileIdx:
discard graph.compileModule(projectFile, cache, {sfMainModule, sfSystemModule}) discard graph.compileModule(projectFile, cache, {sfMainModule, sfSystemModule})

View file

@ -499,14 +499,15 @@ type
hash*: string # the checksum of the file hash*: string # the checksum of the file
when defined(nimpretty): when defined(nimpretty):
fullContent*: string fullContent*: string
FileIndex* = int32 # XXX will make this 'distinct' later FileIndex* = distinct int32
TLineInfo* = object # This is designed to be as small as possible, TLineInfo* = object # This is designed to be as small as possible,
# because it is used # because it is used
# in syntax nodes. We save space here by using # in syntax nodes. We save space here by using
# two int16 and an int32. # two int16 and an int32.
# On 64 bit and on 32 bit systems this is # On 64 bit and on 32 bit systems this is
# only 8 bytes. # only 8 bytes.
line*, col*: int16 line*: uint16
col*: int16
fileIndex*: FileIndex fileIndex*: FileIndex
when defined(nimpretty): when defined(nimpretty):
offsetA*, offsetB*: int offsetA*, offsetB*: int
@ -521,6 +522,8 @@ type
ERecoverableError* = object of ValueError ERecoverableError* = object of ValueError
ESuggestDone* = object of Exception ESuggestDone* = object of Exception
proc `==`*(a, b: FileIndex): bool {.borrow.}
const const
NotesVerbosity*: array[0..3, TNoteKinds] = [ NotesVerbosity*: array[0..3, TNoteKinds] = [
{low(TNoteKind)..high(TNoteKind)} - {warnShadowIdent, warnUninit, {low(TNoteKind)..high(TNoteKind)} - {warnShadowIdent, warnUninit,
@ -545,14 +548,14 @@ const
{low(TNoteKind)..high(TNoteKind)}] {low(TNoteKind)..high(TNoteKind)}]
const const
InvalidFileIDX* = int32(-1) InvalidFileIDX* = FileIndex(-1)
var var
ForeignPackageNotes*: TNoteKinds = {hintProcessing, warnUnknownMagic, ForeignPackageNotes*: TNoteKinds = {hintProcessing, warnUnknownMagic,
hintQuitCalled, hintExecuting} hintQuitCalled, hintExecuting}
filenameToIndexTbl = initTable[string, int32]() filenameToIndexTbl = initTable[string, FileIndex]()
fileInfos*: seq[TFileInfo] = @[] fileInfos*: seq[TFileInfo] = @[]
systemFileIdx*: int32 systemFileIdx*: FileIndex
proc toCChar*(c: char): string = proc toCChar*(c: char): string =
case c case c
@ -598,7 +601,7 @@ proc newFileInfo(fullPath, projPath: string): TFileInfo =
when defined(nimpretty): when defined(nimpretty):
proc fileSection*(fid: FileIndex; a, b: int): string = proc fileSection*(fid: FileIndex; a, b: int): string =
substr(fileInfos[fid].fullContent, a, b) substr(fileInfos[fid.int].fullContent, a, b)
proc fileInfoKnown*(filename: string): bool = proc fileInfoKnown*(filename: string): bool =
var var
@ -609,7 +612,7 @@ proc fileInfoKnown*(filename: string): bool =
canon = filename canon = filename
result = filenameToIndexTbl.hasKey(canon) result = filenameToIndexTbl.hasKey(canon)
proc fileInfoIdx*(filename: string; isKnownFile: var bool): int32 = proc fileInfoIdx*(filename: string; isKnownFile: var bool): FileIndex =
var var
canon: string canon: string
pseudoPath = false pseudoPath = false
@ -627,28 +630,28 @@ proc fileInfoIdx*(filename: string; isKnownFile: var bool): int32 =
result = filenameToIndexTbl[canon] result = filenameToIndexTbl[canon]
else: else:
isKnownFile = false isKnownFile = false
result = fileInfos.len.int32 result = fileInfos.len.FileIndex
fileInfos.add(newFileInfo(canon, if pseudoPath: filename fileInfos.add(newFileInfo(canon, if pseudoPath: filename
else: canon.shortenDir)) else: canon.shortenDir))
filenameToIndexTbl[canon] = result filenameToIndexTbl[canon] = result
proc fileInfoIdx*(filename: string): int32 = proc fileInfoIdx*(filename: string): FileIndex =
var dummy: bool var dummy: bool
result = fileInfoIdx(filename, dummy) result = fileInfoIdx(filename, dummy)
proc newLineInfo*(fileInfoIdx: int32, line, col: int): TLineInfo = proc newLineInfo*(fileInfoIdx: FileIndex, line, col: int): TLineInfo =
result.fileIndex = fileInfoIdx result.fileIndex = fileInfoIdx
result.line = int16(line) result.line = uint16(line)
result.col = int16(col) result.col = int16(col)
proc newLineInfo*(filename: string, line, col: int): TLineInfo {.inline.} = proc newLineInfo*(filename: string, line, col: int): TLineInfo {.inline.} =
result = newLineInfo(filename.fileInfoIdx, line, col) result = newLineInfo(filename.fileInfoIdx, line, col)
fileInfos.add(newFileInfo("", "command line")) fileInfos.add(newFileInfo("", "command line"))
var gCmdLineInfo* = newLineInfo(int32(0), 1, 1) var gCmdLineInfo* = newLineInfo(FileIndex(0), 1, 1)
fileInfos.add(newFileInfo("", "compilation artifact")) fileInfos.add(newFileInfo("", "compilation artifact"))
var gCodegenLineInfo* = newLineInfo(int32(1), 1, 1) var gCodegenLineInfo* = newLineInfo(FileIndex(1), 1, 1)
proc raiseRecoverableError*(msg: string) {.noinline, noreturn.} = proc raiseRecoverableError*(msg: string) {.noinline, noreturn.} =
raise newException(ERecoverableError, msg) raise newException(ERecoverableError, msg)
@ -664,9 +667,9 @@ var
gMainPackageNotes*: TNoteKinds = NotesVerbosity[1] gMainPackageNotes*: TNoteKinds = NotesVerbosity[1]
proc unknownLineInfo*(): TLineInfo = proc unknownLineInfo*(): TLineInfo =
result.line = int16(-1) result.line = uint16(0)
result.col = int16(-1) result.col = int16(-1)
result.fileIndex = -1 result.fileIndex = InvalidFileIDX
type type
Severity* {.pure.} = enum ## VS Code only supports these three Severity* {.pure.} = enum ## VS Code only supports these three
@ -728,32 +731,32 @@ proc getInfoContext*(index: int): TLineInfo =
if i >=% L: result = unknownLineInfo() if i >=% L: result = unknownLineInfo()
else: result = msgContext[i] else: result = msgContext[i]
template toFilename*(fileIdx: int32): string = template toFilename*(fileIdx: FileIndex): string =
(if fileIdx < 0: "???" else: fileInfos[fileIdx].projPath) (if fileIdx.int32 < 0: "???" else: fileInfos[fileIdx.int32].projPath)
proc toFullPath*(fileIdx: int32): string = proc toFullPath*(fileIdx: FileIndex): string =
if fileIdx < 0: result = "???" if fileIdx.int32 < 0: result = "???"
else: result = fileInfos[fileIdx].fullPath else: result = fileInfos[fileIdx.int32].fullPath
proc setDirtyFile*(fileIdx: int32; filename: string) = proc setDirtyFile*(fileIdx: FileIndex; filename: string) =
assert fileIdx >= 0 assert fileIdx.int32 >= 0
fileInfos[fileIdx].dirtyFile = filename fileInfos[fileIdx.int32].dirtyFile = filename
proc setHash*(fileIdx: int32; hash: string) = proc setHash*(fileIdx: FileIndex; hash: string) =
assert fileIdx >= 0 assert fileIdx.int32 >= 0
shallowCopy(fileInfos[fileIdx].hash, hash) shallowCopy(fileInfos[fileIdx.int32].hash, hash)
proc getHash*(fileIdx: int32): string = proc getHash*(fileIdx: FileIndex): string =
assert fileIdx >= 0 assert fileIdx.int32 >= 0
shallowCopy(result, fileInfos[fileIdx].hash) shallowCopy(result, fileInfos[fileIdx.int32].hash)
proc toFullPathConsiderDirty*(fileIdx: int32): string = proc toFullPathConsiderDirty*(fileIdx: FileIndex): string =
if fileIdx < 0: if fileIdx.int32 < 0:
result = "???" result = "???"
elif not fileInfos[fileIdx].dirtyFile.isNil: elif not fileInfos[fileIdx.int32].dirtyFile.isNil:
result = fileInfos[fileIdx].dirtyFile result = fileInfos[fileIdx.int32].dirtyFile
else: else:
result = fileInfos[fileIdx].fullPath result = fileInfos[fileIdx.int32].fullPath
template toFilename*(info: TLineInfo): string = template toFilename*(info: TLineInfo): string =
info.fileIndex.toFilename info.fileIndex.toFilename
@ -762,15 +765,15 @@ template toFullPath*(info: TLineInfo): string =
info.fileIndex.toFullPath info.fileIndex.toFullPath
proc toMsgFilename*(info: TLineInfo): string = proc toMsgFilename*(info: TLineInfo): string =
if info.fileIndex < 0: if info.fileIndex.int32 < 0:
result = "???" result = "???"
elif gListFullPaths: elif gListFullPaths:
result = fileInfos[info.fileIndex].fullPath result = fileInfos[info.fileIndex.int32].fullPath
else: else:
result = fileInfos[info.fileIndex].projPath result = fileInfos[info.fileIndex.int32].projPath
proc toLinenumber*(info: TLineInfo): int {.inline.} = proc toLinenumber*(info: TLineInfo): int {.inline.} =
result = info.line result = int info.line
proc toColumn*(info: TLineInfo): int {.inline.} = proc toColumn*(info: TLineInfo): int {.inline.} =
result = info.col result = info.col
@ -787,7 +790,7 @@ proc `??`* (info: TLineInfo, filename: string): bool =
# only for debugging purposes # only for debugging purposes
result = filename in info.toFilename result = filename in info.toFilename
const trackPosInvalidFileIdx* = -2 # special marker so that no suggestions const trackPosInvalidFileIdx* = FileIndex(-2) # special marker so that no suggestions
# are produced within comments and string literals # are produced within comments and string literals
var gTrackPos*: TLineInfo var gTrackPos*: TLineInfo
var gTrackPosAttached*: bool ## whether the tracking position was attached to some var gTrackPosAttached*: bool ## whether the tracking position was attached to some
@ -926,7 +929,7 @@ proc writeContext(lastinfo: TLineInfo) =
else: else:
styledMsgWriteln(styleBright, styledMsgWriteln(styleBright,
PosFormat % [toMsgFilename(msgContext[i]), PosFormat % [toMsgFilename(msgContext[i]),
coordToStr(msgContext[i].line), coordToStr(msgContext[i].line.int),
coordToStr(msgContext[i].col+1)], coordToStr(msgContext[i].col+1)],
resetStyle, resetStyle,
getMessageStr(errInstantiationFrom, "")) getMessageStr(errInstantiationFrom, ""))
@ -994,7 +997,7 @@ proc formatMsg*(info: TLineInfo, msg: TMsgKind, arg: string): string =
of warnMin..warnMax: WarningTitle of warnMin..warnMax: WarningTitle
of hintMin..hintMax: HintTitle of hintMin..hintMax: HintTitle
else: ErrorTitle else: ErrorTitle
result = PosFormat % [toMsgFilename(info), coordToStr(info.line), result = PosFormat % [toMsgFilename(info), coordToStr(info.line.int),
coordToStr(info.col+1)] & coordToStr(info.col+1)] &
title & title &
getMessageStr(msg, arg) getMessageStr(msg, arg)
@ -1035,7 +1038,7 @@ proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string,
# NOTE: currently line info line numbers start with 1, # NOTE: currently line info line numbers start with 1,
# but column numbers start with 0, however most editors expect # but column numbers start with 0, however most editors expect
# first column to be 1, so we need to +1 here # first column to be 1, so we need to +1 here
let x = PosFormat % [toMsgFilename(info), coordToStr(info.line), let x = PosFormat % [toMsgFilename(info), coordToStr(info.line.int),
coordToStr(info.col+1)] coordToStr(info.col+1)]
let s = getMessageStr(msg, arg) let s = getMessageStr(msg, arg)
@ -1093,30 +1096,30 @@ template assertNotNil*(e): untyped =
template internalAssert*(e: bool) = template internalAssert*(e: bool) =
if not e: internalError($instantiationInfo()) if not e: internalError($instantiationInfo())
proc addSourceLine*(fileIdx: int32, line: string) = proc addSourceLine*(fileIdx: FileIndex, line: string) =
fileInfos[fileIdx].lines.add line.rope fileInfos[fileIdx.int32].lines.add line.rope
proc sourceLine*(i: TLineInfo): Rope = proc sourceLine*(i: TLineInfo): Rope =
if i.fileIndex < 0: return nil if i.fileIndex.int32 < 0: return nil
if not optPreserveOrigSource and fileInfos[i.fileIndex].lines.len == 0: if not optPreserveOrigSource and fileInfos[i.fileIndex.int32].lines.len == 0:
try: try:
for line in lines(i.toFullPath): for line in lines(i.toFullPath):
addSourceLine i.fileIndex, line.string addSourceLine i.fileIndex, line.string
except IOError: except IOError:
discard discard
internalAssert i.fileIndex < fileInfos.len internalAssert i.fileIndex.int32 < fileInfos.len
# can happen if the error points to EOF: # can happen if the error points to EOF:
if i.line > fileInfos[i.fileIndex].lines.len: return nil if i.line.int > fileInfos[i.fileIndex.int32].lines.len: return nil
result = fileInfos[i.fileIndex].lines[i.line-1] result = fileInfos[i.fileIndex.int32].lines[i.line.int-1]
proc quotedFilename*(i: TLineInfo): Rope = proc quotedFilename*(i: TLineInfo): Rope =
internalAssert i.fileIndex >= 0 internalAssert i.fileIndex.int32 >= 0
if optExcessiveStackTrace in gGlobalOptions: if optExcessiveStackTrace in gGlobalOptions:
result = fileInfos[i.fileIndex].quotedFullName result = fileInfos[i.fileIndex.int32].quotedFullName
else: else:
result = fileInfos[i.fileIndex].quotedName result = fileInfos[i.fileIndex.int32].quotedName
ropes.errorHandler = proc (err: RopesError, msg: string, useWarning: bool) = ropes.errorHandler = proc (err: RopesError, msg: string, useWarning: bool) =
case err case err

View file

@ -28,7 +28,7 @@ proc overwriteFiles*() =
let doStrip = options.getConfigVar("pretty.strip").normalize == "on" let doStrip = options.getConfigVar("pretty.strip").normalize == "on"
for i in 0 .. high(gSourceFiles): for i in 0 .. high(gSourceFiles):
if gSourceFiles[i].dirty and not gSourceFiles[i].isNimfixFile and if gSourceFiles[i].dirty and not gSourceFiles[i].isNimfixFile and
(not gOnlyMainfile or gSourceFiles[i].fileIdx == gProjectMainIdx): (not gOnlyMainfile or gSourceFiles[i].fileIdx == gProjectMainIdx.FileIndex):
let newFile = if gOverWrite: gSourceFiles[i].fullpath let newFile = if gOverWrite: gSourceFiles[i].fullpath
else: gSourceFiles[i].fullpath.changeFileExt(".pretty.nim") else: gSourceFiles[i].fullpath.changeFileExt(".pretty.nim")
try: try:
@ -95,7 +95,7 @@ proc beautifyName(s: string, k: TSymKind): string =
proc replaceInFile(info: TLineInfo; newName: string) = proc replaceInFile(info: TLineInfo; newName: string) =
loadFile(info) loadFile(info)
let line = gSourceFiles[info.fileIndex].lines[info.line-1] let line = gSourceFiles[info.fileIndex.int].lines[info.line.int-1]
var first = min(info.col.int, line.len) var first = min(info.col.int, line.len)
if first < 0: return if first < 0: return
#inc first, skipIgnoreCase(line, "proc ", first) #inc first, skipIgnoreCase(line, "proc ", first)
@ -107,8 +107,8 @@ proc replaceInFile(info: TLineInfo; newName: string) =
if differ(line, first, last, newName): if differ(line, first, last, newName):
# last-first+1 != newName.len or # last-first+1 != newName.len or
var x = line.substr(0, first-1) & newName & line.substr(last+1) var x = line.substr(0, first-1) & newName & line.substr(last+1)
system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) system.shallowCopy(gSourceFiles[info.fileIndex.int].lines[info.line.int-1], x)
gSourceFiles[info.fileIndex].dirty = true gSourceFiles[info.fileIndex.int].dirty = true
proc checkStyle(info: TLineInfo, s: string, k: TSymKind; sym: PSym) = proc checkStyle(info: TLineInfo, s: string, k: TSymKind; sym: PSym) =
let beau = beautifyName(s, k) let beau = beautifyName(s, k)
@ -136,7 +136,7 @@ template styleCheckDef*(s: PSym) =
styleCheckDef(s.info, s, s.kind) styleCheckDef(s.info, s, s.kind)
proc styleCheckUseImpl(info: TLineInfo; s: PSym) = proc styleCheckUseImpl(info: TLineInfo; s: PSym) =
if info.fileIndex < 0: return if info.fileIndex.int < 0: return
# we simply convert it to what it looks like in the definition # we simply convert it to what it looks like in the definition
# for consistency # for consistency

View file

@ -16,13 +16,13 @@ type
lines*: seq[string] lines*: seq[string]
dirty*, isNimfixFile*: bool dirty*, isNimfixFile*: bool
fullpath*, newline*: string fullpath*, newline*: string
fileIdx*: int32 fileIdx*: FileIndex
var var
gSourceFiles*: seq[TSourceFile] = @[] gSourceFiles*: seq[TSourceFile] = @[]
proc loadFile*(info: TLineInfo) = proc loadFile*(info: TLineInfo) =
let i = info.fileIndex let i = info.fileIndex.int
if i >= gSourceFiles.len: if i >= gSourceFiles.len:
gSourceFiles.setLen(i+1) gSourceFiles.setLen(i+1)
if gSourceFiles[i].lines.isNil: if gSourceFiles[i].lines.isNil:
@ -64,7 +64,7 @@ proc differ*(line: string, a, b: int, x: string): bool =
proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PIdent) = proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PIdent) =
loadFile(info) loadFile(info)
let line = gSourceFiles[info.fileIndex].lines[info.line-1] let line = gSourceFiles[info.fileIndex.int32].lines[info.line.int-1]
var first = min(info.col.int, line.len) var first = min(info.col.int, line.len)
if first < 0: return if first < 0: return
#inc first, skipIgnoreCase(line, "proc ", first) #inc first, skipIgnoreCase(line, "proc ", first)
@ -75,8 +75,8 @@ proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PIdent) =
let last = first+identLen(line, first)-1 let last = first+identLen(line, first)-1
if cmpIgnoreStyle(line[first..last], oldSym.s) == 0: if cmpIgnoreStyle(line[first..last], oldSym.s) == 0:
var x = line.substr(0, first-1) & newSym.s & line.substr(last+1) var x = line.substr(0, first-1) & newSym.s & line.substr(last+1)
system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) system.shallowCopy(gSourceFiles[info.fileIndex.int32].lines[info.line.int-1], x)
gSourceFiles[info.fileIndex].dirty = true gSourceFiles[info.fileIndex.int32].dirty = true
#if newSym.s == "File": writeStackTrace() #if newSym.s == "File": writeStackTrace()
proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PSym) = proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PSym) =
@ -85,10 +85,10 @@ proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PSym) =
proc replaceComment*(info: TLineInfo) = proc replaceComment*(info: TLineInfo) =
loadFile(info) loadFile(info)
let line = gSourceFiles[info.fileIndex].lines[info.line-1] let line = gSourceFiles[info.fileIndex.int32].lines[info.line.int-1]
var first = info.col.int var first = info.col.int
if line[first] != '#': inc first if line[first] != '#': inc first
var x = line.substr(0, first-1) & "discard " & line.substr(first+1).escape var x = line.substr(0, first-1) & "discard " & line.substr(first+1).escape
system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) system.shallowCopy(gSourceFiles[info.fileIndex.int32].lines[info.line.int-1], x)
gSourceFiles[info.fileIndex].dirty = true gSourceFiles[info.fileIndex.int32].dirty = true

View file

@ -235,7 +235,8 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult
result = arLValue result = arLValue
else: else:
result = isAssignable(owner, n.sons[0], isUnsafeAddr) result = isAssignable(owner, n.sons[0], isUnsafeAddr)
if result != arNone and sfDiscriminant in n.sons[1].sym.flags: if result != arNone and n[1].kind == nkSym and
sfDiscriminant in n[1].sym.flags:
result = arDiscriminant result = arDiscriminant
of nkBracketExpr: of nkBracketExpr:
if skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc}).kind in if skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc}).kind in

View file

@ -83,7 +83,7 @@ proc getTok(p: var TParser) =
rawGetTok(p.lex, p.tok) rawGetTok(p.lex, p.tok)
p.hasProgress = true p.hasProgress = true
proc openParser*(p: var TParser, fileIdx: int32, inputStream: PLLStream, proc openParser*(p: var TParser, fileIdx: FileIndex, inputStream: PLLStream,
cache: IdentCache; cache: IdentCache;
strongSpaces=false) = strongSpaces=false) =
## Open a parser, using the given arguments to set up its internal state. ## Open a parser, using the given arguments to set up its internal state.

View file

@ -52,8 +52,8 @@ proc makePass*(open: TPassOpen = nil,
# the semantic checker needs these: # the semantic checker needs these:
var var
gImportModule*: proc (graph: ModuleGraph; m: PSym, fileIdx: int32; cache: IdentCache): PSym {.nimcall.} gImportModule*: proc (graph: ModuleGraph; m: PSym, fileIdx: FileIndex; cache: IdentCache): PSym {.nimcall.}
gIncludeFile*: proc (graph: ModuleGraph; m: PSym, fileIdx: int32; cache: IdentCache): PNode {.nimcall.} gIncludeFile*: proc (graph: ModuleGraph; m: PSym, fileIdx: FileIndex; cache: IdentCache): PNode {.nimcall.}
# implementation # implementation
@ -63,20 +63,6 @@ proc skipCodegen*(n: PNode): bool {.inline.} =
# error count instead. # error count instead.
result = msgs.gErrorCounter > 0 result = msgs.gErrorCounter > 0
proc astNeeded*(s: PSym): bool =
# The ``rodwrite`` module uses this to determine if the body of a proc
# needs to be stored. The passes manager frees s.sons[codePos] when
# appropriate to free the procedure body's memory. This is important
# to keep memory usage down.
if (s.kind in {skMethod, skProc, skFunc}) and
({sfCompilerProc, sfCompileTime} * s.flags == {}) and
(s.typ.callConv != ccInline) and
(s.ast.sons[genericParamsPos].kind == nkEmpty):
result = false
# XXX this doesn't really make sense with excessive CTFE
else:
result = true
const const
maxPasses = 10 maxPasses = 10
@ -153,7 +139,7 @@ proc closePassesCached(graph: ModuleGraph; a: var TPassContextArray) =
m = gPasses[i].close(graph, a[i], m) m = gPasses[i].close(graph, a[i], m)
a[i] = nil # free the memory here a[i] = nil # free the memory here
proc resolveMod(module, relativeTo: string): int32 = proc resolveMod(module, relativeTo: string): FileIndex =
let fullPath = findModule(module, relativeTo) let fullPath = findModule(module, relativeTo)
if fullPath.len == 0: if fullPath.len == 0:
result = InvalidFileIDX result = InvalidFileIDX
@ -166,7 +152,7 @@ proc processImplicits(implicits: seq[string], nodeKind: TNodeKind,
let relativeTo = m.info.toFullPath let relativeTo = m.info.toFullPath
for module in items(implicits): for module in items(implicits):
# implicit imports should not lead to a module importing itself # implicit imports should not lead to a module importing itself
if m.position != resolveMod(module, relativeTo): if m.position != resolveMod(module, relativeTo).int32:
var importStmt = newNodeI(nodeKind, gCmdLineInfo) var importStmt = newNodeI(nodeKind, gCmdLineInfo)
var str = newStrNode(nkStrLit, module) var str = newStrNode(nkStrLit, module)
str.info = gCmdLineInfo str.info = gCmdLineInfo
@ -180,7 +166,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream,
p: TParsers p: TParsers
a: TPassContextArray a: TPassContextArray
s: PLLStream s: PLLStream
fileIdx = module.fileIdx fileIdx = FileIndex module.fileIdx
if module.id < 0: if module.id < 0:
# new module caching mechanism: # new module caching mechanism:
for i in 0..<gPassesLen: for i in 0..<gPassesLen:

View file

@ -19,7 +19,7 @@ proc getTok(p: var TParser) =
## `tok` member. ## `tok` member.
rawGetTok(p.lex, p.tok) rawGetTok(p.lex, p.tok)
proc openParser*(p: var TParser, fileIdx: int32, inputStream: PLLStream; proc openParser*(p: var TParser, fileIdx: FileIndex, inputStream: PLLStream;
cache: IdentCache) = cache: IdentCache) =
## Open a parser, using the given arguments to set up its internal state. ## Open a parser, using the given arguments to set up its internal state.
## ##

View file

@ -543,7 +543,7 @@ proc pragmaLine(c: PContext, n: PNode) =
else: else:
# XXX this produces weird paths which are not properly resolved: # XXX this produces weird paths which are not properly resolved:
n.info.fileIndex = msgs.fileInfoIdx(x.strVal) n.info.fileIndex = msgs.fileInfoIdx(x.strVal)
n.info.line = int16(y.intVal) n.info.line = uint16(y.intVal)
else: else:
localError(n.info, errXExpected, "tuple") localError(n.info, errXExpected, "tuple")
else: else:

View file

@ -135,11 +135,11 @@ proc hasIncludes(n:PNode): bool =
if a.kind == nkIncludeStmt: if a.kind == nkIncludeStmt:
return true return true
proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: int32; proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex;
cache: IdentCache): PNode {.procvar.} = cache: IdentCache): PNode {.procvar.} =
result = syntaxes.parseFile(fileIdx, cache) result = syntaxes.parseFile(fileIdx, cache)
graph.addDep(s, fileIdx) graph.addDep(s, fileIdx)
graph.addIncludeDep(s.position.int32, fileIdx) graph.addIncludeDep(FileIndex s.position, fileIdx)
proc expandIncludes(graph: ModuleGraph, module: PSym, n: PNode, proc expandIncludes(graph: ModuleGraph, module: PSym, n: PNode,
modulePath: string, includedFiles: var IntSet, modulePath: string, includedFiles: var IntSet,
@ -153,13 +153,13 @@ proc expandIncludes(graph: ModuleGraph, module: PSym, n: PNode,
for i in 0..<a.len: for i in 0..<a.len:
var f = checkModuleName(a.sons[i]) var f = checkModuleName(a.sons[i])
if f != InvalidFileIDX: if f != InvalidFileIDX:
if containsOrIncl(includedFiles, f): if containsOrIncl(includedFiles, f.int):
localError(a.info, errRecursiveDependencyX, f.toFilename) localError(a.info, errRecursiveDependencyX, f.toFilename)
else: else:
let nn = includeModule(graph, module, f, cache) let nn = includeModule(graph, module, f, cache)
let nnn = expandIncludes(graph, module, nn, modulePath, let nnn = expandIncludes(graph, module, nn, modulePath,
includedFiles, cache) includedFiles, cache)
excl(includedFiles, f) excl(includedFiles, f.int)
for b in nnn: for b in nnn:
result.add b result.add b
else: else:
@ -429,7 +429,7 @@ proc reorder*(graph: ModuleGraph, n: PNode, module: PSym, cache: IdentCache): PN
if n.hasForbiddenPragma: if n.hasForbiddenPragma:
return n return n
var includedFiles = initIntSet() var includedFiles = initIntSet()
let mpath = module.fileIdx.toFullPath let mpath = module.fileIdx.FileIndex.toFullPath
let n = expandIncludes(graph, module, n, mpath, let n = expandIncludes(graph, module, n, mpath,
includedFiles, cache).splitSections includedFiles, cache).splitSections
result = newNodeI(nkStmtList, n.info) result = newNodeI(nkStmtList, n.info)

View file

@ -9,124 +9,18 @@
## This module implements the canonalization for the various caching mechanisms. ## This module implements the canonalization for the various caching mechanisms.
import ast, idgen import ast, idgen, msgs
when not defined(nimSymbolfiles): when not defined(nimSymbolfiles):
template setupModuleCache* = discard template setupModuleCache* = discard
template storeNode*(module: PSym; n: PNode) = discard template storeNode*(module: PSym; n: PNode) = discard
template loadNode*(module: PSym; index: var int): PNode = PNode(nil) template loadNode*(module: PSym; index: var int): PNode = PNode(nil)
template getModuleId*(fileIdx: int32; fullpath: string): int = getID() template getModuleId*(fileIdx: FileIndex; fullpath: string): int = getID()
template addModuleDep*(module, fileIdx: int32; isIncludeFile: bool) = discard template addModuleDep*(module, fileIdx: FileIndex; isIncludeFile: bool) = discard
template storeRemaining*(module: PSym) = discard template storeRemaining*(module: PSym) = discard
else: else:
include rodimpl include rodimpl
when false:
type
BlobWriter* = object
buf: string
pos: int
SerializationAction = enum acRead, acWrite
# Varint implementation inspired by SQLite.
proc rdVaruint64(z: ptr UncheckedArray[byte]; n: int; pResult: var uint64): int =
if z[0] <= 240:
pResult = z[0]
return 1
if z[0] <= 248:
if n < 2: return 0
pResult = (z[0] - 241) * 256 + z[1] + 240
return 2
if n < z[0]-246: return 0
if z[0] == 249:
pResult = 2288 + 256*z[1] + z[2]
return 3
if z[0] == 250:
pResult = (z[1] shl 16u64) + (z[2] shl 8u64) + z[3]
return 4
let x = (z[1] shl 24) + (z[2] shl 16) + (z[3] shl 8) + z[4]
if z[0] == 251:
pResult = x
return 5
if z[0] == 252:
pResult = (((uint64)x) shl 8) + z[5]
return 6
if z[0] == 253:
pResult = (((uint64)x) shl 16) + (z[5] shl 8) + z[6]
return 7
if z[0] == 254:
pResult = (((uint64)x) shl 24) + (z[5] shl 16) + (z[6] shl 8) + z[7]
return 8
pResult = (((uint64)x) shl 32) +
(0xffffffff & ((z[5] shl 24) + (z[6] shl 16) + (z[7] shl 8) + z[8]))
return 9
proc varintWrite32(z: ptr UncheckedArray[byte]; y: uint32) =
z[0] = uint8(y shr 24)
z[1] = uint8(y shr 16)
z[2] = uint8(y shr 8)
z[3] = uint8(y)
proc sqlite4PutVarint64(z: ptr UncheckedArray[byte], x: uint64): int =
## Write a varint into z. The buffer z must be at least 9 characters
## long to accommodate the largest possible varint. Returns the number of
## bytes used.
if x <= 240:
z[0] = uint8 x
return 1
if x <= 2287:
y = uint32(x - 240)
z[0] = uint8(y shr 8 + 241)
z[1] = uint8(y and 255)
return 2
if x <= 67823:
y = uint32(x - 2288)
z[0] = 249
z[1] = uint8(y shr 8)
z[2] = uint8(y and 255)
return 3
let y = uint32 x
let w = uint32(x shr 32)
if w == 0:
if y <= 16777215:
z[0] = 250
z[1] = uint8(y shr 16)
z[2] = uint8(y shr 8)
z[3] = uint8(y)
return 4
z[0] = 251
varintWrite32(z+1, y)
return 5
if w <= 255:
z[0] = 252
z[1] = uint8 w
varintWrite32(z+2, y)
return 6
if w <= 65535:
z[0] = 253
z[1] = uint8(w shr 8)
z[2] = uint8 w
varintWrite32(z+3, y)
return 7
if w <= 16777215:
z[0] = 254
z[1] = uint8(w shr 16)
z[2] = uint8(w shr 8)
z[3] = uint8 w
varintWrite32(z+4, y)
return 8
z[0] = 255
varintWrite32(z+1, w)
varintWrite32(z+5, y)
return 9
template field(x: BiggestInt; action: SerializationAction) =
when action == acRead:
readBiggestInt(x)
else:
writeBiggestInt()

View file

@ -126,8 +126,8 @@ type
s: cstring # mmap'ed file contents s: cstring # mmap'ed file contents
options: TOptions options: TOptions
reason: TReasonForRecompile reason: TReasonForRecompile
modDeps: seq[int32] modDeps: seq[FileIndex]
files: seq[int32] files: seq[FileIndex]
dataIdx: int # offset of start of data section dataIdx: int # offset of start of data section
convertersIdx: int # offset of start of converters section convertersIdx: int # offset of start of converters section
initIdx, interfIdx, compilerProcsIdx, methodsIdx: int initIdx, interfIdx, compilerProcsIdx, methodsIdx: int
@ -163,11 +163,11 @@ proc decodeLineInfo(r: PRodReader, info: var TLineInfo) =
else: info.col = int16(decodeVInt(r.s, r.pos)) else: info.col = int16(decodeVInt(r.s, r.pos))
if r.s[r.pos] == ',': if r.s[r.pos] == ',':
inc(r.pos) inc(r.pos)
if r.s[r.pos] == ',': info.line = -1'i16 if r.s[r.pos] == ',': info.line = 0'u16
else: info.line = int16(decodeVInt(r.s, r.pos)) else: info.line = uint16(decodeVInt(r.s, r.pos))
if r.s[r.pos] == ',': if r.s[r.pos] == ',':
inc(r.pos) inc(r.pos)
info = newLineInfo(r.files[decodeVInt(r.s, r.pos)], info.line, info.col) info = newLineInfo(r.files[decodeVInt(r.s, r.pos)], int info.line, info.col)
proc skipNode(r: PRodReader) = proc skipNode(r: PRodReader) =
assert r.s[r.pos] == '(' assert r.s[r.pos] == '('
@ -861,29 +861,29 @@ proc loadMethods(r: PRodReader) =
r.methods.add(rrGetSym(r, d, unknownLineInfo())) r.methods.add(rrGetSym(r, d, unknownLineInfo()))
if r.s[r.pos] == ' ': inc(r.pos) if r.s[r.pos] == ' ': inc(r.pos)
proc getHash*(fileIdx: int32): SecureHash = proc getHash*(fileIdx: FileIndex): SecureHash =
if fileIdx <% gMods.len and gMods[fileIdx].hashDone: if fileIdx.int32 <% gMods.len and gMods[fileIdx.int32].hashDone:
return gMods[fileIdx].hash return gMods[fileIdx.int32].hash
result = secureHashFile(fileIdx.toFullPath) result = secureHashFile(fileIdx.toFullPath)
if fileIdx >= gMods.len: setLen(gMods, fileIdx+1) if fileIdx.int32 >= gMods.len: setLen(gMods, fileIdx.int32+1)
gMods[fileIdx].hash = result gMods[fileIdx.int32].hash = result
template growCache*(cache, pos) = template growCache*(cache, pos) =
if cache.len <= pos: cache.setLen(pos+1) if cache.len <= pos: cache.setLen(pos+1)
proc checkDep(fileIdx: int32; cache: IdentCache): TReasonForRecompile = proc checkDep(fileIdx: FileIndex; cache: IdentCache): TReasonForRecompile =
assert fileIdx != InvalidFileIDX assert fileIdx != InvalidFileIDX
growCache gMods, fileIdx growCache gMods, fileIdx.int32
if gMods[fileIdx].reason != rrEmpty: if gMods[fileIdx.int32].reason != rrEmpty:
# reason has already been computed for this module: # reason has already been computed for this module:
return gMods[fileIdx].reason return gMods[fileIdx.int32].reason
let filename = fileIdx.toFilename let filename = fileIdx.toFilename
var hash = getHash(fileIdx) var hash = getHash(fileIdx)
gMods[fileIdx].reason = rrNone # we need to set it here to avoid cycles gMods[fileIdx.int32].reason = rrNone # we need to set it here to avoid cycles
result = rrNone result = rrNone
var rodfile = toGeneratedFile(filename.withPackageName, RodExt) var rodfile = toGeneratedFile(filename.withPackageName, RodExt)
var r = newRodReader(rodfile, hash, fileIdx, cache) var r = newRodReader(rodfile, hash, fileIdx.int32, cache)
if r == nil: if r == nil:
result = (if existsFile(rodfile): rrRodInvalid else: rrRodDoesNotExist) result = (if existsFile(rodfile): rrRodInvalid else: rrRodDoesNotExist)
else: else:
@ -907,19 +907,18 @@ proc checkDep(fileIdx: int32; cache: IdentCache): TReasonForRecompile =
# recompilation is necessary: # recompilation is necessary:
if r != nil: memfiles.close(r.memfile) if r != nil: memfiles.close(r.memfile)
r = nil r = nil
gMods[fileIdx].rd = r gMods[fileIdx.int32].rd = r
gMods[fileIdx].reason = result # now we know better gMods[fileIdx.int32].reason = result # now we know better
proc handleSymbolFile*(module: PSym; cache: IdentCache): PRodReader = proc handleSymbolFile*(module: PSym; cache: IdentCache): PRodReader =
let fileIdx = module.fileIdx
if gSymbolFiles in {disabledSf, writeOnlySf, v2Sf}: if gSymbolFiles in {disabledSf, writeOnlySf, v2Sf}:
module.id = getID() module.id = getID()
return nil return nil
idgen.loadMaxIds(options.gProjectPath / options.gProjectName) idgen.loadMaxIds(options.gProjectPath / options.gProjectName)
let fileIdx = FileIndex module.fileIdx
discard checkDep(fileIdx, cache) discard checkDep(fileIdx, cache)
if gMods[fileIdx].reason == rrEmpty: internalError("handleSymbolFile") if gMods[fileIdx.int32].reason == rrEmpty: internalError("handleSymbolFile")
result = gMods[fileIdx].rd result = gMods[fileIdx.int32].rd
if result != nil: if result != nil:
module.id = result.moduleID module.id = result.moduleID
result.syms[module.id] = module result.syms[module.id] = module
@ -1153,7 +1152,7 @@ proc viewFile(rodfile: string) =
if r.s[r.pos] == '\x0A': if r.s[r.pos] == '\x0A':
inc(r.pos) inc(r.pos)
inc(r.line) inc(r.line)
outf.write(w, " ", inclHash, "\n") outf.write(w.int32, " ", inclHash, "\n")
if r.s[r.pos] == ')': inc(r.pos) if r.s[r.pos] == ')': inc(r.pos)
outf.write(")\n") outf.write(")\n")
of "DEPS": of "DEPS":
@ -1163,7 +1162,7 @@ proc viewFile(rodfile: string) =
let v = int32(decodeVInt(r.s, r.pos)) let v = int32(decodeVInt(r.s, r.pos))
r.modDeps.add(r.files[v]) r.modDeps.add(r.files[v])
if r.s[r.pos] == ' ': inc(r.pos) if r.s[r.pos] == ' ': inc(r.pos)
outf.write(" ", r.files[v]) outf.write(" ", r.files[v].int32)
outf.write("\n") outf.write("\n")
of "INTERF", "COMPILERPROCS": of "INTERF", "COMPILERPROCS":
inc r.pos, 2 inc r.pos, 2

View file

@ -55,7 +55,7 @@ proc fileIdx(w: PRodWriter, filename: string): int =
w.files[result] = filename w.files[result] = filename
template filename*(w: PRodWriter): string = template filename*(w: PRodWriter): string =
w.module.filename toFilename(FileIndex w.module.position)
proc newRodWriter(hash: SecureHash, module: PSym; cache: IdentCache): PRodWriter = proc newRodWriter(hash: SecureHash, module: PSym; cache: IdentCache): PRodWriter =
new(result) new(result)
@ -125,14 +125,14 @@ proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode,
result.add('?') result.add('?')
encodeVInt(n.info.col, result) encodeVInt(n.info.col, result)
result.add(',') result.add(',')
encodeVInt(n.info.line, result) encodeVInt(int n.info.line, result)
result.add(',') result.add(',')
encodeVInt(fileIdx(w, toFullPath(n.info)), result) encodeVInt(fileIdx(w, toFullPath(n.info)), result)
elif fInfo.line != n.info.line: elif fInfo.line != n.info.line:
result.add('?') result.add('?')
encodeVInt(n.info.col, result) encodeVInt(n.info.col, result)
result.add(',') result.add(',')
encodeVInt(n.info.line, result) encodeVInt(int n.info.line, result)
elif fInfo.col != n.info.col: elif fInfo.col != n.info.col:
result.add('?') result.add('?')
encodeVInt(n.info.col, result) encodeVInt(n.info.col, result)
@ -303,7 +303,7 @@ proc encodeSym(w: PRodWriter, s: PSym, result: var string) =
result.add('?') result.add('?')
if s.info.col != -1'i16: encodeVInt(s.info.col, result) if s.info.col != -1'i16: encodeVInt(s.info.col, result)
result.add(',') result.add(',')
if s.info.line != -1'i16: encodeVInt(s.info.line, result) if s.info.line != 0'u16: encodeVInt(int s.info.line, result)
result.add(',') result.add(',')
encodeVInt(fileIdx(w, toFullPath(s.info)), result) encodeVInt(fileIdx(w, toFullPath(s.info)), result)
if s.owner != nil: if s.owner != nil:
@ -642,7 +642,7 @@ proc process(c: PPassContext, n: PNode): PNode =
proc myOpen(g: ModuleGraph; module: PSym; cache: IdentCache): PPassContext = proc myOpen(g: ModuleGraph; module: PSym; cache: IdentCache): PPassContext =
if module.id < 0: internalError("rodwrite: module ID not set") if module.id < 0: internalError("rodwrite: module ID not set")
var w = newRodWriter(rodread.getHash module.fileIdx, module, cache) var w = newRodWriter(rodread.getHash FileIndex module.position, module, cache)
rawAddInterfaceSym(w, module) rawAddInterfaceSym(w, module)
result = w result = w

View file

@ -144,7 +144,7 @@ proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
proc filename*(c: PContext): string = proc filename*(c: PContext): string =
# the module's filename # the module's filename
return c.module.filename return toFilename(FileIndex c.module.position)
proc scopeDepth*(c: PContext): int {.inline.} = proc scopeDepth*(c: PContext): int {.inline.} =
result = if c.currentScope != nil: c.currentScope.depthLevel result = if c.currentScope != nil: c.currentScope.depthLevel

View file

@ -1095,12 +1095,12 @@ proc semAllTypeSections(c: PContext; n: PNode): PNode =
for i in 0..<n.len: for i in 0..<n.len:
var f = checkModuleName(n.sons[i]) var f = checkModuleName(n.sons[i])
if f != InvalidFileIDX: if f != InvalidFileIDX:
if containsOrIncl(c.includedFiles, f): if containsOrIncl(c.includedFiles, f.int):
localError(n.info, errRecursiveDependencyX, f.toFilename) localError(n.info, errRecursiveDependencyX, f.toFilename)
else: else:
let code = gIncludeFile(c.graph, c.module, f, c.cache) let code = gIncludeFile(c.graph, c.module, f, c.cache)
gatherStmts c, code, result gatherStmts c, code, result
excl(c.includedFiles, f) excl(c.includedFiles, f.int)
of nkStmtList: of nkStmtList:
for i in 0 ..< n.len: for i in 0 ..< n.len:
gatherStmts(c, n.sons[i], result) gatherStmts(c, n.sons[i], result)
@ -1784,11 +1784,11 @@ proc evalInclude(c: PContext, n: PNode): PNode =
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
var f = checkModuleName(n.sons[i]) var f = checkModuleName(n.sons[i])
if f != InvalidFileIDX: if f != InvalidFileIDX:
if containsOrIncl(c.includedFiles, f): if containsOrIncl(c.includedFiles, f.int):
localError(n.info, errRecursiveDependencyX, f.toFilename) localError(n.info, errRecursiveDependencyX, f.toFilename)
else: else:
addSon(result, semStmt(c, gIncludeFile(c.graph, c.module, f, c.cache))) addSon(result, semStmt(c, gIncludeFile(c.graph, c.module, f, c.cache)))
excl(c.includedFiles, f) excl(c.includedFiles, f.int)
proc setLine(n: PNode, info: TLineInfo) = proc setLine(n: PNode, info: TLineInfo) =
for i in 0 ..< safeLen(n): setLine(n.sons[i], info) for i in 0 ..< safeLen(n): setLine(n.sons[i], info)

View file

@ -415,7 +415,7 @@ when defined(nimsuggest):
# Since TLineInfo defined a == operator that doesn't include the column, # Since TLineInfo defined a == operator that doesn't include the column,
# we map TLineInfo to a unique int here for this lookup table: # we map TLineInfo to a unique int here for this lookup table:
proc infoToInt(info: TLineInfo): int64 = proc infoToInt(info: TLineInfo): int64 =
info.fileIndex + info.line.int64 shl 32 + info.col.int64 shl 48 info.fileIndex.int64 + info.line.int64 shl 32 + info.col.int64 shl 48
proc addNoDup(s: PSym; info: TLineInfo) = proc addNoDup(s: PSym; info: TLineInfo) =
# ensure nothing gets too slow: # ensure nothing gets too slow:
@ -574,7 +574,7 @@ proc suggestEnum*(c: PContext; n: PNode; t: PType) =
if outputs.len > 0: suggestQuit() if outputs.len > 0: suggestQuit()
proc suggestSentinel*(c: PContext) = proc suggestSentinel*(c: PContext) =
if gIdeCmd != ideSug or c.module.position != gTrackPos.fileIndex: return if gIdeCmd != ideSug or c.module.position != gTrackPos.fileIndex.int32: return
if c.compilesContextId > 0: return if c.compilesContextId > 0: return
inc(c.compilesContextId) inc(c.compilesContextId)
var outputs: Suggestions = @[] var outputs: Suggestions = @[]

View file

@ -138,7 +138,7 @@ proc evalPipe(p: var TParsers, n: PNode, filename: string,
else: else:
result = applyFilter(p, n, filename, result) result = applyFilter(p, n, filename, result)
proc openParsers*(p: var TParsers, fileIdx: int32, inputstream: PLLStream; proc openParsers*(p: var TParsers, fileIdx: FileIndex, inputstream: PLLStream;
cache: IdentCache) = cache: IdentCache) =
var s: PLLStream var s: PLLStream
p.skin = skinStandard p.skin = skinStandard
@ -155,7 +155,7 @@ proc openParsers*(p: var TParsers, fileIdx: int32, inputstream: PLLStream;
proc closeParsers*(p: var TParsers) = proc closeParsers*(p: var TParsers) =
parser.closeParser(p.parser) parser.closeParser(p.parser)
proc parseFile*(fileIdx: int32; cache: IdentCache): PNode {.procvar.} = proc parseFile*(fileIdx: FileIndex; cache: IdentCache): PNode {.procvar.} =
var var
p: TParsers p: TParsers
f: File f: File

View file

@ -1381,7 +1381,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
of opcNGetLine: of opcNGetLine:
decodeB(rkNode) decodeB(rkNode)
let n = regs[rb].node let n = regs[rb].node
regs[ra].node = newIntNode(nkIntLit, n.info.line) regs[ra].node = newIntNode(nkIntLit, n.info.line.int)
regs[ra].node.info = n.info regs[ra].node.info = n.info
regs[ra].node.typ = n.typ regs[ra].node.typ = n.typ
of opcNGetColumn: of opcNGetColumn:
@ -1521,7 +1521,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
let x = newNodeI(TNodeKind(int(k)), let x = newNodeI(TNodeKind(int(k)),
if cc.kind != nkNilLit: if cc.kind != nkNilLit:
cc.info cc.info
elif c.comesFromHeuristic.line > -1: elif c.comesFromHeuristic.line != 0'u16:
c.comesFromHeuristic c.comesFromHeuristic
elif c.callsite != nil and c.callsite.safeLen > 1: elif c.callsite != nil and c.callsite.safeLen > 1:
c.callsite[1].info c.callsite[1].info
@ -1748,7 +1748,7 @@ proc evalMacroCall*(module: PSym; cache: IdentCache, n, nOrig: PNode,
setupGlobalCtx(module, cache) setupGlobalCtx(module, cache)
var c = globalCtx var c = globalCtx
c.comesFromHeuristic.line = -1 c.comesFromHeuristic.line = 0'u16
c.callsite = nOrig c.callsite = nOrig
let start = genProc(c, sym) let start = genProc(c, sym)